2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version
5 * 2 of the License, or (at your option) any later version.
7 * Original driver code supplied by Multi-Tech
10 * 1/9/98 alan@redhat.com Merge to 2.0.x kernel tree
11 * Obtain and use official major/minors
12 * Loader switched to a misc device
13 * (fixed range check bug as a side effect)
15 * 9/12/98 alan@redhat.com Rough port to 2.1.x
17 * 10/6/99 sameer Merged the ISA and PCI drivers to
18 * a new unified driver.
20 * 3/9/99 sameer Added support for ISI4616 cards.
22 * 16/9/99 sameer We do not force RTS low anymore.
23 * This is to prevent the firmware
24 * from getting confused.
26 * 26/10/99 sameer Cosmetic changes:The driver now
27 * dumps the Port Count information
28 * along with I/O address and IRQ.
30 * 13/12/99 sameer Fixed the problem with IRQ sharing.
32 * 10/5/00 sameer Fixed isicom_shutdown_board()
33 * to not lower DTR on all the ports
34 * when the last port on the card is
37 * 10/5/00 sameer Signal mask setup command added
38 * to isicom_setup_port and
39 * isicom_shutdown_port.
41 * 24/5/00 sameer The driver is now SMP aware.
44 * 27/11/00 Vinayak P Risbud Fixed the Driver Crash Problem
47 * 03/01/01 anil .s Added support for resetting the
48 * internal modems on ISI cards.
50 * 08/02/01 anil .s Upgraded the driver for kernel
53 * 11/04/01 Kevin Fixed firmware load problem with
56 * 30/04/01 anil .s Fixed the remote login through
57 * ISI port problem. Now the link
58 * does not go down before password
61 * 03/05/01 anil .s Fixed the problem with IRQ sharing
62 * among ISI-PCI cards.
64 * 03/05/01 anil .s Added support to display the version
65 * info during insmod as well as module
68 * 10/05/01 anil .s Done the modifications to the source
69 * file and Install script so that the
70 * same installation can be used for
71 * 2.2.x and 2.4.x kernel.
73 * 06/06/01 anil .s Now we drop both dtr and rts during
74 * shutdown_port as well as raise them
75 * during isicom_config_port.
77 * 09/06/01 acme@conectiva.com.br use capable, not suser, do
78 * restore_flags on failure in
79 * isicom_send_break, verify put_user
82 * 11/02/03 ranjeeth Added support for 230 Kbps and 460 Kbps
83 * Baud index extended to 21
85 * 20/03/03 ranjeeth Made to work for Linux Advanced server.
86 * Taken care of license warning.
88 * 10/12/03 Ravindra Made to work for Fedora Core 1 of
89 * Red Hat Distribution
91 * 06/01/05 Alan Cox Merged the ISI and base kernel strands
92 * into a single 2.6 driver
94 * ***********************************************************
96 * To use this driver you also need the support package. You
97 * can find this in RPM format on
98 * ftp://ftp.linux.org.uk/pub/linux/alan
100 * You can find the original tools for this direct from Multitech
101 * ftp://ftp.multitech.com/ISI-Cards/
103 * Having installed the cards the module options (/etc/modprobe.conf)
105 * options isicom io=card1,card2,card3,card4 irq=card1,card2,card3,card4
107 * Omit those entries for boards you don't have installed.
111 * 64-bit verification
114 #include <linux/module.h>
115 #include <linux/firmware.h>
116 #include <linux/kernel.h>
117 #include <linux/tty.h>
118 #include <linux/tty_flip.h>
119 #include <linux/termios.h>
120 #include <linux/fs.h>
121 #include <linux/sched.h>
122 #include <linux/serial.h>
123 #include <linux/mm.h>
124 #include <linux/interrupt.h>
125 #include <linux/timer.h>
126 #include <linux/delay.h>
127 #include <linux/ioport.h>
129 #include <linux/uaccess.h>
130 #include <linux/io.h>
131 #include <asm/system.h>
133 #include <linux/pci.h>
135 #include <linux/isicom.h>
137 #define InterruptTheCard(base) outw(0, (base) + 0xc)
138 #define ClearInterrupt(base) inw((base) + 0x0a)
140 #define pr_dbg(str...) pr_debug("ISICOM: " str)
142 #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c))
144 #define isicom_paranoia_check(a, b, c) 0
147 static int isicom_probe(struct pci_dev *, const struct pci_device_id *);
148 static void __devexit isicom_remove(struct pci_dev *);
150 static struct pci_device_id isicom_pci_tbl[] = {
151 { PCI_DEVICE(VENDOR_ID, 0x2028) },
152 { PCI_DEVICE(VENDOR_ID, 0x2051) },
153 { PCI_DEVICE(VENDOR_ID, 0x2052) },
154 { PCI_DEVICE(VENDOR_ID, 0x2053) },
155 { PCI_DEVICE(VENDOR_ID, 0x2054) },
156 { PCI_DEVICE(VENDOR_ID, 0x2055) },
157 { PCI_DEVICE(VENDOR_ID, 0x2056) },
158 { PCI_DEVICE(VENDOR_ID, 0x2057) },
159 { PCI_DEVICE(VENDOR_ID, 0x2058) },
162 MODULE_DEVICE_TABLE(pci, isicom_pci_tbl);
164 static struct pci_driver isicom_driver = {
166 .id_table = isicom_pci_tbl,
167 .probe = isicom_probe,
168 .remove = __devexit_p(isicom_remove)
171 static int prev_card = 3; /* start servicing isi_card[0] */
172 static struct tty_driver *isicom_normal;
174 static void isicom_tx(unsigned long _data);
175 static void isicom_start(struct tty_struct *tty);
177 static DEFINE_TIMER(tx, isicom_tx, 0, 0);
179 /* baud index mappings from linux defns to isi */
181 static signed char linuxb_to_isib[] = {
182 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21
188 unsigned char port_count;
189 unsigned short status;
190 unsigned short port_status; /* each bit for each port */
191 unsigned short shift_count;
192 struct isi_port *ports;
194 spinlock_t card_lock; /* Card wide lock 11/5/00 -sameer */
200 unsigned short magic;
201 struct tty_port port;
204 struct isi_board *card;
205 unsigned char *xmit_buf;
211 static struct isi_board isi_card[BOARD_COUNT];
212 static struct isi_port isi_ports[PORT_COUNT];
215 * Locking functions for card level locking. We need to own both
216 * the kernel lock for the card and have the card in a position that
220 static inline int WaitTillCardIsFree(unsigned long base)
222 unsigned int count = 0;
223 unsigned int a = in_atomic(); /* do we run under spinlock? */
225 while (!(inw(base + 0xe) & 0x1) && count++ < 100)
231 return !(inw(base + 0xe) & 0x1);
234 static int lock_card(struct isi_board *card)
236 unsigned long base = card->base;
237 unsigned int retries, a;
239 for (retries = 0; retries < 10; retries++) {
240 spin_lock_irqsave(&card->card_lock, card->flags);
241 for (a = 0; a < 10; a++) {
242 if (inw(base + 0xe) & 0x1)
246 spin_unlock_irqrestore(&card->card_lock, card->flags);
249 printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%lx)\n",
252 return 0; /* Failed to acquire the card! */
255 static void unlock_card(struct isi_board *card)
257 spin_unlock_irqrestore(&card->card_lock, card->flags);
261 * ISI Card specific ops ...
264 /* card->lock HAS to be held */
265 static void raise_dtr(struct isi_port *port)
267 struct isi_board *card = port->card;
268 unsigned long base = card->base;
269 u16 channel = port->channel;
271 if (WaitTillCardIsFree(base))
274 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
276 InterruptTheCard(base);
277 port->status |= ISI_DTR;
280 /* card->lock HAS to be held */
281 static inline void drop_dtr(struct isi_port *port)
283 struct isi_board *card = port->card;
284 unsigned long base = card->base;
285 u16 channel = port->channel;
287 if (WaitTillCardIsFree(base))
290 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
292 InterruptTheCard(base);
293 port->status &= ~ISI_DTR;
296 /* card->lock HAS to be held */
297 static inline void raise_rts(struct isi_port *port)
299 struct isi_board *card = port->card;
300 unsigned long base = card->base;
301 u16 channel = port->channel;
303 if (WaitTillCardIsFree(base))
306 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
308 InterruptTheCard(base);
309 port->status |= ISI_RTS;
312 /* card->lock HAS to be held */
313 static inline void drop_rts(struct isi_port *port)
315 struct isi_board *card = port->card;
316 unsigned long base = card->base;
317 u16 channel = port->channel;
319 if (WaitTillCardIsFree(base))
322 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
324 InterruptTheCard(base);
325 port->status &= ~ISI_RTS;
328 /* card->lock MUST NOT be held */
329 static inline void raise_dtr_rts(struct isi_port *port)
331 struct isi_board *card = port->card;
332 unsigned long base = card->base;
333 u16 channel = port->channel;
335 if (!lock_card(card))
338 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
340 InterruptTheCard(base);
341 port->status |= (ISI_DTR | ISI_RTS);
345 /* card->lock HAS to be held */
346 static void drop_dtr_rts(struct isi_port *port)
348 struct isi_board *card = port->card;
349 unsigned long base = card->base;
350 u16 channel = port->channel;
352 if (WaitTillCardIsFree(base))
355 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
357 InterruptTheCard(base);
358 port->status &= ~(ISI_RTS | ISI_DTR);
362 * ISICOM Driver specific routines ...
366 static inline int __isicom_paranoia_check(struct isi_port const *port,
367 char *name, const char *routine)
370 printk(KERN_WARNING "ISICOM: Warning: bad isicom magic for "
371 "dev %s in %s.\n", name, routine);
374 if (port->magic != ISICOM_MAGIC) {
375 printk(KERN_WARNING "ISICOM: Warning: NULL isicom port for "
376 "dev %s in %s.\n", name, routine);
386 * We shovel data into the card buffers on a regular basis. The card
387 * will do the rest of the work for us.
390 static void isicom_tx(unsigned long _data)
392 unsigned long flags, base;
393 unsigned int retries;
394 short count = (BOARD_COUNT-1), card;
395 short txcount, wrd, residue, word_count, cnt;
396 struct isi_port *port;
397 struct tty_struct *tty;
399 /* find next active board */
400 card = (prev_card + 1) & 0x0003;
401 while (count-- > 0) {
402 if (isi_card[card].status & BOARD_ACTIVE)
404 card = (card + 1) & 0x0003;
406 if (!(isi_card[card].status & BOARD_ACTIVE))
411 count = isi_card[card].port_count;
412 port = isi_card[card].ports;
413 base = isi_card[card].base;
415 spin_lock_irqsave(&isi_card[card].card_lock, flags);
416 for (retries = 0; retries < 100; retries++) {
417 if (inw(base + 0xe) & 0x1)
424 tty = tty_port_tty_get(&port->port);
428 for (; count > 0; count--, port++) {
429 /* port not active or tx disabled to force flow control */
430 if (!(port->port.flags & ASYNC_INITIALIZED) ||
431 !(port->status & ISI_TXOK))
434 txcount = min_t(short, TX_SIZE, port->xmit_cnt);
435 if (txcount <= 0 || tty->stopped || tty->hw_stopped)
438 if (!(inw(base + 0x02) & (1 << port->channel)))
441 pr_dbg("txing %d bytes, port%d.\n", txcount,
443 outw((port->channel << isi_card[card].shift_count) | txcount,
448 cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE
450 if (residue == YES) {
453 wrd |= (port->port.xmit_buf[port->xmit_tail]
455 port->xmit_tail = (port->xmit_tail + 1)
456 & (SERIAL_XMIT_SIZE - 1);
468 word_count = cnt >> 1;
469 outsw(base, port->port.xmit_buf+port->xmit_tail, word_count);
470 port->xmit_tail = (port->xmit_tail
471 + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
472 txcount -= (word_count << 1);
473 port->xmit_cnt -= (word_count << 1);
476 wrd = port->port.xmit_buf[port->xmit_tail];
477 port->xmit_tail = (port->xmit_tail + 1)
478 & (SERIAL_XMIT_SIZE - 1);
484 InterruptTheCard(base);
485 if (port->xmit_cnt <= 0)
486 port->status &= ~ISI_TXOK;
487 if (port->xmit_cnt <= WAKEUP_CHARS)
494 spin_unlock_irqrestore(&isi_card[card].card_lock, flags);
495 /* schedule another tx for hopefully in about 10ms */
497 mod_timer(&tx, jiffies + msecs_to_jiffies(10));
501 * Main interrupt handler routine
504 static irqreturn_t isicom_interrupt(int irq, void *dev_id)
506 struct isi_board *card = dev_id;
507 struct isi_port *port;
508 struct tty_struct *tty;
510 u16 header, word_count, count, channel;
514 if (!card || !(card->status & FIRMWARE_LOADED))
519 /* did the card interrupt us? */
520 if (!(inw(base + 0x0e) & 0x02))
523 spin_lock(&card->card_lock);
526 * disable any interrupts from the PCI card and lower the
529 outw(0x8000, base+0x04);
530 ClearInterrupt(base);
532 inw(base); /* get the dummy word out */
534 channel = (header & 0x7800) >> card->shift_count;
535 byte_count = header & 0xff;
537 if (channel + 1 > card->port_count) {
538 printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): "
539 "%d(channel) > port_count.\n", base, channel+1);
540 outw(0x0000, base+0x04); /* enable interrupts */
541 spin_unlock(&card->card_lock);
544 port = card->ports + channel;
545 if (!(port->port.flags & ASYNC_INITIALIZED)) {
546 outw(0x0000, base+0x04); /* enable interrupts */
547 spin_unlock(&card->card_lock);
551 tty = tty_port_tty_get(&port->port);
553 word_count = byte_count >> 1;
554 while (byte_count > 1) {
558 if (byte_count & 0x01)
560 outw(0x0000, base+0x04); /* enable interrupts */
561 spin_unlock(&card->card_lock);
565 if (header & 0x8000) { /* Status Packet */
567 switch (header & 0xff) {
568 case 0: /* Change in EIA signals */
569 if (port->port.flags & ASYNC_CHECK_CD) {
570 if (port->status & ISI_DCD) {
571 if (!(header & ISI_DCD)) {
572 /* Carrier has been lost */
573 pr_dbg("interrupt: DCD->low.\n"
575 port->status &= ~ISI_DCD;
578 } else if (header & ISI_DCD) {
579 /* Carrier has been detected */
580 pr_dbg("interrupt: DCD->high.\n");
581 port->status |= ISI_DCD;
582 wake_up_interruptible(&port->port.open_wait);
585 if (header & ISI_DCD)
586 port->status |= ISI_DCD;
588 port->status &= ~ISI_DCD;
591 if (port->port.flags & ASYNC_CTS_FLOW) {
592 if (tty->hw_stopped) {
593 if (header & ISI_CTS) {
594 port->port.tty->hw_stopped = 0;
596 port->status |= (ISI_TXOK
600 } else if (!(header & ISI_CTS)) {
603 port->status &= ~(ISI_TXOK | ISI_CTS);
606 if (header & ISI_CTS)
607 port->status |= ISI_CTS;
609 port->status &= ~ISI_CTS;
612 if (header & ISI_DSR)
613 port->status |= ISI_DSR;
615 port->status &= ~ISI_DSR;
618 port->status |= ISI_RI;
620 port->status &= ~ISI_RI;
624 case 1: /* Received Break !!! */
625 tty_insert_flip_char(tty, 0, TTY_BREAK);
626 if (port->port.flags & ASYNC_SAK)
628 tty_flip_buffer_push(tty);
631 case 2: /* Statistics */
632 pr_dbg("isicom_interrupt: stats!!!.\n");
636 pr_dbg("Intr: Unknown code in status packet.\n");
639 } else { /* Data Packet */
641 count = tty_prepare_flip_string(tty, &rp, byte_count & ~1);
642 pr_dbg("Intr: Can rx %d of %d bytes.\n", count, byte_count);
643 word_count = count >> 1;
644 insw(base, rp, word_count);
645 byte_count -= (word_count << 1);
646 if (count & 0x0001) {
647 tty_insert_flip_char(tty, inw(base) & 0xff,
651 if (byte_count > 0) {
652 pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping "
653 "bytes...\n", base, channel + 1);
654 /* drain out unread xtra data */
655 while (byte_count > 0) {
660 tty_flip_buffer_push(tty);
662 outw(0x0000, base+0x04); /* enable interrupts */
663 spin_unlock(&card->card_lock);
669 static void isicom_config_port(struct tty_struct *tty)
671 struct isi_port *port = tty->driver_data;
672 struct isi_board *card = port->card;
674 unsigned long base = card->base;
675 u16 channel_setup, channel = port->channel,
676 shift_count = card->shift_count;
677 unsigned char flow_ctrl;
679 /* FIXME: Switch to new tty baud API */
681 if (baud & CBAUDEX) {
684 /* if CBAUDEX bit is on and the baud is set to either 50 or 75
685 * then the card is programmed for 57.6Kbps or 115Kbps
689 /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
690 if (baud < 1 || baud > 4)
691 tty->termios->c_cflag &= ~CBAUDEX;
697 /* the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set
698 * by the set_serial_info ioctl ... this is done by
699 * the 'setserial' utility.
702 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
703 baud++; /* 57.6 Kbps */
704 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
705 baud += 2; /* 115 Kbps */
706 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
707 baud += 3; /* 230 kbps*/
708 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
709 baud += 4; /* 460 kbps*/
711 if (linuxb_to_isib[baud] == -1) {
718 if (WaitTillCardIsFree(base) == 0) {
719 outw(0x8000 | (channel << shift_count) | 0x03, base);
720 outw(linuxb_to_isib[baud] << 8 | 0x03, base);
722 switch (C_CSIZE(tty)) {
724 channel_setup |= ISICOM_CS5;
727 channel_setup |= ISICOM_CS6;
730 channel_setup |= ISICOM_CS7;
733 channel_setup |= ISICOM_CS8;
738 channel_setup |= ISICOM_2SB;
740 channel_setup |= ISICOM_EVPAR;
742 channel_setup |= ISICOM_ODPAR;
744 outw(channel_setup, base);
745 InterruptTheCard(base);
748 port->port.flags &= ~ASYNC_CHECK_CD;
750 port->port.flags |= ASYNC_CHECK_CD;
752 /* flow control settings ...*/
754 port->port.flags &= ~ASYNC_CTS_FLOW;
755 if (C_CRTSCTS(tty)) {
756 port->port.flags |= ASYNC_CTS_FLOW;
757 flow_ctrl |= ISICOM_CTSRTS;
760 flow_ctrl |= ISICOM_RESPOND_XONXOFF;
762 flow_ctrl |= ISICOM_INITIATE_XONXOFF;
764 if (WaitTillCardIsFree(base) == 0) {
765 outw(0x8000 | (channel << shift_count) | 0x04, base);
766 outw(flow_ctrl << 8 | 0x05, base);
767 outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
768 InterruptTheCard(base);
771 /* rx enabled -> enable port for rx on the card */
773 card->port_status |= (1 << channel);
774 outw(card->port_status, base + 0x02);
780 static inline void isicom_setup_board(struct isi_board *bp)
783 struct isi_port *port;
786 spin_lock_irqsave(&bp->card_lock, flags);
787 if (bp->status & BOARD_ACTIVE) {
788 spin_unlock_irqrestore(&bp->card_lock, flags);
792 bp->status |= BOARD_ACTIVE;
793 for (channel = 0; channel < bp->port_count; channel++, port++)
795 spin_unlock_irqrestore(&bp->card_lock, flags);
798 static int isicom_setup_port(struct tty_struct *tty)
800 struct isi_port *port = tty->driver_data;
801 struct isi_board *card = port->card;
804 if (port->port.flags & ASYNC_INITIALIZED)
806 if (tty_port_alloc_xmit_buf(&port->port) < 0)
809 spin_lock_irqsave(&card->card_lock, flags);
810 clear_bit(TTY_IO_ERROR, &tty->flags);
811 if (port->port.count == 1)
814 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
816 /* discard any residual data */
817 if (WaitTillCardIsFree(card->base) == 0) {
818 outw(0x8000 | (port->channel << card->shift_count) | 0x02,
820 outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base);
821 InterruptTheCard(card->base);
824 isicom_config_port(tty);
825 port->port.flags |= ASYNC_INITIALIZED;
826 spin_unlock_irqrestore(&card->card_lock, flags);
831 static int block_til_ready(struct tty_struct *tty, struct file *filp,
832 struct isi_port *port)
834 struct isi_board *card = port->card;
835 int do_clocal = 0, retval;
837 DECLARE_WAITQUEUE(wait, current);
839 /* block if port is in the process of being closed */
841 if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
842 pr_dbg("block_til_ready: close in progress.\n");
843 interruptible_sleep_on(&port->port.close_wait);
844 if (port->port.flags & ASYNC_HUP_NOTIFY)
850 /* if non-blocking mode is set ... */
852 if ((filp->f_flags & O_NONBLOCK) ||
853 (tty->flags & (1 << TTY_IO_ERROR))) {
854 pr_dbg("block_til_ready: non-block mode.\n");
855 port->port.flags |= ASYNC_NORMAL_ACTIVE;
862 /* block waiting for DCD to be asserted, and while
863 callout dev is busy */
865 add_wait_queue(&port->port.open_wait, &wait);
867 spin_lock_irqsave(&card->card_lock, flags);
868 if (!tty_hung_up_p(filp))
870 port->port.blocked_open++;
871 spin_unlock_irqrestore(&card->card_lock, flags);
876 set_current_state(TASK_INTERRUPTIBLE);
877 if (tty_hung_up_p(filp) || !(port->port.flags & ASYNC_INITIALIZED)) {
878 if (port->port.flags & ASYNC_HUP_NOTIFY)
881 retval = -ERESTARTSYS;
884 if (!(port->port.flags & ASYNC_CLOSING) &&
885 (do_clocal || (port->status & ISI_DCD))) {
888 if (signal_pending(current)) {
889 retval = -ERESTARTSYS;
894 set_current_state(TASK_RUNNING);
895 remove_wait_queue(&port->port.open_wait, &wait);
896 spin_lock_irqsave(&card->card_lock, flags);
897 if (!tty_hung_up_p(filp))
899 port->port.blocked_open--;
900 spin_unlock_irqrestore(&card->card_lock, flags);
903 port->port.flags |= ASYNC_NORMAL_ACTIVE;
907 static int isicom_open(struct tty_struct *tty, struct file *filp)
909 struct isi_port *port;
910 struct isi_board *card;
915 if (line < 0 || line > PORT_COUNT-1)
918 card = &isi_card[board];
920 if (!(card->status & FIRMWARE_LOADED))
923 /* open on a port greater than the port count for the card !!! */
924 if (line > ((board * 16) + card->port_count - 1))
927 port = &isi_ports[line];
928 if (isicom_paranoia_check(port, tty->name, "isicom_open"))
931 isicom_setup_board(card);
934 tty->driver_data = port;
935 tty_port_tty_set(&port->port, tty);
936 error = isicom_setup_port(tty);
938 error = block_til_ready(tty, filp, port);
944 static inline void isicom_shutdown_board(struct isi_board *bp)
946 if (bp->status & BOARD_ACTIVE)
947 bp->status &= ~BOARD_ACTIVE;
950 /* card->lock HAS to be held */
951 static void isicom_shutdown_port(struct isi_port *port)
953 struct isi_board *card = port->card;
954 struct tty_struct *tty;
956 tty = tty_port_tty_get(&port->port);
958 if (!(port->port.flags & ASYNC_INITIALIZED)) {
963 tty_port_free_xmit_buf(&port->port);
964 port->port.flags &= ~ASYNC_INITIALIZED;
965 /* 3rd October 2000 : Vinayak P Risbud */
966 tty_port_tty_set(&port->port, NULL);
968 /*Fix done by Anil .S on 30-04-2001
969 remote login through isi port has dtr toggle problem
970 due to which the carrier drops before the password prompt
971 appears on the remote end. Now we drop the dtr only if the
972 HUPCL(Hangup on close) flag is set for the tty*/
975 /* drop dtr on this port */
978 /* any other port uninits */
980 set_bit(TTY_IO_ERROR, &tty->flags);
982 if (--card->count < 0) {
983 pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n",
984 card->base, card->count);
988 /* last port was closed, shutdown that boad too */
991 isicom_shutdown_board(card);
995 static void isicom_flush_buffer(struct tty_struct *tty)
997 struct isi_port *port = tty->driver_data;
998 struct isi_board *card = port->card;
1001 if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
1004 spin_lock_irqsave(&card->card_lock, flags);
1005 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1006 spin_unlock_irqrestore(&card->card_lock, flags);
1011 static void isicom_close(struct tty_struct *tty, struct file *filp)
1013 struct isi_port *port = tty->driver_data;
1014 struct isi_board *card;
1015 unsigned long flags;
1020 if (isicom_paranoia_check(port, tty->name, "isicom_close"))
1023 pr_dbg("Close start!!!.\n");
1025 spin_lock_irqsave(&card->card_lock, flags);
1026 if (tty_hung_up_p(filp)) {
1027 spin_unlock_irqrestore(&card->card_lock, flags);
1031 if (tty->count == 1 && port->port.count != 1) {
1032 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1033 "count tty->count = 1 port count = %d.\n",
1034 card->base, port->port.count);
1035 port->port.count = 1;
1037 if (--port->port.count < 0) {
1038 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1039 "count for channel%d = %d", card->base, port->channel,
1041 port->port.count = 0;
1044 if (port->port.count) {
1045 spin_unlock_irqrestore(&card->card_lock, flags);
1048 port->port.flags |= ASYNC_CLOSING;
1050 spin_unlock_irqrestore(&card->card_lock, flags);
1052 if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1053 tty_wait_until_sent(tty, port->port.closing_wait);
1054 /* indicate to the card that no more data can be received
1056 spin_lock_irqsave(&card->card_lock, flags);
1057 if (port->port.flags & ASYNC_INITIALIZED) {
1058 card->port_status &= ~(1 << port->channel);
1059 outw(card->port_status, card->base + 0x02);
1061 isicom_shutdown_port(port);
1062 spin_unlock_irqrestore(&card->card_lock, flags);
1064 isicom_flush_buffer(tty);
1065 tty_ldisc_flush(tty);
1067 spin_lock_irqsave(&card->card_lock, flags);
1070 if (port->port.blocked_open) {
1071 spin_unlock_irqrestore(&card->card_lock, flags);
1072 if (port->port.close_delay) {
1073 pr_dbg("scheduling until time out.\n");
1074 msleep_interruptible(
1075 jiffies_to_msecs(port->port.close_delay));
1077 spin_lock_irqsave(&card->card_lock, flags);
1078 wake_up_interruptible(&port->port.open_wait);
1080 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1081 wake_up_interruptible(&port->port.close_wait);
1082 spin_unlock_irqrestore(&card->card_lock, flags);
1086 static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
1089 struct isi_port *port = tty->driver_data;
1090 struct isi_board *card = port->card;
1091 unsigned long flags;
1094 if (isicom_paranoia_check(port, tty->name, "isicom_write"))
1097 spin_lock_irqsave(&card->card_lock, flags);
1100 cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
1101 - 1, SERIAL_XMIT_SIZE - port->xmit_head));
1105 memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt);
1106 port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
1108 port->xmit_cnt += cnt;
1113 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped)
1114 port->status |= ISI_TXOK;
1115 spin_unlock_irqrestore(&card->card_lock, flags);
1119 /* put_char et all */
1120 static int isicom_put_char(struct tty_struct *tty, unsigned char ch)
1122 struct isi_port *port = tty->driver_data;
1123 struct isi_board *card = port->card;
1124 unsigned long flags;
1126 if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
1129 spin_lock_irqsave(&card->card_lock, flags);
1130 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
1131 spin_unlock_irqrestore(&card->card_lock, flags);
1135 port->port.xmit_buf[port->xmit_head++] = ch;
1136 port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
1138 spin_unlock_irqrestore(&card->card_lock, flags);
1142 /* flush_chars et all */
1143 static void isicom_flush_chars(struct tty_struct *tty)
1145 struct isi_port *port = tty->driver_data;
1147 if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars"))
1150 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1151 !port->port.xmit_buf)
1154 /* this tells the transmitter to consider this port for
1155 data output to the card ... that's the best we can do. */
1156 port->status |= ISI_TXOK;
1159 /* write_room et all */
1160 static int isicom_write_room(struct tty_struct *tty)
1162 struct isi_port *port = tty->driver_data;
1165 if (isicom_paranoia_check(port, tty->name, "isicom_write_room"))
1168 free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1174 /* chars_in_buffer et all */
1175 static int isicom_chars_in_buffer(struct tty_struct *tty)
1177 struct isi_port *port = tty->driver_data;
1178 if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer"))
1180 return port->xmit_cnt;
1184 static int isicom_send_break(struct tty_struct *tty, int length)
1186 struct isi_port *port = tty->driver_data;
1187 struct isi_board *card = port->card;
1188 unsigned long base = card->base;
1193 if (!lock_card(card))
1196 outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
1197 outw((length & 0xff) << 8 | 0x00, base);
1198 outw((length & 0xff00), base);
1199 InterruptTheCard(base);
1205 static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
1207 struct isi_port *port = tty->driver_data;
1208 /* just send the port status */
1209 u16 status = port->status;
1211 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1214 return ((status & ISI_RTS) ? TIOCM_RTS : 0) |
1215 ((status & ISI_DTR) ? TIOCM_DTR : 0) |
1216 ((status & ISI_DCD) ? TIOCM_CAR : 0) |
1217 ((status & ISI_DSR) ? TIOCM_DSR : 0) |
1218 ((status & ISI_CTS) ? TIOCM_CTS : 0) |
1219 ((status & ISI_RI ) ? TIOCM_RI : 0);
1222 static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
1223 unsigned int set, unsigned int clear)
1225 struct isi_port *port = tty->driver_data;
1226 unsigned long flags;
1228 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1231 spin_lock_irqsave(&port->card->card_lock, flags);
1232 if (set & TIOCM_RTS)
1234 if (set & TIOCM_DTR)
1237 if (clear & TIOCM_RTS)
1239 if (clear & TIOCM_DTR)
1241 spin_unlock_irqrestore(&port->card->card_lock, flags);
1246 static int isicom_set_serial_info(struct tty_struct *tty,
1247 struct serial_struct __user *info)
1249 struct isi_port *port = tty->driver_data;
1250 struct serial_struct newinfo;
1253 if (copy_from_user(&newinfo, info, sizeof(newinfo)))
1258 reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) !=
1259 (newinfo.flags & ASYNC_SPD_MASK));
1261 if (!capable(CAP_SYS_ADMIN)) {
1262 if ((newinfo.close_delay != port->port.close_delay) ||
1263 (newinfo.closing_wait != port->port.closing_wait) ||
1264 ((newinfo.flags & ~ASYNC_USR_MASK) !=
1265 (port->port.flags & ~ASYNC_USR_MASK))) {
1269 port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1270 (newinfo.flags & ASYNC_USR_MASK));
1272 port->port.close_delay = newinfo.close_delay;
1273 port->port.closing_wait = newinfo.closing_wait;
1274 port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1275 (newinfo.flags & ASYNC_FLAGS));
1277 if (reconfig_port) {
1278 unsigned long flags;
1279 spin_lock_irqsave(&port->card->card_lock, flags);
1280 isicom_config_port(tty);
1281 spin_unlock_irqrestore(&port->card->card_lock, flags);
1287 static int isicom_get_serial_info(struct isi_port *port,
1288 struct serial_struct __user *info)
1290 struct serial_struct out_info;
1293 memset(&out_info, 0, sizeof(out_info));
1294 /* out_info.type = ? */
1295 out_info.line = port - isi_ports;
1296 out_info.port = port->card->base;
1297 out_info.irq = port->card->irq;
1298 out_info.flags = port->port.flags;
1299 /* out_info.baud_base = ? */
1300 out_info.close_delay = port->port.close_delay;
1301 out_info.closing_wait = port->port.closing_wait;
1303 if (copy_to_user(info, &out_info, sizeof(out_info)))
1308 static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1309 unsigned int cmd, unsigned long arg)
1311 struct isi_port *port = tty->driver_data;
1312 void __user *argp = (void __user *)arg;
1314 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1319 return isicom_get_serial_info(port, argp);
1322 return isicom_set_serial_info(tty, argp);
1325 return -ENOIOCTLCMD;
1330 /* set_termios et all */
1331 static void isicom_set_termios(struct tty_struct *tty,
1332 struct ktermios *old_termios)
1334 struct isi_port *port = tty->driver_data;
1335 unsigned long flags;
1337 if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
1340 if (tty->termios->c_cflag == old_termios->c_cflag &&
1341 tty->termios->c_iflag == old_termios->c_iflag)
1344 spin_lock_irqsave(&port->card->card_lock, flags);
1345 isicom_config_port(tty);
1346 spin_unlock_irqrestore(&port->card->card_lock, flags);
1348 if ((old_termios->c_cflag & CRTSCTS) &&
1349 !(tty->termios->c_cflag & CRTSCTS)) {
1350 tty->hw_stopped = 0;
1355 /* throttle et all */
1356 static void isicom_throttle(struct tty_struct *tty)
1358 struct isi_port *port = tty->driver_data;
1359 struct isi_board *card = port->card;
1361 if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
1364 /* tell the card that this port cannot handle any more data for now */
1365 card->port_status &= ~(1 << port->channel);
1366 outw(card->port_status, card->base + 0x02);
1369 /* unthrottle et all */
1370 static void isicom_unthrottle(struct tty_struct *tty)
1372 struct isi_port *port = tty->driver_data;
1373 struct isi_board *card = port->card;
1375 if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
1378 /* tell the card that this port is ready to accept more data */
1379 card->port_status |= (1 << port->channel);
1380 outw(card->port_status, card->base + 0x02);
1384 static void isicom_stop(struct tty_struct *tty)
1386 struct isi_port *port = tty->driver_data;
1388 if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
1391 /* this tells the transmitter not to consider this port for
1392 data output to the card. */
1393 port->status &= ~ISI_TXOK;
1397 static void isicom_start(struct tty_struct *tty)
1399 struct isi_port *port = tty->driver_data;
1401 if (isicom_paranoia_check(port, tty->name, "isicom_start"))
1404 /* this tells the transmitter to consider this port for
1405 data output to the card. */
1406 port->status |= ISI_TXOK;
1409 static void isicom_hangup(struct tty_struct *tty)
1411 struct isi_port *port = tty->driver_data;
1412 unsigned long flags;
1414 if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
1417 spin_lock_irqsave(&port->card->card_lock, flags);
1418 isicom_shutdown_port(port);
1419 spin_unlock_irqrestore(&port->card->card_lock, flags);
1421 port->port.count = 0;
1422 port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1423 tty_port_tty_set(&port->port, NULL);
1424 wake_up_interruptible(&port->port.open_wait);
1429 * Driver init and deinit functions
1432 static const struct tty_operations isicom_ops = {
1433 .open = isicom_open,
1434 .close = isicom_close,
1435 .write = isicom_write,
1436 .put_char = isicom_put_char,
1437 .flush_chars = isicom_flush_chars,
1438 .write_room = isicom_write_room,
1439 .chars_in_buffer = isicom_chars_in_buffer,
1440 .ioctl = isicom_ioctl,
1441 .set_termios = isicom_set_termios,
1442 .throttle = isicom_throttle,
1443 .unthrottle = isicom_unthrottle,
1444 .stop = isicom_stop,
1445 .start = isicom_start,
1446 .hangup = isicom_hangup,
1447 .flush_buffer = isicom_flush_buffer,
1448 .tiocmget = isicom_tiocmget,
1449 .tiocmset = isicom_tiocmset,
1450 .break_ctl = isicom_send_break,
1453 static int __devinit reset_card(struct pci_dev *pdev,
1454 const unsigned int card, unsigned int *signature)
1456 struct isi_board *board = pci_get_drvdata(pdev);
1457 unsigned long base = board->base;
1458 unsigned int sig, portcount = 0;
1461 dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
1468 outw(0, base + 0x8); /* Reset */
1472 sig = inw(base + 0x4) & 0xff;
1474 if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd &&
1476 dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible "
1477 "bad I/O Port Address 0x%lx).\n", card + 1, base);
1478 dev_dbg(&pdev->dev, "Sig=0x%x\n", sig);
1485 portcount = inw(base + 0x2);
1486 if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 &&
1487 portcount != 8 && portcount != 16)) {
1488 dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
1498 board->port_count = (portcount == 4) ? 4 : 8;
1499 board->shift_count = 12;
1503 board->port_count = 16;
1504 board->shift_count = 11;
1507 dev_info(&pdev->dev, "-Done\n");
1514 static int __devinit load_firmware(struct pci_dev *pdev,
1515 const unsigned int index, const unsigned int signature)
1517 struct isi_board *board = pci_get_drvdata(pdev);
1518 const struct firmware *fw;
1519 unsigned long base = board->base;
1521 u16 word_count, status;
1532 switch (signature) {
1534 name = "isi608.bin";
1537 name = "isi608em.bin";
1540 name = "isi616em.bin";
1543 name = "isi4608.bin";
1546 name = "isi4616.bin";
1549 dev_err(&pdev->dev, "Unknown signature.\n");
1553 retval = request_firmware(&fw, name, &pdev->dev);
1559 for (frame = (struct stframe *)fw->data;
1560 frame < (struct stframe *)(fw->data + fw->size);
1561 frame = (struct stframe *)((u8 *)(frame + 1) +
1563 if (WaitTillCardIsFree(base))
1566 outw(0xf0, base); /* start upload sequence */
1568 outw(frame->addr, base); /* lsb of address */
1570 word_count = frame->count / 2 + frame->count % 2;
1571 outw(word_count, base);
1572 InterruptTheCard(base);
1574 udelay(100); /* 0x2f */
1576 if (WaitTillCardIsFree(base))
1579 status = inw(base + 0x4);
1581 dev_warn(&pdev->dev, "Card%d rejected load header:\n"
1582 KERN_WARNING "Address:0x%x\n"
1583 KERN_WARNING "Count:0x%x\n"
1584 KERN_WARNING "Status:0x%x\n",
1585 index + 1, frame->addr, frame->count, status);
1588 outsw(base, frame->data, word_count);
1590 InterruptTheCard(base);
1592 udelay(50); /* 0x0f */
1594 if (WaitTillCardIsFree(base))
1597 status = inw(base + 0x4);
1599 dev_err(&pdev->dev, "Card%d got out of sync.Card "
1600 "Status:0x%x\n", index + 1, status);
1605 /* XXX: should we test it by reading it back and comparing with original like
1606 * in load firmware package? */
1607 for (frame = (struct stframe *)fw->data;
1608 frame < (struct stframe *)(fw->data + fw->size);
1609 frame = (struct stframe *)((u8 *)(frame + 1) +
1611 if (WaitTillCardIsFree(base))
1614 outw(0xf1, base); /* start download sequence */
1616 outw(frame->addr, base); /* lsb of address */
1618 word_count = (frame->count >> 1) + frame->count % 2;
1619 outw(word_count + 1, base);
1620 InterruptTheCard(base);
1622 udelay(50); /* 0xf */
1624 if (WaitTillCardIsFree(base))
1627 status = inw(base + 0x4);
1629 dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
1630 KERN_WARNING "Address:0x%x\n"
1631 KERN_WARNING "Count:0x%x\n"
1632 KERN_WARNING "Status: 0x%x\n",
1633 index + 1, frame->addr, frame->count, status);
1637 data = kmalloc(word_count * 2, GFP_KERNEL);
1639 dev_err(&pdev->dev, "Card%d, firmware upload "
1640 "failed, not enough memory\n", index + 1);
1644 insw(base, data, word_count);
1645 InterruptTheCard(base);
1647 for (a = 0; a < frame->count; a++)
1648 if (data[a] != frame->data[a]) {
1650 dev_err(&pdev->dev, "Card%d, firmware upload "
1651 "failed\n", index + 1);
1656 udelay(50); /* 0xf */
1658 if (WaitTillCardIsFree(base))
1661 status = inw(base + 0x4);
1663 dev_err(&pdev->dev, "Card%d verify got out of sync. "
1664 "Card Status:0x%x\n", index + 1, status);
1670 if (WaitTillCardIsFree(base))
1677 InterruptTheCard(base);
1678 outw(0x0, base + 0x4); /* for ISI4608 cards */
1680 board->status |= FIRMWARE_LOADED;
1684 release_firmware(fw);
1690 * Insmod can set static symbols so keep these static
1692 static unsigned int card_count;
1694 static int __devinit isicom_probe(struct pci_dev *pdev,
1695 const struct pci_device_id *ent)
1697 unsigned int signature, index;
1698 int retval = -EPERM;
1699 struct isi_board *board = NULL;
1701 if (card_count >= BOARD_COUNT)
1704 retval = pci_enable_device(pdev);
1706 dev_err(&pdev->dev, "failed to enable\n");
1710 dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
1712 /* allot the first empty slot in the array */
1713 for (index = 0; index < BOARD_COUNT; index++)
1714 if (isi_card[index].base == 0) {
1715 board = &isi_card[index];
1719 board->index = index;
1720 board->base = pci_resource_start(pdev, 3);
1721 board->irq = pdev->irq;
1724 pci_set_drvdata(pdev, board);
1726 retval = pci_request_region(pdev, 3, ISICOM_NAME);
1728 dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
1729 "will be disabled.\n", board->base, board->base + 15,
1735 retval = request_irq(board->irq, isicom_interrupt,
1736 IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
1738 dev_err(&pdev->dev, "Could not install handler at Irq %d. "
1739 "Card%d will be disabled.\n", board->irq, index + 1);
1743 retval = reset_card(pdev, index, &signature);
1747 retval = load_firmware(pdev, index, signature);
1751 for (index = 0; index < board->port_count; index++)
1752 tty_register_device(isicom_normal, board->index * 16 + index,
1758 free_irq(board->irq, board);
1760 pci_release_region(pdev, 3);
1764 pci_disable_device(pdev);
1769 static void __devexit isicom_remove(struct pci_dev *pdev)
1771 struct isi_board *board = pci_get_drvdata(pdev);
1774 for (i = 0; i < board->port_count; i++)
1775 tty_unregister_device(isicom_normal, board->index * 16 + i);
1777 free_irq(board->irq, board);
1778 pci_release_region(pdev, 3);
1781 pci_disable_device(pdev);
1784 static int __init isicom_init(void)
1786 int retval, idx, channel;
1787 struct isi_port *port;
1789 for (idx = 0; idx < BOARD_COUNT; idx++) {
1790 port = &isi_ports[idx * 16];
1791 isi_card[idx].ports = port;
1792 spin_lock_init(&isi_card[idx].card_lock);
1793 for (channel = 0; channel < 16; channel++, port++) {
1794 tty_port_init(&port->port);
1795 port->magic = ISICOM_MAGIC;
1796 port->card = &isi_card[idx];
1797 port->channel = channel;
1798 port->port.close_delay = 50 * HZ/100;
1799 port->port.closing_wait = 3000 * HZ/100;
1803 isi_card[idx].base = 0;
1804 isi_card[idx].irq = 0;
1807 /* tty driver structure initialization */
1808 isicom_normal = alloc_tty_driver(PORT_COUNT);
1809 if (!isicom_normal) {
1814 isicom_normal->owner = THIS_MODULE;
1815 isicom_normal->name = "ttyM";
1816 isicom_normal->major = ISICOM_NMAJOR;
1817 isicom_normal->minor_start = 0;
1818 isicom_normal->type = TTY_DRIVER_TYPE_SERIAL;
1819 isicom_normal->subtype = SERIAL_TYPE_NORMAL;
1820 isicom_normal->init_termios = tty_std_termios;
1821 isicom_normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
1823 isicom_normal->flags = TTY_DRIVER_REAL_RAW |
1824 TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK;
1825 tty_set_operations(isicom_normal, &isicom_ops);
1827 retval = tty_register_driver(isicom_normal);
1829 pr_dbg("Couldn't register the dialin driver\n");
1833 retval = pci_register_driver(&isicom_driver);
1835 printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
1839 mod_timer(&tx, jiffies + 1);
1843 tty_unregister_driver(isicom_normal);
1845 put_tty_driver(isicom_normal);
1850 static void __exit isicom_exit(void)
1852 del_timer_sync(&tx);
1854 pci_unregister_driver(&isicom_driver);
1855 tty_unregister_driver(isicom_normal);
1856 put_tty_driver(isicom_normal);
1859 module_init(isicom_init);
1860 module_exit(isicom_exit);
1862 MODULE_AUTHOR("MultiTech");
1863 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
1864 MODULE_LICENSE("GPL");