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
00032
00033 #include <asm/atomic.h>
00034 #include <linux/list.h>
00035
00036 #include <nucleus/fusion.h>
00037 #include <nucleus/heap.h>
00038 #include <nucleus/pod.h>
00039 #include <nucleus/synch.h>
00040 #include <rtdm/rtdm.h>
00041
00042
00043 struct rtdm_dev_context;
00044
00045
00054 #define RTDM_EXCLUSIVE 0x0001
00055
00057 #define RTDM_NAMED_DEVICE 0x0010
00058
00061 #define RTDM_PROTOCOL_DEVICE 0x0020
00062
00064 #define RTDM_DEVICE_TYPE_MASK 0x00F0
00065
00075 #define RTDM_CREATED_IN_NRT 0
00076
00078 #define RTDM_CLOSING 1
00079
00082 #define RTDM_FORCED_CLOSING 2
00083
00085 #define RTDM_USER_CONTEXT_FLAG 8
00086
00097 #define RTDM_DEVICE_STRUCT_VER 3
00098
00100 #define RTDM_CONTEXT_STRUCT_VER 3
00101
00103 #define RTDM_API_VER 3
00104
00106 #define RTDM_API_MIN_COMPAT_VER 3
00107
00109 #define RTDM_SECURE_DEVICE 0x80000000
00110
00112 #define RTDM_DRIVER_VER(major, minor, patch) \
00113 (((major & 0xFF) << 16) | ((minor & 0xFF) << 8) | (patch & 0xFF))
00114
00116 #define RTDM_DRIVER_MAJOR_VER(ver) (((ver) >> 16) & 0xFF)
00117
00119 #define RTDM_DRIVER_MINOR_VER(ver) (((ver) >> 8) & 0xFF)
00120
00122 #define RTDM_DRIVER_PATCH_VER(ver) ((ver) & 0xFF)
00123
00144 typedef
00145 int (*rtdm_open_handler_t) (struct rtdm_dev_context *context,
00146 rtdm_user_info_t *user_info,
00147 int oflag);
00148
00161 typedef
00162 int (*rtdm_socket_handler_t) (struct rtdm_dev_context *context,
00163 rtdm_user_info_t *user_info,
00164 int protocol);
00165
00177 typedef
00178 int (*rtdm_close_handler_t) (struct rtdm_dev_context *context,
00179 rtdm_user_info_t *user_info);
00180
00194 typedef
00195 int (*rtdm_ioctl_handler_t) (struct rtdm_dev_context *context,
00196 rtdm_user_info_t *user_info,
00197 int request,
00198 void *arg);
00199
00213 typedef
00214 ssize_t (*rtdm_read_handler_t) (struct rtdm_dev_context *context,
00215 rtdm_user_info_t *user_info,
00216 void *buf,
00217 size_t nbyte);
00218
00233 typedef
00234 ssize_t (*rtdm_write_handler_t) (struct rtdm_dev_context *context,
00235 rtdm_user_info_t *user_info,
00236 const void *buf,
00237 size_t nbyte);
00238
00254 typedef
00255 ssize_t (*rtdm_recvmsg_handler_t)(struct rtdm_dev_context *context,
00256 rtdm_user_info_t *user_info,
00257 struct msghdr *msg,
00258 int flags);
00259
00275 typedef
00276 ssize_t (*rtdm_sendmsg_handler_t)(struct rtdm_dev_context *context,
00277 rtdm_user_info_t *user_info,
00278 const struct msghdr *msg,
00279 int flags);
00282 typedef
00283 int (*rtdm_rt_handler_t) (struct rtdm_dev_context *context,
00284 rtdm_user_info_t *user_info,
00285 void *arg);
00286
00287
00292 struct rtdm_operations {
00297 rtdm_close_handler_t close_rt;
00300 rtdm_close_handler_t close_nrt;
00302 rtdm_ioctl_handler_t ioctl_rt;
00304 rtdm_ioctl_handler_t ioctl_nrt;
00310 rtdm_read_handler_t read_rt;
00312 rtdm_read_handler_t read_nrt;
00314 rtdm_write_handler_t write_rt;
00316 rtdm_write_handler_t write_nrt;
00322 rtdm_recvmsg_handler_t recvmsg_rt;
00324 rtdm_recvmsg_handler_t recvmsg_nrt;
00326 rtdm_sendmsg_handler_t sendmsg_rt;
00328 rtdm_sendmsg_handler_t sendmsg_nrt;
00330 };
00331
00343 struct rtdm_dev_context {
00345 unsigned long context_flags;
00347 int fd;
00350 atomic_t close_lock_count;
00352 struct rtdm_operations *ops;
00354 volatile struct rtdm_device *device;
00356 char dev_private[0];
00357 };
00358
00359 struct rtdm_dev_reserved {
00360 struct list_head entry;
00361 atomic_t refcount;
00362 struct rtdm_dev_context *exclusive_context;
00363 };
00364
00373 struct rtdm_device {
00376 int struct_version;
00377
00379 int device_flags;
00381 size_t context_size;
00382
00384 char device_name[RTDM_MAX_DEVNAME_LEN+1];
00385
00387 int protocol_family;
00389 int socket_type;
00390
00393 rtdm_open_handler_t open_rt;
00396 rtdm_open_handler_t open_nrt;
00397
00400 rtdm_socket_handler_t socket_rt;
00403 rtdm_socket_handler_t socket_nrt;
00404
00406 struct rtdm_operations ops;
00407
00409 int device_class;
00412 int device_sub_class;
00414 const char *driver_name;
00416 int driver_version;
00419 const char *peripheral_name;
00421 const char *provider_name;
00422
00424 const char *proc_name;
00426 struct proc_dir_entry *proc_entry;
00427
00429 int device_id;
00430
00432 struct rtdm_dev_reserved reserved;
00433 };
00434
00435
00436
00437
00438 int rtdm_dev_register(struct rtdm_device* device);
00439 int rtdm_dev_unregister(struct rtdm_device* device, unsigned int poll_delay);
00440
00441
00442
00443
00444 #define rtdm_open rt_dev_open
00445 #define rtdm_socket rt_dev_socket
00446 #define rtdm_close rt_dev_close
00447 #define rtdm_ioctl rt_dev_ioctl
00448 #define rtdm_read rt_dev_read
00449 #define rtdm_write rt_dev_write
00450 #define rtdm_rescmsg rt_dev_recvmsg
00451 #define rtdm_recv rt_dev_recv
00452 #define rtdm_recvfrom rt_dev_recvfrom
00453 #define rtdm_sendmsg rt_dev_sendmsg
00454 #define rtdm_send rt_dev_send
00455 #define rtdm_sendto rt_dev_sendto
00456 #define rtdm_bind rt_dev_bind
00457 #define rtdm_listen rt_dev_listen
00458 #define rtdm_accept rt_dev_accept
00459 #define rtdm_getsockopt rt_dev_getsockopt
00460 #define rtdm_setsockopt rt_dev_setsockopt
00461 #define rtdm_getsockname rt_dev_getsockname
00462 #define rtdm_getpeername rt_dev_getpeername
00463 #define rtdm_shutdown rt_dev_shutdown
00464
00465 struct rtdm_dev_context *rtdm_context_get(int fd);
00466
00467 static inline void rtdm_context_lock(struct rtdm_dev_context *context)
00468 {
00469 atomic_inc(&context->close_lock_count);
00470 }
00471
00472 static inline void rtdm_context_unlock(struct rtdm_dev_context *context)
00473 {
00474 atomic_dec(&context->close_lock_count);
00475 }
00476
00477
00478
00479 static inline __u64 rtdm_clock_read(void)
00480 {
00481 return xnpod_ticks2ns(xnpod_get_time());
00482 }
00483
00484
00485
00526 #define RTDM_EXECUTE_ATOMICALLY(code_block) \
00527 { \
00528 spl_t s; \
00529 \
00530 xnlock_get_irqsave(&nklock, s); \
00531 code_block; \
00532 xnlock_put_irqrestore(&nklock, s); \
00533 }
00534
00544 #define RTDM_LOCK_UNLOCKED SPIN_LOCK_UNLOCKED
00545
00547 typedef spinlock_t rtdm_lock_t;
00548
00550 typedef unsigned long rtdm_lockctx_t;
00551
00567 #define rtdm_lock_init(lock) spin_lock_init(lock)
00568
00585 #define rtdm_lock_get(lock) rthal_spin_lock(lock)
00586
00603 #define rtdm_lock_put(lock) rthal_spin_unlock(lock)
00604
00622 #define rtdm_lock_get_irqsave(lock, context) \
00623 rthal_spin_lock_irqsave(lock, context)
00624
00642 #define rtdm_lock_put_irqrestore(lock, context) \
00643 rthal_spin_unlock_irqrestore(lock, context)
00644
00661 #define rtdm_lock_irqsave(context) \
00662 rthal_local_irq_save(context)
00663
00680 #define rtdm_lock_irqrestore(context) \
00681 rthal_local_irq_restore(context)
00682
00687
00693 typedef xnintr_t rtdm_irq_t;
00694
00702 typedef int (*rtdm_irq_handler_t)(rtdm_irq_t *irq_handle);
00703
00704
00711 #define RTDM_IRQ_PROPAGATE XN_ISR_CHAINED
00712
00713 #define RTDM_IRQ_ENABLE XN_ISR_ENABLE
00714
00733 #define rtdm_irq_get_arg(irq_handle, type) ((type *)irq_handle->cookie)
00734
00736 static inline int rtdm_irq_request(rtdm_irq_t *irq_handle,
00737 unsigned int irq_no,
00738 rtdm_irq_handler_t handler,
00739 unsigned long flags,
00740 const char *device_name,
00741 void *arg)
00742 {
00743 xnintr_init(irq_handle, irq_no, handler, NULL, flags);
00744 return xnintr_attach(irq_handle, arg);
00745 }
00746
00747 static inline int rtdm_irq_free(rtdm_irq_t *irq_handle)
00748 {
00749 return xnintr_detach(irq_handle);
00750 }
00751
00752 static inline int rtdm_irq_enable(rtdm_irq_t *irq_handle)
00753 {
00754 return xnintr_enable(irq_handle);
00755 }
00756
00757 static inline int rtdm_irq_disable(rtdm_irq_t *irq_handle)
00758 {
00759 return xnintr_disable(irq_handle);
00760 }
00761
00762
00763
00764
00770 typedef unsigned rtdm_nrtsig_t;
00771
00781 typedef void (*rtdm_nrtsig_handler_t)(rtdm_nrtsig_t nrt_sig);
00785 static inline int rtdm_nrtsig_init(rtdm_nrtsig_t *nrt_sig,
00786 rtdm_nrtsig_handler_t handler)
00787 {
00788 *nrt_sig = rthal_alloc_virq();
00789
00790 if (*nrt_sig == 0)
00791 return -EAGAIN;
00792
00793 rthal_virtualize_irq(rthal_root_domain, *nrt_sig, handler, NULL,
00794 IPIPE_HANDLE_MASK);
00795 return 0;
00796 }
00797
00798 static inline void rtdm_nrtsig_destroy(rtdm_nrtsig_t *nrt_sig)
00799 {
00800 rthal_free_virq(*nrt_sig);
00801 }
00802
00803 static inline void rtdm_nrtsig_pend(rtdm_nrtsig_t *nrt_sig)
00804 {
00805 rthal_trigger_irq(*nrt_sig);
00806 }
00807
00808
00809
00815 typedef xnthread_t rtdm_task_t;
00816
00822 typedef void (*rtdm_task_proc_t)(void *arg);
00823
00824
00829 #define RTDM_TASK_LOWEST_PRIORITY FUSION_LOW_PRIO
00830 #define RTDM_TASK_HIGHEST_PRIORITY FUSION_HIGH_PRIO
00831
00835 static inline int rtdm_task_init(rtdm_task_t *task, const char *name,
00836 rtdm_task_proc_t task_proc, void *arg,
00837 int priority, __u64 period)
00838 {
00839 int res;
00840
00841 res = xnpod_init_thread(task, name, priority, 0, 0);
00842 if (res)
00843 goto done;
00844
00845 if (!__builtin_constant_p(period) || (period != XN_INFINITE)) {
00846 res = xnpod_set_thread_periodic(task, XN_INFINITE,
00847 xnpod_ns2ticks(period));
00848 if (res)
00849 goto done;
00850 }
00851
00852 res = xnpod_start_thread(task, 0, 0, XNPOD_ALL_CPUS, task_proc, arg);
00853
00854 done:
00855 return res;
00856 }
00857
00858 static inline void rtdm_task_destroy(rtdm_task_t *task)
00859 {
00860 xnpod_delete_thread(task);
00861 }
00862
00863 void rtdm_task_join_nrt(rtdm_task_t *task, unsigned int poll_delay);
00864
00865 static inline void rtdm_task_set_priority(rtdm_task_t *task, int priority)
00866 {
00867 xnpod_renice_thread(task, priority);
00868 xnpod_schedule();
00869 }
00870
00871 static inline int rtdm_task_set_period(rtdm_task_t *task, __u64 period)
00872 {
00873 return xnpod_set_thread_periodic(task, XN_INFINITE,
00874 xnpod_ns2ticks(period));
00875 }
00876
00877 static inline int rtdm_task_unblock(rtdm_task_t *task)
00878 {
00879 int res = xnpod_unblock_thread(task);
00880
00881 xnpod_schedule();
00882 return res;
00883 }
00884
00885 static inline rtdm_task_t *rtdm_task_current(void)
00886 {
00887 return xnpod_current_thread();
00888 }
00889
00890 static inline int rtdm_task_wait_period(void)
00891 {
00892 return xnpod_wait_thread_period();
00893 }
00894
00895 int rtdm_task_sleep(__u64 delay);
00896 int rtdm_task_sleep_until(__u64 wakeup_time);
00897 void rtdm_task_busy_sleep(__u64 delay);
00898
00899
00900
00901
00902 typedef __u64 rtdm_toseq_t;
00903
00904 static inline void rtdm_toseq_init(rtdm_toseq_t *timeout_seq, __s64 timeout)
00905 {
00906 *timeout_seq = xnpod_get_time() + xnpod_ns2ticks(timeout);
00907 }
00908
00909
00910
00911
00912 typedef struct {
00913 unsigned long pending;
00914 xnsynch_t synch_base;
00915 } rtdm_event_t;
00916
00917 static inline void rtdm_event_init(rtdm_event_t *event, unsigned long pending)
00918 {
00919 event->pending = pending;
00920 xnsynch_init(&event->synch_base, XNSYNCH_PRIO);
00921 }
00922
00923 void _rtdm_synch_flush(xnsynch_t *synch, unsigned long reason);
00924
00925 static inline void rtdm_event_destroy(rtdm_event_t *event)
00926 {
00927 _rtdm_synch_flush(&event->synch_base, XNRMID);
00928 }
00929
00930 int rtdm_event_wait(rtdm_event_t *event);
00931 int rtdm_event_timedwait(rtdm_event_t *event, __s64 timeout,
00932 rtdm_toseq_t *timeout_seq);
00933 void rtdm_event_signal(rtdm_event_t *event);
00934
00935 static inline void rtdm_event_pulse(rtdm_event_t *event)
00936 {
00937 _rtdm_synch_flush(&event->synch_base, 0);
00938 }
00939
00940 static inline void rtdm_event_clear(rtdm_event_t *event)
00941 {
00942 event->pending = 0;
00943 }
00944
00945
00946
00947
00948 typedef struct {
00949 unsigned long value;
00950 xnsynch_t synch_base;
00951 } rtdm_sem_t;
00952
00953 static inline void rtdm_sem_init(rtdm_sem_t *sem, unsigned long value)
00954 {
00955 sem->value = value;
00956 xnsynch_init(&sem->synch_base, XNSYNCH_PRIO);
00957 }
00958
00959 static inline void rtdm_sem_destroy(rtdm_sem_t *sem)
00960 {
00961 _rtdm_synch_flush(&sem->synch_base, XNRMID);
00962 }
00963
00964 int rtdm_sem_down(rtdm_sem_t *sem);
00965 int rtdm_sem_timeddown(rtdm_sem_t *sem, __s64 timeout,
00966 rtdm_toseq_t *timeout_seq);
00967 void rtdm_sem_up(rtdm_sem_t *sem);
00968
00969
00970
00971
00972 typedef struct {
00973 unsigned long locked;
00974 xnsynch_t synch_base;
00975 } rtdm_mutex_t;
00976
00977 static inline void rtdm_mutex_init(rtdm_mutex_t *mutex)
00978 {
00979 mutex->locked = 0;
00980 xnsynch_init(&mutex->synch_base, XNSYNCH_PRIO|XNSYNCH_PIP);
00981 }
00982
00983 static inline void rtdm_mutex_destroy(rtdm_mutex_t *mutex)
00984 {
00985 _rtdm_synch_flush(&mutex->synch_base, XNRMID);
00986 }
00987
00988 int rtdm_mutex_lock(rtdm_mutex_t *mutex);
00989 int rtdm_mutex_timedlock(rtdm_mutex_t *mutex, __s64 timeout,
00990 rtdm_toseq_t *timeout_seq);
00991 void rtdm_mutex_unlock(rtdm_mutex_t *mutex);
00992
00993
00994
00995
00996 #define rtdm_printk(format, ...) printk(format, ##__VA_ARGS__)
00997
00998 static inline void *rtdm_malloc(size_t size)
00999 {
01000 return xnmalloc(size);
01001 }
01002
01003 static inline void rtdm_free(void *ptr)
01004 {
01005 xnfree(ptr);
01006 }
01007
01008 static inline int rtdm_read_user_ok(rtdm_user_info_t *user_info,
01009 const void __user *ptr, size_t size)
01010 {
01011 return __xn_access_ok(user_info, VERIFY_READ, ptr, size);
01012 }
01013
01014 static inline int rtdm_rw_user_ok(rtdm_user_info_t *user_info,
01015 const void __user *ptr, size_t size)
01016 {
01017 return __xn_access_ok(user_info, VERIFY_WRITE, ptr, size);
01018 }
01019
01020 static inline int rtdm_copy_from_user(rtdm_user_info_t *user_info,
01021 void *dst, const void __user *src,
01022 size_t size)
01023 {
01024 return __xn_copy_from_user(user_info, dst, src, size);
01025 }
01026
01027 static inline int rtdm_copy_to_user(rtdm_user_info_t *user_info,
01028 void __user *dst, const void *src,
01029 size_t size)
01030 {
01031 return __xn_copy_to_user(user_info, dst, src, size);
01032 }
01033
01034 static inline int rtdm_strncpy_from_user(rtdm_user_info_t *user_info,
01035 char *dst,
01036 const char __user *src,
01037 size_t count)
01038 {
01039 if (unlikely(__xn_access_ok(user_info, VERIFY_READ, src, 1)))
01040 return -EFAULT;
01041 return __xn_strncpy_from_user(user_info, dst, src, count);
01042 }
01043
01044 static inline int rtdm_in_rt_context(void)
01045 {
01046 return (rthal_current_domain != rthal_root_domain);
01047 }
01048
01049 int rtdm_exec_in_rt(struct rtdm_dev_context *context,
01050 rtdm_user_info_t *user_info, void *arg,
01051 rtdm_rt_handler_t handler);
01052
01053 #endif