Xenomai  3.0.15
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/list.h>
31 #include <linux/module.h>
32 #include <linux/cdev.h>
33 #include <linux/wait.h>
34 #include <linux/notifier.h>
35 #include <xenomai/version.h>
36 #include <cobalt/kernel/heap.h>
37 #include <cobalt/kernel/sched.h>
38 #include <cobalt/kernel/intr.h>
39 #include <cobalt/kernel/synch.h>
40 #include <cobalt/kernel/select.h>
41 #include <cobalt/kernel/clock.h>
42 #include <cobalt/kernel/apc.h>
43 #include <cobalt/kernel/init.h>
44 #include <cobalt/kernel/ancillaries.h>
45 #include <cobalt/kernel/tree.h>
46 #include <rtdm/fd.h>
47 #include <rtdm/rtdm.h>
48 
49 /* debug support */
50 #include <cobalt/kernel/assert.h>
51 #include <trace/events/cobalt-rtdm.h>
52 #ifdef CONFIG_PCI
53 #include <asm-generic/xenomai/pci_ids.h>
54 #endif /* CONFIG_PCI */
55 #include <asm/xenomai/syscall.h>
56 
57 struct class;
58 typedef struct xnselector rtdm_selector_t;
59 enum rtdm_selecttype;
60 
73 #define RTDM_EXCLUSIVE 0x0001
74 
80 #define RTDM_FIXED_MINOR 0x0002
81 
83 #define RTDM_NAMED_DEVICE 0x0010
84 
87 #define RTDM_PROTOCOL_DEVICE 0x0020
88 
90 #define RTDM_DEVICE_TYPE_MASK 0x00F0
91 
93 #define RTDM_SECURE_DEVICE 0x80000000
97 #define RTDM_MAX_MINOR 4096
98 
113  RTDM_SELECTTYPE_READ = XNSELECT_READ,
114 
116  RTDM_SELECTTYPE_WRITE = XNSELECT_WRITE,
117 
119  RTDM_SELECTTYPE_EXCEPT = XNSELECT_EXCEPT
120 };
137  struct rtdm_fd fd;
138 
142 
144  char dev_private[0];
145 };
146 
147 static inline struct rtdm_dev_context *rtdm_fd_to_context(struct rtdm_fd *fd)
148 {
149  return container_of(fd, struct rtdm_dev_context, fd);
150 }
151 
161 static inline void *rtdm_fd_to_private(struct rtdm_fd *fd)
162 {
163  return &rtdm_fd_to_context(fd)->dev_private[0];
164 }
165 
174 static inline struct rtdm_fd *rtdm_private_to_fd(void *dev_private)
175 {
176  struct rtdm_dev_context *ctx;
177  ctx = container_of(dev_private, struct rtdm_dev_context, dev_private);
178  return &ctx->fd;
179 }
180 
189 static inline bool rtdm_fd_is_user(struct rtdm_fd *fd)
190 {
191  return rtdm_fd_owner(fd) != &cobalt_kernel_ppd;
192 }
193 
202 static inline struct rtdm_device *rtdm_fd_device(struct rtdm_fd *fd)
203 {
204  return rtdm_fd_to_context(fd)->device;
205 }
206 
217  const char *name;
219  int class_id;
224  int version;
226  unsigned int magic;
227  struct module *owner;
228  struct class *kdev_class;
229 };
230 
231 struct rtdm_driver;
232 
236 struct rtdm_sm_ops {
238  int (*start)(struct rtdm_driver *drv);
240  int (*stop)(struct rtdm_driver *drv);
241 };
242 
249 struct rtdm_driver {
269  size_t context_size;
275  struct rtdm_fd_ops ops;
277  struct rtdm_sm_ops smops;
286  struct {
287  union {
288  struct {
289  struct cdev cdev;
290  int major;
291  } named;
292  };
293  atomic_t refcount;
294  struct notifier_block nb_statechange;
295  DECLARE_BITMAP(minor_map, RTDM_MAX_MINOR);
296  };
297 };
298 
299 #define RTDM_CLASS_MAGIC 0x8284636c
300 
319 #define RTDM_PROFILE_INFO(__name, __id, __subid, __version) \
320 { \
321  .name = ( # __name ), \
322  .class_id = (__id), \
323  .subclass_id = (__subid), \
324  .version = (__version), \
325  .magic = ~RTDM_CLASS_MAGIC, \
326  .owner = THIS_MODULE, \
327  .kdev_class = NULL, \
328 }
329 
330 int rtdm_drv_set_sysclass(struct rtdm_driver *drv, struct class *cls);
331 
338 struct rtdm_device {
342  void *device_data;
354  const char *label;
369  int minor;
371  struct {
372  unsigned int magic;
373  char *name;
374  union {
375  struct {
376  xnhandle_t handle;
377  } named;
378  struct {
379  struct xnid id;
380  } proto;
381  };
382  dev_t rdev;
383  struct device *kdev;
384  struct class *kdev_class;
385  atomic_t refcount;
386  struct rtdm_fd_ops ops;
387  wait_queue_head_t putwq;
388  };
389 };
390 
391 /* --- device registration --- */
392 
393 int rtdm_dev_register(struct rtdm_device *device);
394 
395 void rtdm_dev_unregister(struct rtdm_device *device);
396 
397 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
398 
399 static inline struct device *rtdm_dev_to_kdev(struct rtdm_device *device)
400 {
401  return device->kdev;
402 }
403 
404 /* --- clock services --- */
405 static inline nanosecs_abs_t rtdm_clock_read(void)
406 {
407  return xnclock_read_realtime(&nkclock);
408 }
409 
410 static inline nanosecs_abs_t rtdm_clock_read_monotonic(void)
411 {
412  return xnclock_read_monotonic(&nkclock);
413 }
414 #endif /* !DOXYGEN_CPP */
415 
416 /* --- timeout sequences */
417 
418 typedef nanosecs_abs_t rtdm_toseq_t;
419 
420 void rtdm_toseq_init(rtdm_toseq_t *timeout_seq, nanosecs_rel_t timeout);
421 
457 #define cobalt_atomic_enter(__context) \
458  do { \
459  xnlock_get_irqsave(&nklock, (__context)); \
460  xnsched_lock(); \
461  } while (0)
462 
475 #define cobalt_atomic_leave(__context) \
476  do { \
477  xnsched_unlock(); \
478  xnlock_put_irqrestore(&nklock, (__context)); \
479  } while (0)
480 
509 #ifdef DOXYGEN_CPP /* Beautify doxygen output */
510 #define RTDM_EXECUTE_ATOMICALLY(code_block) \
511 { \
512  <ENTER_ATOMIC_SECTION> \
513  code_block; \
514  <LEAVE_ATOMIC_SECTION> \
515 }
516 #else /* This is how it really works */
517 static inline __attribute__((deprecated)) void
518 rtdm_execute_atomically(void) { }
519 
520 #define RTDM_EXECUTE_ATOMICALLY(code_block) \
521 { \
522  spl_t __rtdm_s; \
523  \
524  rtdm_execute_atomically(); \
525  xnlock_get_irqsave(&nklock, __rtdm_s); \
526  xnsched_lock(); \
527  code_block; \
528  xnsched_unlock(); \
529  xnlock_put_irqrestore(&nklock, __rtdm_s); \
530 }
531 #endif
532 
543 #define RTDM_LOCK_UNLOCKED(__name) IPIPE_SPIN_LOCK_UNLOCKED
544 
545 #define DEFINE_RTDM_LOCK(__name) \
546  rtdm_lock_t __name = RTDM_LOCK_UNLOCKED(__name)
547 
549 typedef ipipe_spinlock_t rtdm_lock_t;
550 
552 typedef unsigned long rtdm_lockctx_t;
553 
561 static inline void rtdm_lock_init(rtdm_lock_t *lock)
562 {
563  raw_spin_lock_init(lock);
564 }
565 
573 static inline void rtdm_lock_get(rtdm_lock_t *lock)
574 {
575  XENO_BUG_ON(COBALT, !spltest());
576  raw_spin_lock(lock);
577  xnsched_lock();
578 }
579 
587 static inline void rtdm_lock_put(rtdm_lock_t *lock)
588 {
589  raw_spin_unlock(lock);
590  xnsched_unlock();
591 }
592 
601 #define rtdm_lock_get_irqsave(__lock, __context) \
602  ((__context) = __rtdm_lock_get_irqsave(__lock))
603 
604 static inline rtdm_lockctx_t __rtdm_lock_get_irqsave(rtdm_lock_t *lock)
605 {
606  rtdm_lockctx_t context;
607 
608  context = ipipe_test_and_stall_head();
609  raw_spin_lock(lock);
610  xnsched_lock();
611 
612  return context;
613 }
614 
623 static inline
625 {
626  raw_spin_unlock(lock);
627  xnsched_unlock();
628  ipipe_restore_head(context);
629 }
630 
638 #define rtdm_lock_irqsave(__context) \
639  splhigh(__context)
640 
648 #define rtdm_lock_irqrestore(__context) \
649  splexit(__context)
650 
653 #ifndef DOXYGEN_CPP
654 
655 struct rtdm_waitqueue {
656  struct xnsynch wait;
657 };
658 typedef struct rtdm_waitqueue rtdm_waitqueue_t;
659 
660 #define RTDM_WAITQUEUE_INITIALIZER(__name) { \
661  .wait = XNSYNCH_WAITQUEUE_INITIALIZER((__name).wait), \
662  }
663 
664 #define DEFINE_RTDM_WAITQUEUE(__name) \
665  struct rtdm_waitqueue __name = RTDM_WAITQUEUE_INITIALIZER(__name)
666 
667 #define DEFINE_RTDM_WAITQUEUE_ONSTACK(__name) \
668  DEFINE_RTDM_WAITQUEUE(__name)
669 
670 static inline void rtdm_waitqueue_init(struct rtdm_waitqueue *wq)
671 {
672  *wq = (struct rtdm_waitqueue)RTDM_WAITQUEUE_INITIALIZER(*wq);
673 }
674 
675 static inline void rtdm_waitqueue_destroy(struct rtdm_waitqueue *wq)
676 {
677  xnsynch_destroy(&wq->wait);
678 }
679 
680 static inline int __rtdm_dowait(struct rtdm_waitqueue *wq,
681  nanosecs_rel_t timeout, xntmode_t timeout_mode)
682 {
683  int ret;
684 
685  ret = xnsynch_sleep_on(&wq->wait, timeout, timeout_mode);
686  if (ret & XNBREAK)
687  return -EINTR;
688  if (ret & XNTIMEO)
689  return -ETIMEDOUT;
690  if (ret & XNRMID)
691  return -EIDRM;
692  return 0;
693 }
694 
695 static inline int __rtdm_timedwait(struct rtdm_waitqueue *wq,
696  nanosecs_rel_t timeout, rtdm_toseq_t *toseq)
697 {
698  if (toseq && timeout > 0)
699  return __rtdm_dowait(wq, *toseq, XN_ABSOLUTE);
700 
701  return __rtdm_dowait(wq, timeout, XN_RELATIVE);
702 }
703 
704 #define rtdm_timedwait_condition_locked(__wq, __cond, __timeout, __toseq) \
705  ({ \
706  int __ret = 0; \
707  while (__ret == 0 && !(__cond)) \
708  __ret = __rtdm_timedwait(__wq, __timeout, __toseq); \
709  __ret; \
710  })
711 
712 #define rtdm_wait_condition_locked(__wq, __cond) \
713  ({ \
714  int __ret = 0; \
715  while (__ret == 0 && !(__cond)) \
716  __ret = __rtdm_dowait(__wq, \
717  XN_INFINITE, XN_RELATIVE); \
718  __ret; \
719  })
720 
721 #define rtdm_timedwait_condition(__wq, __cond, __timeout, __toseq) \
722  ({ \
723  spl_t __s; \
724  int __ret; \
725  xnlock_get_irqsave(&nklock, __s); \
726  __ret = rtdm_timedwait_condition_locked(__wq, __cond, \
727  __timeout, __toseq); \
728  xnlock_put_irqrestore(&nklock, __s); \
729  __ret; \
730  })
731 
732 #define rtdm_timedwait(__wq, __timeout, __toseq) \
733  __rtdm_timedwait(__wq, __timeout, __toseq)
734 
735 #define rtdm_timedwait_locked(__wq, __timeout, __toseq) \
736  rtdm_timedwait(__wq, __timeout, __toseq)
737 
738 #define rtdm_wait_condition(__wq, __cond) \
739  ({ \
740  spl_t __s; \
741  int __ret; \
742  xnlock_get_irqsave(&nklock, __s); \
743  __ret = rtdm_wait_condition_locked(__wq, __cond); \
744  xnlock_put_irqrestore(&nklock, __s); \
745  __ret; \
746  })
747 
748 #define rtdm_wait(__wq) \
749  __rtdm_dowait(__wq, XN_INFINITE, XN_RELATIVE)
750 
751 #define rtdm_wait_locked(__wq) rtdm_wait(__wq)
752 
753 #define rtdm_waitqueue_lock(__wq, __context) cobalt_atomic_enter(__context)
754 
755 #define rtdm_waitqueue_unlock(__wq, __context) cobalt_atomic_leave(__context)
756 
757 #define rtdm_waitqueue_signal(__wq) \
758  ({ \
759  struct xnthread *__waiter; \
760  __waiter = xnsynch_wakeup_one_sleeper(&(__wq)->wait); \
761  xnsched_run(); \
762  __waiter != NULL; \
763  })
764 
765 #define __rtdm_waitqueue_flush(__wq, __reason) \
766  ({ \
767  int __ret; \
768  __ret = xnsynch_flush(&(__wq)->wait, __reason); \
769  xnsched_run(); \
770  __ret == XNSYNCH_RESCHED; \
771  })
772 
773 #define rtdm_waitqueue_broadcast(__wq) \
774  __rtdm_waitqueue_flush(__wq, 0)
775 
776 #define rtdm_waitqueue_flush(__wq) \
777  __rtdm_waitqueue_flush(__wq, XNBREAK)
778 
779 #define rtdm_waitqueue_wakeup(__wq, __waiter) \
780  do { \
781  xnsynch_wakeup_this_sleeper(&(__wq)->wait, __waiter); \
782  xnsched_run(); \
783  } while (0)
784 
785 #define rtdm_for_each_waiter(__pos, __wq) \
786  xnsynch_for_each_sleeper(__pos, &(__wq)->wait)
787 
788 #define rtdm_for_each_waiter_safe(__pos, __tmp, __wq) \
789  xnsynch_for_each_sleeper_safe(__pos, __tmp, &(__wq)->wait)
790 
791 #endif /* !DOXYGEN_CPP */
792 
795 /* --- Interrupt management services --- */
801 typedef struct xnintr rtdm_irq_t;
802 
809 #define RTDM_IRQTYPE_SHARED XN_IRQTYPE_SHARED
812 #define RTDM_IRQTYPE_EDGE XN_IRQTYPE_EDGE
822 typedef int (*rtdm_irq_handler_t)(rtdm_irq_t *irq_handle);
823 
830 #define RTDM_IRQ_NONE XN_IRQ_NONE
832 #define RTDM_IRQ_HANDLED XN_IRQ_HANDLED
834 #define RTDM_IRQ_DISABLE XN_IRQ_DISABLE
848 #define rtdm_irq_get_arg(irq_handle, type) ((type *)irq_handle->cookie)
851 int rtdm_irq_request(rtdm_irq_t *irq_handle, unsigned int irq_no,
852  rtdm_irq_handler_t handler, unsigned long flags,
853  const char *device_name, void *arg);
854 
855 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
856 static inline int rtdm_irq_free(rtdm_irq_t *irq_handle)
857 {
858  if (!XENO_ASSERT(COBALT, xnsched_root_p()))
859  return -EPERM;
860  xnintr_destroy(irq_handle);
861  return 0;
862 }
863 
864 static inline int rtdm_irq_enable(rtdm_irq_t *irq_handle)
865 {
866  xnintr_enable(irq_handle);
867  return 0;
868 }
869 
870 static inline int rtdm_irq_disable(rtdm_irq_t *irq_handle)
871 {
872  xnintr_disable(irq_handle);
873  return 0;
874 }
875 #endif /* !DOXYGEN_CPP */
876 
877 /* --- non-real-time signalling services --- */
878 
884 typedef struct rtdm_nrtsig rtdm_nrtsig_t;
895 typedef void (*rtdm_nrtsig_handler_t)(rtdm_nrtsig_t *nrt_sig, void *arg);
896 
897 struct rtdm_nrtsig {
898  rtdm_nrtsig_handler_t handler;
899  void *arg;
900 };
901 
902 void rtdm_schedule_nrt_work(struct work_struct *lostage_work);
905 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
906 static inline void rtdm_nrtsig_init(rtdm_nrtsig_t *nrt_sig,
907  rtdm_nrtsig_handler_t handler, void *arg)
908 {
909  nrt_sig->handler = handler;
910  nrt_sig->arg = arg;
911 }
912 
913 static inline void rtdm_nrtsig_destroy(rtdm_nrtsig_t *nrt_sig)
914 {
915  nrt_sig->handler = NULL;
916  nrt_sig->arg = NULL;
917 }
918 
919 void rtdm_nrtsig_pend(rtdm_nrtsig_t *nrt_sig);
920 #endif /* !DOXYGEN_CPP */
921 
922 /* --- timer services --- */
923 
929 typedef struct xntimer rtdm_timer_t;
930 
936 typedef void (*rtdm_timer_handler_t)(rtdm_timer_t *timer);
937 
945  RTDM_TIMERMODE_RELATIVE = XN_RELATIVE,
946 
948  RTDM_TIMERMODE_ABSOLUTE = XN_ABSOLUTE,
949 
951  RTDM_TIMERMODE_REALTIME = XN_REALTIME
952 };
957 #ifndef DOXYGEN_CPP /* Avoid broken doxygen output */
958 #define rtdm_timer_init(timer, handler, name) \
959 ({ \
960  xntimer_init((timer), &nkclock, handler, \
961  NULL, XNTIMER_IGRAVITY); \
962  xntimer_set_name((timer), (name)); \
963  0; \
964 })
965 
966 #endif /* !DOXYGEN_CPP */
967 
968 void rtdm_timer_destroy(rtdm_timer_t *timer);
969 
970 int rtdm_timer_start(rtdm_timer_t *timer, nanosecs_abs_t expiry,
971  nanosecs_rel_t interval, enum rtdm_timer_mode mode);
972 
973 void rtdm_timer_stop(rtdm_timer_t *timer);
974 
975 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
976 static inline int rtdm_timer_start_in_handler(rtdm_timer_t *timer,
977  nanosecs_abs_t expiry,
978  nanosecs_rel_t interval,
979  enum rtdm_timer_mode mode)
980 {
981  return xntimer_start(timer, expiry, interval, (xntmode_t)mode);
982 }
983 
984 static inline void rtdm_timer_stop_in_handler(rtdm_timer_t *timer)
985 {
986  xntimer_stop(timer);
987 }
988 #endif /* !DOXYGEN_CPP */
989 
990 /* --- task services --- */
996 typedef struct xnthread rtdm_task_t;
997 
1003 typedef void (*rtdm_task_proc_t)(void *arg);
1004 
1009 #define RTDM_TASK_LOWEST_PRIORITY 0
1010 #define RTDM_TASK_HIGHEST_PRIORITY 99
1017 #define RTDM_TASK_RAISE_PRIORITY (+1)
1018 #define RTDM_TASK_LOWER_PRIORITY (-1)
1023 int rtdm_task_init(rtdm_task_t *task, const char *name,
1024  rtdm_task_proc_t task_proc, void *arg,
1025  int priority, nanosecs_rel_t period);
1026 int __rtdm_task_sleep(xnticks_t timeout, xntmode_t mode);
1028 
1029 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
1030 static inline void rtdm_task_destroy(rtdm_task_t *task)
1031 {
1032  xnthread_cancel(task);
1033  xnthread_join(task, true);
1034 }
1035 
1036 static inline int rtdm_task_should_stop(void)
1037 {
1038  return xnthread_test_info(xnthread_current(), XNCANCELD);
1039 }
1040 
1041 void rtdm_task_join(rtdm_task_t *task);
1042 
1043 static inline void __deprecated rtdm_task_join_nrt(rtdm_task_t *task,
1044  unsigned int poll_delay)
1045 {
1046  rtdm_task_join(task);
1047 }
1048 
1049 static inline void rtdm_task_set_priority(rtdm_task_t *task, int priority)
1050 {
1051  union xnsched_policy_param param = { .rt = { .prio = priority } };
1052  spl_t s;
1053 
1054  splhigh(s);
1055  xnthread_set_schedparam(task, &xnsched_class_rt, &param);
1056  xnsched_run();
1057  splexit(s);
1058 }
1059 
1060 static inline int rtdm_task_set_period(rtdm_task_t *task,
1061  nanosecs_abs_t start_date,
1062  nanosecs_rel_t period)
1063 {
1064  if (period < 0)
1065  period = 0;
1066  if (start_date == 0)
1067  start_date = XN_INFINITE;
1068 
1069  return xnthread_set_periodic(task, start_date, XN_ABSOLUTE, period);
1070 }
1071 
1072 static inline int rtdm_task_unblock(rtdm_task_t *task)
1073 {
1074  spl_t s;
1075  int res;
1076 
1077  splhigh(s);
1078  res = xnthread_unblock(task);
1079  xnsched_run();
1080  splexit(s);
1081 
1082  return res;
1083 }
1084 
1085 static inline rtdm_task_t *rtdm_task_current(void)
1086 {
1087  return xnthread_current();
1088 }
1089 
1090 static inline int rtdm_task_wait_period(unsigned long *overruns_r)
1091 {
1092  if (!XENO_ASSERT(COBALT, !xnsched_unblockable_p()))
1093  return -EPERM;
1094  return xnthread_wait_period(overruns_r);
1095 }
1096 
1097 static inline int rtdm_task_sleep(nanosecs_rel_t delay)
1098 {
1099  return __rtdm_task_sleep(delay, XN_RELATIVE);
1100 }
1101 
1102 static inline int
1103 rtdm_task_sleep_abs(nanosecs_abs_t wakeup_date, enum rtdm_timer_mode mode)
1104 {
1105  /* For the sake of a consistent API usage... */
1106  if (mode != RTDM_TIMERMODE_ABSOLUTE && mode != RTDM_TIMERMODE_REALTIME)
1107  return -EINVAL;
1108  return __rtdm_task_sleep(wakeup_date, (xntmode_t)mode);
1109 }
1110 
1111 /* rtdm_task_sleep_abs shall be used instead */
1112 static inline int __deprecated rtdm_task_sleep_until(nanosecs_abs_t wakeup_time)
1113 {
1114  return __rtdm_task_sleep(wakeup_time, XN_REALTIME);
1115 }
1116 
1117 #define rtdm_task_busy_wait(__condition, __spin_ns, __sleep_ns) \
1118  ({ \
1119  __label__ done; \
1120  nanosecs_abs_t __end; \
1121  int __ret = 0; \
1122  for (;;) { \
1123  __end = rtdm_clock_read_monotonic() + __spin_ns; \
1124  for (;;) { \
1125  if (__condition) \
1126  goto done; \
1127  if (rtdm_clock_read_monotonic() >= __end) \
1128  break; \
1129  } \
1130  __ret = rtdm_task_sleep(__sleep_ns); \
1131  if (__ret) \
1132  break; \
1133  } \
1134  done: \
1135  __ret; \
1136  })
1137 
1138 #define rtdm_wait_context xnthread_wait_context
1139 
1140 static inline
1141 void rtdm_wait_complete(struct rtdm_wait_context *wc)
1142 {
1143  xnthread_complete_wait(wc);
1144 }
1145 
1146 static inline
1147 int rtdm_wait_is_completed(struct rtdm_wait_context *wc)
1148 {
1149  return xnthread_wait_complete_p(wc);
1150 }
1151 
1152 static inline void rtdm_wait_prepare(struct rtdm_wait_context *wc)
1153 {
1154  xnthread_prepare_wait(wc);
1155 }
1156 
1157 static inline
1158 struct rtdm_wait_context *rtdm_wait_get_context(rtdm_task_t *task)
1159 {
1160  return xnthread_get_wait_context(task);
1161 }
1162 
1163 #endif /* !DOXYGEN_CPP */
1164 
1165 /* --- event services --- */
1166 
1167 typedef struct rtdm_event {
1168  struct xnsynch synch_base;
1169  DECLARE_XNSELECT(select_block);
1170 } rtdm_event_t;
1171 
1172 #define RTDM_EVENT_PENDING XNSYNCH_SPARE1
1173 
1174 void rtdm_event_init(rtdm_event_t *event, unsigned long pending);
1175 int rtdm_event_select(rtdm_event_t *event, rtdm_selector_t *selector,
1176  enum rtdm_selecttype type, unsigned fd_index);
1177 int rtdm_event_wait(rtdm_event_t *event);
1178 int rtdm_event_timedwait(rtdm_event_t *event, nanosecs_rel_t timeout,
1179  rtdm_toseq_t *timeout_seq);
1180 void rtdm_event_signal(rtdm_event_t *event);
1181 
1182 void rtdm_event_clear(rtdm_event_t *event);
1183 
1184 void rtdm_event_pulse(rtdm_event_t *event);
1185 
1186 void rtdm_event_destroy(rtdm_event_t *event);
1187 
1188 /* --- semaphore services --- */
1189 
1190 typedef struct rtdm_sem {
1191  unsigned long value;
1192  struct xnsynch synch_base;
1193  DECLARE_XNSELECT(select_block);
1194 } rtdm_sem_t;
1195 
1196 void rtdm_sem_init(rtdm_sem_t *sem, unsigned long value);
1197 int rtdm_sem_select(rtdm_sem_t *sem, rtdm_selector_t *selector,
1198  enum rtdm_selecttype type, unsigned fd_index);
1199 int rtdm_sem_down(rtdm_sem_t *sem);
1200 int rtdm_sem_timeddown(rtdm_sem_t *sem, nanosecs_rel_t timeout,
1201  rtdm_toseq_t *timeout_seq);
1202 void rtdm_sem_up(rtdm_sem_t *sem);
1203 
1204 void rtdm_sem_destroy(rtdm_sem_t *sem);
1205 
1206 /* --- mutex services --- */
1207 
1208 typedef struct rtdm_mutex {
1209  struct xnsynch synch_base;
1210  atomic_t fastlock;
1211 } rtdm_mutex_t;
1212 
1213 void rtdm_mutex_init(rtdm_mutex_t *mutex);
1214 int rtdm_mutex_lock(rtdm_mutex_t *mutex);
1215 int rtdm_mutex_timedlock(rtdm_mutex_t *mutex, nanosecs_rel_t timeout,
1216  rtdm_toseq_t *timeout_seq);
1217 void rtdm_mutex_unlock(rtdm_mutex_t *mutex);
1218 void rtdm_mutex_destroy(rtdm_mutex_t *mutex);
1219 
1220 /* --- utility functions --- */
1221 
1222 #define rtdm_printk(format, ...) printk(format, ##__VA_ARGS__)
1223 
1224 struct rtdm_ratelimit_state {
1225  rtdm_lock_t lock; /* protect the state */
1226  nanosecs_abs_t interval;
1227  int burst;
1228  int printed;
1229  int missed;
1230  nanosecs_abs_t begin;
1231 };
1232 
1233 int rtdm_ratelimit(struct rtdm_ratelimit_state *rs, const char *func);
1234 
1235 #define DEFINE_RTDM_RATELIMIT_STATE(name, interval_init, burst_init) \
1236  struct rtdm_ratelimit_state name = { \
1237  .lock = RTDM_LOCK_UNLOCKED((name).lock), \
1238  .interval = interval_init, \
1239  .burst = burst_init, \
1240  }
1241 
1242 /* We use the Linux defaults */
1243 #define DEF_RTDM_RATELIMIT_INTERVAL 5000000000LL
1244 #define DEF_RTDM_RATELIMIT_BURST 10
1245 
1246 #define rtdm_printk_ratelimited(fmt, ...) ({ \
1247  static DEFINE_RTDM_RATELIMIT_STATE(_rs, \
1248  DEF_RTDM_RATELIMIT_INTERVAL, \
1249  DEF_RTDM_RATELIMIT_BURST); \
1250  \
1251  if (rtdm_ratelimit(&_rs, __func__)) \
1252  printk(fmt, ##__VA_ARGS__); \
1253 })
1254 
1255 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
1256 static inline void *rtdm_malloc(size_t size)
1257 {
1258  return xnmalloc(size);
1259 }
1260 
1261 static inline void rtdm_free(void *ptr)
1262 {
1263  xnfree(ptr);
1264 }
1265 
1266 int rtdm_mmap_to_user(struct rtdm_fd *fd,
1267  void *src_addr, size_t len,
1268  int prot, void **pptr,
1269  struct vm_operations_struct *vm_ops,
1270  void *vm_private_data);
1271 
1272 int rtdm_iomap_to_user(struct rtdm_fd *fd,
1273  phys_addr_t src_addr, size_t len,
1274  int prot, void **pptr,
1275  struct vm_operations_struct *vm_ops,
1276  void *vm_private_data);
1277 
1278 int rtdm_mmap_kmem(struct vm_area_struct *vma, void *va);
1279 
1280 int rtdm_mmap_vmem(struct vm_area_struct *vma, void *va);
1281 
1282 int rtdm_mmap_iomem(struct vm_area_struct *vma, phys_addr_t pa);
1283 
1284 int rtdm_munmap(void *ptr, size_t len);
1285 
1286 static inline int rtdm_read_user_ok(struct rtdm_fd *fd,
1287  const void __user *ptr, size_t size)
1288 {
1289  return access_rok(ptr, size);
1290 }
1291 
1292 static inline int rtdm_rw_user_ok(struct rtdm_fd *fd,
1293  const void __user *ptr, size_t size)
1294 {
1295  return access_wok(ptr, size);
1296 }
1297 
1298 static inline int rtdm_copy_from_user(struct rtdm_fd *fd,
1299  void *dst, const void __user *src,
1300  size_t size)
1301 {
1302  return __xn_copy_from_user(dst, src, size) ? -EFAULT : 0;
1303 }
1304 
1305 static inline int rtdm_safe_copy_from_user(struct rtdm_fd *fd,
1306  void *dst, const void __user *src,
1307  size_t size)
1308 {
1309  return cobalt_copy_from_user(dst, src, size);
1310 }
1311 
1312 static inline int rtdm_copy_to_user(struct rtdm_fd *fd,
1313  void __user *dst, const void *src,
1314  size_t size)
1315 {
1316  return __xn_copy_to_user(dst, src, size) ? -EFAULT : 0;
1317 }
1318 
1319 static inline int rtdm_safe_copy_to_user(struct rtdm_fd *fd,
1320  void __user *dst, const void *src,
1321  size_t size)
1322 {
1323  return cobalt_copy_to_user(dst, src, size);
1324 }
1325 
1326 static inline int rtdm_strncpy_from_user(struct rtdm_fd *fd,
1327  char *dst,
1328  const char __user *src, size_t count)
1329 {
1330  return cobalt_strncpy_from_user(dst, src, count);
1331 }
1332 
1333 static inline int rtdm_rt_capable(struct rtdm_fd *fd)
1334 {
1335  if (!XENO_ASSERT(COBALT, !xnsched_interrupt_p()))
1336  return 0;
1337 
1338  if (!rtdm_fd_is_user(fd))
1339  return !xnsched_root_p();
1340 
1341  return xnthread_current() != NULL;
1342 }
1343 
1344 static inline int rtdm_in_rt_context(void)
1345 {
1346  return (ipipe_current_domain != ipipe_root_domain);
1347 }
1348 
1349 #define RTDM_IOV_FASTMAX 16
1350 
1351 int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iov,
1352  const struct user_msghdr *msg,
1353  struct iovec *iov_fast);
1354 
1355 int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
1356  const struct user_msghdr *msg,
1357  struct iovec *iov_fast);
1358 
1359 static inline
1360 void rtdm_drop_iovec(struct iovec *iov, struct iovec *iov_fast)
1361 {
1362  if (iov != iov_fast)
1363  xnfree(iov);
1364 }
1365 
1366 ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen);
1367 
1368 #endif /* !DOXYGEN_CPP */
1369 
1370 #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:189
static void * rtdm_fd_to_private(struct rtdm_fd *fd)
Locate the driver private area associated to a device context structure.
Definition: driver.h:161
static struct rtdm_device * rtdm_fd_device(struct rtdm_fd *fd)
Locate a device structure from a file descriptor.
Definition: driver.h:202
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:174
operation handlers
void xnintr_destroy(struct xnintr *intr)
Destroy an interrupt descriptor.
Definition: intr.c:797
void xnintr_enable(struct xnintr *intr)
Enable an interrupt line.
Definition: intr.c:913
void xnintr_disable(struct xnintr *intr)
Disable an interrupt line.
Definition: intr.c:944
#define splhigh(x)
Hard disable interrupts on the local processor, saving previous state.
Definition: lock.h:39
#define splexit(x)
Restore the saved hard interrupt state on the local processor.
Definition: lock.h:46
#define spltest()
Test hard interrupt state on the local processor.
Definition: lock.h:64
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:162
int xnsynch_destroy(struct xnsynch *synch)
Destroy a synchronization object.
Definition: synch.c:117
#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:1372
static struct xnthread * xnthread_current(void)
Retrieve the current Cobalt core TCB.
Definition: thread.h:371
int xnthread_unblock(struct xnthread *thread)
Unblock a thread.
Definition: thread.c:1196
void xnthread_cancel(struct xnthread *thread)
Cancel a thread.
Definition: thread.c:1505
int xnthread_join(struct xnthread *thread, bool uninterruptible)
Join with a terminated thread.
Definition: thread.c:1634
int xnthread_set_periodic(struct xnthread *thread, xnticks_t idate, xntmode_t timeout_mode, xnticks_t period)
Make a thread periodic.
Definition: thread.c:1287
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:1808
int xntimer_start(struct xntimer *timer, xnticks_t value, xnticks_t interval, xntmode_t mode)
Arm a timer.
Definition: timer.c:113
static void xntimer_stop(struct xntimer *timer)
Disarm a timer.
Definition: timer.h:472
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:97
void rtdm_dev_unregister(struct rtdm_device *device)
Unregister a RTDM device.
Definition: device.c:534
int rtdm_drv_set_sysclass(struct rtdm_driver *drv, struct class *cls)
Set the kernel device class of a RTDM driver.
Definition: device.c:604
int rtdm_irq_enable(rtdm_irq_t *irq_handle)
Enable interrupt line.
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:1423
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:822
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:1571
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:1602
void(* rtdm_nrtsig_handler_t)(rtdm_nrtsig_t *nrt_sig, void *arg)
Non-real-time signal handler.
Definition: driver.h:895
void rtdm_event_signal(rtdm_event_t *event)
Signal an event occurrence.
Definition: drvlib.c:784
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:965
int rtdm_event_wait(rtdm_event_t *event)
Wait on event occurrence.
Definition: drvlib.c:826
void rtdm_event_clear(rtdm_event_t *event)
Clear event state.
Definition: drvlib.c:927
void rtdm_event_destroy(rtdm_event_t *event)
Destroy an event.
Definition: drvlib.c:747
void rtdm_event_pulse(rtdm_event_t *event)
Signal an event occurrence to currently listening waiters.
Definition: drvlib.c:766
void rtdm_event_init(rtdm_event_t *event, unsigned long pending)
Initialise an event.
Definition: drvlib.c:721
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:864
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:1342
int rtdm_mutex_lock(rtdm_mutex_t *mutex)
Request a mutex.
Definition: drvlib.c:1308
void rtdm_mutex_init(rtdm_mutex_t *mutex)
Initialise a mutex.
Definition: drvlib.c:1242
void rtdm_mutex_unlock(rtdm_mutex_t *mutex)
Release a mutex.
Definition: drvlib.c:1278
void rtdm_mutex_destroy(rtdm_mutex_t *mutex)
Destroy a mutex.
Definition: drvlib.c:1260
int rtdm_sem_down(rtdm_sem_t *sem)
Decrement a semaphore.
Definition: drvlib.c:1059
void rtdm_sem_up(rtdm_sem_t *sem)
Increment a semaphore.
Definition: drvlib.c:1156
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:1097
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:1198
void rtdm_sem_init(rtdm_sem_t *sem, unsigned long value)
Initialise a semaphore.
Definition: drvlib.c:1006
void rtdm_sem_destroy(rtdm_sem_t *sem)
Destroy a semaphore.
Definition: drvlib.c:1031
unsigned long rtdm_lockctx_t
Variable to save the context while holding a lock.
Definition: driver.h:552
static void rtdm_lock_get(rtdm_lock_t *lock)
Acquire lock from non-preemptible contexts.
Definition: driver.h:573
static void rtdm_lock_init(rtdm_lock_t *lock)
Dynamic lock initialisation.
Definition: driver.h:561
static void rtdm_lock_put(rtdm_lock_t *lock)
Release lock without preemption restoration.
Definition: driver.h:587
static void rtdm_lock_put_irqrestore(rtdm_lock_t *lock, rtdm_lockctx_t context)
Release lock and restore preemption state.
Definition: driver.h:624
ipipe_spinlock_t rtdm_lock_t
Lock variable.
Definition: driver.h:549
void rtdm_toseq_init(rtdm_toseq_t *timeout_seq, nanosecs_rel_t timeout)
Initialise a timeout sequence.
Definition: drvlib.c:696
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:111
@ RTDM_SELECTTYPE_EXCEPT
Select exceptional events.
Definition: driver.h:119
@ RTDM_SELECTTYPE_WRITE
Select ouput buffer availability events.
Definition: driver.h:116
@ RTDM_SELECTTYPE_READ
Select input data availability events.
Definition: driver.h:113
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:460
void(* rtdm_task_proc_t)(void *arg)
Real-time task procedure.
Definition: driver.h:1003
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:108
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:483
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:936
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:556
void rtdm_timer_stop(rtdm_timer_t *timer)
Stop a timer.
Definition: drvlib.c:578
void rtdm_timer_destroy(rtdm_timer_t *timer)
Destroy a timer.
Definition: drvlib.c:526
rtdm_timer_mode
Definition: driver.h:943
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:948
@ RTDM_TIMERMODE_REALTIME
Adjustable timer with absolute timeout.
Definition: driver.h:951
@ RTDM_TIMERMODE_RELATIVE
Monotonic timer with relative timeout.
Definition: driver.h:945
int rtdm_munmap(void *ptr, size_t len)
Unmap a user memory range.
Definition: drvlib.c:2110
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:1992
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:2036
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:1923
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_ratelimit(struct rtdm_ratelimit_state *rs, const char *func)
Enforces a rate limit.
Definition: drvlib.c:2132
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:2089
int rtdm_mmap_vmem(struct vm_area_struct *vma, void *va)
Map a virtual memory range to a virtual user area.
Definition: drvlib.c:2061
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:136
char dev_private[0]
Begin of driver defined context data structure.
Definition: driver.h:144
struct rtdm_device * device
Set of active device operation handlers.
Definition: driver.h:141
RTDM device.
Definition: driver.h:338
int minor
Minor number of the device.
Definition: driver.h:369
void * device_data
Driver definable device data.
Definition: driver.h:342
struct rtdm_driver * driver
Device driver.
Definition: driver.h:340
const char * label
Device label template for composing the device name.
Definition: driver.h:354
RTDM driver.
Definition: driver.h:249
struct rtdm_fd_ops ops
I/O operation handlers.
Definition: driver.h:275
int socket_type
Protocol device identification: socket type (SOCK_xxx)
Definition: driver.h:273
int device_flags
Device flags, see Device Flags for details .
Definition: driver.h:260
int base_minor
Base minor for named devices.
Definition: driver.h:284
size_t context_size
Size of the private memory area the core should automatically allocate for each open file descriptor,...
Definition: driver.h:269
int device_count
Count of devices this driver manages.
Definition: driver.h:282
struct rtdm_sm_ops smops
State management handlers.
Definition: driver.h:277
int protocol_family
Protocol device identification: protocol family (PF_xxx)
Definition: driver.h:271
struct rtdm_profile_info profile_info
Class profile information.
Definition: driver.h:255
Definition: fd.h:243
RTDM profile information.
Definition: driver.h:215
int version
Supported device profile version.
Definition: driver.h:224
unsigned int magic
Reserved.
Definition: driver.h:226
int subclass_id
Device sub-class, see RTDM_SUBCLASS_xxx definition in the Device Profiles.
Definition: driver.h:222
const char * name
Device class name.
Definition: driver.h:217
int class_id
Device class ID, see RTDM_CLASS_xxx.
Definition: driver.h:219
RTDM state management handlers.
Definition: driver.h:236
int(* stop)(struct rtdm_driver *drv)
Handler called upon transition to COBALT_STATE_TEARDOWN.
Definition: driver.h:240
int(* start)(struct rtdm_driver *drv)
Handler called upon transition to COBALT_STATE_WARMUP.
Definition: driver.h:238