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