source: rtems/cpukit/include/rtems/termiostypes.h @ a660e9dc

Last change on this file since a660e9dc was a660e9dc, checked in by Sebastian Huber <sebastian.huber@…>, on 09/08/22 at 08:37:05

Do not use RTEMS_INLINE_ROUTINE

Directly use "static inline" which is available in C99 and later. This brings
the RTEMS implementation closer to standard C.

Close #3935.

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