static int nvhost_ioctl_ctrl_module_regrdwr(struct nvhost_ctrl_userctx *ctx, struct nvhost_ctrl_module_regrdwr_args *args) { u32 num_offsets = args->num_offsets; u32 *offsets = args->offsets; u32 *values = args->values; u32 vals[64]; struct nvhost_device *ndev; trace_nvhost_ioctl_ctrl_module_regrdwr(args->id, args->num_offsets, args->write); /* Check that there is something to read and that block size is * u32 aligned */ if (num_offsets == 0 || args->block_size & 3) return -EINVAL; ndev = get_ndev_by_moduleid(ctx->dev, args->id); if (!ndev) return -EINVAL; while (num_offsets--) { int err; int remaining = args->block_size >> 2; u32 offs; if (get_user(offs, offsets)) return -EFAULT; offsets++; while (remaining) { int batch = min(remaining, 64); if (args->write) { if (copy_from_user(vals, values, batch*sizeof(u32))) return -EFAULT; err = nvhost_write_module_regs(ndev, offs, batch, vals); if (err) return err; } else { err = nvhost_read_module_regs(ndev, offs, batch, vals); if (err) return err; if (copy_to_user(values, vals, batch*sizeof(u32))) return -EFAULT; } remaining -= batch; offs += batch*sizeof(u32); values += batch; } } return 0; }
static int nvhost_ioctl_ctrl_module_regrdwr( struct nvhost_ctrl_userctx *ctx, struct nvhost_ctrl_module_regrdwr_args *args) { u32 num_offsets = args->num_offsets; u32 *offsets = args->offsets; void *values = args->values; u32 vals[64]; trace_nvhost_ioctl_ctrl_module_regrdwr(args->id, args->num_offsets, args->write); if (!(args->id < ctx->dev->nb_modules) || (num_offsets == 0)) return -EINVAL; while (num_offsets--) { u32 remaining = args->block_size; u32 offs; if (get_user(offs, offsets)) return -EFAULT; offsets++; while (remaining) { u32 batch = min(remaining, 64*sizeof(u32)); if (args->write) { if (copy_from_user(vals, values, batch)) return -EFAULT; nvhost_write_module_regs(&ctx->dev->cpuaccess, args->id, offs, batch, vals); } else { nvhost_read_module_regs(&ctx->dev->cpuaccess, args->id, offs, batch, vals); if (copy_to_user(values, vals, batch)) return -EFAULT; } remaining -= batch; offs += batch; values += batch; } } return 0; }