aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorV. Ananda Krishnan <mansarov@us.ibm.com>2006-02-03 06:04:30 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-03 11:32:07 -0500
commit0a577ce34f703c885f807e2abc77dff02c7857af (patch)
treea2bfd15ca0ffe4ecc65c769008c9bfa8e0b107c9 /drivers/serial
parent7d95c8f27d9be65bf160f1edaf653d33dfceb58c (diff)
[PATCH] jsm: update for tty buffering revamp
Signed-off-by: V. Ananda Krishnan <mansarov@us.ibm.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/Kconfig28
-rw-r--r--drivers/serial/jsm/jsm_tty.c208
2 files changed, 79 insertions, 157 deletions
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 0d38f0f2ae29..ee4265d7a8c9 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -892,20 +892,20 @@ config SERIAL_VR41XX_CONSOLE
892 a console on a serial port, say Y. Otherwise, say N. 892 a console on a serial port, say Y. Otherwise, say N.
893 893
894config SERIAL_JSM 894config SERIAL_JSM
895 tristate "Digi International NEO PCI Support" 895 tristate "Digi International NEO PCI Support"
896 depends on PCI && BROKEN 896 depends on PCI
897 select SERIAL_CORE 897 select SERIAL_CORE
898 help 898 help
899 This is a driver for Digi International's Neo series 899 This is a driver for Digi International's Neo series
900 of cards which provide multiple serial ports. You would need 900 of cards which provide multiple serial ports. You would need
901 something like this to connect more than two modems to your Linux 901 something like this to connect more than two modems to your Linux
902 box, for instance in order to become a dial-in server. This driver 902 box, for instance in order to become a dial-in server. This driver
903 supports PCI boards only. 903 supports PCI boards only.
904 If you have a card like this, say Y here and read the file 904 If you have a card like this, say Y here and read the file
905 <file:Documentation/jsm.txt>. 905 <file:Documentation/jsm.txt>.
906 906
907 To compile this driver as a module, choose M here: the 907 To compile this driver as a module, choose M here: the
908 module will be called jsm. 908 module will be called jsm.
909 909
910config SERIAL_SGI_IOC4 910config SERIAL_SGI_IOC4
911 tristate "SGI IOC4 controller serial support" 911 tristate "SGI IOC4 controller serial support"
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 6fa0d62d6f68..07bf28ca3302 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -20,8 +20,10 @@
20 * 20 *
21 * Contact Information: 21 * Contact Information:
22 * Scott H Kilau <Scott_Kilau@digi.com> 22 * Scott H Kilau <Scott_Kilau@digi.com>
23 * Wendy Xiong <wendyx@us.ltcfwd.linux.ibm.com> 23 * Ananda Venkatarman <mansarov@us.ibm.com>
24 * 24 * Modifications:
25 * 01/19/06: changed jsm_input routine to use the dynamically allocated
26 * tty_buffer changes. Contributors: Scott Kilau and Ananda V.
25 ***********************************************************************/ 27 ***********************************************************************/
26#include <linux/tty.h> 28#include <linux/tty.h>
27#include <linux/tty_flip.h> 29#include <linux/tty_flip.h>
@@ -497,16 +499,16 @@ void jsm_input(struct jsm_channel *ch)
497{ 499{
498 struct jsm_board *bd; 500 struct jsm_board *bd;
499 struct tty_struct *tp; 501 struct tty_struct *tp;
502 struct tty_ldisc *ld;
500 u32 rmask; 503 u32 rmask;
501 u16 head; 504 u16 head;
502 u16 tail; 505 u16 tail;
503 int data_len; 506 int data_len;
504 unsigned long lock_flags; 507 unsigned long lock_flags;
505 int flip_len; 508 int flip_len = 0;
506 int len = 0; 509 int len = 0;
507 int n = 0; 510 int n = 0;
508 char *buf = NULL; 511 char *buf = NULL;
509 char *buf2 = NULL;
510 int s = 0; 512 int s = 0;
511 int i = 0; 513 int i = 0;
512 514
@@ -574,56 +576,50 @@ void jsm_input(struct jsm_channel *ch)
574 576
575 /* 577 /*
576 * If the rxbuf is empty and we are not throttled, put as much 578 * If the rxbuf is empty and we are not throttled, put as much
577 * as we can directly into the linux TTY flip buffer. 579 * as we can directly into the linux TTY buffer.
578 * The jsm_rawreadok case takes advantage of carnal knowledge that
579 * the char_buf and the flag_buf are next to each other and
580 * are each of (2 * TTY_FLIPBUF_SIZE) size.
581 * 580 *
582 * NOTE: if(!tty->real_raw), the call to ldisc.receive_buf
583 *actually still uses the flag buffer, so you can't
584 *use it for input data
585 */ 581 */
586 if (jsm_rawreadok) { 582 flip_len = TTY_FLIPBUF_SIZE;
587 if (tp->real_raw)
588 flip_len = MYFLIPLEN;
589 else
590 flip_len = 2 * TTY_FLIPBUF_SIZE;
591 } else
592 flip_len = TTY_FLIPBUF_SIZE - tp->flip.count;
593 583
594 len = min(data_len, flip_len); 584 len = min(data_len, flip_len);
595 len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt); 585 len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt);
586 ld = tty_ldisc_ref(tp);
596 587
597 if (len <= 0) { 588 /*
598 spin_unlock_irqrestore(&ch->ch_lock, lock_flags); 589 * If the DONT_FLIP flag is on, don't flush our buffer, and act
599 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n"); 590 * like the ld doesn't have any space to put the data right now.
600 return; 591 */
601 } 592 if (test_bit(TTY_DONT_FLIP, &tp->flags))
593 len = 0;
602 594
603 /* 595 /*
604 * If we're bypassing flip buffers on rx, we can blast it 596 * If we were unable to get a reference to the ld,
605 * right into the beginning of the buffer. 597 * don't flush our buffer, and act like the ld doesn't
598 * have any space to put the data right now.
606 */ 599 */
607 if (jsm_rawreadok) { 600 if (!ld) {
608 if (tp->real_raw) { 601 len = 0;
609 if (ch->ch_flags & CH_FLIPBUF_IN_USE) {
610 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
611 "JSM - FLIPBUF in use. delaying input\n");
612 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
613 return;
614 }
615 ch->ch_flags |= CH_FLIPBUF_IN_USE;
616 buf = ch->ch_bd->flipbuf;
617 buf2 = NULL;
618 } else {
619 buf = tp->flip.char_buf;
620 buf2 = tp->flip.flag_buf;
621 }
622 } else { 602 } else {
623 buf = tp->flip.char_buf_ptr; 603 /*
624 buf2 = tp->flip.flag_buf_ptr; 604 * If ld doesn't have a pointer to a receive_buf function,
605 * flush the data, then act like the ld doesn't have any
606 * space to put the data right now.
607 */
608 if (!ld->receive_buf) {
609 ch->ch_r_head = ch->ch_r_tail;
610 len = 0;
611 }
625 } 612 }
626 613
614 if (len <= 0) {
615 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
616 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n");
617 if (ld)
618 tty_ldisc_deref(ld);
619 return;
620 }
621
622 len = tty_buffer_request_room(tp, len);
627 n = len; 623 n = len;
628 624
629 /* 625 /*
@@ -638,121 +634,47 @@ void jsm_input(struct jsm_channel *ch)
638 if (s <= 0) 634 if (s <= 0)
639 break; 635 break;
640 636
641 memcpy(buf, ch->ch_rqueue + tail, s); 637 /*
642 638 * If conditions are such that ld needs to see all
643 /* buf2 is only set when port isn't raw */ 639 * UART errors, we will have to walk each character
644 if (buf2) 640 * and error byte and send them to the buffer one at
645 memcpy(buf2, ch->ch_equeue + tail, s); 641 * a time.
646 642 */
647 tail += s;
648 buf += s;
649 if (buf2)
650 buf2 += s;
651 n -= s;
652 /* Flip queue if needed */
653 tail &= rmask;
654 }
655 643
656 /*
657 * In high performance mode, we don't have to update
658 * flag_buf or any of the counts or pointers into flip buf.
659 */
660 if (!jsm_rawreadok) {
661 if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) { 644 if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) {
662 for (i = 0; i < len; i++) { 645 for (i = 0; i < s; i++) {
663 /* 646 /*
664 * Give the Linux ld the flags in the 647 * Give the Linux ld the flags in the
665 * format it likes. 648 * format it likes.
666 */ 649 */
667 if (tp->flip.flag_buf_ptr[i] & UART_LSR_BI) 650 if (*(ch->ch_equeue +tail +i) & UART_LSR_BI)
668 tp->flip.flag_buf_ptr[i] = TTY_BREAK; 651 tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_BREAK);
669 else if (tp->flip.flag_buf_ptr[i] & UART_LSR_PE) 652 else if (*(ch->ch_equeue +tail +i) & UART_LSR_PE)
670 tp->flip.flag_buf_ptr[i] = TTY_PARITY; 653 tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_PARITY);
671 else if (tp->flip.flag_buf_ptr[i] & UART_LSR_FE) 654 else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE)
672 tp->flip.flag_buf_ptr[i] = TTY_FRAME; 655 tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_FRAME);
673 else 656 else
674 tp->flip.flag_buf_ptr[i] = TTY_NORMAL; 657 tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_NORMAL);
675 } 658 }
676 } else { 659 } else {
677 memset(tp->flip.flag_buf_ptr, 0, len); 660 tty_insert_flip_string(tp, ch->ch_rqueue + tail, s) ;
678 } 661 }
679 662 tail += s;
680 tp->flip.char_buf_ptr += len; 663 n -= s;
681 tp->flip.flag_buf_ptr += len; 664 /* Flip queue if needed */
682 tp->flip.count += len; 665 tail &= rmask;
683 }
684 else if (!tp->real_raw) {
685 if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) {
686 for (i = 0; i < len; i++) {
687 /*
688 * Give the Linux ld the flags in the
689 * format it likes.
690 */
691 if (tp->flip.flag_buf_ptr[i] & UART_LSR_BI)
692 tp->flip.flag_buf_ptr[i] = TTY_BREAK;
693 else if (tp->flip.flag_buf_ptr[i] & UART_LSR_PE)
694 tp->flip.flag_buf_ptr[i] = TTY_PARITY;
695 else if (tp->flip.flag_buf_ptr[i] & UART_LSR_FE)
696 tp->flip.flag_buf_ptr[i] = TTY_FRAME;
697 else
698 tp->flip.flag_buf_ptr[i] = TTY_NORMAL;
699 }
700 } else
701 memset(tp->flip.flag_buf, 0, len);
702 } 666 }
703 667
704 /* 668 ch->ch_r_tail = tail & rmask;
705 * If we're doing raw reads, jam it right into the 669 ch->ch_e_tail = tail & rmask;
706 * line disc bypassing the flip buffers. 670 jsm_check_queue_flow_control(ch);
707 */ 671 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
708 if (jsm_rawreadok) {
709 if (tp->real_raw) {
710 ch->ch_r_tail = tail & rmask;
711 ch->ch_e_tail = tail & rmask;
712
713 jsm_check_queue_flow_control(ch);
714
715 /* !!! WE *MUST* LET GO OF ALL LOCKS BEFORE CALLING RECEIVE BUF !!! */
716 672
717 spin_unlock_irqrestore(&ch->ch_lock, lock_flags); 673 /* Tell the tty layer its okay to "eat" the data now */
674 tty_flip_buffer_push(tp);
718 675
719 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, 676 if (ld)
720 "jsm_input. %d real_raw len:%d calling receive_buf for board %d\n", 677 tty_ldisc_deref(ld);
721 __LINE__, len, ch->ch_bd->boardnum);
722 tp->ldisc.receive_buf(tp, ch->ch_bd->flipbuf, NULL, len);
723
724 /* Allow use of channel flip buffer again */
725 spin_lock_irqsave(&ch->ch_lock, lock_flags);
726 ch->ch_flags &= ~CH_FLIPBUF_IN_USE;
727 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
728
729 } else {
730 ch->ch_r_tail = tail & rmask;
731 ch->ch_e_tail = tail & rmask;
732
733 jsm_check_queue_flow_control(ch);
734
735 /* !!! WE *MUST* LET GO OF ALL LOCKS BEFORE CALLING RECEIVE BUF !!! */
736 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
737
738 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
739 "jsm_input. %d not real_raw len:%d calling receive_buf for board %d\n",
740 __LINE__, len, ch->ch_bd->boardnum);
741
742 tp->ldisc.receive_buf(tp, tp->flip.char_buf, tp->flip.flag_buf, len);
743 }
744 } else {
745 ch->ch_r_tail = tail & rmask;
746 ch->ch_e_tail = tail & rmask;
747
748 jsm_check_queue_flow_control(ch);
749
750 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
751
752 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
753 "jsm_input. %d not jsm_read raw okay scheduling flip\n", __LINE__);
754 tty_schedule_flip(tp);
755 }
756 678
757 jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); 679 jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n");
758} 680}