source: rtems/cpukit/include/rtems/termiostypes.h @ 878487b0

5
Last change on this file since 878487b0 was 2c12262, checked in by Sebastian Huber <sebastian.huber@…>, on 11/28/17 at 05:30:35

termios: Use self-contained objects

Update #2840.

  • Property mode set to 100644
File size: 15.6 KB
Line 
1/**
2 * @file rtems/termiostypes.h
3 *
4 * RTEMS termios device support internal data structures
5 */
6
7/*
8 *  COPYRIGHT (c) 1989-2011.
9 *  On-Line Applications Research Corporation (OAR).
10 *
11 *  The license and distribution terms for this file may be
12 *  found in the file LICENSE in this distribution or at
13 *  http://www.rtems.org/license/LICENSE.
14 */
15
16#ifndef  __TERMIOSTYPES_H
17#define  __TERMIOSTYPES_H
18
19#include <rtems.h>
20#include <rtems/libio.h>
21#include <rtems/assoc.h>
22#include <rtems/chain.h>
23#include <rtems/thread.h>
24#include <sys/ioccom.h>
25#include <stdint.h>
26#include <termios.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32/**
33 *  @defgroup TermiostypesSupport RTEMS Termios Device Support
34 *
35 *  @ingroup libcsupport
36 *
37 *  @brief RTEMS Termios Device Support Internal Data Structures
38 */
39
40/*
41 * Wakeup callback data structure
42 */
43struct ttywakeup {
44  void      (*sw_pfn)(struct termios *tty, void *arg);
45  void      *sw_arg;
46};
47
48/*
49 * Variables associated with the character buffer
50 */
51struct rtems_termios_rawbuf {
52  char *theBuf;
53  volatile unsigned int  Head;
54  volatile unsigned int  Tail;
55  volatile unsigned int  Size;
56  rtems_binary_semaphore Semaphore;
57};
58
59typedef enum {
60  TERMIOS_POLLED,
61  TERMIOS_IRQ_DRIVEN,
62  TERMIOS_TASK_DRIVEN,
63  TERMIOS_IRQ_SERVER_DRIVEN
64} rtems_termios_device_mode;
65
66struct rtems_termios_tty;
67
68/**
69 * @brief Termios device context.
70 *
71 * @see RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER(),
72 * rtems_termios_device_context_initialize() and
73 * rtems_termios_device_install().
74 */
75typedef struct rtems_termios_device_context {
76  union {
77    /* Used for TERMIOS_POLLED and TERMIOS_IRQ_DRIVEN */
78    rtems_interrupt_lock interrupt;
79
80    /* Used for TERMIOS_IRQ_SERVER_DRIVEN or TERMIOS_TASK_DRIVEN */
81    rtems_mutex mutex;
82  } lock;
83
84  void ( *lock_acquire )(
85    struct rtems_termios_device_context *,
86    rtems_interrupt_lock_context *
87  );
88
89  void ( *lock_release )(
90    struct rtems_termios_device_context *,
91    rtems_interrupt_lock_context *
92  );
93} rtems_termios_device_context;
94
95void rtems_termios_device_lock_acquire_default(
96  rtems_termios_device_context *ctx,
97  rtems_interrupt_lock_context *lock_context
98);
99
100void rtems_termios_device_lock_release_default(
101  rtems_termios_device_context *ctx,
102  rtems_interrupt_lock_context *lock_context
103);
104
105/**
106 * @brief Initializes a device context.
107 *
108 * @param[in] context The Termios device context.
109 * @param[in] name The name for the interrupt lock.  This name must be a
110 *   string persistent throughout the life time of this lock.  The name is only
111 *   used if profiling is enabled.
112 */
113RTEMS_INLINE_ROUTINE void rtems_termios_device_context_initialize(
114  rtems_termios_device_context *context,
115  const char                   *name
116)
117{
118  rtems_interrupt_lock_initialize( &context->lock.interrupt, name );
119  context->lock_acquire = rtems_termios_device_lock_acquire_default;
120  context->lock_release = rtems_termios_device_lock_release_default;
121}
122
123/**
124 * @brief Initializer for static initialization of Termios device contexts.
125 *
126 * @param name The name for the interrupt lock.  It must be a string.  The name
127 *   is only used if profiling is enabled.
128 */
129#define RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( name ) \
130  { \
131    { RTEMS_INTERRUPT_LOCK_INITIALIZER( name ) }, \
132    rtems_termios_device_lock_acquire_default, \
133    rtems_termios_device_lock_release_default \
134  }
135
136/**
137 * @brief Termios device handler.
138 *
139 * @see rtems_termios_device_install().
140 */
141typedef struct {
142  /**
143   * @brief First open of this device.
144   *
145   * @param[in] tty The Termios control.  This parameter may be passed to
146   *   interrupt service routines since it must be provided for the
147   *   rtems_termios_enqueue_raw_characters() and
148   *   rtems_termios_dequeue_characters() functions.
149   * @param[in] context The Termios device context.
150   * @param[in] term The current Termios attributes.
151   * @param[in] args The open/close arguments.  This is parameter provided to
152   *   support legacy drivers.  It must not be used by new drivers.
153   *
154   * @retval true Successful operation.
155   * @retval false Cannot open device.
156   *
157   * @see rtems_termios_get_device_context() and rtems_termios_set_best_baud().
158   */
159  bool (*first_open)(
160    struct rtems_termios_tty      *tty,
161    rtems_termios_device_context  *context,
162    struct termios                *term,
163    rtems_libio_open_close_args_t *args
164  );
165
166  /**
167   * @brief Last close of this device.
168   *
169   * @param[in] tty The Termios control.
170   * @param[in] context The Termios device context.
171   * @param[in] args The open/close arguments.  This is parameter provided to
172   *   support legacy drivers.  It must not be used by new drivers.
173   */
174  void (*last_close)(
175    struct rtems_termios_tty      *tty,
176    rtems_termios_device_context  *context,
177    rtems_libio_open_close_args_t *args
178  );
179
180  /**
181   * @brief Polled read.
182   *
183   * In case mode is TERMIOS_IRQ_DRIVEN, TERMIOS_IRQ_SERVER_DRIVEN or
184   * TERMIOS_TASK_DRIVEN, then data is received via
185   * rtems_termios_enqueue_raw_characters().
186   *
187   * @param[in] context The Termios device context.
188   *
189   * @retval char The received data encoded as unsigned char.
190   * @retval -1 No data currently available.
191   */
192  int (*poll_read)(rtems_termios_device_context *context);
193
194  /**
195   * @brief Polled write in case mode is TERMIOS_POLLED or write support
196   * otherwise.
197   *
198   * @param[in] context The Termios device context.
199   * @param[in] buf The output buffer.
200   * @param[in] len The output buffer length in characters.
201   */
202  void (*write)(
203    rtems_termios_device_context *context,
204    const char *buf,
205    size_t len
206  );
207
208  /**
209   * @brief Set attributes after a Termios settings change.
210   *
211   * @param[in] context The Termios device context.
212   * @param[in] term The new Termios attributes.
213   *
214   * @retval true Successful operation.
215   * @retval false Invalid attributes.
216   */
217  bool (*set_attributes)(
218    rtems_termios_device_context *context,
219    const struct termios         *term
220  );
221
222  /**
223   * @brief IO control handler.
224   *
225   * Invoked in case the Termios layer cannot deal with the IO request.
226   *
227   * @param[in] context The Termios device context.
228   * @param[in] request The IO control request.
229   * @param[in] buffer The IO control buffer.
230   */
231  int (*ioctl)(
232    rtems_termios_device_context *context,
233    ioctl_command_t               request,
234    void                         *buffer
235  );
236
237  /**
238   * @brief Termios device mode.
239   */
240  rtems_termios_device_mode mode;
241} rtems_termios_device_handler;
242
243/**
244 * @brief Termios device flow control handler.
245 *
246 * @see rtems_termios_device_install().
247 */
248typedef struct {
249  /**
250   * @brief Indicate to stop remote transmitter.
251   *
252   * @param[in] context The Termios device context.
253   */
254  void (*stop_remote_tx)(rtems_termios_device_context *context);
255
256  /**
257   * @brief Indicate to start remote transmitter.
258   *
259   * @param[in] context The Termios device context.
260   */
261  void (*start_remote_tx)(rtems_termios_device_context *context);
262} rtems_termios_device_flow;
263
264/**
265 * @brief Termios device node for installed devices.
266 *
267 * @see rtems_termios_device_install().
268 */
269typedef struct rtems_termios_device_node {
270  rtems_chain_node                    node;
271  rtems_device_major_number           major;
272  rtems_device_minor_number           minor;
273  const rtems_termios_device_handler *handler;
274  const rtems_termios_device_flow    *flow;
275  rtems_termios_device_context       *context;
276  struct rtems_termios_tty           *tty;
277} rtems_termios_device_node;
278
279/*
280 * Variables associated with each termios instance.
281 * One structure for each hardware I/O device.
282 */
283typedef struct rtems_termios_tty {
284  /*
285   * Linked-list of active TERMIOS devices
286   */
287  struct rtems_termios_tty  *forw;
288  struct rtems_termios_tty  *back;
289
290  /*
291   * How many times has this device been opened
292   */
293  int    refcount;
294
295  /*
296   * This device
297   */
298  rtems_device_major_number  major;
299  rtems_device_minor_number  minor;
300
301  /*
302   * Mutual-exclusion semaphores
303   */
304  rtems_mutex isem;
305  rtems_mutex osem;
306
307  /*
308   * The canonical (cooked) character buffer
309   */
310  char    *cbuf;
311  int    ccount;
312  int    cindex;
313
314  /*
315   * Keep track of cursor (printhead) position
316   */
317  int    column;
318  int    read_start_column;
319
320  /*
321   * The ioctl settings
322   */
323  struct termios  termios;
324  rtems_interval  vtimeTicks;
325
326  /*
327   * Raw input character buffer
328   */
329  struct rtems_termios_rawbuf rawInBuf;
330  bool                        rawInBufSemaphoreWait;
331  rtems_interval              rawInBufSemaphoreTimeout;
332  rtems_interval              rawInBufSemaphoreFirstTimeout;
333  unsigned int                rawInBufDropped;  /* Statistics */
334
335  /*
336   * Raw output character buffer
337   */
338  struct rtems_termios_rawbuf rawOutBuf;
339  int  t_dqlen; /* count of characters dequeued from device */
340  enum {rob_idle, rob_busy, rob_wait }  rawOutBufState;
341
342  /*
343   * Callbacks to device-specific routines
344   */
345  rtems_termios_callbacks  device;
346
347  /**
348   * @brief Context for legacy devices using the callbacks.
349   */
350  rtems_termios_device_context legacy_device_context;
351
352  /**
353   * @brief The device handler.
354   */
355  rtems_termios_device_handler handler;
356
357  /**
358   * @brief The device flow control handler.
359   */
360  rtems_termios_device_flow flow;
361
362  volatile unsigned int    flow_ctrl;
363  unsigned int             lowwater,highwater;
364
365  /*
366   * I/O task IDs (for task-driven drivers)
367   */
368  rtems_id                rxTaskId;
369  rtems_id                txTaskId;
370
371  /*
372   * line discipline related stuff
373   */
374  int t_line;   /* id of line discipline                       */
375  void *t_sc;   /* hook for discipline-specific data structure */
376
377  /*
378   * Wakeup callback variables
379   */
380  struct ttywakeup tty_snd;
381  struct ttywakeup tty_rcv;
382  bool             tty_rcvwakeup;
383
384  /**
385   * @brief Corresponding device node.
386   */
387  rtems_termios_device_node *device_node;
388
389  /**
390   * @brief Context for device driver.
391   */
392  rtems_termios_device_context *device_context;
393} rtems_termios_tty;
394
395/**
396 * @brief Installs a Termios device.
397 *
398 * The installed Termios device may be removed via unlink().
399 *
400 * @param[in] device_file The device file path.
401 * @param[in] handler The device handler.  It must be persistent throughout the
402 *   installed time of the device.
403 * @param[in] flow The device flow control handler.  The device flow control
404 *   handler are optional and may be @c NULL.  If present must be persistent
405 *   throughout the installed time of the device.
406 * @param[in] context The device context.  It must be persistent throughout the
407 *   installed time of the device.
408 *
409 * @retval RTEMS_SUCCESSFUL Successful operation.
410 * @retval RTEMS_NO_MEMORY Not enough memory to create a device node.
411 * @retval RTEMS_UNSATISFIED Creation of the device file failed.
412 * @retval RTEMS_INCORRECT_STATE Termios is not initialized.
413 *
414 * @see rtems_termios_get_device_context().
415 */
416rtems_status_code rtems_termios_device_install(
417  const char                         *device_file,
418  const rtems_termios_device_handler *handler,
419  const rtems_termios_device_flow    *flow,
420  rtems_termios_device_context       *context
421);
422
423/**
424 * @brief Returns the device context of an installed Termios device.
425 *
426 * @param[in] tty The Termios control.
427 */
428RTEMS_INLINE_ROUTINE void *rtems_termios_get_device_context(
429  const rtems_termios_tty *tty
430)
431{
432  return tty->device_context;
433}
434
435/**
436 * @brief Acquires the device lock.
437 *
438 * @param[in] context The device context.
439 * @param[in] lock_context The local interrupt lock context for an acquire and
440 *   release pair.
441 */
442RTEMS_INLINE_ROUTINE void rtems_termios_device_lock_acquire(
443  rtems_termios_device_context *context,
444  rtems_interrupt_lock_context *lock_context
445)
446{
447  ( *context->lock_acquire )( context, lock_context );
448}
449
450/**
451 * @brief Releases the device lock.
452 *
453 * @param[in] context The device context.
454 * @param[in] lock_context The local interrupt lock context for an acquire and
455 *   release pair.
456 */
457RTEMS_INLINE_ROUTINE void rtems_termios_device_lock_release(
458  rtems_termios_device_context *context,
459  rtems_interrupt_lock_context *lock_context
460)
461{
462  ( *context->lock_release )( context, lock_context );
463}
464
465/**
466 * @brief Sets the best baud value in the Termios control.
467 *
468 * The valid Termios baud values are between 0 and 460800.  The Termios baud
469 * value is chosen which minimizes the difference to the value specified.
470 *
471 * @param[in] term The Termios attributes.
472 * @param[in] baud The current baud setting of the device.
473 */
474void rtems_termios_set_best_baud(
475  struct termios *term,
476  uint32_t        baud
477);
478
479struct rtems_termios_linesw {
480  int (*l_open) (struct rtems_termios_tty *tp);
481  int (*l_close)(struct rtems_termios_tty *tp);
482  int (*l_read )(struct rtems_termios_tty *tp,rtems_libio_rw_args_t *args);
483  int (*l_write)(struct rtems_termios_tty *tp,rtems_libio_rw_args_t *args);
484  int (*l_rint )(int c,struct rtems_termios_tty *tp);
485  int (*l_start)(struct rtems_termios_tty *tp);
486  int (*l_ioctl)(struct rtems_termios_tty *tp,rtems_libio_ioctl_args_t *args);
487  int (*l_modem)(struct rtems_termios_tty *tp,int flags);
488};
489
490/*
491 * FIXME: this should move to termios.h!
492 */
493void rtems_termios_rxirq_occured(struct rtems_termios_tty *tty);
494
495/*
496 * FIXME: this should move to termios.h!
497 * put a string to output ring buffer
498 */
499void rtems_termios_puts (
500  const void               *buf,
501  size_t                    len,
502  struct rtems_termios_tty *tty
503);
504
505/*
506 * global hooks for line disciplines
507 */
508extern struct rtems_termios_linesw rtems_termios_linesw[];
509extern int   rtems_termios_nlinesw;
510
511#define TTYDISC   0    /* termios tty line discipline */
512#define TABLDISC  3    /* tablet discipline */
513#define SLIPDISC  4    /* serial IP discipline */
514#define PPPDISC   5    /* PPP discipline */
515#define MAXLDISC  8
516
517/* baudrate xxx integer type */
518typedef uint32_t rtems_termios_baud_t;
519
520/**
521 *  @brief RTEMS Termios Baud Table
522 */
523extern const rtems_assoc_t rtems_termios_baud_table [];
524
525/**
526 *  @brief Converts the Integral Baud value @a baud to the Termios Control Flag
527 *  Representation
528 *
529 *  @retval B0 Invalid baud value or a baud value of 0.
530 *  @retval other Baud constant according to @a baud.
531 */
532speed_t rtems_termios_number_to_baud(rtems_termios_baud_t baud);
533
534/**
535 *  @brief Converts the baud flags to an integral baud value.
536 *
537 *  @retval 0 Invalid baud value or a baud value of @c B0.
538 *  @retval other Integral baud value.
539 */
540rtems_termios_baud_t rtems_termios_baud_to_number(speed_t baud);
541
542/**
543 *  @brief Convert Bxxx Constant to Index
544 */
545int  rtems_termios_baud_to_index(rtems_termios_baud_t termios_baud);
546
547/**
548 * @brief Sets the initial @a baud in the Termios context @a tty.
549 *
550 * @retval 0 Successful operation.
551 * @retval -1 Invalid baud value.
552 */
553int rtems_termios_set_initial_baud(
554  struct rtems_termios_tty *tty,
555  rtems_termios_baud_t baud
556);
557
558/**
559 * @brief Termios kqueue() filter filesystem node handler
560 *
561 * Real implementation is provided by libbsd.
562 */
563int rtems_termios_kqfilter(
564  rtems_libio_t *iop,
565  struct knote  *kn
566);
567
568/**
569 * @brief Termios mmap() filter filesystem node handler
570 *
571 * Real implementation is provided by libbsd.
572 */
573int rtems_termios_mmap(
574  rtems_libio_t *iop,
575  void         **addr,
576  size_t         len,
577  int            prot,
578  off_t          off
579);
580
581/**
582 * @brief Termios poll() filesystem node handler.
583 *
584 * Real implementation is provided by libbsd.
585 */
586int rtems_termios_poll(
587  rtems_libio_t *iop,
588  int            events
589);
590
591#define RTEMS_IO_SNDWAKEUP _IOW('t', 11, struct ttywakeup ) /* send tty wakeup */
592#define RTEMS_IO_RCVWAKEUP _IOW('t', 12, struct ttywakeup ) /* recv tty wakeup */
593
594#define OLCUC           0x00000100      /* map lower case to upper case on output */
595#define IUCLC           0x00004000      /* map upper case to lower case on input */
596
597#define RTEMS_TERMIOS_NUMBER_BAUD_RATES 25
598
599extern rtems_mutex rtems_termios_ttyMutex;
600
601#ifdef __cplusplus
602}
603#endif
604
605#endif  /* TERMIOSTYPES_H */
Note: See TracBrowser for help on using the repository browser.