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/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   /* first user-definable flag */
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 /* --- device registration --- */
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 /* --- inter-driver API --- */
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 /* --- clock services --- */
00479 static inline __u64 rtdm_clock_read(void)
00480 {
00481     return xnpod_ticks2ns(xnpod_get_time());
00482 }
00483 
00484 
00485 /* --- spin lock services --- */
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 /* --- Interrupt management services --- */
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 /* --- non-real-time signalling services --- */
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 /* --- task and timing services --- */
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 /* --- timeout sequences */
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 /* --- event services --- */
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 /* --- semaphore services --- */
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 /* --- mutex services --- */
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 /* --- utility functions --- */
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 /* _RTDM_DRIVER_H */

Generated on Sat Sep 3 12:32:47 2005 for RTAI Fusion API by  doxygen 1.4.2