aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/icom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial/icom.c')
-rw-r--r--drivers/serial/icom.c57
1 files changed, 24 insertions, 33 deletions
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index eb31125c6a30..144a7a352b28 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -729,19 +729,20 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
729 unsigned short int status; 729 unsigned short int status;
730 struct uart_icount *icount; 730 struct uart_icount *icount;
731 unsigned long offset; 731 unsigned long offset;
732 unsigned char flag;
732 733
733 trace(icom_port, "RCV_COMPLETE", 0); 734 trace(icom_port, "RCV_COMPLETE", 0);
734 rcv_buff = icom_port->next_rcv; 735 rcv_buff = icom_port->next_rcv;
735 736
736 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags); 737 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
737 while (status & SA_FL_RCV_DONE) { 738 while (status & SA_FL_RCV_DONE) {
739 int first = -1;
738 740
739 trace(icom_port, "FID_STATUS", status); 741 trace(icom_port, "FID_STATUS", status);
740 count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength); 742 count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
741 743
744 count = tty_buffer_request_room(tty, count);
742 trace(icom_port, "RCV_COUNT", count); 745 trace(icom_port, "RCV_COUNT", count);
743 if (count > (TTY_FLIPBUF_SIZE - tty->flip.count))
744 count = TTY_FLIPBUF_SIZE - tty->flip.count;
745 746
746 trace(icom_port, "REAL_COUNT", count); 747 trace(icom_port, "REAL_COUNT", count);
747 748
@@ -749,15 +750,10 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
749 cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) - 750 cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
750 icom_port->recv_buf_pci; 751 icom_port->recv_buf_pci;
751 752
752 memcpy(tty->flip.char_buf_ptr,(unsigned char *) 753 /* Block copy all but the last byte as this may have status */
753 ((unsigned long)icom_port->recv_buf + offset), count);
754
755 if (count > 0) { 754 if (count > 0) {
756 tty->flip.count += count - 1; 755 first = icom_port->recv_buf[offset];
757 tty->flip.char_buf_ptr += count - 1; 756 tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1);
758
759 memset(tty->flip.flag_buf_ptr, 0, count);
760 tty->flip.flag_buf_ptr += count - 1;
761 } 757 }
762 758
763 icount = &icom_port->uart_port.icount; 759 icount = &icom_port->uart_port.icount;
@@ -765,12 +761,14 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
765 761
766 /* Break detect logic */ 762 /* Break detect logic */
767 if ((status & SA_FLAGS_FRAME_ERROR) 763 if ((status & SA_FLAGS_FRAME_ERROR)
768 && (tty->flip.char_buf_ptr[0] == 0x00)) { 764 && first == 0) {
769 status &= ~SA_FLAGS_FRAME_ERROR; 765 status &= ~SA_FLAGS_FRAME_ERROR;
770 status |= SA_FLAGS_BREAK_DET; 766 status |= SA_FLAGS_BREAK_DET;
771 trace(icom_port, "BREAK_DET", 0); 767 trace(icom_port, "BREAK_DET", 0);
772 } 768 }
773 769
770 flag = TTY_NORMAL;
771
774 if (status & 772 if (status &
775 (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR | 773 (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
776 SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) { 774 SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
@@ -797,33 +795,26 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
797 status &= icom_port->read_status_mask; 795 status &= icom_port->read_status_mask;
798 796
799 if (status & SA_FLAGS_BREAK_DET) { 797 if (status & SA_FLAGS_BREAK_DET) {
800 *tty->flip.flag_buf_ptr = TTY_BREAK; 798 flag = TTY_BREAK;
801 } else if (status & SA_FLAGS_PARITY_ERROR) { 799 } else if (status & SA_FLAGS_PARITY_ERROR) {
802 trace(icom_port, "PARITY_ERROR", 0); 800 trace(icom_port, "PARITY_ERROR", 0);
803 *tty->flip.flag_buf_ptr = TTY_PARITY; 801 flag = TTY_PARITY;
804 } else if (status & SA_FLAGS_FRAME_ERROR) 802 } else if (status & SA_FLAGS_FRAME_ERROR)
805 *tty->flip.flag_buf_ptr = TTY_FRAME; 803 flag = TTY_FRAME;
806 804
807 if (status & SA_FLAGS_OVERRUN) {
808 /*
809 * Overrun is special, since it's
810 * reported immediately, and doesn't
811 * affect the current character
812 */
813 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
814 tty->flip.count++;
815 tty->flip.flag_buf_ptr++;
816 tty->flip.char_buf_ptr++;
817 *tty->flip.flag_buf_ptr = TTY_OVERRUN;
818 }
819 }
820 } 805 }
821 806
822 tty->flip.flag_buf_ptr++; 807 tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag);
823 tty->flip.char_buf_ptr++; 808
824 tty->flip.count++; 809 if (status & SA_FLAGS_OVERRUN)
825 ignore_char: 810 /*
826 icom_port->statStg->rcv[rcv_buff].flags = 0; 811 * Overrun is special, since it's
812 * reported immediately, and doesn't
813 * affect the current character
814 */
815 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
816ignore_char:
817 icom_port->statStg->rcv[rcv_buff].flags = 0;
827 icom_port->statStg->rcv[rcv_buff].leLength = 0; 818 icom_port->statStg->rcv[rcv_buff].leLength = 0;
828 icom_port->statStg->rcv[rcv_buff].WorkingLength = 819 icom_port->statStg->rcv[rcv_buff].WorkingLength =
829 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ); 820 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);