diff options
Diffstat (limited to 'drivers/serial/jsm')
-rw-r--r-- | drivers/serial/jsm/jsm.h | 1 | ||||
-rw-r--r-- | drivers/serial/jsm/jsm_driver.c | 3 | ||||
-rw-r--r-- | drivers/serial/jsm/jsm_neo.c | 85 | ||||
-rw-r--r-- | drivers/serial/jsm/jsm_tty.c | 209 |
4 files changed, 103 insertions, 195 deletions
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h index 18753193f59b..dfc1e86d3aa1 100644 --- a/drivers/serial/jsm/jsm.h +++ b/drivers/serial/jsm/jsm.h | |||
@@ -380,7 +380,6 @@ struct neo_uart_struct { | |||
380 | extern struct uart_driver jsm_uart_driver; | 380 | extern struct uart_driver jsm_uart_driver; |
381 | extern struct board_ops jsm_neo_ops; | 381 | extern struct board_ops jsm_neo_ops; |
382 | extern int jsm_debug; | 382 | extern int jsm_debug; |
383 | extern int jsm_rawreadok; | ||
384 | 383 | ||
385 | /************************************************************************* | 384 | /************************************************************************* |
386 | * | 385 | * |
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c index 7e56c7824194..b1b66e71d281 100644 --- a/drivers/serial/jsm/jsm_driver.c +++ b/drivers/serial/jsm/jsm_driver.c | |||
@@ -49,11 +49,8 @@ struct uart_driver jsm_uart_driver = { | |||
49 | }; | 49 | }; |
50 | 50 | ||
51 | int jsm_debug; | 51 | int jsm_debug; |
52 | int jsm_rawreadok; | ||
53 | module_param(jsm_debug, int, 0); | 52 | module_param(jsm_debug, int, 0); |
54 | module_param(jsm_rawreadok, int, 0); | ||
55 | MODULE_PARM_DESC(jsm_debug, "Driver debugging level"); | 53 | MODULE_PARM_DESC(jsm_debug, "Driver debugging level"); |
56 | MODULE_PARM_DESC(jsm_rawreadok, "Bypass flip buffers on input"); | ||
57 | 54 | ||
58 | static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 55 | static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
59 | { | 56 | { |
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c index 6f22b42d9337..87e4e2cf8ce7 100644 --- a/drivers/serial/jsm/jsm_neo.c +++ b/drivers/serial/jsm/jsm_neo.c | |||
@@ -965,56 +965,47 @@ static void neo_param(struct jsm_channel *ch) | |||
965 | baud = ch->ch_custom_speed; | 965 | baud = ch->ch_custom_speed; |
966 | if (ch->ch_flags & CH_BAUD0) | 966 | if (ch->ch_flags & CH_BAUD0) |
967 | ch->ch_flags &= ~(CH_BAUD0); | 967 | ch->ch_flags &= ~(CH_BAUD0); |
968 | } else { | 968 | } else { |
969 | int iindex = 0; | 969 | int i; |
970 | int jindex = 0; | 970 | unsigned int cflag; |
971 | 971 | static struct { | |
972 | const u64 bauds[4][16] = { | 972 | unsigned int rate; |
973 | { | 973 | unsigned int cflag; |
974 | 0, 50, 75, 110, | 974 | } baud_rates[] = { |
975 | 134, 150, 200, 300, | 975 | { 921600, B921600 }, |
976 | 600, 1200, 1800, 2400, | 976 | { 460800, B460800 }, |
977 | 4800, 9600, 19200, 38400 }, | 977 | { 230400, B230400 }, |
978 | { | 978 | { 115200, B115200 }, |
979 | 0, 57600, 115200, 230400, | 979 | { 57600, B57600 }, |
980 | 460800, 150, 200, 921600, | 980 | { 38400, B38400 }, |
981 | 600, 1200, 1800, 2400, | 981 | { 19200, B19200 }, |
982 | 4800, 9600, 19200, 38400 }, | 982 | { 9600, B9600 }, |
983 | { | 983 | { 4800, B4800 }, |
984 | 0, 57600, 76800, 115200, | 984 | { 2400, B2400 }, |
985 | 131657, 153600, 230400, 460800, | 985 | { 1200, B1200 }, |
986 | 921600, 1200, 1800, 2400, | 986 | { 600, B600 }, |
987 | 4800, 9600, 19200, 38400 }, | 987 | { 300, B300 }, |
988 | { | 988 | { 200, B200 }, |
989 | 0, 57600, 115200, 230400, | 989 | { 150, B150 }, |
990 | 460800, 150, 200, 921600, | 990 | { 134, B134 }, |
991 | 600, 1200, 1800, 2400, | 991 | { 110, B110 }, |
992 | 4800, 9600, 19200, 38400 } | 992 | { 75, B75 }, |
993 | }; | 993 | { 50, B50 }, |
994 | 994 | }; | |
995 | baud = C_BAUD(ch->uart_port.info->tty) & 0xff; | 995 | |
996 | 996 | cflag = C_BAUD(ch->uart_port.info->tty); | |
997 | if (ch->ch_c_cflag & CBAUDEX) | 997 | baud = 9600; |
998 | iindex = 1; | 998 | for (i = 0; i < ARRAY_SIZE(baud_rates); i++) { |
999 | 999 | if (baud_rates[i].cflag == cflag) { | |
1000 | jindex = baud; | 1000 | baud = baud_rates[i].rate; |
1001 | 1001 | break; | |
1002 | if ((iindex >= 0) && (iindex < 4) && (jindex >= 0) && (jindex < 16)) | ||
1003 | baud = bauds[iindex][jindex]; | ||
1004 | else { | ||
1005 | jsm_printk(IOCTL, DEBUG, &ch->ch_bd->pci_dev, | ||
1006 | "baud indices were out of range (%d)(%d)", | ||
1007 | iindex, jindex); | ||
1008 | baud = 0; | ||
1009 | } | 1002 | } |
1010 | |||
1011 | if (baud == 0) | ||
1012 | baud = 9600; | ||
1013 | |||
1014 | if (ch->ch_flags & CH_BAUD0) | ||
1015 | ch->ch_flags &= ~(CH_BAUD0); | ||
1016 | } | 1003 | } |
1017 | 1004 | ||
1005 | if (ch->ch_flags & CH_BAUD0) | ||
1006 | ch->ch_flags &= ~(CH_BAUD0); | ||
1007 | } | ||
1008 | |||
1018 | if (ch->ch_c_cflag & PARENB) | 1009 | if (ch->ch_c_cflag & PARENB) |
1019 | lcr |= UART_LCR_PARITY; | 1010 | lcr |= UART_LCR_PARITY; |
1020 | 1011 | ||
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c index 6fa0d62d6f68..4d48b625cd3d 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,15 @@ 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; | ||
509 | char *buf2 = NULL; | ||
510 | int s = 0; | 511 | int s = 0; |
511 | int i = 0; | 512 | int i = 0; |
512 | 513 | ||
@@ -574,56 +575,50 @@ void jsm_input(struct jsm_channel *ch) | |||
574 | 575 | ||
575 | /* | 576 | /* |
576 | * If the rxbuf is empty and we are not throttled, put as much | 577 | * If the rxbuf is empty and we are not throttled, put as much |
577 | * as we can directly into the linux TTY flip buffer. | 578 | * 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 | * | 579 | * |
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 | */ | 580 | */ |
586 | if (jsm_rawreadok) { | 581 | 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 | 582 | ||
594 | len = min(data_len, flip_len); | 583 | len = min(data_len, flip_len); |
595 | len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt); | 584 | len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt); |
585 | ld = tty_ldisc_ref(tp); | ||
596 | 586 | ||
597 | if (len <= 0) { | 587 | /* |
598 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | 588 | * 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"); | 589 | * like the ld doesn't have any space to put the data right now. |
600 | return; | 590 | */ |
601 | } | 591 | if (test_bit(TTY_DONT_FLIP, &tp->flags)) |
592 | len = 0; | ||
602 | 593 | ||
603 | /* | 594 | /* |
604 | * If we're bypassing flip buffers on rx, we can blast it | 595 | * If we were unable to get a reference to the ld, |
605 | * right into the beginning of the buffer. | 596 | * don't flush our buffer, and act like the ld doesn't |
597 | * have any space to put the data right now. | ||
606 | */ | 598 | */ |
607 | if (jsm_rawreadok) { | 599 | if (!ld) { |
608 | if (tp->real_raw) { | 600 | 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 { | 601 | } else { |
623 | buf = tp->flip.char_buf_ptr; | 602 | /* |
624 | buf2 = tp->flip.flag_buf_ptr; | 603 | * If ld doesn't have a pointer to a receive_buf function, |
604 | * flush the data, then act like the ld doesn't have any | ||
605 | * space to put the data right now. | ||
606 | */ | ||
607 | if (!ld->receive_buf) { | ||
608 | ch->ch_r_head = ch->ch_r_tail; | ||
609 | len = 0; | ||
610 | } | ||
625 | } | 611 | } |
626 | 612 | ||
613 | if (len <= 0) { | ||
614 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | ||
615 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n"); | ||
616 | if (ld) | ||
617 | tty_ldisc_deref(ld); | ||
618 | return; | ||
619 | } | ||
620 | |||
621 | len = tty_buffer_request_room(tp, len); | ||
627 | n = len; | 622 | n = len; |
628 | 623 | ||
629 | /* | 624 | /* |
@@ -638,121 +633,47 @@ void jsm_input(struct jsm_channel *ch) | |||
638 | if (s <= 0) | 633 | if (s <= 0) |
639 | break; | 634 | break; |
640 | 635 | ||
641 | memcpy(buf, ch->ch_rqueue + tail, s); | 636 | /* |
642 | 637 | * If conditions are such that ld needs to see all | |
643 | /* buf2 is only set when port isn't raw */ | 638 | * UART errors, we will have to walk each character |
644 | if (buf2) | 639 | * and error byte and send them to the buffer one at |
645 | memcpy(buf2, ch->ch_equeue + tail, s); | 640 | * a time. |
646 | 641 | */ | |
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 | 642 | ||
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)) { | 643 | if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) { |
662 | for (i = 0; i < len; i++) { | 644 | for (i = 0; i < s; i++) { |
663 | /* | 645 | /* |
664 | * Give the Linux ld the flags in the | 646 | * Give the Linux ld the flags in the |
665 | * format it likes. | 647 | * format it likes. |
666 | */ | 648 | */ |
667 | if (tp->flip.flag_buf_ptr[i] & UART_LSR_BI) | 649 | if (*(ch->ch_equeue +tail +i) & UART_LSR_BI) |
668 | tp->flip.flag_buf_ptr[i] = TTY_BREAK; | 650 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_BREAK); |
669 | else if (tp->flip.flag_buf_ptr[i] & UART_LSR_PE) | 651 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_PE) |
670 | tp->flip.flag_buf_ptr[i] = TTY_PARITY; | 652 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_PARITY); |
671 | else if (tp->flip.flag_buf_ptr[i] & UART_LSR_FE) | 653 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE) |
672 | tp->flip.flag_buf_ptr[i] = TTY_FRAME; | 654 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_FRAME); |
673 | else | 655 | else |
674 | tp->flip.flag_buf_ptr[i] = TTY_NORMAL; | 656 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_NORMAL); |
675 | } | 657 | } |
676 | } else { | 658 | } else { |
677 | memset(tp->flip.flag_buf_ptr, 0, len); | 659 | tty_insert_flip_string(tp, ch->ch_rqueue + tail, s) ; |
678 | } | 660 | } |
679 | 661 | tail += s; | |
680 | tp->flip.char_buf_ptr += len; | 662 | n -= s; |
681 | tp->flip.flag_buf_ptr += len; | 663 | /* Flip queue if needed */ |
682 | tp->flip.count += len; | 664 | 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 | } | 665 | } |
703 | 666 | ||
704 | /* | 667 | ch->ch_r_tail = tail & rmask; |
705 | * If we're doing raw reads, jam it right into the | 668 | ch->ch_e_tail = tail & rmask; |
706 | * line disc bypassing the flip buffers. | 669 | jsm_check_queue_flow_control(ch); |
707 | */ | 670 | 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 | 671 | ||
717 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | 672 | /* Tell the tty layer its okay to "eat" the data now */ |
673 | tty_flip_buffer_push(tp); | ||
718 | 674 | ||
719 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, | 675 | if (ld) |
720 | "jsm_input. %d real_raw len:%d calling receive_buf for board %d\n", | 676 | 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 | 677 | ||
757 | jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); | 678 | jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); |
758 | } | 679 | } |