204
206
rt_net_rpc_fun_ext[1] = ext;
207
struct req_rel_msg { int op, port, priority, hard; unsigned long long owner; unsigned long name, rem_node, chkspare;};
209
struct req_rel_msg { long long op, port, priority, hard; unsigned long long owner, name, rem_node, chkspare;};
211
struct par_t { long long mach, priority, base_priority, argsize, rsize, fun_ext_timed, type; unsigned long long owner, partypes; long a[1]; };
213
struct reply_t { long long wsize, w2size, myport; unsigned long long retval; char msg[1], msg1[1]; };
215
static inline int argconv(void *ain, void *aout, int send_mach, int argsize, unsigned int partypes)
217
#define recv_mach (sizeof(long))
219
if (send_mach == recv_mach) {
220
memcpy(aout, ain, argsize);
224
if (send_mach == 4 && recv_mach == 8) {
230
switch(partypes & WDWMSK) {
235
*out++ = (unsigned int)*in++;
238
*out++ = reset_kadr(*in++);
241
*out++ = (long)*in++;
249
unsigned long *out = aout;
250
unsigned long long *in = ain;
254
switch(partypes & WDWMSK) {
261
*((unsigned long long *)out++) = *in++;
209
273
static void net_resume_task(int sock, struct portslot_t *p)
253
317
static inline int soft_rt_fun_call(RT_TASK *task, void *fun, void *arg)
319
union { long long ll; long l; } retval;
255
320
task->fun_args[0] = (long)arg;
256
321
((struct fun_args *)task->fun_args)->fun = fun;
257
322
rt_schedule_soft(task);
258
return (int)task->retval;
323
retval.ll = task->retval;
324
return (int)retval.l;
261
327
static inline long long soft_rt_genfun_call(RT_TASK *task, void *fun, void *args, int argsize)
266
332
return task->retval;
335
extern void rt_daemonize(void);
269
336
static void thread_fun(RT_TASK *task)
271
338
if (!set_rtext(task, task->fun_args[3], 0, 0, get_min_tasks_cpuid(), 0)) {
272
340
sigfillset(¤t->blocked);
273
341
rtai_set_linux_task_priority(current, SCHED_FIFO, MIN_LINUX_RTPRIO);
274
342
soft_rt_fun_call(task, rt_task_suspend, task);
275
343
((void (*)(long))task->fun_args[1])(task->fun_args[2]);
344
task->fun_args[1] = 0;
295
364
static int soft_kthread_delete(RT_TASK *task)
297
if (clr_rtext(task)) {
300
struct task_struct *lnxtsk = task->lnxtsk;
301
// lnxtsk->rtai_tskext(TSKEXT0) = lnxtsk->rtai_tskext(TSKEXT1) = 0;
302
sigemptyset(&lnxtsk->blocked);
303
lnxtsk->state = TASK_INTERRUPTIBLE;
304
kill_proc(lnxtsk->pid, SIGTERM, 0);
366
task->fun_args[1] = 1;
367
while (task->fun_args[1]) {
368
rt_task_masked_unblock(task, ~RT_SCHED_READY);
369
current->state = TASK_INTERRUPTIBLE;
370
schedule_timeout(HZ/NETRPC_TIMER_FREQ);
392
459
struct sockaddr *addr;
395
struct par_t { int priority, base_priority, argsize, rsize, fun_ext_timed; long type; unsigned long long owner; long a[1]; } *par;
396
463
long wsize, w2size, sock;
400
467
addr = (struct sockaddr *)&portslotp->addr;
401
468
sock = portslotp->socket[0];
402
469
sem = &portslotp->sem;
403
a = (par = (void *)msg)->a;
470
ain = (par = (void *)msg)->a;
404
471
task = (RT_TASK *)portslotp->task;
405
472
sprintf(current->comm, "SFTSTB-%ld", sock);
431
500
task->base_priority = par->base_priority;
502
argsize = argconv(ain, a, par->mach, par->argsize, par->partypes);
433
503
type = par->type;
434
504
if (par->rsize) {
435
a[USP_RBF1(type) - 1] = (long)((char *)a + par->argsize);
505
a[USP_RBF1(type) - 1] = (long)((char *)ain + par->argsize);
437
507
if (NEED_TO_W(type)) {
438
508
wsize = USP_WSZ1(type);
439
wsize = wsize ? a[wsize - 1] : sizeof(long);
509
wsize = wsize ? a[wsize - 1] : par->mach; //sizeof(long);
443
513
if (NEED_TO_W2ND(type)) {
444
514
w2size = USP_WSZ2(type);
445
w2size = w2size ? a[w2size - 1] : sizeof(long);
515
w2size = w2size ? a[w2size - 1] : par->mach; //sizeof(long);
450
struct msg_t { int wsize, w2size; unsigned long long retval; int myport; char msg_buf[wsize], msg_buf2[w2size]; } arg;
520
struct msg_t { struct reply_t arg; char bufspace[wsize + w2size]; } arg;
454
a[USP_WBF1(type) - 1] = (long)arg.msg_buf;
523
arg.arg.wsize = wsize;
524
a[USP_WBF1(type) - 1] = (long)arg.arg.msg;
458
528
if (w2size > 0) {
460
a[USP_WBF2(type) - 1] = (long)arg.msg_buf2;
529
arg.arg.w2size = w2size;
530
a[USP_WBF2(type) - 1] = (long)(arg.arg.msg + arg.arg.wsize);
464
534
#ifndef NETRPC_ALIGN_RTIME
465
535
if ((wsize = TIMED(par->fun_ext_timed) - 1) >= 0) {
470
540
*((long long *)(a + wsize)) = nano2count(*((long long *)(a + wsize)));
472
arg.retval = soft_rt_genfun_call(task, rt_net_rpc_fun_ext[EXT(par->fun_ext_timed)][FUN(par->fun_ext_timed)].fun, a, par->argsize);
542
arg.arg.retval = soft_rt_genfun_call(task, rt_net_rpc_fun_ext[EXT(par->fun_ext_timed)][FUN(par->fun_ext_timed)].fun, a, argsize);
473
543
soft_rt_sendto(sock, &arg, encode ? encode(portslotp, &arg, sizeof(struct msg_t), RPC_RTR) : sizeof(struct msg_t), 0, addr, ADRSZ);
477
547
if (portslotp->recovered) {
478
struct msg_t { int wsize, w2size; unsigned long long retval; int myport; char msg_buf[1], msg_buf2[1]; } arg;
479
549
portslotp->recovered = 0;
480
arg.myport = sock+BASEPORT;
550
arg.myport = sock + BASEPORT;
481
551
arg.retval = portslotp->owner;
482
soft_rt_sendto(sock, &arg, encode ? encode(portslotp, &arg, sizeof(struct msg_t), RPC_RTR) : sizeof(struct msg_t), 0, addr, ADRSZ);
552
soft_rt_sendto(sock, &arg, encode ? encode(portslotp, &arg, sizeof(struct reply_t), RPC_RTR) : sizeof(struct reply_t), 0, addr, ADRSZ);
485
555
// soft_rt_fun_call(task, rt_task_suspend, task);
491
561
struct sockaddr *addr;
494
struct par_t { int priority, base_priority, argsize, rsize, fun_ext_timed; long type; unsigned long long owner; long a[1]; } *par;
495
565
long wsize, w2size, sock;
498
569
addr = (struct sockaddr *)&portslotp->addr;
499
570
sock = portslotp->socket[1];
500
571
sem = &portslotp->sem;
501
a = (par = (void *)msg)->a;
572
ain = (par = (void *)msg)->a;
502
573
task = (RT_TASK *)portslotp->task;
503
574
if (task->lnxtsk) {
504
575
sprintf(current->comm, "HRDSTB-%ld", sock);
509
while (rt_sem_wait(sem)< RTE_LOWERR) {
580
while (rt_sem_wait(sem) < RTE_LOWERR) {
510
581
wsize = hard_rt_recvfrom(sock, msg, MAX_MSG_SIZE, 0, addr, (void *)&w2size);
512
583
decode(portslotp, msg, wsize, RPC_SRV);
514
585
if (portslotp->owner != par->owner) {
515
586
unsigned long flags;
516
588
flags = rt_spin_lock_irqsave(&recovery_lock);
517
589
recovery.msg[recovery.in].priority = par->priority;
518
590
recovery.msg[recovery.in].owner = par->owner;
522
594
rt_spin_unlock_irqrestore(flags, &recovery_lock);
523
595
rt_sem_signal(&portslot[0].sem);
598
long a[par->argsize/sizeof(long) + 1];
525
599
if(par->priority >= 0 && par->priority < RT_SCHED_LINUX_PRIORITY) {
526
600
if ((wsize = par->priority) < task->priority) {
527
601
task->priority = wsize;
529
603
task->base_priority = par->base_priority;
605
argsize = argconv(ain, a, par->mach, par->argsize, par->partypes);
531
606
type = par->type;
532
607
if (par->rsize) {
533
a[USP_RBF1(type) - 1] = (long)((char *)a + par->argsize);
608
a[USP_RBF1(type) - 1] = (long)((char *)ain + par->argsize);
535
610
if (NEED_TO_W(type)) {
536
611
wsize = USP_WSZ1(type);
537
wsize = wsize ? a[wsize - 1] : sizeof(long);
612
wsize = wsize ? a[wsize - 1] : par->mach; //sizeof(long);
541
616
if (NEED_TO_W2ND(type)) {
542
617
w2size = USP_WSZ2(type);
543
w2size = w2size ? a[w2size - 1] : sizeof(long);
618
w2size = w2size ? a[w2size - 1] : par->mach; //sizeof(long);
548
struct msg_t { int wsize, w2size; unsigned long long retval; int myport; char msg_buf[wsize], msg_buf2[w2size]; } arg;
623
struct msg_t { struct reply_t arg; char bufspace[wsize + w2size]; } arg;
552
a[USP_WBF1(type) - 1] = (long)arg.msg_buf;
626
arg.arg.wsize = wsize;
627
a[USP_WBF1(type) - 1] = (long)arg.arg.msg;
556
631
if (w2size > 0) {
558
a[USP_WBF2(type) - 1] = (long)arg.msg_buf2;
632
arg.arg.w2size = w2size;
633
a[USP_WBF2(type) - 1] = (long)(arg.arg.msg + arg.arg.wsize);
562
637
#ifndef NETRPC_ALIGN_RTIME
563
638
if ((wsize = TIMED(par->fun_ext_timed) - 1) >= 0) {
568
643
*((long long *)(a + wsize)) = nano2count(*((long long *)(a + wsize)));
570
arg.retval = ((long long (*)(long, ...))rt_net_rpc_fun_ext[EXT(par->fun_ext_timed)][FUN(par->fun_ext_timed)].fun)(RTAI_FUN_A);
645
arg.arg.retval = ((long long (*)(long, ...))rt_net_rpc_fun_ext[EXT(par->fun_ext_timed)][FUN(par->fun_ext_timed)].fun)(RTAI_FUN_A);
571
646
hard_rt_sendto(sock, &arg, encode ? encode(portslotp, &arg, sizeof(struct msg_t), RPC_RTR) : sizeof(struct msg_t), 0, addr, ADRSZ);
575
650
if (portslotp->recovered) {
576
struct msg_t { int wsize, w2size; unsigned long long retval; int myport; char msg_buf[1], msg_buf2[1]; } arg;
577
652
portslotp->recovered = 0;
578
arg.myport = sock+BASEPORT;
653
arg.myport = sock + BASEPORT;
579
654
arg.retval = portslotp->owner;
580
hard_rt_sendto(sock, &arg, encode ? encode(portslotp, &arg, sizeof(struct msg_t), RPC_RTR) : sizeof(struct msg_t), 0, addr, ADRSZ);
655
hard_rt_sendto(sock, &arg, encode ? encode(portslotp, &arg, sizeof(struct reply_t), RPC_RTR) : sizeof(struct reply_t), 0, addr, ADRSZ);
583
658
rt_task_suspend(task);
884
#define RETURN_I(l, retval) do { retval.i = l; return retval.rt; } while (0)
965
#define RETURN_ERR(err) \
967
union { long long ll; long l; } retval; \
886
RTAI_SYSCALL_MODE long long _rt_net_rpc(long fun_ext_timed, long type, void *args, int argsize, int space)
972
RTAI_SYSCALL_MODE long long _rt_net_rpc(long fun_ext_timed, long type, void *args, int argsize, int space, unsigned long partypes)
888
974
char msg[MAX_MSG_SIZE];
889
struct reply_t { int wsize, w2size; unsigned long long retval; int myport; char msg[1]; } *reply;
975
struct reply_t *reply;
890
976
long rsize, port;
891
977
struct portslot_t *portslotp;
892
union rtai_netrpc_t retval;
894
979
if ((port = PORT(fun_ext_timed)) > 0) {
895
981
if ((portslotp = portslot + port)->task < 0) {
897
983
struct sockaddr addr;
899
985
if (portslotp->timeout) {
900
986
if(rt_sem_wait_timed(&portslotp->sem,portslotp->timeout) == RTE_TIMOUT)
901
RETURN_I(RTE_NETIMOUT, retval);
987
RETURN_ERR(RTE_NETIMOUT);
903
989
rt_sem_wait(&portslotp->sem);
909
995
if((reply = (void *)msg)->myport) {
910
996
if (reply->myport < 0) {
911
RETURN_I(-RTE_CHGPORTERR, retval);
997
RETURN_ERR(-RTE_CHGPORTERR);
913
999
portslotp->addr.sin_port = htons(reply->myport);
914
1000
portslotp->sem.count = 0;
915
1001
portslotp->sem.queue.prev = portslotp->sem.queue.next = &portslotp->sem.queue;
916
1002
portslotp->owner = reply->retval;
917
1003
portslotp->name = (unsigned long)(_rt_whoami());
918
RETURN_I(-RTE_CHGPORTOK, retval);
1004
RETURN_ERR(-RTE_CHGPORTOK);
920
1006
mbx_send_if(portslotp->mbx, msg, offsetof(struct reply_t, msg) + reply->wsize + reply->w2size);
921
1007
// mbx_send_if(portslotp->mbx, msg, rsize);
945
1032
portslotp->sem.queue.prev = portslotp->sem.queue.next = &portslotp->sem.queue;
946
1033
portslotp->owner = reply->retval;
947
1034
portslotp->name = (unsigned long)(_rt_whoami());
948
RETURN_I(-RTE_CHGPORTOK, retval);
1035
RETURN_ERR(-RTE_CHGPORTOK);
950
1037
mbx_send_if(portslotp->mbx, msg, offsetof(struct reply_t, msg) + reply->wsize + reply->w2size);
951
1038
// mbx_send_if(portslotp->mbx, msg, rsize);
976
1063
arg->fun_ext_timed = fun_ext_timed;
977
1064
arg->type = type;
978
1065
arg->owner = portslotp->owner;
979
memcpy(arg->args, args, argsize);
1066
arg->partypes = partypes;
1067
memcpy(arg->a, args, argsize);
980
1068
if (rsize > 0) {
982
memcpy((char *)arg->args + argsize, (void *)((long *)args + USP_RBF1(type) - 1)[0], rsize);
1070
memcpy((char *)arg->a + argsize, (void *)((long *)args + USP_RBF1(type) - 1)[0], rsize);
984
rt_copy_from_user((char *)arg->args + argsize, (void *)((long *)args + USP_RBF1(type) - 1)[0], rsize);
1072
rt_copy_from_user((char *)arg->a + argsize, (void *)((long *)args + USP_RBF1(type) - 1)[0], rsize);
987
rsize = sizeof(struct msg_t) - sizeof(long) + argsize + rsize;
1075
rsize = sizeof(struct par_t) - sizeof(long) + argsize + rsize;
989
1077
rsize = encode(portslotp, msg, rsize, RPC_REQ);
1079
arg->mach = sizeof(long);
991
1080
if (portslotp->hard) {
992
1081
hard_rt_sendto(portslotp->socket[1], msg, rsize, 0, (struct sockaddr *)&portslotp->addr, ADRSZ);
1010
1099
if((reply = (void *)msg)->myport) {
1011
1100
if (reply->myport < 0) {
1012
RETURN_I(-RTE_CHGPORTERR, retval);
1101
RETURN_ERR(-RTE_CHGPORTERR);
1014
1103
portslotp->addr.sin_port = htons(reply->myport);
1015
1104
portslotp->sem.count = 0;
1016
1105
portslotp->sem.queue.prev = portslotp->sem.queue.next = &portslotp->sem.queue;
1017
1106
portslotp->owner = reply->retval;
1018
1107
portslotp->name = (unsigned long)(_rt_whoami());
1019
RETURN_I(-RTE_CHGPORTOK, retval);
1108
RETURN_ERR(-RTE_CHGPORTOK);
1021
1110
if (reply->wsize) {
1042
1131
int rt_get_net_rpc_ret(MBX *mbx, unsigned long long *retval, void *msg1, int *msglen1, void *msg2, int *msglen2, RTIME timeout, int type)
1044
struct reply_t { int wsize, w2size; unsigned long long retval; int myport; char msg[1]; } reply;
1133
struct reply_t reply;
1047
// if ((ret = ((int (*)(MBX *, ...))rt_net_rpc_fun_ext[NET_RPC_EXT][type].fun)(mbx, &reply, sizeof(reply), timeout))) {
1048
1136
if ((ret = ((int (*)(MBX *, ...))rt_net_rpc_fun_ext[NET_RPC_EXT][type].fun)(mbx, &reply, offsetof(struct reply_t, msg), timeout))) {
1095
1183
return this_node[hard ? MSG_HARD : MSG_SOFT] = ddn ? ddn2nl(ddn) : node;
1186
#ifdef CONFIG_RTAI_RT_POLL
1188
RTAI_SYSCALL_MODE int rt_poll_netrpc(struct rt_poll_s *pdsa1, struct rt_poll_s *pdsa2, unsigned long pdsa_size, RTIME timeout)
1190
int retval = pdsa_size/sizeof(struct rt_poll_s);
1191
if (sizeof(long) == 8 && !((unsigned long)pdsa1[0].what & 0xFFFFFFFF00000000ULL)) {
1193
for (i = 0; i < retval; i++) {
1194
pdsa1[i].what = (void *)reset_kadr((unsigned long)pdsa1[i].what);
1197
retval = _rt_poll(pdsa1, retval, timeout, 1);
1198
memcpy(pdsa2, pdsa1, pdsa_size);
1202
EXPORT_SYMBOL(rt_poll_netrpc);
1098
1206
/* +++++++++++++++++++++++++++ NETRPC ENTRIES +++++++++++++++++++++++++++++++ */
1100
1208
struct rt_native_fun_entry rt_netrpc_entries[] = {
1101
{ { 1, _rt_net_rpc }, NETRPC },
1102
{ { 0, rt_set_netrpc_timeout }, SET_NETRPC_TIMEOUT },
1103
{ { 1, rt_send_req_rel_port }, SEND_REQ_REL_PORT },
1104
{ { 0, ddn2nl }, DDN2NL },
1105
{ { 0, rt_set_this_node }, SET_THIS_NODE },
1106
{ { 0, rt_find_asgn_stub }, FIND_ASGN_STUB },
1107
{ { 0, rt_rel_stub }, REL_STUB },
1108
{ { 0, rt_waiting_return }, WAITING_RETURN },
1209
{ { 1, _rt_net_rpc }, NETRPC },
1210
{ { 0, rt_set_netrpc_timeout }, SET_NETRPC_TIMEOUT },
1211
{ { 1, rt_send_req_rel_port }, SEND_REQ_REL_PORT },
1212
{ { 0, ddn2nl }, DDN2NL },
1213
{ { 0, rt_set_this_node }, SET_THIS_NODE },
1214
{ { 0, rt_find_asgn_stub }, FIND_ASGN_STUB },
1215
{ { 0, rt_rel_stub }, REL_STUB },
1216
{ { 0, rt_waiting_return }, WAITING_RETURN },
1217
#ifdef CONFIG_RTAI_RT_POLL
1218
{ { 1, rt_poll_netrpc }, RT_POLL_NETRPC },
1109
1220
{ { 0, 0 }, 000 }
1501
1612
#ifndef DECLARE_MUTEX_LOCKED
1613
#ifndef __DECLARE_SEMAPHORE_GENERIC
1614
#define DECLARE_MUTEX_LOCKED(name) \
1615
struct semaphore name = __SEMAPHORE_INITIALIZER(name, 0)
1502
1617
#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
1504
1620
static DECLARE_MUTEX_LOCKED(mtx);
1505
1621
static unsigned long end_softrtnet;
1512
1628
rtai_set_linux_task_priority(current,SCHED_FIFO,MAX_LINUX_RTPRIO);
1513
1629
sigfillset(¤t->blocked);
1514
1630
while (!end_softrtnet) {
1631
i = down_interruptible(&mtx);
1516
1632
while (sysrq.out != sysrq.in) {
1517
1633
i = sysrq.sockindx[sysrq.out];
1518
1634
ksendto(socks[i].sock, socks[i].msg, socks[i].tosend, MSG_DONTWAIT, &socks[i].addr, ADRSZ);
1686
1802
SPRT_ADDR.sin_port = htons(BASEPORT);
1687
1803
portslotsp = MaxStubs;
1804
portslot[0].hard = 0;
1688
1805
portslot[0].name = PRTSRVNAME;
1689
portslot[0].owner = OWNER(this_node, (unsigned long)port_server);
1806
portslot[0].owner = OWNER(this_node[0], (unsigned long)port_server);
1690
1807
port_server = kmalloc(sizeof(RT_TASK) + 3*sizeof(struct fun_args), GFP_KERNEL);
1691
1808
soft_kthread_init(port_server, (long)port_server_fun, (long)port_server, RT_SCHED_LOWEST_PRIORITY);
1692
1809
portslot[0].task = (long)port_server;