00001 
00026 #ifndef _RTDM_DRIVER_H
00027 #define _RTDM_DRIVER_H
00028 
00029 #ifndef __KERNEL__
00030 #error This header is for kernel space usage only. \
00031        You are likely looking for rtdm/rtdm.h...
00032 #endif 
00033 
00034 #include <asm/atomic.h>
00035 #include <linux/list.h>
00036 
00037 #include <nucleus/xenomai.h>
00038 #include <nucleus/heap.h>
00039 #include <nucleus/pod.h>
00040 #include <nucleus/synch.h>
00041 #include <nucleus/select.h>
00042 #include <rtdm/rtdm.h>
00043 
00044 
00045 #include <nucleus/assert.h>
00046 #ifdef CONFIG_PCI
00047 #include <asm-generic/xenomai/pci_ids.h>
00048 #endif 
00049 
00050 #ifndef CONFIG_XENO_OPT_DEBUG_RTDM
00051 #define CONFIG_XENO_OPT_DEBUG_RTDM      0
00052 #endif
00053 
00054 struct rtdm_dev_context;
00055 typedef struct xnselector rtdm_selector_t;
00056 enum rtdm_selecttype;
00057 
00070 #define RTDM_EXCLUSIVE                  0x0001
00071 
00073 #define RTDM_NAMED_DEVICE               0x0010
00074 
00077 #define RTDM_PROTOCOL_DEVICE            0x0020
00078 
00080 #define RTDM_DEVICE_TYPE_MASK           0x00F0
00081 
00090 #define RTDM_CREATED_IN_NRT             0
00091 
00093 #define RTDM_CLOSING                    1
00094 
00096 #define RTDM_USER_CONTEXT_FLAG          8  
00097 
00106 #define RTDM_DEVICE_STRUCT_VER          5
00107 
00109 #define RTDM_CONTEXT_STRUCT_VER         3
00110 
00112 #define RTDM_SECURE_DEVICE              0x80000000
00113 
00115 #define RTDM_DRIVER_VER(major, minor, patch) \
00116         (((major & 0xFF) << 16) | ((minor & 0xFF) << 8) | (patch & 0xFF))
00117 
00119 #define RTDM_DRIVER_MAJOR_VER(ver)      (((ver) >> 16) & 0xFF)
00120 
00122 #define RTDM_DRIVER_MINOR_VER(ver)      (((ver) >> 8) & 0xFF)
00123 
00125 #define RTDM_DRIVER_PATCH_VER(ver)      ((ver) & 0xFF)
00126 
00138 enum rtdm_selecttype {
00140         RTDM_SELECTTYPE_READ = XNSELECT_READ,
00141 
00143         RTDM_SELECTTYPE_WRITE = XNSELECT_WRITE,
00144 
00146         RTDM_SELECTTYPE_EXCEPT = XNSELECT_EXCEPT
00147 };
00171 typedef int (*rtdm_open_handler_t)(struct rtdm_dev_context *context,
00172                                    rtdm_user_info_t *user_info, int oflag);
00173 
00188 typedef int (*rtdm_socket_handler_t)(struct rtdm_dev_context *context,
00189                                      rtdm_user_info_t *user_info, int protocol);
00190 
00204 typedef int (*rtdm_close_handler_t)(struct rtdm_dev_context *context,
00205                                     rtdm_user_info_t *user_info);
00206 
00222 typedef int (*rtdm_ioctl_handler_t)(struct rtdm_dev_context *context,
00223                                     rtdm_user_info_t *user_info,
00224                                     unsigned int request, void __user *arg);
00225 
00239 typedef int (*rtdm_select_bind_handler_t)(struct rtdm_dev_context *context,
00240                                           rtdm_selector_t *selector,
00241                                           enum rtdm_selecttype type,
00242                                           unsigned fd_index);
00243 
00259 typedef ssize_t (*rtdm_read_handler_t)(struct rtdm_dev_context *context,
00260                                        rtdm_user_info_t *user_info,
00261                                        void *buf, size_t nbyte);
00262 
00278 typedef ssize_t (*rtdm_write_handler_t)(struct rtdm_dev_context *context,
00279                                         rtdm_user_info_t *user_info,
00280                                         const void *buf, size_t nbyte);
00281 
00298 typedef ssize_t (*rtdm_recvmsg_handler_t)(struct rtdm_dev_context *context,
00299                                           rtdm_user_info_t *user_info,
00300                                           struct msghdr *msg, int flags);
00301 
00318 typedef ssize_t (*rtdm_sendmsg_handler_t)(struct rtdm_dev_context *context,
00319                                           rtdm_user_info_t *user_info,
00320                                           const struct msghdr *msg, int flags);
00323 typedef int (*rtdm_rt_handler_t)(struct rtdm_dev_context *context,
00324                                  rtdm_user_info_t *user_info, void *arg);
00328 struct rtdm_operations {
00332         rtdm_close_handler_t close_rt;
00334         rtdm_close_handler_t close_nrt;
00335 
00337         rtdm_ioctl_handler_t ioctl_rt;
00339         rtdm_ioctl_handler_t ioctl_nrt;
00340 
00342         rtdm_select_bind_handler_t select_bind;
00348         rtdm_read_handler_t read_rt;
00350         rtdm_read_handler_t read_nrt;
00351 
00353         rtdm_write_handler_t write_rt;
00355         rtdm_write_handler_t write_nrt;
00361         rtdm_recvmsg_handler_t recvmsg_rt;
00363         rtdm_recvmsg_handler_t recvmsg_nrt;
00364 
00366         rtdm_sendmsg_handler_t sendmsg_rt;
00368         rtdm_sendmsg_handler_t sendmsg_nrt;
00370 };
00371 
00372 struct rtdm_devctx_reserved {
00373         void *owner;
00374 };
00375 
00387 struct rtdm_dev_context {
00389         unsigned long context_flags;
00390 
00392         int fd;
00393 
00396         atomic_t close_lock_count;
00397 
00399         struct rtdm_operations *ops;
00400 
00402         struct rtdm_device *device;
00403 
00405         struct rtdm_devctx_reserved reserved;
00406 
00408         char dev_private[0];
00409 };
00410 
00419 static inline void *
00420 rtdm_context_to_private(struct rtdm_dev_context *context)
00421 {
00422         return (void *)context->dev_private;
00423 }
00424 
00433 static inline struct rtdm_dev_context *
00434 rtdm_private_to_context(void *dev_private)
00435 {
00436         return container_of(dev_private, struct rtdm_dev_context, dev_private);
00437 }
00438 
00439 struct rtdm_dev_reserved {
00440         struct list_head entry;
00441         atomic_t refcount;
00442         struct rtdm_dev_context *exclusive_context;
00443 };
00444 
00452 struct rtdm_device {
00455         int struct_version;
00456 
00458         int device_flags;
00460         size_t context_size;
00461 
00463         char device_name[RTDM_MAX_DEVNAME_LEN + 1];
00464 
00466         int protocol_family;
00468         int socket_type;
00469 
00472         rtdm_open_handler_t open_rt;
00475         rtdm_open_handler_t open_nrt;
00476 
00479         rtdm_socket_handler_t socket_rt;
00482         rtdm_socket_handler_t socket_nrt;
00483 
00485         struct rtdm_operations ops;
00486 
00488         int device_class;
00491         int device_sub_class;
00493         int profile_version;
00495         const char *driver_name;
00497         int driver_version;
00500         const char *peripheral_name;
00502         const char *provider_name;
00503 
00505         const char *proc_name;
00507         struct proc_dir_entry *proc_entry;
00508 
00510         int device_id;
00512         void *device_data;
00513 
00515         struct rtdm_dev_reserved reserved;
00516 };
00519 
00520 
00521 int rtdm_dev_register(struct rtdm_device *device);
00522 int rtdm_dev_unregister(struct rtdm_device *device, unsigned int poll_delay);
00523 
00524 
00525 
00526 #define rtdm_open               rt_dev_open
00527 #define rtdm_socket             rt_dev_socket
00528 #define rtdm_close              rt_dev_close
00529 #define rtdm_ioctl              rt_dev_ioctl
00530 #define rtdm_read               rt_dev_read
00531 #define rtdm_write              rt_dev_write
00532 #define rtdm_recvmsg            rt_dev_recvmsg
00533 #define rtdm_recv               rt_dev_recv
00534 #define rtdm_recvfrom           rt_dev_recvfrom
00535 #define rtdm_sendmsg            rt_dev_sendmsg
00536 #define rtdm_send               rt_dev_send
00537 #define rtdm_sendto             rt_dev_sendto
00538 #define rtdm_bind               rt_dev_bind
00539 #define rtdm_listen             rt_dev_listen
00540 #define rtdm_accept             rt_dev_accept
00541 #define rtdm_getsockopt         rt_dev_getsockopt
00542 #define rtdm_setsockopt         rt_dev_setsockopt
00543 #define rtdm_getsockname        rt_dev_getsockname
00544 #define rtdm_getpeername        rt_dev_getpeername
00545 #define rtdm_shutdown           rt_dev_shutdown
00546 
00547 struct rtdm_dev_context *rtdm_context_get(int fd);
00548 
00549 #ifndef DOXYGEN_CPP 
00550 static inline void rtdm_context_lock(struct rtdm_dev_context *context)
00551 {
00552         atomic_inc(&context->close_lock_count);
00553 }
00554 
00555 static inline void rtdm_context_unlock(struct rtdm_dev_context *context)
00556 {
00557         smp_mb__before_atomic_dec();
00558         atomic_dec(&context->close_lock_count);
00559 }
00560 
00561 
00562 struct xntbase;
00563 extern struct xntbase *rtdm_tbase;
00564 
00565 static inline nanosecs_abs_t rtdm_clock_read(void)
00566 {
00567         return xntbase_ticks2ns(rtdm_tbase, xntbase_get_time(rtdm_tbase));
00568 }
00569 
00570 static inline nanosecs_abs_t rtdm_clock_read_monotonic(void)
00571 {
00572         return xntbase_ticks2ns(rtdm_tbase, xntbase_get_jiffies(rtdm_tbase));
00573 }
00574 #endif 
00575 
00581 int rtdm_select_bind(int fd, rtdm_selector_t *selector,
00582                      enum rtdm_selecttype type, unsigned fd_index);
00583 
00584 
00622 #ifdef DOXYGEN_CPP 
00623 #define RTDM_EXECUTE_ATOMICALLY(code_block)     \
00624 {                                               \
00625         <ENTER_ATOMIC_SECTION>                  \
00626         code_block;                             \
00627         <LEAVE_ATOMIC_SECTION>                  \
00628 }
00629 #else 
00630 #define RTDM_EXECUTE_ATOMICALLY(code_block)             \
00631 {                                                       \
00632         spl_t __rtdm_s;                                 \
00633                                                         \
00634         xnlock_get_irqsave(&nklock, __rtdm_s);          \
00635         code_block;                                     \
00636         xnlock_put_irqrestore(&nklock, __rtdm_s);       \
00637 }
00638 #endif
00639 
00649 #define RTDM_LOCK_UNLOCKED      RTHAL_SPIN_LOCK_UNLOCKED
00650 
00652 typedef rthal_spinlock_t rtdm_lock_t;
00653 
00655 typedef unsigned long rtdm_lockctx_t;
00656 
00672 #define rtdm_lock_init(lock)    rthal_spin_lock_init(lock)
00673 
00690 #ifdef DOXYGEN_CPP 
00691 #define rtdm_lock_get(lock)     rthal_spin_lock(lock)
00692 #else 
00693 #define rtdm_lock_get(lock)                                     \
00694         do {                                                    \
00695                 XENO_BUGON(RTDM, !rthal_local_irq_disabled());  \
00696                 rthal_spin_lock(lock);                          \
00697         } while (0)
00698 #endif
00699 
00716 #define rtdm_lock_put(lock)     rthal_spin_unlock(lock)
00717 
00735 #define rtdm_lock_get_irqsave(lock, context)    \
00736         rthal_spin_lock_irqsave(lock, context)
00737 
00755 #define rtdm_lock_put_irqrestore(lock, context) \
00756         rthal_spin_unlock_irqrestore(lock, context)
00757 
00774 #define rtdm_lock_irqsave(context)      \
00775         rthal_local_irq_save(context)
00776 
00793 #define rtdm_lock_irqrestore(context)   \
00794         rthal_local_irq_restore(context)
00795 
00799 
00805 typedef xnintr_t rtdm_irq_t;
00806 
00813 #define RTDM_IRQTYPE_SHARED             XN_ISR_SHARED
00814 
00816 #define RTDM_IRQTYPE_EDGE               XN_ISR_EDGE
00817 
00826 typedef int (*rtdm_irq_handler_t)(rtdm_irq_t *irq_handle);
00827 
00834 #define RTDM_IRQ_NONE                   XN_ISR_NONE
00835 
00836 #define RTDM_IRQ_HANDLED                XN_ISR_HANDLED
00837 
00856 #define rtdm_irq_get_arg(irq_handle, type)      ((type *)irq_handle->cookie)
00857 
00859 int rtdm_irq_request(rtdm_irq_t *irq_handle, unsigned int irq_no,
00860                      rtdm_irq_handler_t handler, unsigned long flags,
00861                      const char *device_name, void *arg);
00862 
00863 #ifndef DOXYGEN_CPP 
00864 static inline int rtdm_irq_free(rtdm_irq_t *irq_handle)
00865 {
00866         return xnintr_detach(irq_handle);
00867 }
00868 
00869 static inline int rtdm_irq_enable(rtdm_irq_t *irq_handle)
00870 {
00871         return xnintr_enable(irq_handle);
00872 }
00873 
00874 static inline int rtdm_irq_disable(rtdm_irq_t *irq_handle)
00875 {
00876         return xnintr_disable(irq_handle);
00877 }
00878 #endif 
00879 
00880 
00881 
00887 typedef unsigned rtdm_nrtsig_t;
00888 
00899 typedef void (*rtdm_nrtsig_handler_t)(rtdm_nrtsig_t nrt_sig, void *arg);
00902 #ifndef DOXYGEN_CPP 
00903 static inline int rtdm_nrtsig_init(rtdm_nrtsig_t *nrt_sig,
00904                                    rtdm_nrtsig_handler_t handler, void *arg)
00905 {
00906         *nrt_sig = rthal_alloc_virq();
00907 
00908         if (*nrt_sig == 0)
00909                 return -EAGAIN;
00910 
00911         rthal_virtualize_irq(rthal_root_domain, *nrt_sig, handler, arg, NULL,
00912                              IPIPE_HANDLE_MASK);
00913         return 0;
00914 }
00915 
00916 static inline void rtdm_nrtsig_destroy(rtdm_nrtsig_t *nrt_sig)
00917 {
00918         rthal_free_virq(*nrt_sig);
00919 }
00920 
00921 static inline void rtdm_nrtsig_pend(rtdm_nrtsig_t *nrt_sig)
00922 {
00923         rthal_trigger_irq(*nrt_sig);
00924 }
00925 #endif 
00926 
00927 
00928 
00934 typedef xntimer_t rtdm_timer_t;
00935 
00941 typedef void (*rtdm_timer_handler_t)(rtdm_timer_t *timer);
00942 
00948 enum rtdm_timer_mode {
00950         RTDM_TIMERMODE_RELATIVE = XN_RELATIVE,
00951 
00953         RTDM_TIMERMODE_ABSOLUTE = XN_ABSOLUTE,
00954 
00956         RTDM_TIMERMODE_REALTIME = XN_REALTIME
00957 };
00962 #ifndef DOXYGEN_CPP 
00963 #define rtdm_timer_init(timer, handler, name)           \
00964 ({                                                      \
00965         xntimer_init((timer), rtdm_tbase, handler);     \
00966         xntimer_set_name((timer), (name));              \
00967         0;                                              \
00968 })
00969 #endif 
00970 
00971 void rtdm_timer_destroy(rtdm_timer_t *timer);
00972 
00973 int rtdm_timer_start(rtdm_timer_t *timer, nanosecs_abs_t expiry,
00974                      nanosecs_rel_t interval, enum rtdm_timer_mode mode);
00975 
00976 void rtdm_timer_stop(rtdm_timer_t *timer);
00977 
00978 #ifndef DOXYGEN_CPP 
00979 static inline int rtdm_timer_start_in_handler(rtdm_timer_t *timer,
00980                                               nanosecs_abs_t expiry,
00981                                               nanosecs_rel_t interval,
00982                                               enum rtdm_timer_mode mode)
00983 {
00984         return xntimer_start(timer, xntbase_ns2ticks_ceil(rtdm_tbase, expiry),
00985                              xntbase_ns2ticks_ceil(rtdm_tbase, interval),
00986                              (xntmode_t)mode);
00987 }
00988 
00989 static inline void rtdm_timer_stop_in_handler(rtdm_timer_t *timer)
00990 {
00991         xntimer_stop(timer);
00992 }
00993 #endif 
00994 
00995 
01001 typedef xnthread_t rtdm_task_t;
01002 
01008 typedef void (*rtdm_task_proc_t)(void *arg);
01009 
01014 #define RTDM_TASK_LOWEST_PRIORITY       XNSCHED_LOW_PRIO
01015 #define RTDM_TASK_HIGHEST_PRIORITY      XNSCHED_HIGH_PRIO
01016 
01022 #define RTDM_TASK_RAISE_PRIORITY        (+1)
01023 #define RTDM_TASK_LOWER_PRIORITY        (-1)
01024 
01028 int rtdm_task_init(rtdm_task_t *task, const char *name,
01029                    rtdm_task_proc_t task_proc, void *arg,
01030                    int priority, nanosecs_rel_t period);
01031 int __rtdm_task_sleep(xnticks_t timeout, xntmode_t mode);
01032 void rtdm_task_busy_sleep(nanosecs_rel_t delay);
01033 
01034 #ifndef DOXYGEN_CPP 
01035 static inline void rtdm_task_destroy(rtdm_task_t *task)
01036 {
01037         xnpod_delete_thread(task);
01038 }
01039 
01040 void rtdm_task_join_nrt(rtdm_task_t *task, unsigned int poll_delay);
01041 
01042 static inline void rtdm_task_set_priority(rtdm_task_t *task, int priority)
01043 {
01044         union xnsched_policy_param param = { .rt = { .prio = priority } };
01045         xnpod_set_thread_schedparam(task, &xnsched_class_rt, ¶m);
01046         xnpod_schedule();
01047 }
01048 
01049 static inline int rtdm_task_set_period(rtdm_task_t *task,
01050                                        nanosecs_rel_t period)
01051 {
01052         if (period < 0)
01053                 period = 0;
01054         return xnpod_set_thread_periodic(task, XN_INFINITE,
01055                                          xntbase_ns2ticks_ceil
01056                                          (xnthread_time_base(task), period));
01057 }
01058 
01059 static inline int rtdm_task_unblock(rtdm_task_t *task)
01060 {
01061         int res = xnpod_unblock_thread(task);
01062 
01063         xnpod_schedule();
01064         return res;
01065 }
01066 
01067 static inline rtdm_task_t *rtdm_task_current(void)
01068 {
01069         return xnpod_current_thread();
01070 }
01071 
01072 static inline int rtdm_task_wait_period(void)
01073 {
01074         XENO_ASSERT(RTDM, !xnpod_unblockable_p(), return -EPERM;);
01075         return xnpod_wait_thread_period(NULL);
01076 }
01077 
01078 static inline int rtdm_task_sleep(nanosecs_rel_t delay)
01079 {
01080         return __rtdm_task_sleep(delay, XN_RELATIVE);
01081 }
01082 
01083 static inline int
01084 rtdm_task_sleep_abs(nanosecs_abs_t wakeup_date, enum rtdm_timer_mode mode)
01085 {
01086         
01087         if (mode != RTDM_TIMERMODE_ABSOLUTE && mode != RTDM_TIMERMODE_REALTIME)
01088                 return -EINVAL;
01089         return __rtdm_task_sleep(wakeup_date, (xntmode_t)mode);
01090 }
01091 
01092 
01093 static inline int __deprecated rtdm_task_sleep_until(nanosecs_abs_t wakeup_time)
01094 {
01095         return __rtdm_task_sleep(wakeup_time, XN_REALTIME);
01096 }
01097 #endif 
01098 
01099 
01100 
01101 typedef nanosecs_abs_t rtdm_toseq_t;
01102 
01103 void rtdm_toseq_init(rtdm_toseq_t *timeout_seq, nanosecs_rel_t timeout);
01104 
01105 
01106 
01107 typedef struct {
01108         xnsynch_t synch_base;
01109         DECLARE_XNSELECT(select_block);
01110 } rtdm_event_t;
01111 
01112 #define RTDM_EVENT_PENDING              XNSYNCH_SPARE1
01113 
01114 void rtdm_event_init(rtdm_event_t *event, unsigned long pending);
01115 #ifdef CONFIG_XENO_OPT_RTDM_SELECT
01116 int rtdm_event_select_bind(rtdm_event_t *event, rtdm_selector_t *selector,
01117                            enum rtdm_selecttype type, unsigned fd_index);
01118 #else 
01119 #define rtdm_event_select_bind(e, s, t, i) ({ (void)(e); -EBADF; })
01120 #endif 
01121 int rtdm_event_wait(rtdm_event_t *event);
01122 int rtdm_event_timedwait(rtdm_event_t *event, nanosecs_rel_t timeout,
01123                          rtdm_toseq_t *timeout_seq);
01124 void rtdm_event_signal(rtdm_event_t *event);
01125 
01126 void rtdm_event_clear(rtdm_event_t *event);
01127 
01128 #ifndef DOXYGEN_CPP 
01129 void __rtdm_synch_flush(xnsynch_t *synch, unsigned long reason);
01130 
01131 static inline void rtdm_event_pulse(rtdm_event_t *event)
01132 {
01133         trace_mark(xn_rtdm, event_pulse, "event %p", event);
01134         __rtdm_synch_flush(&event->synch_base, 0);
01135 }
01136 
01137 static inline void rtdm_event_destroy(rtdm_event_t *event)
01138 {
01139         trace_mark(xn_rtdm, event_destroy, "event %p", event);
01140         __rtdm_synch_flush(&event->synch_base, XNRMID);
01141         xnselect_destroy(&event->select_block);
01142 }
01143 #endif 
01144 
01145 
01146 
01147 typedef struct {
01148         unsigned long value;
01149         xnsynch_t synch_base;
01150         DECLARE_XNSELECT(select_block);
01151 } rtdm_sem_t;
01152 
01153 void rtdm_sem_init(rtdm_sem_t *sem, unsigned long value);
01154 #ifdef CONFIG_XENO_OPT_RTDM_SELECT
01155 int rtdm_sem_select_bind(rtdm_sem_t *sem, rtdm_selector_t *selector,
01156                          enum rtdm_selecttype type, unsigned fd_index);
01157 #else 
01158 #define rtdm_sem_select_bind(s, se, t, i) ({ (void)(s); -EBADF; })
01159 #endif 
01160 int rtdm_sem_down(rtdm_sem_t *sem);
01161 int rtdm_sem_timeddown(rtdm_sem_t *sem, nanosecs_rel_t timeout,
01162                        rtdm_toseq_t *timeout_seq);
01163 void rtdm_sem_up(rtdm_sem_t *sem);
01164 
01165 #ifndef DOXYGEN_CPP 
01166 static inline void rtdm_sem_destroy(rtdm_sem_t *sem)
01167 {
01168         trace_mark(xn_rtdm, sem_destroy, "sem %p", sem);
01169         __rtdm_synch_flush(&sem->synch_base, XNRMID);
01170         xnselect_destroy(&sem->select_block);
01171 }
01172 #endif 
01173 
01174 
01175 
01176 typedef struct {
01177         xnsynch_t synch_base;
01178 } rtdm_mutex_t;
01179 
01180 void rtdm_mutex_init(rtdm_mutex_t *mutex);
01181 int rtdm_mutex_lock(rtdm_mutex_t *mutex);
01182 int rtdm_mutex_timedlock(rtdm_mutex_t *mutex, nanosecs_rel_t timeout,
01183                          rtdm_toseq_t *timeout_seq);
01184 
01185 #ifndef DOXYGEN_CPP 
01186 static inline void rtdm_mutex_unlock(rtdm_mutex_t *mutex)
01187 {
01188         XENO_ASSERT(RTDM, !xnpod_asynch_p(), return;);
01189 
01190         trace_mark(xn_rtdm, mutex_unlock, "mutex %p", mutex);
01191 
01192         if (unlikely(xnsynch_release(&mutex->synch_base) != NULL))
01193                 xnpod_schedule();
01194 }
01195 
01196 static inline void rtdm_mutex_destroy(rtdm_mutex_t *mutex)
01197 {
01198         trace_mark(xn_rtdm, mutex_destroy, "mutex %p", mutex);
01199 
01200         __rtdm_synch_flush(&mutex->synch_base, XNRMID);
01201 }
01202 #endif 
01203 
01204 
01205 
01206 #define rtdm_printk(format, ...)        printk(format, ##__VA_ARGS__)
01207 
01208 #ifndef DOXYGEN_CPP 
01209 static inline void *rtdm_malloc(size_t size)
01210 {
01211         return xnmalloc(size);
01212 }
01213 
01214 static inline void rtdm_free(void *ptr)
01215 {
01216         xnfree(ptr);
01217 }
01218 
01219 #ifdef CONFIG_XENO_OPT_PERVASIVE
01220 int rtdm_mmap_to_user(rtdm_user_info_t *user_info,
01221                       void *src_addr, size_t len,
01222                       int prot, void **pptr,
01223                       struct vm_operations_struct *vm_ops,
01224                       void *vm_private_data);
01225 int rtdm_iomap_to_user(rtdm_user_info_t *user_info,
01226                        phys_addr_t src_addr, size_t len,
01227                        int prot, void **pptr,
01228                        struct vm_operations_struct *vm_ops,
01229                        void *vm_private_data);
01230 int rtdm_munmap(rtdm_user_info_t *user_info, void *ptr, size_t len);
01231 
01232 static inline int rtdm_read_user_ok(rtdm_user_info_t *user_info,
01233                                     const void __user *ptr, size_t size)
01234 {
01235         return access_rok(ptr, size);
01236 }
01237 
01238 static inline int rtdm_rw_user_ok(rtdm_user_info_t *user_info,
01239                                   const void __user *ptr, size_t size)
01240 {
01241         return access_wok(ptr, size);
01242 }
01243 
01244 static inline int rtdm_copy_from_user(rtdm_user_info_t *user_info,
01245                                       void *dst, const void __user *src,
01246                                       size_t size)
01247 {
01248         return __xn_copy_from_user(dst, src, size) ? -EFAULT : 0;
01249 }
01250 
01251 static inline int rtdm_safe_copy_from_user(rtdm_user_info_t *user_info,
01252                                            void *dst, const void __user *src,
01253                                            size_t size)
01254 {
01255         return (!access_rok(src, size) ||
01256                 __xn_copy_from_user(dst, src, size)) ? -EFAULT : 0;
01257 }
01258 
01259 static inline int rtdm_copy_to_user(rtdm_user_info_t *user_info,
01260                                     void __user *dst, const void *src,
01261                                     size_t size)
01262 {
01263         return __xn_copy_to_user(dst, src, size) ? -EFAULT : 0;
01264 }
01265 
01266 static inline int rtdm_safe_copy_to_user(rtdm_user_info_t *user_info,
01267                                          void __user *dst, const void *src,
01268                                          size_t size)
01269 {
01270         return (!access_wok(dst, size) ||
01271                 __xn_copy_to_user(dst, src, size)) ? -EFAULT : 0;
01272 }
01273 
01274 static inline int rtdm_strncpy_from_user(rtdm_user_info_t *user_info,
01275                                          char *dst,
01276                                          const char __user *src, size_t count)
01277 {
01278         if (unlikely(!access_rok(src, 1)))
01279                 return -EFAULT;
01280         return __xn_strncpy_from_user(dst, src, count);
01281 }
01282 #else 
01283 
01284 #define rtdm_mmap_to_user(...)          ({ -ENOSYS; })
01285 #define rtdm_munmap(...)                ({ -ENOSYS; })
01286 #define rtdm_read_user_ok(...)          ({ 0; })
01287 #define rtdm_rw_user_ok(...)            ({ 0; })
01288 #define rtdm_copy_from_user(...)        ({ -ENOSYS; })
01289 #define rtdm_safe_copy_from_user(...)   ({ -ENOSYS; })
01290 #define rtdm_copy_to_user(...)          ({ -ENOSYS; })
01291 #define rtdm_safe_copy_to_user(...)     ({ -ENOSYS; })
01292 #define rtdm_strncpy_from_user(...)     ({ -ENOSYS; })
01293 #endif 
01294 
01295 static inline int rtdm_in_rt_context(void)
01296 {
01297         return (rthal_current_domain != rthal_root_domain);
01298 }
01299 #endif 
01300 
01301 int rtdm_exec_in_rt(struct rtdm_dev_context *context,
01302                     rtdm_user_info_t *user_info, void *arg,
01303                     rtdm_rt_handler_t handler);
01304 
01305 #endif