Changeset d24ceb3 in rtems
- Timestamp:
- Nov 15, 1997, 6:15:36 PM (23 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- b5ddb74
- Parents:
- a307f79
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/exec/libcsupport/include/rtems/libio.h
ra307f79 rd24ceb3 140 140 int (*deviceLastClose)(int major, int minor, void *arg), 141 141 int (*deviceRead)(int minor), 142 int (*deviceWrite)(int minor, char *buf, int len) 142 int (*deviceWrite)(int minor, char *buf, int len), 143 int deviceOutputUsesInterrupts 143 144 ); 144 145 -
c/src/exec/libcsupport/src/termios.c
ra307f79 rd24ceb3 2 2 * TERMIOS serial line support 3 3 * 4 * Author s:4 * Author: 5 5 * W. Eric Norum 6 6 * Saskatchewan Accelerator Laboratory … … 8 8 * Saskatoon, Saskatchewan, CANADA 9 9 * eric@skatter.usask.ca 10 *11 * AND12 *13 * Katsutoshi Shibuya14 * BU Denken Co.,Ltd.15 * Sapporo, JAPAN16 * shibuya@mxb.meshnet.or.jp17 10 * 18 11 * The license and distribution terms for this file may be … … 38 31 39 32 /* 40 * The size of the raw input message queue 41 */ 42 #define RAW_BUFFER_SIZE 128 33 * The sizes of the raw message buffers. 34 * On most architectures it is quite a bit more 35 * efficient if these are powers of two. 36 */ 37 #define RAW_INPUT_BUFFER_SIZE 128 38 #define RAW_OUTPUT_BUFFER_SIZE 64 43 39 44 40 /* … … 90 86 91 87 /* 92 * Raw character buffer 93 */ 94 volatile char rawBuf[RAW_BUFFER_SIZE]; 95 volatile unsigned int rawBufHead; 96 volatile unsigned int rawBufTail; 97 rtems_id rawBufSemaphore; 98 rtems_unsigned32 rawBufSemaphoreOptions; 99 rtems_interval rawBufSemaphoreTimeout; 100 rtems_interval rawBufSemaphoreFirstTimeout; 101 unsigned int rawBufDropped; /* Statistics */ 88 * Raw input character buffer 89 */ 90 volatile char rawInBuf[RAW_INPUT_BUFFER_SIZE]; 91 volatile unsigned int rawInBufHead; 92 volatile unsigned int rawInBufTail; 93 rtems_id rawInBufSemaphore; 94 rtems_unsigned32 rawInBufSemaphoreOptions; 95 rtems_interval rawInBufSemaphoreTimeout; 96 rtems_interval rawInBufSemaphoreFirstTimeout; 97 unsigned int rawInBufDropped; /* Statistics */ 98 99 /* 100 * Raw output character buffer 101 */ 102 char outputUsesInterrupts; 103 volatile char rawOutBuf[RAW_OUTPUT_BUFFER_SIZE]; 104 volatile unsigned int rawOutBufHead; 105 volatile unsigned int rawOutBufTail; 106 rtems_id rawOutBufSemaphore; 107 enum {rob_idle, rob_busy, rob_wait } rawOutBufState; 102 108 103 109 /* … … 110 116 static struct rtems_termios_tty *ttyHead, *ttyTail; 111 117 static rtems_id ttyMutex; 118 119 /* 120 * Reserve enough resources to open every physical device once. 121 */ 122 void 123 rtems_termios_reserve_resources ( 124 rtems_configuration_table *configuration, 125 rtems_unsigned32 number_of_devices 126 ) 127 { 128 static int first_time = 1; 129 rtems_api_configuration_table *rtems_config; 130 131 if (!configuration) 132 rtems_fatal_error_occurred (0xFFF0F001); 133 rtems_config = configuration->RTEMS_api_configuration; 134 if (!rtems_config) 135 rtems_fatal_error_occurred (0xFFF0F002); 136 if (first_time) 137 rtems_config->maximum_semaphores += 1; 138 first_time = 0; 139 rtems_config->maximum_semaphores += (4 * number_of_devices); 140 } 112 141 113 142 void … … 142 171 int (*deviceLastClose)(int major, int minor, void *arg), 143 172 int (*deviceRead)(int minor), 144 int (*deviceWrite)(int minor, char *buf, int len) 173 int (*deviceWrite)(int minor, char *buf, int len), 174 int deviceOutputUsesInterrupts 145 175 ) 146 176 { … … 195 225 if (sc != RTEMS_SUCCESSFUL) 196 226 rtems_fatal_error_occurred (sc); 227 sc = rtems_semaphore_create ( 228 rtems_build_name ('T', 'R', 'x', c), 229 0, 230 RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY, 231 RTEMS_NO_PRIORITY, 232 &tty->rawOutBufSemaphore); 233 if (sc != RTEMS_SUCCESSFUL) 234 rtems_fatal_error_occurred (sc); 235 tty->rawOutBufHead = 0; 236 tty->rawOutBufTail = 0; 197 237 198 238 /* … … 207 247 RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY, 208 248 RTEMS_NO_PRIORITY, 209 &tty->raw BufSemaphore);249 &tty->rawInBufSemaphore); 210 250 if (sc != RTEMS_SUCCESSFUL) 211 251 rtems_fatal_error_occurred (sc); 212 tty->raw BufHead = 0;213 tty->raw BufTail = 0;252 tty->rawInBufHead = 0; 253 tty->rawInBufTail = 0; 214 254 } 215 255 … … 219 259 tty->column = 0; 220 260 tty->cindex = tty->ccount = 0; 261 tty->outputUsesInterrupts = deviceOutputUsesInterrupts; 221 262 222 263 /* … … 267 308 rtems_status_code sc; 268 309 269 args->ioctl_return = 0;270 310 sc = rtems_semaphore_obtain (ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); 271 311 if (sc != RTEMS_SUCCESSFUL) … … 284 324 rtems_semaphore_delete (tty->isem); 285 325 rtems_semaphore_delete (tty->osem); 326 rtems_semaphore_delete (tty->rawOutBufSemaphore); 286 327 if (tty->read == NULL) 287 rtems_semaphore_delete (tty->raw BufSemaphore);328 rtems_semaphore_delete (tty->rawInBufSemaphore); 288 329 free (tty); 289 330 } … … 299 340 rtems_status_code sc; 300 341 342 args->ioctl_return = 0; 301 343 sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT); 302 344 if (sc != RTEMS_SUCCESSFUL) … … 314 356 tty->termios = *(struct termios *)args->buffer; 315 357 if (tty->termios.c_lflag & ICANON) { 316 tty->raw BufSemaphoreOptions = RTEMS_WAIT;317 tty->raw BufSemaphoreTimeout = RTEMS_NO_TIMEOUT;318 tty->raw BufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;358 tty->rawInBufSemaphoreOptions = RTEMS_WAIT; 359 tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT; 360 tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT; 319 361 } 320 362 else { … … 323 365 tty->vtimeTicks = tty->termios.c_cc[VTIME] * ticksPerSecond / 10; 324 366 if (tty->termios.c_cc[VTIME]) { 325 tty->raw BufSemaphoreOptions = RTEMS_WAIT;326 tty->raw BufSemap`oreTimeout = tty->vtimeTicks;367 tty->rawInBufSemaphoreOptions = RTEMS_WAIT; 368 tty->rawInBufSemaphoreTimeout = tty->vtimeTicks; 327 369 if (tty->termios.c_cc[VMIN]) 328 tty->raw BufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;370 tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT; 329 371 else 330 tty->raw BufSemaphoreFirstTimeout = tty->vtimeTicks;372 tty->rawInBufSemaphoreFirstTimeout = tty->vtimeTicks; 331 373 } 332 374 else { 333 375 if (tty->termios.c_cc[VMIN]) { 334 tty->raw BufSemaphoreOptions = RTEMS_WAIT;335 tty->raw BufSemaphoreTimeout = RTEMS_NO_TIMEOUT;336 tty->raw BufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;376 tty->rawInBufSemaphoreOptions = RTEMS_WAIT; 377 tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT; 378 tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT; 337 379 } 338 380 else { 339 tty->raw BufSemaphoreOptions = RTEMS_NO_WAIT;381 tty->rawInBufSemaphoreOptions = RTEMS_NO_WAIT; 340 382 } 341 383 } … … 345 387 rtems_semaphore_release (tty->osem); 346 388 return sc; 389 } 390 391 /* 392 * Send characters to device-specific code 393 */ 394 static void 395 osend (const char *buf, int len, struct rtems_termios_tty *tty) 396 { 397 unsigned int newHead; 398 rtems_interrupt_level level; 399 rtems_status_code sc; 400 401 if (!tty->outputUsesInterrupts) { 402 (*tty->write)(tty->minor, buf, len); 403 return; 404 } 405 newHead = tty->rawOutBufHead; 406 while (len) { 407 /* 408 * Performance improvement could be made here. 409 * Copy multiple bytes to raw buffer: 410 * if (len > 1) && (space to buffer end, or tail > 1) 411 * ncopy = MIN (len, space to buffer end or tail) 412 * memcpy (raw buffer, buf, ncopy) 413 * buf += ncopy 414 * len -= ncopy 415 * 416 * To minimize latency, the memcpy should be done 417 * with interrupts enabled. 418 */ 419 newHead = (newHead + 1) % RAW_OUTPUT_BUFFER_SIZE; 420 rtems_interrupt_disable (level); 421 while (newHead == tty->rawOutBufTail) { 422 tty->rawOutBufState = rob_wait; 423 rtems_interrupt_enable (level); 424 sc = rtems_semaphore_obtain (tty->rawOutBufSemaphore, 425 RTEMS_WAIT, 426 RTEMS_NO_TIMEOUT); 427 if (sc != RTEMS_SUCCESSFUL) 428 rtems_fatal_error_occurred (sc); 429 rtems_interrupt_disable (level); 430 } 431 tty->rawOutBuf[tty->rawOutBufHead] = *buf++; 432 tty->rawOutBufHead = newHead; 433 if (tty->rawOutBufState == rob_idle) { 434 rtems_interrupt_enable (level); 435 tty->rawOutBufState = rob_busy; 436 (*tty->write)(tty->minor, (char *)&tty->rawOutBuf[tty->rawOutBufTail], 1); 437 } 438 else { 439 rtems_interrupt_enable (level); 440 } 441 len--; 442 } 347 443 } 348 444 … … 361 457 tty->column = 0; 362 458 if (tty->termios.c_oflag & ONLCR) { 363 (*tty->write)(tty->minor, "\r", 1);459 osend ("\r", 1, tty); 364 460 tty->column = 0; 365 461 } … … 382 478 if ((tty->termios.c_oflag & TABDLY) == XTABS) { 383 479 tty->column += i; 384 (*tty->write)(tty->minor, " ", i);480 osend ( " ", i, tty); 385 481 return; 386 482 } … … 401 497 } 402 498 } 403 (*tty->write)(tty->minor, &c, 1);499 osend (&c, 1, tty); 404 500 } 405 501 … … 422 518 } 423 519 else { 424 if ((*tty->write)(tty->minor, args->buffer, args->count) < 0) 425 sc = RTEMS_UNSATISFIED; 426 else 427 args->bytes_moved = args->count; 520 osend (args->buffer, args->count, tty); 521 args->bytes_moved = args->count; 428 522 } 429 523 rtems_semaphore_release (tty->osem); … … 442 536 echobuf[0] = '^'; 443 537 echobuf[1] = c ^ 0x40; 444 (*tty->write)(tty->minor, echobuf, 2);538 osend (echobuf, 2, tty); 445 539 tty->column += 2; 446 540 } … … 505 599 */ 506 600 while (tty->column > col) { 507 (*tty->write)(tty->minor, "\b", 1);601 osend ("\b", 1, tty); 508 602 tty->column--; 509 603 } … … 511 605 else { 512 606 if (iscntrl (c) && (tty->termios.c_lflag & ECHOCTL)) { 513 (*tty->write)(tty->minor, "\b \b", 3);607 osend ("\b \b", 3, tty); 514 608 if (tty->column) 515 609 tty->column--; 516 610 } 517 611 if (!iscntrl (c) || (tty->termios.c_lflag & ECHOCTL)) { 518 (*tty->write)(tty->minor, "\b \b", 3);612 osend ("\b \b", 3, tty); 519 613 if (tty->column) 520 614 tty->column--; … … 669 763 fillBufferQueue (struct rtems_termios_tty *tty) 670 764 { 671 rtems_interval timeout = tty->raw BufSemaphoreFirstTimeout;765 rtems_interval timeout = tty->rawInBufSemaphoreFirstTimeout; 672 766 rtems_status_code sc; 673 767 … … 676 770 * Process characters read from raw queue 677 771 */ 678 while (tty->raw BufHead != tty->rawBufTail) {772 while (tty->rawInBufHead != tty->rawInBufTail) { 679 773 unsigned char c; 680 774 unsigned int newHead; 681 775 682 newHead = (tty->raw BufHead + 1) % RAW_BUFFER_SIZE;683 c = tty->raw Buf[newHead];684 tty->raw BufHead = newHead;776 newHead = (tty->rawInBufHead + 1) % RAW_INPUT_BUFFER_SIZE; 777 c = tty->rawInBuf[newHead]; 778 tty->rawInBufHead = newHead; 685 779 if (tty->termios.c_lflag & ICANON) { 686 780 if (siproc (c, tty)) … … 692 786 return RTEMS_SUCCESSFUL; 693 787 } 694 timeout = tty->raw BufSemaphoreTimeout;788 timeout = tty->rawInBufSemaphoreTimeout; 695 789 } 696 790 … … 698 792 * Wait for characters 699 793 */ 700 sc = rtems_semaphore_obtain (tty->raw BufSemaphore,701 tty->raw BufSemaphoreOptions,794 sc = rtems_semaphore_obtain (tty->rawInBufSemaphore, 795 tty->rawInBufSemaphoreOptions, 702 796 timeout); 703 797 if (sc != RTEMS_SUCCESSFUL) … … 740 834 /* 741 835 * Place characters on raw queue. 742 * NOTE: This routine runs in the context of the device interrupt handler. 836 * NOTE: This routine runs in the context of the 837 * device receive interrupt handler. 743 838 */ 744 839 void … … 749 844 750 845 while (len) { 751 newTail = (tty->raw BufTail + 1) % RAW_BUFFER_SIZE;752 if (newTail == tty->raw BufHead) {753 tty->raw BufDropped += len;846 newTail = (tty->rawInBufTail + 1) % RAW_INPUT_BUFFER_SIZE; 847 if (newTail == tty->rawInBufHead) { 848 tty->rawInBufDropped += len; 754 849 break; 755 850 } 756 tty->raw Buf[newTail] = *buf++;851 tty->rawInBuf[newTail] = *buf++; 757 852 len--; 758 tty->rawBufTail = newTail; 759 } 760 rtems_semaphore_release (tty->rawBufSemaphore); 761 } 762 763 /* 764 * Reserve enough resources to open every physical device once. 765 */ 766 767 void rtems_termios_reserve_resources( 768 rtems_configuration_table *configuration, 769 rtems_unsigned32 number_of_devices 770 ) 771 { 772 static int first_time = 1; 773 rtems_api_configuration_table *rtems_config; 774 775 if (!configuration) 776 rtems_fatal_error_occurred (0xFFF0F001); 777 778 rtems_config = configuration->RTEMS_api_configuration; 779 if (!rtems_config) 780 rtems_fatal_error_occurred (0xFFF0F002); 781 782 if (first_time) 783 rtems_config->maximum_semaphores += 1; 784 785 first_time = 0; 786 rtems_config->maximum_semaphores += (3 * number_of_devices); 787 } 853 tty->rawInBufTail = newTail; 854 } 855 rtems_semaphore_release (tty->rawInBufSemaphore); 856 } 857 858 /* 859 * Characters have been transmitted 860 * NOTE: This routine runs in the context of the 861 * device transmit interrupt handler. 862 * The second argument is the number of characters transmitted so far. 863 * This value will always be 1 for devices which generate an interrupt 864 * for each transmitted character. 865 */ 866 void 867 rtems_termios_dequeue_characters (void *ttyp, int len) 868 { 869 struct rtems_termios_tty *tty = ttyp; 870 unsigned int newTail; 871 int nToSend; 872 873 if (tty->rawOutBufState == rob_wait) 874 rtems_semaphore_release (tty->rawOutBufSemaphore); 875 newTail = (tty->rawOutBufTail + len) % RAW_OUTPUT_BUFFER_SIZE; 876 if (newTail == tty->rawOutBufHead) { 877 /* 878 * Buffer empty 879 */ 880 tty->rawOutBufState = rob_idle; 881 } 882 else { 883 /* 884 * Buffer not empty, start tranmitter 885 */ 886 tty->rawOutBufState = rob_busy; 887 if (newTail > tty->rawOutBufHead) 888 nToSend = RAW_OUTPUT_BUFFER_SIZE - newTail; 889 else 890 nToSend = tty->rawOutBufHead - newTail; 891 (*tty->write)(tty->minor, (char *)&tty->rawOutBuf[newTail], nToSend); 892 } 893 tty->rawOutBufTail = newTail; 894 } -
c/src/lib/include/rtems/libio.h
ra307f79 rd24ceb3 140 140 int (*deviceLastClose)(int major, int minor, void *arg), 141 141 int (*deviceRead)(int minor), 142 int (*deviceWrite)(int minor, char *buf, int len) 142 int (*deviceWrite)(int minor, char *buf, int len), 143 int deviceOutputUsesInterrupts 143 144 ); 144 145 -
c/src/lib/libbsp/m68k/gen68360/console/console.c
ra307f79 rd24ceb3 41 41 * I/O buffers and pointers to buffer descriptors 42 42 */ 43 static volatile char rxBuf[RXBUFSIZE] , txBuf;43 static volatile char rxBuf[RXBUFSIZE]; 44 44 static volatile m360BufferDescriptor_t *smcRxBd, *smcTxBd; 45 45 … … 63 63 } 64 64 } 65 66 /* 67 * Buffer transmitted? 68 */ 69 if (m360.smc1.smce & 0x2) { 70 m360.smc1.smce = 0x2; 71 if ((smcTxBd->status & M360_BD_READY) == 0) 72 rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length); 73 } 65 74 m360.cisr = 1UL << 4; /* Clear SMC1 interrupt-in-service bit */ 66 75 } … … 123 132 */ 124 133 smcTxBd->status = M360_BD_WRAP; 125 smcTxBd->length = 1;126 smcTxBd->buffer = &txBuf;127 134 128 135 /* … … 151 158 (m360.cicr & 0xE0) | 0x04, 152 159 &old_handler); 153 m360.smc1.smcm = 1; /* Enable SMC1 receiver interrupt*/160 m360.smc1.smcm = 3; /* Enable SMC1 TX and RX interrupts */ 154 161 m360.cimr |= 1UL << 4; /* Enable SMC1 interrupts */ 155 162 } … … 169 176 } 170 177 178 /* 179 * Device-dependent write routine 180 * Interrupt-driven devices: 181 * Begin transmission of as many characters as possible (minimum is 1). 182 * Polling devices: 183 * Transmit all characters. 184 */ 171 185 static int 172 186 smc1Write (int minor, char *buf, int len) 173 187 { 174 int nwrite = 0; 175 176 while (nwrite < len) { 188 #if (defined (M360_SMC1_INTERRUPT)) 189 smcTxBd->buffer = buf; 190 smcTxBd->length = len; 191 smcTxBd->status = M360_BD_READY | M360_BD_WRAP | M360_BD_INTERRUPT; 192 #else 193 while (len--) { 194 static char txBuf; 177 195 while (smcTxBd->status & M360_BD_READY) 178 196 continue; 179 197 txBuf = *buf++; 198 smcTxBd->buffer = &txBuf; 199 smcTxBd->length = 1; 180 200 smcTxBd->status = M360_BD_READY | M360_BD_WRAP; 181 nwrite++;182 201 } 183 return nwrite; 202 #endif 203 return 0; 184 204 } 185 205 … … 189 209 *************** 190 210 */ 211 212 /* 213 * Reserve resources consumed by this driver 214 */ 215 void console_reserve_resources( 216 rtems_configuration_table *configuration 217 ) 218 { 219 rtems_termios_reserve_resources (configuration, 1); 220 } 191 221 192 222 /* … … 238 268 NULL, 239 269 NULL, 240 smc1Write); 270 smc1Write, 271 1); 241 272 smc1ttyp = args->iop->data1; 242 273 #else … … 245 276 NULL, 246 277 smc1Read, 247 smc1Write); 278 smc1Write, 279 0); 248 280 #endif 249 281 return sc; -
c/src/lib/libc/libio.h
ra307f79 rd24ceb3 140 140 int (*deviceLastClose)(int major, int minor, void *arg), 141 141 int (*deviceRead)(int minor), 142 int (*deviceWrite)(int minor, char *buf, int len) 142 int (*deviceWrite)(int minor, char *buf, int len), 143 int deviceOutputUsesInterrupts 143 144 ); 144 145 -
c/src/lib/libc/termios.c
ra307f79 rd24ceb3 2 2 * TERMIOS serial line support 3 3 * 4 * Author s:4 * Author: 5 5 * W. Eric Norum 6 6 * Saskatchewan Accelerator Laboratory … … 8 8 * Saskatoon, Saskatchewan, CANADA 9 9 * eric@skatter.usask.ca 10 *11 * AND12 *13 * Katsutoshi Shibuya14 * BU Denken Co.,Ltd.15 * Sapporo, JAPAN16 * shibuya@mxb.meshnet.or.jp17 10 * 18 11 * The license and distribution terms for this file may be … … 38 31 39 32 /* 40 * The size of the raw input message queue 41 */ 42 #define RAW_BUFFER_SIZE 128 33 * The sizes of the raw message buffers. 34 * On most architectures it is quite a bit more 35 * efficient if these are powers of two. 36 */ 37 #define RAW_INPUT_BUFFER_SIZE 128 38 #define RAW_OUTPUT_BUFFER_SIZE 64 43 39 44 40 /* … … 90 86 91 87 /* 92 * Raw character buffer 93 */ 94 volatile char rawBuf[RAW_BUFFER_SIZE]; 95 volatile unsigned int rawBufHead; 96 volatile unsigned int rawBufTail; 97 rtems_id rawBufSemaphore; 98 rtems_unsigned32 rawBufSemaphoreOptions; 99 rtems_interval rawBufSemaphoreTimeout; 100 rtems_interval rawBufSemaphoreFirstTimeout; 101 unsigned int rawBufDropped; /* Statistics */ 88 * Raw input character buffer 89 */ 90 volatile char rawInBuf[RAW_INPUT_BUFFER_SIZE]; 91 volatile unsigned int rawInBufHead; 92 volatile unsigned int rawInBufTail; 93 rtems_id rawInBufSemaphore; 94 rtems_unsigned32 rawInBufSemaphoreOptions; 95 rtems_interval rawInBufSemaphoreTimeout; 96 rtems_interval rawInBufSemaphoreFirstTimeout; 97 unsigned int rawInBufDropped; /* Statistics */ 98 99 /* 100 * Raw output character buffer 101 */ 102 char outputUsesInterrupts; 103 volatile char rawOutBuf[RAW_OUTPUT_BUFFER_SIZE]; 104 volatile unsigned int rawOutBufHead; 105 volatile unsigned int rawOutBufTail; 106 rtems_id rawOutBufSemaphore; 107 enum {rob_idle, rob_busy, rob_wait } rawOutBufState; 102 108 103 109 /* … … 110 116 static struct rtems_termios_tty *ttyHead, *ttyTail; 111 117 static rtems_id ttyMutex; 118 119 /* 120 * Reserve enough resources to open every physical device once. 121 */ 122 void 123 rtems_termios_reserve_resources ( 124 rtems_configuration_table *configuration, 125 rtems_unsigned32 number_of_devices 126 ) 127 { 128 static int first_time = 1; 129 rtems_api_configuration_table *rtems_config; 130 131 if (!configuration) 132 rtems_fatal_error_occurred (0xFFF0F001); 133 rtems_config = configuration->RTEMS_api_configuration; 134 if (!rtems_config) 135 rtems_fatal_error_occurred (0xFFF0F002); 136 if (first_time) 137 rtems_config->maximum_semaphores += 1; 138 first_time = 0; 139 rtems_config->maximum_semaphores += (4 * number_of_devices); 140 } 112 141 113 142 void … … 142 171 int (*deviceLastClose)(int major, int minor, void *arg), 143 172 int (*deviceRead)(int minor), 144 int (*deviceWrite)(int minor, char *buf, int len) 173 int (*deviceWrite)(int minor, char *buf, int len), 174 int deviceOutputUsesInterrupts 145 175 ) 146 176 { … … 195 225 if (sc != RTEMS_SUCCESSFUL) 196 226 rtems_fatal_error_occurred (sc); 227 sc = rtems_semaphore_create ( 228 rtems_build_name ('T', 'R', 'x', c), 229 0, 230 RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY, 231 RTEMS_NO_PRIORITY, 232 &tty->rawOutBufSemaphore); 233 if (sc != RTEMS_SUCCESSFUL) 234 rtems_fatal_error_occurred (sc); 235 tty->rawOutBufHead = 0; 236 tty->rawOutBufTail = 0; 197 237 198 238 /* … … 207 247 RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY, 208 248 RTEMS_NO_PRIORITY, 209 &tty->raw BufSemaphore);249 &tty->rawInBufSemaphore); 210 250 if (sc != RTEMS_SUCCESSFUL) 211 251 rtems_fatal_error_occurred (sc); 212 tty->raw BufHead = 0;213 tty->raw BufTail = 0;252 tty->rawInBufHead = 0; 253 tty->rawInBufTail = 0; 214 254 } 215 255 … … 219 259 tty->column = 0; 220 260 tty->cindex = tty->ccount = 0; 261 tty->outputUsesInterrupts = deviceOutputUsesInterrupts; 221 262 222 263 /* … … 267 308 rtems_status_code sc; 268 309 269 args->ioctl_return = 0;270 310 sc = rtems_semaphore_obtain (ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); 271 311 if (sc != RTEMS_SUCCESSFUL) … … 284 324 rtems_semaphore_delete (tty->isem); 285 325 rtems_semaphore_delete (tty->osem); 326 rtems_semaphore_delete (tty->rawOutBufSemaphore); 286 327 if (tty->read == NULL) 287 rtems_semaphore_delete (tty->raw BufSemaphore);328 rtems_semaphore_delete (tty->rawInBufSemaphore); 288 329 free (tty); 289 330 } … … 299 340 rtems_status_code sc; 300 341 342 args->ioctl_return = 0; 301 343 sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT); 302 344 if (sc != RTEMS_SUCCESSFUL) … … 314 356 tty->termios = *(struct termios *)args->buffer; 315 357 if (tty->termios.c_lflag & ICANON) { 316 tty->raw BufSemaphoreOptions = RTEMS_WAIT;317 tty->raw BufSemaphoreTimeout = RTEMS_NO_TIMEOUT;318 tty->raw BufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;358 tty->rawInBufSemaphoreOptions = RTEMS_WAIT; 359 tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT; 360 tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT; 319 361 } 320 362 else { … … 323 365 tty->vtimeTicks = tty->termios.c_cc[VTIME] * ticksPerSecond / 10; 324 366 if (tty->termios.c_cc[VTIME]) { 325 tty->raw BufSemaphoreOptions = RTEMS_WAIT;326 tty->raw BufSemap`oreTimeout = tty->vtimeTicks;367 tty->rawInBufSemaphoreOptions = RTEMS_WAIT; 368 tty->rawInBufSemaphoreTimeout = tty->vtimeTicks; 327 369 if (tty->termios.c_cc[VMIN]) 328 tty->raw BufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;370 tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT; 329 371 else 330 tty->raw BufSemaphoreFirstTimeout = tty->vtimeTicks;372 tty->rawInBufSemaphoreFirstTimeout = tty->vtimeTicks; 331 373 } 332 374 else { 333 375 if (tty->termios.c_cc[VMIN]) { 334 tty->raw BufSemaphoreOptions = RTEMS_WAIT;335 tty->raw BufSemaphoreTimeout = RTEMS_NO_TIMEOUT;336 tty->raw BufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;376 tty->rawInBufSemaphoreOptions = RTEMS_WAIT; 377 tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT; 378 tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT; 337 379 } 338 380 else { 339 tty->raw BufSemaphoreOptions = RTEMS_NO_WAIT;381 tty->rawInBufSemaphoreOptions = RTEMS_NO_WAIT; 340 382 } 341 383 } … … 345 387 rtems_semaphore_release (tty->osem); 346 388 return sc; 389 } 390 391 /* 392 * Send characters to device-specific code 393 */ 394 static void 395 osend (const char *buf, int len, struct rtems_termios_tty *tty) 396 { 397 unsigned int newHead; 398 rtems_interrupt_level level; 399 rtems_status_code sc; 400 401 if (!tty->outputUsesInterrupts) { 402 (*tty->write)(tty->minor, buf, len); 403 return; 404 } 405 newHead = tty->rawOutBufHead; 406 while (len) { 407 /* 408 * Performance improvement could be made here. 409 * Copy multiple bytes to raw buffer: 410 * if (len > 1) && (space to buffer end, or tail > 1) 411 * ncopy = MIN (len, space to buffer end or tail) 412 * memcpy (raw buffer, buf, ncopy) 413 * buf += ncopy 414 * len -= ncopy 415 * 416 * To minimize latency, the memcpy should be done 417 * with interrupts enabled. 418 */ 419 newHead = (newHead + 1) % RAW_OUTPUT_BUFFER_SIZE; 420 rtems_interrupt_disable (level); 421 while (newHead == tty->rawOutBufTail) { 422 tty->rawOutBufState = rob_wait; 423 rtems_interrupt_enable (level); 424 sc = rtems_semaphore_obtain (tty->rawOutBufSemaphore, 425 RTEMS_WAIT, 426 RTEMS_NO_TIMEOUT); 427 if (sc != RTEMS_SUCCESSFUL) 428 rtems_fatal_error_occurred (sc); 429 rtems_interrupt_disable (level); 430 } 431 tty->rawOutBuf[tty->rawOutBufHead] = *buf++; 432 tty->rawOutBufHead = newHead; 433 if (tty->rawOutBufState == rob_idle) { 434 rtems_interrupt_enable (level); 435 tty->rawOutBufState = rob_busy; 436 (*tty->write)(tty->minor, (char *)&tty->rawOutBuf[tty->rawOutBufTail], 1); 437 } 438 else { 439 rtems_interrupt_enable (level); 440 } 441 len--; 442 } 347 443 } 348 444 … … 361 457 tty->column = 0; 362 458 if (tty->termios.c_oflag & ONLCR) { 363 (*tty->write)(tty->minor, "\r", 1);459 osend ("\r", 1, tty); 364 460 tty->column = 0; 365 461 } … … 382 478 if ((tty->termios.c_oflag & TABDLY) == XTABS) { 383 479 tty->column += i; 384 (*tty->write)(tty->minor, " ", i);480 osend ( " ", i, tty); 385 481 return; 386 482 } … … 401 497 } 402 498 } 403 (*tty->write)(tty->minor, &c, 1);499 osend (&c, 1, tty); 404 500 } 405 501 … … 422 518 } 423 519 else { 424 if ((*tty->write)(tty->minor, args->buffer, args->count) < 0) 425 sc = RTEMS_UNSATISFIED; 426 else 427 args->bytes_moved = args->count; 520 osend (args->buffer, args->count, tty); 521 args->bytes_moved = args->count; 428 522 } 429 523 rtems_semaphore_release (tty->osem); … … 442 536 echobuf[0] = '^'; 443 537 echobuf[1] = c ^ 0x40; 444 (*tty->write)(tty->minor, echobuf, 2);538 osend (echobuf, 2, tty); 445 539 tty->column += 2; 446 540 } … … 505 599 */ 506 600 while (tty->column > col) { 507 (*tty->write)(tty->minor, "\b", 1);601 osend ("\b", 1, tty); 508 602 tty->column--; 509 603 } … … 511 605 else { 512 606 if (iscntrl (c) && (tty->termios.c_lflag & ECHOCTL)) { 513 (*tty->write)(tty->minor, "\b \b", 3);607 osend ("\b \b", 3, tty); 514 608 if (tty->column) 515 609 tty->column--; 516 610 } 517 611 if (!iscntrl (c) || (tty->termios.c_lflag & ECHOCTL)) { 518 (*tty->write)(tty->minor, "\b \b", 3);612 osend ("\b \b", 3, tty); 519 613 if (tty->column) 520 614 tty->column--; … … 669 763 fillBufferQueue (struct rtems_termios_tty *tty) 670 764 { 671 rtems_interval timeout = tty->raw BufSemaphoreFirstTimeout;765 rtems_interval timeout = tty->rawInBufSemaphoreFirstTimeout; 672 766 rtems_status_code sc; 673 767 … … 676 770 * Process characters read from raw queue 677 771 */ 678 while (tty->raw BufHead != tty->rawBufTail) {772 while (tty->rawInBufHead != tty->rawInBufTail) { 679 773 unsigned char c; 680 774 unsigned int newHead; 681 775 682 newHead = (tty->raw BufHead + 1) % RAW_BUFFER_SIZE;683 c = tty->raw Buf[newHead];684 tty->raw BufHead = newHead;776 newHead = (tty->rawInBufHead + 1) % RAW_INPUT_BUFFER_SIZE; 777 c = tty->rawInBuf[newHead]; 778 tty->rawInBufHead = newHead; 685 779 if (tty->termios.c_lflag & ICANON) { 686 780 if (siproc (c, tty)) … … 692 786 return RTEMS_SUCCESSFUL; 693 787 } 694 timeout = tty->raw BufSemaphoreTimeout;788 timeout = tty->rawInBufSemaphoreTimeout; 695 789 } 696 790 … … 698 792 * Wait for characters 699 793 */ 700 sc = rtems_semaphore_obtain (tty->raw BufSemaphore,701 tty->raw BufSemaphoreOptions,794 sc = rtems_semaphore_obtain (tty->rawInBufSemaphore, 795 tty->rawInBufSemaphoreOptions, 702 796 timeout); 703 797 if (sc != RTEMS_SUCCESSFUL) … … 740 834 /* 741 835 * Place characters on raw queue. 742 * NOTE: This routine runs in the context of the device interrupt handler. 836 * NOTE: This routine runs in the context of the 837 * device receive interrupt handler. 743 838 */ 744 839 void … … 749 844 750 845 while (len) { 751 newTail = (tty->raw BufTail + 1) % RAW_BUFFER_SIZE;752 if (newTail == tty->raw BufHead) {753 tty->raw BufDropped += len;846 newTail = (tty->rawInBufTail + 1) % RAW_INPUT_BUFFER_SIZE; 847 if (newTail == tty->rawInBufHead) { 848 tty->rawInBufDropped += len; 754 849 break; 755 850 } 756 tty->raw Buf[newTail] = *buf++;851 tty->rawInBuf[newTail] = *buf++; 757 852 len--; 758 tty->rawBufTail = newTail; 759 } 760 rtems_semaphore_release (tty->rawBufSemaphore); 761 } 762 763 /* 764 * Reserve enough resources to open every physical device once. 765 */ 766 767 void rtems_termios_reserve_resources( 768 rtems_configuration_table *configuration, 769 rtems_unsigned32 number_of_devices 770 ) 771 { 772 static int first_time = 1; 773 rtems_api_configuration_table *rtems_config; 774 775 if (!configuration) 776 rtems_fatal_error_occurred (0xFFF0F001); 777 778 rtems_config = configuration->RTEMS_api_configuration; 779 if (!rtems_config) 780 rtems_fatal_error_occurred (0xFFF0F002); 781 782 if (first_time) 783 rtems_config->maximum_semaphores += 1; 784 785 first_time = 0; 786 rtems_config->maximum_semaphores += (3 * number_of_devices); 787 } 853 tty->rawInBufTail = newTail; 854 } 855 rtems_semaphore_release (tty->rawInBufSemaphore); 856 } 857 858 /* 859 * Characters have been transmitted 860 * NOTE: This routine runs in the context of the 861 * device transmit interrupt handler. 862 * The second argument is the number of characters transmitted so far. 863 * This value will always be 1 for devices which generate an interrupt 864 * for each transmitted character. 865 */ 866 void 867 rtems_termios_dequeue_characters (void *ttyp, int len) 868 { 869 struct rtems_termios_tty *tty = ttyp; 870 unsigned int newTail; 871 int nToSend; 872 873 if (tty->rawOutBufState == rob_wait) 874 rtems_semaphore_release (tty->rawOutBufSemaphore); 875 newTail = (tty->rawOutBufTail + len) % RAW_OUTPUT_BUFFER_SIZE; 876 if (newTail == tty->rawOutBufHead) { 877 /* 878 * Buffer empty 879 */ 880 tty->rawOutBufState = rob_idle; 881 } 882 else { 883 /* 884 * Buffer not empty, start tranmitter 885 */ 886 tty->rawOutBufState = rob_busy; 887 if (newTail > tty->rawOutBufHead) 888 nToSend = RAW_OUTPUT_BUFFER_SIZE - newTail; 889 else 890 nToSend = tty->rawOutBufHead - newTail; 891 (*tty->write)(tty->minor, (char *)&tty->rawOutBuf[newTail], nToSend); 892 } 893 tty->rawOutBufTail = newTail; 894 } -
cpukit/libcsupport/include/rtems/libio.h
ra307f79 rd24ceb3 140 140 int (*deviceLastClose)(int major, int minor, void *arg), 141 141 int (*deviceRead)(int minor), 142 int (*deviceWrite)(int minor, char *buf, int len) 142 int (*deviceWrite)(int minor, char *buf, int len), 143 int deviceOutputUsesInterrupts 143 144 ); 144 145 -
cpukit/libcsupport/src/termios.c
ra307f79 rd24ceb3 2 2 * TERMIOS serial line support 3 3 * 4 * Author s:4 * Author: 5 5 * W. Eric Norum 6 6 * Saskatchewan Accelerator Laboratory … … 8 8 * Saskatoon, Saskatchewan, CANADA 9 9 * eric@skatter.usask.ca 10 *11 * AND12 *13 * Katsutoshi Shibuya14 * BU Denken Co.,Ltd.15 * Sapporo, JAPAN16 * shibuya@mxb.meshnet.or.jp17 10 * 18 11 * The license and distribution terms for this file may be … … 38 31 39 32 /* 40 * The size of the raw input message queue 41 */ 42 #define RAW_BUFFER_SIZE 128 33 * The sizes of the raw message buffers. 34 * On most architectures it is quite a bit more 35 * efficient if these are powers of two. 36 */ 37 #define RAW_INPUT_BUFFER_SIZE 128 38 #define RAW_OUTPUT_BUFFER_SIZE 64 43 39 44 40 /* … … 90 86 91 87 /* 92 * Raw character buffer 93 */ 94 volatile char rawBuf[RAW_BUFFER_SIZE]; 95 volatile unsigned int rawBufHead; 96 volatile unsigned int rawBufTail; 97 rtems_id rawBufSemaphore; 98 rtems_unsigned32 rawBufSemaphoreOptions; 99 rtems_interval rawBufSemaphoreTimeout; 100 rtems_interval rawBufSemaphoreFirstTimeout; 101 unsigned int rawBufDropped; /* Statistics */ 88 * Raw input character buffer 89 */ 90 volatile char rawInBuf[RAW_INPUT_BUFFER_SIZE]; 91 volatile unsigned int rawInBufHead; 92 volatile unsigned int rawInBufTail; 93 rtems_id rawInBufSemaphore; 94 rtems_unsigned32 rawInBufSemaphoreOptions; 95 rtems_interval rawInBufSemaphoreTimeout; 96 rtems_interval rawInBufSemaphoreFirstTimeout; 97 unsigned int rawInBufDropped; /* Statistics */ 98 99 /* 100 * Raw output character buffer 101 */ 102 char outputUsesInterrupts; 103 volatile char rawOutBuf[RAW_OUTPUT_BUFFER_SIZE]; 104 volatile unsigned int rawOutBufHead; 105 volatile unsigned int rawOutBufTail; 106 rtems_id rawOutBufSemaphore; 107 enum {rob_idle, rob_busy, rob_wait } rawOutBufState; 102 108 103 109 /* … … 110 116 static struct rtems_termios_tty *ttyHead, *ttyTail; 111 117 static rtems_id ttyMutex; 118 119 /* 120 * Reserve enough resources to open every physical device once. 121 */ 122 void 123 rtems_termios_reserve_resources ( 124 rtems_configuration_table *configuration, 125 rtems_unsigned32 number_of_devices 126 ) 127 { 128 static int first_time = 1; 129 rtems_api_configuration_table *rtems_config; 130 131 if (!configuration) 132 rtems_fatal_error_occurred (0xFFF0F001); 133 rtems_config = configuration->RTEMS_api_configuration; 134 if (!rtems_config) 135 rtems_fatal_error_occurred (0xFFF0F002); 136 if (first_time) 137 rtems_config->maximum_semaphores += 1; 138 first_time = 0; 139 rtems_config->maximum_semaphores += (4 * number_of_devices); 140 } 112 141 113 142 void … … 142 171 int (*deviceLastClose)(int major, int minor, void *arg), 143 172 int (*deviceRead)(int minor), 144 int (*deviceWrite)(int minor, char *buf, int len) 173 int (*deviceWrite)(int minor, char *buf, int len), 174 int deviceOutputUsesInterrupts 145 175 ) 146 176 { … … 195 225 if (sc != RTEMS_SUCCESSFUL) 196 226 rtems_fatal_error_occurred (sc); 227 sc = rtems_semaphore_create ( 228 rtems_build_name ('T', 'R', 'x', c), 229 0, 230 RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY, 231 RTEMS_NO_PRIORITY, 232 &tty->rawOutBufSemaphore); 233 if (sc != RTEMS_SUCCESSFUL) 234 rtems_fatal_error_occurred (sc); 235 tty->rawOutBufHead = 0; 236 tty->rawOutBufTail = 0; 197 237 198 238 /* … … 207 247 RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY, 208 248 RTEMS_NO_PRIORITY, 209 &tty->raw BufSemaphore);249 &tty->rawInBufSemaphore); 210 250 if (sc != RTEMS_SUCCESSFUL) 211 251 rtems_fatal_error_occurred (sc); 212 tty->raw BufHead = 0;213 tty->raw BufTail = 0;252 tty->rawInBufHead = 0; 253 tty->rawInBufTail = 0; 214 254 } 215 255 … … 219 259 tty->column = 0; 220 260 tty->cindex = tty->ccount = 0; 261 tty->outputUsesInterrupts = deviceOutputUsesInterrupts; 221 262 222 263 /* … … 267 308 rtems_status_code sc; 268 309 269 args->ioctl_return = 0;270 310 sc = rtems_semaphore_obtain (ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); 271 311 if (sc != RTEMS_SUCCESSFUL) … … 284 324 rtems_semaphore_delete (tty->isem); 285 325 rtems_semaphore_delete (tty->osem); 326 rtems_semaphore_delete (tty->rawOutBufSemaphore); 286 327 if (tty->read == NULL) 287 rtems_semaphore_delete (tty->raw BufSemaphore);328 rtems_semaphore_delete (tty->rawInBufSemaphore); 288 329 free (tty); 289 330 } … … 299 340 rtems_status_code sc; 300 341 342 args->ioctl_return = 0; 301 343 sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT); 302 344 if (sc != RTEMS_SUCCESSFUL) … … 314 356 tty->termios = *(struct termios *)args->buffer; 315 357 if (tty->termios.c_lflag & ICANON) { 316 tty->raw BufSemaphoreOptions = RTEMS_WAIT;317 tty->raw BufSemaphoreTimeout = RTEMS_NO_TIMEOUT;318 tty->raw BufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;358 tty->rawInBufSemaphoreOptions = RTEMS_WAIT; 359 tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT; 360 tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT; 319 361 } 320 362 else { … … 323 365 tty->vtimeTicks = tty->termios.c_cc[VTIME] * ticksPerSecond / 10; 324 366 if (tty->termios.c_cc[VTIME]) { 325 tty->raw BufSemaphoreOptions = RTEMS_WAIT;326 tty->raw BufSemap`oreTimeout = tty->vtimeTicks;367 tty->rawInBufSemaphoreOptions = RTEMS_WAIT; 368 tty->rawInBufSemaphoreTimeout = tty->vtimeTicks; 327 369 if (tty->termios.c_cc[VMIN]) 328 tty->raw BufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;370 tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT; 329 371 else 330 tty->raw BufSemaphoreFirstTimeout = tty->vtimeTicks;372 tty->rawInBufSemaphoreFirstTimeout = tty->vtimeTicks; 331 373 } 332 374 else { 333 375 if (tty->termios.c_cc[VMIN]) { 334 tty->raw BufSemaphoreOptions = RTEMS_WAIT;335 tty->raw BufSemaphoreTimeout = RTEMS_NO_TIMEOUT;336 tty->raw BufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;376 tty->rawInBufSemaphoreOptions = RTEMS_WAIT; 377 tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT; 378 tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT; 337 379 } 338 380 else { 339 tty->raw BufSemaphoreOptions = RTEMS_NO_WAIT;381 tty->rawInBufSemaphoreOptions = RTEMS_NO_WAIT; 340 382 } 341 383 } … … 345 387 rtems_semaphore_release (tty->osem); 346 388 return sc; 389 } 390 391 /* 392 * Send characters to device-specific code 393 */ 394 static void 395 osend (const char *buf, int len, struct rtems_termios_tty *tty) 396 { 397 unsigned int newHead; 398 rtems_interrupt_level level; 399 rtems_status_code sc; 400 401 if (!tty->outputUsesInterrupts) { 402 (*tty->write)(tty->minor, buf, len); 403 return; 404 } 405 newHead = tty->rawOutBufHead; 406 while (len) { 407 /* 408 * Performance improvement could be made here. 409 * Copy multiple bytes to raw buffer: 410 * if (len > 1) && (space to buffer end, or tail > 1) 411 * ncopy = MIN (len, space to buffer end or tail) 412 * memcpy (raw buffer, buf, ncopy) 413 * buf += ncopy 414 * len -= ncopy 415 * 416 * To minimize latency, the memcpy should be done 417 * with interrupts enabled. 418 */ 419 newHead = (newHead + 1) % RAW_OUTPUT_BUFFER_SIZE; 420 rtems_interrupt_disable (level); 421 while (newHead == tty->rawOutBufTail) { 422 tty->rawOutBufState = rob_wait; 423 rtems_interrupt_enable (level); 424 sc = rtems_semaphore_obtain (tty->rawOutBufSemaphore, 425 RTEMS_WAIT, 426 RTEMS_NO_TIMEOUT); 427 if (sc != RTEMS_SUCCESSFUL) 428 rtems_fatal_error_occurred (sc); 429 rtems_interrupt_disable (level); 430 } 431 tty->rawOutBuf[tty->rawOutBufHead] = *buf++; 432 tty->rawOutBufHead = newHead; 433 if (tty->rawOutBufState == rob_idle) { 434 rtems_interrupt_enable (level); 435 tty->rawOutBufState = rob_busy; 436 (*tty->write)(tty->minor, (char *)&tty->rawOutBuf[tty->rawOutBufTail], 1); 437 } 438 else { 439 rtems_interrupt_enable (level); 440 } 441 len--; 442 } 347 443 } 348 444 … … 361 457 tty->column = 0; 362 458 if (tty->termios.c_oflag & ONLCR) { 363 (*tty->write)(tty->minor, "\r", 1);459 osend ("\r", 1, tty); 364 460 tty->column = 0; 365 461 } … … 382 478 if ((tty->termios.c_oflag & TABDLY) == XTABS) { 383 479 tty->column += i; 384 (*tty->write)(tty->minor, " ", i);480 osend ( " ", i, tty); 385 481 return; 386 482 } … … 401 497 } 402 498 } 403 (*tty->write)(tty->minor, &c, 1);499 osend (&c, 1, tty); 404 500 } 405 501 … … 422 518 } 423 519 else { 424 if ((*tty->write)(tty->minor, args->buffer, args->count) < 0) 425 sc = RTEMS_UNSATISFIED; 426 else 427 args->bytes_moved = args->count; 520 osend (args->buffer, args->count, tty); 521 args->bytes_moved = args->count; 428 522 } 429 523 rtems_semaphore_release (tty->osem); … … 442 536 echobuf[0] = '^'; 443 537 echobuf[1] = c ^ 0x40; 444 (*tty->write)(tty->minor, echobuf, 2);538 osend (echobuf, 2, tty); 445 539 tty->column += 2; 446 540 } … … 505 599 */ 506 600 while (tty->column > col) { 507 (*tty->write)(tty->minor, "\b", 1);601 osend ("\b", 1, tty); 508 602 tty->column--; 509 603 } … … 511 605 else { 512 606 if (iscntrl (c) && (tty->termios.c_lflag & ECHOCTL)) { 513 (*tty->write)(tty->minor, "\b \b", 3);607 osend ("\b \b", 3, tty); 514 608 if (tty->column) 515 609 tty->column--; 516 610 } 517 611 if (!iscntrl (c) || (tty->termios.c_lflag & ECHOCTL)) { 518 (*tty->write)(tty->minor, "\b \b", 3);612 osend ("\b \b", 3, tty); 519 613 if (tty->column) 520 614 tty->column--; … … 669 763 fillBufferQueue (struct rtems_termios_tty *tty) 670 764 { 671 rtems_interval timeout = tty->raw BufSemaphoreFirstTimeout;765 rtems_interval timeout = tty->rawInBufSemaphoreFirstTimeout; 672 766 rtems_status_code sc; 673 767 … … 676 770 * Process characters read from raw queue 677 771 */ 678 while (tty->raw BufHead != tty->rawBufTail) {772 while (tty->rawInBufHead != tty->rawInBufTail) { 679 773 unsigned char c; 680 774 unsigned int newHead; 681 775 682 newHead = (tty->raw BufHead + 1) % RAW_BUFFER_SIZE;683 c = tty->raw Buf[newHead];684 tty->raw BufHead = newHead;776 newHead = (tty->rawInBufHead + 1) % RAW_INPUT_BUFFER_SIZE; 777 c = tty->rawInBuf[newHead]; 778 tty->rawInBufHead = newHead; 685 779 if (tty->termios.c_lflag & ICANON) { 686 780 if (siproc (c, tty)) … … 692 786 return RTEMS_SUCCESSFUL; 693 787 } 694 timeout = tty->raw BufSemaphoreTimeout;788 timeout = tty->rawInBufSemaphoreTimeout; 695 789 } 696 790 … … 698 792 * Wait for characters 699 793 */ 700 sc = rtems_semaphore_obtain (tty->raw BufSemaphore,701 tty->raw BufSemaphoreOptions,794 sc = rtems_semaphore_obtain (tty->rawInBufSemaphore, 795 tty->rawInBufSemaphoreOptions, 702 796 timeout); 703 797 if (sc != RTEMS_SUCCESSFUL) … … 740 834 /* 741 835 * Place characters on raw queue. 742 * NOTE: This routine runs in the context of the device interrupt handler. 836 * NOTE: This routine runs in the context of the 837 * device receive interrupt handler. 743 838 */ 744 839 void … … 749 844 750 845 while (len) { 751 newTail = (tty->raw BufTail + 1) % RAW_BUFFER_SIZE;752 if (newTail == tty->raw BufHead) {753 tty->raw BufDropped += len;846 newTail = (tty->rawInBufTail + 1) % RAW_INPUT_BUFFER_SIZE; 847 if (newTail == tty->rawInBufHead) { 848 tty->rawInBufDropped += len; 754 849 break; 755 850 } 756 tty->raw Buf[newTail] = *buf++;851 tty->rawInBuf[newTail] = *buf++; 757 852 len--; 758 tty->rawBufTail = newTail; 759 } 760 rtems_semaphore_release (tty->rawBufSemaphore); 761 } 762 763 /* 764 * Reserve enough resources to open every physical device once. 765 */ 766 767 void rtems_termios_reserve_resources( 768 rtems_configuration_table *configuration, 769 rtems_unsigned32 number_of_devices 770 ) 771 { 772 static int first_time = 1; 773 rtems_api_configuration_table *rtems_config; 774 775 if (!configuration) 776 rtems_fatal_error_occurred (0xFFF0F001); 777 778 rtems_config = configuration->RTEMS_api_configuration; 779 if (!rtems_config) 780 rtems_fatal_error_occurred (0xFFF0F002); 781 782 if (first_time) 783 rtems_config->maximum_semaphores += 1; 784 785 first_time = 0; 786 rtems_config->maximum_semaphores += (3 * number_of_devices); 787 } 853 tty->rawInBufTail = newTail; 854 } 855 rtems_semaphore_release (tty->rawInBufSemaphore); 856 } 857 858 /* 859 * Characters have been transmitted 860 * NOTE: This routine runs in the context of the 861 * device transmit interrupt handler. 862 * The second argument is the number of characters transmitted so far. 863 * This value will always be 1 for devices which generate an interrupt 864 * for each transmitted character. 865 */ 866 void 867 rtems_termios_dequeue_characters (void *ttyp, int len) 868 { 869 struct rtems_termios_tty *tty = ttyp; 870 unsigned int newTail; 871 int nToSend; 872 873 if (tty->rawOutBufState == rob_wait) 874 rtems_semaphore_release (tty->rawOutBufSemaphore); 875 newTail = (tty->rawOutBufTail + len) % RAW_OUTPUT_BUFFER_SIZE; 876 if (newTail == tty->rawOutBufHead) { 877 /* 878 * Buffer empty 879 */ 880 tty->rawOutBufState = rob_idle; 881 } 882 else { 883 /* 884 * Buffer not empty, start tranmitter 885 */ 886 tty->rawOutBufState = rob_busy; 887 if (newTail > tty->rawOutBufHead) 888 nToSend = RAW_OUTPUT_BUFFER_SIZE - newTail; 889 else 890 nToSend = tty->rawOutBufHead - newTail; 891 (*tty->write)(tty->minor, (char *)&tty->rawOutBuf[newTail], nToSend); 892 } 893 tty->rawOutBufTail = newTail; 894 }
Note: See TracChangeset
for help on using the changeset viewer.