/** * Read from the device * * This function is called when the device is read in real-time context. * */ static ssize_t mpu9150_rtdm_read_rt(struct rtdm_dev_context *context, rtdm_user_info_t * user_info, void *buf, size_t nbyte) { int ret; if( mpu9150_device ) { /* take the semaphore */ rtdm_sem_down( &sem ); mpu9150_read_accel(); mpu9150_read_gyro(); mpu9150_read_mag(); mpu9150_read_temp(); ret = rtdm_safe_copy_to_user(user_info, buf, buffer.data.alldata, DATA_BUFFER_SIZE); /* if an error has occurred, send it to user */ if( ret ) return ret; /* release the semaphore */ rtdm_sem_up( &sem ); } else return 0; return DATA_BUFFER_SIZE; }
int a4l_ioctl_devinfo(a4l_cxt_t * cxt, void *arg) { a4l_dvinfo_t info; a4l_dev_t *dev = a4l_get_dev(cxt); __a4l_dbg(1, core_dbg, "a4l_ioctl_devinfo: minor=%d\n", a4l_get_minor(cxt)); memset(&info, 0, sizeof(a4l_dvinfo_t)); if (test_bit(A4L_DEV_ATTACHED, &dev->flags)) { int len = (strlen(dev->driver->board_name) > A4L_NAMELEN) ? A4L_NAMELEN : strlen(dev->driver->board_name); memcpy(info.board_name, dev->driver->board_name, len); info.nb_subd = dev->transfer.nb_subd; info.idx_read_subd = dev->transfer.idx_read_subd; info.idx_write_subd = dev->transfer.idx_write_subd; } if (rtdm_safe_copy_to_user(cxt->user_info, arg, &info, sizeof(a4l_dvinfo_t)) != 0) return -EFAULT; return 0; }
int tims_clock_ioctl(rtdm_user_info_t *user_info, unsigned int request, void *arg) { rtdm_lockctx_t lock_ctx; nanosecs_rel_t result = 0; switch(clock_sync_mode) { case SYNC_RTNET: sync_dev_ctx->ops->ioctl_rt(sync_dev_ctx, NULL, RTMAC_RTIOC_TIMEOFFSET, &result); break; case SYNC_CAN_SLAVE: case SYNC_SER_SLAVE: rtdm_lock_get_irqsave(&sync_lock, lock_ctx); result = clock_offset; rtdm_lock_put_irqrestore(&sync_lock, lock_ctx); break; } result += sync_delay; if (request == TIMS_RTIOC_GETTIME) result += rtdm_clock_read(); return rtdm_safe_copy_to_user(user_info, arg, &result, sizeof(result)); }
/** * Read from the device * * This function is called when the device is read in non-realtime context. * */ static ssize_t simple_rtdm_read_nrt(struct rtdm_dev_context *context, rtdm_user_info_t * user_info, void *buf, size_t nbyte) { buffer_t * buffer = (buffer_t *) context->dev_private; int size = (buffer->size > nbyte) ? nbyte : buffer->size; buffer->size = 0; if (rtdm_safe_copy_to_user(user_info, buf, buffer->data, size)) rtdm_printk("ERROR : can't copy data from driver\n"); return size; }
int a4l_free_insndsc(a4l_cxt_t * cxt, a4l_kinsn_t * dsc) { int ret = 0; if ((dsc->type & A4L_INSN_MASK_READ) != 0) ret = rtdm_safe_copy_to_user(cxt->user_info, dsc->__udata, dsc->data, dsc->data_size); if (dsc->data != NULL) rtdm_free(dsc->data); return ret; }
static ssize_t uart_rd_rt(struct rtdm_dev_context *context,rtdm_user_info_t * user_info, void *buf,size_t nbyte) { int err; int ret=0; int count; MY_DEV *up=(MY_DEV *)context->device->device_data; u8 *tmp; printk("..............uart_rd_rt start\n"); tmp=(u8 *)rtdm_malloc(nbyte); up->buf_rx=(u8 *)tmp; up->buf_len_rx = nbyte; count =nbyte; if (!(up->ier & UART_IER_RDI)) { up->ier |= UART_IER_RDI; serial_out(up, UART_IER, up->ier); } err=rtdm_event_wait(&up->w_event_rx); if(err<0) { dev_err(up->dev,"controller timed out\n"); rtdm_printk("rtdm_event_timedwait: timeout\n"); return -ETIMEDOUT; } if(err==0) { ret=nbyte; } while(count--) { *tmp=read_buffer(up); printk("Receive rd=%x\n",*tmp); tmp = tmp +1; } tmp=tmp-nbyte; if(rtdm_safe_copy_to_user(user_info,buf,(void *)tmp, nbyte)) rtdm_printk("ERROR : can't copy data from driver\n"); printk("............uart_rd_rt end\n"); rtdm_free(tmp); return ret; }
static int stat_umm(struct rtdm_fd *fd, struct cobalt_umm __user *u_stat) { struct cobalt_memdev_stat stat; struct cobalt_umm *umm; spl_t s; umm = umm_from_fd(fd); if (umm == NULL) return -ENODEV; xnlock_get_irqsave(&umm->heap.lock, s); stat.size = xnheap_get_size(&umm->heap); stat.free = xnheap_get_free(&umm->heap); xnlock_put_irqrestore(&umm->heap.lock, s); return rtdm_safe_copy_to_user(fd, u_stat, &stat, sizeof(stat)); }
static int do_sysmem_ioctls(struct rtdm_fd *fd, unsigned int request, void __user *arg) { struct cobalt_memdev_stat stat; spl_t s; int ret; switch (request) { case MEMDEV_RTIOC_STAT: xnlock_get_irqsave(&cobalt_heap.lock, s); stat.size = xnheap_get_size(&cobalt_heap); stat.free = xnheap_get_free(&cobalt_heap); xnlock_put_irqrestore(&cobalt_heap.lock, s); ret = rtdm_safe_copy_to_user(fd, arg, &stat, sizeof(stat)); break; default: ret = -EINVAL; } return ret; }
int a4l_ioctl_devinfo(a4l_cxt_t * cxt, void *arg) { a4l_dvinfo_t info; a4l_dev_t *dev = a4l_get_dev(cxt); memset(&info, 0, sizeof(a4l_dvinfo_t)); if (test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { int len = (strlen(dev->driver->board_name) > A4L_NAMELEN) ? A4L_NAMELEN : strlen(dev->driver->board_name); memcpy(info.board_name, dev->driver->board_name, len); info.nb_subd = dev->transfer.nb_subd; /* TODO: for API compatibility issue, find the first read subdevice and write subdevice */ } if (rtdm_safe_copy_to_user(cxt->user_info, arg, &info, sizeof(a4l_dvinfo_t)) != 0) return -EFAULT; return 0; }
static int handleIOctl( struct rtdm_dev_context * ctx, rtdm_user_info_t * usr, unsigned int req, void __user * arg) { struct devCtx * devCtx; int retval; retval = 0; devCtx = getDevCtx( ctx); /*-- Set activity: disable communication -------------------------------------*/ rtdm_sem_down( &devCtx->actvLock); switch (req) { /*-- XSPI_IOC_SET_CURRENT_CHN ------------------------------------------------*/ case XSPI_IOC_SET_CURRENT_CHN : { retval = (int)cfgChnSet( ctx, (enum xspiChn)arg); break; } /*-- XSPI_IOC_GET_CURRENT_CHN ------------------------------------------------*/ case XSPI_IOC_GET_CURRENT_CHN : { enum xspiChn chn; cfgChnGet( ctx, &chn); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &chn, sizeof(int)); } else { *(int *)arg = (int)chn; } break; } /*-- XSPI_IOC_SET_FIFO_MODE --------------------------------------------------*/ case XSPI_IOC_SET_FIFO_CHN : { retval = (int)cfgFIFOChnSet( ctx, (enum xspiFifoChn)arg); break; } /*-- XSPI_IOC_GET_FIFO_MODE --------------------------------------------------*/ case XSPI_IOC_GET_FIFO_CHN : { enum xspiFifoChn fifoChn; cfgFIFOChnGet( ctx, &fifoChn); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &fifoChn, sizeof(int)); } else { *(int *)arg = (int)fifoChn; } break; } /*-- XSPI_IOC_SET_CS_MODE ----------------------------------------------------*/ case XSPI_IOC_SET_CS_MODE : { retval = (int)cfgCsModeSet( ctx, (enum xspiCsMode)arg); break; } /*-- XSPI_IOC_GET_CS_MODE ----------------------------------------------------*/ case XSPI_IOC_GET_CS_MODE : { enum xspiCsMode csMode; cfgCsModeGet( ctx, &csMode); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &csMode, sizeof(int)); } else { *(int *)arg = (int)csMode; } break; } /*-- XSPI_IOC_SET_MODE -------------------------------------------------------*/ case XSPI_IOC_SET_MODE : { retval = (int)cfgModeSet( ctx, (enum xspiMode)arg); break; } /*-- XSPI_IOC_GET_MODE -------------------------------------------------------*/ case XSPI_IOC_GET_MODE : { enum xspiMode mode; cfgModeGet( ctx, &mode); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &mode, sizeof(int)); } else { *(int *)arg = (int)mode; } break; } /*-- XSPI_IOC_SET_CHANNEL_MODE -----------------------------------------------*/ case XSPI_IOC_SET_CHANNEL_MODE : { retval = (int)cfgChannelModeSet( ctx, (enum xspiChannelMode)arg); break; } /*-- XSPI_IOC_GET_CHANNEL_MODE -----------------------------------------------*/ case XSPI_IOC_GET_CHANNEL_MODE : { enum xspiChannelMode channelMode; cfgChannelModeGet( ctx, &channelMode); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &channelMode, sizeof(int)); } else { *(int *)arg = (int)channelMode; } break; } /*-- XSPI_IOC_SET_INITIAL_DELAY ----------------------------------------------*/ case XSPI_IOC_SET_INITIAL_DELAY : { retval = (int)cfgInitialDelaySet( ctx, (enum xspiInitialDelay)arg); break; } /*-- XSPI_IOC_GET_INITIAL_DELAY ----------------------------------------------*/ case XSPI_IOC_GET_INITIAL_DELAY : { enum xspiInitialDelay initialDelay; cfgInitialDelayGet( ctx, &initialDelay); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &initialDelay, sizeof(int)); } else { *(int *)arg = (int)initialDelay; } break; } /*-- XSPI_IOC_SET_TRANSFER_MODE ----------------------------------------------*/ case XSPI_IOC_SET_TRANSFER_MODE : { retval = (int)cfgChnTransferModeSet( ctx, (enum xspiTransferMode)arg); break; } /*-- XSPI_IOC_GET_TRANSFER_MODE ----------------------------------------------*/ case XSPI_IOC_GET_TRANSFER_MODE : { enum xspiTransferMode transferMode; cfgChnTransferModeGet( ctx, &transferMode); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &transferMode, sizeof(int)); } else { *(int *)arg = (int)transferMode; } break; } /*-- XSPI_IOC_SET_PIN_LAYOUT -------------------------------------------------*/ case XSPI_IOC_SET_PIN_LAYOUT : { retval = (int)cfgChnPinLayoutSet( ctx, (enum xspiPinLayout)arg); break; } /*-- XSPI_IOC_GET_PIN_LAYOUT -------------------------------------------------*/ case XSPI_IOC_GET_PIN_LAYOUT : { enum xspiPinLayout pinLayout; cfgChnPinLayoutGet( ctx, &pinLayout); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &pinLayout, sizeof(int)); } else { *(int *)arg = (int)pinLayout; } break; } /*-- XSPI_IOC_SET_WORD_LENGTH ------------------------------------------------*/ case XSPI_IOC_SET_WORD_LENGTH : { retval = (int)cfgChnWordLengthSet( ctx, (uint32_t)arg); break; } /*-- XSPI_IOC_GET_WORD_LENGTH ------------------------------------------------*/ case XSPI_IOC_GET_WORD_LENGTH : { uint32_t wordLength; cfgChnWordLengthGet( ctx, &wordLength); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &wordLength, sizeof(int)); } else { *(int *)arg = (int)wordLength; } break; } /*-- XSPI_IOC_SET_CS_DELAY ---------------------------------------------------*/ case XSPI_IOC_SET_CS_DELAY : { retval = (int)cfgChnCsDelaySet( ctx, (enum xspiCsDelay)arg); break; } /*-- XSPI_IOC_GET_CS_DELAY ---------------------------------------------------*/ case XSPI_IOC_GET_CS_DELAY : { enum xspiCsDelay csDelay; cfgChnCsDelayGet( ctx, &csDelay); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &csDelay, sizeof(int)); } else { *(int *)arg = (int)csDelay; } break; } /*-- XSPI_IOC_SET_CS_POLARITY ------------------------------------------------*/ case XSPI_IOC_SET_CS_POLARITY : { retval = (int)cfgChnCsPolaritySet( ctx, (enum xspiCsPolarity)arg); break; } /*-- XSPI_IOC_GET_CS_POLARITY ------------------------------------------------*/ case XSPI_IOC_GET_CS_POLARITY : { enum xspiCsPolarity csPolarity; cfgChnCsPolarityGet( ctx, &csPolarity); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &csPolarity, sizeof(int)); } else { *(int *)arg = (int)csPolarity; } break; } /*-- XSPI_IOC_SET_CS_STATE ---------------------------------------------------*/ case XSPI_IOC_SET_CS_STATE : { retval = (int)cfgChnCsStateSet( ctx, (enum xspiCsState)arg); break; } /*-- XSPI_IOC_GET_CS_STATE ---------------------------------------------------*/ case XSPI_IOC_GET_CS_STATE : { enum xspiCsState csState; cfgChnCsStateGet( ctx, &csState); if (NULL != usr) { retval = rtdm_safe_copy_to_user( usr, arg, &csState, sizeof(int)); } else { *(int *)arg = (int)csState; } break; } /*-- XSPI_IOC_SET_CLOCK_FREQ -------------------------------------------------*/ case XSPI_IOC_SET_CLOCK_FREQ : { } /*-- XSPI_IOC_GET_CLOCK_FREQ -------------------------------------------------*/ case XSPI_IOC_GET_CLOCK_FREQ : { } /*-- Unhandled request -------------------------------------------------------*/ default : { LOG_DBG("IOC: unknown request (%d) received", req); retval = -EINVAL; } } if (0 != retval) { LOG_INFO("IOC: failed to execute IO request, err: %d", -retval); } /*-- Reset activity: enable communication ------------------------------------*/ rtdm_sem_up( &devCtx->actvLock); return (retval); }
int a4l_ioctl_cmd(struct a4l_device_context * ctx, void *arg) { int ret = 0, simul_flag = 0; struct a4l_cmd_desc *cmd_desc = NULL; struct a4l_device *dev = a4l_get_dev(ctx); unsigned int *chan_descs, *tmp; struct a4l_subdevice *subd; /* The command launching cannot be done in real-time because of some possible buffer allocations in the drivers */ if (rtdm_in_rt_context()) return -ENOSYS; /* Basically check the device */ if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { __a4l_err("a4l_ioctl_cmd: cannot command " "an unattached device\n"); return -EINVAL; } /* Allocates the command */ cmd_desc = (struct a4l_cmd_desc *) rtdm_malloc(sizeof(struct a4l_cmd_desc)); if (cmd_desc == NULL) return -ENOMEM; memset(cmd_desc, 0, sizeof(struct a4l_cmd_desc)); /* Gets the command */ ret = a4l_fill_cmddesc(ctx, cmd_desc, &chan_descs, arg); if (ret != 0) goto out_ioctl_cmd; /* Checks the command */ ret = a4l_check_cmddesc(ctx, cmd_desc); if (ret != 0) goto out_ioctl_cmd; ret = a4l_check_generic_cmdcnt(cmd_desc); if (ret != 0) goto out_ioctl_cmd; ret = a4l_check_specific_cmdcnt(ctx, cmd_desc); if (ret != 0) goto out_ioctl_cmd; __a4l_dbg(1, core_dbg,"1st cmd checks passed\n"); subd = dev->transfer.subds[cmd_desc->idx_subd]; /* Tests the command with the cmdtest function */ if (cmd_desc->flags & A4L_CMD_SIMUL) { simul_flag = 1; if (!subd->do_cmdtest) { __a4l_err("a4l_ioctl_cmd: driver's cmd_test NULL\n"); ret = -EINVAL; goto out_ioctl_cmd; } ret = subd->do_cmdtest(subd, cmd_desc); if (ret != 0) { __a4l_err("a4l_ioctl_cmd: driver's cmd_test failed\n"); goto out_ioctl_cmd; } __a4l_dbg(1, core_dbg, "driver's cmd checks passed\n"); goto out_ioctl_cmd; } /* Gets the transfer system ready */ ret = a4l_setup_buffer(ctx, cmd_desc); if (ret < 0) goto out_ioctl_cmd; /* Eventually launches the command */ ret = subd->do_cmd(subd, cmd_desc); if (ret != 0) { a4l_cancel_buffer(ctx); goto out_ioctl_cmd; } out_ioctl_cmd: if (simul_flag) { /* copy the kernel based descriptor */ tmp = cmd_desc->chan_descs; /* return the user based descriptor */ cmd_desc->chan_descs = chan_descs; rtdm_safe_copy_to_user(rtdm_private_to_fd(ctx), arg, cmd_desc, sizeof(struct a4l_cmd_desc)); /* make sure we release the memory associated to the kernel */ cmd_desc->chan_descs = tmp; } if (ret != 0 || simul_flag == 1) { a4l_free_cmddesc(cmd_desc); rtdm_free(cmd_desc); } return ret; }
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; }