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/core.h>
00039 #include <nucleus/heap.h>
00040 #include <nucleus/pod.h>
00041 #include <nucleus/synch.h>
00042 #include <nucleus/select.h>
00043 #include <rtdm/rtdm.h>
00044
00045
00046 #include <nucleus/assert.h>
00047
00048 #ifndef CONFIG_XENO_OPT_DEBUG_RTDM
00049 #define CONFIG_XENO_OPT_DEBUG_RTDM 0
00050 #endif
00051
00052 struct rtdm_dev_context;
00053 typedef struct xnselector rtdm_selector_t;
00054 enum rtdm_selecttype;
00055
00068 #define RTDM_EXCLUSIVE 0x0001
00069
00071 #define RTDM_NAMED_DEVICE 0x0010
00072
00075 #define RTDM_PROTOCOL_DEVICE 0x0020
00076
00078 #define RTDM_DEVICE_TYPE_MASK 0x00F0
00079
00088 #define RTDM_CREATED_IN_NRT 0
00089
00091 #define RTDM_CLOSING 1
00092
00094 #define RTDM_USER_CONTEXT_FLAG 8
00095
00104 #define RTDM_DEVICE_STRUCT_VER 5
00105
00107 #define RTDM_CONTEXT_STRUCT_VER 3
00108
00110 #define RTDM_SECURE_DEVICE 0x80000000
00111
00113 #define RTDM_DRIVER_VER(major, minor, patch) \
00114 (((major & 0xFF) << 16) | ((minor & 0xFF) << 8) | (patch & 0xFF))
00115
00117 #define RTDM_DRIVER_MAJOR_VER(ver) (((ver) >> 16) & 0xFF)
00118
00120 #define RTDM_DRIVER_MINOR_VER(ver) (((ver) >> 8) & 0xFF)
00121
00123 #define RTDM_DRIVER_PATCH_VER(ver) ((ver) & 0xFF)
00124
00136 enum rtdm_selecttype {
00138 RTDM_SELECTTYPE_READ = XNSELECT_READ,
00139
00141 RTDM_SELECTTYPE_WRITE = XNSELECT_WRITE,
00142
00144 RTDM_SELECTTYPE_EXCEPT = XNSELECT_EXCEPT
00145 };
00167 typedef int (*rtdm_open_handler_t)(struct rtdm_dev_context *context,
00168 rtdm_user_info_t *user_info, int oflag);
00169
00182 typedef int (*rtdm_socket_handler_t)(struct rtdm_dev_context *context,
00183 rtdm_user_info_t *user_info, int protocol);
00184
00196 typedef int (*rtdm_close_handler_t)(struct rtdm_dev_context *context,
00197 rtdm_user_info_t *user_info);
00198
00212 typedef int (*rtdm_ioctl_handler_t)(struct rtdm_dev_context *context,
00213 rtdm_user_info_t *user_info,
00214 unsigned int request, void __user *arg);
00215
00227 typedef int (*rtdm_select_bind_handler_t)(struct rtdm_dev_context *context,
00228 rtdm_selector_t *selector,
00229 enum rtdm_selecttype type,
00230 unsigned fd_index);
00231
00245 typedef ssize_t (*rtdm_read_handler_t)(struct rtdm_dev_context *context,
00246 rtdm_user_info_t *user_info,
00247 void *buf, size_t nbyte);
00248
00263 typedef ssize_t (*rtdm_write_handler_t)(struct rtdm_dev_context *context,
00264 rtdm_user_info_t *user_info,
00265 const void *buf, size_t nbyte);
00266
00282 typedef ssize_t (*rtdm_recvmsg_handler_t)(struct rtdm_dev_context *context,
00283 rtdm_user_info_t *user_info,
00284 struct msghdr *msg, int flags);
00285
00301 typedef ssize_t (*rtdm_sendmsg_handler_t)(struct rtdm_dev_context *context,
00302 rtdm_user_info_t *user_info,
00303 const struct msghdr *msg, int flags);
00306 typedef int (*rtdm_rt_handler_t)(struct rtdm_dev_context *context,
00307 rtdm_user_info_t *user_info, void *arg);
00311 struct rtdm_operations {
00315 rtdm_close_handler_t close_rt;
00317 rtdm_close_handler_t close_nrt;
00318
00320 rtdm_ioctl_handler_t ioctl_rt;
00322 rtdm_ioctl_handler_t ioctl_nrt;
00323
00325 rtdm_select_bind_handler_t select_bind;
00331 rtdm_read_handler_t read_rt;
00333 rtdm_read_handler_t read_nrt;
00334
00336 rtdm_write_handler_t write_rt;
00338 rtdm_write_handler_t write_nrt;
00344 rtdm_recvmsg_handler_t recvmsg_rt;
00346 rtdm_recvmsg_handler_t recvmsg_nrt;
00347
00349 rtdm_sendmsg_handler_t sendmsg_rt;
00351 rtdm_sendmsg_handler_t sendmsg_nrt;
00353 };
00354
00355 struct rtdm_devctx_reserved {
00356 void *owner;
00357 };
00358
00370 struct rtdm_dev_context {
00372 unsigned long context_flags;
00373
00375 int fd;
00376
00379 atomic_t close_lock_count;
00380
00382 struct rtdm_operations *ops;
00383
00385 struct rtdm_device *device;
00386
00388 struct rtdm_devctx_reserved reserved;
00389
00391 char dev_private[0];
00392 };
00393
00394 struct rtdm_dev_reserved {
00395 struct list_head entry;
00396 atomic_t refcount;
00397 struct rtdm_dev_context *exclusive_context;
00398 };
00399
00407 struct rtdm_device {
00410 int struct_version;
00411
00413 int device_flags;
00415 size_t context_size;
00416
00418 char device_name[RTDM_MAX_DEVNAME_LEN + 1];
00419
00421 int protocol_family;
00423 int socket_type;
00424
00427 rtdm_open_handler_t open_rt;
00430 rtdm_open_handler_t open_nrt;
00431
00434 rtdm_socket_handler_t socket_rt;
00437 rtdm_socket_handler_t socket_nrt;
00438
00440 struct rtdm_operations ops;
00441
00443 int device_class;
00446 int device_sub_class;
00448 int profile_version;
00450 const char *driver_name;
00452 int driver_version;
00455 const char *peripheral_name;
00457 const char *provider_name;
00458
00460 const char *proc_name;
00462 struct proc_dir_entry *proc_entry;
00463
00465 int device_id;
00467 void *device_data;
00468
00470 struct rtdm_dev_reserved reserved;
00471 };
00474
00475
00476 int rtdm_dev_register(struct rtdm_device *device);
00477 int rtdm_dev_unregister(struct rtdm_device *device, unsigned int poll_delay);
00478
00479
00480
00481 #define rtdm_open rt_dev_open
00482 #define rtdm_socket rt_dev_socket
00483 #define rtdm_close rt_dev_close
00484 #define rtdm_ioctl rt_dev_ioctl
00485 #define rtdm_read rt_dev_read
00486 #define rtdm_write rt_dev_write
00487 #define rtdm_recvmsg rt_dev_recvmsg
00488 #define rtdm_recv rt_dev_recv
00489 #define rtdm_recvfrom rt_dev_recvfrom
00490 #define rtdm_sendmsg rt_dev_sendmsg
00491 #define rtdm_send rt_dev_send
00492 #define rtdm_sendto rt_dev_sendto
00493 #define rtdm_bind rt_dev_bind
00494 #define rtdm_listen rt_dev_listen
00495 #define rtdm_accept rt_dev_accept
00496 #define rtdm_getsockopt rt_dev_getsockopt
00497 #define rtdm_setsockopt rt_dev_setsockopt
00498 #define rtdm_getsockname rt_dev_getsockname
00499 #define rtdm_getpeername rt_dev_getpeername
00500 #define rtdm_shutdown rt_dev_shutdown
00501
00502 struct rtdm_dev_context *rtdm_context_get(int fd);
00503
00504 #ifndef DOXYGEN_CPP
00505 static inline void rtdm_context_lock(struct rtdm_dev_context *context)
00506 {
00507 atomic_inc(&context->close_lock_count);
00508 }
00509
00510 static inline void rtdm_context_unlock(struct rtdm_dev_context *context)
00511 {
00512 atomic_dec(&context->close_lock_count);
00513 }
00514
00515
00516 struct xntbase;
00517 extern struct xntbase *rtdm_tbase;
00518
00519 static inline nanosecs_abs_t rtdm_clock_read(void)
00520 {
00521 return xntbase_ticks2ns(rtdm_tbase, xntbase_get_time(rtdm_tbase));
00522 }
00523
00524 static inline nanosecs_abs_t rtdm_clock_read_monotonic(void)
00525 {
00526 return xntbase_ticks2ns(rtdm_tbase, xntbase_get_jiffies(rtdm_tbase));
00527 }
00528 #endif
00529
00535 int rtdm_select_bind(int fd, rtdm_selector_t *selector,
00536 enum rtdm_selecttype type, unsigned fd_index);
00537
00538
00576 #ifdef DOXYGEN_CPP
00577 #define RTDM_EXECUTE_ATOMICALLY(code_block) \
00578 { \
00579 <ENTER_ATOMIC_SECTION> \
00580 code_block; \
00581 <LEAVE_ATOMIC_SECTION> \
00582 }
00583 #else
00584 #define RTDM_EXECUTE_ATOMICALLY(code_block) \
00585 { \
00586 spl_t s; \
00587 \
00588 xnlock_get_irqsave(&nklock, s); \
00589 code_block; \
00590 xnlock_put_irqrestore(&nklock, s); \
00591 }
00592 #endif
00593
00603 #define RTDM_LOCK_UNLOCKED RTHAL_SPIN_LOCK_UNLOCKED
00604
00606 typedef rthal_spinlock_t rtdm_lock_t;
00607
00609 typedef unsigned long rtdm_lockctx_t;
00610
00626 #define rtdm_lock_init(lock) rthal_spin_lock_init(lock)
00627
00644 #define rtdm_lock_get(lock) rthal_spin_lock(lock)
00645
00662 #define rtdm_lock_put(lock) rthal_spin_unlock(lock)
00663
00681 #define rtdm_lock_get_irqsave(lock, context) \
00682 rthal_spin_lock_irqsave(lock, context)
00683
00701 #define rtdm_lock_put_irqrestore(lock, context) \
00702 rthal_spin_unlock_irqrestore(lock, context)
00703
00720 #define rtdm_lock_irqsave(context) \
00721 rthal_local_irq_save(context)
00722
00739 #define rtdm_lock_irqrestore(context) \
00740 rthal_local_irq_restore(context)
00741
00745
00751 typedef xnintr_t rtdm_irq_t;
00752
00759 #define RTDM_IRQTYPE_SHARED XN_ISR_SHARED
00760
00762 #define RTDM_IRQTYPE_EDGE XN_ISR_EDGE
00763
00772 typedef int (*rtdm_irq_handler_t)(rtdm_irq_t *irq_handle);
00773
00780 #define RTDM_IRQ_NONE XN_ISR_NONE
00781
00782 #define RTDM_IRQ_HANDLED XN_ISR_HANDLED
00783
00802 #define rtdm_irq_get_arg(irq_handle, type) ((type *)irq_handle->cookie)
00803
00805 int rtdm_irq_request(rtdm_irq_t *irq_handle, unsigned int irq_no,
00806 rtdm_irq_handler_t handler, unsigned long flags,
00807 const char *device_name, void *arg);
00808
00809 #ifndef DOXYGEN_CPP
00810 static inline int rtdm_irq_free(rtdm_irq_t *irq_handle)
00811 {
00812 return xnintr_detach(irq_handle);
00813 }
00814
00815 static inline int rtdm_irq_enable(rtdm_irq_t *irq_handle)
00816 {
00817 return xnintr_enable(irq_handle);
00818 }
00819
00820 static inline int rtdm_irq_disable(rtdm_irq_t *irq_handle)
00821 {
00822 return xnintr_disable(irq_handle);
00823 }
00824 #endif
00825
00826
00827
00833 typedef unsigned rtdm_nrtsig_t;
00834
00845 typedef void (*rtdm_nrtsig_handler_t)(rtdm_nrtsig_t nrt_sig, void *arg);
00848 #ifndef DOXYGEN_CPP
00849 static inline int rtdm_nrtsig_init(rtdm_nrtsig_t *nrt_sig,
00850 rtdm_nrtsig_handler_t handler, void *arg)
00851 {
00852 *nrt_sig = rthal_alloc_virq();
00853
00854 if (*nrt_sig == 0)
00855 return -EAGAIN;
00856
00857 rthal_virtualize_irq(rthal_root_domain, *nrt_sig, handler, arg, NULL,
00858 IPIPE_HANDLE_MASK);
00859 return 0;
00860 }
00861
00862 static inline void rtdm_nrtsig_destroy(rtdm_nrtsig_t *nrt_sig)
00863 {
00864 rthal_free_virq(*nrt_sig);
00865 }
00866
00867 static inline void rtdm_nrtsig_pend(rtdm_nrtsig_t *nrt_sig)
00868 {
00869 rthal_trigger_irq(*nrt_sig);
00870 }
00871 #endif
00872
00873
00874
00880 typedef xntimer_t rtdm_timer_t;
00881
00887 typedef void (*rtdm_timer_handler_t)(rtdm_timer_t *timer);
00888
00894 enum rtdm_timer_mode {
00896 RTDM_TIMERMODE_RELATIVE = XN_RELATIVE,
00897
00899 RTDM_TIMERMODE_ABSOLUTE = XN_ABSOLUTE,
00900
00902 RTDM_TIMERMODE_REALTIME = XN_REALTIME
00903 };
00908 #ifndef DOXYGEN_CPP
00909 #define rtdm_timer_init(timer, handler, name) \
00910 ({ \
00911 xntimer_init((timer), rtdm_tbase, handler); \
00912 xntimer_set_name((timer), (name)); \
00913 0; \
00914 })
00915 #endif
00916
00917 void rtdm_timer_destroy(rtdm_timer_t *timer);
00918
00919 int rtdm_timer_start(rtdm_timer_t *timer, nanosecs_abs_t expiry,
00920 nanosecs_rel_t interval, enum rtdm_timer_mode mode);
00921
00922 void rtdm_timer_stop(rtdm_timer_t *timer);
00923
00924 #ifndef DOXYGEN_CPP
00925 static inline int rtdm_timer_start_in_handler(rtdm_timer_t *timer,
00926 nanosecs_abs_t expiry,
00927 nanosecs_rel_t interval,
00928 enum rtdm_timer_mode mode)
00929 {
00930 return xntimer_start(timer, xntbase_ns2ticks_ceil(rtdm_tbase, expiry),
00931 xntbase_ns2ticks_ceil(rtdm_tbase, interval),
00932 (xntmode_t)mode);
00933 }
00934
00935 static inline void rtdm_timer_stop_in_handler(rtdm_timer_t *timer)
00936 {
00937 xntimer_stop(timer);
00938 }
00939 #endif
00940
00941
00947 typedef xnthread_t rtdm_task_t;
00948
00954 typedef void (*rtdm_task_proc_t)(void *arg);
00955
00960 #define RTDM_TASK_LOWEST_PRIORITY XNCORE_LOW_PRIO
00961 #define RTDM_TASK_HIGHEST_PRIORITY XNCORE_HIGH_PRIO
00962
00968 #define RTDM_TASK_RAISE_PRIORITY (+1)
00969 #define RTDM_TASK_LOWER_PRIORITY (-1)
00970
00974 int rtdm_task_init(rtdm_task_t *task, const char *name,
00975 rtdm_task_proc_t task_proc, void *arg,
00976 int priority, nanosecs_rel_t period);
00977 int __rtdm_task_sleep(xnticks_t timeout, xntmode_t mode);
00978 void rtdm_task_busy_sleep(nanosecs_rel_t delay);
00979
00980 #ifndef DOXYGEN_CPP
00981 static inline void rtdm_task_destroy(rtdm_task_t *task)
00982 {
00983 xnpod_delete_thread(task);
00984 }
00985
00986 void rtdm_task_join_nrt(rtdm_task_t *task, unsigned int poll_delay);
00987
00988 static inline void rtdm_task_set_priority(rtdm_task_t *task, int priority)
00989 {
00990 xnpod_renice_thread(task, priority);
00991 xnpod_schedule();
00992 }
00993
00994 static inline int rtdm_task_set_period(rtdm_task_t *task,
00995 nanosecs_rel_t period)
00996 {
00997 if (period < 0)
00998 period = 0;
00999 return xnpod_set_thread_periodic(task, XN_INFINITE,
01000 xntbase_ns2ticks_ceil
01001 (xnthread_time_base(task), period));
01002 }
01003
01004 static inline int rtdm_task_unblock(rtdm_task_t *task)
01005 {
01006 int res = xnpod_unblock_thread(task);
01007
01008 xnpod_schedule();
01009 return res;
01010 }
01011
01012 static inline rtdm_task_t *rtdm_task_current(void)
01013 {
01014 return xnpod_current_thread();
01015 }
01016
01017 static inline int rtdm_task_wait_period(void)
01018 {
01019 XENO_ASSERT(RTDM, !xnpod_unblockable_p(), return -EPERM;);
01020 return xnpod_wait_thread_period(NULL);
01021 }
01022
01023 static inline int rtdm_task_sleep(nanosecs_rel_t delay)
01024 {
01025 return __rtdm_task_sleep(delay, XN_RELATIVE);
01026 }
01027
01028 static inline int
01029 rtdm_task_sleep_abs(nanosecs_abs_t wakeup_date, enum rtdm_timer_mode mode)
01030 {
01031
01032 if (mode != RTDM_TIMERMODE_ABSOLUTE && mode != RTDM_TIMERMODE_REALTIME)
01033 return -EINVAL;
01034 return __rtdm_task_sleep(wakeup_date, (xntmode_t)mode);
01035 }
01036
01037
01038 static inline int __deprecated rtdm_task_sleep_until(nanosecs_abs_t wakeup_time)
01039 {
01040 return __rtdm_task_sleep(wakeup_time, XN_REALTIME);
01041 }
01042 #endif
01043
01044
01045
01046 typedef nanosecs_abs_t rtdm_toseq_t;
01047
01048 void rtdm_toseq_init(rtdm_toseq_t *timeout_seq, nanosecs_rel_t timeout);
01049
01050
01051
01052 typedef struct {
01053 xnsynch_t synch_base;
01054 DECLARE_XNSELECT(select_block);
01055 } rtdm_event_t;
01056
01057 #define RTDM_EVENT_PENDING XNSYNCH_SPARE1
01058
01059 void rtdm_event_init(rtdm_event_t *event, unsigned long pending);
01060 #ifdef CONFIG_XENO_OPT_RTDM_SELECT
01061 int rtdm_event_select_bind(rtdm_event_t *event, rtdm_selector_t *selector,
01062 enum rtdm_selecttype type, unsigned fd_index);
01063 #else
01064 #define rtdm_event_select_bind(e, s, t, i) ({ -EBADF; })
01065 #endif
01066 int rtdm_event_wait(rtdm_event_t *event);
01067 int rtdm_event_timedwait(rtdm_event_t *event, nanosecs_rel_t timeout,
01068 rtdm_toseq_t *timeout_seq);
01069 void rtdm_event_signal(rtdm_event_t *event);
01070
01071 void rtdm_event_clear(rtdm_event_t *event);
01072
01073 #ifndef DOXYGEN_CPP
01074 void __rtdm_synch_flush(xnsynch_t *synch, unsigned long reason);
01075
01076 static inline void rtdm_event_pulse(rtdm_event_t *event)
01077 {
01078 trace_mark(xn_rtdm, event_pulse, "event %p", event);
01079 __rtdm_synch_flush(&event->synch_base, 0);
01080 }
01081
01082 static inline void rtdm_event_destroy(rtdm_event_t *event)
01083 {
01084 trace_mark(xn_rtdm, event_destroy, "event %p", event);
01085 __rtdm_synch_flush(&event->synch_base, XNRMID);
01086 xnselect_destroy(&event->select_block);
01087 }
01088 #endif
01089
01090
01091
01092 typedef struct {
01093 unsigned long value;
01094 xnsynch_t synch_base;
01095 DECLARE_XNSELECT(select_block);
01096 } rtdm_sem_t;
01097
01098 void rtdm_sem_init(rtdm_sem_t *sem, unsigned long value);
01099 #ifdef CONFIG_XENO_OPT_RTDM_SELECT
01100 int rtdm_sem_select_bind(rtdm_sem_t *sem, rtdm_selector_t *selector,
01101 enum rtdm_selecttype type, unsigned fd_index);
01102 #else
01103 #define rtdm_sem_select_bind(s, se, t, i) ({ -EBADF; })
01104 #endif
01105 int rtdm_sem_down(rtdm_sem_t *sem);
01106 int rtdm_sem_timeddown(rtdm_sem_t *sem, nanosecs_rel_t timeout,
01107 rtdm_toseq_t *timeout_seq);
01108 void rtdm_sem_up(rtdm_sem_t *sem);
01109
01110 #ifndef DOXYGEN_CPP
01111 static inline void rtdm_sem_destroy(rtdm_sem_t *sem)
01112 {
01113 trace_mark(xn_rtdm, sem_destroy, "sem %p", sem);
01114 __rtdm_synch_flush(&sem->synch_base, XNRMID);
01115 xnselect_destroy(&sem->select_block);
01116 }
01117 #endif
01118
01119
01120
01121 typedef struct {
01122 xnsynch_t synch_base;
01123 } rtdm_mutex_t;
01124
01125 void rtdm_mutex_init(rtdm_mutex_t *mutex);
01126 int rtdm_mutex_lock(rtdm_mutex_t *mutex);
01127 int rtdm_mutex_timedlock(rtdm_mutex_t *mutex, nanosecs_rel_t timeout,
01128 rtdm_toseq_t *timeout_seq);
01129
01130 #ifndef DOXYGEN_CPP
01131 static inline void rtdm_mutex_unlock(rtdm_mutex_t *mutex)
01132 {
01133 XENO_ASSERT(RTDM, !xnpod_asynch_p(), return;);
01134
01135 trace_mark(xn_rtdm, mutex_unlock, "mutex %p", mutex);
01136
01137 if (unlikely(xnsynch_wakeup_one_sleeper(&mutex->synch_base) != NULL))
01138 xnpod_schedule();
01139 }
01140
01141 static inline void rtdm_mutex_destroy(rtdm_mutex_t *mutex)
01142 {
01143 trace_mark(xn_rtdm, mutex_destroy, "mutex %p", mutex);
01144
01145 __rtdm_synch_flush(&mutex->synch_base, XNRMID);
01146 }
01147 #endif
01148
01149
01150
01151 #define rtdm_printk(format, ...) printk(format, ##__VA_ARGS__)
01152
01153 #ifndef DOXYGEN_CPP
01154 static inline void *rtdm_malloc(size_t size)
01155 {
01156 return xnmalloc(size);
01157 }
01158
01159 static inline void rtdm_free(void *ptr)
01160 {
01161 xnfree(ptr);
01162 }
01163
01164 #ifdef CONFIG_XENO_OPT_PERVASIVE
01165 int rtdm_mmap_to_user(rtdm_user_info_t *user_info,
01166 void *src_addr, size_t len,
01167 int prot, void **pptr,
01168 struct vm_operations_struct *vm_ops,
01169 void *vm_private_data);
01170 int rtdm_iomap_to_user(rtdm_user_info_t *user_info,
01171 unsigned long src_addr, size_t len,
01172 int prot, void **pptr,
01173 struct vm_operations_struct *vm_ops,
01174 void *vm_private_data);
01175 int rtdm_munmap(rtdm_user_info_t *user_info, void *ptr, size_t len);
01176
01177 static inline int rtdm_read_user_ok(rtdm_user_info_t *user_info,
01178 const void __user *ptr, size_t size)
01179 {
01180 return __xn_access_ok(user_info, VERIFY_READ, ptr, size);
01181 }
01182
01183 static inline int rtdm_rw_user_ok(rtdm_user_info_t *user_info,
01184 const void __user *ptr, size_t size)
01185 {
01186 return __xn_access_ok(user_info, VERIFY_WRITE, ptr, size);
01187 }
01188
01189 static inline int rtdm_copy_from_user(rtdm_user_info_t *user_info,
01190 void *dst, const void __user *src,
01191 size_t size)
01192 {
01193 return __xn_copy_from_user(user_info, dst, src, size) ? -EFAULT : 0;
01194 }
01195
01196 static inline int rtdm_safe_copy_from_user(rtdm_user_info_t *user_info,
01197 void *dst, const void __user *src,
01198 size_t size)
01199 {
01200 return (!__xn_access_ok(user_info, VERIFY_READ, src, size) ||
01201 __xn_copy_from_user(user_info, dst, src, size)) ? -EFAULT : 0;
01202 }
01203
01204 static inline int rtdm_copy_to_user(rtdm_user_info_t *user_info,
01205 void __user *dst, const void *src,
01206 size_t size)
01207 {
01208 return __xn_copy_to_user(user_info, dst, src, size) ? -EFAULT : 0;
01209 }
01210
01211 static inline int rtdm_safe_copy_to_user(rtdm_user_info_t *user_info,
01212 void __user *dst, const void *src,
01213 size_t size)
01214 {
01215 return (!__xn_access_ok(user_info, VERIFY_WRITE, dst, size) ||
01216 __xn_copy_to_user(user_info, dst, src, size)) ? -EFAULT : 0;
01217 }
01218
01219 static inline int rtdm_strncpy_from_user(rtdm_user_info_t *user_info,
01220 char *dst,
01221 const char __user *src, size_t count)
01222 {
01223 if (unlikely(!__xn_access_ok(user_info, VERIFY_READ, src, 1)))
01224 return -EFAULT;
01225 return __xn_strncpy_from_user(user_info, dst, src, count);
01226 }
01227 #else
01228
01229 #define rtdm_mmap_to_user(...) ({ -ENOSYS; })
01230 #define rtdm_munmap(...) ({ -ENOSYS; })
01231 #define rtdm_read_user_ok(...) ({ 0; })
01232 #define rtdm_rw_user_ok(...) ({ 0; })
01233 #define rtdm_copy_from_user(...) ({ -ENOSYS; })
01234 #define rtdm_safe_copy_from_user(...) ({ -ENOSYS; })
01235 #define rtdm_copy_to_user(...) ({ -ENOSYS; })
01236 #define rtdm_safe_copy_to_user(...) ({ -ENOSYS; })
01237 #define rtdm_strncpy_from_user(...) ({ -ENOSYS; })
01238 #endif
01239
01240 static inline int rtdm_in_rt_context(void)
01241 {
01242 return (rthal_current_domain != rthal_root_domain);
01243 }
01244 #endif
01245
01246 int rtdm_exec_in_rt(struct rtdm_dev_context *context,
01247 rtdm_user_info_t *user_info, void *arg,
01248 rtdm_rt_handler_t handler);
01249
01250 #endif