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
00027
00028
00029
00030
00031 #include <linux/kernel.h>
00032 #include <linux/module.h>
00033
00034 #include <asm/uaccess.h>
00035
00036 #include <rtai_schedcore.h>
00037 #include <rtai_prinher.h>
00038
00039 MODULE_LICENSE("GPL");
00040
00041
00042
00043 #define _mbx_signal(mbx, blckdon) \
00044 do { \
00045 unsigned long flags; \
00046 RT_TASK *task; \
00047 flags = rt_global_save_flags_and_cli(); \
00048 if ((task = mbx->waiting_task)) { \
00049 rem_timed_task(task); \
00050 task->blocked_on = blckdon; \
00051 mbx->waiting_task = NULL; \
00052 if (task->state != RT_SCHED_READY && (task->state &= ~(RT_SCHED_MBXSUSP | RT_SCHED_DELAYED)) == RT_SCHED_READY) { \
00053 enq_ready_task(task); \
00054 RT_SCHEDULE(task, rtai_cpuid()); \
00055 } \
00056 } \
00057 rt_global_restore_flags(flags); \
00058 } while (0)
00059
00060 static void mbx_delete_signal(MBX *mbx)
00061 {
00062 _mbx_signal(mbx, RTP_OBJREM);
00063 }
00064
00065 static void mbx_signal(MBX *mbx)
00066 {
00067 _mbx_signal(mbx, NULL);
00068 }
00069
00070 static int mbx_wait(MBX *mbx, int *fravbs, RT_TASK *rt_current)
00071 {
00072 unsigned long flags;
00073
00074 flags = rt_global_save_flags_and_cli();
00075 if (!(*fravbs)) {
00076 unsigned long retval;
00077 rt_current->state |= RT_SCHED_MBXSUSP;
00078 rem_ready_current(rt_current);
00079 rt_current->blocked_on = (void *)mbx;
00080 mbx->waiting_task = rt_current;
00081 rt_schedule();
00082 if (unlikely(retval = (unsigned long)rt_current->blocked_on)) {
00083 mbx->waiting_task = NULL;
00084 rt_global_restore_flags(flags);
00085 return retval;
00086 }
00087 }
00088 rt_global_restore_flags(flags);
00089 return 0;
00090 }
00091
00092 static int mbx_wait_until(MBX *mbx, int *fravbs, RTIME time, RT_TASK *rt_current)
00093 {
00094 unsigned long flags;
00095
00096 flags = rt_global_save_flags_and_cli();
00097 if (!(*fravbs)) {
00098 void *retp;
00099 rt_current->blocked_on = (void *)mbx;
00100 mbx->waiting_task = rt_current;
00101 if ((rt_current->resume_time = time) > rt_smp_time_h[rtai_cpuid()]) {
00102 rt_current->state |= (RT_SCHED_MBXSUSP | RT_SCHED_DELAYED);
00103 rem_ready_current(rt_current);
00104 enq_timed_task(rt_current);
00105 rt_schedule();
00106 }
00107 if (unlikely((retp = rt_current->blocked_on) != NULL)) {
00108 mbx->waiting_task = NULL;
00109 rt_global_restore_flags(flags);
00110 return likely(retp > RTP_HIGERR) ? RTE_TIMOUT : (retp == RTP_UNBLKD ? RTE_UNBLKD : RTE_OBJREM);
00111 }
00112 }
00113 rt_global_restore_flags(flags);
00114 return 0;
00115 }
00116
00117 #define MOD_SIZE(indx) ((indx) < mbx->size ? (indx) : (indx) - mbx->size)
00118
00119 static int mbxput(MBX *mbx, char **msg, int msg_size, int space)
00120 {
00121 unsigned long flags;
00122 int tocpy;
00123
00124 while (msg_size > 0 && mbx->frbs) {
00125 if ((tocpy = mbx->size - mbx->lbyte) > msg_size) {
00126 tocpy = msg_size;
00127 }
00128 if (tocpy > mbx->frbs) {
00129 tocpy = mbx->frbs;
00130 }
00131 if (space) {
00132 memcpy(mbx->bufadr + mbx->lbyte, *msg, tocpy);
00133 } else {
00134 rt_copy_from_user(mbx->bufadr + mbx->lbyte, *msg, tocpy);
00135 }
00136 flags = rt_spin_lock_irqsave(&(mbx->lock));
00137 mbx->frbs -= tocpy;
00138 mbx->avbs += tocpy;
00139 rt_spin_unlock_irqrestore(flags, &(mbx->lock));
00140 msg_size -= tocpy;
00141 *msg += tocpy;
00142 mbx->lbyte = MOD_SIZE(mbx->lbyte + tocpy);
00143 }
00144 return msg_size;
00145 }
00146
00147 static int mbxovrwrput(MBX *mbx, char **msg, int msg_size, int space)
00148 {
00149 unsigned long flags;
00150 int tocpy,n;
00151
00152 if ((n = msg_size - mbx->size) > 0) {
00153 *msg += n;
00154 msg_size -= n;
00155 }
00156 while (msg_size > 0) {
00157 if (mbx->frbs) {
00158 if ((tocpy = mbx->size - mbx->lbyte) > msg_size) {
00159 tocpy = msg_size;
00160 }
00161 if (tocpy > mbx->frbs) {
00162 tocpy = mbx->frbs;
00163 }
00164 if (space) {
00165 memcpy(mbx->bufadr + mbx->lbyte, *msg, tocpy);
00166 } else {
00167 rt_copy_from_user(mbx->bufadr + mbx->lbyte, *msg, tocpy);
00168 }
00169 flags = rt_spin_lock_irqsave(&(mbx->lock));
00170 mbx->frbs -= tocpy;
00171 mbx->avbs += tocpy;
00172 rt_spin_unlock_irqrestore(flags, &(mbx->lock));
00173 msg_size -= tocpy;
00174 *msg += tocpy;
00175 mbx->lbyte = MOD_SIZE(mbx->lbyte + tocpy);
00176 }
00177 if (msg_size) {
00178 while ((n = msg_size - mbx->frbs) > 0) {
00179 if ((tocpy = mbx->size - mbx->fbyte) > n) {
00180 tocpy = n;
00181 }
00182 if (tocpy > mbx->avbs) {
00183 tocpy = mbx->avbs;
00184 }
00185 flags = rt_spin_lock_irqsave(&(mbx->lock));
00186 mbx->frbs += tocpy;
00187 mbx->avbs -= tocpy;
00188 rt_spin_unlock_irqrestore(flags, &(mbx->lock));
00189 mbx->fbyte = MOD_SIZE(mbx->fbyte + tocpy);
00190 }
00191 }
00192 }
00193 return 0;
00194 }
00195
00196 static int mbxget(MBX *mbx, char **msg, int msg_size, int space)
00197 {
00198 unsigned long flags;
00199 int tocpy;
00200
00201 while (msg_size > 0 && mbx->avbs) {
00202 if ((tocpy = mbx->size - mbx->fbyte) > msg_size) {
00203 tocpy = msg_size;
00204 }
00205 if (tocpy > mbx->avbs) {
00206 tocpy = mbx->avbs;
00207 }
00208 if (space) {
00209 memcpy(*msg, mbx->bufadr + mbx->fbyte, tocpy);
00210 } else {
00211 rt_copy_to_user(*msg, mbx->bufadr + mbx->fbyte, tocpy);
00212 }
00213 flags = rt_spin_lock_irqsave(&(mbx->lock));
00214 mbx->frbs += tocpy;
00215 mbx->avbs -= tocpy;
00216 rt_spin_unlock_irqrestore(flags, &(mbx->lock));
00217 msg_size -= tocpy;
00218 *msg += tocpy;
00219 mbx->fbyte = MOD_SIZE(mbx->fbyte + tocpy);
00220 }
00221 return msg_size;
00222 }
00223
00224 static int mbxevdrp(MBX *mbx, char **msg, int msg_size, int space)
00225 {
00226 int tocpy, fbyte, avbs;
00227
00228 fbyte = mbx->fbyte;
00229 avbs = mbx->avbs;
00230 while (msg_size > 0 && avbs) {
00231 if ((tocpy = mbx->size - fbyte) > msg_size) {
00232 tocpy = msg_size;
00233 }
00234 if (tocpy > avbs) {
00235 tocpy = avbs;
00236 }
00237 if (space) {
00238 memcpy(*msg, mbx->bufadr + fbyte, tocpy);
00239 } else {
00240 rt_copy_to_user(*msg, mbx->bufadr + mbx->fbyte, tocpy);
00241 }
00242 avbs -= tocpy;
00243 msg_size -= tocpy;
00244 *msg += tocpy;
00245 fbyte = MOD_SIZE(fbyte + tocpy);
00246 }
00247 return msg_size;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 RTAI_SYSCALL_MODE int _rt_mbx_evdrp(MBX *mbx, void *msg, int msg_size, int space)
00270 {
00271 return mbxevdrp(mbx, (char **)(&msg), msg_size, space);
00272 }
00273
00274
00275 #define CHK_MBX_MAGIC \
00276 do { if (!mbx || mbx->magic != RT_MBX_MAGIC) return (CONFIG_RTAI_USE_NEWERR ? RTE_OBJINV : -EINVAL); } while (0)
00277
00278 #define MBX_RET(msg_size, retval) \
00279 (CONFIG_RTAI_USE_NEWERR ? retval : msg_size)
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 RTAI_SYSCALL_MODE int rt_typed_mbx_init(MBX *mbx, int size, int type)
00302 {
00303 if (!(mbx->bufadr = rt_malloc(size))) {
00304 return -ENOMEM;
00305 }
00306 rt_typed_sem_init(&(mbx->sndsem), 1, type & 3 ? type : BIN_SEM | type);
00307 rt_typed_sem_init(&(mbx->rcvsem), 1, type & 3 ? type : BIN_SEM | type);
00308 mbx->magic = RT_MBX_MAGIC;
00309 mbx->size = mbx->frbs = size;
00310 mbx->owndby = mbx->waiting_task = NULL;
00311 mbx->fbyte = mbx->lbyte = mbx->avbs = 0;
00312 spin_lock_init(&(mbx->lock));
00313 #ifdef CONFIG_RTAI_RT_POLL
00314 mbx->poll_recv.pollq.prev = mbx->poll_recv.pollq.next = &(mbx->poll_recv.pollq);
00315 mbx->poll_send.pollq.prev = mbx->poll_send.pollq.next = &(mbx->poll_send.pollq);
00316 mbx->poll_recv.pollq.task = mbx->poll_send.pollq.task = NULL;
00317 spin_lock_init(&(mbx->poll_recv.pollock));
00318 spin_lock_init(&(mbx->poll_send.pollock));
00319 #endif
00320 return 0;
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 int rt_mbx_init(MBX *mbx, int size)
00358 {
00359 return rt_typed_mbx_init(mbx, size, PRIO_Q);
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 RTAI_SYSCALL_MODE int rt_mbx_delete(MBX *mbx)
00378 {
00379 CHK_MBX_MAGIC;
00380 mbx->magic = 0;
00381 rt_wakeup_pollers(&mbx->poll_recv, RTE_OBJREM);
00382 rt_wakeup_pollers(&mbx->poll_send, RTE_OBJREM);
00383 if (rt_sem_delete(&mbx->sndsem) || rt_sem_delete(&mbx->rcvsem)) {
00384 return -EFAULT;
00385 }
00386 while (mbx->waiting_task) {
00387 mbx_delete_signal(mbx);
00388 }
00389 rt_free(mbx->bufadr);
00390 return 0;
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 RTAI_SYSCALL_MODE int _rt_mbx_send(MBX *mbx, void *msg, int msg_size, int space)
00417 {
00418 RT_TASK *rt_current = RT_CURRENT;
00419 int retval;
00420
00421 CHK_MBX_MAGIC;
00422 if ((retval = rt_sem_wait(&mbx->sndsem)) > 1) {
00423 return MBX_RET(msg_size, retval);
00424 }
00425 while (msg_size) {
00426 if ((retval = mbx_wait(mbx, &mbx->frbs, rt_current))) {
00427 rt_sem_signal(&mbx->sndsem);
00428 retval = MBX_RET(msg_size, retval);
00429 rt_wakeup_pollers(&mbx->poll_recv, retval);
00430 return retval;
00431 }
00432 msg_size = mbxput(mbx, (char **)(&msg), msg_size, space);
00433 mbx_signal(mbx);
00434 }
00435 rt_sem_signal(&mbx->sndsem);
00436 rt_wakeup_pollers(&mbx->poll_recv, 0);
00437 return 0;
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 RTAI_SYSCALL_MODE int _rt_mbx_send_wp(MBX *mbx, void *msg, int msg_size, int space)
00458 {
00459 unsigned long flags;
00460 RT_TASK *rt_current = RT_CURRENT;
00461 int size = msg_size;
00462
00463 CHK_MBX_MAGIC;
00464 flags = rt_global_save_flags_and_cli();
00465 if (mbx->sndsem.count > 0 && mbx->frbs) {
00466 mbx->sndsem.count = 0;
00467 if (mbx->sndsem.type > 0) {
00468 mbx->sndsem.owndby = rt_current;
00469 enqueue_resqel(&mbx->sndsem.resq, rt_current);
00470 }
00471 rt_global_restore_flags(flags);
00472 msg_size = mbxput(mbx, (char **)(&msg), msg_size, space);
00473 mbx_signal(mbx);
00474 rt_sem_signal(&mbx->sndsem);
00475 } else {
00476 rt_global_restore_flags(flags);
00477 }
00478 if (msg_size < size) {
00479 rt_wakeup_pollers(&mbx->poll_recv, 0);
00480 }
00481 return msg_size;
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 RTAI_SYSCALL_MODE int _rt_mbx_send_if(MBX *mbx, void *msg, int msg_size, int space)
00499 {
00500 unsigned long flags;
00501 RT_TASK *rt_current = RT_CURRENT;
00502
00503 CHK_MBX_MAGIC;
00504 flags = rt_global_save_flags_and_cli();
00505 if (mbx->sndsem.count > 0 && msg_size <= mbx->frbs) {
00506 mbx->sndsem.count = 0;
00507 if (mbx->sndsem.type > 0) {
00508 mbx->sndsem.owndby = rt_current;
00509 enqueue_resqel(&mbx->sndsem.resq, rt_current);
00510 }
00511 rt_global_restore_flags(flags);
00512 mbxput(mbx, (char **)(&msg), msg_size, space);
00513 mbx_signal(mbx);
00514 rt_sem_signal(&mbx->sndsem);
00515 rt_wakeup_pollers(&mbx->poll_recv, 0);
00516 return 0;
00517 }
00518 rt_global_restore_flags(flags);
00519 return msg_size;
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 RTAI_SYSCALL_MODE int _rt_mbx_send_until(MBX *mbx, void *msg, int msg_size, RTIME time, int space)
00547 {
00548 RT_TASK *rt_current = RT_CURRENT;
00549 int retval;
00550
00551 CHK_MBX_MAGIC;
00552 if ((retval = rt_sem_wait_until(&mbx->sndsem, time)) > 1) {
00553 return MBX_RET(msg_size, retval);
00554 }
00555 while (msg_size) {
00556 if ((retval = mbx_wait_until(mbx, &mbx->frbs, time, rt_current))) {
00557 rt_sem_signal(&mbx->sndsem);
00558 retval = MBX_RET(msg_size, retval);
00559 rt_wakeup_pollers(&mbx->poll_recv, retval);
00560 return retval;
00561 }
00562 msg_size = mbxput(mbx, (char **)(&msg), msg_size, space);
00563 mbx_signal(mbx);
00564 }
00565 rt_sem_signal(&mbx->sndsem);
00566 rt_wakeup_pollers(&mbx->poll_recv, 0);
00567 return 0;
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594 RTAI_SYSCALL_MODE int _rt_mbx_send_timed(MBX *mbx, void *msg, int msg_size, RTIME delay, int space)
00595 {
00596 return _rt_mbx_send_until(mbx, msg, msg_size, get_time() + delay, space);
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619 RTAI_SYSCALL_MODE int _rt_mbx_receive(MBX *mbx, void *msg, int msg_size, int space)
00620 {
00621 RT_TASK *rt_current = RT_CURRENT;
00622 int retval;
00623
00624 CHK_MBX_MAGIC;
00625 if ((retval = rt_sem_wait(&mbx->rcvsem)) > 1) {
00626 return msg_size;
00627 }
00628 while (msg_size) {
00629 if ((retval = mbx_wait(mbx, &mbx->avbs, rt_current))) {
00630 rt_sem_signal(&mbx->rcvsem);
00631 retval = MBX_RET(msg_size, retval);
00632 rt_wakeup_pollers(&mbx->poll_recv, retval);
00633 return retval;
00634 return MBX_RET(msg_size, retval);
00635 }
00636 msg_size = mbxget(mbx, (char **)(&msg), msg_size, space);
00637 mbx_signal(mbx);
00638 }
00639 rt_sem_signal(&mbx->rcvsem);
00640 rt_wakeup_pollers(&mbx->poll_send, 0);
00641 return 0;
00642 }
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662 RTAI_SYSCALL_MODE int _rt_mbx_receive_wp(MBX *mbx, void *msg, int msg_size, int space)
00663 {
00664 unsigned long flags;
00665 RT_TASK *rt_current = RT_CURRENT;
00666 int size = msg_size;
00667
00668 CHK_MBX_MAGIC;
00669 flags = rt_global_save_flags_and_cli();
00670 if (mbx->rcvsem.count > 0 && mbx->avbs) {
00671 mbx->rcvsem.count = 0;
00672 if (mbx->rcvsem.type > 0) {
00673 mbx->rcvsem.owndby = rt_current;
00674 enqueue_resqel(&mbx->rcvsem.resq, rt_current);
00675 }
00676 rt_global_restore_flags(flags);
00677 msg_size = mbxget(mbx, (char **)(&msg), msg_size, space);
00678 mbx_signal(mbx);
00679 rt_sem_signal(&mbx->rcvsem);
00680 } else {
00681 rt_global_restore_flags(flags);
00682 }
00683 if (msg_size < size) {
00684 rt_wakeup_pollers(&mbx->poll_send, 0);
00685 }
00686 return msg_size;
00687 }
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708 RTAI_SYSCALL_MODE int _rt_mbx_receive_if(MBX *mbx, void *msg, int msg_size, int space)
00709 {
00710 unsigned long flags;
00711 RT_TASK *rt_current = RT_CURRENT;
00712
00713 CHK_MBX_MAGIC;
00714 flags = rt_global_save_flags_and_cli();
00715 if (mbx->rcvsem.count > 0 && msg_size <= mbx->avbs) {
00716 mbx->rcvsem.count = 0;
00717 if (mbx->rcvsem.type > 0) {
00718 mbx->rcvsem.owndby = rt_current;
00719 enqueue_resqel(&mbx->rcvsem.resq, rt_current);
00720 }
00721 rt_global_restore_flags(flags);
00722 mbxget(mbx, (char **)(&msg), msg_size, space);
00723 mbx_signal(mbx);
00724 rt_sem_signal(&mbx->rcvsem);
00725 rt_wakeup_pollers(&mbx->poll_send, 0);
00726 return 0;
00727 }
00728 rt_global_restore_flags(flags);
00729 return msg_size;
00730 }
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 RTAI_SYSCALL_MODE int _rt_mbx_receive_until(MBX *mbx, void *msg, int msg_size, RTIME time, int space)
00757 {
00758 RT_TASK *rt_current = RT_CURRENT;
00759 int retval;
00760
00761 CHK_MBX_MAGIC;
00762 if ((retval = rt_sem_wait_until(&mbx->rcvsem, time)) > 1) {
00763 return MBX_RET(msg_size, retval);
00764 }
00765 while (msg_size) {
00766 if ((retval = mbx_wait_until(mbx, &mbx->avbs, time, rt_current))) {
00767 rt_sem_signal(&mbx->rcvsem);
00768 retval = MBX_RET(msg_size, retval);
00769 rt_wakeup_pollers(&mbx->poll_recv, retval);
00770 return retval;
00771 }
00772 msg_size = mbxget(mbx, (char **)(&msg), msg_size, space);
00773 mbx_signal(mbx);
00774 }
00775 rt_sem_signal(&mbx->rcvsem);
00776 rt_wakeup_pollers(&mbx->poll_send, 0);
00777 return 0;
00778 }
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804 RTAI_SYSCALL_MODE int _rt_mbx_receive_timed(MBX *mbx, void *msg, int msg_size, RTIME delay, int space)
00805 {
00806 return _rt_mbx_receive_until(mbx, msg, msg_size, get_time() + delay, space);
00807 }
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 RTAI_SYSCALL_MODE int _rt_mbx_ovrwr_send(MBX *mbx, void *msg, int msg_size, int space)
00824 {
00825 unsigned long flags;
00826 RT_TASK *rt_current = RT_CURRENT;
00827
00828 CHK_MBX_MAGIC;
00829
00830 flags = rt_global_save_flags_and_cli();
00831 if (mbx->sndsem.count > 0) {
00832 mbx->sndsem.count = 0;
00833 if (mbx->sndsem.type > 0) {
00834 mbx->sndsem.owndby = rt_current;
00835 enqueue_resqel(&mbx->sndsem.resq, rt_current);
00836 }
00837 rt_global_restore_flags(flags);
00838 msg_size = mbxovrwrput(mbx, (char **)(&msg), msg_size, space);
00839 mbx_signal(mbx);
00840 rt_sem_signal(&mbx->sndsem);
00841 } else {
00842 rt_global_restore_flags(flags);
00843 }
00844 return msg_size;
00845 }
00846
00847
00848
00849 #include <rtai_registry.h>
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 RTAI_SYSCALL_MODE MBX *_rt_typed_named_mbx_init(unsigned long mbx_name, int size, int qtype)
00875 {
00876 MBX *mbx;
00877
00878 if ((mbx = rt_get_adr_cnt(mbx_name))) {
00879 return mbx;
00880 }
00881 if ((mbx = rt_malloc(sizeof(MBX)))) {
00882 rt_typed_mbx_init(mbx, size, qtype);
00883 if (rt_register(mbx_name, mbx, IS_MBX, 0)) {
00884 return mbx;
00885 }
00886 rt_mbx_delete(mbx);
00887 }
00888 rt_free(mbx);
00889 return (MBX *)0;
00890 }
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 RTAI_SYSCALL_MODE int rt_named_mbx_delete(MBX *mbx)
00914 {
00915 int ret;
00916 if (!(ret = rt_drg_on_adr_cnt(mbx))) {
00917 if (!rt_mbx_delete(mbx)) {
00918 rt_free(mbx);
00919 return 0;
00920 } else {
00921 return -EFAULT;
00922 }
00923 }
00924 return ret;
00925 }
00926
00927
00928
00929 struct rt_native_fun_entry rt_mbx_entries[] = {
00930
00931 { { 0, rt_typed_mbx_init }, TYPED_MBX_INIT },
00932 { { 0, rt_mbx_delete }, MBX_DELETE },
00933 { { 1, _rt_mbx_send }, MBX_SEND },
00934 { { 1, _rt_mbx_send_wp }, MBX_SEND_WP },
00935 { { 1, _rt_mbx_send_if }, MBX_SEND_IF },
00936 { { 1, _rt_mbx_send_until }, MBX_SEND_UNTIL },
00937 { { 1, _rt_mbx_send_timed }, MBX_SEND_TIMED },
00938 { { 1, _rt_mbx_ovrwr_send }, MBX_OVRWR_SEND },
00939 { { 1, _rt_mbx_evdrp }, MBX_EVDRP },
00940 { { 1, _rt_mbx_receive }, MBX_RECEIVE },
00941 { { 1, _rt_mbx_receive_wp }, MBX_RECEIVE_WP },
00942 { { 1, _rt_mbx_receive_if }, MBX_RECEIVE_IF },
00943 { { 1, _rt_mbx_receive_until }, MBX_RECEIVE_UNTIL },
00944 { { 1, _rt_mbx_receive_timed }, MBX_RECEIVE_TIMED },
00945 { { 0, _rt_typed_named_mbx_init }, NAMED_MBX_INIT },
00946 { { 0, rt_named_mbx_delete }, NAMED_MBX_DELETE },
00947 { { 0, 0 }, 000 }
00948 };
00949
00950 extern int set_rt_fun_entries(struct rt_native_fun_entry *entry);
00951 extern void reset_rt_fun_entries(struct rt_native_fun_entry *entry);
00952
00953 static int recv_blocks(void *mbx) { return ((MBX *)mbx)->avbs <= 0; }
00954 static int send_blocks(void *mbx) { return ((MBX *)mbx)->frbs <= 0; }
00955
00956 int __rtai_mbx_init (void)
00957 {
00958 rt_poll_ofstfun[RT_POLL_MBX_RECV].topoll = recv_blocks;
00959 rt_poll_ofstfun[RT_POLL_MBX_SEND].topoll = send_blocks;
00960 return set_rt_fun_entries(rt_mbx_entries);
00961 }
00962
00963 void __rtai_mbx_exit (void)
00964 {
00965 rt_poll_ofstfun[RT_POLL_MBX_RECV].topoll = NULL;
00966 rt_poll_ofstfun[RT_POLL_MBX_SEND].topoll = NULL;
00967 reset_rt_fun_entries(rt_mbx_entries);
00968 }
00969
00970
00971
00972 #ifndef CONFIG_RTAI_MBX_BUILTIN
00973 module_init(__rtai_mbx_init);
00974 module_exit(__rtai_mbx_exit);
00975 #endif
00976
00977 #ifdef CONFIG_KBUILD
00978 EXPORT_SYMBOL(_rt_mbx_evdrp);
00979 EXPORT_SYMBOL(rt_typed_mbx_init);
00980 EXPORT_SYMBOL(rt_mbx_init);
00981 EXPORT_SYMBOL(rt_mbx_delete);
00982 EXPORT_SYMBOL(_rt_mbx_send);
00983 EXPORT_SYMBOL(_rt_mbx_send_wp);
00984 EXPORT_SYMBOL(_rt_mbx_send_if);
00985 EXPORT_SYMBOL(_rt_mbx_send_until);
00986 EXPORT_SYMBOL(_rt_mbx_send_timed);
00987 EXPORT_SYMBOL(_rt_mbx_receive);
00988 EXPORT_SYMBOL(_rt_mbx_receive_wp);
00989 EXPORT_SYMBOL(_rt_mbx_receive_if);
00990 EXPORT_SYMBOL(_rt_mbx_receive_until);
00991 EXPORT_SYMBOL(_rt_mbx_receive_timed);
00992 EXPORT_SYMBOL(_rt_mbx_ovrwr_send);
00993 EXPORT_SYMBOL(_rt_typed_named_mbx_init);
00994 EXPORT_SYMBOL(rt_named_mbx_delete);
00995 #endif