Example #1
0
RTAI_SYSCALL_MODE int _rt_bits_wait_if(BITS *bits, int testfun, unsigned long testmasks, int exitfun, unsigned long exitmasks, unsigned long *resulting_mask, int space)
{
	unsigned long flags, mask;
	int retval;

	CHECK_BITS_MAGIC(bits);

	flags = rt_global_save_flags_and_cli();
	mask = bits->mask;
	if (test_fun[testfun](bits, testmasks)) {
		exec_fun[exitfun](bits, exitmasks);
		retval = 1;
	} else {
		retval = 0;
	}
	rt_global_restore_flags(flags);
	if (resulting_mask) {
		if (space) {
			*resulting_mask = mask;
		} else {
			rt_copy_to_user(resulting_mask, &mask, sizeof(mask));
		}
	}
	return retval;
}
Example #2
0
RTAI_SYSCALL_MODE void rt_set_tasklet_data(struct rt_tasklet_struct *tasklet, unsigned long data)
{
	tasklet->data = data;
	if (tasklet->task) {
		rt_copy_to_user(tasklet->usptasklet, tasklet, sizeof(struct rt_usp_tasklet_struct));
	}
}
Example #3
0
RTAI_SYSCALL_MODE int rt_insert_tasklet(struct rt_tasklet_struct *tasklet, int priority, void (*handler)(unsigned long), unsigned long data, unsigned long id, int pid)
{
	unsigned long flags;

// tasklet initialization
	if (!handler || !id) {
		return -EINVAL;
	}
	tasklet->uses_fpu = 0;
	tasklet->priority = priority;
	tasklet->handler  = handler;
	tasklet->data     = data;
	tasklet->id       = id;
	if (!pid) {
		tasklet->task = 0;
	} else {
		(tasklet->task)->priority = priority;
		rt_copy_to_user(tasklet->usptasklet, tasklet, sizeof(struct rt_usp_tasklet_struct));
	}
// tasklet insertion tasklets_list
	flags = rt_spin_lock_irqsave(&tasklets_lock);
	tasklet->next	     = &tasklets_list;
	tasklet->prev	     = tasklets_list.prev;
	(tasklets_list.prev)->next = tasklet;
	tasklets_list.prev	 = tasklet;
	rt_spin_unlock_irqrestore(flags, &tasklets_lock);
	return 0;
}
Example #4
0
File: mbx.c Project: ArcEye/RTAI
static int mbxevdrp(MBX *mbx, char **msg, int msg_size, int space)
{
	int tocpy, fbyte, avbs;

	fbyte = mbx->fbyte;
	avbs  = mbx->avbs;
	while (msg_size > 0 && avbs) {
		if ((tocpy = mbx->size - fbyte) > msg_size) {
			tocpy = msg_size;
		}
		if (tocpy > avbs) {
			tocpy = avbs;
		}
		if (space) {
			memcpy(*msg, mbx->bufadr + fbyte, tocpy);
		} else {
			rt_copy_to_user(*msg, mbx->bufadr + mbx->fbyte, tocpy);
		}
		avbs     -= tocpy;
		msg_size -= tocpy;
		*msg     += tocpy;
		fbyte = MOD_SIZE(fbyte + tocpy);
	}
	return msg_size;
}
Example #5
0
File: mbx.c Project: ArcEye/RTAI
static int mbxget(MBX *mbx, char **msg, int msg_size, int space)
{
	unsigned long flags;
	int tocpy;

	while (msg_size > 0 && mbx->avbs) {
		if ((tocpy = mbx->size - mbx->fbyte) > msg_size) {
			tocpy = msg_size;
		}
		if (tocpy > mbx->avbs) {
			tocpy = mbx->avbs;
		}
		if (space) {
			memcpy(*msg, mbx->bufadr + mbx->fbyte, tocpy);
		} else {
			rt_copy_to_user(*msg, mbx->bufadr + mbx->fbyte, tocpy);
		}
		flags = rt_spin_lock_irqsave(&(mbx->lock));
		mbx->frbs  += tocpy;
		mbx->avbs  -= tocpy;
		rt_spin_unlock_irqrestore(flags, &(mbx->lock));
		msg_size -= tocpy;
		*msg     += tocpy;
		mbx->fbyte = MOD_SIZE(mbx->fbyte + tocpy);
	}
	return msg_size;
}
Example #6
0
File: tbx.c Project: Enextuse/RTAI
RTAI_SYSCALL_MODE int _rt_msg_evdrp(RT_MSGQ *mq, void *msg, int msg_size, int *msgpri, int space)
{
	int size;
	RT_MSG *msg_ptr;
	void *p;

	size = min((msg_ptr = mq->firstmsg)->hdr.size, msg_size);
	if (space)
	{
		memcpy(msg, (p = msg_ptr->hdr.malloc) ? p : msg_ptr->msg, size);
		if (msgpri)
		{
			*msgpri = msg_ptr->hdr.priority;
		}
	}
	else
	{
		rt_copy_to_user(msg, (p = msg_ptr->hdr.malloc) ? p : msg_ptr->msg, size);
		if (msgpri)
		{
			rt_put_user(msg_ptr->hdr.priority, msgpri);
		}
	}
	return 0;
}
Example #7
0
RTAI_SYSCALL_MODE int rt_insert_timer(struct rt_tasklet_struct *timer, int priority, RTIME firing_time, RTIME period, void (*handler)(unsigned long), unsigned long data, int pid)
{
	spinlock_t *lock;
	unsigned long flags, cpuid;
	RT_TASK *timer_manager;

// timer initialization
	timer->uses_fpu    = 0;

	if (pid >= 0) {
		if (!handler) {
			return -EINVAL;
		}
		timer->handler   = handler;
		timer->data 			 = data;
	} else {
		if (timer->handler != NULL || timer->handler == (void *)1) {
			timer->handler = (void *)1;
			timer->data    = data;
		}
	}

	timer->priority    = priority;
	REALTIME2COUNT(firing_time)
	timer->firing_time = firing_time;
	timer->period      = period;

	if (!pid) {
		timer->task = 0;
		timer->cpuid = cpuid = NUM_CPUS > 1 ? rtai_cpuid() : 0;
	} else {
		timer->cpuid = cpuid = NUM_CPUS > 1 ? (timer->task)->runnable_on_cpus : 0;
		(timer->task)->priority = priority;
		rt_copy_to_user(timer->usptasklet, timer, sizeof(struct rt_usp_tasklet_struct));
	}
// timer insertion in timers_list
	flags = rt_spin_lock_irqsave(lock = &timers_lock[LIST_CPUID]);
	enq_timer(timer);
	rt_spin_unlock_irqrestore(flags, lock);
// timers_manager priority inheritance
	if (timer->priority < (timer_manager = &timers_manager[LIST_CPUID])->priority) {
		timer_manager->priority = timer->priority;
	}
// timers_task deadline inheritance
	flags = rt_global_save_flags_and_cli();
	if (timers_list[LIST_CPUID].next == timer && (timer_manager->state & RT_SCHED_DELAYED) && firing_time < timer_manager->resume_time) {
		timer_manager->resume_time = firing_time;
		rem_timed_task(timer_manager);
		enq_timed_task(timer_manager);
		rt_schedule();
	}
	rt_global_restore_flags(flags);
	return 0;
}
Example #8
0
RTAI_SYSCALL_MODE int rt_set_tasklet_handler(struct rt_tasklet_struct *tasklet, void (*handler)(unsigned long))
{
	if (!handler) {
		return -EINVAL;
	}
	tasklet->handler = handler;
	if (tasklet->task) {
		rt_copy_to_user(tasklet->usptasklet, tasklet, sizeof(struct rt_usp_tasklet_struct));
	}
	return 0;
}
Example #9
0
File: bits.c Project: Enextuse/RTAI
RTAI_SYSCALL_MODE int _rt_bits_wait(BITS *bits, int testfun, unsigned long testmasks, int exitfun, unsigned long exitmasks, unsigned long *resulting_mask, int space)
{
	RT_TASK *rt_current;
	unsigned long flags, mask = 0;
	int retval;

	CHECK_BITS_MAGIC(bits);

	flags = rt_global_save_flags_and_cli();
	if (!test_fun[testfun](bits, testmasks))
	{
		void *retpnt;
		long bits_test[2];
		rt_current = RT_CURRENT;
		TEST_BUF(rt_current, bits_test);
		TEST_FUN(rt_current)  = testfun;
		TEST_MASK(rt_current) = testmasks;
		rt_current->state |= RT_SCHED_SEMAPHORE;
		rem_ready_current(rt_current);
		enqueue_blocked(rt_current, &bits->queue, 1);
		rt_schedule();
		if (unlikely((retpnt = rt_current->blocked_on) != NULL))
		{
			if (likely(retpnt != RTP_OBJREM))
			{
				dequeue_blocked(rt_current);
				retval = RTE_UNBLKD;
			}
			else
			{
				rt_current->prio_passed_to = NULL;
				retval = RTE_OBJREM;
			}
			goto retmask;
		}
	}
	retval = 0;
	mask = bits->mask;
	exec_fun[exitfun](bits, exitmasks);
retmask:
	rt_global_restore_flags(flags);
	if (resulting_mask)
	{
		if (space)
		{
			*resulting_mask = mask;
		}
		else
		{
			rt_copy_to_user(resulting_mask, &mask, sizeof(mask));
		}
	}
	return retval;
}
Example #10
0
File: tbx.c Project: Enextuse/RTAI
static int _receive(RT_MSGQ *mq, void *msg, int msg_size, int *msgpri, int space)
{
	int size;
	RT_MSG *msg_ptr;
	void *p;

	size = min((msg_ptr = mq->firstmsg)->hdr.size, msg_size);
	if (space)
	{
		memcpy(msg, (p = msg_ptr->hdr.malloc) ? p : msg_ptr->msg, size);
		if (msgpri)
		{
			*msgpri = msg_ptr->hdr.priority;
		}
	}
	else
	{
		rt_copy_to_user(msg, (p = msg_ptr->hdr.malloc) ? p : msg_ptr->msg, size);
		if (msgpri)
		{
			rt_put_user(msg_ptr->hdr.priority, msgpri);
		}
	}

	if (msg_ptr->hdr.broadcast)
	{
		if (!--msg_ptr->hdr.broadcast)
		{
			rt_sem_wait_barrier(&mq->broadcast);
			goto relslot;
		}
		else
		{
			rt_sem_signal(&mq->received);
			rt_sem_signal(&mq->receivers);
			rt_sem_wait_barrier(&mq->broadcast);
		}
	}
	else
	{
		unsigned long flags;
relslot:	flags = rt_spin_lock_irqsave(&mq->lock);
		mq->firstmsg = msg_ptr->hdr.next;
		mq->slots[--mq->slot] = msg_ptr;
		rt_spin_unlock_irqrestore(flags, &mq->lock);
		rt_sem_signal(&mq->freslots);
		rt_sem_signal(&mq->receivers);
		if (p)
		{
			rt_free(p);
		}
	}
	return msg_size - size;
}
Example #11
0
RTAI_SYSCALL_MODE int rt_delete_tasklet(struct rt_tasklet_struct *tasklet)
{
	int thread;

	rt_remove_tasklet(tasklet);
	tasklet->handler = 0;
	rt_copy_to_user(tasklet->usptasklet, tasklet, sizeof(struct rt_usp_tasklet_struct));
	rt_task_resume(tasklet->task);
	thread = tasklet->thread;
	rt_free(tasklet);
	return thread;
}
Example #12
0
RTAI_SYSCALL_MODE int rt_ptimer_delete(timer_t timer, long space)
{
	struct rt_tasklet_struct *tasklet;
	int rtn = 0;

	tasklet = posix_timer[timer].timer;
	gvb_ptimer_indx(timer);
	rt_remove_tasklet(tasklet);
	if (space) {
		tasklet->handler = 0;
		rt_copy_to_user(tasklet->usptasklet, tasklet, sizeof(struct rt_usp_tasklet_struct));
		rt_task_resume(tasklet->task);
		rtn = tasklet->thread;
	}
	rt_free(tasklet);
	return rtn;
}
Example #13
0
RTAI_SYSCALL_MODE void rt_register_task(struct rt_tasklet_struct *tasklet, struct rt_tasklet_struct *usptasklet, RT_TASK *task)
{
	tasklet->task = task;
	tasklet->usptasklet = usptasklet;
	rt_copy_to_user(usptasklet, tasklet, sizeof(struct rt_usp_tasklet_struct));
}
Example #14
0
static inline long long handle_lxrt_request (unsigned int lxsrq, long *arg, RT_TASK *task)
{
#define larg ((struct arg *)arg)

	union {unsigned long name; RT_TASK *rt_task; SEM *sem; MBX *mbx; RWL *rwl; SPL *spl; int i; void *p; long long ll; } arg0;
	int srq;

	if (likely((srq = SRQ(lxsrq)) < MAX_LXRT_FUN)) {
		unsigned long type;
		struct rt_fun_entry *funcm;
/*
 * The next two lines of code do a lot. It makes possible to extend the use of
 * USP to any other real time module service in user space, both for soft and
 * hard real time. Concept contributed and copyrighted by: Giuseppe Renoldi 
 * ([email protected]).
 */
		if (unlikely(!(funcm = rt_fun_ext[INDX(lxsrq)]))) {
			rt_printk("BAD: null rt_fun_ext, no module for extension %d?\n", INDX(lxsrq));
			return -ENOSYS;
		}
		if (!(type = funcm[srq].type)) {
			return ((RTAI_SYSCALL_MODE long long (*)(unsigned long, ...))funcm[srq].fun)(RTAI_FUN_ARGS);
		}
		if (unlikely(NEED_TO_RW(type))) {
			lxrt_fun_call_wbuf(task, funcm[srq].fun, NARG(lxsrq), arg, type);
		} else {
			lxrt_fun_call(task, funcm[srq].fun, NARG(lxsrq), arg);
	        }
		return task->retval;
	}

	arg0.name = arg[0];
	switch (srq) {
		case LXRT_GET_ADR: {
			arg0.p = rt_get_adr(arg0.name);
			return arg0.ll;
		}

		case LXRT_GET_NAME: {
			arg0.name = rt_get_name(arg0.p);
			return arg0.ll;
		}

		case LXRT_TASK_INIT: {
			struct arg { unsigned long name; long prio, stack_size, max_msg_size, cpus_allowed; };
			arg0.rt_task = __task_init(arg0.name, larg->prio, larg->stack_size, larg->max_msg_size, larg->cpus_allowed);
			return arg0.ll;
		}

		case LXRT_TASK_DELETE: {
			arg0.i = __task_delete(arg0.rt_task ? arg0.rt_task : task);
			return arg0.ll;
		}

		case LXRT_SEM_INIT: {
			if (rt_get_adr(arg0.name)) {
				return 0;
			}
			if ((arg0.sem = rt_malloc(sizeof(SEM)))) {
				struct arg { unsigned long name; long cnt; long typ; };
				lxrt_typed_sem_init(arg0.sem, larg->cnt, larg->typ);
				if (rt_register(larg->name, arg0.sem, IS_SEM, current)) {
					return arg0.ll;
				} else {
					rt_free(arg0.sem);
				}
			}
			return 0;
		}

		case LXRT_SEM_DELETE: {
			if (lxrt_sem_delete(arg0.sem)) {
				arg0.i = -EFAULT;
				return arg0.ll;
			}
			rt_free(arg0.sem);
			arg0.i = rt_drg_on_adr(arg0.sem);
			return arg0.ll;
		}

		case LXRT_MBX_INIT: {
			if (rt_get_adr(arg0.name)) {
				return 0;
			}
			if ((arg0.mbx = rt_malloc(sizeof(MBX)))) {
				struct arg { unsigned long name; long size; int qtype; };
				if (lxrt_typed_mbx_init(arg0.mbx, larg->size, larg->qtype) < 0) {
					rt_free(arg0.mbx);
					return 0;
				}
				if (rt_register(larg->name, arg0.mbx, IS_MBX, current)) {
					return arg0.ll;
				} else {
					rt_free(arg0.mbx);
				}
			}
			return 0;
		}

		case LXRT_MBX_DELETE: {
			if (lxrt_mbx_delete(arg0.mbx)) {
				arg0.i = -EFAULT;
				return arg0.ll;
			}
			rt_free(arg0.mbx);
			arg0.i = rt_drg_on_adr(arg0.mbx);
			return arg0.ll;
		}

		case LXRT_RWL_INIT: {
			if (rt_get_adr(arg0.name)) {
				return 0;
			}
			if ((arg0.rwl = rt_malloc(sizeof(RWL)))) {
				struct arg { unsigned long name; long type; };
				lxrt_typed_rwl_init(arg0.rwl, larg->type);
				if (rt_register(larg->name, arg0.rwl, IS_SEM, current)) {
					return arg0.ll;
				} else {
					rt_free(arg0.rwl);
				}
			}
			return 0;
		}

		case LXRT_RWL_DELETE: {
			if (lxrt_rwl_delete(arg0.rwl)) {
				arg0.i = -EFAULT;
				return arg0.ll;
			}
			rt_free(arg0.rwl);
			arg0.i = rt_drg_on_adr(arg0.rwl);
			return arg0.ll;
		}

		case LXRT_SPL_INIT: {
			if (rt_get_adr(arg0.name)) {
				return 0;
			}
			if ((arg0.spl = rt_malloc(sizeof(SPL)))) {
				struct arg { unsigned long name; };
				lxrt_spl_init(arg0.spl);
				if (rt_register(larg->name, arg0.spl, IS_SEM, current)) {
					return arg0.ll;
				} else {
					rt_free(arg0.spl);
				}
			}
			return 0;
		}

		case LXRT_SPL_DELETE: {
			if (lxrt_spl_delete(arg0.spl)) {
				arg0.i = -EFAULT;
				return arg0.ll;
			}
			rt_free(arg0.spl);
			arg0.i = rt_drg_on_adr(arg0.spl);
			return arg0.ll;
		}

		case MAKE_HARD_RT: {
			rt_make_hard_real_time(task);
			return 0;
			if (!task || task->is_hard) {
				 return 0;
			}
			steal_from_linux(task);
			return 0;
		}

		case MAKE_SOFT_RT: {
			rt_make_soft_real_time(task);
			return 0;
			if (!task || !task->is_hard) {
				return 0;
			}
			if (task->is_hard < 0) {
				task->is_hard = 0;
			} else {
				give_back_to_linux(task, 0);
			}
			return 0;
		}
		case PRINT_TO_SCREEN: {
			struct arg { char *display; long nch; };
			arg0.i = rtai_print_to_screen("%s", larg->display);
			return arg0.ll;
		}

		case PRINTK: {
			struct arg { char *display; long nch; };
			arg0.i = rt_printk("%s", larg->display);
			return arg0.ll;
		}

		case NONROOT_HRT: {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
			current->cap_effective |= ((1 << CAP_IPC_LOCK)  |
						   (1 << CAP_SYS_RAWIO) |
						   (1 << CAP_SYS_NICE));
#else
			set_lxrt_perm(CAP_IPC_LOCK);
			set_lxrt_perm(CAP_SYS_RAWIO);
			set_lxrt_perm(CAP_SYS_NICE);
#endif
			return 0;
		}

		case RT_BUDDY: {
			arg0.rt_task = task && current->rtai_tskext(TSKEXT1) == current ? task : NULL;
			return arg0.ll;
		}

		case HRT_USE_FPU: {
			struct arg { RT_TASK *task; long use_fpu; };
			if(!larg->use_fpu) {
				clear_lnxtsk_uses_fpu((larg->task)->lnxtsk);
			} else {
				init_fpu((larg->task)->lnxtsk);
			}
			return 0;
		}

                case GET_USP_FLAGS: {
                        arg0.name = arg0.rt_task->usp_flags;
			return arg0.ll;
                }
                case SET_USP_FLAGS: {
                        struct arg { RT_TASK *task; unsigned long flags; };
                        arg0.rt_task->usp_flags = larg->flags;
                        arg0.rt_task->force_soft = (arg0.rt_task->is_hard > 0) && (larg->flags & arg0.rt_task->usp_flags_mask & FORCE_SOFT);
                        return 0;
                }

                case GET_USP_FLG_MSK: {
                        arg0.name = arg0.rt_task->usp_flags_mask;
			return arg0.ll;
                }

                case SET_USP_FLG_MSK: {
                        task->usp_flags_mask = arg0.name;
                        task->force_soft = (task->is_hard > 0) && (task->usp_flags & arg0.name & FORCE_SOFT);
                        return 0;
                }

                case FORCE_TASK_SOFT: {
			extern void rt_do_force_soft(RT_TASK *rt_task);
                        struct task_struct *ltsk;
                        if ((ltsk = find_task_by_pid(arg0.name)))  {
                                if ((arg0.rt_task = ltsk->rtai_tskext(TSKEXT0))) {
					if ((arg0.rt_task->force_soft = (arg0.rt_task->is_hard != 0) && FORCE_SOFT)) {
						rt_do_force_soft(arg0.rt_task);
					}
					return arg0.ll;
                                }
                        }
                        return 0;
                }

		case IS_HARD: {
			arg0.i = arg0.rt_task || (arg0.rt_task = current->rtai_tskext(TSKEXT0)) ? arg0.rt_task->is_hard : 0;
			return arg0.ll;
		}
		case GET_EXECTIME: {
			struct arg { RT_TASK *task; RTIME *exectime; };
			if ((larg->task)->exectime[0] && (larg->task)->exectime[1]) {
				larg->exectime[0] = (larg->task)->exectime[0]; 
				larg->exectime[1] = (larg->task)->exectime[1]; 
				larg->exectime[2] = rtai_rdtsc(); 
			}
                        return 0;
		}
		case GET_TIMEORIG: {
			struct arg { RTIME *time_orig; };
			if (larg->time_orig) {
				RTIME time_orig[2];
				rt_gettimeorig(time_orig);
				rt_copy_to_user(larg->time_orig, time_orig, sizeof(time_orig));
			} else {
				rt_gettimeorig(NULL);
			}
                        return 0;
		}

		case LINUX_SERVER: {
			struct arg { struct linux_syscalls_list syscalls; };
			if (larg->syscalls.nr) {
				if (larg->syscalls.task->linux_syscall_server) {
					RT_TASK *serv;
					rt_get_user(serv, &larg->syscalls.serv);
					rt_task_masked_unblock(serv, ~RT_SCHED_READY);
				}
				larg->syscalls.task->linux_syscall_server = larg->syscalls.serv;
				rtai_set_linux_task_priority(current, (larg->syscalls.task)->lnxtsk->policy, (larg->syscalls.task)->lnxtsk->rt_priority);
				arg0.rt_task = __task_init((unsigned long)larg->syscalls.task, larg->syscalls.task->base_priority >= BASE_SOFT_PRIORITY ? larg->syscalls.task->base_priority - BASE_SOFT_PRIORITY : larg->syscalls.task->base_priority, 0, 0, 1 << larg->syscalls.task->runnable_on_cpus);

				larg->syscalls.task->linux_syscall_server = arg0.rt_task;
				arg0.rt_task->linux_syscall_server = larg->syscalls.serv;

				return arg0.ll;
			} else {
				if (!larg->syscalls.task) {
					larg->syscalls.task = RT_CURRENT;
				}
				if ((arg0.rt_task = larg->syscalls.task->linux_syscall_server)) {
					larg->syscalls.task->linux_syscall_server = NULL;
					arg0.rt_task->suspdepth = -RTE_HIGERR;
					rt_task_masked_unblock(arg0.rt_task, ~RT_SCHED_READY);
				}
			}
			return 0;
		}

	        default: {
		    rt_printk("RTAI/LXRT: Unknown srq #%d\n", srq);
		    arg0.i = -ENOSYS;
		    return arg0.ll;
		}
	}
	return 0;
}
Example #15
0
static inline void lxrt_fun_call_wbuf(RT_TASK *rt_task, void *fun, int narg, long *arg, unsigned long type)
{
	int rsize, r2size, wsize, w2size, msg_size;
	long *wmsg_adr, *w2msg_adr, *fun_args;
		
	rsize = r2size = wsize = w2size = 0 ;
	wmsg_adr = w2msg_adr = NULL;
	fun_args = arg - 1;
	if (NEED_TO_R(type)) {			
		rsize = USP_RSZ1(type);
		rsize = rsize ? fun_args[rsize] : sizeof(long);
		if (NEED_TO_R2ND(type)) {
			r2size = USP_RSZ2(type);
			r2size = r2size ? fun_args[r2size] : sizeof(long);
		}
	}
	if (NEED_TO_W(type)) {
		wsize = USP_WSZ1(type);
		wsize = wsize ? fun_args[wsize] : sizeof(long);
		if (NEED_TO_W2ND(type)) {
			w2size = USP_WSZ2(type);
			w2size = w2size ? fun_args[w2size] : sizeof(long);
		}
	}
	if ((msg_size = rsize > wsize ? rsize : wsize) > 0) {
		if (msg_size > rt_task->max_msg_size[0]) {
			rt_free(rt_task->msg_buf[0]);
			rt_task->max_msg_size[0] = (msg_size << 7)/100;
			rt_task->msg_buf[0] = rt_malloc(rt_task->max_msg_size[0]);
		}
		if (rsize) {			
			long *buf_arg = fun_args + USP_RBF1(type);
			rt_copy_from_user(rt_task->msg_buf[0], (long *)buf_arg[0], rsize);
			buf_arg[0] = (long)rt_task->msg_buf[0];
		}
		if (wsize) {
			long *buf_arg = fun_args + USP_WBF1(type);
			wmsg_adr = (long *)buf_arg[0];
			buf_arg[0] = (long)rt_task->msg_buf[0];
		}
	}
	if ((msg_size = r2size > w2size ? r2size : w2size) > 0) {
		if (msg_size > rt_task->max_msg_size[1]) {
			rt_free(rt_task->msg_buf[1]);
			rt_task->max_msg_size[1] = (msg_size << 7)/100;
			rt_task->msg_buf[1] = rt_malloc(rt_task->max_msg_size[1]);
		}
		if (r2size) {
			long *buf_arg = fun_args + USP_RBF2(type);
			rt_copy_from_user(rt_task->msg_buf[1], (long *)buf_arg[0], r2size);
			buf_arg[0] = (long)rt_task->msg_buf[1];
       		}
		if (w2size) {
			long *buf_arg = fun_args + USP_WBF2(type);
			w2msg_adr = (long *)buf_arg[0];
       	        	buf_arg[0] = (long)rt_task->msg_buf[1];
       		}
	}
	lxrt_fun_call(rt_task, fun, narg, arg);
	if (wsize) {
		rt_copy_to_user(wmsg_adr, rt_task->msg_buf[0], wsize);
		if (w2size) {
			rt_copy_to_user(w2msg_adr, rt_task->msg_buf[1], w2size);
		}
	}
}