Xenomai  3.2.4
driver.h
Go to the documentation of this file.
1 
26 #ifndef _COBALT_RTDM_DRIVER_H
27 #define _COBALT_RTDM_DRIVER_H
28 
29 #include <asm/atomic.h>
30 #include <linux/cpumask.h>
31 #include <linux/list.h>
32 #include <linux/module.h>
33 #include <linux/cdev.h>
34 #include <linux/wait.h>
35 #include <linux/notifier.h>
36 #include <pipeline/lock.h>
37 #include <pipeline/inband_work.h>
38 #include <xenomai/version.h>
39 #include <cobalt/kernel/heap.h>
40 #include <cobalt/kernel/sched.h>
41 #include <cobalt/kernel/intr.h>
42 #include <cobalt/kernel/synch.h>
43 #include <cobalt/kernel/select.h>
44 #include <cobalt/kernel/clock.h>
45 #include <cobalt/kernel/init.h>
46 #include <cobalt/kernel/ancillaries.h>
47 #include <cobalt/kernel/tree.h>
48 #include <rtdm/fd.h>
49 #include <rtdm/rtdm.h>
50 
51 /* debug support */
52 #include <cobalt/kernel/assert.h>
53 #include <trace/events/cobalt-rtdm.h>
54 #ifdef CONFIG_PCI
55 #include <asm-generic/xenomai/pci_ids.h>
56 #endif /* CONFIG_PCI */
57 #include <asm/xenomai/syscall.h>
58 
59 struct class;
60 typedef struct xnselector rtdm_selector_t;
61 enum rtdm_selecttype;
62 
75 #define RTDM_EXCLUSIVE 0x0001
76 
82 #define RTDM_FIXED_MINOR 0x0002
83 
85 #define RTDM_NAMED_DEVICE 0x0010
86 
89 #define RTDM_PROTOCOL_DEVICE 0x0020
90 
92 #define RTDM_DEVICE_TYPE_MASK 0x00F0
93 
95 #define RTDM_SECURE_DEVICE 0x80000000
99 #define RTDM_MAX_MINOR 4096
100 
115  RTDM_SELECTTYPE_READ = XNSELECT_READ,
116 
118  RTDM_SELECTTYPE_WRITE = XNSELECT_WRITE,
119 
121  RTDM_SELECTTYPE_EXCEPT = XNSELECT_EXCEPT
122 };
139  struct rtdm_fd fd;
140 
144 
146  char dev_private[0];
147 };
148 
149 static inline struct rtdm_dev_context *rtdm_fd_to_context(struct rtdm_fd *fd)
150 {
151  return container_of(fd, struct rtdm_dev_context, fd);
152 }
153 
163 static inline void *rtdm_fd_to_private(struct rtdm_fd *fd)
164 {
165  return &rtdm_fd_to_context(fd)->dev_private[0];
166 }
167 
176 static inline struct rtdm_fd *rtdm_private_to_fd(void *dev_private)
177 {
178  struct rtdm_dev_context *ctx;
179  ctx = container_of(dev_private, struct rtdm_dev_context, dev_private);
180  return &ctx->fd;
181 }
182 
191 static inline bool rtdm_fd_is_user(struct rtdm_fd *fd)
192 {
193  return rtdm_fd_owner(fd) != &cobalt_kernel_ppd;
194 }
195 
204 static inline struct rtdm_device *rtdm_fd_device(struct rtdm_fd *fd)
205 {
206  return rtdm_fd_to_context(fd)->device;
207 }
208 
219  const char *name;
221  int class_id;
226  int version;
228  unsigned int magic;
229  struct module *owner;
230  struct class *kdev_class;
231 };
232 
233 struct rtdm_driver;
234 
238 struct rtdm_sm_ops {
240  int (*start)(struct rtdm_driver *drv);
242  int (*stop)(struct rtdm_driver *drv);
243 };
244 
251 struct rtdm_driver {
271  size_t context_size;
277  struct rtdm_fd_ops ops;
279  struct rtdm_sm_ops smops;
288  struct {
289  union {
290  struct {
291  struct cdev cdev;
292  int major;
293  } named;
294  };
295  atomic_t refcount;
296  struct notifier_block nb_statechange;
297  DECLARE_BITMAP(minor_map, RTDM_MAX_MINOR);
298  };
299 };
300 
301 #define RTDM_CLASS_MAGIC 0x8284636c
302 
321 #define RTDM_PROFILE_INFO(__name, __id, __subid, __version) \
322 { \
323  .name = ( # __name ), \
324  .class_id = (__id), \
325  .subclass_id = (__subid), \
326  .version = (__version), \
327  .magic = ~RTDM_CLASS_MAGIC, \
328  .owner = THIS_MODULE, \
329  .kdev_class = NULL, \
330 }
331 
332 int rtdm_drv_set_sysclass(struct rtdm_driver *drv, struct class *cls);
333 
340 struct rtdm_device {
344  void *device_data;
356  const char *label;
371  int minor;
373  struct {
374  unsigned int magic;
375  char *name;
376  union {
377  struct {
378  xnhandle_t handle;
379  } named;
380  struct {
381  struct xnid id;
382  } proto;
383  };
384  dev_t rdev;
385  struct device *kdev;
386  struct class *kdev_class;
387  atomic_t refcount;
388  struct rtdm_fd_ops ops;
389  wait_queue_head_t putwq;
390  struct list_head openfd_list;
391  };
392 };
393 
394 /* --- device registration --- */
395 
396 int rtdm_dev_register(struct rtdm_device *device);
397 
398 void rtdm_dev_unregister(struct rtdm_device *device);
399 
400 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
401 
402 static inline struct device *rtdm_dev_to_kdev(struct rtdm_device *device)
403 {
404  return device->kdev;
405 }
406 
407 /* --- clock services --- */
408 static inline nanosecs_abs_t rtdm_clock_read(void)
409 {
410  return xnclock_read_realtime(&nkclock);
411 }
412 
413 static inline nanosecs_abs_t rtdm_clock_read_monotonic(void)
414 {
415  return xnclock_read_monotonic(&nkclock);
416 }
417 #endif /* !DOXYGEN_CPP */
418 
419 /* --- timeout sequences */
420 
421 typedef nanosecs_abs_t rtdm_toseq_t;
422 
423 void rtdm_toseq_init(rtdm_toseq_t *timeout_seq, nanosecs_rel_t timeout);
424 
460 #define cobalt_atomic_enter(__context) \
461  do { \
462  xnlock_get_irqsave(&nklock, (__context)); \
463  xnsched_lock(); \
464  } while (0)
465 
478 #define cobalt_atomic_leave(__context) \
479  do { \
480  xnsched_unlock(); \
481  xnlock_put_irqrestore(&nklock, (__context)); \
482  } while (0)
483 
512 #ifdef DOXYGEN_CPP /* Beautify doxygen output */
513 #define RTDM_EXECUTE_ATOMICALLY(code_block) \
514 { \
515  <ENTER_ATOMIC_SECTION> \
516  code_block; \
517  <LEAVE_ATOMIC_SECTION> \
518 }
519 #else /* This is how it really works */
520 static inline __attribute__((deprecated)) void
521 rtdm_execute_atomically(void) { }
522 
523 #define RTDM_EXECUTE_ATOMICALLY(code_block) \
524 { \
525  spl_t __rtdm_s; \
526  \
527  rtdm_execute_atomically(); \
528  xnlock_get_irqsave(&nklock, __rtdm_s); \
529  xnsched_lock(); \
530  code_block; \
531  xnsched_unlock(); \
532  xnlock_put_irqrestore(&nklock, __rtdm_s); \
533 }
534 #endif
535 
546 #define RTDM_LOCK_UNLOCKED(__name) PIPELINE_SPIN_LOCK_UNLOCKED(__name)
547 
548 #define DEFINE_RTDM_LOCK(__name) \
549  rtdm_lock_t __name = RTDM_LOCK_UNLOCKED(__name)
550 
552 typedef pipeline_spinlock_t rtdm_lock_t;
553 
555 typedef unsigned long rtdm_lockctx_t;
556 
564 static inline void rtdm_lock_init(rtdm_lock_t *lock)
565 {
566  raw_spin_lock_init(lock);
567 }
568 
576 static inline void rtdm_lock_get(rtdm_lock_t *lock)
577 {
578  XENO_BUG_ON(COBALT, !spltest());
579  raw_spin_lock(lock);
580  xnsched_lock();
581 }
582 
590 static inline void rtdm_lock_put(rtdm_lock_t *lock)
591 {
592  raw_spin_unlock(lock);
593  xnsched_unlock();
594 }
595 
604 #define rtdm_lock_get_irqsave(__lock, __context) \
605  ((__context) = __rtdm_lock_get_irqsave(__lock))
606 
607 static inline rtdm_lockctx_t __rtdm_lock_get_irqsave(rtdm_lock_t *lock)
608 {
609  rtdm_lockctx_t context;
610 
611  splhigh(context);
612  raw_spin_lock(lock);
613  xnsched_lock();
614 
615  return context;
616 }
617 
626 static inline
628 {
629  raw_spin_unlock(lock);
630  xnsched_unlock();
631  splexit(context);
632 }
633 
641 #define rtdm_lock_irqsave(__context) \
642  splhigh(__context)
643 
651 #define rtdm_lock_irqrestore(__context) \
652  splexit(__context)
653 
656 #ifndef DOXYGEN_CPP
657 
658 struct rtdm_waitqueue {
659  struct xnsynch wait;
660 };
661 typedef struct rtdm_waitqueue rtdm_waitqueue_t;
662 
663 #define RTDM_WAITQUEUE_INITIALIZER(__name) { \
664  .wait = XNSYNCH_WAITQUEUE_INITIALIZER((__name).wait), \
665  }
666 
667 #define DEFINE_RTDM_WAITQUEUE(__name) \
668  struct rtdm_waitqueue __name = RTDM_WAITQUEUE_INITIALIZER(__name)
669 
670 #define DEFINE_RTDM_WAITQUEUE_ONSTACK(__name) \
671  DEFINE_RTDM_WAITQUEUE(__name)
672 
673 static inline void rtdm_waitqueue_init(struct rtdm_waitqueue *wq)
674 {
675  *wq = (struct rtdm_waitqueue)RTDM_WAITQUEUE_INITIALIZER(*wq);
676 }
677 
678 static inline void rtdm_waitqueue_destroy(struct rtdm_waitqueue *wq)
679 {
680  xnsynch_destroy(&wq->wait);
681 }
682 
683 static inline int __rtdm_dowait(struct rtdm_waitqueue *wq,
684  nanosecs_rel_t timeout, xntmode_t timeout_mode)
685 {
686  int ret;
687 
688  ret = xnsynch_sleep_on(&wq->wait, timeout, timeout_mode);
689  if (ret & XNBREAK)
690  return -EINTR;
691  if (ret & XNTIMEO)
692  return -ETIMEDOUT;
693  if (ret & XNRMID)
694  return -EIDRM;
695  return 0;
696 }
697 
698 static inline int __rtdm_timedwait(struct rtdm_waitqueue *wq,
699  nanosecs_rel_t timeout, rtdm_toseq_t *toseq)
700 {
701  if (toseq && timeout > 0)
702  return __rtdm_dowait(wq, *toseq, XN_ABSOLUTE);
703 
704  return __rtdm_dowait(wq, timeout, XN_RELATIVE);
705 }
706 
707 #define rtdm_timedwait_condition_locked(__wq, __cond, __timeout, __toseq) \
708  ({ \
709  int __ret = 0; \
710  while (__ret == 0 && !(__cond)) \
711  __ret = __rtdm_timedwait(__wq, __timeout, __toseq); \
712  __ret; \
713  })
714 
715 #define rtdm_wait_condition_locked(__wq, __cond) \
716  ({ \
717  int __ret = 0; \
718  while (__ret == 0 && !(__cond)) \
719  __ret = __rtdm_dowait(__wq, \
720  XN_INFINITE, XN_RELATIVE); \
721  __ret; \
722  })
723 
724 #define rtdm_timedwait_condition(__wq, __cond, __timeout, __toseq) \
725  ({ \
726  spl_t __s; \
727  int __ret; \
728  xnlock_get_irqsave(&nklock, __s); \
729  __ret = rtdm_timedwait_condition_locked(__wq, __cond, \
730  __timeout, __toseq); \
731  xnlock_put_irqrestore(&nklock, __s); \
732  __ret; \
733  })
734 
735 #define rtdm_timedwait(__wq, __timeout, __toseq) \
736  __rtdm_timedwait(__wq, __timeout, __toseq)
737 
738 #define rtdm_timedwait_locked(__wq, __timeout, __toseq) \
739  rtdm_timedwait(__wq, __timeout, __toseq)
740 
741 #define rtdm_wait_condition(__wq, __cond) \
742  ({ \
743  spl_t __s; \
744  int __ret; \
745  xnlock_get_irqsave(&nklock, __s); \
746  __ret = rtdm_wait_condition_locked(__wq, __cond); \
747  xnlock_put_irqrestore(&nklock, __s); \
748  __ret; \
749  })
750 
751 #define rtdm_wait(__wq) \
752  __rtdm_dowait(__wq, XN_INFINITE, XN_RELATIVE)
753 
754 #define rtdm_wait_locked(__wq) rtdm_wait(__wq)
755 
756 #define rtdm_waitqueue_lock(__wq, __context) cobalt_atomic_enter(__context)
757 
758 #define rtdm_waitqueue_unlock(__wq, __context) cobalt_atomic_leave(__context)
759 
760 #define rtdm_waitqueue_signal(__wq) \
761  ({ \
762  struct xnthread *__waiter; \
763  __waiter = xnsynch_wakeup_one_sleeper(&(__wq)->wait); \
764  xnsched_run(); \
765  __waiter != NULL; \
766  })
767 
768 #define __rtdm_waitqueue_flush(__wq, __reason) \
769  ({ \
770  int __ret; \
771  __ret = xnsynch_flush(&(__wq)->wait, __reason); \
772  xnsched_run(); \
773  __ret == XNSYNCH_RESCHED; \
774  })
775 
776 #define rtdm_waitqueue_broadcast(__wq) \
777  __rtdm_waitqueue_flush(__wq, 0)
778 
779 #define rtdm_waitqueue_flush(__wq) \
780  __rtdm_waitqueue_flush(__wq, XNBREAK)
781 
782 #define rtdm_waitqueue_wakeup(__wq, __waiter) \
783  do { \
784  xnsynch_wakeup_this_sleeper(&(__wq)->wait, __waiter); \
785  xnsched_run(); \
786  } while (0)
787 
788 #define rtdm_for_each_waiter(__pos, __wq) \
789  xnsynch_for_each_sleeper(__pos, &(__wq)->wait)
790 
791 #define rtdm_for_each_waiter_safe(__pos, __tmp, __wq) \
792  xnsynch_for_each_sleeper_safe(__pos, __tmp, &(__wq)->wait)
793 
794 #endif /* !DOXYGEN_CPP */
795 
798 /* --- Interrupt management services --- */
804 typedef struct xnintr rtdm_irq_t;
805 
812 #define RTDM_IRQTYPE_SHARED XN_IRQTYPE_SHARED
815 #define RTDM_IRQTYPE_EDGE XN_IRQTYPE_EDGE
825 typedef int (*rtdm_irq_handler_t)(rtdm_irq_t *irq_handle);
826 
833 #define RTDM_IRQ_NONE XN_IRQ_NONE
835 #define RTDM_IRQ_HANDLED XN_IRQ_HANDLED
837 #define RTDM_IRQ_DISABLE XN_IRQ_DISABLE
851 #define rtdm_irq_get_arg(irq_handle, type) ((type *)irq_handle->cookie)
854 int rtdm_irq_request(rtdm_irq_t *irq_handle, unsigned int irq_no,
855  rtdm_irq_handler_t handler, unsigned long flags,
856  const char *device_name, void *arg);
857 
858 int rtdm_irq_request_affine(rtdm_irq_t *irq_handle, unsigned int irq_no,
859  rtdm_irq_handler_t handler, unsigned long flags,
860  const char *device_name, void *arg,
861  const cpumask_t *cpumask);
862 
863 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
864 static inline int rtdm_irq_free(rtdm_irq_t *irq_handle)
865 {
866  if (!XENO_ASSERT(COBALT, xnsched_root_p()))
867  return -EPERM;
868  xnintr_destroy(irq_handle);
869  return 0;
870 }
871 
872 static inline int rtdm_irq_enable(rtdm_irq_t *irq_handle)
873 {
874  xnintr_enable(irq_handle);
875  return 0;
876 }
877 
878 static inline int rtdm_irq_disable(rtdm_irq_t *irq_handle)
879 {
880  xnintr_disable(irq_handle);
881  return 0;
882 }
883 
884 static inline int rtdm_irq_set_affinity(rtdm_irq_t *irq_handle,
885  const cpumask_t *cpumask)
886 {
887  return xnintr_affinity(irq_handle, cpumask);
888 }
889 #endif /* !DOXYGEN_CPP */
890 
891 /* --- non-real-time signalling services --- */
892 
898 typedef struct rtdm_nrtsig rtdm_nrtsig_t;
909 typedef void (*rtdm_nrtsig_handler_t)(rtdm_nrtsig_t *nrt_sig, void *arg);
910 
911 struct rtdm_nrtsig {
912  struct pipeline_inband_work inband_work; /* Must be first */
913  rtdm_nrtsig_handler_t handler;
914  void *arg;
915 };
916 
917 void rtdm_schedule_nrt_work(struct work_struct *lostage_work);
920 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
921 void __rtdm_nrtsig_execute(struct pipeline_inband_work *inband_work);
922 
923 static inline void rtdm_nrtsig_init(rtdm_nrtsig_t *nrt_sig,
924  rtdm_nrtsig_handler_t handler, void *arg)
925 {
926  nrt_sig->inband_work = (struct pipeline_inband_work)
927  PIPELINE_INBAND_WORK_INITIALIZER(*nrt_sig,
928  __rtdm_nrtsig_execute);
929  nrt_sig->handler = handler;
930  nrt_sig->arg = arg;
931 }
932 
933 static inline void rtdm_nrtsig_destroy(rtdm_nrtsig_t *nrt_sig)
934 {
935  nrt_sig->handler = NULL;
936  nrt_sig->arg = NULL;
937 }
938 
939 void rtdm_nrtsig_pend(rtdm_nrtsig_t *nrt_sig);
940 #endif /* !DOXYGEN_CPP */
941 
942 /* --- timer services --- */
943 
949 typedef struct xntimer rtdm_timer_t;
950 
956 typedef void (*rtdm_timer_handler_t)(rtdm_timer_t *timer);
957 
965  RTDM_TIMERMODE_RELATIVE = XN_RELATIVE,
966 
968  RTDM_TIMERMODE_ABSOLUTE = XN_ABSOLUTE,
969 
971  RTDM_TIMERMODE_REALTIME = XN_REALTIME
972 };
977 int rtdm_timer_init(rtdm_timer_t *timer, rtdm_timer_handler_t handler,
978  const char *name);
979 
980 void rtdm_timer_destroy(rtdm_timer_t *timer);
981 
982 int rtdm_timer_start(rtdm_timer_t *timer, nanosecs_abs_t expiry,
983  nanosecs_rel_t interval, enum rtdm_timer_mode mode);
984 
985 void rtdm_timer_stop(rtdm_timer_t *timer);
986 
987 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
988 static inline int rtdm_timer_start_in_handler(rtdm_timer_t *timer,
989  nanosecs_abs_t expiry,
990  nanosecs_rel_t interval,
991  enum rtdm_timer_mode mode)
992 {
993  return xntimer_start(timer, expiry, interval, (xntmode_t)mode);
994 }
995 
996 static inline void rtdm_timer_stop_in_handler(rtdm_timer_t *timer)
997 {
998  xntimer_stop(timer);
999 }
1000 #endif /* !DOXYGEN_CPP */
1001 
1002 /* --- task services --- */
1008 typedef struct xnthread rtdm_task_t;
1009 
1015 typedef void (*rtdm_task_proc_t)(void *arg);
1016 
1021 #define RTDM_TASK_LOWEST_PRIORITY 0
1022 #define RTDM_TASK_HIGHEST_PRIORITY 99
1029 #define RTDM_TASK_RAISE_PRIORITY (+1)
1030 #define RTDM_TASK_LOWER_PRIORITY (-1)
1035 int rtdm_task_init(rtdm_task_t *task, const char *name,
1036  rtdm_task_proc_t task_proc, void *arg,
1037  int priority, nanosecs_rel_t period);
1038 int __rtdm_task_sleep(xnticks_t timeout, xntmode_t mode);
1040 
1041 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
1042 static inline void rtdm_task_destroy(rtdm_task_t *task)
1043 {
1044  xnthread_cancel(task);
1045  xnthread_join(task, true);
1046 }
1047 
1048 static inline int rtdm_task_should_stop(void)
1049 {
1050  return xnthread_test_info(xnthread_current(), XNCANCELD);
1051 }
1052 
1053 void rtdm_task_join(rtdm_task_t *task);
1054 
1055 static inline void __deprecated rtdm_task_join_nrt(rtdm_task_t *task,
1056  unsigned int poll_delay)
1057 {
1058  rtdm_task_join(task);
1059 }
1060 
1061 static inline void rtdm_task_set_priority(rtdm_task_t *task, int priority)
1062 {
1063  union xnsched_policy_param param = { .rt = { .prio = priority } };
1064  spl_t s;
1065 
1066  splhigh(s);
1067  xnthread_set_schedparam(task, &xnsched_class_rt, &param);
1068  xnsched_run();
1069  splexit(s);
1070 }
1071 
1072 static inline int rtdm_task_set_period(rtdm_task_t *task,
1073  nanosecs_abs_t start_date,
1074  nanosecs_rel_t period)
1075 {
1076  if (period < 0)
1077  period = 0;
1078  if (start_date == 0)
1079  start_date = XN_INFINITE;
1080 
1081  return xnthread_set_periodic(task, start_date, XN_ABSOLUTE, period);
1082 }
1083 
1084 static inline int rtdm_task_unblock(rtdm_task_t *task)
1085 {
1086  spl_t s;
1087  int res;
1088 
1089  splhigh(s);
1090  res = xnthread_unblock(task);
1091  xnsched_run();
1092  splexit(s);
1093 
1094  return res;
1095 }
1096 
1097 static inline rtdm_task_t *rtdm_task_current(void)
1098 {
1099  return xnthread_current();
1100 }
1101 
1102 static inline int rtdm_task_wait_period(unsigned long *overruns_r)
1103 {
1104  if (!XENO_ASSERT(COBALT, !xnsched_unblockable_p()))
1105  return -EPERM;
1106  return xnthread_wait_period(overruns_r);
1107 }
1108 
1109 static inline int rtdm_task_sleep(nanosecs_rel_t delay)
1110 {
1111  return __rtdm_task_sleep(delay, XN_RELATIVE);
1112 }
1113 
1114 static inline int
1115 rtdm_task_sleep_abs(nanosecs_abs_t wakeup_date, enum rtdm_timer_mode mode)
1116 {
1117  /* For the sake of a consistent API usage... */
1118  if (mode != RTDM_TIMERMODE_ABSOLUTE && mode != RTDM_TIMERMODE_REALTIME)
1119  return -EINVAL;
1120  return __rtdm_task_sleep(wakeup_date, (xntmode_t)mode);
1121 }
1122 
1123 /* rtdm_task_sleep_abs shall be used instead */
1124 static inline int __deprecated rtdm_task_sleep_until(nanosecs_abs_t wakeup_time)
1125 {
1126  return __rtdm_task_sleep(wakeup_time, XN_REALTIME);
1127 }
1128 
1129 #define rtdm_task_busy_wait(__condition, __spin_ns, __sleep_ns) \
1130  ({ \
1131  __label__ done; \
1132  nanosecs_abs_t __end; \
1133  int __ret = 0; \
1134  for (;;) { \
1135  __end = rtdm_clock_read_monotonic() + __spin_ns; \
1136  for (;;) { \
1137  if (__condition) \
1138  goto done; \
1139  if (rtdm_clock_read_monotonic() >= __end) \
1140  break; \
1141  } \
1142  __ret = rtdm_task_sleep(__sleep_ns); \
1143  if (__ret) \
1144  break; \
1145  } \
1146  done: \
1147  __ret; \
1148  })
1149 
1150 #define rtdm_wait_context xnthread_wait_context
1151 
1152 static inline
1153 void rtdm_wait_complete(struct rtdm_wait_context *wc)
1154 {
1155  xnthread_complete_wait(wc);
1156 }
1157 
1158 static inline
1159 int rtdm_wait_is_completed(struct rtdm_wait_context *wc)
1160 {
1161  return xnthread_wait_complete_p(wc);
1162 }
1163 
1164 static inline void rtdm_wait_prepare(struct rtdm_wait_context *wc)
1165 {
1166  xnthread_prepare_wait(wc);
1167 }
1168 
1169 static inline
1170 struct rtdm_wait_context *rtdm_wait_get_context(rtdm_task_t *task)
1171 {
1172  return xnthread_get_wait_context(task);
1173 }
1174 
1175 #endif /* !DOXYGEN_CPP */
1176 
1177 /* --- event services --- */
1178 
1179 typedef struct rtdm_event {
1180  struct xnsynch synch_base;
1181  DECLARE_XNSELECT(select_block);
1182 } rtdm_event_t;
1183 
1184 #define RTDM_EVENT_PENDING XNSYNCH_SPARE1
1185 
1186 void rtdm_event_init(rtdm_event_t *event, unsigned long pending);
1187 int rtdm_event_select(rtdm_event_t *event, rtdm_selector_t *selector,
1188  enum rtdm_selecttype type, unsigned fd_index);
1189 int rtdm_event_wait(rtdm_event_t *event);
1190 int rtdm_event_timedwait(rtdm_event_t *event, nanosecs_rel_t timeout,
1191  rtdm_toseq_t *timeout_seq);
1192 void rtdm_event_signal(rtdm_event_t *event);
1193 
1194 void rtdm_event_clear(rtdm_event_t *event);
1195 
1196 void rtdm_event_pulse(rtdm_event_t *event);
1197 
1198 void rtdm_event_destroy(rtdm_event_t *event);
1199 
1200 /* --- semaphore services --- */
1201 
1202 typedef struct rtdm_sem {
1203  unsigned long value;
1204  struct xnsynch synch_base;
1205  DECLARE_XNSELECT(select_block);
1206 } rtdm_sem_t;
1207 
1208 void rtdm_sem_init(rtdm_sem_t *sem, unsigned long value);
1209 int rtdm_sem_select(rtdm_sem_t *sem, rtdm_selector_t *selector,
1210  enum rtdm_selecttype type, unsigned fd_index);
1211 int rtdm_sem_down(rtdm_sem_t *sem);
1212 int rtdm_sem_timeddown(rtdm_sem_t *sem, nanosecs_rel_t timeout,
1213  rtdm_toseq_t *timeout_seq);
1214 void rtdm_sem_up(rtdm_sem_t *sem);
1215 
1216 void rtdm_sem_destroy(rtdm_sem_t *sem);
1217 
1218 /* --- mutex services --- */
1219 
1220 typedef struct rtdm_mutex {
1221  struct xnsynch synch_base;
1222  atomic_t fastlock;
1223 } rtdm_mutex_t;
1224 
1225 void rtdm_mutex_init(rtdm_mutex_t *mutex);
1226 int rtdm_mutex_lock(rtdm_mutex_t *mutex);
1227 int rtdm_mutex_timedlock(rtdm_mutex_t *mutex, nanosecs_rel_t timeout,
1228  rtdm_toseq_t *timeout_seq);
1229 void rtdm_mutex_unlock(rtdm_mutex_t *mutex);
1230 void rtdm_mutex_destroy(rtdm_mutex_t *mutex);
1231 
1232 /* --- utility functions --- */
1233 
1234 #define rtdm_printk(format, ...) printk(format, ##__VA_ARGS__)
1235 
1236 #define rtdm_printk_ratelimited(fmt, ...) do { \
1237  if (xnclock_ratelimit()) \
1238  printk(fmt, ##__VA_ARGS__); \
1239 } while (0)
1240 
1241 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
1242 static inline void *rtdm_malloc(size_t size)
1243 {
1244  return xnmalloc(size);
1245 }
1246 
1247 static inline void rtdm_free(void *ptr)
1248 {
1249  xnfree(ptr);
1250 }
1251 
1252 int rtdm_mmap_to_user(struct rtdm_fd *fd,
1253  void *src_addr, size_t len,
1254  int prot, void **pptr,
1255  struct vm_operations_struct *vm_ops,
1256  void *vm_private_data);
1257 
1258 int rtdm_iomap_to_user(struct rtdm_fd *fd,
1259  phys_addr_t src_addr, size_t len,
1260  int prot, void **pptr,
1261  struct vm_operations_struct *vm_ops,
1262  void *vm_private_data);
1263 
1264 int rtdm_mmap_kmem(struct vm_area_struct *vma, void *va);
1265 
1266 int rtdm_mmap_vmem(struct vm_area_struct *vma, void *va);
1267 
1268 int rtdm_mmap_iomem(struct vm_area_struct *vma, phys_addr_t pa);
1269 
1270 int rtdm_munmap(void *ptr, size_t len);
1271 
1272 static inline int rtdm_read_user_ok(struct rtdm_fd *fd,
1273  const void __user *ptr, size_t size)
1274 {
1275  return access_rok(ptr, size);
1276 }
1277 
1278 static inline int rtdm_rw_user_ok(struct rtdm_fd *fd,
1279  const void __user *ptr, size_t size)
1280 {
1281  return access_wok(ptr, size);
1282 }
1283 
1284 static inline int rtdm_copy_from_user(struct rtdm_fd *fd,
1285  void *dst, const void __user *src,
1286  size_t size)
1287 {
1288  return __xn_copy_from_user(dst, src, size) ? -EFAULT : 0;
1289 }
1290 
1291 static inline int rtdm_safe_copy_from_user(struct rtdm_fd *fd,
1292  void *dst, const void __user *src,
1293  size_t size)
1294 {
1295  return cobalt_copy_from_user(dst, src, size);
1296 }
1297 
1298 static inline int rtdm_copy_to_user(struct rtdm_fd *fd,
1299  void __user *dst, const void *src,
1300  size_t size)
1301 {
1302  return __xn_copy_to_user(dst, src, size) ? -EFAULT : 0;
1303 }
1304 
1305 static inline int rtdm_safe_copy_to_user(struct rtdm_fd *fd,
1306  void __user *dst, const void *src,
1307  size_t size)
1308 {
1309  return cobalt_copy_to_user(dst, src, size);
1310 }
1311 
1312 static inline int rtdm_strncpy_from_user(struct rtdm_fd *fd,
1313  char *dst,
1314  const char __user *src, size_t count)
1315 {
1316  return cobalt_strncpy_from_user(dst, src, count);
1317 }
1318 
1319 static inline bool rtdm_available(void)
1320 {
1321  return realtime_core_enabled();
1322 }
1323 
1324 static inline int rtdm_rt_capable(struct rtdm_fd *fd)
1325 {
1326  if (!XENO_ASSERT(COBALT, !xnsched_interrupt_p()))
1327  return 0;
1328 
1329  if (!rtdm_fd_is_user(fd))
1330  return !xnsched_root_p();
1331 
1332  return xnthread_current() != NULL;
1333 }
1334 
1335 static inline int rtdm_in_rt_context(void)
1336 {
1337  return is_primary_domain();
1338 }
1339 
1340 #define RTDM_IOV_FASTMAX 16
1341 
1342 int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iov,
1343  const struct user_msghdr *msg,
1344  struct iovec *iov_fast);
1345 
1346 int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
1347  const struct user_msghdr *msg,
1348  struct iovec *iov_fast);
1349 
1350 static inline
1351 void rtdm_drop_iovec(struct iovec *iov, struct iovec *iov_fast)
1352 {
1353  if (iov != iov_fast)
1354  xnfree(iov);
1355 }
1356 
1357 ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen);
1358 
1359 #endif /* !DOXYGEN_CPP */
1360 
1361 #endif /* _COBALT_RTDM_DRIVER_H */
static bool rtdm_fd_is_user(struct rtdm_fd *fd)
Tell whether the passed file descriptor belongs to an application.
Definition: driver.h:191
static void * rtdm_fd_to_private(struct rtdm_fd *fd)
Locate the driver private area associated to a device context structure.
Definition: driver.h:163
static struct rtdm_device * rtdm_fd_device(struct rtdm_fd *fd)
Locate a device structure from a file descriptor.
Definition: driver.h:204
static struct rtdm_fd * rtdm_private_to_fd(void *dev_private)
Locate a device file descriptor structure from its driver private area.
Definition: driver.h:176
operation handlers
static int __attribute__((cold))
Test if a mutex structure contains a valid autoinitializer.
Definition: mutex.c:176
void xnintr_destroy(struct xnintr *intr)
Destroy an interrupt descriptor.
Definition: intr.c:808
void xnintr_enable(struct xnintr *intr)
Enable an interrupt line.
Definition: intr.c:940
void xnintr_disable(struct xnintr *intr)
Disable an interrupt line.
Definition: intr.c:971
static int xnsched_run(void)
The rescheduling procedure.
Definition: sched.h:312
int __must_check xnsynch_sleep_on(struct xnsynch *synch, xnticks_t timeout, xntmode_t timeout_mode)
Sleep on an ownerless synchronization object.
Definition: synch.c:201
int xnsynch_destroy(struct xnsynch *synch)
Destroy a synchronization object.
Definition: synch.c:156
#define XNBREAK
Forcibly awaken from a wait state.
Definition: thread.h:68
#define XNTIMEO
Woken up due to a timeout condition.
Definition: thread.h:66
#define XNRMID
Pending on a removed resource.
Definition: thread.h:67
#define XNCANCELD
Cancellation request is pending.
Definition: thread.h:72
int xnthread_wait_period(unsigned long *overruns_r)
Wait for the next periodic release point.
Definition: thread.c:1389
static struct xnthread * xnthread_current(void)
Retrieve the current Cobalt core TCB.
Definition: thread.h:390
int xnthread_unblock(struct xnthread *thread)
Unblock a thread.
Definition: thread.c:1213
void xnthread_cancel(struct xnthread *thread)
Cancel a thread.
Definition: thread.c:1522
int xnthread_join(struct xnthread *thread, bool uninterruptible)
Join with a terminated thread.
Definition: thread.c:1651
int xnthread_set_periodic(struct xnthread *thread, xnticks_t idate, xntmode_t timeout_mode, xnticks_t period)
Make a thread periodic.
Definition: thread.c:1304
int xnthread_set_schedparam(struct xnthread *thread, struct xnsched_class *sched_class, const union xnsched_policy_param *sched_param)
Change the base scheduling parameters of a thread.
Definition: thread.c:1825
int xntimer_start(struct xntimer *timer, xnticks_t value, xnticks_t interval, xntmode_t mode)
Arm a timer.
Definition: timer.c:114
static void xntimer_stop(struct xntimer *timer)
Disarm a timer.
Definition: timer.h:471
nanosecs_abs_t rtdm_clock_read(void)
Get system time.
nanosecs_abs_t rtdm_clock_read_monotonic(void)
Get monotonic time.
int rtdm_dev_register(struct rtdm_device *device)
Register a RTDM device.
Definition: device.c:389
#define RTDM_MAX_MINOR
Maximum number of named devices per driver.
Definition: driver.h:99
void rtdm_dev_unregister(struct rtdm_device *device)
Unregister a RTDM device.
Definition: device.c:538
int rtdm_drv_set_sysclass(struct rtdm_driver *drv, struct class *cls)
Set the kernel device class of a RTDM driver.
Definition: device.c:611
int rtdm_irq_set_affinity(rtdm_irq_t *irq_handle, const cpumask_t *cpumask)
Set interrupt affinity.
int rtdm_irq_enable(rtdm_irq_t *irq_handle)
Enable interrupt line.
int rtdm_irq_request_affine(rtdm_irq_t *irq_handle, unsigned int irq_no, rtdm_irq_handler_t handler, unsigned long flags, const char *device_name, void *arg, const cpumask_t *cpumask)
Register an interrupt handler.
Definition: drvlib.c:1476
int rtdm_irq_request(rtdm_irq_t *irq_handle, unsigned int irq_no, rtdm_irq_handler_t handler, unsigned long flags, const char *device_name, void *arg)
Register an interrupt handler.
Definition: drvlib.c:1442
int rtdm_irq_disable(rtdm_irq_t *irq_handle)
Disable interrupt line.
int(* rtdm_irq_handler_t)(rtdm_irq_t *irq_handle)
Interrupt handler.
Definition: driver.h:825
int rtdm_irq_free(rtdm_irq_t *irq_handle)
Release an interrupt handler.
int rtdm_nrtsig_init(rtdm_nrtsig_t *nrt_sig, rtdm_nrtsig_handler_t handler, void *arg)
Register a non-real-time signal handler.
void rtdm_nrtsig_destroy(rtdm_nrtsig_t *nrt_sig)
Release a non-realtime signal handler.
void rtdm_nrtsig_pend(rtdm_nrtsig_t *nrt_sig)
Trigger non-real-time signal.
Definition: drvlib.c:1635
void rtdm_schedule_nrt_work(struct work_struct *lostage_work)
Put a work task in Linux non real-time global workqueue from primary mode.
Definition: drvlib.c:1678
void(* rtdm_nrtsig_handler_t)(rtdm_nrtsig_t *nrt_sig, void *arg)
Non-real-time signal handler.
Definition: driver.h:909
void rtdm_event_signal(rtdm_event_t *event)
Signal an event occurrence.
Definition: drvlib.c:798
int rtdm_event_select(rtdm_event_t *event, rtdm_selector_t *selector, enum rtdm_selecttype type, unsigned int fd_index)
Bind a selector to an event.
Definition: drvlib.c:979
int rtdm_event_wait(rtdm_event_t *event)
Wait on event occurrence.
Definition: drvlib.c:840
void rtdm_event_clear(rtdm_event_t *event)
Clear event state.
Definition: drvlib.c:941
void rtdm_event_destroy(rtdm_event_t *event)
Destroy an event.
Definition: drvlib.c:759
void rtdm_event_pulse(rtdm_event_t *event)
Signal an event occurrence to currently listening waiters.
Definition: drvlib.c:780
void rtdm_event_init(rtdm_event_t *event, unsigned long pending)
Initialise an event.
Definition: drvlib.c:733
int rtdm_event_timedwait(rtdm_event_t *event, nanosecs_rel_t timeout, rtdm_toseq_t *timeout_seq)
Wait on event occurrence with timeout.
Definition: drvlib.c:878
int rtdm_mutex_timedlock(rtdm_mutex_t *mutex, nanosecs_rel_t timeout, rtdm_toseq_t *timeout_seq)
Request a mutex with timeout.
Definition: drvlib.c:1359
int rtdm_mutex_lock(rtdm_mutex_t *mutex)
Request a mutex.
Definition: drvlib.c:1325
void rtdm_mutex_init(rtdm_mutex_t *mutex)
Initialise a mutex.
Definition: drvlib.c:1258
void rtdm_mutex_unlock(rtdm_mutex_t *mutex)
Release a mutex.
Definition: drvlib.c:1295
void rtdm_mutex_destroy(rtdm_mutex_t *mutex)
Destroy a mutex.
Definition: drvlib.c:1276
int rtdm_sem_down(rtdm_sem_t *sem)
Decrement a semaphore.
Definition: drvlib.c:1075
void rtdm_sem_up(rtdm_sem_t *sem)
Increment a semaphore.
Definition: drvlib.c:1172
int rtdm_sem_timeddown(rtdm_sem_t *sem, nanosecs_rel_t timeout, rtdm_toseq_t *timeout_seq)
Decrement a semaphore with timeout.
Definition: drvlib.c:1113
int rtdm_sem_select(rtdm_sem_t *sem, rtdm_selector_t *selector, enum rtdm_selecttype type, unsigned int fd_index)
Bind a selector to a semaphore.
Definition: drvlib.c:1214
void rtdm_sem_init(rtdm_sem_t *sem, unsigned long value)
Initialise a semaphore.
Definition: drvlib.c:1020
void rtdm_sem_destroy(rtdm_sem_t *sem)
Destroy a semaphore.
Definition: drvlib.c:1045
unsigned long rtdm_lockctx_t
Variable to save the context while holding a lock.
Definition: driver.h:555
static void rtdm_lock_get(rtdm_lock_t *lock)
Acquire lock from non-preemptible contexts.
Definition: driver.h:576
pipeline_spinlock_t rtdm_lock_t
Lock variable.
Definition: driver.h:552
static void rtdm_lock_init(rtdm_lock_t *lock)
Dynamic lock initialisation.
Definition: driver.h:564
static void rtdm_lock_put(rtdm_lock_t *lock)
Release lock without preemption restoration.
Definition: driver.h:590
static void rtdm_lock_put_irqrestore(rtdm_lock_t *lock, rtdm_lockctx_t context)
Release lock and restore preemption state.
Definition: driver.h:627
void rtdm_toseq_init(rtdm_toseq_t *timeout_seq, nanosecs_rel_t timeout)
Initialise a timeout sequence.
Definition: drvlib.c:708
void rtdm_waitqueue_destroy(struct rtdm_waitqueue *wq)
Deletes a RTDM wait queue.
void rtdm_waitqueue_init(struct rtdm_waitqueue *wq)
Initialize a RTDM wait queue.
rtdm_selecttype
Definition: driver.h:113
@ RTDM_SELECTTYPE_EXCEPT
Select exceptional events.
Definition: driver.h:121
@ RTDM_SELECTTYPE_WRITE
Select ouput buffer availability events.
Definition: driver.h:118
@ RTDM_SELECTTYPE_READ
Select input data availability events.
Definition: driver.h:115
int rtdm_task_should_stop(void)
Check for pending termination request.
int rtdm_task_sleep_abs(nanosecs_abs_t wakeup_time, enum rtdm_timer_mode mode)
Sleep until a specified absolute time.
void rtdm_task_set_priority(rtdm_task_t *task, int priority)
Adjust real-time task priority.
void rtdm_task_join(rtdm_task_t *task)
Wait on a real-time task to terminate.
Definition: drvlib.c:464
void(* rtdm_task_proc_t)(void *arg)
Real-time task procedure.
Definition: driver.h:1015
int rtdm_task_init(rtdm_task_t *task, const char *name, rtdm_task_proc_t task_proc, void *arg, int priority, nanosecs_rel_t period)
Initialise and start a real-time task.
Definition: drvlib.c:109
int rtdm_task_set_period(rtdm_task_t *task, nanosecs_abs_t start_date, nanosecs_rel_t period)
Adjust real-time task period.
int rtdm_task_sleep_until(nanosecs_abs_t wakeup_time)
Sleep until a specified absolute time.
void rtdm_task_destroy(rtdm_task_t *task)
Destroy a real-time task.
void rtdm_wait_prepare(struct rtdm_wait_context *wc)
Register wait context.
void rtdm_wait_complete(struct rtdm_wait_context *wc)
Mark completion for a wait context.
int rtdm_task_wait_period(unsigned long *overruns_r)
Wait on next real-time task period.
void rtdm_task_busy_sleep(nanosecs_rel_t delay)
Busy-wait a specified amount of time.
Definition: drvlib.c:487
int rtdm_task_sleep(nanosecs_rel_t delay)
Sleep a specified amount of time.
int rtdm_wait_is_completed(struct rtdm_wait_context *wc)
Test completion of a wait context.
int rtdm_task_unblock(rtdm_task_t *task)
Activate a blocked real-time task.
rtdm_task_t * rtdm_task_current(void)
Get current real-time task.
void(* rtdm_timer_handler_t)(rtdm_timer_t *timer)
Timer handler.
Definition: driver.h:956
int rtdm_timer_start(rtdm_timer_t *timer, nanosecs_abs_t expiry, nanosecs_rel_t interval, enum rtdm_timer_mode mode)
Start a timer.
Definition: drvlib.c:568
void rtdm_timer_stop(rtdm_timer_t *timer)
Stop a timer.
Definition: drvlib.c:590
int rtdm_timer_init(rtdm_timer_t *timer, rtdm_timer_handler_t handler, const char *name)
Initialise a timer.
Definition: drvlib.c:518
void rtdm_timer_destroy(rtdm_timer_t *timer)
Destroy a timer.
Definition: drvlib.c:538
rtdm_timer_mode
Definition: driver.h:963
int rtdm_timer_start_in_handler(rtdm_timer_t *timer, nanosecs_abs_t expiry, nanosecs_rel_t interval, enum rtdm_timer_mode mode)
Start a timer from inside a timer handler.
void rtdm_timer_stop_in_handler(rtdm_timer_t *timer)
Stop a timer from inside a timer handler.
@ RTDM_TIMERMODE_ABSOLUTE
Monotonic timer with absolute timeout.
Definition: driver.h:968
@ RTDM_TIMERMODE_REALTIME
Adjustable timer with absolute timeout.
Definition: driver.h:971
@ RTDM_TIMERMODE_RELATIVE
Monotonic timer with relative timeout.
Definition: driver.h:965
int rtdm_munmap(void *ptr, size_t len)
Unmap a user memory range.
Definition: drvlib.c:2181
int rtdm_read_user_ok(struct rtdm_fd *fd, const void __user *ptr, size_t size)
Check if read access to user-space memory block is safe.
int rtdm_rw_user_ok(struct rtdm_fd *fd, const void __user *ptr, size_t size)
Check if read/write access to user-space memory block is safe.
int rtdm_copy_from_user(struct rtdm_fd *fd, void *dst, const void __user *src, size_t size)
Copy user-space memory block to specified buffer.
void * rtdm_malloc(size_t size)
Allocate memory block.
int rtdm_iomap_to_user(struct rtdm_fd *fd, phys_addr_t src_addr, size_t len, int prot, void **pptr, struct vm_operations_struct *vm_ops, void *vm_private_data)
Map an I/O memory range into the address space of the user.
Definition: drvlib.c:2063
int rtdm_mmap_kmem(struct vm_area_struct *vma, void *va)
Map a kernel logical memory range to a virtual user area.
Definition: drvlib.c:2107
int rtdm_safe_copy_to_user(struct rtdm_fd *fd, void __user *dst, const void *src, size_t size)
Check if read/write access to user-space memory block is safe and copy specified buffer to it.
int rtdm_copy_to_user(struct rtdm_fd *fd, void __user *dst, const void *src, size_t size)
Copy specified buffer to user-space memory block.
int rtdm_mmap_to_user(struct rtdm_fd *fd, void *src_addr, size_t len, int prot, void **pptr, struct vm_operations_struct *vm_ops, void *vm_private_data)
Map a kernel memory range into the address space of the user.
Definition: drvlib.c:1994
void rtdm_free(void *ptr)
Release real-time memory block.
int rtdm_in_rt_context(void)
Test if running in a real-time task.
int rtdm_rt_capable(struct rtdm_fd *fd)
Test if the caller is capable of running in real-time context.
int rtdm_mmap_iomem(struct vm_area_struct *vma, phys_addr_t pa)
Map an I/O memory range to a virtual user area.
Definition: drvlib.c:2160
bool rtdm_available(void)
Test if the real-time core is available.
int rtdm_mmap_vmem(struct vm_area_struct *vma, void *va)
Map a kernel virtual memory range to a virtual user area.
Definition: drvlib.c:2132
int rtdm_strncpy_from_user(struct rtdm_fd *fd, char *dst, const char __user *src, size_t count)
Copy user-space string to specified buffer.
int rtdm_safe_copy_from_user(struct rtdm_fd *fd, void *dst, const void __user *src, size_t size)
Check if read access to user-space memory block and copy it to specified buffer.
uint64_t nanosecs_abs_t
RTDM type for representing absolute dates.
Definition: rtdm.h:43
int64_t nanosecs_rel_t
RTDM type for representing relative intervals.
Definition: rtdm.h:49
Copyright © 2011 Gilles Chanteperdrix [email protected].
Definition: atomic.h:24
Device context.
Definition: driver.h:138
char dev_private[0]
Begin of driver defined context data structure.
Definition: driver.h:146
struct rtdm_device * device
Set of active device operation handlers.
Definition: driver.h:143
RTDM device.
Definition: driver.h:340
int minor
Minor number of the device.
Definition: driver.h:371
void * device_data
Driver definable device data.
Definition: driver.h:344
struct rtdm_driver * driver
Device driver.
Definition: driver.h:342
const char * label
Device label template for composing the device name.
Definition: driver.h:356
RTDM driver.
Definition: driver.h:251
struct rtdm_fd_ops ops
I/O operation handlers.
Definition: driver.h:277
int socket_type
Protocol device identification: socket type (SOCK_xxx)
Definition: driver.h:275
int device_flags
Device flags, see Device Flags for details .
Definition: driver.h:262
int base_minor
Base minor for named devices.
Definition: driver.h:286
size_t context_size
Size of the private memory area the core should automatically allocate for each open file descriptor,...
Definition: driver.h:271
int device_count
Count of devices this driver manages.
Definition: driver.h:284
struct rtdm_sm_ops smops
State management handlers.
Definition: driver.h:279
int protocol_family
Protocol device identification: protocol family (PF_xxx)
Definition: driver.h:273
struct rtdm_profile_info profile_info
Class profile information.
Definition: driver.h:257
Definition: fd.h:246
RTDM profile information.
Definition: driver.h:217
int version
Supported device profile version.
Definition: driver.h:226
unsigned int magic
Reserved.
Definition: driver.h:228
int subclass_id
Device sub-class, see RTDM_SUBCLASS_xxx definition in the Device Profiles.
Definition: driver.h:224
const char * name
Device class name.
Definition: driver.h:219
int class_id
Device class ID, see RTDM_CLASS_xxx.
Definition: driver.h:221
RTDM state management handlers.
Definition: driver.h:238
int(* stop)(struct rtdm_driver *drv)
Handler called upon transition to COBALT_STATE_TEARDOWN.
Definition: driver.h:242
int(* start)(struct rtdm_driver *drv)
Handler called upon transition to COBALT_STATE_WARMUP.
Definition: driver.h:240