diff options
-rw-r--r-- | drivers/tty/amiserial.c | 91 |
1 files changed, 42 insertions, 49 deletions
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 165cd79faea2..5b87744748d5 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c | |||
@@ -102,7 +102,8 @@ static struct tty_driver *serial_driver; | |||
102 | 102 | ||
103 | static unsigned char current_ctl_bits; | 103 | static unsigned char current_ctl_bits; |
104 | 104 | ||
105 | static void change_speed(struct serial_state *info, struct ktermios *old); | 105 | static void change_speed(struct tty_struct *tty, struct serial_state *info, |
106 | struct ktermios *old); | ||
106 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout); | 107 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout); |
107 | 108 | ||
108 | 109 | ||
@@ -500,7 +501,7 @@ static irqreturn_t ser_tx_int(int irq, void *dev_id) | |||
500 | * --------------------------------------------------------------- | 501 | * --------------------------------------------------------------- |
501 | */ | 502 | */ |
502 | 503 | ||
503 | static int startup(struct serial_state *info) | 504 | static int startup(struct tty_struct *tty, struct serial_state *info) |
504 | { | 505 | { |
505 | unsigned long flags; | 506 | unsigned long flags; |
506 | int retval=0; | 507 | int retval=0; |
@@ -534,9 +535,7 @@ static int startup(struct serial_state *info) | |||
534 | retval = request_irq(IRQ_AMIGA_VERTB, ser_vbl_int, 0, "serial status", info); | 535 | retval = request_irq(IRQ_AMIGA_VERTB, ser_vbl_int, 0, "serial status", info); |
535 | if (retval) { | 536 | if (retval) { |
536 | if (serial_isroot()) { | 537 | if (serial_isroot()) { |
537 | if (info->tty) | 538 | set_bit(TTY_IO_ERROR, &tty->flags); |
538 | set_bit(TTY_IO_ERROR, | ||
539 | &info->tty->flags); | ||
540 | retval = 0; | 539 | retval = 0; |
541 | } | 540 | } |
542 | goto errout; | 541 | goto errout; |
@@ -551,32 +550,29 @@ static int startup(struct serial_state *info) | |||
551 | current_ctl_bits = ciab.pra & (SER_DCD | SER_CTS | SER_DSR); | 550 | current_ctl_bits = ciab.pra & (SER_DCD | SER_CTS | SER_DSR); |
552 | 551 | ||
553 | info->MCR = 0; | 552 | info->MCR = 0; |
554 | if (info->tty->termios->c_cflag & CBAUD) | 553 | if (C_BAUD(tty)) |
555 | info->MCR = SER_DTR | SER_RTS; | 554 | info->MCR = SER_DTR | SER_RTS; |
556 | rtsdtr_ctrl(info->MCR); | 555 | rtsdtr_ctrl(info->MCR); |
557 | 556 | ||
558 | if (info->tty) | 557 | clear_bit(TTY_IO_ERROR, &tty->flags); |
559 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | ||
560 | info->xmit.head = info->xmit.tail = 0; | 558 | info->xmit.head = info->xmit.tail = 0; |
561 | 559 | ||
562 | /* | 560 | /* |
563 | * Set up the tty->alt_speed kludge | 561 | * Set up the tty->alt_speed kludge |
564 | */ | 562 | */ |
565 | if (info->tty) { | 563 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) |
566 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | 564 | tty->alt_speed = 57600; |
567 | info->tty->alt_speed = 57600; | 565 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) |
568 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | 566 | tty->alt_speed = 115200; |
569 | info->tty->alt_speed = 115200; | 567 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) |
570 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) | 568 | tty->alt_speed = 230400; |
571 | info->tty->alt_speed = 230400; | 569 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) |
572 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) | 570 | tty->alt_speed = 460800; |
573 | info->tty->alt_speed = 460800; | ||
574 | } | ||
575 | 571 | ||
576 | /* | 572 | /* |
577 | * and set the speed of the serial port | 573 | * and set the speed of the serial port |
578 | */ | 574 | */ |
579 | change_speed(info, NULL); | 575 | change_speed(tty, info, NULL); |
580 | 576 | ||
581 | info->flags |= ASYNC_INITIALIZED; | 577 | info->flags |= ASYNC_INITIALIZED; |
582 | local_irq_restore(flags); | 578 | local_irq_restore(flags); |
@@ -591,7 +587,7 @@ errout: | |||
591 | * This routine will shutdown a serial port; interrupts are disabled, and | 587 | * This routine will shutdown a serial port; interrupts are disabled, and |
592 | * DTR is dropped if the hangup on close termio flag is on. | 588 | * DTR is dropped if the hangup on close termio flag is on. |
593 | */ | 589 | */ |
594 | static void shutdown(struct serial_state *info) | 590 | static void shutdown(struct tty_struct *tty, struct serial_state *info) |
595 | { | 591 | { |
596 | unsigned long flags; | 592 | unsigned long flags; |
597 | struct serial_state *state; | 593 | struct serial_state *state; |
@@ -631,12 +627,11 @@ static void shutdown(struct serial_state *info) | |||
631 | custom.adkcon = AC_UARTBRK; | 627 | custom.adkcon = AC_UARTBRK; |
632 | mb(); | 628 | mb(); |
633 | 629 | ||
634 | if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) | 630 | if (tty->termios->c_cflag & HUPCL) |
635 | info->MCR &= ~(SER_DTR|SER_RTS); | 631 | info->MCR &= ~(SER_DTR|SER_RTS); |
636 | rtsdtr_ctrl(info->MCR); | 632 | rtsdtr_ctrl(info->MCR); |
637 | 633 | ||
638 | if (info->tty) | 634 | set_bit(TTY_IO_ERROR, &tty->flags); |
639 | set_bit(TTY_IO_ERROR, &info->tty->flags); | ||
640 | 635 | ||
641 | info->flags &= ~ASYNC_INITIALIZED; | 636 | info->flags &= ~ASYNC_INITIALIZED; |
642 | local_irq_restore(flags); | 637 | local_irq_restore(flags); |
@@ -647,7 +642,7 @@ static void shutdown(struct serial_state *info) | |||
647 | * This routine is called to set the UART divisor registers to match | 642 | * This routine is called to set the UART divisor registers to match |
648 | * the specified baud rate for a serial port. | 643 | * the specified baud rate for a serial port. |
649 | */ | 644 | */ |
650 | static void change_speed(struct serial_state *info, | 645 | static void change_speed(struct tty_struct *tty, struct serial_state *info, |
651 | struct ktermios *old_termios) | 646 | struct ktermios *old_termios) |
652 | { | 647 | { |
653 | int quot = 0, baud_base, baud; | 648 | int quot = 0, baud_base, baud; |
@@ -655,9 +650,7 @@ static void change_speed(struct serial_state *info, | |||
655 | int bits; | 650 | int bits; |
656 | unsigned long flags; | 651 | unsigned long flags; |
657 | 652 | ||
658 | if (!info->tty || !info->tty->termios) | 653 | cflag = tty->termios->c_cflag; |
659 | return; | ||
660 | cflag = info->tty->termios->c_cflag; | ||
661 | 654 | ||
662 | /* Byte size is always 8 bits plus parity bit if requested */ | 655 | /* Byte size is always 8 bits plus parity bit if requested */ |
663 | 656 | ||
@@ -678,7 +671,7 @@ static void change_speed(struct serial_state *info, | |||
678 | #endif | 671 | #endif |
679 | 672 | ||
680 | /* Determine divisor based on baud rate */ | 673 | /* Determine divisor based on baud rate */ |
681 | baud = tty_get_baud_rate(info->tty); | 674 | baud = tty_get_baud_rate(tty); |
682 | if (!baud) | 675 | if (!baud) |
683 | baud = 9600; /* B0 transition handled in rs_set_termios */ | 676 | baud = 9600; /* B0 transition handled in rs_set_termios */ |
684 | baud_base = info->baud_base; | 677 | baud_base = info->baud_base; |
@@ -695,9 +688,9 @@ static void change_speed(struct serial_state *info, | |||
695 | /* If the quotient is zero refuse the change */ | 688 | /* If the quotient is zero refuse the change */ |
696 | if (!quot && old_termios) { | 689 | if (!quot && old_termios) { |
697 | /* FIXME: Will need updating for new tty in the end */ | 690 | /* FIXME: Will need updating for new tty in the end */ |
698 | info->tty->termios->c_cflag &= ~CBAUD; | 691 | tty->termios->c_cflag &= ~CBAUD; |
699 | info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); | 692 | tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); |
700 | baud = tty_get_baud_rate(info->tty); | 693 | baud = tty_get_baud_rate(tty); |
701 | if (!baud) | 694 | if (!baud) |
702 | baud = 9600; | 695 | baud = 9600; |
703 | if (baud == 38400 && | 696 | if (baud == 38400 && |
@@ -742,24 +735,24 @@ static void change_speed(struct serial_state *info, | |||
742 | */ | 735 | */ |
743 | 736 | ||
744 | info->read_status_mask = UART_LSR_OE | UART_LSR_DR; | 737 | info->read_status_mask = UART_LSR_OE | UART_LSR_DR; |
745 | if (I_INPCK(info->tty)) | 738 | if (I_INPCK(tty)) |
746 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; | 739 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; |
747 | if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) | 740 | if (I_BRKINT(tty) || I_PARMRK(tty)) |
748 | info->read_status_mask |= UART_LSR_BI; | 741 | info->read_status_mask |= UART_LSR_BI; |
749 | 742 | ||
750 | /* | 743 | /* |
751 | * Characters to ignore | 744 | * Characters to ignore |
752 | */ | 745 | */ |
753 | info->ignore_status_mask = 0; | 746 | info->ignore_status_mask = 0; |
754 | if (I_IGNPAR(info->tty)) | 747 | if (I_IGNPAR(tty)) |
755 | info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; | 748 | info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; |
756 | if (I_IGNBRK(info->tty)) { | 749 | if (I_IGNBRK(tty)) { |
757 | info->ignore_status_mask |= UART_LSR_BI; | 750 | info->ignore_status_mask |= UART_LSR_BI; |
758 | /* | 751 | /* |
759 | * If we're ignore parity and break indicators, ignore | 752 | * If we're ignore parity and break indicators, ignore |
760 | * overruns too. (For real raw support). | 753 | * overruns too. (For real raw support). |
761 | */ | 754 | */ |
762 | if (I_IGNPAR(info->tty)) | 755 | if (I_IGNPAR(tty)) |
763 | info->ignore_status_mask |= UART_LSR_OE; | 756 | info->ignore_status_mask |= UART_LSR_OE; |
764 | } | 757 | } |
765 | /* | 758 | /* |
@@ -1038,7 +1031,7 @@ static int get_serial_info(struct serial_state *state, | |||
1038 | return 0; | 1031 | return 0; |
1039 | } | 1032 | } |
1040 | 1033 | ||
1041 | static int set_serial_info(struct serial_state *state, | 1034 | static int set_serial_info(struct tty_struct *tty, struct serial_state *state, |
1042 | struct serial_struct __user * new_info) | 1035 | struct serial_struct __user * new_info) |
1043 | { | 1036 | { |
1044 | struct serial_struct new_serial; | 1037 | struct serial_struct new_serial; |
@@ -1086,23 +1079,23 @@ static int set_serial_info(struct serial_state *state, | |||
1086 | state->custom_divisor = new_serial.custom_divisor; | 1079 | state->custom_divisor = new_serial.custom_divisor; |
1087 | state->close_delay = new_serial.close_delay * HZ/100; | 1080 | state->close_delay = new_serial.close_delay * HZ/100; |
1088 | state->closing_wait = new_serial.closing_wait * HZ/100; | 1081 | state->closing_wait = new_serial.closing_wait * HZ/100; |
1089 | state->tty->low_latency = (state->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1082 | tty->low_latency = (state->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1090 | 1083 | ||
1091 | check_and_exit: | 1084 | check_and_exit: |
1092 | if (state->flags & ASYNC_INITIALIZED) { | 1085 | if (state->flags & ASYNC_INITIALIZED) { |
1093 | if (change_spd) { | 1086 | if (change_spd) { |
1094 | if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | 1087 | if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) |
1095 | state->tty->alt_speed = 57600; | 1088 | tty->alt_speed = 57600; |
1096 | if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | 1089 | if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) |
1097 | state->tty->alt_speed = 115200; | 1090 | tty->alt_speed = 115200; |
1098 | if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) | 1091 | if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) |
1099 | state->tty->alt_speed = 230400; | 1092 | tty->alt_speed = 230400; |
1100 | if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) | 1093 | if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) |
1101 | state->tty->alt_speed = 460800; | 1094 | tty->alt_speed = 460800; |
1102 | change_speed(state, NULL); | 1095 | change_speed(tty, state, NULL); |
1103 | } | 1096 | } |
1104 | } else | 1097 | } else |
1105 | retval = startup(state); | 1098 | retval = startup(tty, state); |
1106 | tty_unlock(); | 1099 | tty_unlock(); |
1107 | return retval; | 1100 | return retval; |
1108 | } | 1101 | } |
@@ -1256,7 +1249,7 @@ static int rs_ioctl(struct tty_struct *tty, | |||
1256 | case TIOCGSERIAL: | 1249 | case TIOCGSERIAL: |
1257 | return get_serial_info(info, argp); | 1250 | return get_serial_info(info, argp); |
1258 | case TIOCSSERIAL: | 1251 | case TIOCSSERIAL: |
1259 | return set_serial_info(info, argp); | 1252 | return set_serial_info(tty, info, argp); |
1260 | case TIOCSERCONFIG: | 1253 | case TIOCSERCONFIG: |
1261 | return 0; | 1254 | return 0; |
1262 | 1255 | ||
@@ -1319,7 +1312,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1319 | unsigned long flags; | 1312 | unsigned long flags; |
1320 | unsigned int cflag = tty->termios->c_cflag; | 1313 | unsigned int cflag = tty->termios->c_cflag; |
1321 | 1314 | ||
1322 | change_speed(info, old_termios); | 1315 | change_speed(tty, info, old_termios); |
1323 | 1316 | ||
1324 | /* Handle transition to B0 status */ | 1317 | /* Handle transition to B0 status */ |
1325 | if ((old_termios->c_cflag & CBAUD) && | 1318 | if ((old_termios->c_cflag & CBAUD) && |
@@ -1444,7 +1437,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1444 | */ | 1437 | */ |
1445 | rs_wait_until_sent(tty, state->timeout); | 1438 | rs_wait_until_sent(tty, state->timeout); |
1446 | } | 1439 | } |
1447 | shutdown(state); | 1440 | shutdown(tty, state); |
1448 | rs_flush_buffer(tty); | 1441 | rs_flush_buffer(tty); |
1449 | 1442 | ||
1450 | tty_ldisc_flush(tty); | 1443 | tty_ldisc_flush(tty); |
@@ -1535,7 +1528,7 @@ static void rs_hangup(struct tty_struct *tty) | |||
1535 | return; | 1528 | return; |
1536 | 1529 | ||
1537 | rs_flush_buffer(tty); | 1530 | rs_flush_buffer(tty); |
1538 | shutdown(info); | 1531 | shutdown(tty, info); |
1539 | info->count = 0; | 1532 | info->count = 0; |
1540 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | 1533 | info->flags &= ~ASYNC_NORMAL_ACTIVE; |
1541 | info->tty = NULL; | 1534 | info->tty = NULL; |
@@ -1696,7 +1689,7 @@ static int rs_open(struct tty_struct *tty, struct file * filp) | |||
1696 | /* | 1689 | /* |
1697 | * Start up serial port | 1690 | * Start up serial port |
1698 | */ | 1691 | */ |
1699 | retval = startup(info); | 1692 | retval = startup(tty, info); |
1700 | if (retval) { | 1693 | if (retval) { |
1701 | return retval; | 1694 | return retval; |
1702 | } | 1695 | } |