00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include <linux/module.h>
00027
#include <linux/kernel.h>
00028
#include <linux/config.h>
00029
#include <linux/version.h>
00030
#include <linux/errno.h>
00031
#include <linux/slab.h>
00032
#include <linux/unistd.h>
00033
#include <linux/mman.h>
00034
#include <asm/uaccess.h>
00035
00036
#include <rtai_sched.h>
00037
#include <rtai_lxrt.h>
00038
#include <rtai_sem.h>
00039
#include <rtai_mbx.h>
00040
#include <rtai_rwl.h>
00041
#include <rtai_spl.h>
00042
00043
#include <asm/rtai_fpu.h>
00044
#include <rtai_registry.h>
00045
#include <rtai_proxies.h>
00046
#include <rtai_msg.h>
00047
#include <rtai_schedcore.h>
00048
00049 #define MAX_FUN_EXT 16
00050 static struct rt_fun_entry *
rt_fun_ext[
MAX_FUN_EXT];
00051
00052
00053
00054
00055 #define USRLAND_MAX_MSG_SIZE 128 // Default max message size, used here only.
00056
00057
#ifdef CONFIG_RTAI_TRACE
00058
00059
00060
00061
void trace_true_lxrt_rtai_syscall_entry(
void);
00062
void trace_true_lxrt_rtai_syscall_exit(
void);
00063
00064
#endif
00065
00066
int get_min_tasks_cpuid(
void);
00067
00068
int set_rtext(
RT_TASK *task,
00069
int priority,
00070
int uses_fpu,
00071
void(*signal)(
void),
00072
unsigned int cpuid,
00073
struct task_struct *relink);
00074
00075
int clr_rtext(
RT_TASK *task);
00076
00077
void steal_from_linux(
RT_TASK *task);
00078
00079
void give_back_to_linux(
RT_TASK *task,
int);
00080
00081
void rt_schedule_soft(
RT_TASK *task);
00082
00083
void *
rt_get_lxrt_fun_entry(
int index);
00084
00085 static inline void lxrt_typed_sem_init(
SEM *sem,
int count,
int type)
00086 {
00087 ((int (*)(
SEM *,
int,
int))
rt_get_lxrt_fun_entry(
TYPED_SEM_INIT))(sem,
count, type);
00088 }
00089
00090 static inline int lxrt_typed_mbx_init(
MBX *mbx,
int bufsize,
int type)
00091 {
00092
return ((int (*)(
MBX *,
int,
int))
rt_get_lxrt_fun_entry(
TYPED_MBX_INIT))(mbx, bufsize, type);
00093 }
00094
00095 static inline int lxrt_rwl_init(
RWL *rwl)
00096 {
00097
return ((int (*)(
RWL *))
rt_get_lxrt_fun_entry(
RWL_INIT))(rwl);
00098 }
00099
00100 static inline int lxrt_spl_init(
SPL *spl)
00101 {
00102
return ((int (*)(
SPL *))
rt_get_lxrt_fun_entry(
SPL_INIT))(spl);
00103 }
00104
00105 static inline int lxrt_Proxy_detach(pid_t pid)
00106 {
00107
return ((int (*)(
int))
rt_get_lxrt_fun_entry(
PROXY_DETACH))(
pid);
00108 }
00109
00110 static inline int GENERIC_DELETE(
int index,
void *object)
00111 {
00112
return ((int (*)(
void *))
rt_get_lxrt_fun_entry(index))(object);
00113 }
00114
00115 #define lxrt_sem_delete(sem) GENERIC_DELETE(SEM_DELETE, sem)
00116 #define lxrt_named_sem_delete(sem) GENERIC_DELETE(NAMED_SEM_DELETE, sem)
00117 #define lxrt_rwl_delete(rwl) GENERIC_DELETE(RWL_DELETE, rwl)
00118 #define lxrt_named_rwl_delete(rwl) GENERIC_DELETE(NAMED_RWL_DELETE, rwl)
00119 #define lxrt_spl_delete(spl) GENERIC_DELETE(SPL_DELETE, spl)
00120 #define lxrt_named_spl_delete(spl) GENERIC_DELETE(NAMED_SPL_DELETE, spl)
00121 #define lxrt_mbx_delete(mbx) GENERIC_DELETE(MBX_DELETE, mbx)
00122 #define lxrt_named_mbx_delete(mbx) GENERIC_DELETE(NAMED_MBX_DELETE, mbx)
00123
00124 static inline void lxrt_resume(
void *fun,
int narg,
long *arg,
unsigned long type,
RT_TASK *rt_task)
00125 {
00126
if (NEED_TO_RW(type)) {
00127
int rsize, r2size, wsize, w2size, msg_size;
00128
long *wmsg_adr, *w2msg_adr, *fun_args;
00129
00130 rsize = r2size = wsize = w2size = 0 ;
00131 wmsg_adr = w2msg_adr = NULL;
00132 fun_args = arg - 1;
00133
if (NEED_TO_R(type)) {
00134 rsize = USP_RSZ1(type);
00135 rsize = rsize ? fun_args[rsize] :
sizeof(
long);
00136
if (NEED_TO_R2ND(type)) {
00137 r2size = USP_RSZ2(type);
00138 r2size = r2size ? fun_args[r2size] :
sizeof(
long);
00139 }
00140 }
00141
if (NEED_TO_W(type)) {
00142 wsize = USP_WSZ1(type);
00143 wsize = wsize ? fun_args[wsize] :
sizeof(
long);
00144
if (NEED_TO_W2ND(type)) {
00145 w2size = USP_WSZ2(type);
00146 w2size = w2size ? fun_args[w2size] :
sizeof(
long);
00147 }
00148 }
00149
if ((msg_size = rsize > wsize ? rsize : wsize) > 0) {
00150
if (msg_size > rt_task->max_msg_size[0]) {
00151
rt_free(rt_task->msg_buf[0]);
00152 rt_task->max_msg_size[0] = (msg_size << 7)/100;
00153 rt_task->msg_buf[0] =
rt_malloc(rt_task->max_msg_size[0]);
00154 }
00155
if (rsize) {
00156
long *buf_arg = fun_args + USP_RBF1(type);
00157 rt_copy_from_user(rt_task->msg_buf[0], (
long *)buf_arg[0], rsize);
00158 buf_arg[0] = (
long)rt_task->msg_buf[0];
00159 }
00160
if (wsize) {
00161
long *buf_arg = fun_args + USP_WBF1(type);
00162 wmsg_adr = (
long *)buf_arg[0];
00163 buf_arg[0] = (
long)rt_task->msg_buf[0];
00164 }
00165 }
00166
if ((msg_size = r2size > w2size ? r2size : w2size) > 0) {
00167
if (msg_size > rt_task->max_msg_size[1]) {
00168
rt_free(rt_task->msg_buf[1]);
00169 rt_task->max_msg_size[1] = (msg_size << 7)/100;
00170 rt_task->msg_buf[1] =
rt_malloc(rt_task->max_msg_size[1]);
00171 }
00172
if (r2size) {
00173
long *buf_arg = fun_args + USP_RBF2(type);
00174 rt_copy_from_user(rt_task->msg_buf[1], (
long *)buf_arg[0], r2size);
00175 buf_arg[0] = (
long)rt_task->msg_buf[1];
00176 }
00177
if (w2size) {
00178
long *buf_arg = fun_args + USP_WBF2(type);
00179 w2msg_adr = (
long *)buf_arg[0];
00180 buf_arg[0] = (
long)rt_task->msg_buf[1];
00181 }
00182 }
00183
if (
likely(rt_task->is_hard > 0)) {
00184 rt_task->retval = ((
long long (*)(
unsigned long, ...))fun)(RTAI_FUN_ARGS);
00185
if (
unlikely(!rt_task->is_hard)) {
00186
extern void rt_schedule_soft_tail(
RT_TASK *rt_task,
int cpuid);
00187
rt_schedule_soft_tail(rt_task, rt_task->runnable_on_cpus);
00188 }
00189 }
else {
00190
struct fun_args *funarg;
00191 memcpy(funarg = (
void *)rt_task->fun_args, arg, narg);
00192 funarg->fun = fun;
00193
rt_schedule_soft(rt_task);
00194 }
00195
if (wsize) {
00196 rt_copy_to_user(wmsg_adr, rt_task->msg_buf[0], wsize);
00197
if (w2size) {
00198 rt_copy_to_user(w2msg_adr, rt_task->msg_buf[1], w2size);
00199 }
00200 }
00201 }
else if (
likely(rt_task->is_hard > 0)) {
00202 rt_task->retval = ((
long long (*)(
unsigned long, ...))fun)(RTAI_FUN_ARGS);
00203
if (
unlikely(!rt_task->is_hard)) {
00204
extern void rt_schedule_soft_tail(
RT_TASK *rt_task,
int cpuid);
00205
rt_schedule_soft_tail(rt_task, rt_task->runnable_on_cpus);
00206 }
00207 }
else {
00208
struct fun_args *funarg;
00209 memcpy(funarg = (
void *)rt_task->fun_args, arg, narg);
00210 funarg->fun = fun;
00211
rt_schedule_soft(rt_task);
00212 }
00213 }
00214
00215 static inline RT_TASK*
__task_init(
unsigned long name,
int prio,
int stack_size,
int max_msg_size,
int cpus_allowed)
00216 {
00217
void *msg_buf0, *msg_buf1;
00218
RT_TASK *rt_task;
00219
00220
if (
rt_get_adr(name)) {
00221
return 0;
00222 }
00223
if (prio >
RT_SCHED_LOWEST_PRIORITY) {
00224 prio =
RT_SCHED_LOWEST_PRIORITY;
00225 }
00226
if (!max_msg_size) {
00227 max_msg_size =
USRLAND_MAX_MSG_SIZE;
00228 }
00229
if (!(msg_buf0 =
rt_malloc(max_msg_size))) {
00230
return 0;
00231 }
00232
if (!(msg_buf1 =
rt_malloc(max_msg_size))) {
00233
rt_free(msg_buf0);
00234
return 0;
00235 }
00236 rt_task =
rt_malloc(
sizeof(
RT_TASK) + 3*
sizeof(
struct fun_args));
00237
if (rt_task) {
00238 rt_task->magic = 0;
00239
if (num_online_cpus() > 1 && cpus_allowed) {
00240 cpus_allowed = hweight32(cpus_allowed) > 1 ?
get_min_tasks_cpuid() :
ffnz(cpus_allowed);
00241 }
else {
00242 cpus_allowed = smp_processor_id();
00243 }
00244
if (!
set_rtext(rt_task, prio, 0, 0, cpus_allowed, 0)) {
00245 rt_task->fun_args = (
long *)((
struct fun_args *)(rt_task + 1));
00246 rt_task->msg_buf[0] = msg_buf0;
00247 rt_task->msg_buf[1] = msg_buf1;
00248 rt_task->max_msg_size[0] =
00249 rt_task->max_msg_size[1] = max_msg_size;
00250
if (
rt_register(name, rt_task,
IS_TASK, 0)) {
00251
return rt_task;
00252 }
else {
00253
clr_rtext(rt_task);
00254 }
00255 }
00256
rt_free(rt_task);
00257 }
00258
rt_free(msg_buf0);
00259
rt_free(msg_buf1);
00260
return 0;
00261 }
00262
00263 static int __task_delete(
RT_TASK *rt_task)
00264 {
00265
struct task_struct *process;
00266
if (rt_task->linux_syscall_server) {
00267
rt_task_masked_unblock(rt_task->linux_syscall_server, ~
RT_SCHED_READY);
00268 }
00269
if (current == rt_task->lnxtsk && rt_task->is_hard > 0) {
00270
give_back_to_linux(rt_task, 0);
00271 }
00272
if (
clr_rtext(rt_task)) {
00273
return -EFAULT;
00274 }
00275
rt_free(rt_task->msg_buf[0]);
00276
rt_free(rt_task->msg_buf[1]);
00277
rt_free(rt_task);
00278
if ((process = rt_task->lnxtsk)) {
00279 process->rtai_tskext(
TSKEXT0) = process->rtai_tskext(
TSKEXT1) = 0;
00280 }
00281
return (!
rt_drg_on_adr(rt_task)) ? -ENODEV : 0;
00282 }
00283
00284
00285
#ifdef ECHO_SYSW
00286
#define SYSW_DIAG_MSG(x) x
00287
#else
00288 #define SYSW_DIAG_MSG(x)
00289
#endif
00290
00291 static inline long long handle_lxrt_request (
unsigned int lxsrq,
long *arg,
RT_TASK *task)
00292 {
00293
#define larg ((struct arg *)arg)
00294
00295
union {
unsigned long name;
RT_TASK *rt_task;
SEM *sem;
MBX *mbx;
RWL *rwl;
SPL *spl; } arg0;
00296
int srq;
00297
00298
srq =
SRQ(lxsrq);
00299
if (
likely(
srq <
MAX_LXRT_FUN)) {
00300
unsigned long type;
00301
struct rt_fun_entry *funcm;
00302
00303
00304
00305
00306
00307
00308 funcm =
rt_fun_ext[
INDX(lxsrq)];
00309
if (
unlikely(!funcm)) {
00310
rt_printk(
"BAD: null rt_fun_ext[%d]\n",
INDX(lxsrq));
00311
return -ENOSYS;
00312 }
00313 type = funcm[
srq].type;
00314
if (
likely(type)) {
00315
if (
unlikely(
task->is_hard < 0)) {
00316
SYSW_DIAG_MSG(
rt_printk(
"GOING BACK TO HARD (SYSLXRT, RESUME), PID = %d.\n", current->pid););
00317
steal_from_linux(
task);
00318
SYSW_DIAG_MSG(
rt_printk(
"GONE BACK TO HARD (SYSLXRT), PID = %d.\n", current->pid););
00319 }
00320
lxrt_resume(funcm[
srq].fun,
NARG(lxsrq), arg, type,
task);
00321
return task->retval;
00322 }
else {
00323
if (
unlikely(
task &&
task->is_hard < 0)) {
00324
SYSW_DIAG_MSG(
rt_printk(
"GOING BACK TO HARD (SYSLXRT, DIRECT), PID = %d.\n", current->pid););
00325
steal_from_linux(
task);
00326
SYSW_DIAG_MSG(
rt_printk(
"GONE BACK TO HARD (SYSLXRT), PID = %d.\n", current->pid););
00327 }
00328
return ((
long long (*)(
unsigned long, ...))funcm[
srq].fun)(RTAI_FUN_ARGS);
00329 }
00330 }
00331
00332 arg0.name = arg[0];
00333
switch (
srq) {
00334
case LXRT_GET_ADR: {
00335
return (
unsigned long)
rt_get_adr(arg0.name);
00336 }
00337
00338
case LXRT_GET_NAME: {
00339
return rt_get_name((
void *)arg0.name);
00340 }
00341
00342
case LXRT_TASK_INIT: {
00343
struct arg {
unsigned long name;
int prio, stack_size, max_msg_size, cpus_allowed; };
00344
return (
unsigned long)
__task_init(arg0.name,
larg->prio,
larg->stack_size,
larg->max_msg_size,
larg->cpus_allowed);
00345 }
00346
00347
case LXRT_TASK_DELETE: {
00348
return __task_delete(arg0.rt_task ? arg0.rt_task :
task);
00349 }
00350
00351
case LXRT_SEM_INIT: {
00352
if (
rt_get_adr(arg0.name)) {
00353
return 0;
00354 }
00355
if ((arg0.sem =
rt_malloc(
sizeof(
SEM)))) {
00356
struct arg {
unsigned long name;
int cnt;
int typ; };
00357
lxrt_typed_sem_init(arg0.sem,
larg->cnt,
larg->typ);
00358
if (
rt_register(
larg->name, arg0.sem,
IS_SEM, current)) {
00359
return arg0.name;
00360 }
else {
00361
rt_free(arg0.sem);
00362 }
00363 }
00364
return 0;
00365 }
00366
00367
case LXRT_SEM_DELETE: {
00368
if (
lxrt_sem_delete(arg0.sem)) {
00369
return -EFAULT;
00370 }
00371
rt_free(arg0.sem);
00372
return rt_drg_on_adr(arg0.sem);
00373 }
00374
00375
case LXRT_MBX_INIT: {
00376
if (
rt_get_adr(arg0.name)) {
00377
return 0;
00378 }
00379
if ((arg0.mbx =
rt_malloc(
sizeof(
MBX)))) {
00380
struct arg {
unsigned long name;
int size;
int qtype; };
00381
if (
lxrt_typed_mbx_init(arg0.mbx,
larg->size,
larg->qtype) < 0) {
00382
rt_free(arg0.mbx);
00383
return 0;
00384 }
00385
if (
rt_register(
larg->name, arg0.mbx,
IS_MBX, current)) {
00386
return arg0.name;
00387 }
else {
00388
rt_free(arg0.mbx);
00389 }
00390 }
00391
return 0;
00392 }
00393
00394
case LXRT_MBX_DELETE: {
00395
if (
lxrt_mbx_delete(arg0.mbx)) {
00396
return -EFAULT;
00397 }
00398
rt_free(arg0.mbx);
00399
return rt_drg_on_adr(arg0.mbx);
00400 }
00401
00402
case LXRT_RWL_INIT: {
00403
if (
rt_get_adr(arg0.name)) {
00404
return 0;
00405 }
00406
if ((arg0.rwl =
rt_malloc(
sizeof(
RWL)))) {
00407
struct arg {
unsigned long name; };
00408
lxrt_rwl_init(arg0.rwl);
00409
if (
rt_register(
larg->name, arg0.rwl,
IS_SEM, current)) {
00410
return arg0.name;
00411 }
else {
00412
rt_free(arg0.rwl);
00413 }
00414 }
00415
return 0;
00416 }
00417
00418
case LXRT_RWL_DELETE: {
00419
if (
lxrt_rwl_delete(arg0.rwl)) {
00420
return -EFAULT;
00421 }
00422
rt_free(arg0.rwl);
00423
return rt_drg_on_adr(arg0.rwl);
00424 }
00425
00426
case LXRT_SPL_INIT: {
00427
if (
rt_get_adr(arg0.name)) {
00428
return 0;
00429 }
00430
if ((arg0.spl =
rt_malloc(
sizeof(
SPL)))) {
00431
struct arg {
unsigned long name; };
00432
lxrt_spl_init(arg0.spl);
00433
if (
rt_register(
larg->name, arg0.spl,
IS_SEM, current)) {
00434
return arg0.name;
00435 }
else {
00436
rt_free(arg0.spl);
00437 }
00438 }
00439
return 0;
00440 }
00441
00442
case LXRT_SPL_DELETE: {
00443
if (
lxrt_spl_delete(arg0.spl)) {
00444
return -EFAULT;
00445 }
00446
rt_free(arg0.spl);
00447
return rt_drg_on_adr(arg0.spl);
00448 }
00449
00450
case MAKE_HARD_RT: {
00451
if (!
task ||
task->is_hard) {
00452
return 0;
00453 }
00454
steal_from_linux(
task);
00455
return 0;
00456 }
00457
00458
case MAKE_SOFT_RT: {
00459
if (!
task || !
task->is_hard) {
00460
return 0;
00461 }
00462
if (
task->is_hard < 0) {
00463
task->is_hard = 0;
00464 }
else {
00465
give_back_to_linux(
task, 0);
00466 }
00467
return 0;
00468 }
00469
case PRINT_TO_SCREEN: {
00470
struct arg {
char *display;
int nch; };
00471
return rtai_print_to_screen(
"%s",
larg->display);
00472 }
00473
00474
case PRINTK: {
00475
struct arg {
char *display;
int nch; };
00476
return rt_printk(
"%s",
larg->display);
00477 }
00478
00479
case NONROOT_HRT: {
00480 current->cap_effective |= ((1 << CAP_IPC_LOCK) |
00481 (1 << CAP_SYS_RAWIO) |
00482 (1 << CAP_SYS_NICE));
00483
return 0;
00484 }
00485
00486
case RT_BUDDY: {
00487
return task && current->rtai_tskext(
TSKEXT1) == current ? (
unsigned long)(
task) : 0;
00488 }
00489
00490
case HRT_USE_FPU: {
00491
struct arg {
RT_TASK *
task;
int use_fpu; };
00492
if(!
larg->use_fpu) {
00493
clear_lnxtsk_uses_fpu((
larg->task)->lnxtsk);
00494 }
else {
00495
init_fpu((
larg->task)->lnxtsk);
00496 }
00497
return 0;
00498 }
00499
00500
case GET_USP_FLAGS: {
00501
return arg0.rt_task->usp_flags;
00502 }
00503
case SET_USP_FLAGS: {
00504
struct arg {
RT_TASK *
task;
unsigned long flags; };
00505 arg0.rt_task->usp_flags =
larg->flags;
00506 arg0.rt_task->force_soft = (arg0.rt_task->is_hard > 0) && (
larg->flags & arg0.rt_task->usp_flags_mask &
FORCE_SOFT);
00507
return 0;
00508 }
00509
00510
case GET_USP_FLG_MSK: {
00511
return arg0.rt_task->usp_flags_mask;
00512 }
00513
00514
case SET_USP_FLG_MSK: {
00515
task->usp_flags_mask = arg0.name;
00516
task->force_soft = (
task->is_hard > 0) && (
task->usp_flags & arg0.name &
FORCE_SOFT);
00517
return 0;
00518 }
00519
00520
case FORCE_TASK_SOFT: {
00521
extern void rt_do_force_soft(
RT_TASK *rt_task);
00522
struct task_struct *ltsk;
00523
if ((ltsk = find_task_by_pid(arg0.name))) {
00524
if ((arg0.rt_task = ltsk->rtai_tskext(
TSKEXT0))) {
00525
if ((arg0.rt_task->force_soft = (arg0.rt_task->is_hard > 0) &&
FORCE_SOFT)) {
00526
rt_do_force_soft(arg0.rt_task);
00527 }
00528
return (
unsigned long)arg0.rt_task;
00529 }
00530 }
00531
return 0;
00532 }
00533
00534
case IS_HARD: {
00535
return arg0.rt_task->is_hard;
00536 }
00537
case GET_EXECTIME: {
00538
struct arg {
RT_TASK *
task;
RTIME *exectime; };
00539
if ((
larg->task)->exectime[0] && (
larg->task)->exectime[1]) {
00540
larg->exectime[0] = (
larg->task)->exectime[0];
00541
larg->exectime[1] = (
larg->task)->exectime[1];
00542
larg->exectime[2] =
rdtsc();
00543 }
00544
return 0;
00545 }
00546
case GET_TIMEORIG: {
00547
struct arg {
RTIME *time_orig; };
00548
rt_gettimeorig(
larg->time_orig);
00549
return 0;
00550 }
00551
00552
case LINUX_SERVER_INIT: {
00553
extern RT_TASK *lxrt_init_linux_server(
RT_TASK *master_task);
00554
00555 arg0.rt_task->linux_syscall_server =
__task_init((
unsigned long)arg0.rt_task, arg0.rt_task->base_priority >= BASE_SOFT_PRIORITY ? arg0.rt_task->base_priority - BASE_SOFT_PRIORITY : arg0.rt_task->base_priority, 0, 0, 1 << arg0.rt_task->runnable_on_cpus);
00556
rt_task_resume(arg0.rt_task);
00557
return (
long)arg0.rt_task->linux_syscall_server;
00558 }
00559
00560
default: {
00561
rt_printk(
"RTAI/LXRT: Unknown srq #%d\n",
srq);
00562
return -ENOSYS;
00563 }
00564 }
00565
return 0;
00566 }
00567
00568 static inline void force_soft(
RT_TASK *task)
00569 {
00570
if (
unlikely(
task->force_soft)) {
00571
task->force_soft = 0;
00572
task->usp_flags &= ~
FORCE_SOFT;
00573
give_back_to_linux(
task, 0);
00574 }
00575 }
00576
00577
extern int FASTCALL(do_signal(
struct pt_regs *regs, sigset_t *oldset));
00578 static inline int rt_do_signal(
struct pt_regs *regs,
RT_TASK *task)
00579 {
00580
if (
unlikely(
task->unblocked)) {
00581
int retval =
task->unblocked < 0;
00582
if (
task->is_hard > 0) {
00583
give_back_to_linux(
task, -1);
00584 }
00585
task->unblocked = 0;
00586
#if LINUX_VERSION_CODE < KERNEL_VERSION(0,0,0)
00587
if (
likely(regs->LINUX_SYSCALL_NR <
RTAI_SYSCALL_NR)) {
00588
unsigned long saved_eax = regs->LINUX_SYSCALL_RETREG;
00589 regs->LINUX_SYSCALL_RETREG = -EINTR;
00590 do_signal(regs, NULL);
00591 regs->LINUX_SYSCALL_RETREG = saved_eax;
00592
if (
task->is_hard < 0) {
00593
steal_from_linux(
task);
00594 }
00595 }
00596
#endif
00597
return retval;
00598 }
00599
return 1;
00600 }
00601
00602 long long rtai_lxrt_invoke (
unsigned int lxsrq,
void *arg,
struct pt_regs *regs)
00603 {
00604
long long retval;
00605
RT_TASK *
task;
00606
00607
#ifdef CONFIG_RTAI_TRACE
00608
trace_true_lxrt_rtai_syscall_entry();
00609
#endif
00610
00611
if (
likely((
task = current->rtai_tskext(
TSKEXT0)) != NULL)) {
00612
if (
unlikely(
rt_do_signal(regs,
task))) {
00613
force_soft(
task);
00614 }
00615 }
00616 retval =
handle_lxrt_request(lxsrq, arg,
task);
00617
if (
likely(
task != NULL)) {
00618
if (
unlikely(
rt_do_signal(regs,
task))) {
00619
force_soft(
task);
00620 }
else {
00621
task->system_data_ptr = regs;
00622 retval = -
RT_EINTR;
00623 }
00624 }
00625
00626
#ifdef CONFIG_RTAI_TRACE
00627
trace_true_lxrt_rtai_syscall_exit();
00628
#endif
00629
00630
return retval;
00631 }
00632
00633 int set_rt_fun_ext_index(
struct rt_fun_entry *fun,
int idx)
00634 {
00635
if (idx > 0 && idx <
MAX_FUN_EXT && !
rt_fun_ext[idx]) {
00636
rt_fun_ext[idx] = fun;
00637
return 0;
00638 }
00639
return -EACCES;
00640 }
00641
00642 void reset_rt_fun_ext_index(
struct rt_fun_entry *fun,
int idx)
00643 {
00644
if (idx > 0 && idx <
MAX_FUN_EXT &&
rt_fun_ext[idx] == fun) {
00645
rt_fun_ext[idx] = 0;
00646 }
00647 }
00648
00649 void linux_process_termination(
void)
00650
00651 {
00652
extern int max_slots;
00653
unsigned long numid;
00654
char name[8];
00655
RT_TASK *task2delete;
00656
struct rt_registry_entry entry;
00657
int slot;
00658
00659
00660
00661
00662
if (!(numid =
is_process_registered(current))) {
00663
return;
00664 }
00665
for (slot = 1; slot <=
max_slots; slot++) {
00666
if (!
rt_get_registry_slot(slot, &entry) || entry.
tsk != current ||
rt_drg_on_name_cnt(entry.
name) <= 0) {
00667
continue;
00668 }
00669
num2nam(entry.
name, name);
00670 entry.
tsk = 0;
00671
switch (entry.
type) {
00672
case IS_SEM:
00673
rt_printk(
"LXRT releases SEM %s\n", name);
00674
lxrt_sem_delete(entry.
adr);
00675
rt_free(entry.
adr);
00676
break;
00677
case IS_RWL:
00678
rt_printk(
"LXRT releases RWL %s\n", name);
00679
lxrt_rwl_delete(entry.
adr);
00680
rt_free(entry.
adr);
00681
break;
00682
case IS_SPL:
00683
rt_printk(
"LXRT releases SPL %s\n", name);
00684
lxrt_spl_delete(entry.
adr);
00685
rt_free(entry.
adr);
00686
break;
00687
case IS_MBX:
00688
rt_printk(
"LXRT releases MBX %s\n", name);
00689
lxrt_mbx_delete(entry.
adr);
00690
rt_free(entry.
adr);
00691
break;
00692
case IS_PRX:
00693 numid = rttask2pid(entry.
adr);
00694
rt_printk(
"LXRT releases PROXY PID %lu\n", numid);
00695
lxrt_Proxy_detach(numid);
00696
break;
00697
case IS_TASK:
00698
rt_printk(
"LXRT deregisters task %s %d\n", name, ((
RT_TASK *)entry.
adr)->lnxtsk->pid);
00699
break;
00700 }
00701 }
00702
if ((task2delete = current->rtai_tskext(
TSKEXT0))) {
00703
if (!
clr_rtext(task2delete)) {
00704
rt_drg_on_adr(task2delete);
00705
rt_printk(
"LXRT releases PID %d (ID: %s).\n", current->pid, current->comm);
00706
rt_free(task2delete->msg_buf[0]);
00707
rt_free(task2delete->msg_buf[1]);
00708
rt_free(task2delete);
00709 current->rtai_tskext(
TSKEXT0) = current->rtai_tskext(
TSKEXT1) = 0;
00710 }
00711 }
00712 }
00713
00714 void init_fun_ext (
void)
00715 {
00716
RT_TASK *rt_linux_tasks[
NR_RT_CPUS];
00717
rt_fun_ext[0] =
rt_fun_lxrt;
00718
rt_get_base_linux_task(rt_linux_tasks);
00719 rt_linux_tasks[0]->task_trap_handler[0] = (
void *)
set_rt_fun_ext_index;
00720 rt_linux_tasks[0]->task_trap_handler[1] = (
void *)
reset_rt_fun_ext_index;
00721 }