include/rtdm/rtdm_driver.h

Go to the documentation of this file.
00001 
00025 #ifndef _RTDM_DRIVER_H
00026 #define _RTDM_DRIVER_H
00027 
00028 #ifndef __KERNEL__
00029 #error This header is for kernel space usage only. \
00030        You are likely looking for rtdm/rtdm.h...
00031 #endif /* !__KERNEL__ */
00032 
00033 #include <asm/atomic.h>
00034 #include <linux/list.h>
00035 
00036 #include <nucleus/xenomai.h>
00037 #include <nucleus/core.h>
00038 #include <nucleus/heap.h>
00039 #include <nucleus/pod.h>
00040 #include <nucleus/synch.h>
00041 #include <rtdm/rtdm.h>
00042 
00043 /* debug support */
00044 #include <nucleus/assert.h>
00045 
00046 #ifndef CONFIG_XENO_OPT_DEBUG_RTDM
00047 #define CONFIG_XENO_OPT_DEBUG_RTDM      0
00048 #endif
00049 
00050 struct rtdm_dev_context;
00051 
00064 #define RTDM_EXCLUSIVE                  0x0001
00065 
00067 #define RTDM_NAMED_DEVICE               0x0010
00068 
00071 #define RTDM_PROTOCOL_DEVICE            0x0020
00072 
00074 #define RTDM_DEVICE_TYPE_MASK           0x00F0
00075 
00084 #define RTDM_CREATED_IN_NRT             0
00085 
00087 #define RTDM_CLOSING                    1
00088 
00090 #define RTDM_USER_CONTEXT_FLAG          8  /* first user-definable flag */
00091 
00100 #define RTDM_DEVICE_STRUCT_VER          4
00101 
00103 #define RTDM_CONTEXT_STRUCT_VER         3
00104 
00106 #define RTDM_SECURE_DEVICE              0x80000000
00107 
00109 #define RTDM_DRIVER_VER(major, minor, patch) \
00110         (((major & 0xFF) << 16) | ((minor & 0xFF) << 8) | (patch & 0xFF))
00111 
00113 #define RTDM_DRIVER_MAJOR_VER(ver)      (((ver) >> 16) & 0xFF)
00114 
00116 #define RTDM_DRIVER_MINOR_VER(ver)      (((ver) >> 8) & 0xFF)
00117 
00119 #define RTDM_DRIVER_PATCH_VER(ver)      ((ver) & 0xFF)
00120 
00139 typedef int (*rtdm_open_handler_t)(struct rtdm_dev_context *context,
00140                                    rtdm_user_info_t *user_info, int oflag);
00141 
00154 typedef int (*rtdm_socket_handler_t)(struct rtdm_dev_context *context,
00155                                      rtdm_user_info_t *user_info, int protocol);
00156 
00168 typedef int (*rtdm_close_handler_t)(struct rtdm_dev_context *context,
00169                                     rtdm_user_info_t *user_info);
00170 
00184 typedef int (*rtdm_ioctl_handler_t)(struct rtdm_dev_context *context,
00185                                     rtdm_user_info_t *user_info,
00186                                     unsigned int request, void __user *arg);
00187 
00201 typedef ssize_t (*rtdm_read_handler_t)(struct rtdm_dev_context *context,
00202                                        rtdm_user_info_t *user_info,
00203                                        void *buf, size_t nbyte);
00204 
00219 typedef ssize_t (*rtdm_write_handler_t)(struct rtdm_dev_context *context,
00220                                         rtdm_user_info_t *user_info,
00221                                         const void *buf, size_t nbyte);
00222 
00238 typedef ssize_t (*rtdm_recvmsg_handler_t)(struct rtdm_dev_context *context,
00239                                           rtdm_user_info_t *user_info,
00240                                           struct msghdr *msg, int flags);
00241 
00257 typedef ssize_t (*rtdm_sendmsg_handler_t)(struct rtdm_dev_context *context,
00258                                           rtdm_user_info_t *user_info,
00259                                           const struct msghdr *msg, int flags);
00262 typedef int (*rtdm_rt_handler_t)(struct rtdm_dev_context *context,
00263                                  rtdm_user_info_t *user_info, void *arg);
00264 
00268 struct rtdm_operations {
00272         rtdm_close_handler_t close_rt;
00274         rtdm_close_handler_t close_nrt;
00275 
00277         rtdm_ioctl_handler_t ioctl_rt;
00279         rtdm_ioctl_handler_t ioctl_nrt;
00285         rtdm_read_handler_t read_rt;
00287         rtdm_read_handler_t read_nrt;
00288 
00290         rtdm_write_handler_t write_rt;
00292         rtdm_write_handler_t write_nrt;
00298         rtdm_recvmsg_handler_t recvmsg_rt;
00300         rtdm_recvmsg_handler_t recvmsg_nrt;
00301 
00303         rtdm_sendmsg_handler_t sendmsg_rt;
00305         rtdm_sendmsg_handler_t sendmsg_nrt;
00307 };
00308 
00309 struct rtdm_devctx_reserved {
00310         void *owner;
00311 };
00312 
00324 struct rtdm_dev_context {
00326         unsigned long context_flags;
00327 
00329         int fd;
00330 
00333         atomic_t close_lock_count;
00334 
00336         struct rtdm_operations *ops;
00337 
00339         struct rtdm_device *device;
00340 
00342         struct rtdm_devctx_reserved reserved;
00343 
00345         char dev_private[0];
00346 };
00347 
00348 struct rtdm_dev_reserved {
00349         struct list_head entry;
00350         atomic_t refcount;
00351         struct rtdm_dev_context *exclusive_context;
00352 };
00353 
00361 struct rtdm_device {
00364         int struct_version;
00365 
00367         int device_flags;
00369         size_t context_size;
00370 
00372         char device_name[RTDM_MAX_DEVNAME_LEN + 1];
00373 
00375         int protocol_family;
00377         int socket_type;
00378 
00381         rtdm_open_handler_t open_rt;
00384         rtdm_open_handler_t open_nrt;
00385 
00388         rtdm_socket_handler_t socket_rt;
00391         rtdm_socket_handler_t socket_nrt;
00392 
00394         struct rtdm_operations ops;
00395 
00397         int device_class;
00400         int device_sub_class;
00402         int profile_version;
00404         const char *driver_name;
00406         int driver_version;
00409         const char *peripheral_name;
00411         const char *provider_name;
00412 
00414         const char *proc_name;
00416         struct proc_dir_entry *proc_entry;
00417 
00419         int device_id;
00421         void *device_data;
00422 
00424         struct rtdm_dev_reserved reserved;
00425 };
00428 /* --- device registration --- */
00429 
00430 int rtdm_dev_register(struct rtdm_device *device);
00431 int rtdm_dev_unregister(struct rtdm_device *device, unsigned int poll_delay);
00432 
00433 /* --- inter-driver API --- */
00434 
00435 #define rtdm_open               rt_dev_open
00436 #define rtdm_socket             rt_dev_socket
00437 #define rtdm_close              rt_dev_close
00438 #define rtdm_ioctl              rt_dev_ioctl
00439 #define rtdm_read               rt_dev_read
00440 #define rtdm_write              rt_dev_write
00441 #define rtdm_recvmsg            rt_dev_recvmsg
00442 #define rtdm_recv               rt_dev_recv
00443 #define rtdm_recvfrom           rt_dev_recvfrom
00444 #define rtdm_sendmsg            rt_dev_sendmsg
00445 #define rtdm_send               rt_dev_send
00446 #define rtdm_sendto             rt_dev_sendto
00447 #define rtdm_bind               rt_dev_bind
00448 #define rtdm_listen             rt_dev_listen
00449 #define rtdm_accept             rt_dev_accept
00450 #define rtdm_getsockopt         rt_dev_getsockopt
00451 #define rtdm_setsockopt         rt_dev_setsockopt
00452 #define rtdm_getsockname        rt_dev_getsockname
00453 #define rtdm_getpeername        rt_dev_getpeername
00454 #define rtdm_shutdown           rt_dev_shutdown
00455 
00456 struct rtdm_dev_context *rtdm_context_get(int fd);
00457 
00458 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
00459 static inline void rtdm_context_lock(struct rtdm_dev_context *context)
00460 {
00461         atomic_inc(&context->close_lock_count);
00462 }
00463 
00464 static inline void rtdm_context_unlock(struct rtdm_dev_context *context)
00465 {
00466         atomic_dec(&context->close_lock_count);
00467 }
00468 
00469 /* --- clock services --- */
00470 struct xntbase;
00471 extern struct xntbase *rtdm_tbase;
00472 
00473 static inline nanosecs_abs_t rtdm_clock_read(void)
00474 {
00475         return xntbase_ticks2ns(rtdm_tbase, xntbase_get_time(rtdm_tbase));
00476 }
00477 
00478 static inline nanosecs_abs_t rtdm_clock_read_monotonic(void)
00479 {
00480         return xntbase_ticks2ns(rtdm_tbase, xntbase_get_jiffies(rtdm_tbase));
00481 }
00482 #endif /* !DOXYGEN_CPP */
00483 
00484 /* --- spin lock services --- */
00527 #ifdef DOXYGEN_CPP /* Beautify doxygen output */
00528 #define RTDM_EXECUTE_ATOMICALLY(code_block)     \
00529 {                                               \
00530         <ENTER_ATOMIC_SECTION>                  \
00531         code_block;                             \
00532         <LEAVE_ATOMIC_SECTION>                  \
00533 }
00534 #else /* This is how it really works */
00535 #define RTDM_EXECUTE_ATOMICALLY(code_block)     \
00536 {                                               \
00537         spl_t s;                                \
00538                                                 \
00539         xnlock_get_irqsave(&nklock, s);         \
00540         code_block;                             \
00541         xnlock_put_irqrestore(&nklock, s);      \
00542 }
00543 #endif
00544 
00554 #define RTDM_LOCK_UNLOCKED      RTHAL_SPIN_LOCK_UNLOCKED
00555 
00557 typedef rthal_spinlock_t rtdm_lock_t;
00558 
00560 typedef unsigned long rtdm_lockctx_t;
00561 
00577 #define rtdm_lock_init(lock)    rthal_spin_lock_init(lock)
00578 
00595 #define rtdm_lock_get(lock)     rthal_spin_lock(lock)
00596 
00613 #define rtdm_lock_put(lock)     rthal_spin_unlock(lock)
00614 
00632 #define rtdm_lock_get_irqsave(lock, context)    \
00633         rthal_spin_lock_irqsave(lock, context)
00634 
00652 #define rtdm_lock_put_irqrestore(lock, context) \
00653         rthal_spin_unlock_irqrestore(lock, context)
00654 
00671 #define rtdm_lock_irqsave(context)      \
00672         rthal_local_irq_save(context)
00673 
00690 #define rtdm_lock_irqrestore(context)   \
00691         rthal_local_irq_restore(context)
00692 
00696 /* --- Interrupt management services --- */
00702 typedef xnintr_t rtdm_irq_t;
00703 
00710 #define RTDM_IRQTYPE_SHARED             XN_ISR_SHARED
00711 
00713 #define RTDM_IRQTYPE_EDGE               XN_ISR_EDGE
00714 
00723 typedef int (*rtdm_irq_handler_t)(rtdm_irq_t *irq_handle);
00724 
00731 #define RTDM_IRQ_NONE                   XN_ISR_NONE
00732 
00733 #define RTDM_IRQ_HANDLED                XN_ISR_HANDLED
00734 
00753 #define rtdm_irq_get_arg(irq_handle, type)      ((type *)irq_handle->cookie)
00754 
00756 int rtdm_irq_request(rtdm_irq_t *irq_handle, unsigned int irq_no,
00757                      rtdm_irq_handler_t handler, unsigned long flags,
00758                      const char *device_name, void *arg);
00759 
00760 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
00761 static inline int rtdm_irq_free(rtdm_irq_t *irq_handle)
00762 {
00763         return xnintr_detach(irq_handle);
00764 }
00765 
00766 static inline int rtdm_irq_enable(rtdm_irq_t *irq_handle)
00767 {
00768         return xnintr_enable(irq_handle);
00769 }
00770 
00771 static inline int rtdm_irq_disable(rtdm_irq_t *irq_handle)
00772 {
00773         return xnintr_disable(irq_handle);
00774 }
00775 #endif /* !DOXYGEN_CPP */
00776 
00777 /* --- non-real-time signalling services --- */
00778 
00784 typedef unsigned rtdm_nrtsig_t;
00785 
00796 typedef void (*rtdm_nrtsig_handler_t)(rtdm_nrtsig_t nrt_sig, void *arg);
00799 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
00800 static inline int rtdm_nrtsig_init(rtdm_nrtsig_t *nrt_sig,
00801                                    rtdm_nrtsig_handler_t handler, void *arg)
00802 {
00803         *nrt_sig = rthal_alloc_virq();
00804 
00805         if (*nrt_sig == 0)
00806                 return -EAGAIN;
00807 
00808         rthal_virtualize_irq(rthal_root_domain, *nrt_sig, handler, arg, NULL,
00809                              IPIPE_HANDLE_MASK);
00810         return 0;
00811 }
00812 
00813 static inline void rtdm_nrtsig_destroy(rtdm_nrtsig_t *nrt_sig)
00814 {
00815         rthal_free_virq(*nrt_sig);
00816 }
00817 
00818 static inline void rtdm_nrtsig_pend(rtdm_nrtsig_t *nrt_sig)
00819 {
00820         rthal_trigger_irq(*nrt_sig);
00821 }
00822 #endif /* !DOXYGEN_CPP */
00823 
00824 /* --- timer services --- */
00825 
00831 typedef xntimer_t rtdm_timer_t;
00832 
00838 typedef void (*rtdm_timer_handler_t)(rtdm_timer_t *timer);
00839 
00845 enum rtdm_timer_mode {
00847         RTDM_TIMERMODE_RELATIVE = XN_RELATIVE,
00848 
00850         RTDM_TIMERMODE_ABSOLUTE = XN_ABSOLUTE,
00851 
00853         RTDM_TIMERMODE_REALTIME = XN_REALTIME
00854 };
00859 #ifndef DOXYGEN_CPP /* Avoid broken doxygen output */
00860 #define rtdm_timer_init(timer, handler, name)           \
00861 ({                                                      \
00862         xntimer_init((timer), rtdm_tbase, handler);     \
00863         xntimer_set_name((timer), (name));              \
00864         0;                                              \
00865 })
00866 #endif /* !DOXYGEN_CPP */
00867 
00868 void rtdm_timer_destroy(rtdm_timer_t *timer);
00869 
00870 int rtdm_timer_start(rtdm_timer_t *timer, nanosecs_abs_t expiry,
00871                      nanosecs_rel_t interval, enum rtdm_timer_mode mode);
00872 
00873 void rtdm_timer_stop(rtdm_timer_t *timer);
00874 
00875 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
00876 static inline int rtdm_timer_start_in_handler(rtdm_timer_t *timer,
00877                                               nanosecs_abs_t expiry,
00878                                               nanosecs_rel_t interval,
00879                                               enum rtdm_timer_mode mode)
00880 {
00881         return xntimer_start(timer, xntbase_ns2ticks_ceil(rtdm_tbase, expiry),
00882                              xntbase_ns2ticks_ceil(rtdm_tbase, interval),
00883                              (xntmode_t)mode);
00884 }
00885 
00886 static inline void rtdm_timer_stop_in_handler(rtdm_timer_t *timer)
00887 {
00888         xntimer_stop(timer);
00889 }
00890 #endif /* !DOXYGEN_CPP */
00891 
00892 /* --- task services --- */
00898 typedef xnthread_t rtdm_task_t;
00899 
00905 typedef void (*rtdm_task_proc_t)(void *arg);
00906 
00911 #define RTDM_TASK_LOWEST_PRIORITY       XNCORE_LOW_PRIO
00912 #define RTDM_TASK_HIGHEST_PRIORITY      XNCORE_HIGH_PRIO
00913 
00919 #define RTDM_TASK_RAISE_PRIORITY        (+1)
00920 #define RTDM_TASK_LOWER_PRIORITY        (-1)
00921 
00925 int rtdm_task_init(rtdm_task_t *task, const char *name,
00926                    rtdm_task_proc_t task_proc, void *arg,
00927                    int priority, nanosecs_rel_t period);
00928 int __rtdm_task_sleep(xnticks_t timeout, xntmode_t mode);
00929 void rtdm_task_busy_sleep(nanosecs_rel_t delay);
00930 
00931 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
00932 static inline void rtdm_task_destroy(rtdm_task_t *task)
00933 {
00934         xnpod_delete_thread(task);
00935 }
00936 
00937 void rtdm_task_join_nrt(rtdm_task_t *task, unsigned int poll_delay);
00938 
00939 static inline void rtdm_task_set_priority(rtdm_task_t *task, int priority)
00940 {
00941         xnpod_renice_thread(task, priority);
00942         xnpod_schedule();
00943 }
00944 
00945 static inline int rtdm_task_set_period(rtdm_task_t *task,
00946                                        nanosecs_rel_t period)
00947 {
00948         if (period < 0)
00949                 period = 0;
00950         return xnpod_set_thread_periodic(task, XN_INFINITE,
00951                                          xntbase_ns2ticks_ceil
00952                                          (xnthread_time_base(task), period));
00953 }
00954 
00955 static inline int rtdm_task_unblock(rtdm_task_t *task)
00956 {
00957         int res = xnpod_unblock_thread(task);
00958 
00959         xnpod_schedule();
00960         return res;
00961 }
00962 
00963 static inline rtdm_task_t *rtdm_task_current(void)
00964 {
00965         return xnpod_current_thread();
00966 }
00967 
00968 static inline int rtdm_task_wait_period(void)
00969 {
00970         XENO_ASSERT(RTDM, !xnpod_unblockable_p(), return -EPERM;);
00971         return xnpod_wait_thread_period(NULL);
00972 }
00973 
00974 static inline int rtdm_task_sleep(nanosecs_rel_t delay)
00975 {
00976         return __rtdm_task_sleep(delay, XN_RELATIVE);
00977 }
00978 
00979 static inline int
00980 rtdm_task_sleep_abs(nanosecs_abs_t wakeup_date, enum rtdm_timer_mode mode)
00981 {
00982         /* For the sake of a consistent API usage... */
00983         if (mode != RTDM_TIMERMODE_ABSOLUTE && mode != RTDM_TIMERMODE_REALTIME)
00984                 return -EINVAL;
00985         return __rtdm_task_sleep(wakeup_date, (xntmode_t)mode);
00986 }
00987 
00988 /* rtdm_task_sleep_abs shall be used instead */
00989 static inline int __deprecated rtdm_task_sleep_until(nanosecs_abs_t wakeup_time)
00990 {
00991         return __rtdm_task_sleep(wakeup_time, XN_REALTIME);
00992 }
00993 #endif /* !DOXYGEN_CPP */
00994 
00995 /* --- timeout sequences */
00996 
00997 typedef nanosecs_abs_t rtdm_toseq_t;
00998 
00999 void rtdm_toseq_init(rtdm_toseq_t *timeout_seq, nanosecs_rel_t timeout);
01000 
01001 /* --- event services --- */
01002 
01003 typedef struct {
01004         xnsynch_t synch_base;
01005 } rtdm_event_t;
01006 
01007 #define RTDM_EVENT_PENDING              XNSYNCH_SPARE1
01008 
01009 void rtdm_event_init(rtdm_event_t *event, unsigned long pending);
01010 int rtdm_event_wait(rtdm_event_t *event);
01011 int rtdm_event_timedwait(rtdm_event_t *event, nanosecs_rel_t timeout,
01012                          rtdm_toseq_t *timeout_seq);
01013 void rtdm_event_signal(rtdm_event_t *event);
01014 
01015 void rtdm_event_clear(rtdm_event_t *event);
01016 
01017 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
01018 void __rtdm_synch_flush(xnsynch_t *synch, unsigned long reason);
01019 
01020 static inline void rtdm_event_pulse(rtdm_event_t *event)
01021 {
01022         trace_mark(xn_rtdm_event_pulse, "event %p", event);
01023         __rtdm_synch_flush(&event->synch_base, 0);
01024 }
01025 
01026 static inline void rtdm_event_destroy(rtdm_event_t *event)
01027 {
01028         trace_mark(xn_rtdm_event_destroy, "event %p", event);
01029         __rtdm_synch_flush(&event->synch_base, XNRMID);
01030 }
01031 #endif /* !DOXYGEN_CPP */
01032 
01033 /* --- semaphore services --- */
01034 
01035 typedef struct {
01036         unsigned long value;
01037         xnsynch_t synch_base;
01038 } rtdm_sem_t;
01039 
01040 void rtdm_sem_init(rtdm_sem_t *sem, unsigned long value);
01041 int rtdm_sem_down(rtdm_sem_t *sem);
01042 int rtdm_sem_timeddown(rtdm_sem_t *sem, nanosecs_rel_t timeout,
01043                        rtdm_toseq_t *timeout_seq);
01044 void rtdm_sem_up(rtdm_sem_t *sem);
01045 
01046 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
01047 static inline void rtdm_sem_destroy(rtdm_sem_t *sem)
01048 {
01049         trace_mark(xn_rtdm_sem_destroy, "sem %p", sem);
01050         __rtdm_synch_flush(&sem->synch_base, XNRMID);
01051 }
01052 #endif /* !DOXYGEN_CPP */
01053 
01054 /* --- mutex services --- */
01055 
01056 typedef struct {
01057         xnsynch_t synch_base;
01058 } rtdm_mutex_t;
01059 
01060 void rtdm_mutex_init(rtdm_mutex_t *mutex);
01061 int rtdm_mutex_lock(rtdm_mutex_t *mutex);
01062 int rtdm_mutex_timedlock(rtdm_mutex_t *mutex, nanosecs_rel_t timeout,
01063                          rtdm_toseq_t *timeout_seq);
01064 
01065 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
01066 static inline void rtdm_mutex_unlock(rtdm_mutex_t *mutex)
01067 {
01068         XENO_ASSERT(RTDM, !xnpod_asynch_p(), return;);
01069 
01070         trace_mark(xn_rtdm_mutex_unlock, "mutex %p", mutex);
01071 
01072         if (unlikely(xnsynch_wakeup_one_sleeper(&mutex->synch_base) != NULL))
01073                 xnpod_schedule();
01074 }
01075 
01076 static inline void rtdm_mutex_destroy(rtdm_mutex_t *mutex)
01077 {
01078         trace_mark(xn_rtdm_mutex_destroy, "mutex %p", mutex);
01079 
01080         __rtdm_synch_flush(&mutex->synch_base, XNRMID);
01081 }
01082 #endif /* !DOXYGEN_CPP */
01083 
01084 /* --- utility functions --- */
01085 
01086 #define rtdm_printk(format, ...)        printk(format, ##__VA_ARGS__)
01087 
01088 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
01089 static inline void *rtdm_malloc(size_t size)
01090 {
01091         return xnmalloc(size);
01092 }
01093 
01094 static inline void rtdm_free(void *ptr)
01095 {
01096         xnfree(ptr);
01097 }
01098 
01099 #ifdef CONFIG_XENO_OPT_PERVASIVE
01100 int rtdm_mmap_to_user(rtdm_user_info_t *user_info,
01101                       void *src_addr, size_t len,
01102                       int prot, void **pptr,
01103                       struct vm_operations_struct *vm_ops,
01104                       void *vm_private_data);
01105 int rtdm_iomap_to_user(rtdm_user_info_t *user_info,
01106                        unsigned long src_addr, size_t len,
01107                        int prot, void **pptr,
01108                        struct vm_operations_struct *vm_ops,
01109                        void *vm_private_data);
01110 int rtdm_munmap(rtdm_user_info_t *user_info, void *ptr, size_t len);
01111 
01112 static inline int rtdm_read_user_ok(rtdm_user_info_t *user_info,
01113                                     const void __user *ptr, size_t size)
01114 {
01115         return __xn_access_ok(user_info, VERIFY_READ, ptr, size);
01116 }
01117 
01118 static inline int rtdm_rw_user_ok(rtdm_user_info_t *user_info,
01119                                   const void __user *ptr, size_t size)
01120 {
01121         return __xn_access_ok(user_info, VERIFY_WRITE, ptr, size);
01122 }
01123 
01124 static inline int rtdm_copy_from_user(rtdm_user_info_t *user_info,
01125                                       void *dst, const void __user *src,
01126                                       size_t size)
01127 {
01128         return __xn_copy_from_user(user_info, dst, src, size) ? -EFAULT : 0;
01129 }
01130 
01131 static inline int rtdm_safe_copy_from_user(rtdm_user_info_t *user_info,
01132                                            void *dst, const void __user *src,
01133                                            size_t size)
01134 {
01135         return (!__xn_access_ok(user_info, VERIFY_READ, src, size) ||
01136                 __xn_copy_from_user(user_info, dst, src, size)) ? -EFAULT : 0;
01137 }
01138 
01139 static inline int rtdm_copy_to_user(rtdm_user_info_t *user_info,
01140                                     void __user *dst, const void *src,
01141                                     size_t size)
01142 {
01143         return __xn_copy_to_user(user_info, dst, src, size) ? -EFAULT : 0;
01144 }
01145 
01146 static inline int rtdm_safe_copy_to_user(rtdm_user_info_t *user_info,
01147                                          void __user *dst, const void *src,
01148                                          size_t size)
01149 {
01150         return (!__xn_access_ok(user_info, VERIFY_WRITE, dst, size) ||
01151                 __xn_copy_to_user(user_info, dst, src, size)) ? -EFAULT : 0;
01152 }
01153 
01154 static inline int rtdm_strncpy_from_user(rtdm_user_info_t *user_info,
01155                                          char *dst,
01156                                          const char __user *src, size_t count)
01157 {
01158         if (unlikely(!__xn_access_ok(user_info, VERIFY_READ, src, 1)))
01159                 return -EFAULT;
01160         return __xn_strncpy_from_user(user_info, dst, src, count);
01161 }
01162 #else /* !CONFIG_XENO_OPT_PERVASIVE */
01163 /* Define void user<->kernel services that simply fail */
01164 #define rtdm_mmap_to_user(...)          ({ -ENOSYS; })
01165 #define rtdm_munmap(...)                ({ -ENOSYS; })
01166 #define rtdm_read_user_ok(...)          ({ 0; })
01167 #define rtdm_rw_user_ok(...)            ({ 0; })
01168 #define rtdm_copy_from_user(...)        ({ -ENOSYS; })
01169 #define rtdm_safe_copy_from_user(...)   ({ -ENOSYS; })
01170 #define rtdm_copy_to_user(...)          ({ -ENOSYS; })
01171 #define rtdm_safe_copy_to_user(...)     ({ -ENOSYS; })
01172 #define rtdm_strncpy_from_user(...)     ({ -ENOSYS; })
01173 #endif /* CONFIG_XENO_OPT_PERVASIVE */
01174 
01175 static inline int rtdm_in_rt_context(void)
01176 {
01177         return (rthal_current_domain != rthal_root_domain);
01178 }
01179 #endif /* !DOXYGEN_CPP */
01180 
01181 int rtdm_exec_in_rt(struct rtdm_dev_context *context,
01182                     rtdm_user_info_t *user_info, void *arg,
01183                     rtdm_rt_handler_t handler);
01184 
01185 #endif /* _RTDM_DRIVER_H */

Generated on Tue Jan 1 18:24:38 2008 for Xenomai API by  doxygen 1.5.3