int __init rtcfg_init_frames(void) { int ret; if (rtskb_pool_init(&rtcfg_pool, num_rtskbs) < num_rtskbs) return -ENOMEM; rtskb_queue_init(&rx_queue); rtdm_event_init(&rx_event, 0); ret = rtdm_task_init(&rx_task, "rtcfg-rx", rtcfg_rx_task, 0, RTDM_TASK_LOWEST_PRIORITY, 0); if (ret < 0) { rtdm_event_destroy(&rx_event); goto error1; } ret = rtdev_add_pack(&rtcfg_packet_type); if (ret < 0) goto error2; return 0; error2: rtdm_event_destroy(&rx_event); rtdm_task_join_nrt(&rx_task, 100); error1: rtskb_pool_release(&rtcfg_pool); return ret; }
static int rtdmtest_close(struct rtdm_dev_context *context, rtdm_user_info_t *user_info) { struct rtdmtest_context *ctx; ctx = (struct rtdmtest_context *)context->dev_private; printk("%s state=%#lx\n", __FUNCTION__, ctx->event.state); down(&ctx->nrt_mutex); rtdm_event_destroy(&ctx->event); rtdm_sem_destroy(&ctx->sem); rtdm_mutex_destroy(&ctx->mutex); up(&ctx->nrt_mutex); return 0; }
int demo_close_rt(struct rtdm_dev_context *context, rtdm_user_info_t *user_info) { struct demodrv_context *my_context; rtdm_lockctx_t lock_ctx; #ifdef USEMMAP unsigned long vaddr; #endif // get the context my_context = (struct demodrv_context *)context->dev_private; #ifdef USEMMAP // printk some test value printk("%d\n", *((int *)my_context->buf + 10)); // munmap our buffer if (my_context->mapped_user_addr) { int ret = rtdm_munmap(my_context->mapped_user_info, my_context->mapped_user_addr, BUFFER_SIZE); printk("rtdm_munmap = %p, %d\n", my_context->mapped_user_info, ret); } /* clear pages reserved */ for (vaddr = (unsigned long)my_context->buf; vaddr < (unsigned long)my_context->buf + BUFFER_SIZE; vaddr += PAGE_SIZE) ClearPageReserved(virt_to_page(vaddr)); kfree(my_context->buf); #endif // if we need to do some stuff with preemption disabled: rtdm_lock_get_irqsave(&my_context->lock, lock_ctx); // other stuff here rtdm_lock_put_irqrestore(&my_context->lock, lock_ctx); // free irq in RTDM rtdm_irq_free(&my_context->irq_handle); // destroy our interrupt signal/event rtdm_event_destroy(&my_context->irq_event); return 0; }
void rtcfg_cleanup_frames(void) { struct rtskb *rtskb; while (rtdev_remove_pack(&rtcfg_packet_type) == -EAGAIN) { RTCFG_DEBUG(3, "RTcfg: waiting for protocol unregistration\n"); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1*HZ); /* wait a second */ } rtdm_event_destroy(&rx_event); rtdm_task_join_nrt(&rx_task, 100); while ((rtskb = rtskb_dequeue(&rx_queue)) != NULL) { rtdev_dereference(rtskb->rtdev); kfree_rtskb(rtskb); } rtskb_pool_release(&rtcfg_pool); }
static int rtswitch_close(struct rtdm_dev_context *context, rtdm_user_info_t *user_info) { rtswitch_context_t *ctx = (rtswitch_context_t *) context->dev_private; unsigned i; if (ctx->tasks) { set_cpus_allowed(current, cpumask_of_cpu(ctx->cpu)); for (i = 0; i < ctx->next_index; i++) { rtswitch_task_t *task = &ctx->tasks[i]; if (task->base.flags & RTSWITCH_KERNEL) xnpod_delete_thread(&task->ktask); rtdm_event_destroy(&task->rt_synch); } kfree(ctx->tasks); } rtdm_timer_destroy(&ctx->wake_up_delay); return 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; }