diff options
Diffstat (limited to 'drivers/char/isicom.c')
-rw-r--r-- | drivers/char/isicom.c | 181 |
1 files changed, 79 insertions, 102 deletions
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index a1a67e3d52c..5a53c15b0dc 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -198,17 +198,12 @@ struct isi_board { | |||
198 | 198 | ||
199 | struct isi_port { | 199 | struct isi_port { |
200 | unsigned short magic; | 200 | unsigned short magic; |
201 | unsigned int flags; | 201 | struct tty_port port; |
202 | int count; | ||
203 | int blocked_open; | ||
204 | int close_delay; | 202 | int close_delay; |
205 | u16 channel; | 203 | u16 channel; |
206 | u16 status; | 204 | u16 status; |
207 | u16 closing_wait; | 205 | u16 closing_wait; |
208 | struct isi_board *card; | 206 | struct isi_board *card; |
209 | struct tty_struct *tty; | ||
210 | wait_queue_head_t close_wait; | ||
211 | wait_queue_head_t open_wait; | ||
212 | unsigned char *xmit_buf; | 207 | unsigned char *xmit_buf; |
213 | int xmit_head; | 208 | int xmit_head; |
214 | int xmit_tail; | 209 | int xmit_tail; |
@@ -430,11 +425,11 @@ static void isicom_tx(unsigned long _data) | |||
430 | 425 | ||
431 | for (; count > 0; count--, port++) { | 426 | for (; count > 0; count--, port++) { |
432 | /* port not active or tx disabled to force flow control */ | 427 | /* port not active or tx disabled to force flow control */ |
433 | if (!(port->flags & ASYNC_INITIALIZED) || | 428 | if (!(port->port.flags & ASYNC_INITIALIZED) || |
434 | !(port->status & ISI_TXOK)) | 429 | !(port->status & ISI_TXOK)) |
435 | continue; | 430 | continue; |
436 | 431 | ||
437 | tty = port->tty; | 432 | tty = port->port.tty; |
438 | 433 | ||
439 | if (tty == NULL) | 434 | if (tty == NULL) |
440 | continue; | 435 | continue; |
@@ -458,7 +453,7 @@ static void isicom_tx(unsigned long _data) | |||
458 | if (residue == YES) { | 453 | if (residue == YES) { |
459 | residue = NO; | 454 | residue = NO; |
460 | if (cnt > 0) { | 455 | if (cnt > 0) { |
461 | wrd |= (port->xmit_buf[port->xmit_tail] | 456 | wrd |= (port->port.xmit_buf[port->xmit_tail] |
462 | << 8); | 457 | << 8); |
463 | port->xmit_tail = (port->xmit_tail + 1) | 458 | port->xmit_tail = (port->xmit_tail + 1) |
464 | & (SERIAL_XMIT_SIZE - 1); | 459 | & (SERIAL_XMIT_SIZE - 1); |
@@ -474,14 +469,14 @@ static void isicom_tx(unsigned long _data) | |||
474 | if (cnt <= 0) | 469 | if (cnt <= 0) |
475 | break; | 470 | break; |
476 | word_count = cnt >> 1; | 471 | word_count = cnt >> 1; |
477 | outsw(base, port->xmit_buf+port->xmit_tail, word_count); | 472 | outsw(base, port->port.xmit_buf+port->xmit_tail, word_count); |
478 | port->xmit_tail = (port->xmit_tail | 473 | port->xmit_tail = (port->xmit_tail |
479 | + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1); | 474 | + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1); |
480 | txcount -= (word_count << 1); | 475 | txcount -= (word_count << 1); |
481 | port->xmit_cnt -= (word_count << 1); | 476 | port->xmit_cnt -= (word_count << 1); |
482 | if (cnt & 0x0001) { | 477 | if (cnt & 0x0001) { |
483 | residue = YES; | 478 | residue = YES; |
484 | wrd = port->xmit_buf[port->xmit_tail]; | 479 | wrd = port->port.xmit_buf[port->xmit_tail]; |
485 | port->xmit_tail = (port->xmit_tail + 1) | 480 | port->xmit_tail = (port->xmit_tail + 1) |
486 | & (SERIAL_XMIT_SIZE - 1); | 481 | & (SERIAL_XMIT_SIZE - 1); |
487 | port->xmit_cnt--; | 482 | port->xmit_cnt--; |
@@ -548,13 +543,13 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
548 | return IRQ_HANDLED; | 543 | return IRQ_HANDLED; |
549 | } | 544 | } |
550 | port = card->ports + channel; | 545 | port = card->ports + channel; |
551 | if (!(port->flags & ASYNC_INITIALIZED)) { | 546 | if (!(port->port.flags & ASYNC_INITIALIZED)) { |
552 | outw(0x0000, base+0x04); /* enable interrupts */ | 547 | outw(0x0000, base+0x04); /* enable interrupts */ |
553 | spin_unlock(&card->card_lock); | 548 | spin_unlock(&card->card_lock); |
554 | return IRQ_HANDLED; | 549 | return IRQ_HANDLED; |
555 | } | 550 | } |
556 | 551 | ||
557 | tty = port->tty; | 552 | tty = port->port.tty; |
558 | if (tty == NULL) { | 553 | if (tty == NULL) { |
559 | word_count = byte_count >> 1; | 554 | word_count = byte_count >> 1; |
560 | while (byte_count > 1) { | 555 | while (byte_count > 1) { |
@@ -572,7 +567,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
572 | header = inw(base); | 567 | header = inw(base); |
573 | switch (header & 0xff) { | 568 | switch (header & 0xff) { |
574 | case 0: /* Change in EIA signals */ | 569 | case 0: /* Change in EIA signals */ |
575 | if (port->flags & ASYNC_CHECK_CD) { | 570 | if (port->port.flags & ASYNC_CHECK_CD) { |
576 | if (port->status & ISI_DCD) { | 571 | if (port->status & ISI_DCD) { |
577 | if (!(header & ISI_DCD)) { | 572 | if (!(header & ISI_DCD)) { |
578 | /* Carrier has been lost */ | 573 | /* Carrier has been lost */ |
@@ -585,7 +580,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
585 | /* Carrier has been detected */ | 580 | /* Carrier has been detected */ |
586 | pr_dbg("interrupt: DCD->high.\n"); | 581 | pr_dbg("interrupt: DCD->high.\n"); |
587 | port->status |= ISI_DCD; | 582 | port->status |= ISI_DCD; |
588 | wake_up_interruptible(&port->open_wait); | 583 | wake_up_interruptible(&port->port.open_wait); |
589 | } | 584 | } |
590 | } else { | 585 | } else { |
591 | if (header & ISI_DCD) | 586 | if (header & ISI_DCD) |
@@ -594,17 +589,17 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
594 | port->status &= ~ISI_DCD; | 589 | port->status &= ~ISI_DCD; |
595 | } | 590 | } |
596 | 591 | ||
597 | if (port->flags & ASYNC_CTS_FLOW) { | 592 | if (port->port.flags & ASYNC_CTS_FLOW) { |
598 | if (port->tty->hw_stopped) { | 593 | if (port->port.tty->hw_stopped) { |
599 | if (header & ISI_CTS) { | 594 | if (header & ISI_CTS) { |
600 | port->tty->hw_stopped = 0; | 595 | port->port.tty->hw_stopped = 0; |
601 | /* start tx ing */ | 596 | /* start tx ing */ |
602 | port->status |= (ISI_TXOK | 597 | port->status |= (ISI_TXOK |
603 | | ISI_CTS); | 598 | | ISI_CTS); |
604 | tty_wakeup(tty); | 599 | tty_wakeup(tty); |
605 | } | 600 | } |
606 | } else if (!(header & ISI_CTS)) { | 601 | } else if (!(header & ISI_CTS)) { |
607 | port->tty->hw_stopped = 1; | 602 | port->port.tty->hw_stopped = 1; |
608 | /* stop tx ing */ | 603 | /* stop tx ing */ |
609 | port->status &= ~(ISI_TXOK | ISI_CTS); | 604 | port->status &= ~(ISI_TXOK | ISI_CTS); |
610 | } | 605 | } |
@@ -629,7 +624,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
629 | 624 | ||
630 | case 1: /* Received Break !!! */ | 625 | case 1: /* Received Break !!! */ |
631 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 626 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
632 | if (port->flags & ASYNC_SAK) | 627 | if (port->port.flags & ASYNC_SAK) |
633 | do_SAK(tty); | 628 | do_SAK(tty); |
634 | tty_flip_buffer_push(tty); | 629 | tty_flip_buffer_push(tty); |
635 | break; | 630 | break; |
@@ -681,7 +676,7 @@ static void isicom_config_port(struct isi_port *port) | |||
681 | shift_count = card->shift_count; | 676 | shift_count = card->shift_count; |
682 | unsigned char flow_ctrl; | 677 | unsigned char flow_ctrl; |
683 | 678 | ||
684 | tty = port->tty; | 679 | tty = port->port.tty; |
685 | 680 | ||
686 | if (tty == NULL) | 681 | if (tty == NULL) |
687 | return; | 682 | return; |
@@ -697,7 +692,7 @@ static void isicom_config_port(struct isi_port *port) | |||
697 | 692 | ||
698 | /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ | 693 | /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ |
699 | if (baud < 1 || baud > 4) | 694 | if (baud < 1 || baud > 4) |
700 | port->tty->termios->c_cflag &= ~CBAUDEX; | 695 | port->port.tty->termios->c_cflag &= ~CBAUDEX; |
701 | else | 696 | else |
702 | baud += 15; | 697 | baud += 15; |
703 | } | 698 | } |
@@ -708,13 +703,13 @@ static void isicom_config_port(struct isi_port *port) | |||
708 | * the 'setserial' utility. | 703 | * the 'setserial' utility. |
709 | */ | 704 | */ |
710 | 705 | ||
711 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | 706 | if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) |
712 | baud++; /* 57.6 Kbps */ | 707 | baud++; /* 57.6 Kbps */ |
713 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | 708 | if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) |
714 | baud += 2; /* 115 Kbps */ | 709 | baud += 2; /* 115 Kbps */ |
715 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) | 710 | if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) |
716 | baud += 3; /* 230 kbps*/ | 711 | baud += 3; /* 230 kbps*/ |
717 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) | 712 | if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) |
718 | baud += 4; /* 460 kbps*/ | 713 | baud += 4; /* 460 kbps*/ |
719 | } | 714 | } |
720 | if (linuxb_to_isib[baud] == -1) { | 715 | if (linuxb_to_isib[baud] == -1) { |
@@ -754,15 +749,15 @@ static void isicom_config_port(struct isi_port *port) | |||
754 | InterruptTheCard(base); | 749 | InterruptTheCard(base); |
755 | } | 750 | } |
756 | if (C_CLOCAL(tty)) | 751 | if (C_CLOCAL(tty)) |
757 | port->flags &= ~ASYNC_CHECK_CD; | 752 | port->port.flags &= ~ASYNC_CHECK_CD; |
758 | else | 753 | else |
759 | port->flags |= ASYNC_CHECK_CD; | 754 | port->port.flags |= ASYNC_CHECK_CD; |
760 | 755 | ||
761 | /* flow control settings ...*/ | 756 | /* flow control settings ...*/ |
762 | flow_ctrl = 0; | 757 | flow_ctrl = 0; |
763 | port->flags &= ~ASYNC_CTS_FLOW; | 758 | port->port.flags &= ~ASYNC_CTS_FLOW; |
764 | if (C_CRTSCTS(tty)) { | 759 | if (C_CRTSCTS(tty)) { |
765 | port->flags |= ASYNC_CTS_FLOW; | 760 | port->port.flags |= ASYNC_CTS_FLOW; |
766 | flow_ctrl |= ISICOM_CTSRTS; | 761 | flow_ctrl |= ISICOM_CTSRTS; |
767 | } | 762 | } |
768 | if (I_IXON(tty)) | 763 | if (I_IXON(tty)) |
@@ -809,23 +804,15 @@ static int isicom_setup_port(struct isi_port *port) | |||
809 | struct isi_board *card = port->card; | 804 | struct isi_board *card = port->card; |
810 | unsigned long flags; | 805 | unsigned long flags; |
811 | 806 | ||
812 | if (port->flags & ASYNC_INITIALIZED) | 807 | if (port->port.flags & ASYNC_INITIALIZED) |
813 | return 0; | 808 | return 0; |
814 | if (!port->xmit_buf) { | 809 | if (tty_port_alloc_xmit_buf(&port->port) < 0) |
815 | /* Relies on BKL */ | 810 | return -ENOMEM; |
816 | unsigned long page = get_zeroed_page(GFP_KERNEL); | ||
817 | if (page == 0) | ||
818 | return -ENOMEM; | ||
819 | if (port->xmit_buf) | ||
820 | free_page(page); | ||
821 | else | ||
822 | port->xmit_buf = (unsigned char *) page; | ||
823 | } | ||
824 | 811 | ||
825 | spin_lock_irqsave(&card->card_lock, flags); | 812 | spin_lock_irqsave(&card->card_lock, flags); |
826 | if (port->tty) | 813 | if (port->port.tty) |
827 | clear_bit(TTY_IO_ERROR, &port->tty->flags); | 814 | clear_bit(TTY_IO_ERROR, &port->port.tty->flags); |
828 | if (port->count == 1) | 815 | if (port->port.count == 1) |
829 | card->count++; | 816 | card->count++; |
830 | 817 | ||
831 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | 818 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; |
@@ -839,7 +826,7 @@ static int isicom_setup_port(struct isi_port *port) | |||
839 | } | 826 | } |
840 | 827 | ||
841 | isicom_config_port(port); | 828 | isicom_config_port(port); |
842 | port->flags |= ASYNC_INITIALIZED; | 829 | port->port.flags |= ASYNC_INITIALIZED; |
843 | spin_unlock_irqrestore(&card->card_lock, flags); | 830 | spin_unlock_irqrestore(&card->card_lock, flags); |
844 | 831 | ||
845 | return 0; | 832 | return 0; |
@@ -855,10 +842,10 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
855 | 842 | ||
856 | /* block if port is in the process of being closed */ | 843 | /* block if port is in the process of being closed */ |
857 | 844 | ||
858 | if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { | 845 | if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) { |
859 | pr_dbg("block_til_ready: close in progress.\n"); | 846 | pr_dbg("block_til_ready: close in progress.\n"); |
860 | interruptible_sleep_on(&port->close_wait); | 847 | interruptible_sleep_on(&port->port.close_wait); |
861 | if (port->flags & ASYNC_HUP_NOTIFY) | 848 | if (port->port.flags & ASYNC_HUP_NOTIFY) |
862 | return -EAGAIN; | 849 | return -EAGAIN; |
863 | else | 850 | else |
864 | return -ERESTARTSYS; | 851 | return -ERESTARTSYS; |
@@ -869,7 +856,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
869 | if ((filp->f_flags & O_NONBLOCK) || | 856 | if ((filp->f_flags & O_NONBLOCK) || |
870 | (tty->flags & (1 << TTY_IO_ERROR))) { | 857 | (tty->flags & (1 << TTY_IO_ERROR))) { |
871 | pr_dbg("block_til_ready: non-block mode.\n"); | 858 | pr_dbg("block_til_ready: non-block mode.\n"); |
872 | port->flags |= ASYNC_NORMAL_ACTIVE; | 859 | port->port.flags |= ASYNC_NORMAL_ACTIVE; |
873 | return 0; | 860 | return 0; |
874 | } | 861 | } |
875 | 862 | ||
@@ -879,26 +866,26 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
879 | /* block waiting for DCD to be asserted, and while | 866 | /* block waiting for DCD to be asserted, and while |
880 | callout dev is busy */ | 867 | callout dev is busy */ |
881 | retval = 0; | 868 | retval = 0; |
882 | add_wait_queue(&port->open_wait, &wait); | 869 | add_wait_queue(&port->port.open_wait, &wait); |
883 | 870 | ||
884 | spin_lock_irqsave(&card->card_lock, flags); | 871 | spin_lock_irqsave(&card->card_lock, flags); |
885 | if (!tty_hung_up_p(filp)) | 872 | if (!tty_hung_up_p(filp)) |
886 | port->count--; | 873 | port->port.count--; |
887 | port->blocked_open++; | 874 | port->port.blocked_open++; |
888 | spin_unlock_irqrestore(&card->card_lock, flags); | 875 | spin_unlock_irqrestore(&card->card_lock, flags); |
889 | 876 | ||
890 | while (1) { | 877 | while (1) { |
891 | raise_dtr_rts(port); | 878 | raise_dtr_rts(port); |
892 | 879 | ||
893 | set_current_state(TASK_INTERRUPTIBLE); | 880 | set_current_state(TASK_INTERRUPTIBLE); |
894 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { | 881 | if (tty_hung_up_p(filp) || !(port->port.flags & ASYNC_INITIALIZED)) { |
895 | if (port->flags & ASYNC_HUP_NOTIFY) | 882 | if (port->port.flags & ASYNC_HUP_NOTIFY) |
896 | retval = -EAGAIN; | 883 | retval = -EAGAIN; |
897 | else | 884 | else |
898 | retval = -ERESTARTSYS; | 885 | retval = -ERESTARTSYS; |
899 | break; | 886 | break; |
900 | } | 887 | } |
901 | if (!(port->flags & ASYNC_CLOSING) && | 888 | if (!(port->port.flags & ASYNC_CLOSING) && |
902 | (do_clocal || (port->status & ISI_DCD))) { | 889 | (do_clocal || (port->status & ISI_DCD))) { |
903 | break; | 890 | break; |
904 | } | 891 | } |
@@ -909,15 +896,15 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
909 | schedule(); | 896 | schedule(); |
910 | } | 897 | } |
911 | set_current_state(TASK_RUNNING); | 898 | set_current_state(TASK_RUNNING); |
912 | remove_wait_queue(&port->open_wait, &wait); | 899 | remove_wait_queue(&port->port.open_wait, &wait); |
913 | spin_lock_irqsave(&card->card_lock, flags); | 900 | spin_lock_irqsave(&card->card_lock, flags); |
914 | if (!tty_hung_up_p(filp)) | 901 | if (!tty_hung_up_p(filp)) |
915 | port->count++; | 902 | port->port.count++; |
916 | port->blocked_open--; | 903 | port->port.blocked_open--; |
917 | spin_unlock_irqrestore(&card->card_lock, flags); | 904 | spin_unlock_irqrestore(&card->card_lock, flags); |
918 | if (retval) | 905 | if (retval) |
919 | return retval; | 906 | return retval; |
920 | port->flags |= ASYNC_NORMAL_ACTIVE; | 907 | port->port.flags |= ASYNC_NORMAL_ACTIVE; |
921 | return 0; | 908 | return 0; |
922 | } | 909 | } |
923 | 910 | ||
@@ -947,9 +934,9 @@ static int isicom_open(struct tty_struct *tty, struct file *filp) | |||
947 | 934 | ||
948 | isicom_setup_board(card); | 935 | isicom_setup_board(card); |
949 | 936 | ||
950 | port->count++; | 937 | port->port.count++; |
951 | tty->driver_data = port; | 938 | tty->driver_data = port; |
952 | port->tty = tty; | 939 | port->port.tty = tty; |
953 | error = isicom_setup_port(port); | 940 | error = isicom_setup_port(port); |
954 | if (error == 0) | 941 | if (error == 0) |
955 | error = block_til_ready(tty, filp, port); | 942 | error = block_til_ready(tty, filp, port); |
@@ -970,18 +957,15 @@ static void isicom_shutdown_port(struct isi_port *port) | |||
970 | struct isi_board *card = port->card; | 957 | struct isi_board *card = port->card; |
971 | struct tty_struct *tty; | 958 | struct tty_struct *tty; |
972 | 959 | ||
973 | tty = port->tty; | 960 | tty = port->port.tty; |
974 | 961 | ||
975 | if (!(port->flags & ASYNC_INITIALIZED)) | 962 | if (!(port->port.flags & ASYNC_INITIALIZED)) |
976 | return; | 963 | return; |
977 | 964 | ||
978 | if (port->xmit_buf) { | 965 | tty_port_free_xmit_buf(&port->port); |
979 | free_page((unsigned long) port->xmit_buf); | 966 | port->port.flags &= ~ASYNC_INITIALIZED; |
980 | port->xmit_buf = NULL; | ||
981 | } | ||
982 | port->flags &= ~ASYNC_INITIALIZED; | ||
983 | /* 3rd October 2000 : Vinayak P Risbud */ | 967 | /* 3rd October 2000 : Vinayak P Risbud */ |
984 | port->tty = NULL; | 968 | port->port.tty = NULL; |
985 | 969 | ||
986 | /*Fix done by Anil .S on 30-04-2001 | 970 | /*Fix done by Anil .S on 30-04-2001 |
987 | remote login through isi port has dtr toggle problem | 971 | remote login through isi port has dtr toggle problem |
@@ -1046,24 +1030,24 @@ static void isicom_close(struct tty_struct *tty, struct file *filp) | |||
1046 | return; | 1030 | return; |
1047 | } | 1031 | } |
1048 | 1032 | ||
1049 | if (tty->count == 1 && port->count != 1) { | 1033 | if (tty->count == 1 && port->port.count != 1) { |
1050 | printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port " | 1034 | printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port " |
1051 | "count tty->count = 1 port count = %d.\n", | 1035 | "count tty->count = 1 port count = %d.\n", |
1052 | card->base, port->count); | 1036 | card->base, port->port.count); |
1053 | port->count = 1; | 1037 | port->port.count = 1; |
1054 | } | 1038 | } |
1055 | if (--port->count < 0) { | 1039 | if (--port->port.count < 0) { |
1056 | printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port " | 1040 | printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port " |
1057 | "count for channel%d = %d", card->base, port->channel, | 1041 | "count for channel%d = %d", card->base, port->channel, |
1058 | port->count); | 1042 | port->port.count); |
1059 | port->count = 0; | 1043 | port->port.count = 0; |
1060 | } | 1044 | } |
1061 | 1045 | ||
1062 | if (port->count) { | 1046 | if (port->port.count) { |
1063 | spin_unlock_irqrestore(&card->card_lock, flags); | 1047 | spin_unlock_irqrestore(&card->card_lock, flags); |
1064 | return; | 1048 | return; |
1065 | } | 1049 | } |
1066 | port->flags |= ASYNC_CLOSING; | 1050 | port->port.flags |= ASYNC_CLOSING; |
1067 | tty->closing = 1; | 1051 | tty->closing = 1; |
1068 | spin_unlock_irqrestore(&card->card_lock, flags); | 1052 | spin_unlock_irqrestore(&card->card_lock, flags); |
1069 | 1053 | ||
@@ -1072,7 +1056,7 @@ static void isicom_close(struct tty_struct *tty, struct file *filp) | |||
1072 | /* indicate to the card that no more data can be received | 1056 | /* indicate to the card that no more data can be received |
1073 | on this port */ | 1057 | on this port */ |
1074 | spin_lock_irqsave(&card->card_lock, flags); | 1058 | spin_lock_irqsave(&card->card_lock, flags); |
1075 | if (port->flags & ASYNC_INITIALIZED) { | 1059 | if (port->port.flags & ASYNC_INITIALIZED) { |
1076 | card->port_status &= ~(1 << port->channel); | 1060 | card->port_status &= ~(1 << port->channel); |
1077 | outw(card->port_status, card->base + 0x02); | 1061 | outw(card->port_status, card->base + 0x02); |
1078 | } | 1062 | } |
@@ -1085,7 +1069,7 @@ static void isicom_close(struct tty_struct *tty, struct file *filp) | |||
1085 | spin_lock_irqsave(&card->card_lock, flags); | 1069 | spin_lock_irqsave(&card->card_lock, flags); |
1086 | tty->closing = 0; | 1070 | tty->closing = 0; |
1087 | 1071 | ||
1088 | if (port->blocked_open) { | 1072 | if (port->port.blocked_open) { |
1089 | spin_unlock_irqrestore(&card->card_lock, flags); | 1073 | spin_unlock_irqrestore(&card->card_lock, flags); |
1090 | if (port->close_delay) { | 1074 | if (port->close_delay) { |
1091 | pr_dbg("scheduling until time out.\n"); | 1075 | pr_dbg("scheduling until time out.\n"); |
@@ -1093,10 +1077,10 @@ static void isicom_close(struct tty_struct *tty, struct file *filp) | |||
1093 | jiffies_to_msecs(port->close_delay)); | 1077 | jiffies_to_msecs(port->close_delay)); |
1094 | } | 1078 | } |
1095 | spin_lock_irqsave(&card->card_lock, flags); | 1079 | spin_lock_irqsave(&card->card_lock, flags); |
1096 | wake_up_interruptible(&port->open_wait); | 1080 | wake_up_interruptible(&port->port.open_wait); |
1097 | } | 1081 | } |
1098 | port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); | 1082 | port->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); |
1099 | wake_up_interruptible(&port->close_wait); | 1083 | wake_up_interruptible(&port->port.close_wait); |
1100 | spin_unlock_irqrestore(&card->card_lock, flags); | 1084 | spin_unlock_irqrestore(&card->card_lock, flags); |
1101 | } | 1085 | } |
1102 | 1086 | ||
@@ -1112,9 +1096,6 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf, | |||
1112 | if (isicom_paranoia_check(port, tty->name, "isicom_write")) | 1096 | if (isicom_paranoia_check(port, tty->name, "isicom_write")) |
1113 | return 0; | 1097 | return 0; |
1114 | 1098 | ||
1115 | if (!port->xmit_buf) | ||
1116 | return 0; | ||
1117 | |||
1118 | spin_lock_irqsave(&card->card_lock, flags); | 1099 | spin_lock_irqsave(&card->card_lock, flags); |
1119 | 1100 | ||
1120 | while (1) { | 1101 | while (1) { |
@@ -1123,7 +1104,7 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf, | |||
1123 | if (cnt <= 0) | 1104 | if (cnt <= 0) |
1124 | break; | 1105 | break; |
1125 | 1106 | ||
1126 | memcpy(port->xmit_buf + port->xmit_head, buf, cnt); | 1107 | memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt); |
1127 | port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE | 1108 | port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE |
1128 | - 1); | 1109 | - 1); |
1129 | port->xmit_cnt += cnt; | 1110 | port->xmit_cnt += cnt; |
@@ -1147,16 +1128,13 @@ static int isicom_put_char(struct tty_struct *tty, unsigned char ch) | |||
1147 | if (isicom_paranoia_check(port, tty->name, "isicom_put_char")) | 1128 | if (isicom_paranoia_check(port, tty->name, "isicom_put_char")) |
1148 | return 0; | 1129 | return 0; |
1149 | 1130 | ||
1150 | if (!port->xmit_buf) | ||
1151 | return 0; | ||
1152 | |||
1153 | spin_lock_irqsave(&card->card_lock, flags); | 1131 | spin_lock_irqsave(&card->card_lock, flags); |
1154 | if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { | 1132 | if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { |
1155 | spin_unlock_irqrestore(&card->card_lock, flags); | 1133 | spin_unlock_irqrestore(&card->card_lock, flags); |
1156 | return 0; | 1134 | return 0; |
1157 | } | 1135 | } |
1158 | 1136 | ||
1159 | port->xmit_buf[port->xmit_head++] = ch; | 1137 | port->port.xmit_buf[port->xmit_head++] = ch; |
1160 | port->xmit_head &= (SERIAL_XMIT_SIZE - 1); | 1138 | port->xmit_head &= (SERIAL_XMIT_SIZE - 1); |
1161 | port->xmit_cnt++; | 1139 | port->xmit_cnt++; |
1162 | spin_unlock_irqrestore(&card->card_lock, flags); | 1140 | spin_unlock_irqrestore(&card->card_lock, flags); |
@@ -1172,7 +1150,7 @@ static void isicom_flush_chars(struct tty_struct *tty) | |||
1172 | return; | 1150 | return; |
1173 | 1151 | ||
1174 | if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || | 1152 | if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || |
1175 | !port->xmit_buf) | 1153 | !port->port.xmit_buf) |
1176 | return; | 1154 | return; |
1177 | 1155 | ||
1178 | /* this tells the transmitter to consider this port for | 1156 | /* this tells the transmitter to consider this port for |
@@ -1274,23 +1252,23 @@ static int isicom_set_serial_info(struct isi_port *port, | |||
1274 | 1252 | ||
1275 | lock_kernel(); | 1253 | lock_kernel(); |
1276 | 1254 | ||
1277 | reconfig_port = ((port->flags & ASYNC_SPD_MASK) != | 1255 | reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) != |
1278 | (newinfo.flags & ASYNC_SPD_MASK)); | 1256 | (newinfo.flags & ASYNC_SPD_MASK)); |
1279 | 1257 | ||
1280 | if (!capable(CAP_SYS_ADMIN)) { | 1258 | if (!capable(CAP_SYS_ADMIN)) { |
1281 | if ((newinfo.close_delay != port->close_delay) || | 1259 | if ((newinfo.close_delay != port->close_delay) || |
1282 | (newinfo.closing_wait != port->closing_wait) || | 1260 | (newinfo.closing_wait != port->closing_wait) || |
1283 | ((newinfo.flags & ~ASYNC_USR_MASK) != | 1261 | ((newinfo.flags & ~ASYNC_USR_MASK) != |
1284 | (port->flags & ~ASYNC_USR_MASK))) { | 1262 | (port->port.flags & ~ASYNC_USR_MASK))) { |
1285 | unlock_kernel(); | 1263 | unlock_kernel(); |
1286 | return -EPERM; | 1264 | return -EPERM; |
1287 | } | 1265 | } |
1288 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | | 1266 | port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | |
1289 | (newinfo.flags & ASYNC_USR_MASK)); | 1267 | (newinfo.flags & ASYNC_USR_MASK)); |
1290 | } else { | 1268 | } else { |
1291 | port->close_delay = newinfo.close_delay; | 1269 | port->close_delay = newinfo.close_delay; |
1292 | port->closing_wait = newinfo.closing_wait; | 1270 | port->closing_wait = newinfo.closing_wait; |
1293 | port->flags = ((port->flags & ~ASYNC_FLAGS) | | 1271 | port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) | |
1294 | (newinfo.flags & ASYNC_FLAGS)); | 1272 | (newinfo.flags & ASYNC_FLAGS)); |
1295 | } | 1273 | } |
1296 | if (reconfig_port) { | 1274 | if (reconfig_port) { |
@@ -1314,7 +1292,7 @@ static int isicom_get_serial_info(struct isi_port *port, | |||
1314 | out_info.line = port - isi_ports; | 1292 | out_info.line = port - isi_ports; |
1315 | out_info.port = port->card->base; | 1293 | out_info.port = port->card->base; |
1316 | out_info.irq = port->card->irq; | 1294 | out_info.irq = port->card->irq; |
1317 | out_info.flags = port->flags; | 1295 | out_info.flags = port->port.flags; |
1318 | /* out_info.baud_base = ? */ | 1296 | /* out_info.baud_base = ? */ |
1319 | out_info.close_delay = port->close_delay; | 1297 | out_info.close_delay = port->close_delay; |
1320 | out_info.closing_wait = port->closing_wait; | 1298 | out_info.closing_wait = port->closing_wait; |
@@ -1454,10 +1432,10 @@ static void isicom_hangup(struct tty_struct *tty) | |||
1454 | isicom_shutdown_port(port); | 1432 | isicom_shutdown_port(port); |
1455 | spin_unlock_irqrestore(&port->card->card_lock, flags); | 1433 | spin_unlock_irqrestore(&port->card->card_lock, flags); |
1456 | 1434 | ||
1457 | port->count = 0; | 1435 | port->port.count = 0; |
1458 | port->flags &= ~ASYNC_NORMAL_ACTIVE; | 1436 | port->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
1459 | port->tty = NULL; | 1437 | port->port.tty = NULL; |
1460 | wake_up_interruptible(&port->open_wait); | 1438 | wake_up_interruptible(&port->port.open_wait); |
1461 | } | 1439 | } |
1462 | 1440 | ||
1463 | 1441 | ||
@@ -1832,8 +1810,7 @@ static int __init isicom_init(void) | |||
1832 | port->close_delay = 50 * HZ/100; | 1810 | port->close_delay = 50 * HZ/100; |
1833 | port->closing_wait = 3000 * HZ/100; | 1811 | port->closing_wait = 3000 * HZ/100; |
1834 | port->status = 0; | 1812 | port->status = 0; |
1835 | init_waitqueue_head(&port->open_wait); | 1813 | tty_port_init(&port->port); |
1836 | init_waitqueue_head(&port->close_wait); | ||
1837 | /* . . . */ | 1814 | /* . . . */ |
1838 | } | 1815 | } |
1839 | isi_card[idx].base = 0; | 1816 | isi_card[idx].base = 0; |