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@lxorguk.ukuu.org.uk
11 * Merge to 2.0.x kernel tree
12 * Obtain and use official major/minors
13 * Loader switched to a misc device
14 * (fixed range check bug as a side effect)
16 * 9/12/98 alan@lxorguk.ukuu.org.uk
19 * 10/6/99 sameer Merged the ISA and PCI drivers to
20 * a new unified driver.
22 * 3/9/99 sameer Added support for ISI4616 cards.
24 * 16/9/99 sameer We do not force RTS low anymore.
25 * This is to prevent the firmware
26 * from getting confused.
28 * 26/10/99 sameer Cosmetic changes:The driver now
29 * dumps the Port Count information
30 * along with I/O address and IRQ.
32 * 13/12/99 sameer Fixed the problem with IRQ sharing.
34 * 10/5/00 sameer Fixed isicom_shutdown_board()
35 * to not lower DTR on all the ports
36 * when the last port on the card is
39 * 10/5/00 sameer Signal mask setup command added
40 * to isicom_setup_port and
41 * isicom_shutdown_port.
43 * 24/5/00 sameer The driver is now SMP aware.
46 * 27/11/00 Vinayak P Risbud Fixed the Driver Crash Problem
49 * 03/01/01 anil .s Added support for resetting the
50 * internal modems on ISI cards.
52 * 08/02/01 anil .s Upgraded the driver for kernel
55 * 11/04/01 Kevin Fixed firmware load problem with
58 * 30/04/01 anil .s Fixed the remote login through
59 * ISI port problem. Now the link
60 * does not go down before password
63 * 03/05/01 anil .s Fixed the problem with IRQ sharing
64 * among ISI-PCI cards.
66 * 03/05/01 anil .s Added support to display the version
67 * info during insmod as well as module
70 * 10/05/01 anil .s Done the modifications to the source
71 * file and Install script so that the
72 * same installation can be used for
73 * 2.2.x and 2.4.x kernel.
75 * 06/06/01 anil .s Now we drop both dtr and rts during
76 * shutdown_port as well as raise them
77 * during isicom_config_port.
79 * 09/06/01 acme@conectiva.com.br use capable, not suser, do
80 * restore_flags on failure in
81 * isicom_send_break, verify put_user
84 * 11/02/03 ranjeeth Added support for 230 Kbps and 460 Kbps
85 * Baud index extended to 21
87 * 20/03/03 ranjeeth Made to work for Linux Advanced server.
88 * Taken care of license warning.
90 * 10/12/03 Ravindra Made to work for Fedora Core 1 of
91 * Red Hat Distribution
93 * 06/01/05 Alan Cox Merged the ISI and base kernel strands
94 * into a single 2.6 driver
96 * ***********************************************************
98 * To use this driver you also need the support package. You
99 * can find this in RPM format on
100 * ftp://ftp.linux.org.uk/pub/linux/alan
102 * You can find the original tools for this direct from Multitech
103 * ftp://ftp.multitech.com/ISI-Cards/
105 * Having installed the cards the module options (/etc/modprobe.conf)
107 * options isicom io=card1,card2,card3,card4 irq=card1,card2,card3,card4
109 * Omit those entries for boards you don't have installed.
113 * 64-bit verification
116 #include <linux/module.h>
117 #include <linux/firmware.h>
118 #include <linux/kernel.h>
119 #include <linux/tty.h>
120 #include <linux/tty_flip.h>
121 #include <linux/termios.h>
122 #include <linux/fs.h>
123 #include <linux/sched.h>
124 #include <linux/serial.h>
125 #include <linux/mm.h>
126 #include <linux/interrupt.h>
127 #include <linux/timer.h>
128 #include <linux/delay.h>
129 #include <linux/ioport.h>
131 #include <linux/uaccess.h>
132 #include <linux/io.h>
133 #include <asm/system.h>
135 #include <linux/pci.h>
137 #include <linux/isicom.h>
139 #define InterruptTheCard(base) outw(0, (base) + 0xc)
140 #define ClearInterrupt(base) inw((base) + 0x0a)
142 #define pr_dbg(str...) pr_debug("ISICOM: " str)
144 #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c))
146 #define isicom_paranoia_check(a, b, c) 0
149 static int isicom_probe(struct pci_dev *, const struct pci_device_id *);
150 static void __devexit isicom_remove(struct pci_dev *);
152 static struct pci_device_id isicom_pci_tbl[] = {
153 { PCI_DEVICE(VENDOR_ID, 0x2028) },
154 { PCI_DEVICE(VENDOR_ID, 0x2051) },
155 { PCI_DEVICE(VENDOR_ID, 0x2052) },
156 { PCI_DEVICE(VENDOR_ID, 0x2053) },
157 { PCI_DEVICE(VENDOR_ID, 0x2054) },
158 { PCI_DEVICE(VENDOR_ID, 0x2055) },
159 { PCI_DEVICE(VENDOR_ID, 0x2056) },
160 { PCI_DEVICE(VENDOR_ID, 0x2057) },
161 { PCI_DEVICE(VENDOR_ID, 0x2058) },
164 MODULE_DEVICE_TABLE(pci, isicom_pci_tbl);
166 static struct pci_driver isicom_driver = {
168 .id_table = isicom_pci_tbl,
169 .probe = isicom_probe,
170 .remove = __devexit_p(isicom_remove)
173 static int prev_card = 3; /* start servicing isi_card[0] */
174 static struct tty_driver *isicom_normal;
176 static void isicom_tx(unsigned long _data);
177 static void isicom_start(struct tty_struct *tty);
179 static DEFINE_TIMER(tx, isicom_tx, 0, 0);
181 /* baud index mappings from linux defns to isi */
183 static signed char linuxb_to_isib[] = {
184 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21
190 unsigned char port_count;
191 unsigned short status;
192 unsigned short port_status; /* each bit for each port */
193 unsigned short shift_count;
194 struct isi_port *ports;
196 spinlock_t card_lock; /* Card wide lock 11/5/00 -sameer */
202 unsigned short magic;
203 struct tty_port port;
206 struct isi_board *card;
207 unsigned char *xmit_buf;
213 static struct isi_board isi_card[BOARD_COUNT];
214 static struct isi_port isi_ports[PORT_COUNT];
217 * Locking functions for card level locking. We need to own both
218 * the kernel lock for the card and have the card in a position that
222 static inline int WaitTillCardIsFree(unsigned long base)
224 unsigned int count = 0;
225 unsigned int a = in_atomic(); /* do we run under spinlock? */
227 while (!(inw(base + 0xe) & 0x1) && count++ < 100)
233 return !(inw(base + 0xe) & 0x1);
236 static int lock_card(struct isi_board *card)
238 unsigned long base = card->base;
239 unsigned int retries, a;
241 for (retries = 0; retries < 10; retries++) {
242 spin_lock_irqsave(&card->card_lock, card->flags);
243 for (a = 0; a < 10; a++) {
244 if (inw(base + 0xe) & 0x1)
248 spin_unlock_irqrestore(&card->card_lock, card->flags);
251 printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%lx)\n",
254 return 0; /* Failed to acquire the card! */
257 static void unlock_card(struct isi_board *card)
259 spin_unlock_irqrestore(&card->card_lock, card->flags);
263 * ISI Card specific ops ...
266 /* card->lock HAS to be held */
267 static void raise_dtr(struct isi_port *port)
269 struct isi_board *card = port->card;
270 unsigned long base = card->base;
271 u16 channel = port->channel;
273 if (WaitTillCardIsFree(base))
276 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
278 InterruptTheCard(base);
279 port->status |= ISI_DTR;
282 /* card->lock HAS to be held */
283 static inline void drop_dtr(struct isi_port *port)
285 struct isi_board *card = port->card;
286 unsigned long base = card->base;
287 u16 channel = port->channel;
289 if (WaitTillCardIsFree(base))
292 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
294 InterruptTheCard(base);
295 port->status &= ~ISI_DTR;
298 /* card->lock HAS to be held */
299 static inline void raise_rts(struct isi_port *port)
301 struct isi_board *card = port->card;
302 unsigned long base = card->base;
303 u16 channel = port->channel;
305 if (WaitTillCardIsFree(base))
308 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
310 InterruptTheCard(base);
311 port->status |= ISI_RTS;
314 /* card->lock HAS to be held */
315 static inline void drop_rts(struct isi_port *port)
317 struct isi_board *card = port->card;
318 unsigned long base = card->base;
319 u16 channel = port->channel;
321 if (WaitTillCardIsFree(base))
324 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
326 InterruptTheCard(base);
327 port->status &= ~ISI_RTS;
330 /* card->lock MUST NOT be held */
331 static inline void raise_dtr_rts(struct isi_port *port)
333 struct isi_board *card = port->card;
334 unsigned long base = card->base;
335 u16 channel = port->channel;
337 if (!lock_card(card))
340 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
342 InterruptTheCard(base);
343 port->status |= (ISI_DTR | ISI_RTS);
347 /* card->lock HAS to be held */
348 static void drop_dtr_rts(struct isi_port *port)
350 struct isi_board *card = port->card;
351 unsigned long base = card->base;
352 u16 channel = port->channel;
354 if (WaitTillCardIsFree(base))
357 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
359 InterruptTheCard(base);
360 port->status &= ~(ISI_RTS | ISI_DTR);
364 * ISICOM Driver specific routines ...
368 static inline int __isicom_paranoia_check(struct isi_port const *port,
369 char *name, const char *routine)
372 printk(KERN_WARNING "ISICOM: Warning: bad isicom magic for "
373 "dev %s in %s.\n", name, routine);
376 if (port->magic != ISICOM_MAGIC) {
377 printk(KERN_WARNING "ISICOM: Warning: NULL isicom port for "
378 "dev %s in %s.\n", name, routine);
388 * We shovel data into the card buffers on a regular basis. The card
389 * will do the rest of the work for us.
392 static void isicom_tx(unsigned long _data)
394 unsigned long flags, base;
395 unsigned int retries;
396 short count = (BOARD_COUNT-1), card;
397 short txcount, wrd, residue, word_count, cnt;
398 struct isi_port *port;
399 struct tty_struct *tty;
401 /* find next active board */
402 card = (prev_card + 1) & 0x0003;
403 while (count-- > 0) {
404 if (isi_card[card].status & BOARD_ACTIVE)
406 card = (card + 1) & 0x0003;
408 if (!(isi_card[card].status & BOARD_ACTIVE))
413 count = isi_card[card].port_count;
414 port = isi_card[card].ports;
415 base = isi_card[card].base;
417 spin_lock_irqsave(&isi_card[card].card_lock, flags);
418 for (retries = 0; retries < 100; retries++) {
419 if (inw(base + 0xe) & 0x1)
426 tty = tty_port_tty_get(&port->port);
430 for (; count > 0; count--, port++) {
431 /* port not active or tx disabled to force flow control */
432 if (!(port->port.flags & ASYNC_INITIALIZED) ||
433 !(port->status & ISI_TXOK))
436 txcount = min_t(short, TX_SIZE, port->xmit_cnt);
437 if (txcount <= 0 || tty->stopped || tty->hw_stopped)
440 if (!(inw(base + 0x02) & (1 << port->channel)))
443 pr_dbg("txing %d bytes, port%d.\n", txcount,
445 outw((port->channel << isi_card[card].shift_count) | txcount,
450 cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE
452 if (residue == YES) {
455 wrd |= (port->port.xmit_buf[port->xmit_tail]
457 port->xmit_tail = (port->xmit_tail + 1)
458 & (SERIAL_XMIT_SIZE - 1);
470 word_count = cnt >> 1;
471 outsw(base, port->port.xmit_buf+port->xmit_tail, word_count);
472 port->xmit_tail = (port->xmit_tail
473 + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
474 txcount -= (word_count << 1);
475 port->xmit_cnt -= (word_count << 1);
478 wrd = port->port.xmit_buf[port->xmit_tail];
479 port->xmit_tail = (port->xmit_tail + 1)
480 & (SERIAL_XMIT_SIZE - 1);
486 InterruptTheCard(base);
487 if (port->xmit_cnt <= 0)
488 port->status &= ~ISI_TXOK;
489 if (port->xmit_cnt <= WAKEUP_CHARS)
496 spin_unlock_irqrestore(&isi_card[card].card_lock, flags);
497 /* schedule another tx for hopefully in about 10ms */
499 mod_timer(&tx, jiffies + msecs_to_jiffies(10));
503 * Main interrupt handler routine
506 static irqreturn_t isicom_interrupt(int irq, void *dev_id)
508 struct isi_board *card = dev_id;
509 struct isi_port *port;
510 struct tty_struct *tty;
512 u16 header, word_count, count, channel;
516 if (!card || !(card->status & FIRMWARE_LOADED))
521 /* did the card interrupt us? */
522 if (!(inw(base + 0x0e) & 0x02))
525 spin_lock(&card->card_lock);
528 * disable any interrupts from the PCI card and lower the
531 outw(0x8000, base+0x04);
532 ClearInterrupt(base);
534 inw(base); /* get the dummy word out */
536 channel = (header & 0x7800) >> card->shift_count;
537 byte_count = header & 0xff;
539 if (channel + 1 > card->port_count) {
540 printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): "
541 "%d(channel) > port_count.\n", base, channel+1);
542 outw(0x0000, base+0x04); /* enable interrupts */
543 spin_unlock(&card->card_lock);
546 port = card->ports + channel;
547 if (!(port->port.flags & ASYNC_INITIALIZED)) {
548 outw(0x0000, base+0x04); /* enable interrupts */
549 spin_unlock(&card->card_lock);
553 tty = tty_port_tty_get(&port->port);
555 word_count = byte_count >> 1;
556 while (byte_count > 1) {
560 if (byte_count & 0x01)
562 outw(0x0000, base+0x04); /* enable interrupts */
563 spin_unlock(&card->card_lock);
567 if (header & 0x8000) { /* Status Packet */
569 switch (header & 0xff) {
570 case 0: /* Change in EIA signals */
571 if (port->port.flags & ASYNC_CHECK_CD) {
572 if (port->status & ISI_DCD) {
573 if (!(header & ISI_DCD)) {
574 /* Carrier has been lost */
575 pr_dbg("interrupt: DCD->low.\n"
577 port->status &= ~ISI_DCD;
580 } else if (header & ISI_DCD) {
581 /* Carrier has been detected */
582 pr_dbg("interrupt: DCD->high.\n");
583 port->status |= ISI_DCD;
584 wake_up_interruptible(&port->port.open_wait);
587 if (header & ISI_DCD)
588 port->status |= ISI_DCD;
590 port->status &= ~ISI_DCD;
593 if (port->port.flags & ASYNC_CTS_FLOW) {
594 if (tty->hw_stopped) {
595 if (header & ISI_CTS) {
596 port->port.tty->hw_stopped = 0;
598 port->status |= (ISI_TXOK
602 } else if (!(header & ISI_CTS)) {
605 port->status &= ~(ISI_TXOK | ISI_CTS);
608 if (header & ISI_CTS)
609 port->status |= ISI_CTS;
611 port->status &= ~ISI_CTS;
614 if (header & ISI_DSR)
615 port->status |= ISI_DSR;
617 port->status &= ~ISI_DSR;
620 port->status |= ISI_RI;
622 port->status &= ~ISI_RI;
626 case 1: /* Received Break !!! */
627 tty_insert_flip_char(tty, 0, TTY_BREAK);
628 if (port->port.flags & ASYNC_SAK)
630 tty_flip_buffer_push(tty);
633 case 2: /* Statistics */
634 pr_dbg("isicom_interrupt: stats!!!.\n");
638 pr_dbg("Intr: Unknown code in status packet.\n");
641 } else { /* Data Packet */
643 count = tty_prepare_flip_string(tty, &rp, byte_count & ~1);
644 pr_dbg("Intr: Can rx %d of %d bytes.\n", count, byte_count);
645 word_count = count >> 1;
646 insw(base, rp, word_count);
647 byte_count -= (word_count << 1);
648 if (count & 0x0001) {
649 tty_insert_flip_char(tty, inw(base) & 0xff,
653 if (byte_count > 0) {
654 pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping "
655 "bytes...\n", base, channel + 1);
656 /* drain out unread xtra data */
657 while (byte_count > 0) {
662 tty_flip_buffer_push(tty);
664 outw(0x0000, base+0x04); /* enable interrupts */
665 spin_unlock(&card->card_lock);
671 static void isicom_config_port(struct tty_struct *tty)
673 struct isi_port *port = tty->driver_data;
674 struct isi_board *card = port->card;
676 unsigned long base = card->base;
677 u16 channel_setup, channel = port->channel,
678 shift_count = card->shift_count;
679 unsigned char flow_ctrl;
681 /* FIXME: Switch to new tty baud API */
683 if (baud & CBAUDEX) {
686 /* if CBAUDEX bit is on and the baud is set to either 50 or 75
687 * then the card is programmed for 57.6Kbps or 115Kbps
691 /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
692 if (baud < 1 || baud > 4)
693 tty->termios->c_cflag &= ~CBAUDEX;
699 /* the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set
700 * by the set_serial_info ioctl ... this is done by
701 * the 'setserial' utility.
704 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
705 baud++; /* 57.6 Kbps */
706 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
707 baud += 2; /* 115 Kbps */
708 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
709 baud += 3; /* 230 kbps*/
710 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
711 baud += 4; /* 460 kbps*/
713 if (linuxb_to_isib[baud] == -1) {
720 if (WaitTillCardIsFree(base) == 0) {
721 outw(0x8000 | (channel << shift_count) | 0x03, base);
722 outw(linuxb_to_isib[baud] << 8 | 0x03, base);
724 switch (C_CSIZE(tty)) {
726 channel_setup |= ISICOM_CS5;
729 channel_setup |= ISICOM_CS6;
732 channel_setup |= ISICOM_CS7;
735 channel_setup |= ISICOM_CS8;
740 channel_setup |= ISICOM_2SB;
742 channel_setup |= ISICOM_EVPAR;
744 channel_setup |= ISICOM_ODPAR;
746 outw(channel_setup, base);
747 InterruptTheCard(base);
750 port->port.flags &= ~ASYNC_CHECK_CD;
752 port->port.flags |= ASYNC_CHECK_CD;
754 /* flow control settings ...*/
756 port->port.flags &= ~ASYNC_CTS_FLOW;
757 if (C_CRTSCTS(tty)) {
758 port->port.flags |= ASYNC_CTS_FLOW;
759 flow_ctrl |= ISICOM_CTSRTS;
762 flow_ctrl |= ISICOM_RESPOND_XONXOFF;
764 flow_ctrl |= ISICOM_INITIATE_XONXOFF;
766 if (WaitTillCardIsFree(base) == 0) {
767 outw(0x8000 | (channel << shift_count) | 0x04, base);
768 outw(flow_ctrl << 8 | 0x05, base);
769 outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
770 InterruptTheCard(base);
773 /* rx enabled -> enable port for rx on the card */
775 card->port_status |= (1 << channel);
776 outw(card->port_status, base + 0x02);
782 static inline void isicom_setup_board(struct isi_board *bp)
785 struct isi_port *port;
788 spin_lock_irqsave(&bp->card_lock, flags);
789 if (bp->status & BOARD_ACTIVE) {
790 spin_unlock_irqrestore(&bp->card_lock, flags);
794 bp->status |= BOARD_ACTIVE;
795 for (channel = 0; channel < bp->port_count; channel++, port++)
797 spin_unlock_irqrestore(&bp->card_lock, flags);
800 static int isicom_setup_port(struct tty_struct *tty)
802 struct isi_port *port = tty->driver_data;
803 struct isi_board *card = port->card;
806 if (port->port.flags & ASYNC_INITIALIZED)
808 if (tty_port_alloc_xmit_buf(&port->port) < 0)
811 spin_lock_irqsave(&card->card_lock, flags);
812 clear_bit(TTY_IO_ERROR, &tty->flags);
813 if (port->port.count == 1)
816 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
818 /* discard any residual data */
819 if (WaitTillCardIsFree(card->base) == 0) {
820 outw(0x8000 | (port->channel << card->shift_count) | 0x02,
822 outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base);
823 InterruptTheCard(card->base);
826 isicom_config_port(tty);
827 port->port.flags |= ASYNC_INITIALIZED;
828 spin_unlock_irqrestore(&card->card_lock, flags);
833 static int block_til_ready(struct tty_struct *tty, struct file *filp,
834 struct isi_port *port)
836 struct isi_board *card = port->card;
837 int do_clocal = 0, retval;
839 DECLARE_WAITQUEUE(wait, current);
841 /* block if port is in the process of being closed */
843 if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
844 pr_dbg("block_til_ready: close in progress.\n");
845 interruptible_sleep_on(&port->port.close_wait);
846 if (port->port.flags & ASYNC_HUP_NOTIFY)
852 /* if non-blocking mode is set ... */
854 if ((filp->f_flags & O_NONBLOCK) ||
855 (tty->flags & (1 << TTY_IO_ERROR))) {
856 pr_dbg("block_til_ready: non-block mode.\n");
857 port->port.flags |= ASYNC_NORMAL_ACTIVE;
864 /* block waiting for DCD to be asserted, and while
865 callout dev is busy */
867 add_wait_queue(&port->port.open_wait, &wait);
869 spin_lock_irqsave(&card->card_lock, flags);
870 if (!tty_hung_up_p(filp))
872 port->port.blocked_open++;
873 spin_unlock_irqrestore(&card->card_lock, flags);
878 set_current_state(TASK_INTERRUPTIBLE);
879 if (tty_hung_up_p(filp) || !(port->port.flags & ASYNC_INITIALIZED)) {
880 if (port->port.flags & ASYNC_HUP_NOTIFY)
883 retval = -ERESTARTSYS;
886 if (!(port->port.flags & ASYNC_CLOSING) &&
887 (do_clocal || (port->status & ISI_DCD))) {
890 if (signal_pending(current)) {
891 retval = -ERESTARTSYS;
896 set_current_state(TASK_RUNNING);
897 remove_wait_queue(&port->port.open_wait, &wait);
898 spin_lock_irqsave(&card->card_lock, flags);
899 if (!tty_hung_up_p(filp))
901 port->port.blocked_open--;
902 spin_unlock_irqrestore(&card->card_lock, flags);
905 port->port.flags |= ASYNC_NORMAL_ACTIVE;
909 static int isicom_open(struct tty_struct *tty, struct file *filp)
911 struct isi_port *port;
912 struct isi_board *card;
917 if (line < 0 || line > PORT_COUNT-1)
920 card = &isi_card[board];
922 if (!(card->status & FIRMWARE_LOADED))
925 /* open on a port greater than the port count for the card !!! */
926 if (line > ((board * 16) + card->port_count - 1))
929 port = &isi_ports[line];
930 if (isicom_paranoia_check(port, tty->name, "isicom_open"))
933 isicom_setup_board(card);
936 tty->driver_data = port;
937 tty_port_tty_set(&port->port, tty);
938 error = isicom_setup_port(tty);
940 error = block_til_ready(tty, filp, port);
946 static inline void isicom_shutdown_board(struct isi_board *bp)
948 if (bp->status & BOARD_ACTIVE)
949 bp->status &= ~BOARD_ACTIVE;
952 /* card->lock HAS to be held */
953 static void isicom_shutdown_port(struct isi_port *port)
955 struct isi_board *card = port->card;
956 struct tty_struct *tty;
958 tty = tty_port_tty_get(&port->port);
960 if (!(port->port.flags & ASYNC_INITIALIZED)) {
965 tty_port_free_xmit_buf(&port->port);
966 port->port.flags &= ~ASYNC_INITIALIZED;
967 /* 3rd October 2000 : Vinayak P Risbud */
968 tty_port_tty_set(&port->port, NULL);
970 /*Fix done by Anil .S on 30-04-2001
971 remote login through isi port has dtr toggle problem
972 due to which the carrier drops before the password prompt
973 appears on the remote end. Now we drop the dtr only if the
974 HUPCL(Hangup on close) flag is set for the tty*/
977 /* drop dtr on this port */
980 /* any other port uninits */
982 set_bit(TTY_IO_ERROR, &tty->flags);
984 if (--card->count < 0) {
985 pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n",
986 card->base, card->count);
990 /* last port was closed, shutdown that boad too */
993 isicom_shutdown_board(card);
997 static void isicom_flush_buffer(struct tty_struct *tty)
999 struct isi_port *port = tty->driver_data;
1000 struct isi_board *card = port->card;
1001 unsigned long flags;
1003 if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
1006 spin_lock_irqsave(&card->card_lock, flags);
1007 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1008 spin_unlock_irqrestore(&card->card_lock, flags);
1013 static void isicom_close(struct tty_struct *tty, struct file *filp)
1015 struct isi_port *port = tty->driver_data;
1016 struct isi_board *card;
1017 unsigned long flags;
1022 if (isicom_paranoia_check(port, tty->name, "isicom_close"))
1025 pr_dbg("Close start!!!.\n");
1027 spin_lock_irqsave(&card->card_lock, flags);
1028 if (tty_hung_up_p(filp)) {
1029 spin_unlock_irqrestore(&card->card_lock, flags);
1033 if (tty->count == 1 && port->port.count != 1) {
1034 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1035 "count tty->count = 1 port count = %d.\n",
1036 card->base, port->port.count);
1037 port->port.count = 1;
1039 if (--port->port.count < 0) {
1040 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1041 "count for channel%d = %d", card->base, port->channel,
1043 port->port.count = 0;
1046 if (port->port.count) {
1047 spin_unlock_irqrestore(&card->card_lock, flags);
1050 port->port.flags |= ASYNC_CLOSING;
1052 spin_unlock_irqrestore(&card->card_lock, flags);
1054 if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1055 tty_wait_until_sent(tty, port->port.closing_wait);
1056 /* indicate to the card that no more data can be received
1058 spin_lock_irqsave(&card->card_lock, flags);
1059 if (port->port.flags & ASYNC_INITIALIZED) {
1060 card->port_status &= ~(1 << port->channel);
1061 outw(card->port_status, card->base + 0x02);
1063 isicom_shutdown_port(port);
1064 spin_unlock_irqrestore(&card->card_lock, flags);
1066 isicom_flush_buffer(tty);
1067 tty_ldisc_flush(tty);
1069 spin_lock_irqsave(&card->card_lock, flags);
1072 if (port->port.blocked_open) {
1073 spin_unlock_irqrestore(&card->card_lock, flags);
1074 if (port->port.close_delay) {
1075 pr_dbg("scheduling until time out.\n");
1076 msleep_interruptible(
1077 jiffies_to_msecs(port->port.close_delay));
1079 spin_lock_irqsave(&card->card_lock, flags);
1080 wake_up_interruptible(&port->port.open_wait);
1082 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1083 wake_up_interruptible(&port->port.close_wait);
1084 spin_unlock_irqrestore(&card->card_lock, flags);
1088 static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
1091 struct isi_port *port = tty->driver_data;
1092 struct isi_board *card = port->card;
1093 unsigned long flags;
1096 if (isicom_paranoia_check(port, tty->name, "isicom_write"))
1099 spin_lock_irqsave(&card->card_lock, flags);
1102 cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
1103 - 1, SERIAL_XMIT_SIZE - port->xmit_head));
1107 memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt);
1108 port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
1110 port->xmit_cnt += cnt;
1115 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped)
1116 port->status |= ISI_TXOK;
1117 spin_unlock_irqrestore(&card->card_lock, flags);
1121 /* put_char et all */
1122 static int isicom_put_char(struct tty_struct *tty, unsigned char ch)
1124 struct isi_port *port = tty->driver_data;
1125 struct isi_board *card = port->card;
1126 unsigned long flags;
1128 if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
1131 spin_lock_irqsave(&card->card_lock, flags);
1132 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
1133 spin_unlock_irqrestore(&card->card_lock, flags);
1137 port->port.xmit_buf[port->xmit_head++] = ch;
1138 port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
1140 spin_unlock_irqrestore(&card->card_lock, flags);
1144 /* flush_chars et all */
1145 static void isicom_flush_chars(struct tty_struct *tty)
1147 struct isi_port *port = tty->driver_data;
1149 if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars"))
1152 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1153 !port->port.xmit_buf)
1156 /* this tells the transmitter to consider this port for
1157 data output to the card ... that's the best we can do. */
1158 port->status |= ISI_TXOK;
1161 /* write_room et all */
1162 static int isicom_write_room(struct tty_struct *tty)
1164 struct isi_port *port = tty->driver_data;
1167 if (isicom_paranoia_check(port, tty->name, "isicom_write_room"))
1170 free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1176 /* chars_in_buffer et all */
1177 static int isicom_chars_in_buffer(struct tty_struct *tty)
1179 struct isi_port *port = tty->driver_data;
1180 if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer"))
1182 return port->xmit_cnt;
1186 static int isicom_send_break(struct tty_struct *tty, int length)
1188 struct isi_port *port = tty->driver_data;
1189 struct isi_board *card = port->card;
1190 unsigned long base = card->base;
1195 if (!lock_card(card))
1198 outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
1199 outw((length & 0xff) << 8 | 0x00, base);
1200 outw((length & 0xff00), base);
1201 InterruptTheCard(base);
1207 static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
1209 struct isi_port *port = tty->driver_data;
1210 /* just send the port status */
1211 u16 status = port->status;
1213 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1216 return ((status & ISI_RTS) ? TIOCM_RTS : 0) |
1217 ((status & ISI_DTR) ? TIOCM_DTR : 0) |
1218 ((status & ISI_DCD) ? TIOCM_CAR : 0) |
1219 ((status & ISI_DSR) ? TIOCM_DSR : 0) |
1220 ((status & ISI_CTS) ? TIOCM_CTS : 0) |
1221 ((status & ISI_RI ) ? TIOCM_RI : 0);
1224 static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
1225 unsigned int set, unsigned int clear)
1227 struct isi_port *port = tty->driver_data;
1228 unsigned long flags;
1230 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1233 spin_lock_irqsave(&port->card->card_lock, flags);
1234 if (set & TIOCM_RTS)
1236 if (set & TIOCM_DTR)
1239 if (clear & TIOCM_RTS)
1241 if (clear & TIOCM_DTR)
1243 spin_unlock_irqrestore(&port->card->card_lock, flags);
1248 static int isicom_set_serial_info(struct tty_struct *tty,
1249 struct serial_struct __user *info)
1251 struct isi_port *port = tty->driver_data;
1252 struct serial_struct newinfo;
1255 if (copy_from_user(&newinfo, info, sizeof(newinfo)))
1260 reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) !=
1261 (newinfo.flags & ASYNC_SPD_MASK));
1263 if (!capable(CAP_SYS_ADMIN)) {
1264 if ((newinfo.close_delay != port->port.close_delay) ||
1265 (newinfo.closing_wait != port->port.closing_wait) ||
1266 ((newinfo.flags & ~ASYNC_USR_MASK) !=
1267 (port->port.flags & ~ASYNC_USR_MASK))) {
1271 port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1272 (newinfo.flags & ASYNC_USR_MASK));
1274 port->port.close_delay = newinfo.close_delay;
1275 port->port.closing_wait = newinfo.closing_wait;
1276 port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1277 (newinfo.flags & ASYNC_FLAGS));
1279 if (reconfig_port) {
1280 unsigned long flags;
1281 spin_lock_irqsave(&port->card->card_lock, flags);
1282 isicom_config_port(tty);
1283 spin_unlock_irqrestore(&port->card->card_lock, flags);
1289 static int isicom_get_serial_info(struct isi_port *port,
1290 struct serial_struct __user *info)
1292 struct serial_struct out_info;
1295 memset(&out_info, 0, sizeof(out_info));
1296 /* out_info.type = ? */
1297 out_info.line = port - isi_ports;
1298 out_info.port = port->card->base;
1299 out_info.irq = port->card->irq;
1300 out_info.flags = port->port.flags;
1301 /* out_info.baud_base = ? */
1302 out_info.close_delay = port->port.close_delay;
1303 out_info.closing_wait = port->port.closing_wait;
1305 if (copy_to_user(info, &out_info, sizeof(out_info)))
1310 static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1311 unsigned int cmd, unsigned long arg)
1313 struct isi_port *port = tty->driver_data;
1314 void __user *argp = (void __user *)arg;
1316 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1321 return isicom_get_serial_info(port, argp);
1324 return isicom_set_serial_info(tty, argp);
1327 return -ENOIOCTLCMD;
1332 /* set_termios et all */
1333 static void isicom_set_termios(struct tty_struct *tty,
1334 struct ktermios *old_termios)
1336 struct isi_port *port = tty->driver_data;
1337 unsigned long flags;
1339 if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
1342 if (tty->termios->c_cflag == old_termios->c_cflag &&
1343 tty->termios->c_iflag == old_termios->c_iflag)
1346 spin_lock_irqsave(&port->card->card_lock, flags);
1347 isicom_config_port(tty);
1348 spin_unlock_irqrestore(&port->card->card_lock, flags);
1350 if ((old_termios->c_cflag & CRTSCTS) &&
1351 !(tty->termios->c_cflag & CRTSCTS)) {
1352 tty->hw_stopped = 0;
1357 /* throttle et all */
1358 static void isicom_throttle(struct tty_struct *tty)
1360 struct isi_port *port = tty->driver_data;
1361 struct isi_board *card = port->card;
1363 if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
1366 /* tell the card that this port cannot handle any more data for now */
1367 card->port_status &= ~(1 << port->channel);
1368 outw(card->port_status, card->base + 0x02);
1371 /* unthrottle et all */
1372 static void isicom_unthrottle(struct tty_struct *tty)
1374 struct isi_port *port = tty->driver_data;
1375 struct isi_board *card = port->card;
1377 if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
1380 /* tell the card that this port is ready to accept more data */
1381 card->port_status |= (1 << port->channel);
1382 outw(card->port_status, card->base + 0x02);
1386 static void isicom_stop(struct tty_struct *tty)
1388 struct isi_port *port = tty->driver_data;
1390 if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
1393 /* this tells the transmitter not to consider this port for
1394 data output to the card. */
1395 port->status &= ~ISI_TXOK;
1399 static void isicom_start(struct tty_struct *tty)
1401 struct isi_port *port = tty->driver_data;
1403 if (isicom_paranoia_check(port, tty->name, "isicom_start"))
1406 /* this tells the transmitter to consider this port for
1407 data output to the card. */
1408 port->status |= ISI_TXOK;
1411 static void isicom_hangup(struct tty_struct *tty)
1413 struct isi_port *port = tty->driver_data;
1414 unsigned long flags;
1416 if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
1419 spin_lock_irqsave(&port->card->card_lock, flags);
1420 isicom_shutdown_port(port);
1421 spin_unlock_irqrestore(&port->card->card_lock, flags);
1423 port->port.count = 0;
1424 port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1425 tty_port_tty_set(&port->port, NULL);
1426 wake_up_interruptible(&port->port.open_wait);
1431 * Driver init and deinit functions
1434 static const struct tty_operations isicom_ops = {
1435 .open = isicom_open,
1436 .close = isicom_close,
1437 .write = isicom_write,
1438 .put_char = isicom_put_char,
1439 .flush_chars = isicom_flush_chars,
1440 .write_room = isicom_write_room,
1441 .chars_in_buffer = isicom_chars_in_buffer,
1442 .ioctl = isicom_ioctl,
1443 .set_termios = isicom_set_termios,
1444 .throttle = isicom_throttle,
1445 .unthrottle = isicom_unthrottle,
1446 .stop = isicom_stop,
1447 .start = isicom_start,
1448 .hangup = isicom_hangup,
1449 .flush_buffer = isicom_flush_buffer,
1450 .tiocmget = isicom_tiocmget,
1451 .tiocmset = isicom_tiocmset,
1452 .break_ctl = isicom_send_break,
1455 static int __devinit reset_card(struct pci_dev *pdev,
1456 const unsigned int card, unsigned int *signature)
1458 struct isi_board *board = pci_get_drvdata(pdev);
1459 unsigned long base = board->base;
1460 unsigned int sig, portcount = 0;
1463 dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
1470 outw(0, base + 0x8); /* Reset */
1474 sig = inw(base + 0x4) & 0xff;
1476 if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd &&
1478 dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible "
1479 "bad I/O Port Address 0x%lx).\n", card + 1, base);
1480 dev_dbg(&pdev->dev, "Sig=0x%x\n", sig);
1487 portcount = inw(base + 0x2);
1488 if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 &&
1489 portcount != 8 && portcount != 16)) {
1490 dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
1500 board->port_count = (portcount == 4) ? 4 : 8;
1501 board->shift_count = 12;
1505 board->port_count = 16;
1506 board->shift_count = 11;
1509 dev_info(&pdev->dev, "-Done\n");
1516 static int __devinit load_firmware(struct pci_dev *pdev,
1517 const unsigned int index, const unsigned int signature)
1519 struct isi_board *board = pci_get_drvdata(pdev);
1520 const struct firmware *fw;
1521 unsigned long base = board->base;
1523 u16 word_count, status;
1534 switch (signature) {
1536 name = "isi608.bin";
1539 name = "isi608em.bin";
1542 name = "isi616em.bin";
1545 name = "isi4608.bin";
1548 name = "isi4616.bin";
1551 dev_err(&pdev->dev, "Unknown signature.\n");
1555 retval = request_firmware(&fw, name, &pdev->dev);
1561 for (frame = (struct stframe *)fw->data;
1562 frame < (struct stframe *)(fw->data + fw->size);
1563 frame = (struct stframe *)((u8 *)(frame + 1) +
1565 if (WaitTillCardIsFree(base))
1568 outw(0xf0, base); /* start upload sequence */
1570 outw(frame->addr, base); /* lsb of address */
1572 word_count = frame->count / 2 + frame->count % 2;
1573 outw(word_count, base);
1574 InterruptTheCard(base);
1576 udelay(100); /* 0x2f */
1578 if (WaitTillCardIsFree(base))
1581 status = inw(base + 0x4);
1583 dev_warn(&pdev->dev, "Card%d rejected load header:\n"
1584 KERN_WARNING "Address:0x%x\n"
1585 KERN_WARNING "Count:0x%x\n"
1586 KERN_WARNING "Status:0x%x\n",
1587 index + 1, frame->addr, frame->count, status);
1590 outsw(base, frame->data, word_count);
1592 InterruptTheCard(base);
1594 udelay(50); /* 0x0f */
1596 if (WaitTillCardIsFree(base))
1599 status = inw(base + 0x4);
1601 dev_err(&pdev->dev, "Card%d got out of sync.Card "
1602 "Status:0x%x\n", index + 1, status);
1607 /* XXX: should we test it by reading it back and comparing with original like
1608 * in load firmware package? */
1609 for (frame = (struct stframe *)fw->data;
1610 frame < (struct stframe *)(fw->data + fw->size);
1611 frame = (struct stframe *)((u8 *)(frame + 1) +
1613 if (WaitTillCardIsFree(base))
1616 outw(0xf1, base); /* start download sequence */
1618 outw(frame->addr, base); /* lsb of address */
1620 word_count = (frame->count >> 1) + frame->count % 2;
1621 outw(word_count + 1, base);
1622 InterruptTheCard(base);
1624 udelay(50); /* 0xf */
1626 if (WaitTillCardIsFree(base))
1629 status = inw(base + 0x4);
1631 dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
1632 KERN_WARNING "Address:0x%x\n"
1633 KERN_WARNING "Count:0x%x\n"
1634 KERN_WARNING "Status: 0x%x\n",
1635 index + 1, frame->addr, frame->count, status);
1639 data = kmalloc(word_count * 2, GFP_KERNEL);
1641 dev_err(&pdev->dev, "Card%d, firmware upload "
1642 "failed, not enough memory\n", index + 1);
1646 insw(base, data, word_count);
1647 InterruptTheCard(base);
1649 for (a = 0; a < frame->count; a++)
1650 if (data[a] != frame->data[a]) {
1652 dev_err(&pdev->dev, "Card%d, firmware upload "
1653 "failed\n", index + 1);
1658 udelay(50); /* 0xf */
1660 if (WaitTillCardIsFree(base))
1663 status = inw(base + 0x4);
1665 dev_err(&pdev->dev, "Card%d verify got out of sync. "
1666 "Card Status:0x%x\n", index + 1, status);
1672 if (WaitTillCardIsFree(base))
1679 InterruptTheCard(base);
1680 outw(0x0, base + 0x4); /* for ISI4608 cards */
1682 board->status |= FIRMWARE_LOADED;
1686 release_firmware(fw);
1692 * Insmod can set static symbols so keep these static
1694 static unsigned int card_count;
1696 static int __devinit isicom_probe(struct pci_dev *pdev,
1697 const struct pci_device_id *ent)
1699 unsigned int signature, index;
1700 int retval = -EPERM;
1701 struct isi_board *board = NULL;
1703 if (card_count >= BOARD_COUNT)
1706 retval = pci_enable_device(pdev);
1708 dev_err(&pdev->dev, "failed to enable\n");
1712 dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
1714 /* allot the first empty slot in the array */
1715 for (index = 0; index < BOARD_COUNT; index++)
1716 if (isi_card[index].base == 0) {
1717 board = &isi_card[index];
1721 board->index = index;
1722 board->base = pci_resource_start(pdev, 3);
1723 board->irq = pdev->irq;
1726 pci_set_drvdata(pdev, board);
1728 retval = pci_request_region(pdev, 3, ISICOM_NAME);
1730 dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
1731 "will be disabled.\n", board->base, board->base + 15,
1737 retval = request_irq(board->irq, isicom_interrupt,
1738 IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
1740 dev_err(&pdev->dev, "Could not install handler at Irq %d. "
1741 "Card%d will be disabled.\n", board->irq, index + 1);
1745 retval = reset_card(pdev, index, &signature);
1749 retval = load_firmware(pdev, index, signature);
1753 for (index = 0; index < board->port_count; index++)
1754 tty_register_device(isicom_normal, board->index * 16 + index,
1760 free_irq(board->irq, board);
1762 pci_release_region(pdev, 3);
1766 pci_disable_device(pdev);
1771 static void __devexit isicom_remove(struct pci_dev *pdev)
1773 struct isi_board *board = pci_get_drvdata(pdev);
1776 for (i = 0; i < board->port_count; i++)
1777 tty_unregister_device(isicom_normal, board->index * 16 + i);
1779 free_irq(board->irq, board);
1780 pci_release_region(pdev, 3);
1783 pci_disable_device(pdev);
1786 static int __init isicom_init(void)
1788 int retval, idx, channel;
1789 struct isi_port *port;
1791 for (idx = 0; idx < BOARD_COUNT; idx++) {
1792 port = &isi_ports[idx * 16];
1793 isi_card[idx].ports = port;
1794 spin_lock_init(&isi_card[idx].card_lock);
1795 for (channel = 0; channel < 16; channel++, port++) {
1796 tty_port_init(&port->port);
1797 port->magic = ISICOM_MAGIC;
1798 port->card = &isi_card[idx];
1799 port->channel = channel;
1800 port->port.close_delay = 50 * HZ/100;
1801 port->port.closing_wait = 3000 * HZ/100;
1805 isi_card[idx].base = 0;
1806 isi_card[idx].irq = 0;
1809 /* tty driver structure initialization */
1810 isicom_normal = alloc_tty_driver(PORT_COUNT);
1811 if (!isicom_normal) {
1816 isicom_normal->owner = THIS_MODULE;
1817 isicom_normal->name = "ttyM";
1818 isicom_normal->major = ISICOM_NMAJOR;
1819 isicom_normal->minor_start = 0;
1820 isicom_normal->type = TTY_DRIVER_TYPE_SERIAL;
1821 isicom_normal->subtype = SERIAL_TYPE_NORMAL;
1822 isicom_normal->init_termios = tty_std_termios;
1823 isicom_normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
1825 isicom_normal->flags = TTY_DRIVER_REAL_RAW |
1826 TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK;
1827 tty_set_operations(isicom_normal, &isicom_ops);
1829 retval = tty_register_driver(isicom_normal);
1831 pr_dbg("Couldn't register the dialin driver\n");
1835 retval = pci_register_driver(&isicom_driver);
1837 printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
1841 mod_timer(&tx, jiffies + 1);
1845 tty_unregister_driver(isicom_normal);
1847 put_tty_driver(isicom_normal);
1852 static void __exit isicom_exit(void)
1854 del_timer_sync(&tx);
1856 pci_unregister_driver(&isicom_driver);
1857 tty_unregister_driver(isicom_normal);
1858 put_tty_driver(isicom_normal);
1861 module_init(isicom_init);
1862 module_exit(isicom_exit);
1864 MODULE_AUTHOR("MultiTech");
1865 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
1866 MODULE_LICENSE("GPL");