static int rtswitch_ioctl_rt(struct rtdm_dev_context *context, rtdm_user_info_t *user_info, unsigned int request, void *arg) { rtswitch_context_t *ctx = (rtswitch_context_t *) context->dev_private; struct rttst_swtest_task task; struct rttst_swtest_dir fromto; switch (request) { case RTTST_RTIOC_SWTEST_REGISTER_UTASK: case RTTST_RTIOC_SWTEST_CREATE_KTASK: case RTTST_RTIOC_SWTEST_GET_SWITCHES_COUNT: return -ENOSYS; case RTTST_RTIOC_SWTEST_PEND: if (!rtdm_read_user_ok(user_info, arg, sizeof(task))) return -EFAULT; rtdm_copy_from_user(user_info, &task, arg, sizeof(task)); return rtswitch_pend_rt(ctx, task.index); case RTTST_RTIOC_SWTEST_SWITCH_TO: if (!rtdm_read_user_ok(user_info, arg, sizeof(fromto))) return -EFAULT; rtdm_copy_from_user(user_info, &fromto, arg, sizeof(fromto)); return rtswitch_to_rt(ctx, fromto.from, fromto.to); case RTTST_RTIOC_SWTEST_GET_LAST_ERROR: if (!rtdm_rw_user_ok(user_info, arg, sizeof(ctx->error))) return -EFAULT; rtdm_copy_to_user(user_info, arg, &ctx->error, sizeof(ctx->error)); return 0; default: return -ENOTTY; } }
int demo_ioctl_rt(struct rtdm_dev_context *context, rtdm_user_info_t *user_info, unsigned int request, void *arg) { struct demodrv_context *my_context; #ifdef USEMMAP int err; #endif int ret = 0; my_context = (struct demodrv_context *)context->dev_private; switch (request) { case MMAP: // set mmap pointer #ifdef USEMMAP printk("buf = %p:%x\n", my_context->buf, *(int *)my_context->buf); err = rtdm_mmap_to_user(user_info, my_context->buf, BUFFER_SIZE, PROT_READ|PROT_WRITE, (void **)arg, &mmap_ops, (void *)0x12345678); if (!err) { my_context->mapped_user_info = user_info; my_context->mapped_user_addr = *(void **)arg; } printk("rtdm_mmap = %p %d\n", my_context->mapped_user_info, err); #else return -EPERM; #endif break; case GETVALUE: // write "ioctlvalue" to user if (user_info) { if (!rtdm_rw_user_ok(user_info, arg, sizeof(int)) || rtdm_copy_to_user(user_info, arg, &ioctlvalue, sizeof(int))) return -EFAULT; } else memcpy(arg, &ioctlvalue, sizeof(int)); break; case SETVALUE: // read "ioctlvalue" from user if (user_info) { if ((unsigned long)arg < BUFFER_SIZE) ioctlvalue = ((int *)my_context->buf)[(unsigned long)arg]; else if (!rtdm_read_user_ok(user_info, arg, sizeof(int)) || rtdm_copy_from_user(user_info, &ioctlvalue, arg, sizeof(int))) return -EFAULT; } break; default: ret = -ENOTTY; } return ret; }
int demo_write_rt(struct rtdm_dev_context *context, rtdm_user_info_t *user_info, const void *buf, size_t nbyte) { struct demodrv_context *ctx; int dev_id; char *in_pos = (char *)buf; int ret; if (nbyte == 0) return 0; if (user_info && !rtdm_read_user_ok(user_info, buf, nbyte)) return -EFAULT; ctx = (struct demodrv_context *)context->dev_private; dev_id = ctx->dev_id; // make write operation atomic /* ret = rtdm_mutex_timedlock(&ctx->out_lock, ctx->config.rx_timeout, &timeout_seq); if (ret) return ret; */ /* // if we need to do some stuff with preemption disabled: rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); // stuff here rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); */ // now copy the stuff from user-space to our kernel dummy_buffer if (rtdm_copy_from_user(user_info, dummy_buffer, in_pos, BUFSIZE) != 0) { ret = -EFAULT; } else { ret = BUFSIZE; } // used when it is atomic // rtdm_mutex_unlock(&ctx->out_lock); return ret; }
static int rtswitch_ioctl_nrt(struct rtdm_dev_context *context, rtdm_user_info_t *user_info, unsigned int request, void *arg) { rtswitch_context_t *ctx = (rtswitch_context_t *) context->dev_private; struct rttst_swtest_task task; struct rttst_swtest_dir fromto; unsigned long count; int err; switch (request) { case RTTST_RTIOC_SWTEST_SET_TASKS_COUNT: return rtswitch_set_tasks_count(ctx, (unsigned long) arg); case RTTST_RTIOC_SWTEST_SET_CPU: if ((unsigned long) arg > xnarch_num_online_cpus() - 1) return -EINVAL; ctx->cpu = (unsigned long) arg; return 0; case RTTST_RTIOC_SWTEST_SET_PAUSE: ctx->pause_us = (unsigned long) arg; return 0; case RTTST_RTIOC_SWTEST_REGISTER_UTASK: if (!rtdm_rw_user_ok(user_info, arg, sizeof(task))) return -EFAULT; rtdm_copy_from_user(user_info, &task, arg, sizeof(task)); err = rtswitch_register_task(ctx, &task); if (!err) rtdm_copy_to_user(user_info, arg, &task, sizeof(task)); return err; case RTTST_RTIOC_SWTEST_CREATE_KTASK: if (!rtdm_rw_user_ok(user_info, arg, sizeof(task))) return -EFAULT; rtdm_copy_from_user(user_info, &task, arg, sizeof(task)); err = rtswitch_create_ktask(ctx, &task); if (!err) rtdm_copy_to_user(user_info, arg, &task, sizeof(task)); return err; case RTTST_RTIOC_SWTEST_PEND: if (!rtdm_read_user_ok(user_info, arg, sizeof(task))) return -EFAULT; rtdm_copy_from_user(user_info, &task, arg, sizeof(task)); return rtswitch_pend_nrt(ctx, task.index); case RTTST_RTIOC_SWTEST_SWITCH_TO: if (!rtdm_read_user_ok(user_info, arg, sizeof(fromto))) return -EFAULT; rtdm_copy_from_user(user_info, &fromto, arg, sizeof(fromto)); return rtswitch_to_nrt(ctx, fromto.from, fromto.to); case RTTST_RTIOC_SWTEST_GET_SWITCHES_COUNT: if (!rtdm_rw_user_ok(user_info, arg, sizeof(count))) return -EFAULT; count = ctx->switches_count; rtdm_copy_to_user(user_info, arg, &count, sizeof(count)); return 0; case RTTST_RTIOC_SWTEST_GET_LAST_ERROR: if (!rtdm_rw_user_ok(user_info, arg, sizeof(ctx->error))) return -EFAULT; rtdm_copy_to_user(user_info, arg, &ctx->error, sizeof(ctx->error)); return 0; default: return -ENOTTY; } }