in devices/rio_mport_cdev.c [303:352]
static int rio_mport_maint_wr(struct mport_cdev_priv *priv, void __user *arg,
int local)
{
struct rio_mport *mport = priv->md->mport;
struct rio_mport_maint_io maint_io;
u32 *buffer;
u32 offset;
size_t length;
int ret = -EINVAL, i;
if (unlikely(copy_from_user(&maint_io, arg, sizeof(maint_io))))
return -EFAULT;
if ((maint_io.offset % 4) ||
(maint_io.length == 0) || (maint_io.length % 4) ||
(maint_io.length + maint_io.offset) > RIO_MAINT_SPACE_SZ)
return -EINVAL;
buffer = vmalloc(maint_io.length);
if (buffer == NULL)
return -ENOMEM;
length = maint_io.length;
if (unlikely(copy_from_user(buffer,
(void __user *)(uintptr_t)maint_io.buffer, length))) {
ret = -EFAULT;
goto out;
}
offset = maint_io.offset;
length /= sizeof(u32);
for (i = 0; i < length; i++) {
if (local)
ret = __rio_local_write_config_32(mport,
offset, buffer[i]);
else
ret = rio_mport_write_config_32(mport, maint_io.rioid,
maint_io.hopcount,
offset, buffer[i]);
if (ret)
goto out;
offset += 4;
}
out:
vfree(buffer);
return ret;
}