tty: rework break handling
[linux-2.6/verdex.git] / drivers / char / isicom.c
blobd4281df10c22dbd54a28f790774c7636126cd709
1 /*
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
9 * Changes
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)
14 * Printk clean up
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
35 * closed.
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
51 * 2.4.x
53 * 11/04/01 Kevin Fixed firmware load problem with
54 * ISIHP-4X card
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
59 * prompt.
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
66 * listing by lsmod.
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
80 * result
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.
109 * TODO
110 * Merge testing
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)
141 #ifdef DEBUG
142 #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c))
143 #else
144 #define isicom_paranoia_check(a, b, c) 0
145 #endif
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) },
160 { 0 }
162 MODULE_DEVICE_TABLE(pci, isicom_pci_tbl);
164 static struct pci_driver isicom_driver = {
165 .name = "isicom",
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
185 struct isi_board {
186 unsigned long base;
187 int irq;
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;
193 signed char count;
194 spinlock_t card_lock; /* Card wide lock 11/5/00 -sameer */
195 unsigned long flags;
196 unsigned int index;
199 struct isi_port {
200 unsigned short magic;
201 struct tty_port port;
202 u16 channel;
203 u16 status;
204 struct isi_board *card;
205 unsigned char *xmit_buf;
206 int xmit_head;
207 int xmit_tail;
208 int xmit_cnt;
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
217 * it wants to talk.
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)
226 if (a)
227 mdelay(1);
228 else
229 msleep(1);
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)
243 return 1;
244 udelay(10);
246 spin_unlock_irqrestore(&card->card_lock, card->flags);
247 msleep(10);
249 printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%lx)\n",
250 card->base);
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))
272 return;
274 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
275 outw(0x0504, 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))
288 return;
290 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
291 outw(0x0404, 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))
304 return;
306 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
307 outw(0x0a04, 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))
320 return;
322 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
323 outw(0x0804, 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))
336 return;
338 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
339 outw(0x0f04, base);
340 InterruptTheCard(base);
341 port->status |= (ISI_DTR | ISI_RTS);
342 unlock_card(card);
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))
353 return;
355 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
356 outw(0x0c04, 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)
369 if (!port) {
370 printk(KERN_WARNING "ISICOM: Warning: bad isicom magic for "
371 "dev %s in %s.\n", name, routine);
372 return 1;
374 if (port->magic != ISICOM_MAGIC) {
375 printk(KERN_WARNING "ISICOM: Warning: NULL isicom port for "
376 "dev %s in %s.\n", name, routine);
377 return 1;
380 return 0;
384 * Transmitter.
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)
403 break;
404 card = (card + 1) & 0x0003;
406 if (!(isi_card[card].status & BOARD_ACTIVE))
407 goto sched_again;
409 prev_card = card;
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)
418 break;
419 udelay(2);
421 if (retries >= 100)
422 goto unlock;
424 for (; count > 0; count--, port++) {
425 /* port not active or tx disabled to force flow control */
426 if (!(port->port.flags & ASYNC_INITIALIZED) ||
427 !(port->status & ISI_TXOK))
428 continue;
430 tty = port->port.tty;
432 if (tty == NULL)
433 continue;
435 txcount = min_t(short, TX_SIZE, port->xmit_cnt);
436 if (txcount <= 0 || tty->stopped || tty->hw_stopped)
437 continue;
439 if (!(inw(base + 0x02) & (1 << port->channel)))
440 continue;
442 pr_dbg("txing %d bytes, port%d.\n", txcount,
443 port->channel + 1);
444 outw((port->channel << isi_card[card].shift_count) | txcount,
445 base);
446 residue = NO;
447 wrd = 0;
448 while (1) {
449 cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE
450 - port->xmit_tail));
451 if (residue == YES) {
452 residue = NO;
453 if (cnt > 0) {
454 wrd |= (port->port.xmit_buf[port->xmit_tail]
455 << 8);
456 port->xmit_tail = (port->xmit_tail + 1)
457 & (SERIAL_XMIT_SIZE - 1);
458 port->xmit_cnt--;
459 txcount--;
460 cnt--;
461 outw(wrd, base);
462 } else {
463 outw(wrd, base);
464 break;
467 if (cnt <= 0)
468 break;
469 word_count = cnt >> 1;
470 outsw(base, port->port.xmit_buf+port->xmit_tail, word_count);
471 port->xmit_tail = (port->xmit_tail
472 + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
473 txcount -= (word_count << 1);
474 port->xmit_cnt -= (word_count << 1);
475 if (cnt & 0x0001) {
476 residue = YES;
477 wrd = port->port.xmit_buf[port->xmit_tail];
478 port->xmit_tail = (port->xmit_tail + 1)
479 & (SERIAL_XMIT_SIZE - 1);
480 port->xmit_cnt--;
481 txcount--;
485 InterruptTheCard(base);
486 if (port->xmit_cnt <= 0)
487 port->status &= ~ISI_TXOK;
488 if (port->xmit_cnt <= WAKEUP_CHARS)
489 tty_wakeup(tty);
492 unlock:
493 spin_unlock_irqrestore(&isi_card[card].card_lock, flags);
494 /* schedule another tx for hopefully in about 10ms */
495 sched_again:
496 mod_timer(&tx, jiffies + msecs_to_jiffies(10));
500 * Main interrupt handler routine
503 static irqreturn_t isicom_interrupt(int irq, void *dev_id)
505 struct isi_board *card = dev_id;
506 struct isi_port *port;
507 struct tty_struct *tty;
508 unsigned long base;
509 u16 header, word_count, count, channel;
510 short byte_count;
511 unsigned char *rp;
513 if (!card || !(card->status & FIRMWARE_LOADED))
514 return IRQ_NONE;
516 base = card->base;
518 /* did the card interrupt us? */
519 if (!(inw(base + 0x0e) & 0x02))
520 return IRQ_NONE;
522 spin_lock(&card->card_lock);
525 * disable any interrupts from the PCI card and lower the
526 * interrupt line
528 outw(0x8000, base+0x04);
529 ClearInterrupt(base);
531 inw(base); /* get the dummy word out */
532 header = inw(base);
533 channel = (header & 0x7800) >> card->shift_count;
534 byte_count = header & 0xff;
536 if (channel + 1 > card->port_count) {
537 printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): "
538 "%d(channel) > port_count.\n", base, channel+1);
539 outw(0x0000, base+0x04); /* enable interrupts */
540 spin_unlock(&card->card_lock);
541 return IRQ_HANDLED;
543 port = card->ports + channel;
544 if (!(port->port.flags & ASYNC_INITIALIZED)) {
545 outw(0x0000, base+0x04); /* enable interrupts */
546 spin_unlock(&card->card_lock);
547 return IRQ_HANDLED;
550 tty = port->port.tty;
551 if (tty == NULL) {
552 word_count = byte_count >> 1;
553 while (byte_count > 1) {
554 inw(base);
555 byte_count -= 2;
557 if (byte_count & 0x01)
558 inw(base);
559 outw(0x0000, base+0x04); /* enable interrupts */
560 spin_unlock(&card->card_lock);
561 return IRQ_HANDLED;
564 if (header & 0x8000) { /* Status Packet */
565 header = inw(base);
566 switch (header & 0xff) {
567 case 0: /* Change in EIA signals */
568 if (port->port.flags & ASYNC_CHECK_CD) {
569 if (port->status & ISI_DCD) {
570 if (!(header & ISI_DCD)) {
571 /* Carrier has been lost */
572 pr_dbg("interrupt: DCD->low.\n"
574 port->status &= ~ISI_DCD;
575 tty_hangup(tty);
577 } else if (header & ISI_DCD) {
578 /* Carrier has been detected */
579 pr_dbg("interrupt: DCD->high.\n");
580 port->status |= ISI_DCD;
581 wake_up_interruptible(&port->port.open_wait);
583 } else {
584 if (header & ISI_DCD)
585 port->status |= ISI_DCD;
586 else
587 port->status &= ~ISI_DCD;
590 if (port->port.flags & ASYNC_CTS_FLOW) {
591 if (port->port.tty->hw_stopped) {
592 if (header & ISI_CTS) {
593 port->port.tty->hw_stopped = 0;
594 /* start tx ing */
595 port->status |= (ISI_TXOK
596 | ISI_CTS);
597 tty_wakeup(tty);
599 } else if (!(header & ISI_CTS)) {
600 port->port.tty->hw_stopped = 1;
601 /* stop tx ing */
602 port->status &= ~(ISI_TXOK | ISI_CTS);
604 } else {
605 if (header & ISI_CTS)
606 port->status |= ISI_CTS;
607 else
608 port->status &= ~ISI_CTS;
611 if (header & ISI_DSR)
612 port->status |= ISI_DSR;
613 else
614 port->status &= ~ISI_DSR;
616 if (header & ISI_RI)
617 port->status |= ISI_RI;
618 else
619 port->status &= ~ISI_RI;
621 break;
623 case 1: /* Received Break !!! */
624 tty_insert_flip_char(tty, 0, TTY_BREAK);
625 if (port->port.flags & ASYNC_SAK)
626 do_SAK(tty);
627 tty_flip_buffer_push(tty);
628 break;
630 case 2: /* Statistics */
631 pr_dbg("isicom_interrupt: stats!!!.\n");
632 break;
634 default:
635 pr_dbg("Intr: Unknown code in status packet.\n");
636 break;
638 } else { /* Data Packet */
640 count = tty_prepare_flip_string(tty, &rp, byte_count & ~1);
641 pr_dbg("Intr: Can rx %d of %d bytes.\n", count, byte_count);
642 word_count = count >> 1;
643 insw(base, rp, word_count);
644 byte_count -= (word_count << 1);
645 if (count & 0x0001) {
646 tty_insert_flip_char(tty, inw(base) & 0xff,
647 TTY_NORMAL);
648 byte_count -= 2;
650 if (byte_count > 0) {
651 pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping "
652 "bytes...\n", base, channel + 1);
653 /* drain out unread xtra data */
654 while (byte_count > 0) {
655 inw(base);
656 byte_count -= 2;
659 tty_flip_buffer_push(tty);
661 outw(0x0000, base+0x04); /* enable interrupts */
662 spin_unlock(&card->card_lock);
664 return IRQ_HANDLED;
667 static void isicom_config_port(struct isi_port *port)
669 struct isi_board *card = port->card;
670 struct tty_struct *tty;
671 unsigned long baud;
672 unsigned long base = card->base;
673 u16 channel_setup, channel = port->channel,
674 shift_count = card->shift_count;
675 unsigned char flow_ctrl;
677 tty = port->port.tty;
679 if (tty == NULL)
680 return;
681 /* FIXME: Switch to new tty baud API */
682 baud = C_BAUD(tty);
683 if (baud & CBAUDEX) {
684 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
688 * respectively.
691 /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
692 if (baud < 1 || baud > 4)
693 port->port.tty->termios->c_cflag &= ~CBAUDEX;
694 else
695 baud += 15;
697 if (baud == 15) {
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) {
714 /* hang up */
715 drop_dtr(port);
716 return;
717 } else
718 raise_dtr(port);
720 if (WaitTillCardIsFree(base) == 0) {
721 outw(0x8000 | (channel << shift_count) | 0x03, base);
722 outw(linuxb_to_isib[baud] << 8 | 0x03, base);
723 channel_setup = 0;
724 switch (C_CSIZE(tty)) {
725 case CS5:
726 channel_setup |= ISICOM_CS5;
727 break;
728 case CS6:
729 channel_setup |= ISICOM_CS6;
730 break;
731 case CS7:
732 channel_setup |= ISICOM_CS7;
733 break;
734 case CS8:
735 channel_setup |= ISICOM_CS8;
736 break;
739 if (C_CSTOPB(tty))
740 channel_setup |= ISICOM_2SB;
741 if (C_PARENB(tty)) {
742 channel_setup |= ISICOM_EVPAR;
743 if (C_PARODD(tty))
744 channel_setup |= ISICOM_ODPAR;
746 outw(channel_setup, base);
747 InterruptTheCard(base);
749 if (C_CLOCAL(tty))
750 port->port.flags &= ~ASYNC_CHECK_CD;
751 else
752 port->port.flags |= ASYNC_CHECK_CD;
754 /* flow control settings ...*/
755 flow_ctrl = 0;
756 port->port.flags &= ~ASYNC_CTS_FLOW;
757 if (C_CRTSCTS(tty)) {
758 port->port.flags |= ASYNC_CTS_FLOW;
759 flow_ctrl |= ISICOM_CTSRTS;
761 if (I_IXON(tty))
762 flow_ctrl |= ISICOM_RESPOND_XONXOFF;
763 if (I_IXOFF(tty))
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 */
774 if (C_CREAD(tty)) {
775 card->port_status |= (1 << channel);
776 outw(card->port_status, base + 0x02);
780 /* open et all */
782 static inline void isicom_setup_board(struct isi_board *bp)
784 int channel;
785 struct isi_port *port;
786 unsigned long flags;
788 spin_lock_irqsave(&bp->card_lock, flags);
789 if (bp->status & BOARD_ACTIVE) {
790 spin_unlock_irqrestore(&bp->card_lock, flags);
791 return;
793 port = bp->ports;
794 bp->status |= BOARD_ACTIVE;
795 for (channel = 0; channel < bp->port_count; channel++, port++)
796 drop_dtr_rts(port);
797 spin_unlock_irqrestore(&bp->card_lock, flags);
800 static int isicom_setup_port(struct isi_port *port)
802 struct isi_board *card = port->card;
803 unsigned long flags;
805 if (port->port.flags & ASYNC_INITIALIZED)
806 return 0;
807 if (tty_port_alloc_xmit_buf(&port->port) < 0)
808 return -ENOMEM;
810 spin_lock_irqsave(&card->card_lock, flags);
811 if (port->port.tty)
812 clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
813 if (port->port.count == 1)
814 card->count++;
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,
821 card->base);
822 outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base);
823 InterruptTheCard(card->base);
826 isicom_config_port(port);
827 port->port.flags |= ASYNC_INITIALIZED;
828 spin_unlock_irqrestore(&card->card_lock, flags);
830 return 0;
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;
838 unsigned long flags;
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)
847 return -EAGAIN;
848 else
849 return -ERESTARTSYS;
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;
858 return 0;
861 if (C_CLOCAL(tty))
862 do_clocal = 1;
864 /* block waiting for DCD to be asserted, and while
865 callout dev is busy */
866 retval = 0;
867 add_wait_queue(&port->port.open_wait, &wait);
869 spin_lock_irqsave(&card->card_lock, flags);
870 if (!tty_hung_up_p(filp))
871 port->port.count--;
872 port->port.blocked_open++;
873 spin_unlock_irqrestore(&card->card_lock, flags);
875 while (1) {
876 raise_dtr_rts(port);
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)
881 retval = -EAGAIN;
882 else
883 retval = -ERESTARTSYS;
884 break;
886 if (!(port->port.flags & ASYNC_CLOSING) &&
887 (do_clocal || (port->status & ISI_DCD))) {
888 break;
890 if (signal_pending(current)) {
891 retval = -ERESTARTSYS;
892 break;
894 schedule();
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))
900 port->port.count++;
901 port->port.blocked_open--;
902 spin_unlock_irqrestore(&card->card_lock, flags);
903 if (retval)
904 return retval;
905 port->port.flags |= ASYNC_NORMAL_ACTIVE;
906 return 0;
909 static int isicom_open(struct tty_struct *tty, struct file *filp)
911 struct isi_port *port;
912 struct isi_board *card;
913 unsigned int board;
914 int error, line;
916 line = tty->index;
917 if (line < 0 || line > PORT_COUNT-1)
918 return -ENODEV;
919 board = BOARD(line);
920 card = &isi_card[board];
922 if (!(card->status & FIRMWARE_LOADED))
923 return -ENODEV;
925 /* open on a port greater than the port count for the card !!! */
926 if (line > ((board * 16) + card->port_count - 1))
927 return -ENODEV;
929 port = &isi_ports[line];
930 if (isicom_paranoia_check(port, tty->name, "isicom_open"))
931 return -ENODEV;
933 isicom_setup_board(card);
935 port->port.count++;
936 tty->driver_data = port;
937 port->port.tty = tty;
938 error = isicom_setup_port(port);
939 if (error == 0)
940 error = block_til_ready(tty, filp, port);
941 return error;
944 /* close et all */
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 = port->port.tty;
960 if (!(port->port.flags & ASYNC_INITIALIZED))
961 return;
963 tty_port_free_xmit_buf(&port->port);
964 port->port.flags &= ~ASYNC_INITIALIZED;
965 /* 3rd October 2000 : Vinayak P Risbud */
966 port->port.tty = 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*/
974 if (C_HUPCL(tty))
975 /* drop dtr on this port */
976 drop_dtr(port);
978 /* any other port uninits */
979 if (tty)
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);
985 card->count = 0;
988 /* last port was closed, shutdown that boad too */
989 if (C_HUPCL(tty)) {
990 if (!card->count)
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;
999 unsigned long flags;
1001 if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
1002 return;
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);
1008 tty_wakeup(tty);
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;
1017 if (!port)
1018 return;
1019 card = port->card;
1020 if (isicom_paranoia_check(port, tty->name, "isicom_close"))
1021 return;
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);
1028 return;
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,
1040 port->port.count);
1041 port->port.count = 0;
1044 if (port->port.count) {
1045 spin_unlock_irqrestore(&card->card_lock, flags);
1046 return;
1048 port->port.flags |= ASYNC_CLOSING;
1049 tty->closing = 1;
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
1055 on this port */
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);
1068 tty->closing = 0;
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);
1085 /* write et all */
1086 static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
1087 int count)
1089 struct isi_port *port = tty->driver_data;
1090 struct isi_board *card = port->card;
1091 unsigned long flags;
1092 int cnt, total = 0;
1094 if (isicom_paranoia_check(port, tty->name, "isicom_write"))
1095 return 0;
1097 spin_lock_irqsave(&card->card_lock, flags);
1099 while (1) {
1100 cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
1101 - 1, SERIAL_XMIT_SIZE - port->xmit_head));
1102 if (cnt <= 0)
1103 break;
1105 memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt);
1106 port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
1107 - 1);
1108 port->xmit_cnt += cnt;
1109 buf += cnt;
1110 count -= cnt;
1111 total += cnt;
1113 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped)
1114 port->status |= ISI_TXOK;
1115 spin_unlock_irqrestore(&card->card_lock, flags);
1116 return total;
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"))
1127 return 0;
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);
1132 return 0;
1135 port->port.xmit_buf[port->xmit_head++] = ch;
1136 port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
1137 port->xmit_cnt++;
1138 spin_unlock_irqrestore(&card->card_lock, flags);
1139 return 1;
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"))
1148 return;
1150 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1151 !port->port.xmit_buf)
1152 return;
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;
1163 int free;
1165 if (isicom_paranoia_check(port, tty->name, "isicom_write_room"))
1166 return 0;
1168 free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1169 if (free < 0)
1170 free = 0;
1171 return free;
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"))
1179 return 0;
1180 return port->xmit_cnt;
1183 /* ioctl et all */
1184 static inline void isicom_send_break(struct isi_port *port,
1185 unsigned long length)
1187 struct isi_board *card = port->card;
1188 unsigned long base = card->base;
1190 if (!lock_card(card))
1191 return;
1193 outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
1194 outw((length & 0xff) << 8 | 0x00, base);
1195 outw((length & 0xff00), base);
1196 InterruptTheCard(base);
1198 unlock_card(card);
1201 static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
1203 struct isi_port *port = tty->driver_data;
1204 /* just send the port status */
1205 u16 status = port->status;
1207 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1208 return -ENODEV;
1210 return ((status & ISI_RTS) ? TIOCM_RTS : 0) |
1211 ((status & ISI_DTR) ? TIOCM_DTR : 0) |
1212 ((status & ISI_DCD) ? TIOCM_CAR : 0) |
1213 ((status & ISI_DSR) ? TIOCM_DSR : 0) |
1214 ((status & ISI_CTS) ? TIOCM_CTS : 0) |
1215 ((status & ISI_RI ) ? TIOCM_RI : 0);
1218 static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
1219 unsigned int set, unsigned int clear)
1221 struct isi_port *port = tty->driver_data;
1222 unsigned long flags;
1224 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1225 return -ENODEV;
1227 spin_lock_irqsave(&port->card->card_lock, flags);
1228 if (set & TIOCM_RTS)
1229 raise_rts(port);
1230 if (set & TIOCM_DTR)
1231 raise_dtr(port);
1233 if (clear & TIOCM_RTS)
1234 drop_rts(port);
1235 if (clear & TIOCM_DTR)
1236 drop_dtr(port);
1237 spin_unlock_irqrestore(&port->card->card_lock, flags);
1239 return 0;
1242 static int isicom_set_serial_info(struct isi_port *port,
1243 struct serial_struct __user *info)
1245 struct serial_struct newinfo;
1246 int reconfig_port;
1248 if (copy_from_user(&newinfo, info, sizeof(newinfo)))
1249 return -EFAULT;
1251 lock_kernel();
1253 reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) !=
1254 (newinfo.flags & ASYNC_SPD_MASK));
1256 if (!capable(CAP_SYS_ADMIN)) {
1257 if ((newinfo.close_delay != port->port.close_delay) ||
1258 (newinfo.closing_wait != port->port.closing_wait) ||
1259 ((newinfo.flags & ~ASYNC_USR_MASK) !=
1260 (port->port.flags & ~ASYNC_USR_MASK))) {
1261 unlock_kernel();
1262 return -EPERM;
1264 port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1265 (newinfo.flags & ASYNC_USR_MASK));
1266 } else {
1267 port->port.close_delay = newinfo.close_delay;
1268 port->port.closing_wait = newinfo.closing_wait;
1269 port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1270 (newinfo.flags & ASYNC_FLAGS));
1272 if (reconfig_port) {
1273 unsigned long flags;
1274 spin_lock_irqsave(&port->card->card_lock, flags);
1275 isicom_config_port(port);
1276 spin_unlock_irqrestore(&port->card->card_lock, flags);
1278 unlock_kernel();
1279 return 0;
1282 static int isicom_get_serial_info(struct isi_port *port,
1283 struct serial_struct __user *info)
1285 struct serial_struct out_info;
1287 lock_kernel();
1288 memset(&out_info, 0, sizeof(out_info));
1289 /* out_info.type = ? */
1290 out_info.line = port - isi_ports;
1291 out_info.port = port->card->base;
1292 out_info.irq = port->card->irq;
1293 out_info.flags = port->port.flags;
1294 /* out_info.baud_base = ? */
1295 out_info.close_delay = port->port.close_delay;
1296 out_info.closing_wait = port->port.closing_wait;
1297 unlock_kernel();
1298 if (copy_to_user(info, &out_info, sizeof(out_info)))
1299 return -EFAULT;
1300 return 0;
1303 static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1304 unsigned int cmd, unsigned long arg)
1306 struct isi_port *port = tty->driver_data;
1307 void __user *argp = (void __user *)arg;
1308 int retval;
1310 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1311 return -ENODEV;
1313 switch (cmd) {
1314 case TCSBRK:
1315 retval = tty_check_change(tty);
1316 if (retval)
1317 return retval;
1318 tty_wait_until_sent(tty, 0);
1319 if (!arg)
1320 isicom_send_break(port, HZ/4);
1321 return 0;
1323 case TCSBRKP:
1324 retval = tty_check_change(tty);
1325 if (retval)
1326 return retval;
1327 tty_wait_until_sent(tty, 0);
1328 isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4);
1329 return 0;
1330 case TIOCGSERIAL:
1331 return isicom_get_serial_info(port, argp);
1333 case TIOCSSERIAL:
1334 return isicom_set_serial_info(port, argp);
1336 default:
1337 return -ENOIOCTLCMD;
1339 return 0;
1342 /* set_termios et all */
1343 static void isicom_set_termios(struct tty_struct *tty,
1344 struct ktermios *old_termios)
1346 struct isi_port *port = tty->driver_data;
1347 unsigned long flags;
1349 if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
1350 return;
1352 if (tty->termios->c_cflag == old_termios->c_cflag &&
1353 tty->termios->c_iflag == old_termios->c_iflag)
1354 return;
1356 spin_lock_irqsave(&port->card->card_lock, flags);
1357 isicom_config_port(port);
1358 spin_unlock_irqrestore(&port->card->card_lock, flags);
1360 if ((old_termios->c_cflag & CRTSCTS) &&
1361 !(tty->termios->c_cflag & CRTSCTS)) {
1362 tty->hw_stopped = 0;
1363 isicom_start(tty);
1367 /* throttle et all */
1368 static void isicom_throttle(struct tty_struct *tty)
1370 struct isi_port *port = tty->driver_data;
1371 struct isi_board *card = port->card;
1373 if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
1374 return;
1376 /* tell the card that this port cannot handle any more data for now */
1377 card->port_status &= ~(1 << port->channel);
1378 outw(card->port_status, card->base + 0x02);
1381 /* unthrottle et all */
1382 static void isicom_unthrottle(struct tty_struct *tty)
1384 struct isi_port *port = tty->driver_data;
1385 struct isi_board *card = port->card;
1387 if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
1388 return;
1390 /* tell the card that this port is ready to accept more data */
1391 card->port_status |= (1 << port->channel);
1392 outw(card->port_status, card->base + 0x02);
1395 /* stop et all */
1396 static void isicom_stop(struct tty_struct *tty)
1398 struct isi_port *port = tty->driver_data;
1400 if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
1401 return;
1403 /* this tells the transmitter not to consider this port for
1404 data output to the card. */
1405 port->status &= ~ISI_TXOK;
1408 /* start et all */
1409 static void isicom_start(struct tty_struct *tty)
1411 struct isi_port *port = tty->driver_data;
1413 if (isicom_paranoia_check(port, tty->name, "isicom_start"))
1414 return;
1416 /* this tells the transmitter to consider this port for
1417 data output to the card. */
1418 port->status |= ISI_TXOK;
1421 static void isicom_hangup(struct tty_struct *tty)
1423 struct isi_port *port = tty->driver_data;
1424 unsigned long flags;
1426 if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
1427 return;
1429 spin_lock_irqsave(&port->card->card_lock, flags);
1430 isicom_shutdown_port(port);
1431 spin_unlock_irqrestore(&port->card->card_lock, flags);
1433 port->port.count = 0;
1434 port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1435 port->port.tty = NULL;
1436 wake_up_interruptible(&port->port.open_wait);
1441 * Driver init and deinit functions
1444 static const struct tty_operations isicom_ops = {
1445 .open = isicom_open,
1446 .close = isicom_close,
1447 .write = isicom_write,
1448 .put_char = isicom_put_char,
1449 .flush_chars = isicom_flush_chars,
1450 .write_room = isicom_write_room,
1451 .chars_in_buffer = isicom_chars_in_buffer,
1452 .ioctl = isicom_ioctl,
1453 .set_termios = isicom_set_termios,
1454 .throttle = isicom_throttle,
1455 .unthrottle = isicom_unthrottle,
1456 .stop = isicom_stop,
1457 .start = isicom_start,
1458 .hangup = isicom_hangup,
1459 .flush_buffer = isicom_flush_buffer,
1460 .tiocmget = isicom_tiocmget,
1461 .tiocmset = isicom_tiocmset,
1464 static int __devinit reset_card(struct pci_dev *pdev,
1465 const unsigned int card, unsigned int *signature)
1467 struct isi_board *board = pci_get_drvdata(pdev);
1468 unsigned long base = board->base;
1469 unsigned int sig, portcount = 0;
1470 int retval = 0;
1472 dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
1473 base);
1475 inw(base + 0x8);
1477 msleep(10);
1479 outw(0, base + 0x8); /* Reset */
1481 msleep(1000);
1483 sig = inw(base + 0x4) & 0xff;
1485 if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd &&
1486 sig != 0xee) {
1487 dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible "
1488 "bad I/O Port Address 0x%lx).\n", card + 1, base);
1489 dev_dbg(&pdev->dev, "Sig=0x%x\n", sig);
1490 retval = -EIO;
1491 goto end;
1494 msleep(10);
1496 portcount = inw(base + 0x2);
1497 if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 &&
1498 portcount != 8 && portcount != 16)) {
1499 dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
1500 card + 1);
1501 retval = -EIO;
1502 goto end;
1505 switch (sig) {
1506 case 0xa5:
1507 case 0xbb:
1508 case 0xdd:
1509 board->port_count = (portcount == 4) ? 4 : 8;
1510 board->shift_count = 12;
1511 break;
1512 case 0xcc:
1513 case 0xee:
1514 board->port_count = 16;
1515 board->shift_count = 11;
1516 break;
1518 dev_info(&pdev->dev, "-Done\n");
1519 *signature = sig;
1521 end:
1522 return retval;
1525 static int __devinit load_firmware(struct pci_dev *pdev,
1526 const unsigned int index, const unsigned int signature)
1528 struct isi_board *board = pci_get_drvdata(pdev);
1529 const struct firmware *fw;
1530 unsigned long base = board->base;
1531 unsigned int a;
1532 u16 word_count, status;
1533 int retval = -EIO;
1534 char *name;
1535 u8 *data;
1537 struct stframe {
1538 u16 addr;
1539 u16 count;
1540 u8 data[0];
1541 } *frame;
1543 switch (signature) {
1544 case 0xa5:
1545 name = "isi608.bin";
1546 break;
1547 case 0xbb:
1548 name = "isi608em.bin";
1549 break;
1550 case 0xcc:
1551 name = "isi616em.bin";
1552 break;
1553 case 0xdd:
1554 name = "isi4608.bin";
1555 break;
1556 case 0xee:
1557 name = "isi4616.bin";
1558 break;
1559 default:
1560 dev_err(&pdev->dev, "Unknown signature.\n");
1561 goto end;
1564 retval = request_firmware(&fw, name, &pdev->dev);
1565 if (retval)
1566 goto end;
1568 retval = -EIO;
1570 for (frame = (struct stframe *)fw->data;
1571 frame < (struct stframe *)(fw->data + fw->size);
1572 frame = (struct stframe *)((u8 *)(frame + 1) +
1573 frame->count)) {
1574 if (WaitTillCardIsFree(base))
1575 goto errrelfw;
1577 outw(0xf0, base); /* start upload sequence */
1578 outw(0x00, base);
1579 outw(frame->addr, base); /* lsb of address */
1581 word_count = frame->count / 2 + frame->count % 2;
1582 outw(word_count, base);
1583 InterruptTheCard(base);
1585 udelay(100); /* 0x2f */
1587 if (WaitTillCardIsFree(base))
1588 goto errrelfw;
1590 status = inw(base + 0x4);
1591 if (status != 0) {
1592 dev_warn(&pdev->dev, "Card%d rejected load header:\n"
1593 KERN_WARNING "Address:0x%x\n"
1594 KERN_WARNING "Count:0x%x\n"
1595 KERN_WARNING "Status:0x%x\n",
1596 index + 1, frame->addr, frame->count, status);
1597 goto errrelfw;
1599 outsw(base, frame->data, word_count);
1601 InterruptTheCard(base);
1603 udelay(50); /* 0x0f */
1605 if (WaitTillCardIsFree(base))
1606 goto errrelfw;
1608 status = inw(base + 0x4);
1609 if (status != 0) {
1610 dev_err(&pdev->dev, "Card%d got out of sync.Card "
1611 "Status:0x%x\n", index + 1, status);
1612 goto errrelfw;
1616 /* XXX: should we test it by reading it back and comparing with original like
1617 * in load firmware package? */
1618 for (frame = (struct stframe *)fw->data;
1619 frame < (struct stframe *)(fw->data + fw->size);
1620 frame = (struct stframe *)((u8 *)(frame + 1) +
1621 frame->count)) {
1622 if (WaitTillCardIsFree(base))
1623 goto errrelfw;
1625 outw(0xf1, base); /* start download sequence */
1626 outw(0x00, base);
1627 outw(frame->addr, base); /* lsb of address */
1629 word_count = (frame->count >> 1) + frame->count % 2;
1630 outw(word_count + 1, base);
1631 InterruptTheCard(base);
1633 udelay(50); /* 0xf */
1635 if (WaitTillCardIsFree(base))
1636 goto errrelfw;
1638 status = inw(base + 0x4);
1639 if (status != 0) {
1640 dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
1641 KERN_WARNING "Address:0x%x\n"
1642 KERN_WARNING "Count:0x%x\n"
1643 KERN_WARNING "Status: 0x%x\n",
1644 index + 1, frame->addr, frame->count, status);
1645 goto errrelfw;
1648 data = kmalloc(word_count * 2, GFP_KERNEL);
1649 if (data == NULL) {
1650 dev_err(&pdev->dev, "Card%d, firmware upload "
1651 "failed, not enough memory\n", index + 1);
1652 goto errrelfw;
1654 inw(base);
1655 insw(base, data, word_count);
1656 InterruptTheCard(base);
1658 for (a = 0; a < frame->count; a++)
1659 if (data[a] != frame->data[a]) {
1660 kfree(data);
1661 dev_err(&pdev->dev, "Card%d, firmware upload "
1662 "failed\n", index + 1);
1663 goto errrelfw;
1665 kfree(data);
1667 udelay(50); /* 0xf */
1669 if (WaitTillCardIsFree(base))
1670 goto errrelfw;
1672 status = inw(base + 0x4);
1673 if (status != 0) {
1674 dev_err(&pdev->dev, "Card%d verify got out of sync. "
1675 "Card Status:0x%x\n", index + 1, status);
1676 goto errrelfw;
1680 /* xfer ctrl */
1681 if (WaitTillCardIsFree(base))
1682 goto errrelfw;
1684 outw(0xf2, base);
1685 outw(0x800, base);
1686 outw(0x0, base);
1687 outw(0x0, base);
1688 InterruptTheCard(base);
1689 outw(0x0, base + 0x4); /* for ISI4608 cards */
1691 board->status |= FIRMWARE_LOADED;
1692 retval = 0;
1694 errrelfw:
1695 release_firmware(fw);
1696 end:
1697 return retval;
1701 * Insmod can set static symbols so keep these static
1703 static unsigned int card_count;
1705 static int __devinit isicom_probe(struct pci_dev *pdev,
1706 const struct pci_device_id *ent)
1708 unsigned int signature, index;
1709 int retval = -EPERM;
1710 struct isi_board *board = NULL;
1712 if (card_count >= BOARD_COUNT)
1713 goto err;
1715 retval = pci_enable_device(pdev);
1716 if (retval) {
1717 dev_err(&pdev->dev, "failed to enable\n");
1718 goto err;
1721 dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
1723 /* allot the first empty slot in the array */
1724 for (index = 0; index < BOARD_COUNT; index++)
1725 if (isi_card[index].base == 0) {
1726 board = &isi_card[index];
1727 break;
1730 board->index = index;
1731 board->base = pci_resource_start(pdev, 3);
1732 board->irq = pdev->irq;
1733 card_count++;
1735 pci_set_drvdata(pdev, board);
1737 retval = pci_request_region(pdev, 3, ISICOM_NAME);
1738 if (retval) {
1739 dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
1740 "will be disabled.\n", board->base, board->base + 15,
1741 index + 1);
1742 retval = -EBUSY;
1743 goto errdec;
1746 retval = request_irq(board->irq, isicom_interrupt,
1747 IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
1748 if (retval < 0) {
1749 dev_err(&pdev->dev, "Could not install handler at Irq %d. "
1750 "Card%d will be disabled.\n", board->irq, index + 1);
1751 goto errunrr;
1754 retval = reset_card(pdev, index, &signature);
1755 if (retval < 0)
1756 goto errunri;
1758 retval = load_firmware(pdev, index, signature);
1759 if (retval < 0)
1760 goto errunri;
1762 for (index = 0; index < board->port_count; index++)
1763 tty_register_device(isicom_normal, board->index * 16 + index,
1764 &pdev->dev);
1766 return 0;
1768 errunri:
1769 free_irq(board->irq, board);
1770 errunrr:
1771 pci_release_region(pdev, 3);
1772 errdec:
1773 board->base = 0;
1774 card_count--;
1775 pci_disable_device(pdev);
1776 err:
1777 return retval;
1780 static void __devexit isicom_remove(struct pci_dev *pdev)
1782 struct isi_board *board = pci_get_drvdata(pdev);
1783 unsigned int i;
1785 for (i = 0; i < board->port_count; i++)
1786 tty_unregister_device(isicom_normal, board->index * 16 + i);
1788 free_irq(board->irq, board);
1789 pci_release_region(pdev, 3);
1790 board->base = 0;
1791 card_count--;
1792 pci_disable_device(pdev);
1795 static int __init isicom_init(void)
1797 int retval, idx, channel;
1798 struct isi_port *port;
1800 for (idx = 0; idx < BOARD_COUNT; idx++) {
1801 port = &isi_ports[idx * 16];
1802 isi_card[idx].ports = port;
1803 spin_lock_init(&isi_card[idx].card_lock);
1804 for (channel = 0; channel < 16; channel++, port++) {
1805 tty_port_init(&port->port);
1806 port->magic = ISICOM_MAGIC;
1807 port->card = &isi_card[idx];
1808 port->channel = channel;
1809 port->port.close_delay = 50 * HZ/100;
1810 port->port.closing_wait = 3000 * HZ/100;
1811 port->status = 0;
1812 /* . . . */
1814 isi_card[idx].base = 0;
1815 isi_card[idx].irq = 0;
1818 /* tty driver structure initialization */
1819 isicom_normal = alloc_tty_driver(PORT_COUNT);
1820 if (!isicom_normal) {
1821 retval = -ENOMEM;
1822 goto error;
1825 isicom_normal->owner = THIS_MODULE;
1826 isicom_normal->name = "ttyM";
1827 isicom_normal->major = ISICOM_NMAJOR;
1828 isicom_normal->minor_start = 0;
1829 isicom_normal->type = TTY_DRIVER_TYPE_SERIAL;
1830 isicom_normal->subtype = SERIAL_TYPE_NORMAL;
1831 isicom_normal->init_termios = tty_std_termios;
1832 isicom_normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
1833 CLOCAL;
1834 isicom_normal->flags = TTY_DRIVER_REAL_RAW |
1835 TTY_DRIVER_DYNAMIC_DEV;
1836 tty_set_operations(isicom_normal, &isicom_ops);
1838 retval = tty_register_driver(isicom_normal);
1839 if (retval) {
1840 pr_dbg("Couldn't register the dialin driver\n");
1841 goto err_puttty;
1844 retval = pci_register_driver(&isicom_driver);
1845 if (retval < 0) {
1846 printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
1847 goto err_unrtty;
1850 mod_timer(&tx, jiffies + 1);
1852 return 0;
1853 err_unrtty:
1854 tty_unregister_driver(isicom_normal);
1855 err_puttty:
1856 put_tty_driver(isicom_normal);
1857 error:
1858 return retval;
1861 static void __exit isicom_exit(void)
1863 del_timer_sync(&tx);
1865 pci_unregister_driver(&isicom_driver);
1866 tty_unregister_driver(isicom_normal);
1867 put_tty_driver(isicom_normal);
1870 module_init(isicom_init);
1871 module_exit(isicom_exit);
1873 MODULE_AUTHOR("MultiTech");
1874 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
1875 MODULE_LICENSE("GPL");