static int __ui_twai_flg(struct pt_regs *regs) { UINT flgptn, waiptn, wfmode; TMO tmout; ID flgid; ER err; flgid = __xn_reg_arg2(regs); waiptn = __xn_reg_arg3(regs); wfmode = __xn_reg_arg4(regs); tmout = __xn_reg_arg5(regs); err = twai_flg(&flgptn, flgid, waiptn, wfmode, tmout); if (err == E_OK) { if (__xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &flgptn, sizeof(flgptn))) return -EFAULT; } else if (err == E_RLWAI) { uitask_t *task = ui_current_task(); if (!xnthread_test_info(&task->threadbase, uITRON_TASK_RLWAIT)) err = -EINTR; } return err; }
static int __wind_msgq_receive(struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); char tmp_buf[128], *msgbuf; wind_msgq_t *msgq; int timeout, err; unsigned nbytes; nbytes = __xn_reg_arg3(regs); timeout = __xn_reg_arg4(regs); msgq = (wind_msgq_t *)xnregistry_fetch(handle); if (!msgq) return S_objLib_OBJ_ID_ERROR; if (nbytes <= sizeof(tmp_buf)) msgbuf = tmp_buf; else { msgbuf = (char *)xnmalloc(nbytes); if (!msgbuf) return S_memLib_NOT_ENOUGH_MEMORY; } /* This is sub-optimal since we end up copying the data twice. */ err = msgQReceive((MSG_Q_ID)msgq, msgbuf, nbytes, timeout); if (err != ERROR) { if (__xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), msgbuf, err) || __xn_safe_copy_to_user((void __user *)__xn_reg_arg5(regs), &err, sizeof(err))) err = -EFAULT; else err = 0; } else err = wind_errnoget(); if (msgbuf != tmp_buf) xnfree(msgbuf); return err; }
static int __wind_tick_get(struct pt_regs *regs) { ULONG ticks; ticks = tickGet(); return __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &ticks, sizeof(ticks)); }
static int __wind_wd_wait(struct pt_regs *regs) { union xnsched_policy_param param; xnholder_t *holder; wind_rholder_t *rh; WIND_TCB *pTcb; wind_wd_t *wd; int err = 0; spl_t s; rh = wind_get_rholder(); xnlock_get_irqsave(&nklock, s); pTcb = __wind_task_current(current); if (xnthread_base_priority(&pTcb->threadbase) != XNSCHED_IRQ_PRIO) { /* Boost the waiter above all regular tasks if needed. */ param.rt.prio = XNSCHED_IRQ_PRIO; xnpod_set_thread_schedparam(&pTcb->threadbase, &xnsched_class_rt, ¶m); } if (!emptyq_p(&rh->wdpending)) goto pull_event; xnsynch_sleep_on(&rh->wdsynch, XN_INFINITE, XN_RELATIVE); if (xnthread_test_info(&pTcb->threadbase, XNBREAK)) { err = -EINTR; /* Unblocked. */ goto unlock_and_exit; } if (xnthread_test_info(&pTcb->threadbase, XNRMID)) { err = -EIDRM; /* Watchdog deleted while pending. */ goto unlock_and_exit; } pull_event: holder = getq(&rh->wdpending); if (holder) { wd = link2wind_wd(holder); /* We need the following to mark the watchdog as unqueued. */ inith(holder); xnlock_put_irqrestore(&nklock, s); return __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &wd->wdt, sizeof(wd->wdt)); } unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }
static int __wind_taskinfo_iddfl(struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); TASK_ID ret_id; ret_id = taskIdDefault(handle); return __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), &ret_id, sizeof(ret_id)); }
int cobalt_mutexattr_init(pthread_mutexattr_t __user *u_attr) { pthread_mutexattr_t attr; int err; err = pthread_mutexattr_init(&attr); if (err) return -err; return __xn_safe_copy_to_user(u_attr, &attr, sizeof(*u_attr)); }
int cobalt_mutexattr_destroy(pthread_mutexattr_t __user *u_attr) { pthread_mutexattr_t attr; int err; if (__xn_safe_copy_from_user(&attr, u_attr, sizeof(attr))) return -EFAULT; err = pthread_mutexattr_destroy(&attr); if (err) return -err; return __xn_safe_copy_to_user(u_attr, &attr, sizeof(*u_attr)); }
static int __ui_get_tid(struct pt_regs *regs) { ID tskid; ER err; err = get_tid(&tskid); if (err == E_OK && __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &tskid, sizeof(tskid))) return -EFAULT; return err; }
int cobalt_mutexattr_getpshared(const pthread_mutexattr_t __user *u_attr, int __user *u_pshared) { pthread_mutexattr_t attr; int err, pshared; if (__xn_safe_copy_from_user(&attr, u_attr, sizeof(attr))) return -EFAULT; err = pthread_mutexattr_getpshared(&attr, &pshared); if (err) return -err; return __xn_safe_copy_to_user(u_pshared, &pshared, sizeof(*u_pshared)); }
static int __ui_ref_sem(struct pt_regs *regs) { ID semid = __xn_reg_arg2(regs); T_RSEM pk_rsem; ER err; err = ref_sem(&pk_rsem, semid); if (err == E_OK && __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &pk_rsem, sizeof(pk_rsem))) return -EFAULT; return err; }
static int __ui_prcv_msg(struct pt_regs *regs) { ID mbxid = __xn_reg_arg2(regs); T_MSG *pk_msg; ER err; err = prcv_msg(&pk_msg, mbxid); if (err == E_OK && __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &pk_msg, sizeof(pk_msg))) return -EFAULT; return err; }
static int __ui_ref_tsk(struct pt_regs *regs) { ID tskid = __xn_reg_arg2(regs); T_RTSK pk_rtsk; ER err; err = ref_tsk(&pk_rtsk, tskid); if (err == E_OK && __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &pk_rtsk, sizeof(pk_rtsk))) return -EFAULT; return err; }
static int __ui_can_wup(struct pt_regs *regs) { ID tskid = __xn_reg_arg2(regs); INT wupcnt; ER err; err = can_wup(&wupcnt, tskid); if (err == E_OK && __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &wupcnt, sizeof(wupcnt))) return -EFAULT; return err; }
static int __wind_wd_create(struct pt_regs *regs) { WDOG_ID wdog_id; wind_wd_t *wd; wd = (wind_wd_t *)wdCreate(); if (!wd) return wind_errnoget(); wdog_id = wd->handle; return __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &wdog_id, sizeof(wdog_id)); }
static int __ui_ref_mbx(struct pt_regs *regs) { ID mbxid = __xn_reg_arg2(regs); T_RMBX pk_rmbx; ER err; err = ref_mbx(&pk_rmbx, mbxid); if (err == E_OK && __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &pk_rmbx, sizeof(pk_rmbx))) return -EFAULT; return err; }
int cobalt_mutexattr_gettype(const pthread_mutexattr_t __user *u_attr, int __user *u_type) { pthread_mutexattr_t attr; int err, type; if (__xn_safe_copy_from_user(&attr, u_attr, sizeof(attr))) return -EFAULT; err = pthread_mutexattr_gettype(&attr, &type); if (err) return -err; return __xn_safe_copy_to_user(u_type, &type, sizeof(*u_type)); }
int cobalt_mutexattr_setprotocol(pthread_mutexattr_t __user *u_attr, int proto) { pthread_mutexattr_t attr; int err; if (__xn_safe_copy_from_user(&attr, u_attr, sizeof(attr))) return -EFAULT; err = pthread_mutexattr_setprotocol(&attr, proto); if (err) return -err; return __xn_safe_copy_to_user(u_attr, &attr, sizeof(*u_attr)); }
static int __ui_ref_flg(struct pt_regs *regs) { ID flgid = __xn_reg_arg2(regs); T_RFLG pk_rflg; ER err; err = ref_flg(&pk_rflg, flgid); if (err == E_OK && __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &pk_rflg, sizeof(pk_rflg))) return -EFAULT; return err; }
static int __wind_task_self(struct pt_regs *regs) { WIND_TCB_PLACEHOLDER ph; WIND_TCB *pTcb; pTcb = __wind_task_current(current); if (!pTcb) /* Calls on behalf of a non-task context beget an error for the user-space interface. */ return S_objLib_OBJ_ID_ERROR; ph.handle = xnthread_handle(&pTcb->threadbase); /* Copy back the task handle. */ return __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &ph, sizeof(ph)); }
static int __wind_sem_mcreate(struct pt_regs *regs) { wind_sem_t *sem; SEM_ID sem_id; int flags; flags = __xn_reg_arg1(regs); sem = (wind_sem_t *)semMCreate(flags); if (!sem) return wind_errnoget(); sem_id = sem->handle; return __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), &sem_id, sizeof(sem_id)); }
static int __wind_wd_start(struct pt_regs *regs) { wind_rholder_t *rh; long start_server; xnhandle_t handle; wind_wd_t *wd; int timeout; spl_t s; handle = __xn_reg_arg1(regs); wd = (wind_wd_t *)xnregistry_fetch(handle); if (!wd) return S_objLib_OBJ_ID_ERROR; rh = wind_get_rholder(); if (wd->rh != rh) /* * User may not fiddle with watchdogs created from * other processes. */ return S_objLib_OBJ_UNAVAILABLE; timeout = __xn_reg_arg2(regs); xnlock_get_irqsave(&nklock, s); if (wdStart ((WDOG_ID)wd, timeout, (wind_timer_t) & __wind_wd_handler, (long)wd) == ERROR) { xnlock_put_irqrestore(&nklock, s); return wind_errnoget(); } wd->wdt.handler = (wind_timer_t) __xn_reg_arg3(regs); wd->wdt.arg = (long)__xn_reg_arg4(regs); start_server = rh->wdcount++ == 0; xnlock_put_irqrestore(&nklock, s); return __xn_safe_copy_to_user((void __user *)__xn_reg_arg5(regs), &start_server, sizeof(start_server)); }
static int __wind_msgq_nummsgs(struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); wind_msgq_t *msgq; int nummsgs; msgq = (wind_msgq_t *)xnregistry_fetch(handle); if (!msgq) return S_objLib_OBJ_ID_ERROR; nummsgs = msgQNumMsgs((MSG_Q_ID)msgq); if (nummsgs == ERROR) return wind_errnoget(); return __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), &nummsgs, sizeof(nummsgs)); }
static int __wind_msgq_create(struct pt_regs *regs) { int nb_msgs, length, flags; wind_msgq_t *msgq; MSG_Q_ID qid; nb_msgs = __xn_reg_arg1(regs); length = __xn_reg_arg2(regs); flags = __xn_reg_arg3(regs); msgq = (wind_msgq_t *)msgQCreate(nb_msgs, length, flags); if (!msgq) return wind_errnoget(); qid = msgq->handle; return __xn_safe_copy_to_user((void __user *)__xn_reg_arg4(regs), &qid, sizeof(qid)); }
static int __ui_pol_flg(struct pt_regs *regs) { UINT flgptn, waiptn, wfmode; ID flgid; ER err; flgid = __xn_reg_arg2(regs); waiptn = __xn_reg_arg3(regs); wfmode = __xn_reg_arg4(regs); err = pol_flg(&flgptn, flgid, waiptn, wfmode); if (err == E_OK && __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &flgptn, sizeof(flgptn))) return -EFAULT; return err; }
static int __wind_task_priorityget(struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); WIND_TCB *pTcb; int prio; if (handle) pTcb = __wind_lookup_task(handle); else pTcb = __wind_task_current(current); if (!pTcb) return S_objLib_OBJ_ID_ERROR; if (taskPriorityGet((TASK_ID) pTcb, &prio) == ERROR) return wind_errnoget(); return __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), &prio, sizeof(prio)); }
static int __ui_rcv_msg(struct pt_regs *regs) { ID mbxid = __xn_reg_arg2(regs); T_MSG *pk_msg; ER err; err = rcv_msg(&pk_msg, mbxid); if (err == E_OK) { if (__xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &pk_msg, sizeof(pk_msg))) return -EFAULT; } else if (err == E_RLWAI) { uitask_t *task = ui_current_task(); if (!xnthread_test_info(&task->threadbase, uITRON_TASK_RLWAIT)) err = -EINTR; } return err; }
static int __wind_errno_taskget(struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); WIND_TCB *pTcb; int errcode; if (!handle) errcode = wind_errnoget(); else { pTcb = __wind_lookup_task(handle); if (!pTcb) return S_objLib_OBJ_ID_ERROR; errcode = errnoOfTaskGet((TASK_ID) pTcb); if (errcode == ERROR) return wind_errnoget(); } return __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), &errcode, sizeof(errcode)); }
/* * int __wind_taskinfo_get(TASK_ID task_id, TASK_DESC *desc) */ static int __wind_taskinfo_get(struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); TASK_DESC desc; WIND_TCB *pTcb; int err; pTcb = __wind_lookup_task(handle); if (!pTcb) return S_objLib_OBJ_ID_ERROR; err = taskInfoGet((TASK_ID)pTcb, &desc); if (err) return err; /* Replace the kernel-based pointer by the userland handle. */ desc.td_tid = handle; return __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), &desc, sizeof(desc)); }
static int __wind_taskinfo_name(struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); const char *name; WIND_TCB *pTcb; pTcb = __wind_lookup_task(handle); if (!pTcb) return S_objLib_OBJ_ID_ERROR; name = taskName((TASK_ID) pTcb); if (!name) return S_objLib_OBJ_ID_ERROR; /* We assume that a VxWorks task name fits in XNOBJECT_NAME_LEN bytes, including the trailing \0. */ return __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), name, strlen(name) + 1); }
static int __wind_taskinfo_status(struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); unsigned long status; WIND_TCB *pTcb; spl_t s; xnlock_get_irqsave(&nklock, s); pTcb = __wind_lookup_task(handle); if (!pTcb || pTcb->magic != WIND_TASK_MAGIC) { xnlock_put_irqrestore(&nklock, s); return S_objLib_OBJ_ID_ERROR; } status = xnthread_state_flags(&pTcb->threadbase); xnlock_put_irqrestore(&nklock, s); return __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), &status, sizeof(status)); }