Exemple #1
0
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;
}
Exemple #2
0
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;
	}
}
Exemple #3
0
int demo_read_rt(struct rtdm_dev_context *context,
                  rtdm_user_info_t *user_info, void *buf, size_t nbyte)
{
    struct demodrv_context *ctx;
    int                     dev_id;
//    rtdm_lockctx_t          lock_ctx;
    char                    *out_pos = (char *)buf;
    rtdm_toseq_t            timeout_seq;
    int                     ret;

    // zero bytes requested ? return!
    if (nbyte == 0)
        return 0;

    // check if R/W actions to user-space are allowed
    if (user_info && !rtdm_rw_user_ok(user_info, buf, nbyte))
        return -EFAULT;

    ctx    = (struct demodrv_context *)context->dev_private;
    dev_id = ctx->dev_id;

    // in case we need to check if reading is allowed (locking)
/*    if (test_and_set_bit(0, &ctx->in_lock))
        return -EBUSY;
*/
/*  // 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);
*/

    // wait: if ctx->timeout = 0, it will block infintely until
    //       rtdm_event_signal(&ctx->irq_event); is called from our
    //       interrupt routine
    ret = rtdm_event_timedwait(&ctx->irq_event, ctx->timeout, &timeout_seq);

    // now write the requested stuff to user-space
    if (rtdm_copy_to_user(user_info, out_pos,
                dummy_buffer, BUFSIZE) != 0) {
        ret = -EFAULT;
    } else {
        ret = BUFSIZE;
    }
    return ret;
}
Exemple #4
0
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;
		}
}
Exemple #5
0
// userpace task receives data from userspace mailbox
static unsigned long tims_copy_userslot_user(rtdm_user_info_t *user_info,
                                             tims_mbx_slot *slot,
                                             const struct msghdr *msg)
{
    unsigned long akt_copy_size = 0;
    unsigned long copy_bytes    = 0;
    unsigned long bytes_copied  = 0;
    unsigned long bytes_in_page = 0;
    int i;

    unsigned long  ret;
    unsigned long  p_src_map    = slot->p_head_map;
    void          *p_src        = slot->p_head;
    void          *p_dest       = NULL;
    unsigned long  src_page     = slot->map_idx;
    tims_msg_head *p_head       = (tims_msg_head *)slot->p_head_map;
    unsigned long  databytes    = p_head->msglen - TIMS_HEADLEN;

    for (i=0; i<2; i++)
    {
        if (!i)
            copy_bytes = TIMS_HEADLEN;
        else
            copy_bytes = databytes;

        p_dest = msg->msg_iov[i].iov_base;

        // check destination pointer
        ret = rtdm_rw_user_ok(user_info, p_dest, copy_bytes);
        if (!ret)
        {
            tims_error("ERROR: userspace destination 0x%p (%lu bytes) NOT OK \n",
                       p_dest, copy_bytes);
            return ret;
        }

        // copy data
        while (copy_bytes)
        {
            bytes_in_page = get_remain_bytes_in_page(p_src_map);
            akt_copy_size = min_t(unsigned long, bytes_in_page, copy_bytes);

            ret = rtdm_copy_to_user(user_info, p_dest, (void *)p_src_map,
                                    akt_copy_size);
            if (ret)
            {
                if (ret < 0)
                {
                    tims_error("ERROR while copy userbuffer -> user, "
                               "code = %lu \n", ret);
                }
                else
                {
                    tims_error("ERROR while copy userbuffer -> user, "
                               "only %lu/%lu bytes were copied \n",
                               akt_copy_size - ret, akt_copy_size);
                }
                return ret;
            }

            bytes_in_page -= akt_copy_size;
            copy_bytes    -= akt_copy_size;
            p_src_map     += akt_copy_size;
            p_src         += akt_copy_size;
            p_dest        += akt_copy_size;
            bytes_copied  += akt_copy_size;

            if (!bytes_in_page)
            {
                src_page++;
                if (slot->p_mbx->p_mapInfo[src_page].mapped)
                {
                    p_src_map = slot->p_mbx->p_mapInfo[src_page].virtual;
                }
                else
                {
                    return -EFAULT;
                }
            }