Ejemplo n.º 1
0
/* --- Command descriptor management functions --- */
int a4l_fill_cmddesc(struct a4l_device_context *cxt, struct a4l_cmd_desc *desc,
                     unsigned int **chan_descs, void *arg)
{
    unsigned int *tmpchans = NULL;
    int ret = 0;

    ret = rtdm_safe_copy_from_user(rtdm_private_to_fd(cxt),
                                   desc, arg, sizeof(struct a4l_cmd_desc));
    if (ret != 0)
        goto out_cmddesc;


    if (desc->nb_chan == 0) {
        ret = -EINVAL;
        goto out_cmddesc;
    }

    tmpchans = rtdm_malloc(desc->nb_chan * sizeof(unsigned int));
    if (tmpchans == NULL) {
        ret = -ENOMEM;
        goto out_cmddesc;
    }

    ret = rtdm_safe_copy_from_user(rtdm_private_to_fd(cxt),
                                   tmpchans,
                                   desc->chan_descs,
                                   desc->nb_chan * sizeof(unsigned int));
    if (ret != 0) {
        __a4l_err("%s invalid arguments \n", __FUNCTION__);
        goto out_cmddesc;
    }

    *chan_descs = desc->chan_descs;
    desc->chan_descs = tmpchans;

    __a4l_dbg(1, core_dbg, "desc dump: \n");
    __a4l_dbg(1, core_dbg, "\t->idx_subd=%u\n", desc->idx_subd);
    __a4l_dbg(1, core_dbg, "\t->flags=%lu\n", desc->flags);
    __a4l_dbg(1, core_dbg, "\t->nb_chan=%u\n", desc->nb_chan);
    __a4l_dbg(1, core_dbg, "\t->chan_descs=0x%x\n", *desc->chan_descs);
    __a4l_dbg(1, core_dbg, "\t->data_len=%u\n", desc->data_len);
    __a4l_dbg(1, core_dbg, "\t->pdata=0x%p\n", desc->data);

out_cmddesc:

    if (ret != 0) {
        __a4l_err("a4l_fill_cmddesc: %d \n", ret);
        if (tmpchans != NULL)
            rtdm_free(tmpchans);
        desc->chan_descs = NULL;
    }

    return ret;
}
Ejemplo n.º 2
0
int a4l_fill_insndsc(a4l_cxt_t * cxt, a4l_kinsn_t * dsc, void *arg)
{
	int ret = 0;
	void *tmp_data = NULL;

	ret = rtdm_safe_copy_from_user(cxt->user_info, 
				       dsc, arg, sizeof(a4l_insn_t));
	if (ret != 0)
		goto out_insndsc;

	if (dsc->data_size != 0 && dsc->data == NULL) {
		__a4l_err("a4l_fill_insndsc: no data pointer specified\n");
		ret = -EINVAL;
		goto out_insndsc;
	}

	if (dsc->data_size != 0 && dsc->data != NULL) {
		tmp_data = rtdm_malloc(dsc->data_size);
		if (tmp_data == NULL) {
			ret = -ENOMEM;
			goto out_insndsc;
		}

		if ((dsc->type & A4L_INSN_MASK_WRITE) != 0) {
			ret = rtdm_safe_copy_from_user(cxt->user_info,
						       tmp_data, dsc->data,
						       dsc->data_size);
			if (ret < 0)
				goto out_insndsc;
		}
	}

	dsc->__udata = dsc->data;
	dsc->data = tmp_data;

out_insndsc:

	if (ret != 0 && tmp_data != NULL)
		rtdm_free(tmp_data);

	return ret;
}
Ejemplo n.º 3
0
/**
 * Write in the device
 *
 * This function is called when the device is written in non-realtime context.
 *
 */
