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 <asm/uaccess.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)
141 #define pr_dbg(str...) printk(KERN_DEBUG "ISICOM: " str)
142 #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c))
144 #define pr_dbg(str...) do { } while (0)
145 #define isicom_paranoia_check(a, b, c) 0
148 static int isicom_probe(struct pci_dev *, const struct pci_device_id *);
149 static void __devexit isicom_remove(struct pci_dev *);
151 static struct pci_device_id isicom_pci_tbl[] = {
152 { PCI_DEVICE(VENDOR_ID, 0x2028) },
153 { PCI_DEVICE(VENDOR_ID, 0x2051) },
154 { PCI_DEVICE(VENDOR_ID, 0x2052) },
155 { PCI_DEVICE(VENDOR_ID, 0x2053) },
156 { PCI_DEVICE(VENDOR_ID, 0x2054) },
157 { PCI_DEVICE(VENDOR_ID, 0x2055) },
158 { PCI_DEVICE(VENDOR_ID, 0x2056) },
159 { PCI_DEVICE(VENDOR_ID, 0x2057) },
160 { PCI_DEVICE(VENDOR_ID, 0x2058) },
163 MODULE_DEVICE_TABLE(pci, isicom_pci_tbl);
165 static struct pci_driver isicom_driver = {
167 .id_table = isicom_pci_tbl,
168 .probe = isicom_probe,
169 .remove = __devexit_p(isicom_remove)
172 static int prev_card = 3; /* start servicing isi_card[0] */
173 static struct tty_driver *isicom_normal;
175 static struct timer_list tx;
176 static char re_schedule = 1;
178 static void isicom_tx(unsigned long _data);
179 static void isicom_start(struct tty_struct *tty);
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
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 */
201 unsigned short magic;
209 struct isi_board * card;
210 struct tty_struct * tty;
211 wait_queue_head_t close_wait;
212 wait_queue_head_t open_wait;
213 struct work_struct hangup_tq;
214 struct work_struct bh_tqueue;
215 unsigned char * xmit_buf;
221 static struct isi_board isi_card[BOARD_COUNT];
222 static struct isi_port isi_ports[PORT_COUNT];
225 * Locking functions for card level locking. We need to own both
226 * the kernel lock for the card and have the card in a position that
230 static int lock_card(struct isi_board *card)
233 unsigned long base = card->base;
235 for (retries = 0; retries < 100; retries++) {
236 spin_lock_irqsave(&card->card_lock, card->flags);
237 if (inw(base + 0xe) & 0x1) {
240 spin_unlock_irqrestore(&card->card_lock, card->flags);
241 udelay(1000); /* 1ms */
244 printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%lx)\n",
247 return 0; /* Failed to acquire the card! */
250 static int lock_card_at_interrupt(struct isi_board *card)
252 unsigned char retries;
253 unsigned long base = card->base;
255 for (retries = 0; retries < 200; retries++) {
256 spin_lock_irqsave(&card->card_lock, card->flags);
258 if (inw(base + 0xe) & 0x1)
261 spin_unlock_irqrestore(&card->card_lock, card->flags);
263 /* Failing in interrupt is an acceptable event */
264 return 0; /* Failed to acquire the card! */
267 static void unlock_card(struct isi_board *card)
269 spin_unlock_irqrestore(&card->card_lock, card->flags);
273 * ISI Card specific ops ...
276 static void raise_dtr(struct isi_port *port)
278 struct isi_board *card = port->card;
279 unsigned long base = card->base;
280 u16 channel = port->channel;
282 if (!lock_card(card))
285 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
287 InterruptTheCard(base);
288 port->status |= ISI_DTR;
292 static inline void drop_dtr(struct isi_port *port)
294 struct isi_board *card = port->card;
295 unsigned long base = card->base;
296 u16 channel = port->channel;
298 if (!lock_card(card))
301 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
303 InterruptTheCard(base);
304 port->status &= ~ISI_DTR;
308 static inline void raise_rts(struct isi_port *port)
310 struct isi_board *card = port->card;
311 unsigned long base = card->base;
312 u16 channel = port->channel;
314 if (!lock_card(card))
317 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
319 InterruptTheCard(base);
320 port->status |= ISI_RTS;
323 static inline void drop_rts(struct isi_port *port)
325 struct isi_board *card = port->card;
326 unsigned long base = card->base;
327 u16 channel = port->channel;
329 if (!lock_card(card))
332 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
334 InterruptTheCard(base);
335 port->status &= ~ISI_RTS;
339 static inline void raise_dtr_rts(struct isi_port *port)
341 struct isi_board *card = port->card;
342 unsigned long base = card->base;
343 u16 channel = port->channel;
345 if (!lock_card(card))
348 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
350 InterruptTheCard(base);
351 port->status |= (ISI_DTR | ISI_RTS);
355 static void drop_dtr_rts(struct isi_port *port)
357 struct isi_board *card = port->card;
358 unsigned long base = card->base;
359 u16 channel = port->channel;
361 if (!lock_card(card))
364 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
366 InterruptTheCard(base);
367 port->status &= ~(ISI_RTS | ISI_DTR);
371 static inline void kill_queue(struct isi_port *port, short queue)
373 struct isi_board *card = port->card;
374 unsigned long base = card->base;
375 u16 channel = port->channel;
377 if (!lock_card(card))
380 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
381 outw((queue << 8) | 0x06, base);
382 InterruptTheCard(base);
387 * ISICOM Driver specific routines ...
391 static inline int __isicom_paranoia_check(struct isi_port const *port,
392 char *name, const char *routine)
395 printk(KERN_WARNING "ISICOM: Warning: bad isicom magic for "
396 "dev %s in %s.\n", name, routine);
399 if (port->magic != ISICOM_MAGIC) {
400 printk(KERN_WARNING "ISICOM: Warning: NULL isicom port for "
401 "dev %s in %s.\n", name, routine);
411 * We shovel data into the card buffers on a regular basis. The card
412 * will do the rest of the work for us.
415 static void isicom_tx(unsigned long _data)
417 short count = (BOARD_COUNT-1), card, base;
418 short txcount, wrd, residue, word_count, cnt;
419 struct isi_port *port;
420 struct tty_struct *tty;
422 /* find next active board */
423 card = (prev_card + 1) & 0x0003;
425 if (isi_card[card].status & BOARD_ACTIVE)
427 card = (card + 1) & 0x0003;
429 if (!(isi_card[card].status & BOARD_ACTIVE))
434 count = isi_card[card].port_count;
435 port = isi_card[card].ports;
436 base = isi_card[card].base;
437 for (;count > 0;count--, port++) {
438 if (!lock_card_at_interrupt(&isi_card[card]))
440 /* port not active or tx disabled to force flow control */
441 if (!(port->flags & ASYNC_INITIALIZED) ||
442 !(port->status & ISI_TXOK))
443 unlock_card(&isi_card[card]);
450 unlock_card(&isi_card[card]);
454 txcount = min_t(short, TX_SIZE, port->xmit_cnt);
455 if (txcount <= 0 || tty->stopped || tty->hw_stopped) {
456 unlock_card(&isi_card[card]);
459 if (!(inw(base + 0x02) & (1 << port->channel))) {
460 unlock_card(&isi_card[card]);
463 pr_dbg("txing %d bytes, port%d.\n", txcount,
465 outw((port->channel << isi_card[card].shift_count) | txcount,
470 cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE
472 if (residue == YES) {
475 wrd |= (port->xmit_buf[port->xmit_tail]
477 port->xmit_tail = (port->xmit_tail + 1)
478 & (SERIAL_XMIT_SIZE - 1);
489 word_count = cnt >> 1;
490 outsw(base, port->xmit_buf+port->xmit_tail,word_count);
491 port->xmit_tail = (port->xmit_tail
492 + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
493 txcount -= (word_count << 1);
494 port->xmit_cnt -= (word_count << 1);
497 wrd = port->xmit_buf[port->xmit_tail];
498 port->xmit_tail = (port->xmit_tail + 1)
499 & (SERIAL_XMIT_SIZE - 1);
505 InterruptTheCard(base);
506 if (port->xmit_cnt <= 0)
507 port->status &= ~ISI_TXOK;
508 if (port->xmit_cnt <= WAKEUP_CHARS)
509 schedule_work(&port->bh_tqueue);
510 unlock_card(&isi_card[card]);
513 /* schedule another tx for hopefully in about 10ms */
521 tx.expires = jiffies + HZ/100;
523 tx.function = isicom_tx;
529 /* Interrupt handlers */
532 static void isicom_bottomhalf(struct work_struct *work)
534 struct isi_port *port = container_of(work, struct isi_port, bh_tqueue);
535 struct tty_struct *tty = port->tty;
541 wake_up_interruptible(&tty->write_wait);
545 * Main interrupt handler routine
548 static irqreturn_t isicom_interrupt(int irq, void *dev_id)
550 struct isi_board *card = dev_id;
551 struct isi_port *port;
552 struct tty_struct *tty;
554 u16 header, word_count, count, channel;
558 if (!card || !(card->status & FIRMWARE_LOADED))
562 spin_lock(&card->card_lock);
565 * disable any interrupts from the PCI card and lower the
568 outw(0x8000, base+0x04);
569 ClearInterrupt(base);
571 inw(base); /* get the dummy word out */
573 channel = (header & 0x7800) >> card->shift_count;
574 byte_count = header & 0xff;
576 if (channel + 1 > card->port_count) {
577 printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): "
578 "%d(channel) > port_count.\n", base, channel+1);
579 outw(0x0000, base+0x04); /* enable interrupts */
580 spin_unlock(&card->card_lock);
583 port = card->ports + channel;
584 if (!(port->flags & ASYNC_INITIALIZED)) {
585 outw(0x0000, base+0x04); /* enable interrupts */
591 word_count = byte_count >> 1;
592 while(byte_count > 1) {
596 if (byte_count & 0x01)
598 outw(0x0000, base+0x04); /* enable interrupts */
599 spin_unlock(&card->card_lock);
603 if (header & 0x8000) { /* Status Packet */
605 switch(header & 0xff) {
606 case 0: /* Change in EIA signals */
607 if (port->flags & ASYNC_CHECK_CD) {
608 if (port->status & ISI_DCD) {
609 if (!(header & ISI_DCD)) {
610 /* Carrier has been lost */
611 pr_dbg("interrupt: DCD->low.\n"
613 port->status &= ~ISI_DCD;
614 schedule_work(&port->hangup_tq);
616 } else if (header & ISI_DCD) {
617 /* Carrier has been detected */
618 pr_dbg("interrupt: DCD->high.\n");
619 port->status |= ISI_DCD;
620 wake_up_interruptible(&port->open_wait);
623 if (header & ISI_DCD)
624 port->status |= ISI_DCD;
626 port->status &= ~ISI_DCD;
629 if (port->flags & ASYNC_CTS_FLOW) {
630 if (port->tty->hw_stopped) {
631 if (header & ISI_CTS) {
632 port->tty->hw_stopped = 0;
634 port->status |= (ISI_TXOK
636 schedule_work(&port->bh_tqueue);
638 } else if (!(header & ISI_CTS)) {
639 port->tty->hw_stopped = 1;
641 port->status &= ~(ISI_TXOK | ISI_CTS);
644 if (header & ISI_CTS)
645 port->status |= ISI_CTS;
647 port->status &= ~ISI_CTS;
650 if (header & ISI_DSR)
651 port->status |= ISI_DSR;
653 port->status &= ~ISI_DSR;
656 port->status |= ISI_RI;
658 port->status &= ~ISI_RI;
662 case 1: /* Received Break !!! */
663 tty_insert_flip_char(tty, 0, TTY_BREAK);
664 if (port->flags & ASYNC_SAK)
666 tty_flip_buffer_push(tty);
669 case 2: /* Statistics */
670 pr_dbg("isicom_interrupt: stats!!!.\n");
674 pr_dbg("Intr: Unknown code in status packet.\n");
677 } else { /* Data Packet */
679 count = tty_prepare_flip_string(tty, &rp, byte_count & ~1);
680 pr_dbg("Intr: Can rx %d of %d bytes.\n", count, byte_count);
681 word_count = count >> 1;
682 insw(base, rp, word_count);
683 byte_count -= (word_count << 1);
684 if (count & 0x0001) {
685 tty_insert_flip_char(tty, inw(base) & 0xff,
689 if (byte_count > 0) {
690 pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping "
691 "bytes...\n", base, channel + 1);
692 while(byte_count > 0) { /* drain out unread xtra data */
697 tty_flip_buffer_push(tty);
699 outw(0x0000, base+0x04); /* enable interrupts */
704 static void isicom_config_port(struct isi_port *port)
706 struct isi_board *card = port->card;
707 struct tty_struct *tty;
709 unsigned long base = card->base;
710 u16 channel_setup, channel = port->channel,
711 shift_count = card->shift_count;
712 unsigned char flow_ctrl;
714 if (!(tty = port->tty) || !tty->termios)
717 if (baud & CBAUDEX) {
720 /* if CBAUDEX bit is on and the baud is set to either 50 or 75
721 * then the card is programmed for 57.6Kbps or 115Kbps
725 if (baud < 1 || baud > 2)
726 port->tty->termios->c_cflag &= ~CBAUDEX;
732 /* the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set
733 * by the set_serial_info ioctl ... this is done by
734 * the 'setserial' utility.
737 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
738 baud++; /* 57.6 Kbps */
739 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
740 baud +=2; /* 115 Kbps */
742 if (linuxb_to_isib[baud] == -1) {
750 if (lock_card(card)) {
751 outw(0x8000 | (channel << shift_count) |0x03, base);
752 outw(linuxb_to_isib[baud] << 8 | 0x03, base);
754 switch(C_CSIZE(tty)) {
756 channel_setup |= ISICOM_CS5;
759 channel_setup |= ISICOM_CS6;
762 channel_setup |= ISICOM_CS7;
765 channel_setup |= ISICOM_CS8;
770 channel_setup |= ISICOM_2SB;
772 channel_setup |= ISICOM_EVPAR;
774 channel_setup |= ISICOM_ODPAR;
776 outw(channel_setup, base);
777 InterruptTheCard(base);
781 port->flags &= ~ASYNC_CHECK_CD;
783 port->flags |= ASYNC_CHECK_CD;
785 /* flow control settings ...*/
787 port->flags &= ~ASYNC_CTS_FLOW;
788 if (C_CRTSCTS(tty)) {
789 port->flags |= ASYNC_CTS_FLOW;
790 flow_ctrl |= ISICOM_CTSRTS;
793 flow_ctrl |= ISICOM_RESPOND_XONXOFF;
795 flow_ctrl |= ISICOM_INITIATE_XONXOFF;
797 if (lock_card(card)) {
798 outw(0x8000 | (channel << shift_count) |0x04, base);
799 outw(flow_ctrl << 8 | 0x05, base);
800 outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
801 InterruptTheCard(base);
805 /* rx enabled -> enable port for rx on the card */
807 card->port_status |= (1 << channel);
808 outw(card->port_status, base + 0x02);
814 static inline void isicom_setup_board(struct isi_board *bp)
817 struct isi_port *port;
820 spin_lock_irqsave(&bp->card_lock, flags);
821 if (bp->status & BOARD_ACTIVE) {
822 spin_unlock_irqrestore(&bp->card_lock, flags);
826 bp->status |= BOARD_ACTIVE;
827 spin_unlock_irqrestore(&bp->card_lock, flags);
828 for (channel = 0; channel < bp->port_count; channel++, port++)
833 static int isicom_setup_port(struct isi_port *port)
835 struct isi_board *card = port->card;
838 if (port->flags & ASYNC_INITIALIZED) {
841 if (!port->xmit_buf) {
844 if (!(page = get_zeroed_page(GFP_KERNEL)))
847 if (port->xmit_buf) {
851 port->xmit_buf = (unsigned char *) page;
854 spin_lock_irqsave(&card->card_lock, flags);
856 clear_bit(TTY_IO_ERROR, &port->tty->flags);
857 if (port->count == 1)
860 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
862 /* discard any residual data */
863 kill_queue(port, ISICOM_KILLTX | ISICOM_KILLRX);
865 isicom_config_port(port);
866 port->flags |= ASYNC_INITIALIZED;
867 spin_unlock_irqrestore(&card->card_lock, flags);
872 static int block_til_ready(struct tty_struct *tty, struct file *filp,
873 struct isi_port *port)
875 struct isi_board *card = port->card;
876 int do_clocal = 0, retval;
878 DECLARE_WAITQUEUE(wait, current);
880 /* block if port is in the process of being closed */
882 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
883 pr_dbg("block_til_ready: close in progress.\n");
884 interruptible_sleep_on(&port->close_wait);
885 if (port->flags & ASYNC_HUP_NOTIFY)
891 /* if non-blocking mode is set ... */
893 if ((filp->f_flags & O_NONBLOCK) ||
894 (tty->flags & (1 << TTY_IO_ERROR))) {
895 pr_dbg("block_til_ready: non-block mode.\n");
896 port->flags |= ASYNC_NORMAL_ACTIVE;
903 /* block waiting for DCD to be asserted, and while
904 callout dev is busy */
906 add_wait_queue(&port->open_wait, &wait);
908 spin_lock_irqsave(&card->card_lock, flags);
909 if (!tty_hung_up_p(filp))
911 port->blocked_open++;
912 spin_unlock_irqrestore(&card->card_lock, flags);
917 set_current_state(TASK_INTERRUPTIBLE);
918 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
919 if (port->flags & ASYNC_HUP_NOTIFY)
922 retval = -ERESTARTSYS;
925 if (!(port->flags & ASYNC_CLOSING) &&
926 (do_clocal || (port->status & ISI_DCD))) {
929 if (signal_pending(current)) {
930 retval = -ERESTARTSYS;
935 set_current_state(TASK_RUNNING);
936 remove_wait_queue(&port->open_wait, &wait);
937 spin_lock_irqsave(&card->card_lock, flags);
938 if (!tty_hung_up_p(filp))
940 port->blocked_open--;
941 spin_unlock_irqrestore(&card->card_lock, flags);
944 port->flags |= ASYNC_NORMAL_ACTIVE;
948 static int isicom_open(struct tty_struct *tty, struct file *filp)
950 struct isi_port *port;
951 struct isi_board *card;
952 unsigned int line, board;
956 if (line < 0 || line > PORT_COUNT-1)
959 card = &isi_card[board];
961 if (!(card->status & FIRMWARE_LOADED))
964 /* open on a port greater than the port count for the card !!! */
965 if (line > ((board * 16) + card->port_count - 1))
968 port = &isi_ports[line];
969 if (isicom_paranoia_check(port, tty->name, "isicom_open"))
972 isicom_setup_board(card);
975 tty->driver_data = port;
977 if ((error = isicom_setup_port(port))!=0)
979 if ((error = block_til_ready(tty, filp, port))!=0)
987 static inline void isicom_shutdown_board(struct isi_board *bp)
991 spin_lock_irqsave(&bp->card_lock, flags);
992 if (bp->status & BOARD_ACTIVE) {
993 bp->status &= ~BOARD_ACTIVE;
995 spin_unlock_irqrestore(&bp->card_lock, flags);
998 static void isicom_shutdown_port(struct isi_port *port)
1000 struct isi_board *card = port->card;
1001 struct tty_struct *tty;
1002 unsigned long flags;
1006 spin_lock_irqsave(&card->card_lock, flags);
1007 if (!(port->flags & ASYNC_INITIALIZED)) {
1008 spin_unlock_irqrestore(&card->card_lock, flags);
1011 if (port->xmit_buf) {
1012 free_page((unsigned long) port->xmit_buf);
1013 port->xmit_buf = NULL;
1015 port->flags &= ~ASYNC_INITIALIZED;
1016 /* 3rd October 2000 : Vinayak P Risbud */
1018 spin_unlock_irqrestore(&card->card_lock, flags);
1020 /*Fix done by Anil .S on 30-04-2001
1021 remote login through isi port has dtr toggle problem
1022 due to which the carrier drops before the password prompt
1023 appears on the remote end. Now we drop the dtr only if the
1024 HUPCL(Hangup on close) flag is set for the tty*/
1027 /* drop dtr on this port */
1030 /* any other port uninits */
1032 set_bit(TTY_IO_ERROR, &tty->flags);
1034 if (--card->count < 0) {
1035 pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n",
1036 card->base, card->count);
1040 /* last port was closed, shutdown that boad too */
1043 isicom_shutdown_board(card);
1047 static void isicom_close(struct tty_struct *tty, struct file *filp)
1049 struct isi_port *port = tty->driver_data;
1050 struct isi_board *card;
1051 unsigned long flags;
1056 if (isicom_paranoia_check(port, tty->name, "isicom_close"))
1059 pr_dbg("Close start!!!.\n");
1061 spin_lock_irqsave(&card->card_lock, flags);
1062 if (tty_hung_up_p(filp)) {
1063 spin_unlock_irqrestore(&card->card_lock, flags);
1067 if (tty->count == 1 && port->count != 1) {
1068 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1069 "count tty->count = 1 port count = %d.\n",
1070 card->base, port->count);
1073 if (--port->count < 0) {
1074 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1075 "count for channel%d = %d", card->base, port->channel,
1081 spin_unlock_irqrestore(&card->card_lock, flags);
1084 port->flags |= ASYNC_CLOSING;
1086 spin_unlock_irqrestore(&card->card_lock, flags);
1088 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1089 tty_wait_until_sent(tty, port->closing_wait);
1090 /* indicate to the card that no more data can be received
1092 spin_lock_irqsave(&card->card_lock, flags);
1093 if (port->flags & ASYNC_INITIALIZED) {
1094 card->port_status &= ~(1 << port->channel);
1095 outw(card->port_status, card->base + 0x02);
1097 isicom_shutdown_port(port);
1098 spin_unlock_irqrestore(&card->card_lock, flags);
1100 if (tty->driver->flush_buffer)
1101 tty->driver->flush_buffer(tty);
1102 tty_ldisc_flush(tty);
1104 spin_lock_irqsave(&card->card_lock, flags);
1107 if (port->blocked_open) {
1108 spin_unlock_irqrestore(&card->card_lock, flags);
1109 if (port->close_delay) {
1110 pr_dbg("scheduling until time out.\n");
1111 msleep_interruptible(
1112 jiffies_to_msecs(port->close_delay));
1114 spin_lock_irqsave(&card->card_lock, flags);
1115 wake_up_interruptible(&port->open_wait);
1117 port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1118 wake_up_interruptible(&port->close_wait);
1119 spin_unlock_irqrestore(&card->card_lock, flags);
1123 static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
1126 struct isi_port *port = tty->driver_data;
1127 struct isi_board *card = port->card;
1128 unsigned long flags;
1131 if (isicom_paranoia_check(port, tty->name, "isicom_write"))
1134 if (!port->xmit_buf)
1137 spin_lock_irqsave(&card->card_lock, flags);
1140 cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
1141 - 1, SERIAL_XMIT_SIZE - port->xmit_head));
1145 memcpy(port->xmit_buf + port->xmit_head, buf, cnt);
1146 port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
1148 port->xmit_cnt += cnt;
1153 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped)
1154 port->status |= ISI_TXOK;
1155 spin_unlock_irqrestore(&card->card_lock, flags);
1159 /* put_char et all */
1160 static void isicom_put_char(struct tty_struct *tty, unsigned char ch)
1162 struct isi_port *port = tty->driver_data;
1163 struct isi_board *card = port->card;
1164 unsigned long flags;
1166 if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
1169 if (!port->xmit_buf)
1172 spin_lock_irqsave(&card->card_lock, flags);
1173 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
1174 spin_unlock_irqrestore(&card->card_lock, flags);
1178 port->xmit_buf[port->xmit_head++] = ch;
1179 port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
1181 spin_unlock_irqrestore(&card->card_lock, flags);
1184 /* flush_chars et all */
1185 static void isicom_flush_chars(struct tty_struct *tty)
1187 struct isi_port *port = tty->driver_data;
1189 if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars"))
1192 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1196 /* this tells the transmitter to consider this port for
1197 data output to the card ... that's the best we can do. */
1198 port->status |= ISI_TXOK;
1201 /* write_room et all */
1202 static int isicom_write_room(struct tty_struct *tty)
1204 struct isi_port *port = tty->driver_data;
1207 if (isicom_paranoia_check(port, tty->name, "isicom_write_room"))
1210 free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1216 /* chars_in_buffer et all */
1217 static int isicom_chars_in_buffer(struct tty_struct *tty)
1219 struct isi_port *port = tty->driver_data;
1220 if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer"))
1222 return port->xmit_cnt;
1226 static inline void isicom_send_break(struct isi_port *port,
1227 unsigned long length)
1229 struct isi_board *card = port->card;
1230 unsigned long base = card->base;
1232 if (!lock_card(card))
1235 outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
1236 outw((length & 0xff) << 8 | 0x00, base);
1237 outw((length & 0xff00), base);
1238 InterruptTheCard(base);
1243 static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
1245 struct isi_port *port = tty->driver_data;
1246 /* just send the port status */
1247 u16 status = port->status;
1249 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1252 return ((status & ISI_RTS) ? TIOCM_RTS : 0) |
1253 ((status & ISI_DTR) ? TIOCM_DTR : 0) |
1254 ((status & ISI_DCD) ? TIOCM_CAR : 0) |
1255 ((status & ISI_DSR) ? TIOCM_DSR : 0) |
1256 ((status & ISI_CTS) ? TIOCM_CTS : 0) |
1257 ((status & ISI_RI ) ? TIOCM_RI : 0);
1260 static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
1261 unsigned int set, unsigned int clear)
1263 struct isi_port *port = tty->driver_data;
1265 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1268 if (set & TIOCM_RTS)
1270 if (set & TIOCM_DTR)
1273 if (clear & TIOCM_RTS)
1275 if (clear & TIOCM_DTR)
1281 static int isicom_set_serial_info(struct isi_port *port,
1282 struct serial_struct __user *info)
1284 struct serial_struct newinfo;
1287 if (copy_from_user(&newinfo, info, sizeof(newinfo)))
1290 reconfig_port = ((port->flags & ASYNC_SPD_MASK) !=
1291 (newinfo.flags & ASYNC_SPD_MASK));
1293 if (!capable(CAP_SYS_ADMIN)) {
1294 if ((newinfo.close_delay != port->close_delay) ||
1295 (newinfo.closing_wait != port->closing_wait) ||
1296 ((newinfo.flags & ~ASYNC_USR_MASK) !=
1297 (port->flags & ~ASYNC_USR_MASK)))
1299 port->flags = ((port->flags & ~ ASYNC_USR_MASK) |
1300 (newinfo.flags & ASYNC_USR_MASK));
1303 port->close_delay = newinfo.close_delay;
1304 port->closing_wait = newinfo.closing_wait;
1305 port->flags = ((port->flags & ~ASYNC_FLAGS) |
1306 (newinfo.flags & ASYNC_FLAGS));
1308 if (reconfig_port) {
1309 isicom_config_port(port);
1314 static int isicom_get_serial_info(struct isi_port *port,
1315 struct serial_struct __user *info)
1317 struct serial_struct out_info;
1319 memset(&out_info, 0, sizeof(out_info));
1320 /* out_info.type = ? */
1321 out_info.line = port - isi_ports;
1322 out_info.port = port->card->base;
1323 out_info.irq = port->card->irq;
1324 out_info.flags = port->flags;
1325 /* out_info.baud_base = ? */
1326 out_info.close_delay = port->close_delay;
1327 out_info.closing_wait = port->closing_wait;
1328 if (copy_to_user(info, &out_info, sizeof(out_info)))
1333 static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1334 unsigned int cmd, unsigned long arg)
1336 struct isi_port *port = tty->driver_data;
1337 void __user *argp = (void __user *)arg;
1340 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1345 retval = tty_check_change(tty);
1348 tty_wait_until_sent(tty, 0);
1350 isicom_send_break(port, HZ/4);
1354 retval = tty_check_change(tty);
1357 tty_wait_until_sent(tty, 0);
1358 isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4);
1362 return put_user(C_CLOCAL(tty) ? 1 : 0,
1363 (unsigned long __user *)argp);
1366 if (get_user(arg, (unsigned long __user *) argp))
1368 tty->termios->c_cflag =
1369 ((tty->termios->c_cflag & ~CLOCAL) |
1370 (arg ? CLOCAL : 0));
1374 return isicom_get_serial_info(port, argp);
1377 return isicom_set_serial_info(port, argp);
1380 return -ENOIOCTLCMD;
1385 /* set_termios et all */
1386 static void isicom_set_termios(struct tty_struct *tty,
1387 struct ktermios *old_termios)
1389 struct isi_port *port = tty->driver_data;
1391 if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
1394 if (tty->termios->c_cflag == old_termios->c_cflag &&
1395 tty->termios->c_iflag == old_termios->c_iflag)
1398 isicom_config_port(port);
1400 if ((old_termios->c_cflag & CRTSCTS) &&
1401 !(tty->termios->c_cflag & CRTSCTS)) {
1402 tty->hw_stopped = 0;
1407 /* throttle et all */
1408 static void isicom_throttle(struct tty_struct *tty)
1410 struct isi_port *port = tty->driver_data;
1411 struct isi_board *card = port->card;
1413 if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
1416 /* tell the card that this port cannot handle any more data for now */
1417 card->port_status &= ~(1 << port->channel);
1418 outw(card->port_status, card->base + 0x02);
1421 /* unthrottle et all */
1422 static void isicom_unthrottle(struct tty_struct *tty)
1424 struct isi_port *port = tty->driver_data;
1425 struct isi_board *card = port->card;
1427 if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
1430 /* tell the card that this port is ready to accept more data */
1431 card->port_status |= (1 << port->channel);
1432 outw(card->port_status, card->base + 0x02);
1436 static void isicom_stop(struct tty_struct *tty)
1438 struct isi_port *port = tty->driver_data;
1440 if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
1443 /* this tells the transmitter not to consider this port for
1444 data output to the card. */
1445 port->status &= ~ISI_TXOK;
1449 static void isicom_start(struct tty_struct *tty)
1451 struct isi_port *port = tty->driver_data;
1453 if (isicom_paranoia_check(port, tty->name, "isicom_start"))
1456 /* this tells the transmitter to consider this port for
1457 data output to the card. */
1458 port->status |= ISI_TXOK;
1462 static void do_isicom_hangup(struct work_struct *work)
1464 struct isi_port *port = container_of(work, struct isi_port, hangup_tq);
1465 struct tty_struct *tty;
1472 static void isicom_hangup(struct tty_struct *tty)
1474 struct isi_port *port = tty->driver_data;
1476 if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
1479 isicom_shutdown_port(port);
1481 port->flags &= ~ASYNC_NORMAL_ACTIVE;
1483 wake_up_interruptible(&port->open_wait);
1486 /* flush_buffer et all */
1487 static void isicom_flush_buffer(struct tty_struct *tty)
1489 struct isi_port *port = tty->driver_data;
1490 struct isi_board *card = port->card;
1491 unsigned long flags;
1493 if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
1496 spin_lock_irqsave(&card->card_lock, flags);
1497 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1498 spin_unlock_irqrestore(&card->card_lock, flags);
1500 wake_up_interruptible(&tty->write_wait);
1505 * Driver init and deinit functions
1508 static const struct tty_operations isicom_ops = {
1509 .open = isicom_open,
1510 .close = isicom_close,
1511 .write = isicom_write,
1512 .put_char = isicom_put_char,
1513 .flush_chars = isicom_flush_chars,
1514 .write_room = isicom_write_room,
1515 .chars_in_buffer = isicom_chars_in_buffer,
1516 .ioctl = isicom_ioctl,
1517 .set_termios = isicom_set_termios,
1518 .throttle = isicom_throttle,
1519 .unthrottle = isicom_unthrottle,
1520 .stop = isicom_stop,
1521 .start = isicom_start,
1522 .hangup = isicom_hangup,
1523 .flush_buffer = isicom_flush_buffer,
1524 .tiocmget = isicom_tiocmget,
1525 .tiocmset = isicom_tiocmset,
1528 static int __devinit reset_card(struct pci_dev *pdev,
1529 const unsigned int card, unsigned int *signature)
1531 struct isi_board *board = pci_get_drvdata(pdev);
1532 unsigned long base = board->base;
1533 unsigned int portcount = 0;
1536 dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
1543 outw(0, base + 0x8); /* Reset */
1547 *signature = inw(base + 0x4) & 0xff;
1549 portcount = inw(base + 0x2);
1550 if (!(inw(base + 0xe) & 0x1) || ((portcount != 0) &&
1551 (portcount != 4) && (portcount != 8))) {
1552 dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n",
1553 inw(base + 0x2), inw(base + 0xe));
1554 dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure "
1555 "(Possible bad I/O Port Address 0x%lx).\n",
1561 switch (*signature) {
1565 board->port_count = (portcount == 4) ? 4 : 8;
1566 board->shift_count = 12;
1569 board->port_count = 16;
1570 board->shift_count = 11;
1573 dev_warn(&pdev->dev, "ISILoad:Card%d reset failure (Possible "
1574 "bad I/O Port Address 0x%lx).\n", card + 1, base);
1575 dev_dbg(&pdev->dev, "Sig=0x%lx\n", signature);
1578 dev_info(&pdev->dev, "-Done\n");
1584 static inline int WaitTillCardIsFree(u16 base)
1586 unsigned long count = 0;
1588 while (!(inw(base + 0xe) & 0x1) && count++ < 100)
1591 return !(inw(base + 0xe) & 0x1);
1594 static int __devinit load_firmware(struct pci_dev *pdev,
1595 const unsigned int index, const unsigned int signature)
1597 struct isi_board *board = pci_get_drvdata(pdev);
1598 const struct firmware *fw;
1599 unsigned long base = board->base;
1601 u16 word_count, status;
1612 switch (signature) {
1614 name = "isi608.bin";
1617 name = "isi608em.bin";
1620 name = "isi616em.bin";
1623 name = "isi4608.bin";
1626 name = "isi4616.bin";
1629 dev_err(&pdev->dev, "Unknown signature.\n");
1633 retval = request_firmware(&fw, name, &pdev->dev);
1639 for (frame = (struct stframe *)fw->data;
1640 frame < (struct stframe *)(fw->data + fw->size);
1641 frame = (struct stframe *)((u8 *)(frame + 1) +
1643 if (WaitTillCardIsFree(base))
1646 outw(0xf0, base); /* start upload sequence */
1648 outw(frame->addr, base); /* lsb of address */
1650 word_count = frame->count / 2 + frame->count % 2;
1651 outw(word_count, base);
1652 InterruptTheCard(base);
1654 udelay(100); /* 0x2f */
1656 if (WaitTillCardIsFree(base))
1659 if ((status = inw(base + 0x4)) != 0) {
1660 dev_warn(&pdev->dev, "Card%d rejected load header:\n"
1661 "Address:0x%x\nCount:0x%x\nStatus:0x%x\n",
1662 index + 1, frame->addr, frame->count, status);
1665 outsw(base, frame->data, word_count);
1667 InterruptTheCard(base);
1669 udelay(50); /* 0x0f */
1671 if (WaitTillCardIsFree(base))
1674 if ((status = inw(base + 0x4)) != 0) {
1675 dev_err(&pdev->dev, "Card%d got out of sync.Card "
1676 "Status:0x%x\n", index + 1, status);
1681 /* XXX: should we test it by reading it back and comparing with original like
1682 * in load firmware package? */
1683 for (frame = (struct stframe *)fw->data;
1684 frame < (struct stframe *)(fw->data + fw->size);
1685 frame = (struct stframe *)((u8 *)(frame + 1) +
1687 if (WaitTillCardIsFree(base))
1690 outw(0xf1, base); /* start download sequence */
1692 outw(frame->addr, base); /* lsb of address */
1694 word_count = (frame->count >> 1) + frame->count % 2;
1695 outw(word_count + 1, base);
1696 InterruptTheCard(base);
1698 udelay(50); /* 0xf */
1700 if (WaitTillCardIsFree(base))
1703 if ((status = inw(base + 0x4)) != 0) {
1704 dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
1705 "Address:0x%x\nCount:0x%x\nStatus: 0x%x\n",
1706 index + 1, frame->addr, frame->count, status);
1710 data = kmalloc(word_count * 2, GFP_KERNEL);
1712 insw(base, data, word_count);
1713 InterruptTheCard(base);
1715 for (a = 0; a < frame->count; a++)
1716 if (data[a] != frame->data[a]) {
1718 dev_err(&pdev->dev, "Card%d, firmware upload "
1719 "failed\n", index + 1);
1724 udelay(50); /* 0xf */
1726 if (WaitTillCardIsFree(base))
1729 if ((status = inw(base + 0x4)) != 0) {
1730 dev_err(&pdev->dev, "Card%d verify got out of sync. "
1731 "Card Status:0x%x\n", index + 1, status);
1737 if (WaitTillCardIsFree(base))
1744 InterruptTheCard(base);
1745 outw(0x0, base + 0x4); /* for ISI4608 cards */
1747 board->status |= FIRMWARE_LOADED;
1751 release_firmware(fw);
1757 * Insmod can set static symbols so keep these static
1761 static int __devinit isicom_probe(struct pci_dev *pdev,
1762 const struct pci_device_id *ent)
1764 unsigned int ioaddr, signature, index;
1765 int retval = -EPERM;
1767 struct isi_board *board = NULL;
1769 if (card >= BOARD_COUNT)
1772 ioaddr = pci_resource_start(pdev, 3);
1773 /* i.e at offset 0x1c in the PCI configuration register space. */
1775 dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
1777 /* allot the first empty slot in the array */
1778 for (index = 0; index < BOARD_COUNT; index++)
1779 if (isi_card[index].base == 0) {
1780 board = &isi_card[index];
1784 board->base = ioaddr;
1785 board->irq = pciirq;
1788 pci_set_drvdata(pdev, board);
1790 if (!request_region(board->base, 16, ISICOM_NAME)) {
1791 dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
1792 "will be disabled.\n", board->base, board->base + 15,
1798 retval = request_irq(board->irq, isicom_interrupt,
1799 IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
1801 dev_err(&pdev->dev, "Could not install handler at Irq %d. "
1802 "Card%d will be disabled.\n", board->irq, index + 1);
1806 retval = reset_card(pdev, index, &signature);
1810 retval = load_firmware(pdev, index, signature);
1817 free_irq(board->irq, board);
1819 release_region(board->base, 16);
1825 static void __devexit isicom_remove(struct pci_dev *pdev)
1827 struct isi_board *board = pci_get_drvdata(pdev);
1829 free_irq(board->irq, board);
1830 release_region(board->base, 16);
1833 static int __init isicom_init(void)
1835 int retval, idx, channel;
1836 struct isi_port *port;
1839 memset(isi_ports, 0, sizeof(isi_ports));
1841 for(idx = 0; idx < BOARD_COUNT; idx++) {
1842 port = &isi_ports[idx * 16];
1843 isi_card[idx].ports = port;
1844 spin_lock_init(&isi_card[idx].card_lock);
1845 for (channel = 0; channel < 16; channel++, port++) {
1846 port->magic = ISICOM_MAGIC;
1847 port->card = &isi_card[idx];
1848 port->channel = channel;
1849 port->close_delay = 50 * HZ/100;
1850 port->closing_wait = 3000 * HZ/100;
1851 INIT_WORK(&port->hangup_tq, do_isicom_hangup);
1852 INIT_WORK(&port->bh_tqueue, isicom_bottomhalf);
1854 init_waitqueue_head(&port->open_wait);
1855 init_waitqueue_head(&port->close_wait);
1858 isi_card[idx].base = 0;
1859 isi_card[idx].irq = 0;
1862 /* tty driver structure initialization */
1863 isicom_normal = alloc_tty_driver(PORT_COUNT);
1864 if (!isicom_normal) {
1869 isicom_normal->owner = THIS_MODULE;
1870 isicom_normal->name = "ttyM";
1871 isicom_normal->major = ISICOM_NMAJOR;
1872 isicom_normal->minor_start = 0;
1873 isicom_normal->type = TTY_DRIVER_TYPE_SERIAL;
1874 isicom_normal->subtype = SERIAL_TYPE_NORMAL;
1875 isicom_normal->init_termios = tty_std_termios;
1876 isicom_normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
1878 isicom_normal->flags = TTY_DRIVER_REAL_RAW;
1879 tty_set_operations(isicom_normal, &isicom_ops);
1881 retval = tty_register_driver(isicom_normal);
1883 pr_dbg("Couldn't register the dialin driver\n");
1887 retval = pci_register_driver(&isicom_driver);
1889 printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
1894 tx.expires = jiffies + 1;
1896 tx.function = isicom_tx;
1902 tty_unregister_driver(isicom_normal);
1904 put_tty_driver(isicom_normal);
1909 static void __exit isicom_exit(void)
1911 unsigned int index = 0;
1915 while (re_schedule != 2 && index++ < 100)
1918 pci_unregister_driver(&isicom_driver);
1919 tty_unregister_driver(isicom_normal);
1920 put_tty_driver(isicom_normal);
1923 module_init(isicom_init);
1924 module_exit(isicom_exit);
1926 MODULE_AUTHOR("MultiTech");
1927 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
1928 MODULE_LICENSE("GPL");