00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include <linux/kernel.h>
00021
#include <linux/module.h>
00022
#include <linux/config.h>
00023
#include <linux/version.h>
00024
#include <linux/timer.h>
00025
#include <linux/unistd.h>
00026
#include <asm/uaccess.h>
00027
00028
#include <net/ip.h>
00029
00030
#include <rtai_schedcore.h>
00031
#include <rtai_netrpc.h>
00032
#include <rtai_sem.h>
00033
#include <rtai_mbx.h>
00034
00035
MODULE_LICENSE(
"GPL");
00036
00037 #define COMPILE_ANYHOW // RTNet is not available but we want to compile anyhow
00038
#include "rtnetP.h"
00039
00040
00041
00042 #define HARD_RTNET 0
00043
00044
#ifdef CONFIG_RTAI_NETRPC_RTNET
00045 #define SOFT_RTNET 1
00046
#else
00047
#define SOFT_RTNET 0
00048
#endif
00049
00050
00051
00052
#if SOFT_RTNET && !HARD_RTNET
00053 #define MSG_SOFT 0
00054 #define MSG_HARD 0
00055 #define hard_rt_socket(a, b, c) portslot[i].socket[0]
00056 #define hard_rt_bind(a, b, c)
00057 #define hard_rt_close(a)
00058 #define hard_rt_socket_callback soft_rt_socket_callback
00059 #define hard_rt_recvfrom soft_rt_recvfrom
00060 #define hard_rt_sendto soft_rt_sendto
00061
#endif
00062
00063
#if !SOFT_RTNET && HARD_RTNET
00064
#ifndef COMPILE_ANYHOW
00065
#include <rtnet.h>
00066
#endif
00067
#define MSG_SOFT 1
00068
#define MSG_HARD 1
00069
#define soft_rt_socket rt_socket
00070
#define soft_rt_bind(a, b, c) rt_bind(a, b, c)
00071
#define soft_rt_close(a) rt_close(a)
00072
#define soft_rt_socket_callback rt_socket_callback
00073
#define soft_rt_recvfrom rt_recvfrom
00074
#define soft_rt_sendto rt_sendto
00075
#define hard_rt_socket(a, b, c) portslot[i].socket[0]
00076
#define hard_rt_bind(a, b, c)
00077
#define hard_rt_close(a)
00078
#define hard_rt_socket_callback rt_socket_callback
00079
#define hard_rt_recvfrom rt_recvfrom
00080
#define hard_rt_sendto rt_sendto
00081
#endif
00082
00083
#if SOFT_RTNET && HARD_RTNET
00084
#ifndef COMPILE_ANYHOW
00085
#include <rtnet.h>
00086
#endif
00087
#define MSG_SOFT 0
00088
#define MSG_HARD 1
00089
#define hard_rt_socket rt_socket
00090
#define hard_rt_bind rt_bind
00091
#define hard_rt_close rt_close
00092
#define hard_rt_socket_callback rt_socket_callback
00093
#define hard_rt_recvfrom rt_recvfrom
00094
#define hard_rt_sendto rt_sendto
00095
#endif
00096
00097 #define LOCALHOST "127.0.0.1"
00098 #define BASEPORT 5000
00099 #define NETRPC_STACK_SIZE 6000
00100
00101 static unsigned long MaxStubs =
MAX_STUBS;
00102
MODULE_PARM(MaxStubs,
"i");
00103 static int MaxStubsMone;
00104
00105 static unsigned long MaxSocks =
MAX_SOCKS;
00106
MODULE_PARM(MaxSocks,
"i");
00107
00108 static int StackSize =
NETRPC_STACK_SIZE;
00109
MODULE_PARM(StackSize,
"i");
00110
00111 static char *
ThisNode =
LOCALHOST;
00112
MODULE_PARM(ThisNode,
"s");
00113
00114 static char *
ThisSoftNode = 0;
00115
MODULE_PARM(ThisSoftNode,
"s");
00116
00117 static char *
ThisHardNode = 0;
00118
MODULE_PARM(ThisHardNode,
"s");
00119
00120 #define MAX_DFUN_EXT 16
00121 static struct rt_fun_entry *
rt_net_rpc_fun_ext[
MAX_DFUN_EXT];
00122
00123 static unsigned long this_node[2];
00124
00125 #define PRTSRVNAME 0xFFFFFFFF
00126 struct portslot_t {
struct portslot_t *
p;
long task;
int indx,
socket[2],
hard;
unsigned long long owner;
SEM sem;
void *
msg;
struct sockaddr_in addr;
MBX *
mbx;
unsigned long name; };
00127 static spinlock_t
portslot_lock = SPIN_LOCK_UNLOCKED;
00128 static volatile int portslotsp;
00129 static struct portslot_t *
portslot;
00130 static struct sockaddr_in
SPRT_ADDR;
00131
00132 static inline struct portslot_t *
get_portslot(
void)
00133 {
00134
unsigned long flags;
00135
00136
flags =
rt_spin_lock_irqsave(&
portslot_lock);
00137
if (
portslotsp <
MaxSocks) {
00138
struct portslot_t *p;
00139 p =
portslot[
portslotsp++].
p;
00140
rt_spin_unlock_irqrestore(
flags, &
portslot_lock);
00141
return p;
00142 }
00143
rt_spin_unlock_irqrestore(
flags, &
portslot_lock);
00144
return 0;
00145 }
00146
00147 static inline int gvb_portslot(
struct portslot_t *portslotp)
00148 {
00149
unsigned long flags;
00150
00151
flags =
rt_spin_lock_irqsave(&
portslot_lock);
00152
if (
portslotsp >
MaxStubs) {
00153
portslot[--
portslotsp].
p = portslotp;
00154
rt_spin_unlock_irqrestore(
flags, &
portslot_lock);
00155
return 0;
00156 }
00157
rt_spin_unlock_irqrestore(
flags, &
portslot_lock);
00158
return -EINVAL;
00159 }
00160
00161 static spinlock_t
req_rel_lock = SPIN_LOCK_UNLOCKED;
00162
00163 static inline int hash_fun(
unsigned long long owner)
00164 {
00165
unsigned short *us;
00166 us = (
unsigned short *)&owner;
00167
return ((us[0] >> 4) + us[3]) &
MaxStubsMone;
00168 }
00169
00170 static inline int hash_ins(
unsigned long long owner)
00171 {
00172
int i, k;
00173
unsigned long flags;
00174
00175 i =
hash_fun(owner);
00176
while (1) {
00177 k = i;
00178
while (
portslot[k].
owner) {
00179
if ((k = (k + 1) &
MaxStubsMone) == i) {
00180
return 0;
00181 }
00182 }
00183
flags =
rt_spin_lock_irqsave(&
req_rel_lock);
00184
if (!
portslot[k].
owner) {
00185
break;
00186 }
00187
rt_spin_unlock_irqrestore(
flags, &
req_rel_lock);
00188 }
00189
portslot[k].
owner = owner;
00190
rt_spin_unlock_irqrestore(
flags, &
req_rel_lock);
00191
return k;
00192 }
00193
00194 static inline int hash_find(
unsigned long long owner)
00195 {
00196
int i, k;
00197
00198 k = i =
hash_fun(owner);
00199
while (
portslot[k].
owner != owner) {
00200
if (!
portslot[k].
owner || (k = (k + 1) &
MaxStubsMone) == i) {
00201
return 0;
00202 }
00203 }
00204
return k;
00205 }
00206
00207 static inline int hash_find_if_not_ins(
unsigned long long owner)
00208 {
00209
int i, k;
00210
unsigned long flags;
00211
00212 i =
hash_fun(owner);
00213
while (1) {
00214 k = i;
00215
while (
portslot[k].
owner &&
portslot[k].
owner != owner) {
00216
if ((k = (k + 1) &
MaxStubsMone) == i) {
00217
return 0;
00218 }
00219 }
00220
flags =
rt_spin_lock_irqsave(&
req_rel_lock);
00221
if (
portslot[k].
owner == owner) {
00222
rt_spin_unlock_irqrestore(
flags, &
req_rel_lock);
00223
return k;
00224 }
else if (!
portslot[k].
owner) {
00225
break;
00226 }
00227
rt_spin_unlock_irqrestore(
flags, &
req_rel_lock);
00228 }
00229
portslot[k].
owner = owner;
00230
rt_spin_unlock_irqrestore(
flags, &
req_rel_lock);
00231
return k;
00232 }
00233
00234 static inline int hash_rem(
unsigned long long owner)
00235 {
00236
int i, k;
00237
unsigned long flags;
00238
00239 i =
hash_fun(owner);
00240
while (1) {
00241 k = i;
00242
while (
portslot[k].
owner != owner) {
00243
if (!
portslot[k].
owner || (k = (k + 1) &
MaxStubsMone) == i) {
00244
return 0;
00245 }
00246 }
00247
flags =
rt_spin_lock_irqsave(&
req_rel_lock);
00248
if (
portslot[k].
owner == owner) {
00249
break;
00250 }
00251
rt_spin_unlock_irqrestore(
flags, &
req_rel_lock);
00252 }
00253
portslot[k].
owner = 0;
00254
rt_spin_unlock_irqrestore(
flags, &
req_rel_lock);
00255
return k;
00256 }
00257
00258 #define NETRPC_TIMER_FREQ 50
00259 static struct timer_list
timer;
00260 static SEM timer_sem;
00261
00262 static void timer_fun(
unsigned long none)
00263 {
00264
if (
timer_sem.count < 0) {
00265
rt_sem_signal(&
timer_sem);
00266
timer.expires = jiffies + (HZ +
NETRPC_TIMER_FREQ/2 - 1)/
NETRPC_TIMER_FREQ;
00267 add_timer(&
timer);
00268 }
00269 }
00270
00271 static int (*encode)(
struct portslot_t *portslotp,
void *msg,
int size,
int where);
00272 static int (*decode)(
struct portslot_t *portslotp,
void *msg,
int size,
int where);
00273
00274 void set_netrpc_encoding(
void *encode_fun,
void *decode_fun,
void *ext)
00275 {
00276
encode = encode_fun;
00277
decode = decode_fun;
00278
rt_net_rpc_fun_ext[1] = ext;
00279 }
00280
00281 struct req_rel_msg {
int op,
port,
priority,
hard;
unsigned long long owner;
unsigned long name,
chkspare;};
00282
00283 static void net_resume_task(
int sock,
SEM *sem)
00284 {
00285
rt_sem_signal(sem);
00286 }
00287
00288
int get_min_tasks_cpuid(
void);
00289
int set_rtext(
RT_TASK *,
int,
int,
void(*)(
void),
unsigned int,
void *);
00290
int clr_rtext(
RT_TASK *);
00291
void rt_schedule_soft(
RT_TASK *);
00292
00293 static inline int soft_rt_fun_call(
RT_TASK *task,
void *fun,
void *arg)
00294 {
00295
task->fun_args[0] = (
long)arg;
00296 ((
struct fun_args *)
task->fun_args)->fun = fun;
00297
rt_schedule_soft(
task);
00298
return (
int)
task->retval;
00299 }
00300
00301 static inline long long soft_rt_genfun_call(
RT_TASK *task,
void *fun,
void *args,
int argsize)
00302 {
00303 memcpy(
task->fun_args, args, argsize);
00304 ((
struct fun_args *)
task->fun_args)->fun = fun;
00305
rt_schedule_soft(
task);
00306
return task->retval;
00307 }
00308
00309 static void thread_fun(
RT_TASK *task)
00310 {
00311
if (!
set_rtext(
task,
task->fun_args[3], 0, 0,
get_min_tasks_cpuid(), 0)) {
00312 sigfillset(¤t->blocked);
00313 rtai_set_linux_task_priority(current, SCHED_FIFO, MIN_LINUX_RTPRIO);
00314
soft_rt_fun_call(
task,
rt_task_suspend,
task);
00315 ((void (*)(
long))
task->fun_args[1])(
task->fun_args[2]);
00316 }
00317 }
00318
00319 static int soft_kthread_init(
RT_TASK *task,
long fun,
long arg,
int priority)
00320 {
00321
task->magic =
task->state = 0;
00322 (
task->fun_args = (
long *)(
task + 1))[1] = fun;
00323
task->fun_args[2] = arg;
00324
task->fun_args[3] = priority;
00325
if (kernel_thread((
void *)
thread_fun,
task, 0) > 0) {
00326
while (
task->state != (
RT_SCHED_READY |
RT_SCHED_SUSPENDED)) {
00327 current->state = TASK_INTERRUPTIBLE;
00328 schedule_timeout((HZ +
NETRPC_TIMER_FREQ/2 - 1)/
NETRPC_TIMER_FREQ);
00329 }
00330
return 0;
00331 }
00332
return -ENOEXEC;
00333 }
00334
00335 static int soft_kthread_delete(
RT_TASK *task)
00336 {
00337
if (
clr_rtext(
task)) {
00338
return -EFAULT;
00339 }
else {
00340
struct task_struct *lnxtsk =
task->lnxtsk;
00341
00342 sigemptyset(&lnxtsk->blocked);
00343 lnxtsk->state = TASK_INTERRUPTIBLE;
00344 kill_proc(lnxtsk->pid, SIGTERM, 0);
00345 }
00346
return 0;
00347 }
00348
00349 #define ADRSZ sizeof(struct sockaddr)
00350
00351 static void soft_stub_fun(
struct portslot_t *portslotp)
00352 {
00353
char msg[
MAX_MSG_SIZE];
00354
struct sockaddr *addr;
00355
RT_TASK *
task;
00356
SEM *sem;
00357
struct par_t {
int priority, base_priority, argsize, rsize, fun_ext_timed;
long type;
long a[1]; } *par;
00358
int wsize, w2size, sock;
00359
long *a;
00360
long type;
00361
00362 addr = (
struct sockaddr *)&portslotp->
addr;
00363 sock = portslotp->
socket[0];
00364 sem = &portslotp->
sem;
00365 a = (par = (
void *)msg)->a;
00366
task = (
RT_TASK *)portslotp->
task;
00367 sprintf(current->comm,
"SFTSTB-%d", sock);
00368
00369
while (
soft_rt_fun_call(
task,
rt_sem_wait, sem) !=
SEM_ERR) {
00370 wsize =
soft_rt_recvfrom(sock, msg,
MAX_MSG_SIZE, 0, addr, &w2size);
00371
if (
decode) {
00372
decode(portslotp, msg, wsize,
RPC_SRV);
00373 }
00374
if(par->priority >= 0 && par->priority <
RT_SCHED_LINUX_PRIORITY) {
00375
if ((wsize = par->priority) <
task->priority) {
00376
task->priority = wsize;
00377 rtai_set_linux_task_priority(
task->lnxtsk,
task->lnxtsk->policy, wsize >= MAX_LINUX_RTPRIO ? MIN_LINUX_RTPRIO : MAX_LINUX_RTPRIO - wsize);
00378 }
00379
task->base_priority = par->base_priority;
00380 }
00381 type = par->type;
00382
if (par->rsize) {
00383 a[USP_RBF1(type) - 1] = (
long)((
char *)a + par->argsize);
00384 }
00385
if (NEED_TO_W(type)) {
00386 wsize = USP_WSZ1(type);
00387 wsize = wsize ? a[wsize - 1] :
sizeof(
long);
00388 }
else {
00389 wsize = 0;
00390 }
00391
if (NEED_TO_W2ND(type)) {
00392 w2size = USP_WSZ2(type);
00393 w2size = w2size ? a[w2size - 1] :
sizeof(
long);
00394 }
else {
00395 w2size = 0;
00396 }
00397
do {
00398
struct msg_t {
int wsize, w2size;
unsigned long long retval;
char msg_buf[wsize], msg_buf2[w2size]; } arg;
00399
if (wsize > 0) {
00400 arg.wsize = wsize;
00401 a[USP_WBF1(type) - 1] = (
long)arg.msg_buf;
00402 }
else {
00403 arg.wsize = 0;
00404 }
00405
if (w2size > 0) {
00406 arg.w2size = w2size;
00407 a[USP_WBF2(type) - 1] = (
long)arg.msg_buf2;
00408 }
else {
00409 arg.w2size = 0;
00410 }
00411
if ((wsize =
TIMED(par->fun_ext_timed) - 1) >= 0) {
00412 *((
long long *)(a + wsize)) =
nano2count(*((
long long *)(a + wsize)));
00413 }
00414 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);
00415
soft_rt_sendto(sock, &arg,
encode ?
encode(portslotp, &arg,
sizeof(
struct msg_t),
RPC_RTR) :
sizeof(
struct msg_t), 0, addr,
ADRSZ);
00416 }
while (0);
00417 }
00418
00419 }
00420
00421 static void hard_stub_fun(
struct portslot_t *portslotp)
00422 {
00423
char msg[
MAX_MSG_SIZE];
00424
struct sockaddr *addr;
00425
RT_TASK *
task;
00426
SEM *sem;
00427
struct par_t {
int priority, base_priority, argsize, rsize, fun_ext_timed;
long type;
long a[1]; } *par;
00428
int wsize, w2size, sock;
00429
long *a;
00430
long type;
00431
00432 addr = (
struct sockaddr *)&portslotp->
addr;
00433 sock = portslotp->
socket[1];
00434 sem = &portslotp->
sem;
00435 a = (par = (
void *)msg)->a;
00436
task = (
RT_TASK *)portslotp->
task;
00437 sprintf(current->comm,
"HRDSTB-%d", sock);
00438
00439
while (
rt_sem_wait(sem) !=
SEM_ERR) {
00440 wsize =
hard_rt_recvfrom(sock, msg,
MAX_MSG_SIZE, 0, addr, &w2size);
00441
if (
decode) {
00442
decode(portslotp, msg, wsize,
RPC_SRV);
00443 }
00444
if(par->priority >= 0 && par->priority <
RT_SCHED_LINUX_PRIORITY) {
00445
if ((wsize = par->priority) <
task->priority) {
00446
task->priority = wsize;
00447 }
00448
task->base_priority = par->base_priority;
00449 }
00450 type = par->type;
00451
if (par->rsize) {
00452 a[USP_RBF1(type) - 1] = (
long)((
char *)a + par->argsize);
00453 }
00454
if (NEED_TO_W(type)) {
00455 wsize = USP_WSZ1(type);
00456 wsize = wsize ? a[wsize - 1] :
sizeof(
long);
00457 }
else {
00458 wsize = 0;
00459 }
00460
if (NEED_TO_W2ND(type)) {
00461 w2size = USP_WSZ2(type);
00462 w2size = w2size ? a[w2size - 1] :
sizeof(
long);
00463 }
else {
00464 w2size = 0;
00465 }
00466
do {
00467
struct msg_t {
int wsize, w2size;
unsigned long long retval;
char msg_buf[wsize], msg_buf2[w2size]; } arg;
00468
if (wsize > 0) {
00469 arg.wsize = wsize;
00470 a[USP_WBF1(type) - 1] = (
long)arg.msg_buf;
00471 }
else {
00472 arg.wsize = 0;
00473 }
00474
if (w2size > 0) {
00475 arg.w2size = w2size;
00476 a[USP_WBF2(type) - 1] = (
long)arg.msg_buf2;
00477 }
else {
00478 arg.w2size = 0;
00479 }
00480
if ((wsize =
TIMED(par->fun_ext_timed) - 1) >= 0) {
00481 *((
long long *)(a + wsize)) =
nano2count(*((
long long *)(a + wsize)));
00482 }
00483 arg.retval = ((
long long (*)(
long, ...))
rt_net_rpc_fun_ext[
EXT(par->fun_ext_timed)][
FUN(par->fun_ext_timed)].fun)(RTAI_FUN_A);
00484
hard_rt_sendto(sock, &arg,
encode ?
encode(portslotp, &arg,
sizeof(
struct msg_t),
RPC_RTR) :
sizeof(
struct msg_t), 0, addr,
ADRSZ);
00485 }
while (0);
00486 }
00487
rt_task_suspend(
task);
00488 }
00489
00490 static void trashmsg(
struct portslot_t *portslotp,
int hard)
00491 {
00492
char msg[
MAX_MSG_SIZE];
00493
if (hard) {
00494
hard_rt_recvfrom(portslotp->
socket[hard], msg,
MAX_MSG_SIZE, MSG_DONTWAIT, (
void *)msg, (
void *)msg);
00495 }
else {
00496
soft_rt_recvfrom(portslotp->
socket[hard], msg,
MAX_MSG_SIZE, MSG_DONTWAIT, (
void *)msg, (
void *)msg);
00497 }
00498 }
00499
00500 static void port_server_fun(
RT_TASK *port_server)
00501 {
00502
int i, rsize;
00503
RT_TASK *
task;
00504
unsigned long flags;
00505
struct sockaddr *addr;
00506
struct req_rel_msg msg;
00507
00508 addr = (
struct sockaddr *)&
portslot[0].
addr;
00509 sprintf(current->comm,
"PRTSRV");
00510
00511
while (
soft_rt_fun_call(
port_server,
rt_sem_wait, &
portslot[0].sem) !=
SEM_ERR) {
00512
if ((rsize =
hard_rt_recvfrom(
portslot[0].socket[1], &msg,
sizeof(msg), MSG_DONTWAIT, addr, &i)) <= 0) {
00513 rsize =
soft_rt_recvfrom(
portslot[0].socket[0], &msg,
sizeof(msg), 0, addr, &i);
00514 }
00515
if (
decode) {
00516
decode(&
portslot[0], &msg, rsize,
PRT_SRV);
00517 }
00518
if (msg.op) {
00519 i = msg.op -
BASEPORT;
00520
if (i > 0 && i <
MaxStubs) {
00521
flags =
rt_spin_lock_irqsave(&
req_rel_lock);
00522
if (
portslot[i].
owner == msg.owner) {
00523
task = (
RT_TASK *)
portslot[i].
task;
00524
portslot[i].
task = 0;
00525
portslot[i].
owner = 0;
00526 msg.port = msg.op;
00527
rt_spin_unlock_irqrestore(
flags, &
req_rel_lock);
00528
if (
task->is_hard) {
00529
rt_task_delete(
task);
00530 }
else {
00531
soft_kthread_delete(
task);
00532 }
00533 kfree(
task);
00534 }
else {
00535 msg.port = !
portslot[i].
owner ? msg.op : -ENXIO;
00536
rt_spin_unlock_irqrestore(
flags, &
req_rel_lock);
00537 }
00538 }
else {
00539 msg.port = -EINVAL;
00540 }
00541
goto ret;
00542 }
00543
if ((msg.port =
hash_find_if_not_ins(msg.owner)) <= 0) {
00544 msg.port = -ENODEV;
00545
goto ret;
00546 }
00547
if (!
portslot[msg.port].
task) {
00548
if ((
task = kmalloc(
sizeof(
RT_TASK) + 2*
sizeof(
struct fun_args), GFP_KERNEL))) {
00549
if ((msg.hard ?
rt_task_init(
task, (
void *)
hard_stub_fun, (
long)(
portslot + msg.port),
StackSize + 2*
MAX_MSG_SIZE, msg.priority, 0, 0) :
soft_kthread_init(
task, (
long)
soft_stub_fun, (
long)(
portslot + msg.port), msg.priority < BASE_SOFT_PRIORITY ? msg.priority + BASE_SOFT_PRIORITY : msg.priority))) {
00550 kfree(
task);
00551
task = 0;
00552 }
00553 }
00554
if (!
task) {
00555
portslot[msg.port].
owner = 0;
00556 msg.port = -ENOMEM;
00557
goto ret;
00558 }
00559
trashmsg(
portslot + msg.port, msg.
hard);
00560
portslot[msg.port].
name = msg.name;
00561
portslot[msg.port].
task = (
unsigned long)(
task);
00562
portslot[msg.port].
sem.count = 0;
00563
portslot[msg.port].
sem.queue.prev =
portslot[msg.port].
sem.queue.next = &
portslot[msg.port].
sem.queue;
00564
rt_task_resume(
task);
00565 }
00566 msg.port +=
BASEPORT;
00567 ret:
00568
if (msg.hard) {
00569
hard_rt_sendto(
portslot[0].socket[1], &msg,
encode ?
encode(&
portslot[0], &msg,
sizeof(msg),
PRT_RTR) :
sizeof(msg), 0, addr,
ADRSZ);
00570 }
else {
00571
soft_rt_sendto(
portslot[0].socket[0], &msg,
encode ?
encode(&
portslot[0], &msg,
sizeof(msg),
PRT_RTR) :
sizeof(msg), 0, addr,
ADRSZ);
00572 }
00573 }
00574
00575 }
00576
00577 static int mod_timer_srq;
00578
00579 int rt_send_req_rel_port(
unsigned long node,
int op,
unsigned long id,
MBX *mbx,
int hard)
00580 {
00581
RT_TASK *
task;
00582
int i, msgsize;
00583
struct portslot_t *portslotp;
00584
struct req_rel_msg msg;
00585
00586
00587
if (!node || (op && (op < MaxStubs || op >=
MaxSocks))) {
00588
return -EINVAL;
00589 }
00590
if (!(portslotp =
get_portslot())) {
00591
return -ENODEV;
00592 }
00593 portslotp->
name =
PRTSRVNAME;
00594 portslotp->addr =
SPRT_ADDR;
00595 portslotp->addr.sin_addr.s_addr = node;
00596
task = _rt_whoami();
00597
if (op) {
00598 msg.
op = ntohs(
portslot[op].addr.sin_port);
00599
id =
portslot[op].
name;
00600 }
else {
00601 msg.
op = 0;
00602
if (!
id) {
00603
id = (
unsigned long)
task;
00604 }
00605 }
00606 msg.
port = portslotp->sem.count = 0;
00607 portslotp->sem.queue.prev = portslotp->sem.queue.next = &portslotp->sem.queue;
00608 msg.
hard = hard ?
MSG_HARD :
MSG_SOFT;
00609 msg.
name =
id;
00610 msg.
owner =
OWNER(
this_node[msg.
hard],
id);
00611 msg.
priority =
task->base_priority;
00612
trashmsg(
portslot + msg.
port, msg.
hard);
00613 msgsize =
encode ?
encode(&
portslot[0], &msg,
sizeof(msg),
PRT_REQ) :
sizeof(msg);
00614
for (i = 0; i <
NETRPC_TIMER_FREQ && !portslotp->sem.count; i++) {
00615
if (msg.hard) {
00616
hard_rt_sendto(portslotp->socket[1], &msg, msgsize, 0, (
void *)&portslotp->addr,
ADRSZ);
00617 }
else {
00618
soft_rt_sendto(portslotp->socket[0], &msg, msgsize, 0, (
void *)&portslotp->addr,
ADRSZ);
00619 }
00620
rt_pend_linux_srq(
mod_timer_srq);
00621
rt_sem_wait(&
timer_sem);
00622 }
00623
if (portslotp->sem.count >= 1) {
00624 msgsize = msg.hard ?
hard_rt_recvfrom(portslotp->socket[1], &msg,
sizeof(msg), 0, (
void *)&portslotp->addr, &i) :
soft_rt_recvfrom(portslotp->socket[0], &msg,
sizeof(msg), 0, (
void *)&portslotp->addr, &i);
00625
if (
decode) {
00626
decode(&
portslot[0], &msg, msgsize,
PRT_RCV);
00627 }
00628
if (msg.port > 0) {
00629
if (op) {
00630
portslot[op].
task = 0;
00631
gvb_portslot(
portslot + op);
00632
gvb_portslot(portslotp);
00633
return op;
00634 }
else {
00635
trashmsg(
portslot + msg.port, msg.
hard);
00636 portslotp->sem.count = 0;
00637 portslotp->sem.queue.prev = portslotp->sem.queue.next = &portslotp->sem.queue;
00638 portslotp->hard = msg.hard;
00639 portslotp->owner = msg.owner;
00640 portslotp->name = msg.name;
00641 portslotp->addr.sin_port = htons(msg.port);
00642 portslotp->mbx = mbx;
00643 portslotp->task = 1;
00644
return portslotp->indx;
00645 }
00646 }
00647 }
00648
gvb_portslot(portslotp);
00649
return msg.port ? msg.port : -ETIMEDOUT;
00650 }
00651
00652 RT_TASK *
rt_find_asgn_stub(
unsigned long long owner,
int asgn)
00653 {
00654
int i;
00655 i = asgn ?
hash_find_if_not_ins(owner) :
hash_find(owner);
00656
return i > 0 ? (
RT_TASK *)
portslot[i].
task : 0;
00657 }
00658
00659 int rt_rel_stub(
unsigned long long owner)
00660 {
00661
return hash_rem(owner) > 0 ? 0 : -ESRCH;
00662 }
00663
00664 int rt_waiting_return(
unsigned long node,
int port)
00665 {
00666
struct portslot_t *portslotp;
00667 portslotp =
portslot + abs(port);
00668
return portslotp->task < 0 && !portslotp->sem.count;
00669 }
00670
00671
#if 0
00672
00673
static inline void mbx_send_if(
MBX *mbx,
void *sendmsg,
int msg_size)
00674 {
00675
#define MOD_SIZE(indx) ((indx) < mbx->size ? (indx) : (indx) - mbx->size)
00676
00677
unsigned long flags;
00678
int tocpy, avbs;
00679
char *msg;
00680
00681
if (!mbx) {
00682
return;
00683 }
00684 msg = sendmsg;
00685
if (msg_size <= mbx->frbs) {
00686
RT_TASK *
task;
00687 avbs = mbx->avbs;
00688
while (msg_size > 0 && mbx->frbs) {
00689
if ((tocpy = mbx->size - mbx->lbyte) > msg_size) {
00690 tocpy = msg_size;
00691 }
00692
if (tocpy > mbx->frbs) {
00693 tocpy = mbx->frbs;
00694 }
00695 memcpy(mbx->bufadr + mbx->lbyte, msg, tocpy);
00696
flags =
rt_spin_lock_irqsave(&mbx->lock);
00697 mbx->frbs -= tocpy;
00698
rt_spin_unlock_irqrestore(flags, &mbx->lock);
00699 avbs += tocpy;
00700 msg_size -= tocpy;
00701 *msg += tocpy;
00702 mbx->lbyte =
MOD_SIZE(mbx->lbyte + tocpy);
00703 }
00704 mbx->avbs = avbs;
00705
flags = rt_global_save_flags_and_cli();
00706
if ((
task = mbx->waiting_task)) {
00707 rem_timed_task(task);
00708 mbx->waiting_task = (
void *)0;
00709
if (
task->state !=
RT_SCHED_READY && (
task->state &= ~(
RT_SCHED_MBXSUSP |
RT_SCHED_DELAYED)) ==
RT_SCHED_READY) {
00710 enq_ready_task(task);
00711
rt_schedule();
00712 }
00713 }
00714 rt_global_restore_flags(flags);
00715 }
00716 }
00717
00718
#else
00719
00720 static inline void mbx_signal(
MBX *mbx)
00721 {
00722
unsigned long flags;
00723
RT_TASK *
task;
00724
int tosched;
00725
00726
flags = rt_global_save_flags_and_cli();
00727
if ((
task = mbx->waiting_task)) {
00728 rem_timed_task(
task);
00729
task->blocked_on = NOTHING;
00730
task->prio_passed_to = mbx->waiting_task = NOTHING;
00731
if (
task->state !=
RT_SCHED_READY && (
task->state &= ~(
RT_SCHED_MBXSUSP |
RT_SCHED_DELAYED)) ==
RT_SCHED_READY) {
00732 enq_ready_task(
task);
00733
if (mbx->sndsem.type <= 0) {
00734 RT_SCHEDULE(
task, rtai_cpuid());
00735 rt_global_restore_flags(
flags);
00736
return;
00737 }
00738 tosched = 1;
00739
goto res;
00740 }
00741 }
00742 tosched = 0;
00743 res:
if (mbx->sndsem.type > 0) {
00744 DECLARE_RT_CURRENT;
00745
int sched;
00746 ASSIGN_RT_CURRENT;
00747 mbx->owndby = 0;
00748
if (rt_current->owndres & SEMHLF) {
00749 --rt_current->owndres;
00750 }
00751
if (!rt_current->owndres) {
00752 sched = renq_current(rt_current, rt_current->base_priority);
00753 }
else if (!(rt_current->owndres & SEMHLF)) {
00754
int priority;
00755 sched = renq_current(rt_current, rt_current->base_priority > (priority = ((rt_current->msg_queue.next)->task)->priority) ? priority : rt_current->base_priority);
00756 }
else {
00757 sched = 0;
00758 }
00759
if (rt_current->suspdepth) {
00760
if (rt_current->suspdepth > 0) {
00761 rt_current->state |=
RT_SCHED_SUSPENDED;
00762 rem_ready_current(rt_current);
00763 sched = 1;
00764 }
else {
00765
rt_task_delete(rt_current);
00766 }
00767 }
00768
if (sched) {
00769
if (tosched) {
00770 RT_SCHEDULE_BOTH(
task,
cpuid);
00771 }
else {
00772
rt_schedule();
00773 }
00774 }
else if (tosched) {
00775 RT_SCHEDULE(
task,
cpuid);
00776 }
00777 }
00778 rt_global_restore_flags(
flags);
00779 }
00780
00781 #define MOD_SIZE(indx) ((indx) < mbx->size ? (indx) : (indx) - mbx->size)
00782
00783 static inline int mbxput(
MBX *mbx,
char **msg,
int msg_size)
00784 {
00785
unsigned long flags;
00786
int tocpy;
00787
00788
while (msg_size > 0 && mbx->frbs) {
00789
if ((tocpy = mbx->size - mbx->lbyte) > msg_size) {
00790 tocpy = msg_size;
00791 }
00792
if (tocpy > mbx->frbs) {
00793 tocpy = mbx->frbs;
00794 }
00795 memcpy(mbx->bufadr + mbx->lbyte, *msg, tocpy);
00796
flags =
rt_spin_lock_irqsave(&(mbx->lock));
00797 mbx->frbs -= tocpy;
00798 mbx->avbs += tocpy;
00799
rt_spin_unlock_irqrestore(
flags, &(mbx->lock));
00800 msg_size -= tocpy;
00801 *msg += tocpy;
00802 mbx->lbyte =
MOD_SIZE(mbx->lbyte + tocpy);
00803 }
00804
return msg_size;
00805 }
00806
00807 static void mbx_send_if(
MBX *mbx,
void *msg,
int msg_size)
00808 {
00809
unsigned long flags;
00810
RT_TASK *rt_current;
00811
00812
if (!mbx || mbx->magic !=
RT_MBX_MAGIC) {
00813
return;
00814 }
00815
00816
flags = rt_global_save_flags_and_cli();
00817 rt_current = RT_CURRENT;
00818
if (mbx->sndsem.count && msg_size <= mbx->frbs) {
00819 mbx->sndsem.count = 0;
00820
if (mbx->sndsem.type > 0) {
00821 (mbx->sndsem.owndby = mbx->owndby = rt_current)->owndres += 2;
00822 }
00823 rt_global_restore_flags(
flags);
00824
mbxput(mbx, (
char **)(&msg), msg_size);
00825
mbx_signal(mbx);
00826
rt_sem_signal(&mbx->sndsem);
00827 }
00828 rt_global_restore_flags(
flags);
00829 }
00830
00831
#endif
00832
00833 unsigned long long rt_net_rpc(
long fun_ext_timed,
long type,
void *args,
int argsize,
int space)
00834 {
00835
char msg[
MAX_MSG_SIZE];
00836
struct reply_t {
int wsize, w2size;
unsigned long long retval;
char msg[1]; } *reply;
00837
int rsize, port;
00838
struct portslot_t *portslotp;
00839
00840
if ((port =
PORT(fun_ext_timed)) > 0) {
00841
if ((portslotp =
portslot + port)->task < 0) {
00842
int i;
00843
struct sockaddr addr;
00844
rt_sem_wait(&portslotp->sem);
00845
if ((rsize = portslotp->hard ?
hard_rt_recvfrom(portslotp->socket[1], msg,
MAX_MSG_SIZE, 0, &addr, &i) :
soft_rt_recvfrom(portslotp->socket[0], msg,
MAX_MSG_SIZE, 0, &addr, &i))) {
00846
if (
decode) {
00847 rsize =
decode(portslotp, msg, rsize,
RPC_RCV);
00848 }
00849
mbx_send_if(portslotp->mbx, msg, rsize);
00850 }
00851 portslotp->task = 1;
00852 }
00853 portslotp->msg = msg;
00854 }
else {
00855
if ((portslotp =
portslot - port)->task < 0) {
00856
if (!
rt_sem_wait_if(&portslotp->sem)) {
00857
return 0;
00858 }
else {
00859
int i;
00860
struct sockaddr addr;
00861
if ((rsize = portslotp->hard ?
hard_rt_recvfrom(portslotp->socket[1], msg,
MAX_MSG_SIZE, 0, &addr, &i) :
soft_rt_recvfrom(portslotp->socket[0], msg,
MAX_MSG_SIZE, 0, &addr, &i))) {
00862
if (
decode) {
00863 rsize =
decode(portslotp, msg, rsize,
RPC_RCV);
00864 }
00865
mbx_send_if(portslotp->mbx, msg, rsize);
00866 }
00867 }
00868 }
else {
00869 portslotp->task = -1;
00870 }
00871 }
00872
if (
FUN(fun_ext_timed) ==
SYNC_NET_RPC) {
00873
return 1;
00874 }
00875
if (NEED_TO_R(type)) {
00876 rsize = USP_RSZ1(type);
00877 rsize = rsize ? ((
long *)args)[rsize - 1] :
sizeof(
long);
00878 }
else {
00879 rsize = 0;
00880 }
00881
do {
00882
struct msg_t {
int priority, base_priority, argsize, rsize, fun_ext_timed;
long type;
long args[1]; } *arg;
00883
RT_TASK *
task;
00884
00885 arg = (
void *)msg;
00886 arg->priority = (
task = _rt_whoami())->priority;
00887 arg->base_priority =
task->base_priority;
00888 arg->argsize = argsize;
00889 arg->rsize = rsize;
00890 arg->fun_ext_timed = fun_ext_timed;
00891 arg->type = type;
00892 memcpy(arg->args, args, argsize);
00893
if (rsize > 0) {
00894
if (space) {
00895 memcpy((
char *)arg->args + argsize, (
void *)((
long *)args + USP_RBF1(type) - 1)[0], rsize);
00896 }
else {
00897 rt_copy_from_user((
char *)arg->args + argsize, (
void *)((
long *)args + USP_RBF1(type) - 1)[0], rsize);
00898 }
00899 }
00900 rsize =
sizeof(
struct msg_t) - sizeof(long) + argsize + rsize;
00901
if (
encode) {
00902 rsize =
encode(portslotp, msg, rsize,
RPC_REQ);
00903 }
00904
if (portslotp->hard) {
00905
hard_rt_sendto(portslotp->socket[1], msg, rsize, 0, (
struct sockaddr *)&portslotp->addr,
ADRSZ);
00906 }
else {
00907
soft_rt_sendto(portslotp->socket[0], msg, rsize, 0, (
struct sockaddr *)&portslotp->addr,
ADRSZ);
00908 }
00909 }
while (0);
00910
if (port > 0) {
00911
struct sockaddr addr;
00912
rt_sem_wait(&portslotp->sem);
00913 rsize = portslotp->hard ?
hard_rt_recvfrom(portslotp->socket[1], msg,
MAX_MSG_SIZE, 0, &addr, &port) :
soft_rt_recvfrom(portslotp->socket[0], msg,
MAX_MSG_SIZE, 0, &addr, &port);
00914
if (
decode) {
00915
decode(portslotp, portslotp->msg, rsize,
RPC_RCV);
00916 }
00917
if ((reply = (
void *)msg)->wsize) {
00918
if (space) {
00919 memcpy((
char *)(*((
long *)args + USP_WBF1(type) - 1)), reply->msg, reply->wsize);
00920 }
else {
00921 rt_copy_to_user((
char *)(*((
long *)args + USP_WBF1(type) - 1)), reply->msg, reply->wsize);
00922 }
00923
if (reply->w2size) {
00924
if (space) {
00925 memcpy((
char *)(*((
long *)args + USP_WBF2(type) - 1)), reply->msg + reply->wsize, reply->w2size);
00926 }
else {
00927 rt_copy_to_user((
char *)(*((
long *)args + USP_WBF2(type) - 1)), reply->msg + reply->wsize, reply->w2size);
00928 }
00929 }
00930 }
00931
return reply->retval;
00932 }
00933
return 0;
00934 }
00935
00936 int rt_get_net_rpc_ret(
MBX *mbx,
unsigned long long *retval,
void *msg1,
int *msglen1,
void *msg2,
int *msglen2,
RTIME timeout,
int type)
00937 {
00938
struct {
int wsize, w2size;
unsigned long long retval; } reply;
00939
int ret;
00940
00941
if ((ret = ((int (*)(
MBX *, ...))
rt_net_rpc_fun_ext[
NET_RPC_EXT][type].fun)(mbx, &reply,
sizeof(reply), timeout))) {
00942
return ret;
00943 }
00944 *retval = reply.retval;
00945
if (reply.wsize) {
00946
if (*msglen1 > reply.wsize) {
00947 *msglen1 = reply.wsize;
00948 }
00949
_rt_mbx_receive(mbx, &msg1, *msglen1, 1);
00950 }
else {
00951 *msglen1 = 0;
00952 }
00953
if (reply.w2size) {
00954
if (*msglen2 > reply.w2size) {
00955 *msglen2 = reply.w2size;
00956 }
00957
_rt_mbx_receive(mbx, &msg2, *msglen2, 1);
00958 }
else {
00959 *msglen2 = 0;
00960 }
00961
return 0;
00962 }
00963
00964 unsigned long ddn2nl(
const char *ddn)
00965 {
00966
int p, n, c;
00967
union {
unsigned long l;
char c[4]; } u;
00968
00969 p = n = 0;
00970
while ((c = *ddn++)) {
00971
if (c !=
'.') {
00972 n = n*10 + c -
'0';
00973 }
else {
00974
if (n > 0xFF) {
00975
return 0;
00976 }
00977 u.c[p++] = n;
00978 n = 0;
00979 }
00980 }
00981 u.c[3] = n;
00982
00983
return u.l;
00984 }
00985
00986 unsigned long rt_set_this_node(
const char *ddn,
unsigned long node,
int hard)
00987 {
00988
return this_node[hard ?
MSG_HARD :
MSG_SOFT] = ddn ?
ddn2nl(ddn) : node;
00989 }
00990
00991
00992
00993 struct rt_native_fun_entry
rt_netrpc_entries[] = {
00994 { { 1,
rt_net_rpc },
NETRPC },
00995 { { 1,
rt_send_req_rel_port },
SEND_REQ_REL_PORT },
00996 { { 0,
ddn2nl },
DDN2NL },
00997 { { 0,
rt_set_this_node },
SET_THIS_NODE },
00998 { { 0,
rt_find_asgn_stub },
FIND_ASGN_STUB },
00999 { { 0,
rt_rel_stub },
REL_STUB },
01000 { { 0,
rt_waiting_return },
WAITING_RETURN },
01001 { { 0, 0 }, 000 }
01002 };
01003
01004
extern int set_rt_fun_entries(
struct rt_native_fun_entry *entry);
01005
extern void reset_rt_fun_entries(
struct rt_native_fun_entry *entry);
01006
01007 static RT_TASK *
port_server;
01008
01009
static int init_softrtnet(
void);
01010
static void cleanup_softrtnet(
void);
01011
01012 void do_mod_timer(
void)
01013 {
01014 mod_timer(&
timer, jiffies + (HZ +
NETRPC_TIMER_FREQ/2 - 1)/
NETRPC_TIMER_FREQ);
01015 }
01016
01017
#ifdef CONFIG_RTAI_NETRPC_RTNET
01018
01019 static struct sock_t *
socks;
01020
01021 int soft_rt_socket(
int domain,
int type,
int protocol)
01022 {
01023
int i;
01024
for (i = 0; i <
MaxSocks; i++) {
01025
if (!
cmpxchg(&
socks[i].opnd, 0, 1)) {
01026
return i;
01027 }
01028 }
01029
return -1;
01030 }
01031
01032 int soft_rt_close(
int sock)
01033 {
01034
if (sock >= 0 && sock <
MaxSocks) {
01035
return socks[sock].
opnd = 0;
01036 }
01037
return -1;
01038 }
01039
01040 int soft_rt_bind(
int sock,
struct sockaddr *addr,
int addrlen)
01041 {
01042
return 0;
01043 }
01044
01045 int soft_rt_socket_callback(
int sock,
int (*func)(
int sock,
void *arg),
void *arg)
01046 {
01047
if (sock >= 0 && sock < MaxSocks && func > 0) {
01048
socks[sock].
callback = func;
01049
socks[sock].
arg = arg;
01050
return 0;
01051 }
01052
return -1;
01053 }
01054
01055 static int MaxSockSrq;
01056 static struct {
int srq,
in,
out, *
sockindx; }
sysrq;
01057 static spinlock_t
sysrq_lock = SPIN_LOCK_UNLOCKED;
01058
01059 int soft_rt_sendto(
int sock,
const void *msg,
int msglen,
unsigned int sflags,
struct sockaddr *to,
int tolen)
01060 {
01061
unsigned long flags;
01062
if (sock >= 0 && sock <
MaxSocks) {
01063
if (msglen >
MAX_MSG_SIZE) {
01064 msglen =
MAX_MSG_SIZE;
01065 }
01066 memcpy(
socks[sock].msg, msg,
socks[sock].tosend = msglen);
01067 memcpy(&
socks[sock].addr, to, tolen);
01068
flags =
rt_spin_lock_irqsave(&
sysrq_lock);
01069
sysrq.sockindx[
sysrq.in] = sock;
01070
sysrq.in = (
sysrq.in + 1) &
MaxSockSrq;
01071
rt_spin_unlock_irqrestore(
flags, &
sysrq_lock);
01072
rt_pend_linux_srq(
sysrq.srq);
01073
return msglen;
01074 }
01075
return -1;
01076 }
01077
01078 int soft_rt_recvfrom(
int sock,
void *msg,
int msglen,
unsigned int flags,
struct sockaddr *from,
int *fromlen)
01079 {
01080
if (sock >= 0 && sock <
MaxSocks) {
01081
if (msglen >
socks[sock].
recvd) {
01082 msglen =
socks[sock].
recvd;
01083 }
01084 memcpy(msg,
socks[sock].msg, msglen);
01085
if (from && fromlen) {
01086 memcpy(from, &
socks[sock].addr,
socks[sock].addrlen);
01087 *fromlen =
socks[sock].
addrlen;
01088 }
01089
return msglen;
01090 }
01091
return -1;
01092 }
01093
01094
#include <linux/unistd.h>
01095
#include <linux/poll.h>
01096
#include <linux/net.h>
01097
01098 int errno;
01099
01100 #define SYSCALL_BGN() \
01101
do { int retval; mm_segment_t svdfs = get_fs(); set_fs(KERNEL_DS)
01102 #define SYSCALL_END() \
01103
set_fs(svdfs); return retval; } while (0)
01104
01105
#ifdef __NR_socketcall
01106
01107
01108
01109
static _syscall3(
int, poll,
struct pollfd *, ufds,
unsigned int, nfds,
int, timeout)
01110 static inline
int kpoll(struct pollfd *ufds,
unsigned int nfds,
int timeout)
01111 {
01112
SYSCALL_BGN();
01113
01114 retval = poll(ufds, nfds, timeout);
01115
SYSCALL_END();
01116 }
01117
01118
static _syscall2(
int, socketcall,
int, call,
void *, args)
01119 static inline
int ksocketcall(
int call,
void *args)
01120 {
01121
SYSCALL_BGN();
01122
01123 retval = socketcall(call, args);
01124
SYSCALL_END();
01125 }
01126
01127
static inline int ksocket(
int family,
int type,
int protocol)
01128 {
01129
struct {
int family;
int type;
int protocol; } args = { family, type, protocol };
01130
return ksocketcall(SYS_SOCKET, &args);
01131 }
01132
01133
static inline int kbind(
int fd,
struct sockaddr *umyaddr,
int addrlen)
01134 {
01135
struct {
int fd;
struct sockaddr *umyaddr;
int addrlen; } args = { fd, umyaddr, addrlen };
01136
return ksocketcall(SYS_BIND, &args);
01137 }
01138
01139
static inline int kconnect(
int fd,
struct sockaddr *serv_addr,
int addrlen)
01140 {
01141
struct {
int fd;
struct sockaddr *serv_addr;
int addrlen; } args = { fd, serv_addr, addrlen };
01142
return ksocketcall(SYS_CONNECT, &args);
01143 }
01144
01145
static inline int klisten(
int fd,
int backlog)
01146 {
01147
struct {
int fd;
int backlog; } args = { fd, backlog };
01148
return ksocketcall(SYS_LISTEN, &args);
01149 }
01150
01151
static inline int kaccept(
int fd,
struct sockaddr *upeer_sockaddr,
int *upeer_addrlen)
01152 {
01153
struct {
int fd;
struct sockaddr *upeer_sockaddr;
int *upeer_addrlen; } args = { fd, upeer_sockaddr, upeer_addrlen };
01154
return ksocketcall(SYS_ACCEPT, &args);
01155 }
01156
01157
static inline int kgetsockname(
int fd,
struct sockaddr *usockaddr,
int *usockaddr_len)
01158 {
01159
struct {
int fd;
struct sockaddr *usockaddr;
int *usockaddr_len; } args = { fd, usockaddr, usockaddr_len };
01160
return ksocketcall(SYS_GETSOCKNAME, &args);
01161 }
01162
01163
static inline int kgetpeername(
int fd,
struct sockaddr *usockaddr,
int *usockaddr_len)
01164 {
01165
struct {
int fd;
struct sockaddr *usockaddr;
int *usockaddr_len; } args = { fd, usockaddr, usockaddr_len };
01166
return ksocketcall(SYS_GETPEERNAME, &args);
01167 }
01168
01169
static inline int ksocketpair(
int family,
int type,
int protocol,
int *usockvec)
01170 {
01171
struct {
int family;
int type;
int protocol;
int *usockvec; } args = { family, type, protocol, usockvec };
01172
return ksocketcall(SYS_SOCKETPAIR, &args);
01173 }
01174
01175
static inline int ksendto(
int fd,
void *buff, size_t len,
unsigned flags,
struct sockaddr *addr,
int addr_len)
01176 {
01177
struct {
int fd;
void *buff; size_t len;
unsigned flags;
struct sockaddr *addr;
int addr_len; } args = { fd, buff, len,
flags, addr, addr_len };
01178
return ksocketcall(SYS_SENDTO, &args);
01179 }
01180
01181
static inline int krecvfrom(
int fd,
void *ubuf, size_t len,
unsigned flags,
struct sockaddr *addr,
int *addr_len)
01182 {
01183
struct {
int fd;
void *ubuf; size_t len;
unsigned flags;
struct sockaddr *addr;
int *addr_len; } args = { fd, ubuf, len,
flags, addr, addr_len };
01184
return ksocketcall(SYS_RECVFROM, &args);
01185 }
01186
01187
static inline int kshutdown(
int fd,
int how)
01188 {
01189
struct {
int fd;
int how; } args = { fd, how };
01190
return ksocketcall(SYS_SHUTDOWN, &args);
01191 }
01192
01193
static inline int ksetsockopt(
int fd,
int level,
int optname,
void *optval,
int optlen)
01194 {
01195
struct {
int fd;
int level;
int optname;
void *optval;
int optlen; } args = { fd, level, optname, optval, optlen };
01196
return ksocketcall(SYS_SETSOCKOPT, &args);
01197 }
01198
01199
static inline int kgetsockopt(
int fd,
int level,
int optname,
char *optval,
int *optlen)
01200 {
01201
struct {
int fd;
int level;
int optname;
void *optval;
int *optlen; } args = { fd, level, optname, optval, optlen };
01202
return ksocketcall(SYS_GETSOCKOPT, &args);
01203 }
01204
01205
static inline int ksendmsg(
int fd,
struct msghdr *msg,
unsigned flags)
01206 {
01207
struct {
int fd;
struct msghdr *msg;
unsigned flags; } args = { fd, msg,
flags };
01208
return ksocketcall(SYS_SENDMSG, &args);
01209 }
01210
01211
static inline int krecvmsg(
int fd,
struct msghdr *msg,
unsigned flags)
01212 {
01213
struct {
int fd;
struct msghdr *msg;
unsigned flags; } args = { fd, msg,
flags };
01214
return ksocketcall(SYS_RECVMSG, &args);
01215 }
01216
01217
#else
01218
01219
#if 0 // just for compiling
01220
#define __NR_socket 1
01221
#define __NR_bind 1
01222
#define __NR_connect 1
01223
#define __NR_accept 1
01224
#define __NR_listen 1
01225
#define __NR_getsockname 1
01226
#define __NR_getpeername 1
01227
#define __NR_socketpair 1
01228
#define __NR_sendto 1
01229
#define __NR_recvfrom 1
01230
#define __NR_shutdown 1
01231
#define __NR_setsockopt 1
01232
#define __NR_getsockopt 1
01233
#define __NR_sendmsg 1
01234
#define __NR_recvmsg 1
01235
#endif
01236
01237
extern void *
sys_call_table[];
01238
01239
01240 static inline int kpoll(
struct pollfd *ufds,
unsigned int nfds,
int timeout)
01241 {
01242
SYSCALL_BGN();
01243 retval = ((int (*)(
void *,
unsigned int,
int))
sys_call_table[__NR_poll])(ufds, nfds, timeout);
01244
01245
SYSCALL_END();
01246 }
01247
01248
01249 static inline int ksocket(
int family,
int type,
int protocol)
01250 {
01251
SYSCALL_BGN();
01252 retval = ((int (*)(
int,
int,
int))
sys_call_table[__NR_socket])(family, type, protocol);
01253
01254
SYSCALL_END();
01255 }
01256
01257
01258 static inline int kbind(
int fd,
struct sockaddr *umyaddr,
int addrlen)
01259 {
01260
SYSCALL_BGN();
01261 retval = ((int (*)(
int,
struct sockaddr *,
int))
sys_call_table[__NR_bind])(fd, umyaddr, addrlen);
01262
01263
SYSCALL_END();
01264 }
01265
01266
01267 static inline int kconnect(
int fd,
struct sockaddr *serv_addr,
int addrlen)
01268 {
01269
SYSCALL_BGN();
01270 retval = ((int (*)(
int,
struct sockaddr *,
int))
sys_call_table[__NR_connect])(fd, serv_addr, addrlen);
01271
01272
SYSCALL_END();
01273 }
01274
01275
01276 static inline int klisten(
int fd,
int backlog)
01277 {
01278
SYSCALL_BGN();
01279 retval = ((int (*)(
int,
int))
sys_call_table[__NR_listen])(fd, backlog);
01280
01281
SYSCALL_END();
01282 }
01283
01284
01285 static inline int kaccept(
int fd,
struct sockaddr *upeer_sockaddr,
int *upeer_addrlen)
01286 {
01287
SYSCALL_BGN();
01288 retval = ((int (*)(
int,
struct sockaddr *,
int *))
sys_call_table[__NR_accept])(fd, upeer_sockaddr, upeer_addrlen);
01289
01290
SYSCALL_END();
01291 }
01292
01293
01294 static inline int kgetsockname(
int fd,
struct sockaddr *usockaddr,
int *usockaddr_len)
01295 {
01296
SYSCALL_BGN();
01297 retval = ((int (*)(
int,
struct sockaddr *,
int *))
sys_call_table[__NR_getsockname])(fd, usockaddr, usockaddr_len);
01298
01299
SYSCALL_END();
01300 }
01301
01302
01303 static inline int kgetpeername(
int fd,
struct sockaddr *usockaddr,
int *usockaddr_len)
01304 {
01305
SYSCALL_BGN();
01306 retval = ((int (*)(
int,
struct sockaddr *,
int *))
sys_call_table[__NR_getpeername])(fd, usockaddr, usockaddr_len);
01307
01308
SYSCALL_END();
01309 }
01310
01311
01312 static inline int ksocketpair(
int family,
int type,
int protocol,
int *usockvec)
01313 {
01314
SYSCALL_BGN();
01315 retval = ((int (*)(
int,
int,
int,
int *))
sys_call_table[__NR_socketpair])(family, type, protocol, usockvec);
01316
01317
SYSCALL_END();
01318 }
01319
01320
01321 static inline int ksendto(
int fd,
void *buff, size_t len,
unsigned flags,
struct sockaddr *addr,
int addr_len)
01322 {
01323
SYSCALL_BGN();
01324 retval = ((int (*)(
int,
void *, size_t,
unsigned,
struct sockaddr *,
int))
sys_call_table[__NR_sendto])(fd, buff, len,
flags, addr, addr_len);
01325
01326
SYSCALL_END();
01327 }
01328
01329
01330 static inline int krecvfrom(
int fd,
void *ubuf, size_t len,
unsigned flags,
struct sockaddr *addr,
int *addr_len)
01331 {
01332
SYSCALL_BGN();
01333 retval = ((int (*)(
int,
void *, size_t,
unsigned,
struct sockaddr *,
int *))
sys_call_table[__NR_recvfrom])(fd, ubuf, len,
flags, addr, addr_len);
01334
01335
SYSCALL_END();
01336 }
01337
01338
01339 static inline int kshutdown(
int fd,
int how)
01340 {
01341
SYSCALL_BGN();
01342 retval = ((int (*)(
int,
int))
sys_call_table[__NR_shutdown])(fd, how);
01343
01344
SYSCALL_END();
01345 }
01346
01347
01348 static inline int ksetsockopt(
int fd,
int level,
int optname,
void *optval,
int optlen)
01349 {
01350
SYSCALL_BGN();
01351 retval = ((int (*)(
int,
int,
int,
void *,
int))
sys_call_table[__NR_setsockopt])(fd, level, optname, optval, optlen);
01352
01353
SYSCALL_END();
01354 }
01355
01356
01357 static inline int kgetsockopt(
int fd,
int level,
int optname,
char *optval,
int *optlen)
01358 {
01359
SYSCALL_BGN();
01360 retval = ((int (*)(
int,
int,
int,
void *,
int *))
sys_call_table[__NR_getsockopt])(fd, level, optname, optval, optlen);
01361
01362
SYSCALL_END();
01363 }
01364
01365
01366 static inline int ksendmsg(
int fd,
struct msghdr *msg,
unsigned flags)
01367 {
01368
SYSCALL_BGN();
01369 retval = ((int (*)(
int,
struct msghdr *,
unsigned))
sys_call_table[__NR_sendmsg])(fd, msg,
flags);
01370
01371
SYSCALL_END();
01372 }
01373
01374
01375 static inline int krecvmsg(
int fd,
struct msghdr *msg,
unsigned flags)
01376 {
01377
SYSCALL_BGN();
01378 retval = ((int (*)(
int,
struct msghdr *,
unsigned))
sys_call_table[__NR_recvmsg])(fd, msg,
flags);
01379
01380
SYSCALL_END();
01381 }
01382
01383
#endif
01384
01385 static inline int ksend(
int fd,
void *buff, size_t len,
unsigned flags)
01386 {
01387
return ksendto(fd, buff, len,
flags, NULL, 0);
01388 }
01389
01390 static inline int krecv(
int fd,
void *ubuf, size_t size,
unsigned flags)
01391 {
01392
return krecvfrom(fd, ubuf, size,
flags, NULL, NULL);
01393 }
01394
01395
static DECLARE_MUTEX_LOCKED(mtx);
01396 static unsigned long end_softrtnet;
01397
01398 static void send_thread(
void)
01399 {
01400
int i;
01401
01402 sprintf(current->comm,
"SNDSRV");
01403 rtai_set_linux_task_priority(current,SCHED_FIFO,MAX_LINUX_RTPRIO);
01404 sigfillset(¤t->blocked);
01405
while (!
end_softrtnet) {
01406 down(&mtx);
01407
while (
sysrq.out !=
sysrq.in) {
01408 i =
sysrq.sockindx[
sysrq.out];
01409
ksendto(
socks[i].sock,
socks[i].msg,
socks[i].tosend, MSG_DONTWAIT, &
socks[i].addr,
ADRSZ);
01410
sysrq.out = (
sysrq.out + 1) &
MaxSockSrq;
01411 }
01412 }
01413 set_bit(1, &
end_softrtnet);
01414 }
01415
01416 static struct pollfd *
pollv;
01417 static struct task_struct *
recv_handle;
01418
01419 static void recv_thread(
void)
01420 {
01421
int i, nevents;
01422
01423
recv_handle = current;
01424 sprintf(current->comm,
"RCVSRV");
01425 rtai_set_linux_task_priority(current,SCHED_RR,MAX_LINUX_RTPRIO);
01426 sigfillset(¤t->blocked);
01427
while (!
end_softrtnet) {
01428
if ((nevents =
kpoll(
pollv,
MaxSocks, 1000)) > 0) {
01429 i = -1;
01430
do {
01431
while (!
pollv[++i].revents);
01432
if ((
socks[i].
recvd =
krecvfrom(
socks[i].sock,
socks[i].msg,
MAX_MSG_SIZE, MSG_DONTWAIT, &
socks[i].addr, &
socks[i].addrlen)) > 0) {
01433
socks[i].
callback(i,
socks[i].arg);
01434 }
01435 }
while (--nevents);
01436 }
01437 }
01438 set_bit(2, &
end_softrtnet);
01439 }
01440
01441 static void softrtnet_hdl(
void)
01442 {
01443 up(&mtx);
01444 }
01445
01446 static int init_softrtnet(
void)
01447 {
01448
int i;
01449
for (i = 8*
sizeof(
unsigned long) - 1; !test_bit(i, &
MaxSocks); i--);
01450
MaxSockSrq = ((1 << i) !=
MaxSocks ? 1 << (i + 1) :
MaxSocks) - 1;
01451
if ((
sysrq.srq =
rt_request_srq(0xbadbeef2,
softrtnet_hdl, 0)) < 0) {
01452
printk(
"SOFT RTNet: no sysrq available.\n");
01453
return sysrq.srq;
01454 }
01455
if (!(
sysrq.sockindx = (
int *)kmalloc((
MaxSockSrq + 1)*
sizeof(
int), GFP_KERNEL))) {
01456
printk(
"SOFT RTNet: no memory available for socket queus.\n");
01457
return -ENOMEM;
01458 }
01459
if (!(
socks = (
struct sock_t *)kmalloc(
MaxSocks*
sizeof(
struct sock_t), GFP_KERNEL))) {
01460 kfree(
sysrq.sockindx);
01461
printk(
"SOFT RTNet: no memory available for socks.\n");
01462
return -ENOMEM;
01463 }
01464
if (!(
pollv = (
struct pollfd *)kmalloc(
MaxSocks*
sizeof(
struct pollfd), GFP_KERNEL))) {
01465 kfree(
sysrq.sockindx);
01466 kfree(
socks);
01467
printk(
"SOFT RTNet: no memory available for polling.\n");
01468
return -ENOMEM;
01469 }
01470 memset(
socks, 0,
MaxSocks*
sizeof(
struct sock_t));
01471
for (i = 0; i <
MaxSocks; i++) {
01472
SPRT_ADDR.sin_port = htons(
BASEPORT + i);
01473
if ((
socks[i].
sock =
ksocket(AF_INET, SOCK_DGRAM, 0)) < 0 ||
kbind(
socks[i].sock, (
struct sockaddr *)&
SPRT_ADDR,
ADRSZ) < 0) {
01474
rt_free_srq(
sysrq.srq);
01475 kfree(
socks);
01476 kfree(
pollv);
01477 kfree(
sysrq.sockindx);
01478
printk(
"SOFT RTNet: unable to set up Linux support sockets.\n");
01479
return -ESOCKTNOSUPPORT;
01480 }
01481
socks[i].
addrlen =
ADRSZ;
01482
pollv[i].fd =
socks[i].
sock;
01483
pollv[i].events = POLLIN;
01484 }
01485
if (kernel_thread((
void *)
send_thread, 0, 0) <= 0 || kernel_thread((
void *)
recv_thread, 0, 0) <= 0) {
01486 kfree(
sysrq.sockindx);
01487 kfree(
socks);
01488 kfree(
pollv);
01489
printk(
"SOFT RTNet: unable to set up Linux support kernel threads.\n");
01490
return -EINVAL;
01491 }
01492
while (!
recv_handle) {
01493 current->state = TASK_INTERRUPTIBLE;
01494 schedule_timeout(HZ/2);
01495 }
01496
return 0;
01497 }
01498
01499 static void cleanup_softrtnet(
void)
01500 {
01501
int i;
01502
rt_free_srq(
sysrq.srq);
01503
end_softrtnet = 1;
01504
01505
01506
01507
01508
softrtnet_hdl();
01509
while (
end_softrtnet < 7) {
01510 current->state = TASK_INTERRUPTIBLE;
01511 schedule_timeout(HZ/2);
01512 }
01513
for (i = 0; i <
MaxSocks; i++) {
01514
kshutdown(
socks[i].sock, 2);
01515 }
01516 kfree(
sysrq.sockindx);
01517 kfree(
socks);
01518 kfree(
pollv);
01519 }
01520
01521
#else
01522
01523
int init_softrtnet(
void)
01524 {
01525
return 0;
01526 }
01527
01528
void cleanup_softrtnet(
void)
01529 {
01530
return;
01531 }
01532
01533
#endif
01534
01535
01536
01537
01538
01539 void **
rt_net_rpc_fun_hook = (
void *)
rt_net_rpc_fun_ext;
01540
01541 int __rtai_netrpc_init(
void)
01542 {
01543
int i;
01544
01545
for (i = 8*
sizeof(
unsigned long) - 1; !test_bit(i, &
MaxStubs); i--);
01546
if ((1 << i) !=
MaxStubs) {
01547
printk(
"MAX_STUBS (%lu): must be a power of 2.\n",
MaxStubs);
01548
MaxStubs = 1 << (i + 1);
01549
printk(
"MAX_STUBS (%lu): forced to a power of 2.\n",
MaxStubs);
01550 }
01551
MaxStubsMone =
MaxStubs - 1;
01552
if ((
mod_timer_srq =
rt_request_srq(0xbadbeef1,
do_mod_timer, 0)) < 0) {
01553
printk(
"MOD_TIMER: no sysrq available.\n");
01554
return mod_timer_srq;
01555 }
01556
MaxSocks +=
MaxStubs;
01557
SPRT_ADDR.sin_family = AF_INET;
01558
SPRT_ADDR.sin_addr.s_addr = htonl(INADDR_ANY);
01559
if (
init_softrtnet()) {
01560
return 1;
01561 }
01562
rt_net_rpc_fun_ext[
NET_RPC_EXT] =
rt_fun_lxrt;
01563
set_rt_fun_entries(
rt_netrpc_entries);
01564
if (!(
portslot = kmalloc(
MaxSocks*
sizeof(
struct portslot_t), GFP_KERNEL))) {
01565
printk(
"KMALLOC FAILED ALLOCATING PORT SLOTS\n");
01566 }
01567
if (!
ThisSoftNode) {
01568
ThisSoftNode =
ThisNode;
01569 }
01570
if (!
ThisHardNode) {
01571
ThisHardNode =
ThisNode;
01572 }
01573
this_node[0] =
ddn2nl(
ThisSoftNode);
01574
this_node[1] =
ddn2nl(
ThisHardNode);
01575
01576
for (i = 0; i <
MaxSocks; i++) {
01577
portslot[i].
p =
portslot + i;
01578
portslot[i].
indx = i;
01579
SPRT_ADDR.sin_port = htons(
BASEPORT + i);
01580
portslot[i].
addr =
SPRT_ADDR;
01581
portslot[i].
socket[0] =
soft_rt_socket(AF_INET, SOCK_DGRAM, 0);
01582
soft_rt_bind(
portslot[i].socket[0], (
struct sockaddr *)&
SPRT_ADDR,
ADRSZ);
01583
portslot[i].
socket[1] =
hard_rt_socket(AF_INET, SOCK_DGRAM, 0);
01584
hard_rt_bind(
portslot[i].socket[1], (
struct sockaddr *)&
SPRT_ADDR,
ADRSZ);
01585
soft_rt_socket_callback(
portslot[i].socket[0], (
void *)
net_resume_task, &
portslot[i].sem);
01586
hard_rt_socket_callback(
portslot[i].socket[1], (
void *)
net_resume_task, &
portslot[i].sem);
01587
portslot[i].
owner = 0;
01588
rt_typed_sem_init(&
portslot[i].sem, 0,
BIN_SEM |
FIFO_Q);
01589
portslot[i].
task = 0;
01590 }
01591
SPRT_ADDR.sin_port = htons(
BASEPORT);
01592
portslotsp =
MaxStubs;
01593
portslot[0].
name =
PRTSRVNAME;
01594
portslot[0].
owner =
OWNER(
this_node, (
unsigned long)
port_server);
01595
port_server = kmalloc(
sizeof(
RT_TASK) + 3*
sizeof(
struct fun_args), GFP_KERNEL);
01596
soft_kthread_init(
port_server, (
long)
port_server_fun, (
long)
port_server,
RT_SCHED_LOWEST_PRIORITY);
01597
portslot[0].
task = (
long)
port_server;
01598
rt_task_resume(
port_server);
01599
rt_typed_sem_init(&
timer_sem, 0,
BIN_SEM |
FIFO_Q);
01600 init_timer(&
timer);
01601
timer.function =
timer_fun;
01602
return 0 ;
01603 }
01604
01605 void __rtai_netrpc_exit(
void)
01606 {
01607
int i;
01608
01609
reset_rt_fun_entries(
rt_netrpc_entries);
01610 del_timer(&
timer);
01611
soft_kthread_delete(
port_server);
01612 kfree(
port_server);
01613
rt_sem_delete(&
timer_sem);
01614
for (i = 0; i <
MaxStubs; i++) {
01615
if (
portslot[i].
task) {
01616
rt_task_delete((
RT_TASK *)
portslot[i].
task);
01617 }
01618 }
01619
for (i = 0; i <
MaxSocks; i++) {
01620
rt_sem_delete(&
portslot[i].sem);
01621
soft_rt_close(
portslot[i].socket[0]);
01622
hard_rt_close(
portslot[i].socket[1]);
01623 }
01624 kfree(
portslot);
01625
cleanup_softrtnet();
01626
rt_free_srq(
mod_timer_srq);
01627
return;
01628 }
01629
01630
#ifndef CONFIG_RTAI_NETRPC_BUILTIN
01631
module_init(__rtai_netrpc_init);
01632
module_exit(__rtai_netrpc_exit);
01633
#endif
01634
01635
#ifdef CONFIG_KBUILD
01636
EXPORT_SYMBOL(set_netrpc_encoding);
01637
EXPORT_SYMBOL(rt_send_req_rel_port);
01638
EXPORT_SYMBOL(rt_find_asgn_stub);
01639
EXPORT_SYMBOL(rt_rel_stub);
01640
EXPORT_SYMBOL(rt_waiting_return);
01641
EXPORT_SYMBOL(rt_net_rpc);
01642
EXPORT_SYMBOL(rt_get_net_rpc_ret);
01643
EXPORT_SYMBOL(rt_set_this_node);
01644
01645
#ifdef CONFIG_RTAI_NETRPC_RTNET
01646
EXPORT_SYMBOL(soft_rt_socket);
01647
EXPORT_SYMBOL(soft_rt_close);
01648
EXPORT_SYMBOL(soft_rt_bind);
01649
EXPORT_SYMBOL(soft_rt_socket_callback);
01650
EXPORT_SYMBOL(soft_rt_sendto);
01651
EXPORT_SYMBOL(soft_rt_recvfrom);
01652
EXPORT_SYMBOL(ddn2nl);
01653
#endif
01654
01655
EXPORT_SYMBOL(rt_net_rpc_fun_hook);
01656
#endif