source: rtems/testsuites/libtests/termios01/init.c @ 610b9ef1

5
Last change on this file since 610b9ef1 was 7fd5e89, checked in by Sebastian Huber <sebastian.huber@…>, on 10/07/14 at 14:28:04

termios: Partially hide rtems_termios_tty

Move interrupt lock to device context and expose only this structure to
the read, write and set attributes device handler. This makes these
device handler independent of the general Termios infrastructure
suitable for direct use in printk() support.

  • Property mode set to 100644
File size: 23.9 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2010.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.org/license/LICENSE.
8 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif
13
14#include "tmacros.h"
15#include <termios.h>
16#include <rtems/libcsupport.h>
17#include <rtems/malloc.h>
18#include <rtems/termiostypes.h>
19#include <fcntl.h>
20#include <limits.h>
21#include <sys/errno.h>
22
23const char rtems_test_name[] = "TERMIOS 1";
24
25/* rtems_termios_baud_t is a typedefs to int32_t */
26#define PRIdrtems_termios_baud_t PRId32
27
28/*
29 *  Termios Test Driver
30 */
31#include "termios_testdriver.h"
32
33static const rtems_driver_address_table test_driver =
34  TERMIOS_TEST_DRIVER_TABLE_ENTRY;
35
36/*
37 *  Baud Rate Constant Mapping Entry
38 */
39typedef struct {
40  tcflag_t constant;
41  rtems_termios_baud_t baud;
42} termios_baud_test_r;
43
44#define INVALID_CONSTANT ((tcflag_t) -2)
45
46#define INVALID_BAUD ((rtems_termios_baud_t) -2)
47/*
48 *  Baud Rate Constant Mapping Table
49 */
50static const termios_baud_test_r baud_table[] = {
51  { B0,           0 },
52  { B50,         50 },
53  { B75,         75 },
54  { B110,       110 },
55  { B134,       134 },
56  { B150,       150 },
57  { B200,       200 },
58  { B300,       300 },
59  { B600,       600 },
60  { B1200,     1200 },
61  { B1800,     1800 },
62  { B2400,     2400 },
63  { B4800,     4800 },
64  { B9600,     9600 },
65  { B19200,   19200 },
66  { B38400,   38400 },
67  { B57600,   57600 },
68  { B115200, 115200 },
69  { B230400, 230400 },
70  { B460800, 460800 },
71  { INVALID_CONSTANT, INVALID_BAUD }
72};
73
74/*
75 *  Character Size Constant Mapping Entry
76 */
77typedef struct {
78  tcflag_t constant;
79  int bits;
80} termios_character_size_test_r;
81
82/*
83 *  Character Size Constant Mapping Table
84 */
85static const termios_character_size_test_r char_size_table[] = {
86  { CS5,      5 },
87  { CS6,      6 },
88  { CS7,      7 },
89  { CS8,      8 },
90  { INVALID_CONSTANT, -1 }
91};
92
93/*
94 *  Parity Constant Mapping Entry
95 */
96typedef struct {
97  tcflag_t constant;
98  const char *parity;
99} termios_parity_test_r;
100
101/*
102 *  Parity Constant Mapping Table
103 */
104static const termios_parity_test_r parity_table[] = {
105  { 0,                "none" },
106  { PARENB,           "even" },
107  { PARENB | PARODD,  "odd" },
108  { INVALID_CONSTANT, NULL }
109};
110
111/*
112 *  Stop Bit Constant Mapping Entry
113 */
114typedef struct {
115  tcflag_t constant;
116  int stop;
117} termios_stop_bits_test_r;
118
119/*
120 *  Stop Bit Constant Mapping Table
121 */
122static const termios_stop_bits_test_r stop_bits_table[] = {
123  { 0,       1 },
124  { CSTOPB,  2 },
125  { INVALID_CONSTANT, -1 }
126};
127
128/*
129 *  Test converting baud rate into an index
130 */
131static void test_termios_baud2index(void)
132{
133  int i;
134  int index;
135
136  puts( "Test termios_baud2index..." );
137  puts( "termios_baud_to_index(-2) - NOT OK" );
138  i = rtems_termios_baud_to_index( INVALID_CONSTANT );
139  rtems_test_assert( i == -1 );
140
141  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
142    printf(
143      "termios_baud_to_index(B%" PRIdrtems_termios_baud_t ") - OK\n",
144      baud_table[i].baud
145    );
146    index = rtems_termios_baud_to_index( baud_table[i].constant );
147    if ( index != i ) {
148      printf( "ERROR - returned %d should be %d\n", index, i );
149      rtems_test_exit(0);
150    }
151  }
152}
153
154/*
155 *  Test converting termios baud constant to baud number
156 */
157static void test_termios_baud2number(void)
158{
159  int i;
160  rtems_termios_baud_t number;
161
162  puts(
163    "\n"
164    "Test termios_baud2number..."
165  );
166  puts( "termios_baud_to_number(-2) - NOT OK" );
167  number = rtems_termios_baud_to_number( INVALID_CONSTANT );
168  rtems_test_assert( number == 0 );
169
170  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
171    printf(
172      "termios_baud_to_number(B%" PRIdrtems_termios_baud_t ") - OK\n",
173      baud_table[i].baud
174    );
175    number = rtems_termios_baud_to_number( baud_table[i].constant );
176    if ( number != baud_table[i].baud ) {
177      printf(
178        "ERROR - returned %" PRIdrtems_termios_baud_t
179        " should be %" PRIdrtems_termios_baud_t "\n",
180        number,
181        baud_table[i].baud
182      );
183      rtems_test_exit(0);
184    }
185  }
186}
187
188/*
189 *  Test converting baud number to termios baud constant
190 */
191static void test_termios_number_to_baud(void)
192{
193  int i;
194  tcflag_t termios_baud;
195
196  puts(
197    "\n"
198    "Test termios_number_to_baud..."
199  );
200  puts( "termios_number_to_baud(-2) - NOT OK" );
201  termios_baud = rtems_termios_number_to_baud( INVALID_BAUD );
202  rtems_test_assert( termios_baud == 0 );
203
204  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
205    printf(
206      "termios_number_to_baud(B%" PRIdrtems_termios_baud_t ") - OK\n",
207      baud_table[i].baud
208    );
209    termios_baud = rtems_termios_number_to_baud( baud_table[i].baud );
210    if ( termios_baud != baud_table[i].constant ) {
211      printf(
212        "ERROR - returned %d should be %d\n",
213        termios_baud,
214        baud_table[i].constant
215      );
216      rtems_test_exit(0);
217    }
218  }
219}
220
221/*
222 *  Test all the baud rate options
223 */
224static void test_termios_set_baud(
225  int test
226)
227{
228  int             sc;
229  int             i;
230  struct termios  attr;
231
232  puts( "Test termios setting device baud rate..." );
233  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
234    tcflag_t cbaud = CBAUD;
235
236    sc = tcgetattr( test, &attr );
237    if ( sc != 0 ) {
238      printf( "ERROR - return %d\n", sc );
239      rtems_test_exit(0);
240    }
241
242    attr.c_cflag &= ~cbaud;
243    attr.c_cflag |= baud_table[i].constant;
244
245    printf(
246      "tcsetattr(TCSANOW, B%" PRIdrtems_termios_baud_t ") - OK\n",
247      baud_table[i].baud
248    );
249    sc = tcsetattr( test, TCSANOW, &attr );
250    if ( sc != 0 ) {
251      printf( "ERROR - return %d\n", sc );
252      rtems_test_exit(0);
253    }
254
255    printf(
256      "tcsetattr(TCSADRAIN, B%" PRIdrtems_termios_baud_t ") - OK\n",
257      baud_table[i].baud
258    );
259    sc = tcsetattr( test, TCSANOW, &attr );
260    if ( sc != 0 ) {
261      printf( "ERROR - return %d\n", sc );
262      rtems_test_exit(0);
263    }
264  }
265}
266
267/*
268 *  Test all the character size options
269 */
270static void test_termios_set_charsize(
271  int test
272)
273{
274  int             sc;
275  int             i;
276  struct termios  attr;
277
278  puts(
279    "\n"
280    "Test termios setting device character size ..."
281  );
282  for (i=0 ; char_size_table[i].constant != INVALID_CONSTANT ; i++ ) {
283    tcflag_t csize = CSIZE;
284
285    sc = tcgetattr( test, &attr );
286    if ( sc != 0 ) {
287      printf( "ERROR - return %d\n", sc );
288      rtems_test_exit(0);
289    }
290
291    attr.c_cflag &= ~csize;
292    attr.c_cflag |= char_size_table[i].constant;
293
294    printf( "tcsetattr(TCSANOW, CS%d) - OK\n", char_size_table[i].bits );
295    sc = tcsetattr( test, TCSANOW, &attr );
296    if ( sc != 0 ) {
297      printf( "ERROR - return %d\n", sc );
298      rtems_test_exit(0);
299    }
300
301    printf( "tcsetattr(TCSADRAIN, CS%d) - OK\n", char_size_table[i].bits );
302    sc = tcsetattr( test, TCSANOW, &attr );
303    if ( sc != 0 ) {
304      printf( "ERROR - return %d\n", sc );
305      rtems_test_exit(0);
306    }
307  }
308}
309
310/*
311 *  Test all the parity options
312 */
313static void test_termios_set_parity(
314  int test
315)
316{
317  int             sc;
318  int             i;
319  struct termios  attr;
320
321  puts(
322    "\n"
323    "Test termios setting device parity ..."
324  );
325  for (i=0 ; parity_table[i].constant != INVALID_CONSTANT ; i++ ) {
326    tcflag_t par = PARENB | PARODD;
327
328    sc = tcgetattr( test, &attr );
329    if ( sc != 0 ) {
330      printf( "ERROR - return %d\n", sc );
331      rtems_test_exit(0);
332    }
333
334    attr.c_cflag &= ~par;
335    attr.c_cflag |= parity_table[i].constant;
336
337    printf( "tcsetattr(TCSANOW, %s) - OK\n", parity_table[i].parity );
338    sc = tcsetattr( test, TCSANOW, &attr );
339    if ( sc != 0 ) {
340      printf( "ERROR - return %d\n", sc );
341      rtems_test_exit(0);
342    }
343
344    printf( "tcsetattr(TCSADRAIN, %s) - OK\n", parity_table[i].parity );
345    sc = tcsetattr( test, TCSANOW, &attr );
346    if ( sc != 0 ) {
347      printf( "ERROR - return %d\n", sc );
348      rtems_test_exit(0);
349    }
350  }
351}
352
353/*
354 *  Test all the stop bit options
355 */
356static void test_termios_set_stop_bits(
357  int test
358)
359{
360  int             sc;
361  int             i;
362  struct termios  attr;
363
364  puts(
365    "\n"
366    "Test termios setting device character size ..."
367  );
368  for (i=0 ; stop_bits_table[i].constant != INVALID_CONSTANT ; i++ ) {
369    tcflag_t cstopb = CSTOPB;
370
371    sc = tcgetattr( test, &attr );
372    if ( sc != 0 ) {
373      printf( "ERROR - return %d\n", sc );
374      rtems_test_exit(0);
375    }
376
377    attr.c_cflag &= ~cstopb;
378    attr.c_cflag |= stop_bits_table[i].constant;
379
380    printf( "tcsetattr(TCSANOW, %d bit%s) - OK\n",
381      stop_bits_table[i].stop,
382      ((stop_bits_table[i].stop == 1) ? "" : "s")
383    );
384    sc = tcsetattr( test, TCSANOW, &attr );
385    if ( sc != 0 ) {
386      printf( "ERROR - return %d\n", sc );
387      rtems_test_exit(0);
388    }
389
390    printf( "tcsetattr(TCSADRAIN, %d bits) - OK\n", stop_bits_table[i].stop );
391    sc = tcsetattr( test, TCSANOW, &attr );
392    if ( sc != 0 ) {
393      printf( "ERROR - return %d\n", sc );
394      rtems_test_exit(0);
395    }
396  }
397}
398
399static void test_termios_cfoutspeed(void)
400{
401  int i;
402  int sc;
403  speed_t speed;
404  struct termios term;
405  tcflag_t        bad;
406
407  bad = CBAUD << 1;
408  memset( &term, '\0', sizeof(term) );
409  puts( "cfsetospeed(BAD BAUD) - EINVAL" );
410  sc = cfsetospeed( &term, bad );
411  rtems_test_assert( sc == -1 );
412  rtems_test_assert( errno == EINVAL );
413
414  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
415    memset( &term, '\0', sizeof(term) );
416    printf(
417      "cfsetospeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
418      baud_table[i].baud
419    );
420    sc = cfsetospeed( &term, baud_table[i].constant );
421    rtems_test_assert( !sc );
422    printf(
423      "cfgetospeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
424      baud_table[i].baud
425    );
426    speed = cfgetospeed( &term );
427    rtems_test_assert( speed == baud_table[i].constant );
428  }
429}
430
431static void test_termios_cfinspeed(void)
432{
433  int             i;
434  int             sc;
435  speed_t         speed;
436  struct termios  term;
437  tcflag_t        bad;
438
439  bad = CBAUD << 1;
440  memset( &term, '\0', sizeof(term) );
441  puts( "cfsetispeed(BAD BAUD) - EINVAL" );
442  sc = cfsetispeed( &term, bad );
443  rtems_test_assert( sc == -1 );
444  rtems_test_assert( errno == EINVAL );
445
446  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
447    memset( &term, '\0', sizeof(term) );
448    printf(
449      "cfsetispeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
450      baud_table[i].baud
451    );
452    sc = cfsetispeed( &term, baud_table[i].constant );
453    rtems_test_assert( !sc );
454
455    printf(
456      "cfgetispeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
457      baud_table[i].baud
458    );
459    speed = cfgetispeed( &term );
460    rtems_test_assert( speed == baud_table[i].constant );
461  }
462}
463
464static void test_termios_cfsetspeed(void)
465{
466  int             i;
467  int             status;
468  speed_t         speed;
469  struct termios  term;
470  tcflag_t        bad;
471
472  bad = CBAUD << 1;
473  memset( &term, '\0', sizeof(term) );
474  puts( "cfsetspeed(BAD BAUD) - EINVAL" );
475  status = cfsetspeed( &term, bad );
476  rtems_test_assert( status == -1 );
477  rtems_test_assert( errno == EINVAL );
478
479  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
480    memset( &term, '\0', sizeof(term) );
481    printf(
482      "cfsetspeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
483      baud_table[i].baud
484    );
485    status = cfsetspeed( &term, baud_table[i].constant );
486    rtems_test_assert( !status );
487
488    printf(
489      "cfgetspeed(B%" PRIdrtems_termios_baud_t ") - checking both inspeed and outspeed - OK\n",
490      baud_table[i].baud
491    );
492    speed = cfgetispeed( &term );
493    rtems_test_assert( speed == baud_table[i].constant );
494
495    speed = cfgetospeed( &term );
496    rtems_test_assert( speed == baud_table[i].constant );
497  }
498}
499
500static void test_termios_cfmakeraw(void)
501{
502  struct termios  term;
503
504  memset( &term, '\0', sizeof(term) );
505  cfmakeraw( &term );
506  puts( "cfmakeraw - OK" );
507
508  /* Check that all of the flags were set correctly */
509  rtems_test_assert( ~(term.c_iflag & (IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON)) );
510
511  rtems_test_assert( ~(term.c_oflag & OPOST) );
512
513  rtems_test_assert( ~(term.c_lflag & (ECHO|ECHONL|ICANON|ISIG|IEXTEN)) );
514
515  rtems_test_assert( ~(term.c_cflag & (CSIZE|PARENB)) );
516
517  rtems_test_assert( term.c_cflag & CS8 );
518}
519
520typedef struct {
521  rtems_termios_device_context base;
522  bool done;
523} device_context;
524
525static rtems_status_code test_early_device_install_remove(
526  rtems_device_major_number major,
527  rtems_device_minor_number minor,
528  void *arg
529)
530{
531  rtems_resource_snapshot snapshot;
532  rtems_status_code sc;
533
534  rtems_resource_snapshot_take( &snapshot );
535
536  sc = rtems_termios_device_install( "/", 0, 0, NULL, NULL, NULL );
537  rtems_test_assert( sc == RTEMS_INCORRECT_STATE );
538
539  sc = rtems_termios_device_remove( "/", 0, 0 );
540  rtems_test_assert( sc == RTEMS_INCORRECT_STATE );
541
542  rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
543
544  return RTEMS_SUCCESSFUL;
545}
546
547static void test_device_install_remove(void)
548{
549  static const rtems_termios_device_handler handler;
550  static const rtems_device_major_number major = 123456789;
551  static const rtems_device_minor_number minor = 0xdeadbeef;
552  static const char dev[] = "/foobar";
553
554  rtems_resource_snapshot snapshot;
555  rtems_status_code sc;
556  void *greedy;
557  rtems_libio_t iop;
558  rtems_libio_open_close_args_t args;
559
560  memset( &iop, 0, sizeof( iop ) );
561  memset( &args, 0, sizeof( args ) );
562  args.iop = &iop;
563
564  rtems_resource_snapshot_take( &snapshot );
565
566  greedy = rtems_heap_greedy_allocate( NULL, 0 );
567
568  sc = rtems_termios_device_install( "/", major, minor, &handler, NULL, NULL );
569  rtems_test_assert( sc == RTEMS_NO_MEMORY );
570
571  rtems_heap_greedy_free( greedy );
572
573  rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
574
575  sc = rtems_termios_device_install(
576    NULL,
577    major,
578    minor,
579    &handler,
580    NULL,
581    NULL
582  );
583  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
584
585  sc = rtems_termios_device_install(
586    NULL,
587    major,
588    minor,
589    &handler,
590    NULL,
591    NULL
592  );
593  rtems_test_assert( sc == RTEMS_RESOURCE_IN_USE );
594
595  sc = rtems_termios_device_remove( NULL, major, minor );
596  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
597
598  rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
599
600  sc = rtems_termios_device_install( "/", major, minor, &handler, NULL, NULL );
601  rtems_test_assert( sc == RTEMS_UNSATISFIED );
602
603  rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
604
605  sc = rtems_termios_device_remove( NULL, major, minor );
606  rtems_test_assert( sc == RTEMS_INVALID_ID );
607
608  sc = rtems_termios_device_install(
609    &dev[0],
610    major,
611    minor,
612    &handler,
613    NULL,
614    NULL
615  );
616  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
617
618  sc = rtems_termios_device_remove( "/barfoo", major, minor );
619  rtems_test_assert( sc == RTEMS_UNSATISFIED );
620
621  sc = rtems_termios_device_open( major, minor, &args );
622  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
623
624  sc = rtems_termios_device_remove( &dev[0], major, minor );
625  rtems_test_assert( sc == RTEMS_RESOURCE_IN_USE );
626
627  sc = rtems_termios_device_close( &args );
628  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
629
630  sc = rtems_termios_device_remove( &dev[0], major, minor );
631  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
632
633  rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
634}
635
636static bool first_open_error(
637  rtems_termios_tty *tty,
638  rtems_termios_device_context *base,
639  struct termios *term,
640  rtems_libio_open_close_args_t *args
641)
642{
643  device_context *ctx = (device_context *) base;
644
645  (void) tty;
646  (void) term;
647  (void) args;
648
649  ctx->done = true;
650
651  return false;
652}
653
654static void test_first_open_error(void)
655{
656  static const rtems_termios_device_handler handler = {
657    .first_open = first_open_error
658  };
659  static const rtems_device_major_number major = 123456789;
660  static const rtems_device_minor_number minor = 0xdeadbeef;
661  static const char dev[] = "/foobar";
662
663  rtems_resource_snapshot snapshot;
664  rtems_status_code sc;
665  rtems_libio_t iop;
666  rtems_libio_open_close_args_t args;
667  device_context ctx = {
668    .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "abc" ),
669    .done = false
670  };
671
672  rtems_resource_snapshot_take( &snapshot );
673
674  sc = rtems_termios_device_install(
675    &dev[0],
676    major,
677    minor,
678    &handler,
679    NULL,
680    &ctx.base
681  );
682  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
683
684  memset( &iop, 0, sizeof( iop ) );
685  memset( &args, 0, sizeof( args ) );
686  args.iop = &iop;
687
688  rtems_test_assert( !ctx.done );
689  sc = rtems_termios_device_open( major, minor, &args );
690  rtems_test_assert( sc == RTEMS_NO_MEMORY );
691  rtems_test_assert( ctx.done );
692
693  sc = rtems_termios_device_remove( &dev[0], major, minor );
694  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
695
696  rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
697}
698
699static bool set_attributes_error(
700  rtems_termios_device_context *base,
701  const struct termios *term
702)
703{
704  device_context *ctx = (device_context *) base;
705
706  (void) term;
707
708  ctx->done = true;
709
710  return false;
711}
712
713static void test_set_attributes_error(void)
714{
715  static const rtems_termios_device_handler handler = {
716    .set_attributes = set_attributes_error
717  };
718  static const rtems_device_major_number major = 123456789;
719  static const rtems_device_minor_number minor = 0xdeadbeef;
720  static const char dev[] = "/foobar";
721
722  rtems_resource_snapshot snapshot;
723  rtems_status_code sc;
724  rtems_libio_t iop;
725  rtems_libio_open_close_args_t oc_args;
726  rtems_libio_ioctl_args_t io_args;
727  struct termios term;
728  device_context ctx = {
729    .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "abc" ),
730    .done = false
731  };
732
733  rtems_resource_snapshot_take( &snapshot );
734
735  sc = rtems_termios_device_install(
736    &dev[0],
737    major,
738    minor,
739    &handler,
740    NULL,
741    &ctx.base
742  );
743  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
744
745  memset( &iop, 0, sizeof( iop ) );
746  memset( &oc_args, 0, sizeof( oc_args ) );
747  oc_args.iop = &iop;
748
749  sc = rtems_termios_device_open( major, minor, &oc_args );
750  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
751
752  memset( &io_args, 0, sizeof( io_args ) );
753  io_args.iop = &iop;
754  io_args.command = RTEMS_IO_SET_ATTRIBUTES;
755  io_args.buffer = &term;
756
757  rtems_test_assert( !ctx.done );
758  sc = rtems_termios_ioctl( &io_args );
759  rtems_test_assert( sc == RTEMS_IO_ERROR );
760  rtems_test_assert( ctx.done );
761
762  sc = rtems_termios_device_close( &oc_args );
763  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
764
765  sc = rtems_termios_device_remove( &dev[0], major, minor );
766  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
767
768  rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
769}
770
771static void test_set_best_baud(void)
772{
773  static const struct {
774    uint32_t baud;
775    tcflag_t cflag;
776  } baud_to_cflag_table[] = {
777    { 0,          B0 },
778    { 25,         B0 },
779    { 26,         B50 },
780    { 50,         B50 },
781    { 62,         B50 },
782    { 63,         B75 },
783    { 75,         B75 },
784    { 110,        B110 },
785    { 134,        B134 },
786    { 150,        B150 },
787    { 200,        B200 },
788    { 300,        B300 },
789    { 600,        B600 },
790    { 1200,       B1200 },
791    { 1800,       B1800 },
792    { 2400,       B2400 },
793    { 4800,       B4800 },
794    { 9600,       B9600 },
795    { 19200,      B19200 },
796    { 38400,      B38400 },
797    { 57600,      B57600 },
798    { 115200,     B115200 },
799    { 230400,     B230400 },
800    { 460800,     B460800 },
801    { 0xffffffff, B460800 }
802  };
803
804  size_t n = RTEMS_ARRAY_SIZE(baud_to_cflag_table);
805  size_t i;
806
807  for ( i = 0; i < n; ++i ) {
808    struct termios term;
809    tcflag_t cbaud_mask = CBAUD;
810
811    memset( &term, 0xff, sizeof( term ) );
812    rtems_termios_set_best_baud( &term, baud_to_cflag_table[ i ].baud );
813
814    rtems_test_assert(
815      (term.c_cflag & cbaud_mask) == baud_to_cflag_table[ i ].cflag
816    );
817  }
818}
819
820static rtems_task Init(
821  rtems_task_argument ignored
822)
823{
824  int                       rc;
825  rtems_status_code         sc;
826  rtems_device_major_number registered;
827  int                       test;
828  struct termios            t;
829  int index = 0;
830
831  TEST_BEGIN();
832
833  test_termios_baud2index();
834  test_termios_baud2number();
835  test_termios_number_to_baud();
836
837  sc = rtems_termios_bufsize( 256, 128, 64 );
838  directive_failed( sc, "rtems_termios_bufsize" );
839
840  /*
841   * Register a driver
842   */
843  puts(
844    "\n"
845    "Init - rtems_io_register_driver - Termios Test Driver - OK"
846  );
847  sc = rtems_io_register_driver( 0, &test_driver, &registered );
848  printf( "Init - Major slot returned = %d\n", (int) registered );
849  directive_failed( sc, "rtems_io_register_driver" );
850
851  /*
852   * Test baud rate
853   */
854  puts( "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
855  test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
856  if ( test == -1 ) {
857    printf( "ERROR - baud opening test device (%d)\n", test );
858    rtems_test_exit(0);
859  }
860
861  /*
862   * tcsetattr - ERROR invalid operation
863   */
864  puts( "tcsetattr - invalid operation - ENOTSUP" );
865  rc = tcsetattr( test, INT_MAX, &t );
866  rtems_test_assert( rc == -1 );
867  rtems_test_assert( errno == ENOTSUP );
868
869  test_termios_cfmakeraw();
870 
871  /*
872   * tcsetattr - TCSADRAIN
873   */
874  puts( "\ntcsetattr - drain - OK" );
875  rc = tcsetattr( test, TCSADRAIN, &t );
876  rtems_test_assert( rc == 0 );
877
878  test_termios_set_baud(test);
879
880  puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
881  rc = close( test );
882  if ( rc != 0 ) {
883    printf( "ERROR - baud close test device (%d) %s\n", test, strerror(errno) );
884    rtems_test_exit(0);
885  }
886
887  /*
888   * Test character size
889   */
890  puts(
891    "\n"
892    "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK"
893  );
894  test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
895  if ( test == -1 ) {
896    printf( "ERROR - size open test device (%d) %s\n", test, strerror(errno) );
897    rtems_test_exit(0);
898  }
899
900  test_termios_set_charsize(test);
901
902  puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
903  rc = close( test );
904  if ( rc != 0 ) {
905    printf( "ERROR - size close test device (%d) %s\n", test, strerror(errno) );
906    rtems_test_exit(0);
907  }
908
909  /*
910   * Test parity
911   */
912  puts(
913    "\n"
914    "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK"
915  );
916  test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
917  if ( test == -1 ) {
918    printf( "ERROR - parity open test device (%d) %s\n",
919      test, strerror(errno) );
920    rtems_test_exit(0);
921  }
922
923  test_termios_set_parity(test);
924
925  puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
926  rc = close( test );
927  if ( rc != 0 ) {
928    printf( "ERROR - parity close test device (%d) %s\n",
929      test, strerror(errno) );
930    rtems_test_exit(0);
931  }
932
933  /*
934   * Test stop bits
935   */
936  puts(
937    "\n"
938    "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK"
939  );
940  test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
941  if ( test == -1 ) {
942    printf( "ERROR - stop bits open test device (%d) %s\n",
943      test, strerror(errno) );
944    rtems_test_exit(0);
945  }
946
947  test_termios_set_stop_bits(test);
948
949  test_termios_cfoutspeed();
950
951  test_termios_cfinspeed();
952
953  test_termios_cfsetspeed();
954
955  puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
956  rc = close( test );
957  if ( rc != 0 ) {
958    printf( "ERROR - stop bits close test device (%d) %s\n",
959      test, strerror(errno) );
960    rtems_test_exit(0);
961  }
962
963
964  puts( "Multiple open of the device" );
965  for( ; index < 26; ++index ) {
966    test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
967    rtems_test_assert( test != -1 );
968    rc = close( test );
969    rtems_test_assert( rc == 0 );
970  }
971  puts( "" );
972
973  test_device_install_remove();
974  test_first_open_error();
975  test_set_attributes_error();
976  test_set_best_baud();
977
978  TEST_END();
979  rtems_test_exit(0);
980}
981
982/* configuration information */
983
984#define CONFIGURE_APPLICATION_PREREQUISITE_DRIVERS \
985  { .initialization_entry = test_early_device_install_remove }
986
987#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
988#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
989
990/* include an extra slot for registering the termios one dynamically */
991#define CONFIGURE_MAXIMUM_DRIVERS 4
992
993/* one for the console and one for the test port */
994#define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 3
995
996/* we need to be able to open the test device */
997#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 4
998
999#define CONFIGURE_MAXIMUM_TASKS         1
1000#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
1001
1002#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
1003
1004#define CONFIGURE_INIT
1005#include <rtems/confdefs.h>
1006
1007/* global variables */
Note: See TracBrowser for help on using the repository browser.