static ssize_t simple_rtdm_write_nrt(struct rtdm_dev_context *context,
                                     rtdm_user_info_t * user_info,
                                     const void *buf, size_t nbyte)
{
    buffer_t * buffer = (buffer_t *) context->dev_private;

    buffer->size = (nbyte > SIZE_MAX) ? SIZE_MAX : nbyte;
    if (rtdm_safe_copy_from_user(user_info, buffer->data, buf, buffer->size))
        rtdm_printk("ERROR : can't copy data to driver\n");

    return nbyte;
}
Ejemplo n.º 4
0
int a4l_fill_ilstdsc(a4l_cxt_t * cxt, a4l_kilst_t * dsc, void *arg)
{
	int i, ret = 0;

	dsc->insns = NULL;

	/* Recovers the structure from user space */
	ret = rtdm_safe_copy_from_user(cxt->user_info, 
				       dsc, arg, sizeof(a4l_insnlst_t));
	if (ret < 0)
		return ret;

	/* Some basic checking */
	if (dsc->count == 0) {
		__a4l_err("a4l_fill_ilstdsc: instruction list's count is 0\n");
		return -EINVAL;
	}

	/* Keeps the user pointer in an opaque field */
	dsc->__uinsns = (a4l_insn_t *)dsc->insns;

	dsc->insns = rtdm_malloc(dsc->count * sizeof(a4l_kinsn_t));
	if (dsc->insns == NULL)
		return -ENOMEM;

	/* Recovers the instructions, one by one. This part is not 
	   optimized */
	for (i = 0; i < dsc->count && ret == 0; i++)
		ret = a4l_fill_insndsc(cxt,
				       &(dsc->insns[i]),
				       &(dsc->__uinsns[i]));

	/* In case of error, frees the allocated memory */
	if (ret < 0 && dsc->insns != NULL)
		rtdm_free(dsc->insns);

	return ret;
}
Ejemplo n.º 5
0
static ssize_t uart_wr_rt(struct rtdm_dev_context *context,rtdm_user_info_t * user_info,const void *buf, size_t nbyte)
{
	int ret=0;
	int err;	
	int count;
	char c;

	MY_DEV *up=(MY_DEV *)context->device->device_data;
	
	char *tmp;
	up->buf_len_tx = nbyte;
	
	printk("uart_wr_rt  start\n");
	tmp=rtdm_malloc(nbyte);
	
	if ((rtdm_safe_copy_from_user(user_info,tmp, buf, up->buf_len_tx)))
                rtdm_printk("ERROR : can't copy data to driver\n");
	

	 count=nbyte;
	while(count--)
	{
	write_buffer(up,*tmp);
	tmp=tmp+1;
	
//	up->buf_tx=(char *)tmp;
//	printk("up->buf_tx=%x\n",*up->buf_tx);
			
	//enable Trasmitter holding Register
	if (!(up->ier & UART_IER_THRI)) 
	{
		up->ier |= UART_IER_THRI;
		 up->systime = rtdm_clock_read();
		serial_out(up, UART_IER, up->ier);
	}

	}

	printk("Tx interrupt enable\n");
	printk("rtdm_event_wait before\n");

	err=rtdm_event_wait(&up->w_event_tx);
        if(err<0)
        {
                dev_err(up->dev,"controller timed out\n");
                rtdm_printk("rtdm_event_timedwait: timeout\n");
                return -ETIMEDOUT;
        }

	up->systime1 = rtdm_clock_read();

	up->timeout=(up->systime1)-(up->systime);

	printk("scheduling latency=%ld\n",up->timeout);

	if(err==0)
	{
	 	ret=nbyte;
	}
	printk("rtdm_event_wait after\n");
	printk("uart_wr_rt end\n");
	rtdm_free(tmp);
	return ret;
}
Ejemplo n.º 6
0
int a4l_fill_lnkdesc(a4l_cxt_t * cxt,
		     a4l_lnkdesc_t * link_arg, void *arg)
{
	int ret;
	char *tmpname = NULL;
	void *tmpopts = NULL;

	ret = rtdm_safe_copy_from_user(cxt->user_info,
				       link_arg, arg, sizeof(a4l_lnkdesc_t));
	if (ret != 0) {
		__a4l_err("a4l_fill_lnkdesc: "
			  "call1(copy_from_user) failed\n");
		goto out_get_lnkdesc;
	}

	if (link_arg->bname_size != 0 && link_arg->bname != NULL) {
		tmpname = rtdm_malloc(link_arg->bname_size + 1);
		if (tmpname == NULL) {
			__a4l_err("a4l_fill_lnkdesc: "
				  "call1(alloc) failed\n");
			ret = -ENOMEM;
			goto out_get_lnkdesc;
		}
		tmpname[link_arg->bname_size] = 0;

		ret = rtdm_safe_copy_from_user(cxt->user_info,
					       tmpname,
					       link_arg->bname,
					       link_arg->bname_size);
		if (ret != 0) {
			__a4l_err("a4l_fill_lnkdesc: "
				  "call2(copy_from_user) failed\n");
			goto out_get_lnkdesc;
		}
	} else {
		__a4l_err("a4l_fill_lnkdesc: board name missing\n");
		ret = -EINVAL;
		goto out_get_lnkdesc;
	}

	if (link_arg->opts_size != 0 && link_arg->opts != NULL) {
		tmpopts = rtdm_malloc(link_arg->opts_size);

		if (tmpopts == NULL) {
			__a4l_err("a4l_fill_lnkdesc: "
				  "call2(alloc) failed\n");
			ret = -ENOMEM;
			goto out_get_lnkdesc;
		}

		ret = rtdm_safe_copy_from_user(cxt->user_info,
					       tmpopts,
					       link_arg->opts,
					       link_arg->opts_size);
		if (ret != 0) {
			__a4l_err("a4l_fill_lnkdesc: "
				  "call3(copy_from_user) failed\n");
			goto out_get_lnkdesc;
		}
	}

	link_arg->bname = tmpname;
	link_arg->opts = tmpopts;

      out_get_lnkdesc:

	if (tmpname == NULL) {
		link_arg->bname = NULL;
		link_arg->bname_size = 0;
	}

	if (tmpopts == NULL) {
		link_arg->opts = NULL;
		link_arg->opts_size = 0;
	}

	return ret;
}
Ejemplo n.º 7
0
static int rtdmtest_ioctl(struct rtdm_dev_context *context,
			  rtdm_user_info_t *user_info,
			  unsigned int request,
			  void *arg)
{
	struct rtdmtest_context *ctx;
	struct rttst_rtdmtest_config config_buf, *config;
	rtdm_toseq_t toseq_local, *toseq = NULL;
	int i, err = 0;

	ctx = (struct rtdmtest_context *)context->dev_private;

	switch (request) {
	case RTTST_RTIOC_RTDMTEST_SEM_TIMEDDOWN:
	case RTTST_RTIOC_RTDMTEST_EVENT_TIMEDWAIT:
        case RTTST_RTIOC_RTDMTEST_MUTEX_TIMEDTEST:
        case RTTST_RTIOC_RTDMTEST_MUTEX_TEST:
		config = arg;
		if (user_info) {
			if (rtdm_safe_copy_from_user
			    (user_info, &config_buf, arg,
			     sizeof(struct rttst_rtdmtest_config)) < 0)
				return -EFAULT;

			config = &config_buf;
		}
		if (!config->seqcount)
			config->seqcount = 1;
		if (config->timeout && config->seqcount > 1) {
			toseq = &toseq_local;
			rtdm_toseq_init(toseq, config->timeout);
		}
		switch(request) {
		case RTTST_RTIOC_RTDMTEST_SEM_TIMEDDOWN:
			for (i = 0; i < config->seqcount; i++) {
				err = rtdm_sem_timeddown(&ctx->sem,
							 config->timeout,
							 toseq);
				if (err)
					break;
			}
			break;
		case RTTST_RTIOC_RTDMTEST_EVENT_TIMEDWAIT:
			for (i = 0; i < config->seqcount; i++) {
				err = rtdm_event_timedwait(&ctx->event,
							   config->timeout,
							   toseq);
				if (err)
					break;
			}
			break;
		case RTTST_RTIOC_RTDMTEST_MUTEX_TIMEDTEST:
			for (i = 0; i < config->seqcount; i++) {
				err = rtdm_mutex_timedlock(&ctx->mutex,
							   config->timeout,
							   toseq);
				if (err)
					break;
				if (config->delay_jiffies) {
					__set_current_state(TASK_INTERRUPTIBLE);
					schedule_timeout(config->delay_jiffies);
				}
				rtdm_lock_count++;
				rtdm_mutex_unlock(&ctx->mutex);
			}
			break;
		case RTTST_RTIOC_RTDMTEST_MUTEX_TEST:
			for (i = 0; i < config->seqcount; i++) {
				if ((err = rtdm_mutex_lock(&ctx->mutex)))
					break;
				rtdm_lock_count++;
				rtdm_mutex_unlock(&ctx->mutex);
			}
			break;
		}
		break;

	case RTTST_RTIOC_RTDMTEST_SEM_DOWN:
		err = rtdm_sem_down(&ctx->sem);
		break;

	case RTTST_RTIOC_RTDMTEST_SEM_UP:
		rtdm_sem_up(&ctx->sem);
		break;

        case RTTST_RTIOC_RTDMTEST_SEM_DESTROY:
                rtdm_sem_destroy(&ctx->sem);
                break;

	case RTTST_RTIOC_RTDMTEST_EVENT_WAIT:
		err = rtdm_event_wait(&ctx->event);
		break;

	case RTTST_RTIOC_RTDMTEST_EVENT_SIGNAL:
		rtdm_event_signal(&ctx->event);
		break;

        case RTTST_RTIOC_RTDMTEST_EVENT_DESTROY:
                rtdm_event_destroy(&ctx->event);
                break;

        case RTTST_RTIOC_RTDMTEST_MUTEX_DESTROY:
                rtdm_mutex_destroy(&ctx->mutex);
                break;

        case RTTST_RTIOC_RTDMTEST_MUTEX_GETSTAT:
		printk("RTTST_RTIOC_RTDMTEST_MUTEX_GETSTAT\n");
		if (user_info)
			config = &config_buf;
		else
			config = arg;
		config->seqcount = rtdm_lock_count;
		if (user_info) {
			if (rtdm_safe_copy_to_user
			    (user_info, arg, &config_buf,
			     sizeof(struct rttst_rtdmtest_config)) < 0)
				return -EFAULT;
		}
                break;

        case RTTST_RTIOC_RTDMTEST_NRTSIG_PEND:
		rtdm_nrtsig_pend(&ctx->nrtsig);
                break;

        case RTTST_RTIOC_RTDMTEST_TASK_CREATE:
        case RTTST_RTIOC_RTDMTEST_TASK_SET_PRIO:
                config = arg;
                if (user_info) {
                        if (rtdm_safe_copy_from_user
                            (user_info, &config_buf, arg,
                             sizeof(struct rttst_rtdmtest_config)) < 0)
                                return -EFAULT;

                        config = &config_buf;
                }
		if (request == RTTST_RTIOC_RTDMTEST_TASK_CREATE) {
			task_period = config->timeout;
			rtdm_task_init(&task, "RTDMTEST",
				       rtdmtest_task, (void *)config,
				       config->priority, 0);
		} else {
			rtdm_task_set_priority(&task, config->priority);
		}
		break;

        case RTTST_RTIOC_RTDMTEST_TASK_DESTROY:
		rtdm_task_destroy(&task);
		rtdm_task_join_nrt(&task, 100);
                break;

	default:
		printk("request=%d\n", request);
		err = -ENOTTY;
	}

	return err;
}