diff options
Diffstat (limited to 'drivers/char/mxser.c')
-rw-r--r-- | drivers/char/mxser.c | 662 |
1 files changed, 280 insertions, 382 deletions
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 4b81a85c5b53..e30575e87648 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -16,7 +16,6 @@ | |||
16 | * Fed through a cleanup, indent and remove of non 2.6 code by Alan Cox | 16 | * Fed through a cleanup, indent and remove of non 2.6 code by Alan Cox |
17 | * <alan@redhat.com>. The original 1.8 code is available on www.moxa.com. | 17 | * <alan@redhat.com>. The original 1.8 code is available on www.moxa.com. |
18 | * - Fixed x86_64 cleanness | 18 | * - Fixed x86_64 cleanness |
19 | * - Fixed sleep with spinlock held in mxser_send_break | ||
20 | */ | 19 | */ |
21 | 20 | ||
22 | #include <linux/module.h> | 21 | #include <linux/module.h> |
@@ -47,20 +46,14 @@ | |||
47 | 46 | ||
48 | #include "mxser.h" | 47 | #include "mxser.h" |
49 | 48 | ||
50 | #define MXSER_VERSION "2.0.3" /* 1.11 */ | 49 | #define MXSER_VERSION "2.0.4" /* 1.12 */ |
51 | #define MXSERMAJOR 174 | 50 | #define MXSERMAJOR 174 |
52 | #define MXSERCUMAJOR 175 | ||
53 | 51 | ||
54 | #define MXSER_BOARDS 4 /* Max. boards */ | 52 | #define MXSER_BOARDS 4 /* Max. boards */ |
55 | #define MXSER_PORTS_PER_BOARD 8 /* Max. ports per board */ | 53 | #define MXSER_PORTS_PER_BOARD 8 /* Max. ports per board */ |
56 | #define MXSER_PORTS (MXSER_BOARDS * MXSER_PORTS_PER_BOARD) | 54 | #define MXSER_PORTS (MXSER_BOARDS * MXSER_PORTS_PER_BOARD) |
57 | #define MXSER_ISR_PASS_LIMIT 100 | 55 | #define MXSER_ISR_PASS_LIMIT 100 |
58 | 56 | ||
59 | #define MXSER_ERR_IOADDR -1 | ||
60 | #define MXSER_ERR_IRQ -2 | ||
61 | #define MXSER_ERR_IRQ_CONFLIT -3 | ||
62 | #define MXSER_ERR_VECTOR -4 | ||
63 | |||
64 | /*CheckIsMoxaMust return value*/ | 57 | /*CheckIsMoxaMust return value*/ |
65 | #define MOXA_OTHER_UART 0x00 | 58 | #define MOXA_OTHER_UART 0x00 |
66 | #define MOXA_MUST_MU150_HWID 0x01 | 59 | #define MOXA_MUST_MU150_HWID 0x01 |
@@ -71,12 +64,13 @@ | |||
71 | #define UART_MCR_AFE 0x20 | 64 | #define UART_MCR_AFE 0x20 |
72 | #define UART_LSR_SPECIAL 0x1E | 65 | #define UART_LSR_SPECIAL 0x1E |
73 | 66 | ||
67 | #define PCI_DEVICE_ID_POS104UL 0x1044 | ||
74 | #define PCI_DEVICE_ID_CB108 0x1080 | 68 | #define PCI_DEVICE_ID_CB108 0x1080 |
69 | #define PCI_DEVICE_ID_CP102UF 0x1023 | ||
75 | #define PCI_DEVICE_ID_CB114 0x1142 | 70 | #define PCI_DEVICE_ID_CB114 0x1142 |
76 | #define PCI_DEVICE_ID_CP114UL 0x1143 | 71 | #define PCI_DEVICE_ID_CP114UL 0x1143 |
77 | #define PCI_DEVICE_ID_CB134I 0x1341 | 72 | #define PCI_DEVICE_ID_CB134I 0x1341 |
78 | #define PCI_DEVICE_ID_CP138U 0x1380 | 73 | #define PCI_DEVICE_ID_CP138U 0x1380 |
79 | #define PCI_DEVICE_ID_POS104UL 0x1044 | ||
80 | 74 | ||
81 | 75 | ||
82 | #define C168_ASIC_ID 1 | 76 | #define C168_ASIC_ID 1 |
@@ -142,7 +136,8 @@ static const struct mxser_cardinfo mxser_cards[] = { | |||
142 | { "CB-134I series", 4, }, | 136 | { "CB-134I series", 4, }, |
143 | { "CP-138U series", 8, }, | 137 | { "CP-138U series", 8, }, |
144 | { "POS-104UL series", 4, }, | 138 | { "POS-104UL series", 4, }, |
145 | { "CP-114UL series", 4, } | 139 | { "CP-114UL series", 4, }, |
140 | /*30*/ { "CP-102UF series", 2, } | ||
146 | }; | 141 | }; |
147 | 142 | ||
148 | /* driver_data correspond to the lines in the structure above | 143 | /* driver_data correspond to the lines in the structure above |
@@ -172,18 +167,20 @@ static struct pci_device_id mxser_pcibrds[] = { | |||
172 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U), .driver_data = 27 }, | 167 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U), .driver_data = 27 }, |
173 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 28 }, | 168 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 28 }, |
174 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL), .driver_data = 29 }, | 169 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL), .driver_data = 29 }, |
170 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP102UF), .driver_data = 30 }, | ||
175 | { } | 171 | { } |
176 | }; | 172 | }; |
177 | MODULE_DEVICE_TABLE(pci, mxser_pcibrds); | 173 | MODULE_DEVICE_TABLE(pci, mxser_pcibrds); |
178 | 174 | ||
179 | static int ioaddr[MXSER_BOARDS] = { 0, 0, 0, 0 }; | 175 | static unsigned long ioaddr[MXSER_BOARDS]; |
180 | static int ttymajor = MXSERMAJOR; | 176 | static int ttymajor = MXSERMAJOR; |
181 | 177 | ||
182 | /* Variables for insmod */ | 178 | /* Variables for insmod */ |
183 | 179 | ||
184 | MODULE_AUTHOR("Casper Yang"); | 180 | MODULE_AUTHOR("Casper Yang"); |
185 | MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver"); | 181 | MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver"); |
186 | module_param_array(ioaddr, int, NULL, 0); | 182 | module_param_array(ioaddr, ulong, NULL, 0); |
183 | MODULE_PARM_DESC(ioaddr, "ISA io addresses to look for a moxa board"); | ||
187 | module_param(ttymajor, int, 0); | 184 | module_param(ttymajor, int, 0); |
188 | MODULE_LICENSE("GPL"); | 185 | MODULE_LICENSE("GPL"); |
189 | 186 | ||
@@ -193,7 +190,6 @@ struct mxser_log { | |||
193 | unsigned long txcnt[MXSER_PORTS]; | 190 | unsigned long txcnt[MXSER_PORTS]; |
194 | }; | 191 | }; |
195 | 192 | ||
196 | |||
197 | struct mxser_mon { | 193 | struct mxser_mon { |
198 | unsigned long rxcnt; | 194 | unsigned long rxcnt; |
199 | unsigned long txcnt; | 195 | unsigned long txcnt; |
@@ -222,8 +218,8 @@ struct mxser_mon_ext { | |||
222 | struct mxser_board; | 218 | struct mxser_board; |
223 | 219 | ||
224 | struct mxser_port { | 220 | struct mxser_port { |
221 | struct tty_port port; | ||
225 | struct mxser_board *board; | 222 | struct mxser_board *board; |
226 | struct tty_struct *tty; | ||
227 | 223 | ||
228 | unsigned long ioaddr; | 224 | unsigned long ioaddr; |
229 | unsigned long opmode_ioaddr; | 225 | unsigned long opmode_ioaddr; |
@@ -234,7 +230,6 @@ struct mxser_port { | |||
234 | int rx_low_water; | 230 | int rx_low_water; |
235 | int baud_base; /* max. speed */ | 231 | int baud_base; /* max. speed */ |
236 | int type; /* UART type */ | 232 | int type; /* UART type */ |
237 | int flags; /* defined in tty.h */ | ||
238 | 233 | ||
239 | int x_char; /* xon/xoff character */ | 234 | int x_char; /* xon/xoff character */ |
240 | int IER; /* Interrupt Enable Register */ | 235 | int IER; /* Interrupt Enable Register */ |
@@ -244,20 +239,14 @@ struct mxser_port { | |||
244 | unsigned char ldisc_stop_rx; | 239 | unsigned char ldisc_stop_rx; |
245 | 240 | ||
246 | int custom_divisor; | 241 | int custom_divisor; |
247 | int close_delay; | ||
248 | unsigned short closing_wait; | ||
249 | unsigned char err_shadow; | 242 | unsigned char err_shadow; |
250 | unsigned long event; | ||
251 | 243 | ||
252 | int count; /* # of fd on device */ | ||
253 | int blocked_open; /* # of blocked opens */ | ||
254 | struct async_icount icount; /* kernel counters for 4 input interrupts */ | 244 | struct async_icount icount; /* kernel counters for 4 input interrupts */ |
255 | int timeout; | 245 | int timeout; |
256 | 246 | ||
257 | int read_status_mask; | 247 | int read_status_mask; |
258 | int ignore_status_mask; | 248 | int ignore_status_mask; |
259 | int xmit_fifo_size; | 249 | int xmit_fifo_size; |
260 | unsigned char *xmit_buf; | ||
261 | int xmit_head; | 250 | int xmit_head; |
262 | int xmit_tail; | 251 | int xmit_tail; |
263 | int xmit_cnt; | 252 | int xmit_cnt; |
@@ -267,7 +256,6 @@ struct mxser_port { | |||
267 | struct mxser_mon mon_data; | 256 | struct mxser_mon mon_data; |
268 | 257 | ||
269 | spinlock_t slock; | 258 | spinlock_t slock; |
270 | wait_queue_head_t open_wait; | ||
271 | wait_queue_head_t delta_msr_wait; | 259 | wait_queue_head_t delta_msr_wait; |
272 | }; | 260 | }; |
273 | 261 | ||
@@ -292,19 +280,9 @@ struct mxser_mstatus { | |||
292 | int dcd; | 280 | int dcd; |
293 | }; | 281 | }; |
294 | 282 | ||
295 | static struct mxser_mstatus GMStatus[MXSER_PORTS]; | ||
296 | |||
297 | static int mxserBoardCAP[MXSER_BOARDS] = { | ||
298 | 0, 0, 0, 0 | ||
299 | /* 0x180, 0x280, 0x200, 0x320 */ | ||
300 | }; | ||
301 | |||
302 | static struct mxser_board mxser_boards[MXSER_BOARDS]; | 283 | static struct mxser_board mxser_boards[MXSER_BOARDS]; |
303 | static struct tty_driver *mxvar_sdriver; | 284 | static struct tty_driver *mxvar_sdriver; |
304 | static struct mxser_log mxvar_log; | 285 | static struct mxser_log mxvar_log; |
305 | static int mxvar_diagflag; | ||
306 | static unsigned char mxser_msr[MXSER_PORTS + 1]; | ||
307 | static struct mxser_mon_ext mon_data_ext; | ||
308 | static int mxser_set_baud_method[MXSER_PORTS + 1]; | 286 | static int mxser_set_baud_method[MXSER_PORTS + 1]; |
309 | 287 | ||
310 | static void mxser_enable_must_enchance_mode(unsigned long baseio) | 288 | static void mxser_enable_must_enchance_mode(unsigned long baseio) |
@@ -548,6 +526,7 @@ static void process_txrx_fifo(struct mxser_port *info) | |||
548 | 526 | ||
549 | static unsigned char mxser_get_msr(int baseaddr, int mode, int port) | 527 | static unsigned char mxser_get_msr(int baseaddr, int mode, int port) |
550 | { | 528 | { |
529 | static unsigned char mxser_msr[MXSER_PORTS + 1]; | ||
551 | unsigned char status = 0; | 530 | unsigned char status = 0; |
552 | 531 | ||
553 | status = inb(baseaddr + UART_MSR); | 532 | status = inb(baseaddr + UART_MSR); |
@@ -575,7 +554,7 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, | |||
575 | */ | 554 | */ |
576 | if ((filp->f_flags & O_NONBLOCK) || | 555 | if ((filp->f_flags & O_NONBLOCK) || |
577 | test_bit(TTY_IO_ERROR, &tty->flags)) { | 556 | test_bit(TTY_IO_ERROR, &tty->flags)) { |
578 | port->flags |= ASYNC_NORMAL_ACTIVE; | 557 | port->port.flags |= ASYNC_NORMAL_ACTIVE; |
579 | return 0; | 558 | return 0; |
580 | } | 559 | } |
581 | 560 | ||
@@ -585,32 +564,32 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, | |||
585 | /* | 564 | /* |
586 | * Block waiting for the carrier detect and the line to become | 565 | * Block waiting for the carrier detect and the line to become |
587 | * free (i.e., not in use by the callout). While we are in | 566 | * free (i.e., not in use by the callout). While we are in |
588 | * this loop, port->count is dropped by one, so that | 567 | * this loop, port->port.count is dropped by one, so that |
589 | * mxser_close() knows when to free things. We restore it upon | 568 | * mxser_close() knows when to free things. We restore it upon |
590 | * exit, either normal or abnormal. | 569 | * exit, either normal or abnormal. |
591 | */ | 570 | */ |
592 | retval = 0; | 571 | retval = 0; |
593 | add_wait_queue(&port->open_wait, &wait); | 572 | add_wait_queue(&port->port.open_wait, &wait); |
594 | 573 | ||
595 | spin_lock_irqsave(&port->slock, flags); | 574 | spin_lock_irqsave(&port->slock, flags); |
596 | if (!tty_hung_up_p(filp)) | 575 | if (!tty_hung_up_p(filp)) |
597 | port->count--; | 576 | port->port.count--; |
598 | spin_unlock_irqrestore(&port->slock, flags); | 577 | spin_unlock_irqrestore(&port->slock, flags); |
599 | port->blocked_open++; | 578 | port->port.blocked_open++; |
600 | while (1) { | 579 | while (1) { |
601 | spin_lock_irqsave(&port->slock, flags); | 580 | spin_lock_irqsave(&port->slock, flags); |
602 | outb(inb(port->ioaddr + UART_MCR) | | 581 | outb(inb(port->ioaddr + UART_MCR) | |
603 | UART_MCR_DTR | UART_MCR_RTS, port->ioaddr + UART_MCR); | 582 | UART_MCR_DTR | UART_MCR_RTS, port->ioaddr + UART_MCR); |
604 | spin_unlock_irqrestore(&port->slock, flags); | 583 | spin_unlock_irqrestore(&port->slock, flags); |
605 | set_current_state(TASK_INTERRUPTIBLE); | 584 | set_current_state(TASK_INTERRUPTIBLE); |
606 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { | 585 | if (tty_hung_up_p(filp) || !(port->port.flags & ASYNC_INITIALIZED)) { |
607 | if (port->flags & ASYNC_HUP_NOTIFY) | 586 | if (port->port.flags & ASYNC_HUP_NOTIFY) |
608 | retval = -EAGAIN; | 587 | retval = -EAGAIN; |
609 | else | 588 | else |
610 | retval = -ERESTARTSYS; | 589 | retval = -ERESTARTSYS; |
611 | break; | 590 | break; |
612 | } | 591 | } |
613 | if (!(port->flags & ASYNC_CLOSING) && | 592 | if (!(port->port.flags & ASYNC_CLOSING) && |
614 | (do_clocal || | 593 | (do_clocal || |
615 | (inb(port->ioaddr + UART_MSR) & UART_MSR_DCD))) | 594 | (inb(port->ioaddr + UART_MSR) & UART_MSR_DCD))) |
616 | break; | 595 | break; |
@@ -621,13 +600,13 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, | |||
621 | schedule(); | 600 | schedule(); |
622 | } | 601 | } |
623 | set_current_state(TASK_RUNNING); | 602 | set_current_state(TASK_RUNNING); |
624 | remove_wait_queue(&port->open_wait, &wait); | 603 | remove_wait_queue(&port->port.open_wait, &wait); |
625 | if (!tty_hung_up_p(filp)) | 604 | if (!tty_hung_up_p(filp)) |
626 | port->count++; | 605 | port->port.count++; |
627 | port->blocked_open--; | 606 | port->port.blocked_open--; |
628 | if (retval) | 607 | if (retval) |
629 | return retval; | 608 | return retval; |
630 | port->flags |= ASYNC_NORMAL_ACTIVE; | 609 | port->port.flags |= ASYNC_NORMAL_ACTIVE; |
631 | return 0; | 610 | return 0; |
632 | } | 611 | } |
633 | 612 | ||
@@ -636,7 +615,7 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) | |||
636 | int quot = 0, baud; | 615 | int quot = 0, baud; |
637 | unsigned char cval; | 616 | unsigned char cval; |
638 | 617 | ||
639 | if (!info->tty || !info->tty->termios) | 618 | if (!info->port.tty || !info->port.tty->termios) |
640 | return -1; | 619 | return -1; |
641 | 620 | ||
642 | if (!(info->ioaddr)) | 621 | if (!(info->ioaddr)) |
@@ -647,13 +626,13 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) | |||
647 | 626 | ||
648 | if (newspd == 134) { | 627 | if (newspd == 134) { |
649 | quot = 2 * info->baud_base / 269; | 628 | quot = 2 * info->baud_base / 269; |
650 | tty_encode_baud_rate(info->tty, 134, 134); | 629 | tty_encode_baud_rate(info->port.tty, 134, 134); |
651 | } else if (newspd) { | 630 | } else if (newspd) { |
652 | quot = info->baud_base / newspd; | 631 | quot = info->baud_base / newspd; |
653 | if (quot == 0) | 632 | if (quot == 0) |
654 | quot = 1; | 633 | quot = 1; |
655 | baud = info->baud_base/quot; | 634 | baud = info->baud_base/quot; |
656 | tty_encode_baud_rate(info->tty, baud, baud); | 635 | tty_encode_baud_rate(info->port.tty, baud, baud); |
657 | } else { | 636 | } else { |
658 | quot = 0; | 637 | quot = 0; |
659 | } | 638 | } |
@@ -679,7 +658,7 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) | |||
679 | outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ | 658 | outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ |
680 | 659 | ||
681 | #ifdef BOTHER | 660 | #ifdef BOTHER |
682 | if (C_BAUD(info->tty) == BOTHER) { | 661 | if (C_BAUD(info->port.tty) == BOTHER) { |
683 | quot = info->baud_base % newspd; | 662 | quot = info->baud_base % newspd; |
684 | quot *= 8; | 663 | quot *= 8; |
685 | if (quot % newspd > newspd / 2) { | 664 | if (quot % newspd > newspd / 2) { |
@@ -707,14 +686,14 @@ static int mxser_change_speed(struct mxser_port *info, | |||
707 | int ret = 0; | 686 | int ret = 0; |
708 | unsigned char status; | 687 | unsigned char status; |
709 | 688 | ||
710 | if (!info->tty || !info->tty->termios) | 689 | if (!info->port.tty || !info->port.tty->termios) |
711 | return ret; | 690 | return ret; |
712 | cflag = info->tty->termios->c_cflag; | 691 | cflag = info->port.tty->termios->c_cflag; |
713 | if (!(info->ioaddr)) | 692 | if (!(info->ioaddr)) |
714 | return ret; | 693 | return ret; |
715 | 694 | ||
716 | if (mxser_set_baud_method[info->tty->index] == 0) | 695 | if (mxser_set_baud_method[info->port.tty->index] == 0) |
717 | mxser_set_baud(info, tty_get_baud_rate(info->tty)); | 696 | mxser_set_baud(info, tty_get_baud_rate(info->port.tty)); |
718 | 697 | ||
719 | /* byte size and parity */ | 698 | /* byte size and parity */ |
720 | switch (cflag & CSIZE) { | 699 | switch (cflag & CSIZE) { |
@@ -777,15 +756,15 @@ static int mxser_change_speed(struct mxser_port *info, | |||
777 | info->IER &= ~UART_IER_MSI; | 756 | info->IER &= ~UART_IER_MSI; |
778 | info->MCR &= ~UART_MCR_AFE; | 757 | info->MCR &= ~UART_MCR_AFE; |
779 | if (cflag & CRTSCTS) { | 758 | if (cflag & CRTSCTS) { |
780 | info->flags |= ASYNC_CTS_FLOW; | 759 | info->port.flags |= ASYNC_CTS_FLOW; |
781 | info->IER |= UART_IER_MSI; | 760 | info->IER |= UART_IER_MSI; |
782 | if ((info->type == PORT_16550A) || (info->board->chip_flag)) { | 761 | if ((info->type == PORT_16550A) || (info->board->chip_flag)) { |
783 | info->MCR |= UART_MCR_AFE; | 762 | info->MCR |= UART_MCR_AFE; |
784 | } else { | 763 | } else { |
785 | status = inb(info->ioaddr + UART_MSR); | 764 | status = inb(info->ioaddr + UART_MSR); |
786 | if (info->tty->hw_stopped) { | 765 | if (info->port.tty->hw_stopped) { |
787 | if (status & UART_MSR_CTS) { | 766 | if (status & UART_MSR_CTS) { |
788 | info->tty->hw_stopped = 0; | 767 | info->port.tty->hw_stopped = 0; |
789 | if (info->type != PORT_16550A && | 768 | if (info->type != PORT_16550A && |
790 | !info->board->chip_flag) { | 769 | !info->board->chip_flag) { |
791 | outb(info->IER & ~UART_IER_THRI, | 770 | outb(info->IER & ~UART_IER_THRI, |
@@ -795,11 +774,11 @@ static int mxser_change_speed(struct mxser_port *info, | |||
795 | outb(info->IER, info->ioaddr + | 774 | outb(info->IER, info->ioaddr + |
796 | UART_IER); | 775 | UART_IER); |
797 | } | 776 | } |
798 | tty_wakeup(info->tty); | 777 | tty_wakeup(info->port.tty); |
799 | } | 778 | } |
800 | } else { | 779 | } else { |
801 | if (!(status & UART_MSR_CTS)) { | 780 | if (!(status & UART_MSR_CTS)) { |
802 | info->tty->hw_stopped = 1; | 781 | info->port.tty->hw_stopped = 1; |
803 | if ((info->type != PORT_16550A) && | 782 | if ((info->type != PORT_16550A) && |
804 | (!info->board->chip_flag)) { | 783 | (!info->board->chip_flag)) { |
805 | info->IER &= ~UART_IER_THRI; | 784 | info->IER &= ~UART_IER_THRI; |
@@ -810,13 +789,13 @@ static int mxser_change_speed(struct mxser_port *info, | |||
810 | } | 789 | } |
811 | } | 790 | } |
812 | } else { | 791 | } else { |
813 | info->flags &= ~ASYNC_CTS_FLOW; | 792 | info->port.flags &= ~ASYNC_CTS_FLOW; |
814 | } | 793 | } |
815 | outb(info->MCR, info->ioaddr + UART_MCR); | 794 | outb(info->MCR, info->ioaddr + UART_MCR); |
816 | if (cflag & CLOCAL) { | 795 | if (cflag & CLOCAL) { |
817 | info->flags &= ~ASYNC_CHECK_CD; | 796 | info->port.flags &= ~ASYNC_CHECK_CD; |
818 | } else { | 797 | } else { |
819 | info->flags |= ASYNC_CHECK_CD; | 798 | info->port.flags |= ASYNC_CHECK_CD; |
820 | info->IER |= UART_IER_MSI; | 799 | info->IER |= UART_IER_MSI; |
821 | } | 800 | } |
822 | outb(info->IER, info->ioaddr + UART_IER); | 801 | outb(info->IER, info->ioaddr + UART_IER); |
@@ -825,21 +804,21 @@ static int mxser_change_speed(struct mxser_port *info, | |||
825 | * Set up parity check flag | 804 | * Set up parity check flag |
826 | */ | 805 | */ |
827 | info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; | 806 | info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; |
828 | if (I_INPCK(info->tty)) | 807 | if (I_INPCK(info->port.tty)) |
829 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; | 808 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; |
830 | if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) | 809 | if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) |
831 | info->read_status_mask |= UART_LSR_BI; | 810 | info->read_status_mask |= UART_LSR_BI; |
832 | 811 | ||
833 | info->ignore_status_mask = 0; | 812 | info->ignore_status_mask = 0; |
834 | 813 | ||
835 | if (I_IGNBRK(info->tty)) { | 814 | if (I_IGNBRK(info->port.tty)) { |
836 | info->ignore_status_mask |= UART_LSR_BI; | 815 | info->ignore_status_mask |= UART_LSR_BI; |
837 | info->read_status_mask |= UART_LSR_BI; | 816 | info->read_status_mask |= UART_LSR_BI; |
838 | /* | 817 | /* |
839 | * If we're ignore parity and break indicators, ignore | 818 | * If we're ignore parity and break indicators, ignore |
840 | * overruns too. (For real raw support). | 819 | * overruns too. (For real raw support). |
841 | */ | 820 | */ |
842 | if (I_IGNPAR(info->tty)) { | 821 | if (I_IGNPAR(info->port.tty)) { |
843 | info->ignore_status_mask |= | 822 | info->ignore_status_mask |= |
844 | UART_LSR_OE | | 823 | UART_LSR_OE | |
845 | UART_LSR_PE | | 824 | UART_LSR_PE | |
@@ -851,16 +830,16 @@ static int mxser_change_speed(struct mxser_port *info, | |||
851 | } | 830 | } |
852 | } | 831 | } |
853 | if (info->board->chip_flag) { | 832 | if (info->board->chip_flag) { |
854 | mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->tty)); | 833 | mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->port.tty)); |
855 | mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->tty)); | 834 | mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->port.tty)); |
856 | if (I_IXON(info->tty)) { | 835 | if (I_IXON(info->port.tty)) { |
857 | mxser_enable_must_rx_software_flow_control( | 836 | mxser_enable_must_rx_software_flow_control( |
858 | info->ioaddr); | 837 | info->ioaddr); |
859 | } else { | 838 | } else { |
860 | mxser_disable_must_rx_software_flow_control( | 839 | mxser_disable_must_rx_software_flow_control( |
861 | info->ioaddr); | 840 | info->ioaddr); |
862 | } | 841 | } |
863 | if (I_IXOFF(info->tty)) { | 842 | if (I_IXOFF(info->port.tty)) { |
864 | mxser_enable_must_tx_software_flow_control( | 843 | mxser_enable_must_tx_software_flow_control( |
865 | info->ioaddr); | 844 | info->ioaddr); |
866 | } else { | 845 | } else { |
@@ -890,15 +869,15 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) | |||
890 | port->mon_data.modem_status = status; | 869 | port->mon_data.modem_status = status; |
891 | wake_up_interruptible(&port->delta_msr_wait); | 870 | wake_up_interruptible(&port->delta_msr_wait); |
892 | 871 | ||
893 | if ((port->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { | 872 | if ((port->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { |
894 | if (status & UART_MSR_DCD) | 873 | if (status & UART_MSR_DCD) |
895 | wake_up_interruptible(&port->open_wait); | 874 | wake_up_interruptible(&port->port.open_wait); |
896 | } | 875 | } |
897 | 876 | ||
898 | if (port->flags & ASYNC_CTS_FLOW) { | 877 | if (port->port.flags & ASYNC_CTS_FLOW) { |
899 | if (port->tty->hw_stopped) { | 878 | if (port->port.tty->hw_stopped) { |
900 | if (status & UART_MSR_CTS) { | 879 | if (status & UART_MSR_CTS) { |
901 | port->tty->hw_stopped = 0; | 880 | port->port.tty->hw_stopped = 0; |
902 | 881 | ||
903 | if ((port->type != PORT_16550A) && | 882 | if ((port->type != PORT_16550A) && |
904 | (!port->board->chip_flag)) { | 883 | (!port->board->chip_flag)) { |
@@ -908,11 +887,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) | |||
908 | outb(port->IER, port->ioaddr + | 887 | outb(port->IER, port->ioaddr + |
909 | UART_IER); | 888 | UART_IER); |
910 | } | 889 | } |
911 | tty_wakeup(port->tty); | 890 | tty_wakeup(port->port.tty); |
912 | } | 891 | } |
913 | } else { | 892 | } else { |
914 | if (!(status & UART_MSR_CTS)) { | 893 | if (!(status & UART_MSR_CTS)) { |
915 | port->tty->hw_stopped = 1; | 894 | port->port.tty->hw_stopped = 1; |
916 | if (port->type != PORT_16550A && | 895 | if (port->type != PORT_16550A && |
917 | !port->board->chip_flag) { | 896 | !port->board->chip_flag) { |
918 | port->IER &= ~UART_IER_THRI; | 897 | port->IER &= ~UART_IER_THRI; |
@@ -935,23 +914,23 @@ static int mxser_startup(struct mxser_port *info) | |||
935 | 914 | ||
936 | spin_lock_irqsave(&info->slock, flags); | 915 | spin_lock_irqsave(&info->slock, flags); |
937 | 916 | ||
938 | if (info->flags & ASYNC_INITIALIZED) { | 917 | if (info->port.flags & ASYNC_INITIALIZED) { |
939 | free_page(page); | 918 | free_page(page); |
940 | spin_unlock_irqrestore(&info->slock, flags); | 919 | spin_unlock_irqrestore(&info->slock, flags); |
941 | return 0; | 920 | return 0; |
942 | } | 921 | } |
943 | 922 | ||
944 | if (!info->ioaddr || !info->type) { | 923 | if (!info->ioaddr || !info->type) { |
945 | if (info->tty) | 924 | if (info->port.tty) |
946 | set_bit(TTY_IO_ERROR, &info->tty->flags); | 925 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); |
947 | free_page(page); | 926 | free_page(page); |
948 | spin_unlock_irqrestore(&info->slock, flags); | 927 | spin_unlock_irqrestore(&info->slock, flags); |
949 | return 0; | 928 | return 0; |
950 | } | 929 | } |
951 | if (info->xmit_buf) | 930 | if (info->port.xmit_buf) |
952 | free_page(page); | 931 | free_page(page); |
953 | else | 932 | else |
954 | info->xmit_buf = (unsigned char *) page; | 933 | info->port.xmit_buf = (unsigned char *) page; |
955 | 934 | ||
956 | /* | 935 | /* |
957 | * Clear the FIFO buffers and disable them | 936 | * Clear the FIFO buffers and disable them |
@@ -973,8 +952,8 @@ static int mxser_startup(struct mxser_port *info) | |||
973 | if (inb(info->ioaddr + UART_LSR) == 0xff) { | 952 | if (inb(info->ioaddr + UART_LSR) == 0xff) { |
974 | spin_unlock_irqrestore(&info->slock, flags); | 953 | spin_unlock_irqrestore(&info->slock, flags); |
975 | if (capable(CAP_SYS_ADMIN)) { | 954 | if (capable(CAP_SYS_ADMIN)) { |
976 | if (info->tty) | 955 | if (info->port.tty) |
977 | set_bit(TTY_IO_ERROR, &info->tty->flags); | 956 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); |
978 | return 0; | 957 | return 0; |
979 | } else | 958 | } else |
980 | return -ENODEV; | 959 | return -ENODEV; |
@@ -1012,15 +991,15 @@ static int mxser_startup(struct mxser_port *info) | |||
1012 | (void) inb(info->ioaddr + UART_IIR); | 991 | (void) inb(info->ioaddr + UART_IIR); |
1013 | (void) inb(info->ioaddr + UART_MSR); | 992 | (void) inb(info->ioaddr + UART_MSR); |
1014 | 993 | ||
1015 | if (info->tty) | 994 | if (info->port.tty) |
1016 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | 995 | clear_bit(TTY_IO_ERROR, &info->port.tty->flags); |
1017 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 996 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
1018 | 997 | ||
1019 | /* | 998 | /* |
1020 | * and set the speed of the serial port | 999 | * and set the speed of the serial port |
1021 | */ | 1000 | */ |
1022 | mxser_change_speed(info, NULL); | 1001 | mxser_change_speed(info, NULL); |
1023 | info->flags |= ASYNC_INITIALIZED; | 1002 | info->port.flags |= ASYNC_INITIALIZED; |
1024 | spin_unlock_irqrestore(&info->slock, flags); | 1003 | spin_unlock_irqrestore(&info->slock, flags); |
1025 | 1004 | ||
1026 | return 0; | 1005 | return 0; |
@@ -1034,7 +1013,7 @@ static void mxser_shutdown(struct mxser_port *info) | |||
1034 | { | 1013 | { |
1035 | unsigned long flags; | 1014 | unsigned long flags; |
1036 | 1015 | ||
1037 | if (!(info->flags & ASYNC_INITIALIZED)) | 1016 | if (!(info->port.flags & ASYNC_INITIALIZED)) |
1038 | return; | 1017 | return; |
1039 | 1018 | ||
1040 | spin_lock_irqsave(&info->slock, flags); | 1019 | spin_lock_irqsave(&info->slock, flags); |
@@ -1048,15 +1027,15 @@ static void mxser_shutdown(struct mxser_port *info) | |||
1048 | /* | 1027 | /* |
1049 | * Free the IRQ, if necessary | 1028 | * Free the IRQ, if necessary |
1050 | */ | 1029 | */ |
1051 | if (info->xmit_buf) { | 1030 | if (info->port.xmit_buf) { |
1052 | free_page((unsigned long) info->xmit_buf); | 1031 | free_page((unsigned long) info->port.xmit_buf); |
1053 | info->xmit_buf = NULL; | 1032 | info->port.xmit_buf = NULL; |
1054 | } | 1033 | } |
1055 | 1034 | ||
1056 | info->IER = 0; | 1035 | info->IER = 0; |
1057 | outb(0x00, info->ioaddr + UART_IER); | 1036 | outb(0x00, info->ioaddr + UART_IER); |
1058 | 1037 | ||
1059 | if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) | 1038 | if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) |
1060 | info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); | 1039 | info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); |
1061 | outb(info->MCR, info->ioaddr + UART_MCR); | 1040 | outb(info->MCR, info->ioaddr + UART_MCR); |
1062 | 1041 | ||
@@ -1072,10 +1051,10 @@ static void mxser_shutdown(struct mxser_port *info) | |||
1072 | /* read data port to reset things */ | 1051 | /* read data port to reset things */ |
1073 | (void) inb(info->ioaddr + UART_RX); | 1052 | (void) inb(info->ioaddr + UART_RX); |
1074 | 1053 | ||
1075 | if (info->tty) | 1054 | if (info->port.tty) |
1076 | set_bit(TTY_IO_ERROR, &info->tty->flags); | 1055 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); |
1077 | 1056 | ||
1078 | info->flags &= ~ASYNC_INITIALIZED; | 1057 | info->port.flags &= ~ASYNC_INITIALIZED; |
1079 | 1058 | ||
1080 | if (info->board->chip_flag) | 1059 | if (info->board->chip_flag) |
1081 | SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr); | 1060 | SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr); |
@@ -1105,12 +1084,12 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
1105 | return -ENODEV; | 1084 | return -ENODEV; |
1106 | 1085 | ||
1107 | tty->driver_data = info; | 1086 | tty->driver_data = info; |
1108 | info->tty = tty; | 1087 | info->port.tty = tty; |
1109 | /* | 1088 | /* |
1110 | * Start up serial port | 1089 | * Start up serial port |
1111 | */ | 1090 | */ |
1112 | spin_lock_irqsave(&info->slock, flags); | 1091 | spin_lock_irqsave(&info->slock, flags); |
1113 | info->count++; | 1092 | info->port.count++; |
1114 | spin_unlock_irqrestore(&info->slock, flags); | 1093 | spin_unlock_irqrestore(&info->slock, flags); |
1115 | retval = mxser_startup(info); | 1094 | retval = mxser_startup(info); |
1116 | if (retval) | 1095 | if (retval) |
@@ -1170,42 +1149,42 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1170 | spin_unlock_irqrestore(&info->slock, flags); | 1149 | spin_unlock_irqrestore(&info->slock, flags); |
1171 | return; | 1150 | return; |
1172 | } | 1151 | } |
1173 | if ((tty->count == 1) && (info->count != 1)) { | 1152 | if ((tty->count == 1) && (info->port.count != 1)) { |
1174 | /* | 1153 | /* |
1175 | * Uh, oh. tty->count is 1, which means that the tty | 1154 | * Uh, oh. tty->count is 1, which means that the tty |
1176 | * structure will be freed. Info->count should always | 1155 | * structure will be freed. Info->port.count should always |
1177 | * be one in these conditions. If it's greater than | 1156 | * be one in these conditions. If it's greater than |
1178 | * one, we've got real problems, since it means the | 1157 | * one, we've got real problems, since it means the |
1179 | * serial port won't be shutdown. | 1158 | * serial port won't be shutdown. |
1180 | */ | 1159 | */ |
1181 | printk(KERN_ERR "mxser_close: bad serial port count; " | 1160 | printk(KERN_ERR "mxser_close: bad serial port count; " |
1182 | "tty->count is 1, info->count is %d\n", info->count); | 1161 | "tty->count is 1, info->port.count is %d\n", info->port.count); |
1183 | info->count = 1; | 1162 | info->port.count = 1; |
1184 | } | 1163 | } |
1185 | if (--info->count < 0) { | 1164 | if (--info->port.count < 0) { |
1186 | printk(KERN_ERR "mxser_close: bad serial port count for " | 1165 | printk(KERN_ERR "mxser_close: bad serial port count for " |
1187 | "ttys%d: %d\n", tty->index, info->count); | 1166 | "ttys%d: %d\n", tty->index, info->port.count); |
1188 | info->count = 0; | 1167 | info->port.count = 0; |
1189 | } | 1168 | } |
1190 | if (info->count) { | 1169 | if (info->port.count) { |
1191 | spin_unlock_irqrestore(&info->slock, flags); | 1170 | spin_unlock_irqrestore(&info->slock, flags); |
1192 | return; | 1171 | return; |
1193 | } | 1172 | } |
1194 | info->flags |= ASYNC_CLOSING; | 1173 | info->port.flags |= ASYNC_CLOSING; |
1195 | spin_unlock_irqrestore(&info->slock, flags); | 1174 | spin_unlock_irqrestore(&info->slock, flags); |
1196 | /* | 1175 | /* |
1197 | * Save the termios structure, since this port may have | 1176 | * Save the termios structure, since this port may have |
1198 | * separate termios for callout and dialin. | 1177 | * separate termios for callout and dialin. |
1199 | */ | 1178 | */ |
1200 | if (info->flags & ASYNC_NORMAL_ACTIVE) | 1179 | if (info->port.flags & ASYNC_NORMAL_ACTIVE) |
1201 | info->normal_termios = *tty->termios; | 1180 | info->normal_termios = *tty->termios; |
1202 | /* | 1181 | /* |
1203 | * Now we wait for the transmit buffer to clear; and we notify | 1182 | * Now we wait for the transmit buffer to clear; and we notify |
1204 | * the line discipline to only process XON/XOFF characters. | 1183 | * the line discipline to only process XON/XOFF characters. |
1205 | */ | 1184 | */ |
1206 | tty->closing = 1; | 1185 | tty->closing = 1; |
1207 | if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) | 1186 | if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) |
1208 | tty_wait_until_sent(tty, info->closing_wait); | 1187 | tty_wait_until_sent(tty, info->port.closing_wait); |
1209 | /* | 1188 | /* |
1210 | * At this point we stop accepting input. To do this, we | 1189 | * At this point we stop accepting input. To do this, we |
1211 | * disable the receive line status interrupts, and tell the | 1190 | * disable the receive line status interrupts, and tell the |
@@ -1216,7 +1195,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1216 | if (info->board->chip_flag) | 1195 | if (info->board->chip_flag) |
1217 | info->IER &= ~MOXA_MUST_RECV_ISR; | 1196 | info->IER &= ~MOXA_MUST_RECV_ISR; |
1218 | 1197 | ||
1219 | if (info->flags & ASYNC_INITIALIZED) { | 1198 | if (info->port.flags & ASYNC_INITIALIZED) { |
1220 | outb(info->IER, info->ioaddr + UART_IER); | 1199 | outb(info->IER, info->ioaddr + UART_IER); |
1221 | /* | 1200 | /* |
1222 | * Before we drop DTR, make sure the UART transmitter | 1201 | * Before we drop DTR, make sure the UART transmitter |
@@ -1236,15 +1215,14 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1236 | tty_ldisc_flush(tty); | 1215 | tty_ldisc_flush(tty); |
1237 | 1216 | ||
1238 | tty->closing = 0; | 1217 | tty->closing = 0; |
1239 | info->event = 0; | 1218 | info->port.tty = NULL; |
1240 | info->tty = NULL; | 1219 | if (info->port.blocked_open) { |
1241 | if (info->blocked_open) { | 1220 | if (info->port.close_delay) |
1242 | if (info->close_delay) | 1221 | schedule_timeout_interruptible(info->port.close_delay); |
1243 | schedule_timeout_interruptible(info->close_delay); | 1222 | wake_up_interruptible(&info->port.open_wait); |
1244 | wake_up_interruptible(&info->open_wait); | ||
1245 | } | 1223 | } |
1246 | 1224 | ||
1247 | info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); | 1225 | info->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); |
1248 | } | 1226 | } |
1249 | 1227 | ||
1250 | static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) | 1228 | static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) |
@@ -1253,7 +1231,7 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou | |||
1253 | struct mxser_port *info = tty->driver_data; | 1231 | struct mxser_port *info = tty->driver_data; |
1254 | unsigned long flags; | 1232 | unsigned long flags; |
1255 | 1233 | ||
1256 | if (!info->xmit_buf) | 1234 | if (!info->port.xmit_buf) |
1257 | return 0; | 1235 | return 0; |
1258 | 1236 | ||
1259 | while (1) { | 1237 | while (1) { |
@@ -1262,7 +1240,7 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou | |||
1262 | if (c <= 0) | 1240 | if (c <= 0) |
1263 | break; | 1241 | break; |
1264 | 1242 | ||
1265 | memcpy(info->xmit_buf + info->xmit_head, buf, c); | 1243 | memcpy(info->port.xmit_buf + info->xmit_head, buf, c); |
1266 | spin_lock_irqsave(&info->slock, flags); | 1244 | spin_lock_irqsave(&info->slock, flags); |
1267 | info->xmit_head = (info->xmit_head + c) & | 1245 | info->xmit_head = (info->xmit_head + c) & |
1268 | (SERIAL_XMIT_SIZE - 1); | 1246 | (SERIAL_XMIT_SIZE - 1); |
@@ -1294,14 +1272,14 @@ static int mxser_put_char(struct tty_struct *tty, unsigned char ch) | |||
1294 | struct mxser_port *info = tty->driver_data; | 1272 | struct mxser_port *info = tty->driver_data; |
1295 | unsigned long flags; | 1273 | unsigned long flags; |
1296 | 1274 | ||
1297 | if (!info->xmit_buf) | 1275 | if (!info->port.xmit_buf) |
1298 | return 0; | 1276 | return 0; |
1299 | 1277 | ||
1300 | if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) | 1278 | if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) |
1301 | return 0; | 1279 | return 0; |
1302 | 1280 | ||
1303 | spin_lock_irqsave(&info->slock, flags); | 1281 | spin_lock_irqsave(&info->slock, flags); |
1304 | info->xmit_buf[info->xmit_head++] = ch; | 1282 | info->port.xmit_buf[info->xmit_head++] = ch; |
1305 | info->xmit_head &= SERIAL_XMIT_SIZE - 1; | 1283 | info->xmit_head &= SERIAL_XMIT_SIZE - 1; |
1306 | info->xmit_cnt++; | 1284 | info->xmit_cnt++; |
1307 | spin_unlock_irqrestore(&info->slock, flags); | 1285 | spin_unlock_irqrestore(&info->slock, flags); |
@@ -1325,13 +1303,9 @@ static void mxser_flush_chars(struct tty_struct *tty) | |||
1325 | struct mxser_port *info = tty->driver_data; | 1303 | struct mxser_port *info = tty->driver_data; |
1326 | unsigned long flags; | 1304 | unsigned long flags; |
1327 | 1305 | ||
1328 | if (info->xmit_cnt <= 0 || | 1306 | if (info->xmit_cnt <= 0 || tty->stopped || !info->port.xmit_buf || |
1329 | tty->stopped || | 1307 | (tty->hw_stopped && info->type != PORT_16550A && |
1330 | !info->xmit_buf || | 1308 | !info->board->chip_flag)) |
1331 | (tty->hw_stopped && | ||
1332 | (info->type != PORT_16550A) && | ||
1333 | (!info->board->chip_flag) | ||
1334 | )) | ||
1335 | return; | 1309 | return; |
1336 | 1310 | ||
1337 | spin_lock_irqsave(&info->slock, flags); | 1311 | spin_lock_irqsave(&info->slock, flags); |
@@ -1349,9 +1323,7 @@ static int mxser_write_room(struct tty_struct *tty) | |||
1349 | int ret; | 1323 | int ret; |
1350 | 1324 | ||
1351 | ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; | 1325 | ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; |
1352 | if (ret < 0) | 1326 | return ret < 0 ? 0 : ret; |
1353 | ret = 0; | ||
1354 | return ret; | ||
1355 | } | 1327 | } |
1356 | 1328 | ||
1357 | static int mxser_chars_in_buffer(struct tty_struct *tty) | 1329 | static int mxser_chars_in_buffer(struct tty_struct *tty) |
@@ -1370,13 +1342,13 @@ static int mxser_get_serial_info(struct mxser_port *info, | |||
1370 | { | 1342 | { |
1371 | struct serial_struct tmp = { | 1343 | struct serial_struct tmp = { |
1372 | .type = info->type, | 1344 | .type = info->type, |
1373 | .line = info->tty->index, | 1345 | .line = info->port.tty->index, |
1374 | .port = info->ioaddr, | 1346 | .port = info->ioaddr, |
1375 | .irq = info->board->irq, | 1347 | .irq = info->board->irq, |
1376 | .flags = info->flags, | 1348 | .flags = info->port.flags, |
1377 | .baud_base = info->baud_base, | 1349 | .baud_base = info->baud_base, |
1378 | .close_delay = info->close_delay, | 1350 | .close_delay = info->port.close_delay, |
1379 | .closing_wait = info->closing_wait, | 1351 | .closing_wait = info->port.closing_wait, |
1380 | .custom_divisor = info->custom_divisor, | 1352 | .custom_divisor = info->custom_divisor, |
1381 | .hub6 = 0 | 1353 | .hub6 = 0 |
1382 | }; | 1354 | }; |
@@ -1403,33 +1375,32 @@ static int mxser_set_serial_info(struct mxser_port *info, | |||
1403 | new_serial.port != info->ioaddr) | 1375 | new_serial.port != info->ioaddr) |
1404 | return -EINVAL; | 1376 | return -EINVAL; |
1405 | 1377 | ||
1406 | flags = info->flags & ASYNC_SPD_MASK; | 1378 | flags = info->port.flags & ASYNC_SPD_MASK; |
1407 | 1379 | ||
1408 | if (!capable(CAP_SYS_ADMIN)) { | 1380 | if (!capable(CAP_SYS_ADMIN)) { |
1409 | if ((new_serial.baud_base != info->baud_base) || | 1381 | if ((new_serial.baud_base != info->baud_base) || |
1410 | (new_serial.close_delay != info->close_delay) || | 1382 | (new_serial.close_delay != info->port.close_delay) || |
1411 | ((new_serial.flags & ~ASYNC_USR_MASK) != (info->flags & ~ASYNC_USR_MASK))) | 1383 | ((new_serial.flags & ~ASYNC_USR_MASK) != (info->port.flags & ~ASYNC_USR_MASK))) |
1412 | return -EPERM; | 1384 | return -EPERM; |
1413 | info->flags = ((info->flags & ~ASYNC_USR_MASK) | | 1385 | info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) | |
1414 | (new_serial.flags & ASYNC_USR_MASK)); | 1386 | (new_serial.flags & ASYNC_USR_MASK)); |
1415 | } else { | 1387 | } else { |
1416 | /* | 1388 | /* |
1417 | * OK, past this point, all the error checking has been done. | 1389 | * OK, past this point, all the error checking has been done. |
1418 | * At this point, we start making changes..... | 1390 | * At this point, we start making changes..... |
1419 | */ | 1391 | */ |
1420 | info->flags = ((info->flags & ~ASYNC_FLAGS) | | 1392 | info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) | |
1421 | (new_serial.flags & ASYNC_FLAGS)); | 1393 | (new_serial.flags & ASYNC_FLAGS)); |
1422 | info->close_delay = new_serial.close_delay * HZ / 100; | 1394 | info->port.close_delay = new_serial.close_delay * HZ / 100; |
1423 | info->closing_wait = new_serial.closing_wait * HZ / 100; | 1395 | info->port.closing_wait = new_serial.closing_wait * HZ / 100; |
1424 | info->tty->low_latency = | 1396 | info->port.tty->low_latency = |
1425 | (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1397 | (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1426 | info->tty->low_latency = 0; | 1398 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && |
1427 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && | ||
1428 | (new_serial.baud_base != info->baud_base || | 1399 | (new_serial.baud_base != info->baud_base || |
1429 | new_serial.custom_divisor != | 1400 | new_serial.custom_divisor != |
1430 | info->custom_divisor)) { | 1401 | info->custom_divisor)) { |
1431 | baud = new_serial.baud_base / new_serial.custom_divisor; | 1402 | baud = new_serial.baud_base / new_serial.custom_divisor; |
1432 | tty_encode_baud_rate(info->tty, baud, baud); | 1403 | tty_encode_baud_rate(info->port.tty, baud, baud); |
1433 | } | 1404 | } |
1434 | } | 1405 | } |
1435 | 1406 | ||
@@ -1437,8 +1408,8 @@ static int mxser_set_serial_info(struct mxser_port *info, | |||
1437 | 1408 | ||
1438 | process_txrx_fifo(info); | 1409 | process_txrx_fifo(info); |
1439 | 1410 | ||
1440 | if (info->flags & ASYNC_INITIALIZED) { | 1411 | if (info->port.flags & ASYNC_INITIALIZED) { |
1441 | if (flags != (info->flags & ASYNC_SPD_MASK)) { | 1412 | if (flags != (info->port.flags & ASYNC_SPD_MASK)) { |
1442 | spin_lock_irqsave(&info->slock, sl_flags); | 1413 | spin_lock_irqsave(&info->slock, sl_flags); |
1443 | mxser_change_speed(info, NULL); | 1414 | mxser_change_speed(info, NULL); |
1444 | spin_unlock_irqrestore(&info->slock, sl_flags); | 1415 | spin_unlock_irqrestore(&info->slock, sl_flags); |
@@ -1473,27 +1444,6 @@ static int mxser_get_lsr_info(struct mxser_port *info, | |||
1473 | return put_user(result, value); | 1444 | return put_user(result, value); |
1474 | } | 1445 | } |
1475 | 1446 | ||
1476 | /* | ||
1477 | * This routine sends a break character out the serial port. | ||
1478 | */ | ||
1479 | static void mxser_send_break(struct mxser_port *info, int duration) | ||
1480 | { | ||
1481 | unsigned long flags; | ||
1482 | |||
1483 | if (!info->ioaddr) | ||
1484 | return; | ||
1485 | set_current_state(TASK_INTERRUPTIBLE); | ||
1486 | spin_lock_irqsave(&info->slock, flags); | ||
1487 | outb(inb(info->ioaddr + UART_LCR) | UART_LCR_SBC, | ||
1488 | info->ioaddr + UART_LCR); | ||
1489 | spin_unlock_irqrestore(&info->slock, flags); | ||
1490 | schedule_timeout(duration); | ||
1491 | spin_lock_irqsave(&info->slock, flags); | ||
1492 | outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC, | ||
1493 | info->ioaddr + UART_LCR); | ||
1494 | spin_unlock_irqrestore(&info->slock, flags); | ||
1495 | } | ||
1496 | |||
1497 | static int mxser_tiocmget(struct tty_struct *tty, struct file *file) | 1447 | static int mxser_tiocmget(struct tty_struct *tty, struct file *file) |
1498 | { | 1448 | { |
1499 | struct mxser_port *info = tty->driver_data; | 1449 | struct mxser_port *info = tty->driver_data; |
@@ -1662,6 +1612,8 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1662 | 1612 | ||
1663 | switch (cmd) { | 1613 | switch (cmd) { |
1664 | case MOXA_GET_MAJOR: | 1614 | case MOXA_GET_MAJOR: |
1615 | printk(KERN_WARNING "mxser: '%s' uses deprecated ioctl %x, fix " | ||
1616 | "your userspace\n", current->comm, cmd); | ||
1665 | return put_user(ttymajor, (int __user *)argp); | 1617 | return put_user(ttymajor, (int __user *)argp); |
1666 | 1618 | ||
1667 | case MOXA_CHKPORTENABLE: | 1619 | case MOXA_CHKPORTENABLE: |
@@ -1679,62 +1631,60 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1679 | ret = -EFAULT; | 1631 | ret = -EFAULT; |
1680 | unlock_kernel(); | 1632 | unlock_kernel(); |
1681 | return ret; | 1633 | return ret; |
1682 | case MOXA_GETMSTATUS: | 1634 | case MOXA_GETMSTATUS: { |
1635 | struct mxser_mstatus ms, __user *msu = argp; | ||
1683 | lock_kernel(); | 1636 | lock_kernel(); |
1684 | for (i = 0; i < MXSER_BOARDS; i++) | 1637 | for (i = 0; i < MXSER_BOARDS; i++) |
1685 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { | 1638 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { |
1686 | port = &mxser_boards[i].ports[j]; | 1639 | port = &mxser_boards[i].ports[j]; |
1640 | memset(&ms, 0, sizeof(ms)); | ||
1687 | 1641 | ||
1688 | GMStatus[i].ri = 0; | 1642 | if (!port->ioaddr) |
1689 | if (!port->ioaddr) { | 1643 | goto copy; |
1690 | GMStatus[i].dcd = 0; | ||
1691 | GMStatus[i].dsr = 0; | ||
1692 | GMStatus[i].cts = 0; | ||
1693 | continue; | ||
1694 | } | ||
1695 | 1644 | ||
1696 | if (!port->tty || !port->tty->termios) | 1645 | if (!port->port.tty || !port->port.tty->termios) |
1697 | GMStatus[i].cflag = | 1646 | ms.cflag = port->normal_termios.c_cflag; |
1698 | port->normal_termios.c_cflag; | ||
1699 | else | 1647 | else |
1700 | GMStatus[i].cflag = | 1648 | ms.cflag = port->port.tty->termios->c_cflag; |
1701 | port->tty->termios->c_cflag; | ||
1702 | 1649 | ||
1703 | status = inb(port->ioaddr + UART_MSR); | 1650 | status = inb(port->ioaddr + UART_MSR); |
1704 | if (status & 0x80 /*UART_MSR_DCD */ ) | 1651 | if (status & UART_MSR_DCD) |
1705 | GMStatus[i].dcd = 1; | 1652 | ms.dcd = 1; |
1706 | else | 1653 | if (status & UART_MSR_DSR) |
1707 | GMStatus[i].dcd = 0; | 1654 | ms.dsr = 1; |
1708 | 1655 | if (status & UART_MSR_CTS) | |
1709 | if (status & 0x20 /*UART_MSR_DSR */ ) | 1656 | ms.cts = 1; |
1710 | GMStatus[i].dsr = 1; | 1657 | copy: |
1711 | else | 1658 | if (copy_to_user(msu, &ms, sizeof(ms))) { |
1712 | GMStatus[i].dsr = 0; | 1659 | unlock_kernel(); |
1713 | 1660 | return -EFAULT; | |
1714 | 1661 | } | |
1715 | if (status & 0x10 /*UART_MSR_CTS */ ) | 1662 | msu++; |
1716 | GMStatus[i].cts = 1; | ||
1717 | else | ||
1718 | GMStatus[i].cts = 0; | ||
1719 | } | 1663 | } |
1720 | unlock_kernel(); | 1664 | unlock_kernel(); |
1721 | if (copy_to_user(argp, GMStatus, | ||
1722 | sizeof(struct mxser_mstatus) * MXSER_PORTS)) | ||
1723 | return -EFAULT; | ||
1724 | return 0; | 1665 | return 0; |
1666 | } | ||
1725 | case MOXA_ASPP_MON_EXT: { | 1667 | case MOXA_ASPP_MON_EXT: { |
1726 | int p, shiftbit; | 1668 | struct mxser_mon_ext *me; /* it's 2k, stack unfriendly */ |
1727 | unsigned long opmode; | 1669 | unsigned int cflag, iflag, p; |
1728 | unsigned cflag, iflag; | 1670 | u8 opmode; |
1671 | |||
1672 | me = kzalloc(sizeof(*me), GFP_KERNEL); | ||
1673 | if (!me) | ||
1674 | return -ENOMEM; | ||
1729 | 1675 | ||
1730 | lock_kernel(); | 1676 | lock_kernel(); |
1731 | for (i = 0; i < MXSER_BOARDS; i++) { | 1677 | for (i = 0, p = 0; i < MXSER_BOARDS; i++) { |
1732 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { | 1678 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++, p++) { |
1679 | if (p >= ARRAY_SIZE(me->rx_cnt)) { | ||
1680 | i = MXSER_BOARDS; | ||
1681 | break; | ||
1682 | } | ||
1733 | port = &mxser_boards[i].ports[j]; | 1683 | port = &mxser_boards[i].ports[j]; |
1734 | if (!port->ioaddr) | 1684 | if (!port->ioaddr) |
1735 | continue; | 1685 | continue; |
1736 | 1686 | ||
1737 | status = mxser_get_msr(port->ioaddr, 0, i); | 1687 | status = mxser_get_msr(port->ioaddr, 0, p); |
1738 | 1688 | ||
1739 | if (status & UART_MSR_TERI) | 1689 | if (status & UART_MSR_TERI) |
1740 | port->icount.rng++; | 1690 | port->icount.rng++; |
@@ -1746,59 +1696,47 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1746 | port->icount.cts++; | 1696 | port->icount.cts++; |
1747 | 1697 | ||
1748 | port->mon_data.modem_status = status; | 1698 | port->mon_data.modem_status = status; |
1749 | mon_data_ext.rx_cnt[i] = port->mon_data.rxcnt; | 1699 | me->rx_cnt[p] = port->mon_data.rxcnt; |
1750 | mon_data_ext.tx_cnt[i] = port->mon_data.txcnt; | 1700 | me->tx_cnt[p] = port->mon_data.txcnt; |
1751 | mon_data_ext.up_rxcnt[i] = | 1701 | me->up_rxcnt[p] = port->mon_data.up_rxcnt; |
1752 | port->mon_data.up_rxcnt; | 1702 | me->up_txcnt[p] = port->mon_data.up_txcnt; |
1753 | mon_data_ext.up_txcnt[i] = | 1703 | me->modem_status[p] = |
1754 | port->mon_data.up_txcnt; | ||
1755 | mon_data_ext.modem_status[i] = | ||
1756 | port->mon_data.modem_status; | 1704 | port->mon_data.modem_status; |
1757 | mon_data_ext.baudrate[i] = | 1705 | me->baudrate[p] = tty_get_baud_rate(port->port.tty); |
1758 | tty_get_baud_rate(port->tty); | ||
1759 | 1706 | ||
1760 | if (!port->tty || !port->tty->termios) { | 1707 | if (!port->port.tty || !port->port.tty->termios) { |
1761 | cflag = port->normal_termios.c_cflag; | 1708 | cflag = port->normal_termios.c_cflag; |
1762 | iflag = port->normal_termios.c_iflag; | 1709 | iflag = port->normal_termios.c_iflag; |
1763 | } else { | 1710 | } else { |
1764 | cflag = port->tty->termios->c_cflag; | 1711 | cflag = port->port.tty->termios->c_cflag; |
1765 | iflag = port->tty->termios->c_iflag; | 1712 | iflag = port->port.tty->termios->c_iflag; |
1766 | } | 1713 | } |
1767 | 1714 | ||
1768 | mon_data_ext.databits[i] = cflag & CSIZE; | 1715 | me->databits[p] = cflag & CSIZE; |
1769 | 1716 | me->stopbits[p] = cflag & CSTOPB; | |
1770 | mon_data_ext.stopbits[i] = cflag & CSTOPB; | 1717 | me->parity[p] = cflag & (PARENB | PARODD | |
1771 | 1718 | CMSPAR); | |
1772 | mon_data_ext.parity[i] = | ||
1773 | cflag & (PARENB | PARODD | CMSPAR); | ||
1774 | |||
1775 | mon_data_ext.flowctrl[i] = 0x00; | ||
1776 | 1719 | ||
1777 | if (cflag & CRTSCTS) | 1720 | if (cflag & CRTSCTS) |
1778 | mon_data_ext.flowctrl[i] |= 0x03; | 1721 | me->flowctrl[p] |= 0x03; |
1779 | 1722 | ||
1780 | if (iflag & (IXON | IXOFF)) | 1723 | if (iflag & (IXON | IXOFF)) |
1781 | mon_data_ext.flowctrl[i] |= 0x0C; | 1724 | me->flowctrl[p] |= 0x0C; |
1782 | 1725 | ||
1783 | if (port->type == PORT_16550A) | 1726 | if (port->type == PORT_16550A) |
1784 | mon_data_ext.fifo[i] = 1; | 1727 | me->fifo[p] = 1; |
1785 | else | ||
1786 | mon_data_ext.fifo[i] = 0; | ||
1787 | 1728 | ||
1788 | p = i % 4; | 1729 | opmode = inb(port->opmode_ioaddr) >> |
1789 | shiftbit = p * 2; | 1730 | ((p % 4) * 2); |
1790 | opmode = inb(port->opmode_ioaddr) >> shiftbit; | ||
1791 | opmode &= OP_MODE_MASK; | 1731 | opmode &= OP_MODE_MASK; |
1792 | 1732 | me->iftype[p] = opmode; | |
1793 | mon_data_ext.iftype[i] = opmode; | ||
1794 | |||
1795 | } | 1733 | } |
1796 | } | 1734 | } |
1797 | unlock_kernel(); | 1735 | unlock_kernel(); |
1798 | if (copy_to_user(argp, &mon_data_ext, | 1736 | if (copy_to_user(argp, me, sizeof(*me))) |
1799 | sizeof(mon_data_ext))) | 1737 | ret = -EFAULT; |
1800 | return -EFAULT; | 1738 | kfree(me); |
1801 | return 0; | 1739 | return ret; |
1802 | } | 1740 | } |
1803 | default: | 1741 | default: |
1804 | return -ENOIOCTLCMD; | 1742 | return -ENOIOCTLCMD; |
@@ -1832,7 +1770,6 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1832 | { | 1770 | { |
1833 | struct mxser_port *info = tty->driver_data; | 1771 | struct mxser_port *info = tty->driver_data; |
1834 | struct async_icount cnow; | 1772 | struct async_icount cnow; |
1835 | struct serial_icounter_struct __user *p_cuser; | ||
1836 | unsigned long flags; | 1773 | unsigned long flags; |
1837 | void __user *argp = (void __user *)arg; | 1774 | void __user *argp = (void __user *)arg; |
1838 | int retval; | 1775 | int retval; |
@@ -1881,21 +1818,6 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1881 | return -EIO; | 1818 | return -EIO; |
1882 | 1819 | ||
1883 | switch (cmd) { | 1820 | switch (cmd) { |
1884 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | ||
1885 | retval = tty_check_change(tty); | ||
1886 | if (retval) | ||
1887 | return retval; | ||
1888 | tty_wait_until_sent(tty, 0); | ||
1889 | if (!arg) | ||
1890 | mxser_send_break(info, HZ / 4); /* 1/4 second */ | ||
1891 | return 0; | ||
1892 | case TCSBRKP: /* support for POSIX tcsendbreak() */ | ||
1893 | retval = tty_check_change(tty); | ||
1894 | if (retval) | ||
1895 | return retval; | ||
1896 | tty_wait_until_sent(tty, 0); | ||
1897 | mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4); | ||
1898 | return 0; | ||
1899 | case TIOCGSERIAL: | 1821 | case TIOCGSERIAL: |
1900 | lock_kernel(); | 1822 | lock_kernel(); |
1901 | retval = mxser_get_serial_info(info, argp); | 1823 | retval = mxser_get_serial_info(info, argp); |
@@ -1927,30 +1849,26 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1927 | * NB: both 1->0 and 0->1 transitions are counted except for | 1849 | * NB: both 1->0 and 0->1 transitions are counted except for |
1928 | * RI where only 0->1 is counted. | 1850 | * RI where only 0->1 is counted. |
1929 | */ | 1851 | */ |
1930 | case TIOCGICOUNT: | 1852 | case TIOCGICOUNT: { |
1853 | struct serial_icounter_struct icnt = { 0 }; | ||
1931 | spin_lock_irqsave(&info->slock, flags); | 1854 | spin_lock_irqsave(&info->slock, flags); |
1932 | cnow = info->icount; | 1855 | cnow = info->icount; |
1933 | spin_unlock_irqrestore(&info->slock, flags); | 1856 | spin_unlock_irqrestore(&info->slock, flags); |
1934 | p_cuser = argp; | 1857 | |
1935 | if (put_user(cnow.frame, &p_cuser->frame)) | 1858 | icnt.frame = cnow.frame; |
1936 | return -EFAULT; | 1859 | icnt.brk = cnow.brk; |
1937 | if (put_user(cnow.brk, &p_cuser->brk)) | 1860 | icnt.overrun = cnow.overrun; |
1938 | return -EFAULT; | 1861 | icnt.buf_overrun = cnow.buf_overrun; |
1939 | if (put_user(cnow.overrun, &p_cuser->overrun)) | 1862 | icnt.parity = cnow.parity; |
1940 | return -EFAULT; | 1863 | icnt.rx = cnow.rx; |
1941 | if (put_user(cnow.buf_overrun, &p_cuser->buf_overrun)) | 1864 | icnt.tx = cnow.tx; |
1942 | return -EFAULT; | 1865 | icnt.cts = cnow.cts; |
1943 | if (put_user(cnow.parity, &p_cuser->parity)) | 1866 | icnt.dsr = cnow.dsr; |
1944 | return -EFAULT; | 1867 | icnt.rng = cnow.rng; |
1945 | if (put_user(cnow.rx, &p_cuser->rx)) | 1868 | icnt.dcd = cnow.dcd; |
1946 | return -EFAULT; | 1869 | |
1947 | if (put_user(cnow.tx, &p_cuser->tx)) | 1870 | return copy_to_user(argp, &icnt, sizeof(icnt)) ? -EFAULT : 0; |
1948 | return -EFAULT; | 1871 | } |
1949 | put_user(cnow.cts, &p_cuser->cts); | ||
1950 | put_user(cnow.dsr, &p_cuser->dsr); | ||
1951 | put_user(cnow.rng, &p_cuser->rng); | ||
1952 | put_user(cnow.dcd, &p_cuser->dcd); | ||
1953 | return 0; | ||
1954 | case MOXA_HighSpeedOn: | 1872 | case MOXA_HighSpeedOn: |
1955 | return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); | 1873 | return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); |
1956 | case MOXA_SDS_RSTICOUNTER: | 1874 | case MOXA_SDS_RSTICOUNTER: |
@@ -1989,7 +1907,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1989 | else | 1907 | else |
1990 | info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; | 1908 | info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; |
1991 | 1909 | ||
1992 | if (info->tty->hw_stopped) | 1910 | if (info->port.tty->hw_stopped) |
1993 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; | 1911 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; |
1994 | else | 1912 | else |
1995 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; | 1913 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; |
@@ -2038,7 +1956,7 @@ static void mxser_stoprx(struct tty_struct *tty) | |||
2038 | } | 1956 | } |
2039 | } | 1957 | } |
2040 | 1958 | ||
2041 | if (info->tty->termios->c_cflag & CRTSCTS) { | 1959 | if (info->port.tty->termios->c_cflag & CRTSCTS) { |
2042 | info->MCR &= ~UART_MCR_RTS; | 1960 | info->MCR &= ~UART_MCR_RTS; |
2043 | outb(info->MCR, info->ioaddr + UART_MCR); | 1961 | outb(info->MCR, info->ioaddr + UART_MCR); |
2044 | } | 1962 | } |
@@ -2075,7 +1993,7 @@ static void mxser_unthrottle(struct tty_struct *tty) | |||
2075 | } | 1993 | } |
2076 | } | 1994 | } |
2077 | 1995 | ||
2078 | if (info->tty->termios->c_cflag & CRTSCTS) { | 1996 | if (info->port.tty->termios->c_cflag & CRTSCTS) { |
2079 | info->MCR |= UART_MCR_RTS; | 1997 | info->MCR |= UART_MCR_RTS; |
2080 | outb(info->MCR, info->ioaddr + UART_MCR); | 1998 | outb(info->MCR, info->ioaddr + UART_MCR); |
2081 | } | 1999 | } |
@@ -2106,7 +2024,7 @@ static void mxser_start(struct tty_struct *tty) | |||
2106 | unsigned long flags; | 2024 | unsigned long flags; |
2107 | 2025 | ||
2108 | spin_lock_irqsave(&info->slock, flags); | 2026 | spin_lock_irqsave(&info->slock, flags); |
2109 | if (info->xmit_cnt && info->xmit_buf) { | 2027 | if (info->xmit_cnt && info->port.xmit_buf) { |
2110 | outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); | 2028 | outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); |
2111 | info->IER |= UART_IER_THRI; | 2029 | info->IER |= UART_IER_THRI; |
2112 | outb(info->IER, info->ioaddr + UART_IER); | 2030 | outb(info->IER, info->ioaddr + UART_IER); |
@@ -2219,17 +2137,16 @@ static void mxser_hangup(struct tty_struct *tty) | |||
2219 | 2137 | ||
2220 | mxser_flush_buffer(tty); | 2138 | mxser_flush_buffer(tty); |
2221 | mxser_shutdown(info); | 2139 | mxser_shutdown(info); |
2222 | info->event = 0; | 2140 | info->port.count = 0; |
2223 | info->count = 0; | 2141 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
2224 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | 2142 | info->port.tty = NULL; |
2225 | info->tty = NULL; | 2143 | wake_up_interruptible(&info->port.open_wait); |
2226 | wake_up_interruptible(&info->open_wait); | ||
2227 | } | 2144 | } |
2228 | 2145 | ||
2229 | /* | 2146 | /* |
2230 | * mxser_rs_break() --- routine which turns the break handling on or off | 2147 | * mxser_rs_break() --- routine which turns the break handling on or off |
2231 | */ | 2148 | */ |
2232 | static void mxser_rs_break(struct tty_struct *tty, int break_state) | 2149 | static int mxser_rs_break(struct tty_struct *tty, int break_state) |
2233 | { | 2150 | { |
2234 | struct mxser_port *info = tty->driver_data; | 2151 | struct mxser_port *info = tty->driver_data; |
2235 | unsigned long flags; | 2152 | unsigned long flags; |
@@ -2242,11 +2159,12 @@ static void mxser_rs_break(struct tty_struct *tty, int break_state) | |||
2242 | outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC, | 2159 | outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC, |
2243 | info->ioaddr + UART_LCR); | 2160 | info->ioaddr + UART_LCR); |
2244 | spin_unlock_irqrestore(&info->slock, flags); | 2161 | spin_unlock_irqrestore(&info->slock, flags); |
2162 | return 0; | ||
2245 | } | 2163 | } |
2246 | 2164 | ||
2247 | static void mxser_receive_chars(struct mxser_port *port, int *status) | 2165 | static void mxser_receive_chars(struct mxser_port *port, int *status) |
2248 | { | 2166 | { |
2249 | struct tty_struct *tty = port->tty; | 2167 | struct tty_struct *tty = port->port.tty; |
2250 | unsigned char ch, gdl; | 2168 | unsigned char ch, gdl; |
2251 | int ignored = 0; | 2169 | int ignored = 0; |
2252 | int cnt = 0; | 2170 | int cnt = 0; |
@@ -2302,7 +2220,7 @@ intr_old: | |||
2302 | flag = TTY_BREAK; | 2220 | flag = TTY_BREAK; |
2303 | port->icount.brk++; | 2221 | port->icount.brk++; |
2304 | 2222 | ||
2305 | if (port->flags & ASYNC_SAK) | 2223 | if (port->port.flags & ASYNC_SAK) |
2306 | do_SAK(tty); | 2224 | do_SAK(tty); |
2307 | } else if (*status & UART_LSR_PE) { | 2225 | } else if (*status & UART_LSR_PE) { |
2308 | flag = TTY_PARITY; | 2226 | flag = TTY_PARITY; |
@@ -2333,7 +2251,7 @@ intr_old: | |||
2333 | } while (*status & UART_LSR_DR); | 2251 | } while (*status & UART_LSR_DR); |
2334 | 2252 | ||
2335 | end_intr: | 2253 | end_intr: |
2336 | mxvar_log.rxcnt[port->tty->index] += cnt; | 2254 | mxvar_log.rxcnt[port->port.tty->index] += cnt; |
2337 | port->mon_data.rxcnt += cnt; | 2255 | port->mon_data.rxcnt += cnt; |
2338 | port->mon_data.up_rxcnt += cnt; | 2256 | port->mon_data.up_rxcnt += cnt; |
2339 | 2257 | ||
@@ -2354,18 +2272,18 @@ static void mxser_transmit_chars(struct mxser_port *port) | |||
2354 | if (port->x_char) { | 2272 | if (port->x_char) { |
2355 | outb(port->x_char, port->ioaddr + UART_TX); | 2273 | outb(port->x_char, port->ioaddr + UART_TX); |
2356 | port->x_char = 0; | 2274 | port->x_char = 0; |
2357 | mxvar_log.txcnt[port->tty->index]++; | 2275 | mxvar_log.txcnt[port->port.tty->index]++; |
2358 | port->mon_data.txcnt++; | 2276 | port->mon_data.txcnt++; |
2359 | port->mon_data.up_txcnt++; | 2277 | port->mon_data.up_txcnt++; |
2360 | port->icount.tx++; | 2278 | port->icount.tx++; |
2361 | return; | 2279 | return; |
2362 | } | 2280 | } |
2363 | 2281 | ||
2364 | if (port->xmit_buf == NULL) | 2282 | if (port->port.xmit_buf == NULL) |
2365 | return; | 2283 | return; |
2366 | 2284 | ||
2367 | if ((port->xmit_cnt <= 0) || port->tty->stopped || | 2285 | if ((port->xmit_cnt <= 0) || port->port.tty->stopped || |
2368 | (port->tty->hw_stopped && | 2286 | (port->port.tty->hw_stopped && |
2369 | (port->type != PORT_16550A) && | 2287 | (port->type != PORT_16550A) && |
2370 | (!port->board->chip_flag))) { | 2288 | (!port->board->chip_flag))) { |
2371 | port->IER &= ~UART_IER_THRI; | 2289 | port->IER &= ~UART_IER_THRI; |
@@ -2376,20 +2294,20 @@ static void mxser_transmit_chars(struct mxser_port *port) | |||
2376 | cnt = port->xmit_cnt; | 2294 | cnt = port->xmit_cnt; |
2377 | count = port->xmit_fifo_size; | 2295 | count = port->xmit_fifo_size; |
2378 | do { | 2296 | do { |
2379 | outb(port->xmit_buf[port->xmit_tail++], | 2297 | outb(port->port.xmit_buf[port->xmit_tail++], |
2380 | port->ioaddr + UART_TX); | 2298 | port->ioaddr + UART_TX); |
2381 | port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE - 1); | 2299 | port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE - 1); |
2382 | if (--port->xmit_cnt <= 0) | 2300 | if (--port->xmit_cnt <= 0) |
2383 | break; | 2301 | break; |
2384 | } while (--count > 0); | 2302 | } while (--count > 0); |
2385 | mxvar_log.txcnt[port->tty->index] += (cnt - port->xmit_cnt); | 2303 | mxvar_log.txcnt[port->port.tty->index] += (cnt - port->xmit_cnt); |
2386 | 2304 | ||
2387 | port->mon_data.txcnt += (cnt - port->xmit_cnt); | 2305 | port->mon_data.txcnt += (cnt - port->xmit_cnt); |
2388 | port->mon_data.up_txcnt += (cnt - port->xmit_cnt); | 2306 | port->mon_data.up_txcnt += (cnt - port->xmit_cnt); |
2389 | port->icount.tx += (cnt - port->xmit_cnt); | 2307 | port->icount.tx += (cnt - port->xmit_cnt); |
2390 | 2308 | ||
2391 | if (port->xmit_cnt < WAKEUP_CHARS) | 2309 | if (port->xmit_cnt < WAKEUP_CHARS) |
2392 | tty_wakeup(port->tty); | 2310 | tty_wakeup(port->port.tty); |
2393 | 2311 | ||
2394 | if (port->xmit_cnt <= 0) { | 2312 | if (port->xmit_cnt <= 0) { |
2395 | port->IER &= ~UART_IER_THRI; | 2313 | port->IER &= ~UART_IER_THRI; |
@@ -2440,9 +2358,9 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2440 | if (iir & UART_IIR_NO_INT) | 2358 | if (iir & UART_IIR_NO_INT) |
2441 | break; | 2359 | break; |
2442 | iir &= MOXA_MUST_IIR_MASK; | 2360 | iir &= MOXA_MUST_IIR_MASK; |
2443 | if (!port->tty || | 2361 | if (!port->port.tty || |
2444 | (port->flags & ASYNC_CLOSING) || | 2362 | (port->port.flags & ASYNC_CLOSING) || |
2445 | !(port->flags & | 2363 | !(port->port.flags & |
2446 | ASYNC_INITIALIZED)) { | 2364 | ASYNC_INITIALIZED)) { |
2447 | status = inb(port->ioaddr + UART_LSR); | 2365 | status = inb(port->ioaddr + UART_LSR); |
2448 | outb(0x27, port->ioaddr + UART_FCR); | 2366 | outb(0x27, port->ioaddr + UART_FCR); |
@@ -2546,10 +2464,12 @@ static int __devinit mxser_initbrd(struct mxser_board *brd, | |||
2546 | unsigned int i; | 2464 | unsigned int i; |
2547 | int retval; | 2465 | int retval; |
2548 | 2466 | ||
2549 | printk(KERN_INFO "max. baud rate = %d bps.\n", brd->ports[0].max_baud); | 2467 | printk(KERN_INFO "mxser: max. baud rate = %d bps\n", |
2468 | brd->ports[0].max_baud); | ||
2550 | 2469 | ||
2551 | for (i = 0; i < brd->info->nports; i++) { | 2470 | for (i = 0; i < brd->info->nports; i++) { |
2552 | info = &brd->ports[i]; | 2471 | info = &brd->ports[i]; |
2472 | tty_port_init(&info->port); | ||
2553 | info->board = brd; | 2473 | info->board = brd; |
2554 | info->stop_rx = 0; | 2474 | info->stop_rx = 0; |
2555 | info->ldisc_stop_rx = 0; | 2475 | info->ldisc_stop_rx = 0; |
@@ -2558,16 +2478,15 @@ static int __devinit mxser_initbrd(struct mxser_board *brd, | |||
2558 | if (brd->chip_flag != MOXA_OTHER_UART) | 2478 | if (brd->chip_flag != MOXA_OTHER_UART) |
2559 | mxser_enable_must_enchance_mode(info->ioaddr); | 2479 | mxser_enable_must_enchance_mode(info->ioaddr); |
2560 | 2480 | ||
2561 | info->flags = ASYNC_SHARE_IRQ; | 2481 | info->port.flags = ASYNC_SHARE_IRQ; |
2562 | info->type = brd->uart_type; | 2482 | info->type = brd->uart_type; |
2563 | 2483 | ||
2564 | process_txrx_fifo(info); | 2484 | process_txrx_fifo(info); |
2565 | 2485 | ||
2566 | info->custom_divisor = info->baud_base * 16; | 2486 | info->custom_divisor = info->baud_base * 16; |
2567 | info->close_delay = 5 * HZ / 10; | 2487 | info->port.close_delay = 5 * HZ / 10; |
2568 | info->closing_wait = 30 * HZ; | 2488 | info->port.closing_wait = 30 * HZ; |
2569 | info->normal_termios = mxvar_sdriver->init_termios; | 2489 | info->normal_termios = mxvar_sdriver->init_termios; |
2570 | init_waitqueue_head(&info->open_wait); | ||
2571 | init_waitqueue_head(&info->delta_msr_wait); | 2490 | init_waitqueue_head(&info->delta_msr_wait); |
2572 | memset(&info->mon_data, 0, sizeof(struct mxser_mon)); | 2491 | memset(&info->mon_data, 0, sizeof(struct mxser_mon)); |
2573 | info->err_shadow = 0; | 2492 | info->err_shadow = 0; |
@@ -2629,28 +2548,32 @@ static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) | |||
2629 | irq = regs[9] & 0xF000; | 2548 | irq = regs[9] & 0xF000; |
2630 | irq = irq | (irq >> 4); | 2549 | irq = irq | (irq >> 4); |
2631 | if (irq != (regs[9] & 0xFF00)) | 2550 | if (irq != (regs[9] & 0xFF00)) |
2632 | return MXSER_ERR_IRQ_CONFLIT; | 2551 | goto err_irqconflict; |
2633 | } else if (brd->info->nports == 4) { | 2552 | } else if (brd->info->nports == 4) { |
2634 | irq = regs[9] & 0xF000; | 2553 | irq = regs[9] & 0xF000; |
2635 | irq = irq | (irq >> 4); | 2554 | irq = irq | (irq >> 4); |
2636 | irq = irq | (irq >> 8); | 2555 | irq = irq | (irq >> 8); |
2637 | if (irq != regs[9]) | 2556 | if (irq != regs[9]) |
2638 | return MXSER_ERR_IRQ_CONFLIT; | 2557 | goto err_irqconflict; |
2639 | } else if (brd->info->nports == 8) { | 2558 | } else if (brd->info->nports == 8) { |
2640 | irq = regs[9] & 0xF000; | 2559 | irq = regs[9] & 0xF000; |
2641 | irq = irq | (irq >> 4); | 2560 | irq = irq | (irq >> 4); |
2642 | irq = irq | (irq >> 8); | 2561 | irq = irq | (irq >> 8); |
2643 | if ((irq != regs[9]) || (irq != regs[10])) | 2562 | if ((irq != regs[9]) || (irq != regs[10])) |
2644 | return MXSER_ERR_IRQ_CONFLIT; | 2563 | goto err_irqconflict; |
2645 | } | 2564 | } |
2646 | 2565 | ||
2647 | if (!irq) | 2566 | if (!irq) { |
2648 | return MXSER_ERR_IRQ; | 2567 | printk(KERN_ERR "mxser: interrupt number unset\n"); |
2568 | return -EIO; | ||
2569 | } | ||
2649 | brd->irq = ((int)(irq & 0xF000) >> 12); | 2570 | brd->irq = ((int)(irq & 0xF000) >> 12); |
2650 | for (i = 0; i < 8; i++) | 2571 | for (i = 0; i < 8; i++) |
2651 | brd->ports[i].ioaddr = (int) regs[i + 1] & 0xFFF8; | 2572 | brd->ports[i].ioaddr = (int) regs[i + 1] & 0xFFF8; |
2652 | if ((regs[12] & 0x80) == 0) | 2573 | if ((regs[12] & 0x80) == 0) { |
2653 | return MXSER_ERR_VECTOR; | 2574 | printk(KERN_ERR "mxser: invalid interrupt vector\n"); |
2575 | return -EIO; | ||
2576 | } | ||
2654 | brd->vector = (int)regs[11]; /* interrupt vector */ | 2577 | brd->vector = (int)regs[11]; /* interrupt vector */ |
2655 | if (id == 1) | 2578 | if (id == 1) |
2656 | brd->vector_mask = 0x00FF; | 2579 | brd->vector_mask = 0x00FF; |
@@ -2677,13 +2600,26 @@ static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) | |||
2677 | else | 2600 | else |
2678 | brd->uart_type = PORT_16450; | 2601 | brd->uart_type = PORT_16450; |
2679 | if (!request_region(brd->ports[0].ioaddr, 8 * brd->info->nports, | 2602 | if (!request_region(brd->ports[0].ioaddr, 8 * brd->info->nports, |
2680 | "mxser(IO)")) | 2603 | "mxser(IO)")) { |
2681 | return MXSER_ERR_IOADDR; | 2604 | printk(KERN_ERR "mxser: can't request ports I/O region: " |
2605 | "0x%.8lx-0x%.8lx\n", | ||
2606 | brd->ports[0].ioaddr, brd->ports[0].ioaddr + | ||
2607 | 8 * brd->info->nports - 1); | ||
2608 | return -EIO; | ||
2609 | } | ||
2682 | if (!request_region(brd->vector, 1, "mxser(vector)")) { | 2610 | if (!request_region(brd->vector, 1, "mxser(vector)")) { |
2683 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); | 2611 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); |
2684 | return MXSER_ERR_VECTOR; | 2612 | printk(KERN_ERR "mxser: can't request interrupt vector region: " |
2613 | "0x%.8lx-0x%.8lx\n", | ||
2614 | brd->ports[0].ioaddr, brd->ports[0].ioaddr + | ||
2615 | 8 * brd->info->nports - 1); | ||
2616 | return -EIO; | ||
2685 | } | 2617 | } |
2686 | return brd->info->nports; | 2618 | return brd->info->nports; |
2619 | |||
2620 | err_irqconflict: | ||
2621 | printk(KERN_ERR "mxser: invalid interrupt number\n"); | ||
2622 | return -EIO; | ||
2687 | } | 2623 | } |
2688 | 2624 | ||
2689 | static int __devinit mxser_probe(struct pci_dev *pdev, | 2625 | static int __devinit mxser_probe(struct pci_dev *pdev, |
@@ -2700,20 +2636,20 @@ static int __devinit mxser_probe(struct pci_dev *pdev, | |||
2700 | break; | 2636 | break; |
2701 | 2637 | ||
2702 | if (i >= MXSER_BOARDS) { | 2638 | if (i >= MXSER_BOARDS) { |
2703 | printk(KERN_ERR "Too many Smartio/Industio family boards found " | 2639 | dev_err(&pdev->dev, "too many boards found (maximum %d), board " |
2704 | "(maximum %d), board not configured\n", MXSER_BOARDS); | 2640 | "not configured\n", MXSER_BOARDS); |
2705 | goto err; | 2641 | goto err; |
2706 | } | 2642 | } |
2707 | 2643 | ||
2708 | brd = &mxser_boards[i]; | 2644 | brd = &mxser_boards[i]; |
2709 | brd->idx = i * MXSER_PORTS_PER_BOARD; | 2645 | brd->idx = i * MXSER_PORTS_PER_BOARD; |
2710 | printk(KERN_INFO "Found MOXA %s board (BusNo=%d, DevNo=%d)\n", | 2646 | dev_info(&pdev->dev, "found MOXA %s board (BusNo=%d, DevNo=%d)\n", |
2711 | mxser_cards[ent->driver_data].name, | 2647 | mxser_cards[ent->driver_data].name, |
2712 | pdev->bus->number, PCI_SLOT(pdev->devfn)); | 2648 | pdev->bus->number, PCI_SLOT(pdev->devfn)); |
2713 | 2649 | ||
2714 | retval = pci_enable_device(pdev); | 2650 | retval = pci_enable_device(pdev); |
2715 | if (retval) { | 2651 | if (retval) { |
2716 | printk(KERN_ERR "Moxa SmartI/O PCI enable fail !\n"); | 2652 | dev_err(&pdev->dev, "PCI enable failed\n"); |
2717 | goto err; | 2653 | goto err; |
2718 | } | 2654 | } |
2719 | 2655 | ||
@@ -2815,11 +2751,8 @@ static struct pci_driver mxser_driver = { | |||
2815 | static int __init mxser_module_init(void) | 2751 | static int __init mxser_module_init(void) |
2816 | { | 2752 | { |
2817 | struct mxser_board *brd; | 2753 | struct mxser_board *brd; |
2818 | unsigned long cap; | 2754 | unsigned int b, i, m; |
2819 | unsigned int i, m, isaloop; | 2755 | int retval; |
2820 | int retval, b; | ||
2821 | |||
2822 | pr_debug("Loading module mxser ...\n"); | ||
2823 | 2756 | ||
2824 | mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1); | 2757 | mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1); |
2825 | if (!mxvar_sdriver) | 2758 | if (!mxvar_sdriver) |
@@ -2849,74 +2782,43 @@ static int __init mxser_module_init(void) | |||
2849 | goto err_put; | 2782 | goto err_put; |
2850 | } | 2783 | } |
2851 | 2784 | ||
2852 | mxvar_diagflag = 0; | ||
2853 | |||
2854 | m = 0; | ||
2855 | /* Start finding ISA boards here */ | 2785 | /* Start finding ISA boards here */ |
2856 | for (isaloop = 0; isaloop < 2; isaloop++) | 2786 | for (m = 0, b = 0; b < MXSER_BOARDS; b++) { |
2857 | for (b = 0; b < MXSER_BOARDS && m < MXSER_BOARDS; b++) { | 2787 | if (!ioaddr[b]) |
2858 | if (!isaloop) | 2788 | continue; |
2859 | cap = mxserBoardCAP[b]; /* predefined */ | 2789 | |
2860 | else | 2790 | brd = &mxser_boards[m]; |
2861 | cap = ioaddr[b]; /* module param */ | 2791 | retval = mxser_get_ISA_conf(!ioaddr[b], brd); |
2792 | if (retval <= 0) { | ||
2793 | brd->info = NULL; | ||
2794 | continue; | ||
2795 | } | ||
2862 | 2796 | ||
2863 | if (!cap) | 2797 | printk(KERN_INFO "mxser: found MOXA %s board (CAP=0x%lx)\n", |
2864 | continue; | 2798 | brd->info->name, ioaddr[b]); |
2865 | 2799 | ||
2866 | brd = &mxser_boards[m]; | 2800 | /* mxser_initbrd will hook ISR. */ |
2867 | retval = mxser_get_ISA_conf(cap, brd); | 2801 | if (mxser_initbrd(brd, NULL) < 0) { |
2868 | 2802 | brd->info = NULL; | |
2869 | if (retval != 0) | 2803 | continue; |
2870 | printk(KERN_INFO "Found MOXA %s board " | 2804 | } |
2871 | "(CAP=0x%x)\n", | ||
2872 | brd->info->name, ioaddr[b]); | ||
2873 | |||
2874 | if (retval <= 0) { | ||
2875 | if (retval == MXSER_ERR_IRQ) | ||
2876 | printk(KERN_ERR "Invalid interrupt " | ||
2877 | "number, board not " | ||
2878 | "configured\n"); | ||
2879 | else if (retval == MXSER_ERR_IRQ_CONFLIT) | ||
2880 | printk(KERN_ERR "Invalid interrupt " | ||
2881 | "number, board not " | ||
2882 | "configured\n"); | ||
2883 | else if (retval == MXSER_ERR_VECTOR) | ||
2884 | printk(KERN_ERR "Invalid interrupt " | ||
2885 | "vector, board not " | ||
2886 | "configured\n"); | ||
2887 | else if (retval == MXSER_ERR_IOADDR) | ||
2888 | printk(KERN_ERR "Invalid I/O address, " | ||
2889 | "board not configured\n"); | ||
2890 | |||
2891 | brd->info = NULL; | ||
2892 | continue; | ||
2893 | } | ||
2894 | |||
2895 | /* mxser_initbrd will hook ISR. */ | ||
2896 | if (mxser_initbrd(brd, NULL) < 0) { | ||
2897 | brd->info = NULL; | ||
2898 | continue; | ||
2899 | } | ||
2900 | 2805 | ||
2901 | brd->idx = m * MXSER_PORTS_PER_BOARD; | 2806 | brd->idx = m * MXSER_PORTS_PER_BOARD; |
2902 | for (i = 0; i < brd->info->nports; i++) | 2807 | for (i = 0; i < brd->info->nports; i++) |
2903 | tty_register_device(mxvar_sdriver, brd->idx + i, | 2808 | tty_register_device(mxvar_sdriver, brd->idx + i, NULL); |
2904 | NULL); | ||
2905 | 2809 | ||
2906 | m++; | 2810 | m++; |
2907 | } | 2811 | } |
2908 | 2812 | ||
2909 | retval = pci_register_driver(&mxser_driver); | 2813 | retval = pci_register_driver(&mxser_driver); |
2910 | if (retval) { | 2814 | if (retval) { |
2911 | printk(KERN_ERR "Can't register pci driver\n"); | 2815 | printk(KERN_ERR "mxser: can't register pci driver\n"); |
2912 | if (!m) { | 2816 | if (!m) { |
2913 | retval = -ENODEV; | 2817 | retval = -ENODEV; |
2914 | goto err_unr; | 2818 | goto err_unr; |
2915 | } /* else: we have some ISA cards under control */ | 2819 | } /* else: we have some ISA cards under control */ |
2916 | } | 2820 | } |
2917 | 2821 | ||
2918 | pr_debug("Done.\n"); | ||
2919 | |||
2920 | return 0; | 2822 | return 0; |
2921 | err_unr: | 2823 | err_unr: |
2922 | tty_unregister_driver(mxvar_sdriver); | 2824 | tty_unregister_driver(mxvar_sdriver); |
@@ -2929,8 +2831,6 @@ static void __exit mxser_module_exit(void) | |||
2929 | { | 2831 | { |
2930 | unsigned int i, j; | 2832 | unsigned int i, j; |
2931 | 2833 | ||
2932 | pr_debug("Unloading module mxser ...\n"); | ||
2933 | |||
2934 | pci_unregister_driver(&mxser_driver); | 2834 | pci_unregister_driver(&mxser_driver); |
2935 | 2835 | ||
2936 | for (i = 0; i < MXSER_BOARDS; i++) /* ISA remains */ | 2836 | for (i = 0; i < MXSER_BOARDS; i++) /* ISA remains */ |
@@ -2944,8 +2844,6 @@ static void __exit mxser_module_exit(void) | |||
2944 | for (i = 0; i < MXSER_BOARDS; i++) | 2844 | for (i = 0; i < MXSER_BOARDS; i++) |
2945 | if (mxser_boards[i].info != NULL) | 2845 | if (mxser_boards[i].info != NULL) |
2946 | mxser_release_res(&mxser_boards[i], NULL, 1); | 2846 | mxser_release_res(&mxser_boards[i], NULL, 1); |
2947 | |||
2948 | pr_debug("Done.\n"); | ||
2949 | } | 2847 | } |
2950 | 2848 | ||
2951 | module_init(mxser_module_init); | 2849 | module_init(mxser_module_init); |