aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/jsm
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/jsm
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/jsm')
-rw-r--r--drivers/serial/jsm/jsm_tty.c208
1 files changed, 65 insertions, 143 deletions
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}