USB: fsl_udc_core: Fix kernel oops on module removal
[safe/jmp/linux-2.6] / drivers / char / isicom.c
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.
6  *
7  *      Original driver code supplied by Multi-Tech
8  *
9  *      Changes
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)
15  *                                      Printk clean up
16  *      9/12/98 alan@lxorguk.ukuu.org.uk
17  *                                      Rough port to 2.1.x
18  *
19  *      10/6/99 sameer                  Merged the ISA and PCI drivers to
20  *                                      a new unified driver.
21  *
22  *      3/9/99  sameer                  Added support for ISI4616 cards.
23  *
24  *      16/9/99 sameer                  We do not force RTS low anymore.
25  *                                      This is to prevent the firmware
26  *                                      from getting confused.
27  *
28  *      26/10/99 sameer                 Cosmetic changes:The driver now
29  *                                      dumps the Port Count information
30  *                                      along with I/O address and IRQ.
31  *
32  *      13/12/99 sameer                 Fixed the problem with IRQ sharing.
33  *
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
37  *                                      closed.
38  *
39  *      10/5/00  sameer                 Signal mask setup command added
40  *                                      to  isicom_setup_port and
41  *                                      isicom_shutdown_port.
42  *
43  *      24/5/00  sameer                 The driver is now SMP aware.
44  *
45  *
46  *      27/11/00 Vinayak P Risbud       Fixed the Driver Crash Problem
47  *
48  *
49  *      03/01/01  anil .s               Added support for resetting the
50  *                                      internal modems on ISI cards.
51  *
52  *      08/02/01  anil .s               Upgraded the driver for kernel
53  *                                      2.4.x
54  *
55  *      11/04/01  Kevin                 Fixed firmware load problem with
56  *                                      ISIHP-4X card
57  *
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
61  *                                      prompt.
62  *
63  *      03/05/01  anil .s               Fixed the problem with IRQ sharing
64  *                                      among ISI-PCI cards.
65  *
66  *      03/05/01  anil .s               Added support to display the version
67  *                                      info during insmod as well as module
68  *                                      listing by lsmod.
69  *
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.
74  *
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.
78  *
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
82  *                                      result
83  *
84  *      11/02/03  ranjeeth              Added support for 230 Kbps and 460 Kbps
85  *                                      Baud index extended to 21
86  *
87  *      20/03/03  ranjeeth              Made to work for Linux Advanced server.
88  *                                      Taken care of license warning.
89  *
90  *      10/12/03  Ravindra              Made to work for Fedora Core 1 of
91  *                                      Red Hat Distribution
92  *
93  *      06/01/05  Alan Cox              Merged the ISI and base kernel strands
94  *                                      into a single 2.6 driver
95  *
96  *      ***********************************************************
97  *
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
101  *
102  *      You can find the original tools for this direct from Multitech
103  *              ftp://ftp.multitech.com/ISI-Cards/
104  *
105  *      Having installed the cards the module options (/etc/modprobe.conf)
106  *
107  *      options isicom   io=card1,card2,card3,card4 irq=card1,card2,card3,card4
108  *
109  *      Omit those entries for boards you don't have installed.
110  *
111  *      TODO
112  *              Merge testing
113  *              64-bit verification
114  */
115
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/smp_lock.h>
126 #include <linux/mm.h>
127 #include <linux/interrupt.h>
128 #include <linux/timer.h>
129 #include <linux/delay.h>
130 #include <linux/ioport.h>
131
132 #include <linux/uaccess.h>
133 #include <linux/io.h>
134 #include <asm/system.h>
135
136 #include <linux/pci.h>
137
138 #include <linux/isicom.h>
139
140 #define InterruptTheCard(base) outw(0, (base) + 0xc)
141 #define ClearInterrupt(base) inw((base) + 0x0a)
142
143 #define pr_dbg(str...) pr_debug("ISICOM: " str)
144 #ifdef DEBUG
145 #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c))
146 #else
147 #define isicom_paranoia_check(a, b, c) 0
148 #endif
149
150 static int isicom_probe(struct pci_dev *, const struct pci_device_id *);
151 static void __devexit isicom_remove(struct pci_dev *);
152
153 static struct pci_device_id isicom_pci_tbl[] = {
154         { PCI_DEVICE(VENDOR_ID, 0x2028) },
155         { PCI_DEVICE(VENDOR_ID, 0x2051) },
156         { PCI_DEVICE(VENDOR_ID, 0x2052) },
157         { PCI_DEVICE(VENDOR_ID, 0x2053) },
158         { PCI_DEVICE(VENDOR_ID, 0x2054) },
159         { PCI_DEVICE(VENDOR_ID, 0x2055) },
160         { PCI_DEVICE(VENDOR_ID, 0x2056) },
161         { PCI_DEVICE(VENDOR_ID, 0x2057) },
162         { PCI_DEVICE(VENDOR_ID, 0x2058) },
163         { 0 }
164 };
165 MODULE_DEVICE_TABLE(pci, isicom_pci_tbl);
166
167 static struct pci_driver isicom_driver = {
168         .name           = "isicom",
169         .id_table       = isicom_pci_tbl,
170         .probe          = isicom_probe,
171         .remove         = __devexit_p(isicom_remove)
172 };
173
174 static int prev_card = 3;       /*      start servicing isi_card[0]     */
175 static struct tty_driver *isicom_normal;
176
177 static void isicom_tx(unsigned long _data);
178 static void isicom_start(struct tty_struct *tty);
179
180 static DEFINE_TIMER(tx, isicom_tx, 0, 0);
181
182 /*   baud index mappings from linux defns to isi */
183
184 static signed char linuxb_to_isib[] = {
185         -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21
186 };
187
188 struct  isi_board {
189         unsigned long           base;
190         int                     irq;
191         unsigned char           port_count;
192         unsigned short          status;
193         unsigned short          port_status; /* each bit for each port */
194         unsigned short          shift_count;
195         struct isi_port         *ports;
196         signed char             count;
197         spinlock_t              card_lock; /* Card wide lock 11/5/00 -sameer */
198         unsigned long           flags;
199         unsigned int            index;
200 };
201
202 struct  isi_port {
203         unsigned short          magic;
204         struct tty_port         port;
205         u16                     channel;
206         u16                     status;
207         struct isi_board        *card;
208         unsigned char           *xmit_buf;
209         int                     xmit_head;
210         int                     xmit_tail;
211         int                     xmit_cnt;
212 };
213
214 static struct isi_board isi_card[BOARD_COUNT];
215 static struct isi_port  isi_ports[PORT_COUNT];
216
217 /*
218  *      Locking functions for card level locking. We need to own both
219  *      the kernel lock for the card and have the card in a position that
220  *      it wants to talk.
221  */
222
223 static inline int WaitTillCardIsFree(unsigned long base)
224 {
225         unsigned int count = 0;
226         unsigned int a = in_atomic(); /* do we run under spinlock? */
227
228         while (!(inw(base + 0xe) & 0x1) && count++ < 100)
229                 if (a)
230                         mdelay(1);
231                 else
232                         msleep(1);
233
234         return !(inw(base + 0xe) & 0x1);
235 }
236
237 static int lock_card(struct isi_board *card)
238 {
239         unsigned long base = card->base;
240         unsigned int retries, a;
241
242         for (retries = 0; retries < 10; retries++) {
243                 spin_lock_irqsave(&card->card_lock, card->flags);
244                 for (a = 0; a < 10; a++) {
245                         if (inw(base + 0xe) & 0x1)
246                                 return 1;
247                         udelay(10);
248                 }
249                 spin_unlock_irqrestore(&card->card_lock, card->flags);
250                 msleep(10);
251         }
252         printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%lx)\n",
253                 card->base);
254
255         return 0;       /* Failed to acquire the card! */
256 }
257
258 static void unlock_card(struct isi_board *card)
259 {
260         spin_unlock_irqrestore(&card->card_lock, card->flags);
261 }
262
263 /*
264  *  ISI Card specific ops ...
265  */
266
267 /* card->lock HAS to be held */
268 static void raise_dtr(struct isi_port *port)
269 {
270         struct isi_board *card = port->card;
271         unsigned long base = card->base;
272         u16 channel = port->channel;
273
274         if (WaitTillCardIsFree(base))
275                 return;
276
277         outw(0x8000 | (channel << card->shift_count) | 0x02, base);
278         outw(0x0504, base);
279         InterruptTheCard(base);
280         port->status |= ISI_DTR;
281 }
282
283 /* card->lock HAS to be held */
284 static inline void drop_dtr(struct isi_port *port)
285 {
286         struct isi_board *card = port->card;
287         unsigned long base = card->base;
288         u16 channel = port->channel;
289
290         if (WaitTillCardIsFree(base))
291                 return;
292
293         outw(0x8000 | (channel << card->shift_count) | 0x02, base);
294         outw(0x0404, base);
295         InterruptTheCard(base);
296         port->status &= ~ISI_DTR;
297 }
298
299 /* card->lock HAS to be held */
300 static inline void raise_rts(struct isi_port *port)
301 {
302         struct isi_board *card = port->card;
303         unsigned long base = card->base;
304         u16 channel = port->channel;
305
306         if (WaitTillCardIsFree(base))
307                 return;
308
309         outw(0x8000 | (channel << card->shift_count) | 0x02, base);
310         outw(0x0a04, base);
311         InterruptTheCard(base);
312         port->status |= ISI_RTS;
313 }
314
315 /* card->lock HAS to be held */
316 static inline void drop_rts(struct isi_port *port)
317 {
318         struct isi_board *card = port->card;
319         unsigned long base = card->base;
320         u16 channel = port->channel;
321
322         if (WaitTillCardIsFree(base))
323                 return;
324
325         outw(0x8000 | (channel << card->shift_count) | 0x02, base);
326         outw(0x0804, base);
327         InterruptTheCard(base);
328         port->status &= ~ISI_RTS;
329 }
330
331 /* card->lock MUST NOT be held */
332
333 static void isicom_dtr_rts(struct tty_port *port, int on)
334 {
335         struct isi_port *ip = container_of(port, struct isi_port, port);
336         struct isi_board *card = ip->card;
337         unsigned long base = card->base;
338         u16 channel = ip->channel;
339
340         if (!lock_card(card))
341                 return;
342
343         if (on) {
344                 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
345                 outw(0x0f04, base);
346                 InterruptTheCard(base);
347                 ip->status |= (ISI_DTR | ISI_RTS);
348         } else {
349                 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
350                 outw(0x0C04, base);
351                 InterruptTheCard(base);
352                 ip->status &= ~(ISI_DTR | ISI_RTS);
353         }
354         unlock_card(card);
355 }
356
357 /* card->lock HAS to be held */
358 static void drop_dtr_rts(struct isi_port *port)
359 {
360         struct isi_board *card = port->card;
361         unsigned long base = card->base;
362         u16 channel = port->channel;
363
364         if (WaitTillCardIsFree(base))
365                 return;
366
367         outw(0x8000 | (channel << card->shift_count) | 0x02, base);
368         outw(0x0c04, base);
369         InterruptTheCard(base);
370         port->status &= ~(ISI_RTS | ISI_DTR);
371 }
372
373 /*
374  *      ISICOM Driver specific routines ...
375  *
376  */
377
378 static inline int __isicom_paranoia_check(struct isi_port const *port,
379         char *name, const char *routine)
380 {
381         if (!port) {
382                 printk(KERN_WARNING "ISICOM: Warning: bad isicom magic for "
383                         "dev %s in %s.\n", name, routine);
384                 return 1;
385         }
386         if (port->magic != ISICOM_MAGIC) {
387                 printk(KERN_WARNING "ISICOM: Warning: NULL isicom port for "
388                         "dev %s in %s.\n", name, routine);
389                 return 1;
390         }
391
392         return 0;
393 }
394
395 /*
396  *      Transmitter.
397  *
398  *      We shovel data into the card buffers on a regular basis. The card
399  *      will do the rest of the work for us.
400  */
401
402 static void isicom_tx(unsigned long _data)
403 {
404         unsigned long flags, base;
405         unsigned int retries;
406         short count = (BOARD_COUNT-1), card;
407         short txcount, wrd, residue, word_count, cnt;
408         struct isi_port *port;
409         struct tty_struct *tty;
410
411         /*      find next active board  */
412         card = (prev_card + 1) & 0x0003;
413         while (count-- > 0) {
414                 if (isi_card[card].status & BOARD_ACTIVE)
415                         break;
416                 card = (card + 1) & 0x0003;
417         }
418         if (!(isi_card[card].status & BOARD_ACTIVE))
419                 goto sched_again;
420
421         prev_card = card;
422
423         count = isi_card[card].port_count;
424         port = isi_card[card].ports;
425         base = isi_card[card].base;
426
427         spin_lock_irqsave(&isi_card[card].card_lock, flags);
428         for (retries = 0; retries < 100; retries++) {
429                 if (inw(base + 0xe) & 0x1)
430                         break;
431                 udelay(2);
432         }
433         if (retries >= 100)
434                 goto unlock;
435
436         tty = tty_port_tty_get(&port->port);
437         if (tty == NULL)
438                 goto put_unlock;
439
440         for (; count > 0; count--, port++) {
441                 /* port not active or tx disabled to force flow control */
442                 if (!(port->port.flags & ASYNC_INITIALIZED) ||
443                                 !(port->status & ISI_TXOK))
444                         continue;
445
446                 txcount = min_t(short, TX_SIZE, port->xmit_cnt);
447                 if (txcount <= 0 || tty->stopped || tty->hw_stopped)
448                         continue;
449
450                 if (!(inw(base + 0x02) & (1 << port->channel)))
451                         continue;
452
453                 pr_dbg("txing %d bytes, port%d.\n", txcount,
454                         port->channel + 1);
455                 outw((port->channel << isi_card[card].shift_count) | txcount,
456                         base);
457                 residue = NO;
458                 wrd = 0;
459                 while (1) {
460                         cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE
461                                         - port->xmit_tail));
462                         if (residue == YES) {
463                                 residue = NO;
464                                 if (cnt > 0) {
465                                         wrd |= (port->port.xmit_buf[port->xmit_tail]
466                                                                         << 8);
467                                         port->xmit_tail = (port->xmit_tail + 1)
468                                                 & (SERIAL_XMIT_SIZE - 1);
469                                         port->xmit_cnt--;
470                                         txcount--;
471                                         cnt--;
472                                         outw(wrd, base);
473                                 } else {
474                                         outw(wrd, base);
475                                         break;
476                                 }
477                         }
478                         if (cnt <= 0)
479                                 break;
480                         word_count = cnt >> 1;
481                         outsw(base, port->port.xmit_buf+port->xmit_tail, word_count);
482                         port->xmit_tail = (port->xmit_tail
483                                 + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
484                         txcount -= (word_count << 1);
485                         port->xmit_cnt -= (word_count << 1);
486                         if (cnt & 0x0001) {
487                                 residue = YES;
488                                 wrd = port->port.xmit_buf[port->xmit_tail];
489                                 port->xmit_tail = (port->xmit_tail + 1)
490                                         & (SERIAL_XMIT_SIZE - 1);
491                                 port->xmit_cnt--;
492                                 txcount--;
493                         }
494                 }
495
496                 InterruptTheCard(base);
497                 if (port->xmit_cnt <= 0)
498                         port->status &= ~ISI_TXOK;
499                 if (port->xmit_cnt <= WAKEUP_CHARS)
500                         tty_wakeup(tty);
501         }
502
503 put_unlock:
504         tty_kref_put(tty);
505 unlock:
506         spin_unlock_irqrestore(&isi_card[card].card_lock, flags);
507         /*      schedule another tx for hopefully in about 10ms */
508 sched_again:
509         mod_timer(&tx, jiffies + msecs_to_jiffies(10));
510 }
511
512 /*
513  *      Main interrupt handler routine
514  */
515
516 static irqreturn_t isicom_interrupt(int irq, void *dev_id)
517 {
518         struct isi_board *card = dev_id;
519         struct isi_port *port;
520         struct tty_struct *tty;
521         unsigned long base;
522         u16 header, word_count, count, channel;
523         short byte_count;
524         unsigned char *rp;
525
526         if (!card || !(card->status & FIRMWARE_LOADED))
527                 return IRQ_NONE;
528
529         base = card->base;
530
531         /* did the card interrupt us? */
532         if (!(inw(base + 0x0e) & 0x02))
533                 return IRQ_NONE;
534
535         spin_lock(&card->card_lock);
536
537         /*
538          * disable any interrupts from the PCI card and lower the
539          * interrupt line
540          */
541         outw(0x8000, base+0x04);
542         ClearInterrupt(base);
543
544         inw(base);              /* get the dummy word out */
545         header = inw(base);
546         channel = (header & 0x7800) >> card->shift_count;
547         byte_count = header & 0xff;
548
549         if (channel + 1 > card->port_count) {
550                 printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): "
551                         "%d(channel) > port_count.\n", base, channel+1);
552                 outw(0x0000, base+0x04); /* enable interrupts */
553                 spin_unlock(&card->card_lock);
554                 return IRQ_HANDLED;
555         }
556         port = card->ports + channel;
557         if (!(port->port.flags & ASYNC_INITIALIZED)) {
558                 outw(0x0000, base+0x04); /* enable interrupts */
559                 spin_unlock(&card->card_lock);
560                 return IRQ_HANDLED;
561         }
562
563         tty = tty_port_tty_get(&port->port);
564         if (tty == NULL) {
565                 word_count = byte_count >> 1;
566                 while (byte_count > 1) {
567                         inw(base);
568                         byte_count -= 2;
569                 }
570                 if (byte_count & 0x01)
571                         inw(base);
572                 outw(0x0000, base+0x04); /* enable interrupts */
573                 spin_unlock(&card->card_lock);
574                 return IRQ_HANDLED;
575         }
576
577         if (header & 0x8000) {          /* Status Packet */
578                 header = inw(base);
579                 switch (header & 0xff) {
580                 case 0: /* Change in EIA signals */
581                         if (port->port.flags & ASYNC_CHECK_CD) {
582                                 if (port->status & ISI_DCD) {
583                                         if (!(header & ISI_DCD)) {
584                                         /* Carrier has been lost  */
585                                                 pr_dbg("interrupt: DCD->low.\n"
586                                                         );
587                                                 port->status &= ~ISI_DCD;
588                                                 tty_hangup(tty);
589                                         }
590                                 } else if (header & ISI_DCD) {
591                                 /* Carrier has been detected */
592                                         pr_dbg("interrupt: DCD->high.\n");
593                                         port->status |= ISI_DCD;
594                                         wake_up_interruptible(&port->port.open_wait);
595                                 }
596                         } else {
597                                 if (header & ISI_DCD)
598                                         port->status |= ISI_DCD;
599                                 else
600                                         port->status &= ~ISI_DCD;
601                         }
602
603                         if (port->port.flags & ASYNC_CTS_FLOW) {
604                                 if (tty->hw_stopped) {
605                                         if (header & ISI_CTS) {
606                                                 port->port.tty->hw_stopped = 0;
607                                                 /* start tx ing */
608                                                 port->status |= (ISI_TXOK
609                                                         | ISI_CTS);
610                                                 tty_wakeup(tty);
611                                         }
612                                 } else if (!(header & ISI_CTS)) {
613                                         tty->hw_stopped = 1;
614                                         /* stop tx ing */
615                                         port->status &= ~(ISI_TXOK | ISI_CTS);
616                                 }
617                         } else {
618                                 if (header & ISI_CTS)
619                                         port->status |= ISI_CTS;
620                                 else
621                                         port->status &= ~ISI_CTS;
622                         }
623
624                         if (header & ISI_DSR)
625                                 port->status |= ISI_DSR;
626                         else
627                                 port->status &= ~ISI_DSR;
628
629                         if (header & ISI_RI)
630                                 port->status |= ISI_RI;
631                         else
632                                 port->status &= ~ISI_RI;
633
634                         break;
635
636                 case 1: /* Received Break !!! */
637                         tty_insert_flip_char(tty, 0, TTY_BREAK);
638                         if (port->port.flags & ASYNC_SAK)
639                                 do_SAK(tty);
640                         tty_flip_buffer_push(tty);
641                         break;
642
643                 case 2: /* Statistics            */
644                         pr_dbg("isicom_interrupt: stats!!!.\n");
645                         break;
646
647                 default:
648                         pr_dbg("Intr: Unknown code in status packet.\n");
649                         break;
650                 }
651         } else {                                /* Data   Packet */
652
653                 count = tty_prepare_flip_string(tty, &rp, byte_count & ~1);
654                 pr_dbg("Intr: Can rx %d of %d bytes.\n", count, byte_count);
655                 word_count = count >> 1;
656                 insw(base, rp, word_count);
657                 byte_count -= (word_count << 1);
658                 if (count & 0x0001) {
659                         tty_insert_flip_char(tty,  inw(base) & 0xff,
660                                 TTY_NORMAL);
661                         byte_count -= 2;
662                 }
663                 if (byte_count > 0) {
664                         pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping "
665                                 "bytes...\n", base, channel + 1);
666                 /* drain out unread xtra data */
667                 while (byte_count > 0) {
668                                 inw(base);
669                                 byte_count -= 2;
670                         }
671                 }
672                 tty_flip_buffer_push(tty);
673         }
674         outw(0x0000, base+0x04); /* enable interrupts */
675         spin_unlock(&card->card_lock);
676         tty_kref_put(tty);
677
678         return IRQ_HANDLED;
679 }
680
681 static void isicom_config_port(struct tty_struct *tty)
682 {
683         struct isi_port *port = tty->driver_data;
684         struct isi_board *card = port->card;
685         unsigned long baud;
686         unsigned long base = card->base;
687         u16 channel_setup, channel = port->channel,
688                 shift_count = card->shift_count;
689         unsigned char flow_ctrl;
690
691         /* FIXME: Switch to new tty baud API */
692         baud = C_BAUD(tty);
693         if (baud & CBAUDEX) {
694                 baud &= ~CBAUDEX;
695
696                 /*  if CBAUDEX bit is on and the baud is set to either 50 or 75
697                  *  then the card is programmed for 57.6Kbps or 115Kbps
698                  *  respectively.
699                  */
700
701                 /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
702                 if (baud < 1 || baud > 4)
703                         tty->termios->c_cflag &= ~CBAUDEX;
704                 else
705                         baud += 15;
706         }
707         if (baud == 15) {
708
709                 /*  the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set
710                  *  by the set_serial_info ioctl ... this is done by
711                  *  the 'setserial' utility.
712                  */
713
714                 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
715                         baud++; /*  57.6 Kbps */
716                 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
717                         baud += 2; /*  115  Kbps */
718                 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
719                         baud += 3; /* 230 kbps*/
720                 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
721                         baud += 4; /* 460 kbps*/
722         }
723         if (linuxb_to_isib[baud] == -1) {
724                 /* hang up */
725                 drop_dtr(port);
726                 return;
727         } else
728                 raise_dtr(port);
729
730         if (WaitTillCardIsFree(base) == 0) {
731                 outw(0x8000 | (channel << shift_count) | 0x03, base);
732                 outw(linuxb_to_isib[baud] << 8 | 0x03, base);
733                 channel_setup = 0;
734                 switch (C_CSIZE(tty)) {
735                 case CS5:
736                         channel_setup |= ISICOM_CS5;
737                         break;
738                 case CS6:
739                         channel_setup |= ISICOM_CS6;
740                         break;
741                 case CS7:
742                         channel_setup |= ISICOM_CS7;
743                         break;
744                 case CS8:
745                         channel_setup |= ISICOM_CS8;
746                         break;
747                 }
748
749                 if (C_CSTOPB(tty))
750                         channel_setup |= ISICOM_2SB;
751                 if (C_PARENB(tty)) {
752                         channel_setup |= ISICOM_EVPAR;
753                         if (C_PARODD(tty))
754                                 channel_setup |= ISICOM_ODPAR;
755                 }
756                 outw(channel_setup, base);
757                 InterruptTheCard(base);
758         }
759         if (C_CLOCAL(tty))
760                 port->port.flags &= ~ASYNC_CHECK_CD;
761         else
762                 port->port.flags |= ASYNC_CHECK_CD;
763
764         /* flow control settings ...*/
765         flow_ctrl = 0;
766         port->port.flags &= ~ASYNC_CTS_FLOW;
767         if (C_CRTSCTS(tty)) {
768                 port->port.flags |= ASYNC_CTS_FLOW;
769                 flow_ctrl |= ISICOM_CTSRTS;
770         }
771         if (I_IXON(tty))
772                 flow_ctrl |= ISICOM_RESPOND_XONXOFF;
773         if (I_IXOFF(tty))
774                 flow_ctrl |= ISICOM_INITIATE_XONXOFF;
775
776         if (WaitTillCardIsFree(base) == 0) {
777                 outw(0x8000 | (channel << shift_count) | 0x04, base);
778                 outw(flow_ctrl << 8 | 0x05, base);
779                 outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
780                 InterruptTheCard(base);
781         }
782
783         /*      rx enabled -> enable port for rx on the card    */
784         if (C_CREAD(tty)) {
785                 card->port_status |= (1 << channel);
786                 outw(card->port_status, base + 0x02);
787         }
788 }
789
790 /* open et all */
791
792 static inline void isicom_setup_board(struct isi_board *bp)
793 {
794         int channel;
795         struct isi_port *port;
796         unsigned long flags;
797
798         spin_lock_irqsave(&bp->card_lock, flags);
799         if (bp->status & BOARD_ACTIVE) {
800                 spin_unlock_irqrestore(&bp->card_lock, flags);
801                 return;
802         }
803         port = bp->ports;
804         bp->status |= BOARD_ACTIVE;
805         for (channel = 0; channel < bp->port_count; channel++, port++)
806                 drop_dtr_rts(port);
807         spin_unlock_irqrestore(&bp->card_lock, flags);
808 }
809
810 static int isicom_setup_port(struct tty_struct *tty)
811 {
812         struct isi_port *port = tty->driver_data;
813         struct isi_board *card = port->card;
814         unsigned long flags;
815
816         if (port->port.flags & ASYNC_INITIALIZED)
817                 return 0;
818         if (tty_port_alloc_xmit_buf(&port->port) < 0)
819                 return -ENOMEM;
820
821         spin_lock_irqsave(&card->card_lock, flags);
822         clear_bit(TTY_IO_ERROR, &tty->flags);
823         if (port->port.count == 1)
824                 card->count++;
825
826         port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
827
828         /*      discard any residual data       */
829         if (WaitTillCardIsFree(card->base) == 0) {
830                 outw(0x8000 | (port->channel << card->shift_count) | 0x02,
831                                 card->base);
832                 outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base);
833                 InterruptTheCard(card->base);
834         }
835
836         isicom_config_port(tty);
837         port->port.flags |= ASYNC_INITIALIZED;
838         spin_unlock_irqrestore(&card->card_lock, flags);
839
840         return 0;
841 }
842
843 static int isicom_carrier_raised(struct tty_port *port)
844 {
845         struct isi_port *ip = container_of(port, struct isi_port, port);
846         return (ip->status & ISI_DCD)?1 : 0;
847 }
848
849 static struct tty_port *isicom_find_port(struct tty_struct *tty)
850 {
851         struct isi_port *port;
852         struct isi_board *card;
853         unsigned int board;
854         int line = tty->index;
855
856         if (line < 0 || line > PORT_COUNT-1)
857                 return NULL;
858         board = BOARD(line);
859         card = &isi_card[board];
860
861         if (!(card->status & FIRMWARE_LOADED))
862                 return NULL;
863
864         /*  open on a port greater than the port count for the card !!! */
865         if (line > ((board * 16) + card->port_count - 1))
866                 return NULL;
867
868         port = &isi_ports[line];
869         if (isicom_paranoia_check(port, tty->name, "isicom_open"))
870                 return NULL;
871
872         return &port->port;
873 }
874         
875 static int isicom_open(struct tty_struct *tty, struct file *filp)
876 {
877         struct isi_port *port;
878         struct isi_board *card;
879         struct tty_port *tport;
880         int error = 0;
881
882         tport = isicom_find_port(tty);
883         if (tport == NULL)
884                 return -ENODEV;
885         port = container_of(tport, struct isi_port, port);
886         card = &isi_card[BOARD(tty->index)];
887         isicom_setup_board(card);
888
889         /* FIXME: locking on port.count etc */
890         port->port.count++;
891         tty->driver_data = port;
892         tty_port_tty_set(&port->port, tty);
893         /* FIXME: Locking on Initialized flag */
894         if (!test_bit(ASYNCB_INITIALIZED, &tport->flags))
895                 error = isicom_setup_port(tty);
896         if (error == 0)
897                 error = tty_port_block_til_ready(&port->port, tty, filp);
898         return error;
899 }
900
901 /* close et all */
902
903 static inline void isicom_shutdown_board(struct isi_board *bp)
904 {
905         if (bp->status & BOARD_ACTIVE)
906                 bp->status &= ~BOARD_ACTIVE;
907 }
908
909 /* card->lock HAS to be held */
910 static void isicom_shutdown_port(struct isi_port *port)
911 {
912         struct isi_board *card = port->card;
913         struct tty_struct *tty;
914
915         tty = tty_port_tty_get(&port->port);
916
917         if (!(port->port.flags & ASYNC_INITIALIZED)) {
918                 tty_kref_put(tty);
919                 return;
920         }
921
922         tty_port_free_xmit_buf(&port->port);
923         port->port.flags &= ~ASYNC_INITIALIZED;
924         /* 3rd October 2000 : Vinayak P Risbud */
925         tty_port_tty_set(&port->port, NULL);
926
927         /*Fix done by Anil .S on 30-04-2001
928         remote login through isi port has dtr toggle problem
929         due to which the carrier drops before the password prompt
930         appears on the remote end. Now we drop the dtr only if the
931         HUPCL(Hangup on close) flag is set for the tty*/
932
933         if (C_HUPCL(tty))
934                 /* drop dtr on this port */
935                 drop_dtr(port);
936
937         /* any other port uninits  */
938         if (tty)
939                 set_bit(TTY_IO_ERROR, &tty->flags);
940
941         if (--card->count < 0) {
942                 pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n",
943                         card->base, card->count);
944                 card->count = 0;
945         }
946
947         /* last port was closed, shutdown that boad too */
948         if (C_HUPCL(tty)) {
949                 if (!card->count)
950                         isicom_shutdown_board(card);
951         }
952         tty_kref_put(tty);
953 }
954
955 static void isicom_flush_buffer(struct tty_struct *tty)
956 {
957         struct isi_port *port = tty->driver_data;
958         struct isi_board *card = port->card;
959         unsigned long flags;
960
961         if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
962                 return;
963
964         spin_lock_irqsave(&card->card_lock, flags);
965         port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
966         spin_unlock_irqrestore(&card->card_lock, flags);
967
968         tty_wakeup(tty);
969 }
970
971 static void isicom_close_port(struct tty_port *port)
972 {
973         struct isi_port *ip = container_of(port, struct isi_port, port);
974         struct isi_board *card = ip->card;
975         unsigned long flags;
976
977         /* indicate to the card that no more data can be received
978            on this port */
979         spin_lock_irqsave(&card->card_lock, flags);
980         if (port->flags & ASYNC_INITIALIZED) {
981                 card->port_status &= ~(1 << ip->channel);
982                 outw(card->port_status, card->base + 0x02);
983         }
984         isicom_shutdown_port(ip);
985         spin_unlock_irqrestore(&card->card_lock, flags);
986 }
987
988 static void isicom_close(struct tty_struct *tty, struct file *filp)
989 {
990         struct isi_port *ip = tty->driver_data;
991         struct tty_port *port = &ip->port;
992         if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
993                 return;
994
995         if (tty_port_close_start(port, tty, filp) == 0)
996                 return;
997         isicom_close_port(port);
998         isicom_flush_buffer(tty);
999         tty_port_close_end(port, tty);
1000 }
1001
1002 /* write et all */
1003 static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
1004         int count)
1005 {
1006         struct isi_port *port = tty->driver_data;
1007         struct isi_board *card = port->card;
1008         unsigned long flags;
1009         int cnt, total = 0;
1010
1011         if (isicom_paranoia_check(port, tty->name, "isicom_write"))
1012                 return 0;
1013
1014         spin_lock_irqsave(&card->card_lock, flags);
1015
1016         while (1) {
1017                 cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
1018                                 - 1, SERIAL_XMIT_SIZE - port->xmit_head));
1019                 if (cnt <= 0)
1020                         break;
1021
1022                 memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt);
1023                 port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
1024                         - 1);
1025                 port->xmit_cnt += cnt;
1026                 buf += cnt;
1027                 count -= cnt;
1028                 total += cnt;
1029         }
1030         if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped)
1031                 port->status |= ISI_TXOK;
1032         spin_unlock_irqrestore(&card->card_lock, flags);
1033         return total;
1034 }
1035
1036 /* put_char et all */
1037 static int isicom_put_char(struct tty_struct *tty, unsigned char ch)
1038 {
1039         struct isi_port *port = tty->driver_data;
1040         struct isi_board *card = port->card;
1041         unsigned long flags;
1042
1043         if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
1044                 return 0;
1045
1046         spin_lock_irqsave(&card->card_lock, flags);
1047         if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
1048                 spin_unlock_irqrestore(&card->card_lock, flags);
1049                 return 0;
1050         }
1051
1052         port->port.xmit_buf[port->xmit_head++] = ch;
1053         port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
1054         port->xmit_cnt++;
1055         spin_unlock_irqrestore(&card->card_lock, flags);
1056         return 1;
1057 }
1058
1059 /* flush_chars et all */
1060 static void isicom_flush_chars(struct tty_struct *tty)
1061 {
1062         struct isi_port *port = tty->driver_data;
1063
1064         if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars"))
1065                 return;
1066
1067         if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1068                         !port->port.xmit_buf)
1069                 return;
1070
1071         /* this tells the transmitter to consider this port for
1072            data output to the card ... that's the best we can do. */
1073         port->status |= ISI_TXOK;
1074 }
1075
1076 /* write_room et all */
1077 static int isicom_write_room(struct tty_struct *tty)
1078 {
1079         struct isi_port *port = tty->driver_data;
1080         int free;
1081
1082         if (isicom_paranoia_check(port, tty->name, "isicom_write_room"))
1083                 return 0;
1084
1085         free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1086         if (free < 0)
1087                 free = 0;
1088         return free;
1089 }
1090
1091 /* chars_in_buffer et all */
1092 static int isicom_chars_in_buffer(struct tty_struct *tty)
1093 {
1094         struct isi_port *port = tty->driver_data;
1095         if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer"))
1096                 return 0;
1097         return port->xmit_cnt;
1098 }
1099
1100 /* ioctl et all */
1101 static int isicom_send_break(struct tty_struct *tty, int length)
1102 {
1103         struct isi_port *port = tty->driver_data;
1104         struct isi_board *card = port->card;
1105         unsigned long base = card->base;
1106
1107         if (length == -1)
1108                 return -EOPNOTSUPP;
1109
1110         if (!lock_card(card))
1111                 return -EINVAL;
1112
1113         outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
1114         outw((length & 0xff) << 8 | 0x00, base);
1115         outw((length & 0xff00), base);
1116         InterruptTheCard(base);
1117
1118         unlock_card(card);
1119         return 0;
1120 }
1121
1122 static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
1123 {
1124         struct isi_port *port = tty->driver_data;
1125         /* just send the port status */
1126         u16 status = port->status;
1127
1128         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1129                 return -ENODEV;
1130
1131         return  ((status & ISI_RTS) ? TIOCM_RTS : 0) |
1132                 ((status & ISI_DTR) ? TIOCM_DTR : 0) |
1133                 ((status & ISI_DCD) ? TIOCM_CAR : 0) |
1134                 ((status & ISI_DSR) ? TIOCM_DSR : 0) |
1135                 ((status & ISI_CTS) ? TIOCM_CTS : 0) |
1136                 ((status & ISI_RI ) ? TIOCM_RI  : 0);
1137 }
1138
1139 static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
1140         unsigned int set, unsigned int clear)
1141 {
1142         struct isi_port *port = tty->driver_data;
1143         unsigned long flags;
1144
1145         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1146                 return -ENODEV;
1147
1148         spin_lock_irqsave(&port->card->card_lock, flags);
1149         if (set & TIOCM_RTS)
1150                 raise_rts(port);
1151         if (set & TIOCM_DTR)
1152                 raise_dtr(port);
1153
1154         if (clear & TIOCM_RTS)
1155                 drop_rts(port);
1156         if (clear & TIOCM_DTR)
1157                 drop_dtr(port);
1158         spin_unlock_irqrestore(&port->card->card_lock, flags);
1159
1160         return 0;
1161 }
1162
1163 static int isicom_set_serial_info(struct tty_struct *tty,
1164                                         struct serial_struct __user *info)
1165 {
1166         struct isi_port *port = tty->driver_data;
1167         struct serial_struct newinfo;
1168         int reconfig_port;
1169
1170         if (copy_from_user(&newinfo, info, sizeof(newinfo)))
1171                 return -EFAULT;
1172
1173         lock_kernel();
1174
1175         reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) !=
1176                 (newinfo.flags & ASYNC_SPD_MASK));
1177
1178         if (!capable(CAP_SYS_ADMIN)) {
1179                 if ((newinfo.close_delay != port->port.close_delay) ||
1180                                 (newinfo.closing_wait != port->port.closing_wait) ||
1181                                 ((newinfo.flags & ~ASYNC_USR_MASK) !=
1182                                 (port->port.flags & ~ASYNC_USR_MASK))) {
1183                         unlock_kernel();
1184                         return -EPERM;
1185                 }
1186                 port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1187                                 (newinfo.flags & ASYNC_USR_MASK));
1188         } else {
1189                 port->port.close_delay = newinfo.close_delay;
1190                 port->port.closing_wait = newinfo.closing_wait;
1191                 port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1192                                 (newinfo.flags & ASYNC_FLAGS));
1193         }
1194         if (reconfig_port) {
1195                 unsigned long flags;
1196                 spin_lock_irqsave(&port->card->card_lock, flags);
1197                 isicom_config_port(tty);
1198                 spin_unlock_irqrestore(&port->card->card_lock, flags);
1199         }
1200         unlock_kernel();
1201         return 0;
1202 }
1203
1204 static int isicom_get_serial_info(struct isi_port *port,
1205         struct serial_struct __user *info)
1206 {
1207         struct serial_struct out_info;
1208
1209         lock_kernel();
1210         memset(&out_info, 0, sizeof(out_info));
1211 /*      out_info.type = ? */
1212         out_info.line = port - isi_ports;
1213         out_info.port = port->card->base;
1214         out_info.irq = port->card->irq;
1215         out_info.flags = port->port.flags;
1216 /*      out_info.baud_base = ? */
1217         out_info.close_delay = port->port.close_delay;
1218         out_info.closing_wait = port->port.closing_wait;
1219         unlock_kernel();
1220         if (copy_to_user(info, &out_info, sizeof(out_info)))
1221                 return -EFAULT;
1222         return 0;
1223 }
1224
1225 static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1226         unsigned int cmd, unsigned long arg)
1227 {
1228         struct isi_port *port = tty->driver_data;
1229         void __user *argp = (void __user *)arg;
1230
1231         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1232                 return -ENODEV;
1233
1234         switch (cmd) {
1235         case TIOCGSERIAL:
1236                 return isicom_get_serial_info(port, argp);
1237
1238         case TIOCSSERIAL:
1239                 return isicom_set_serial_info(tty, argp);
1240
1241         default:
1242                 return -ENOIOCTLCMD;
1243         }
1244         return 0;
1245 }
1246
1247 /* set_termios et all */
1248 static void isicom_set_termios(struct tty_struct *tty,
1249         struct ktermios *old_termios)
1250 {
1251         struct isi_port *port = tty->driver_data;
1252         unsigned long flags;
1253
1254         if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
1255                 return;
1256
1257         if (tty->termios->c_cflag == old_termios->c_cflag &&
1258                         tty->termios->c_iflag == old_termios->c_iflag)
1259                 return;
1260
1261         spin_lock_irqsave(&port->card->card_lock, flags);
1262         isicom_config_port(tty);
1263         spin_unlock_irqrestore(&port->card->card_lock, flags);
1264
1265         if ((old_termios->c_cflag & CRTSCTS) &&
1266                         !(tty->termios->c_cflag & CRTSCTS)) {
1267                 tty->hw_stopped = 0;
1268                 isicom_start(tty);
1269         }
1270 }
1271
1272 /* throttle et all */
1273 static void isicom_throttle(struct tty_struct *tty)
1274 {
1275         struct isi_port *port = tty->driver_data;
1276         struct isi_board *card = port->card;
1277
1278         if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
1279                 return;
1280
1281         /* tell the card that this port cannot handle any more data for now */
1282         card->port_status &= ~(1 << port->channel);
1283         outw(card->port_status, card->base + 0x02);
1284 }
1285
1286 /* unthrottle et all */
1287 static void isicom_unthrottle(struct tty_struct *tty)
1288 {
1289         struct isi_port *port = tty->driver_data;
1290         struct isi_board *card = port->card;
1291
1292         if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
1293                 return;
1294
1295         /* tell the card that this port is ready to accept more data */
1296         card->port_status |= (1 << port->channel);
1297         outw(card->port_status, card->base + 0x02);
1298 }
1299
1300 /* stop et all */
1301 static void isicom_stop(struct tty_struct *tty)
1302 {
1303         struct isi_port *port = tty->driver_data;
1304
1305         if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
1306                 return;
1307
1308         /* this tells the transmitter not to consider this port for
1309            data output to the card. */
1310         port->status &= ~ISI_TXOK;
1311 }
1312
1313 /* start et all */
1314 static void isicom_start(struct tty_struct *tty)
1315 {
1316         struct isi_port *port = tty->driver_data;
1317
1318         if (isicom_paranoia_check(port, tty->name, "isicom_start"))
1319                 return;
1320
1321         /* this tells the transmitter to consider this port for
1322            data output to the card. */
1323         port->status |= ISI_TXOK;
1324 }
1325
1326 static void isicom_hangup(struct tty_struct *tty)
1327 {
1328         struct isi_port *port = tty->driver_data;
1329         unsigned long flags;
1330
1331         if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
1332                 return;
1333
1334         spin_lock_irqsave(&port->card->card_lock, flags);
1335         isicom_shutdown_port(port);
1336         spin_unlock_irqrestore(&port->card->card_lock, flags);
1337
1338         tty_port_hangup(&port->port);
1339 }
1340
1341
1342 /*
1343  * Driver init and deinit functions
1344  */
1345
1346 static const struct tty_operations isicom_ops = {
1347         .open                   = isicom_open,
1348         .close                  = isicom_close,
1349         .write                  = isicom_write,
1350         .put_char               = isicom_put_char,
1351         .flush_chars            = isicom_flush_chars,
1352         .write_room             = isicom_write_room,
1353         .chars_in_buffer        = isicom_chars_in_buffer,
1354         .ioctl                  = isicom_ioctl,
1355         .set_termios            = isicom_set_termios,
1356         .throttle               = isicom_throttle,
1357         .unthrottle             = isicom_unthrottle,
1358         .stop                   = isicom_stop,
1359         .start                  = isicom_start,
1360         .hangup                 = isicom_hangup,
1361         .flush_buffer           = isicom_flush_buffer,
1362         .tiocmget               = isicom_tiocmget,
1363         .tiocmset               = isicom_tiocmset,
1364         .break_ctl              = isicom_send_break,
1365 };
1366
1367 static const struct tty_port_operations isicom_port_ops = {
1368         .carrier_raised         = isicom_carrier_raised,
1369         .dtr_rts                = isicom_dtr_rts,
1370 };
1371
1372 static int __devinit reset_card(struct pci_dev *pdev,
1373         const unsigned int card, unsigned int *signature)
1374 {
1375         struct isi_board *board = pci_get_drvdata(pdev);
1376         unsigned long base = board->base;
1377         unsigned int sig, portcount = 0;
1378         int retval = 0;
1379
1380         dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
1381                 base);
1382
1383         inw(base + 0x8);
1384
1385         msleep(10);
1386
1387         outw(0, base + 0x8); /* Reset */
1388
1389         msleep(1000);
1390
1391         sig = inw(base + 0x4) & 0xff;
1392
1393         if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd &&
1394                         sig != 0xee) {
1395                 dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible "
1396                         "bad I/O Port Address 0x%lx).\n", card + 1, base);
1397                 dev_dbg(&pdev->dev, "Sig=0x%x\n", sig);
1398                 retval = -EIO;
1399                 goto end;
1400         }
1401
1402         msleep(10);
1403
1404         portcount = inw(base + 0x2);
1405         if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 &&
1406                                 portcount != 8 && portcount != 16)) {
1407                 dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
1408                         card + 1);
1409                 retval = -EIO;
1410                 goto end;
1411         }
1412
1413         switch (sig) {
1414         case 0xa5:
1415         case 0xbb:
1416         case 0xdd:
1417                 board->port_count = (portcount == 4) ? 4 : 8;
1418                 board->shift_count = 12;
1419                 break;
1420         case 0xcc:
1421         case 0xee:
1422                 board->port_count = 16;
1423                 board->shift_count = 11;
1424                 break;
1425         }
1426         dev_info(&pdev->dev, "-Done\n");
1427         *signature = sig;
1428
1429 end:
1430         return retval;
1431 }
1432
1433 static int __devinit load_firmware(struct pci_dev *pdev,
1434         const unsigned int index, const unsigned int signature)
1435 {
1436         struct isi_board *board = pci_get_drvdata(pdev);
1437         const struct firmware *fw;
1438         unsigned long base = board->base;
1439         unsigned int a;
1440         u16 word_count, status;
1441         int retval = -EIO;
1442         char *name;
1443         u8 *data;
1444
1445         struct stframe {
1446                 u16     addr;
1447                 u16     count;
1448                 u8      data[0];
1449         } *frame;
1450
1451         switch (signature) {
1452         case 0xa5:
1453                 name = "isi608.bin";
1454                 break;
1455         case 0xbb:
1456                 name = "isi608em.bin";
1457                 break;
1458         case 0xcc:
1459                 name = "isi616em.bin";
1460                 break;
1461         case 0xdd:
1462                 name = "isi4608.bin";
1463                 break;
1464         case 0xee:
1465                 name = "isi4616.bin";
1466                 break;
1467         default:
1468                 dev_err(&pdev->dev, "Unknown signature.\n");
1469                 goto end;
1470         }
1471
1472         retval = request_firmware(&fw, name, &pdev->dev);
1473         if (retval)
1474                 goto end;
1475
1476         retval = -EIO;
1477
1478         for (frame = (struct stframe *)fw->data;
1479                         frame < (struct stframe *)(fw->data + fw->size);
1480                         frame = (struct stframe *)((u8 *)(frame + 1) +
1481                                 frame->count)) {
1482                 if (WaitTillCardIsFree(base))
1483                         goto errrelfw;
1484
1485                 outw(0xf0, base);       /* start upload sequence */
1486                 outw(0x00, base);
1487                 outw(frame->addr, base); /* lsb of address */
1488
1489                 word_count = frame->count / 2 + frame->count % 2;
1490                 outw(word_count, base);
1491                 InterruptTheCard(base);
1492
1493                 udelay(100); /* 0x2f */
1494
1495                 if (WaitTillCardIsFree(base))
1496                         goto errrelfw;
1497
1498                 status = inw(base + 0x4);
1499                 if (status != 0) {
1500                         dev_warn(&pdev->dev, "Card%d rejected load header:\n"
1501                                  "Address:0x%x\n"
1502                                  "Count:0x%x\n"
1503                                  "Status:0x%x\n",
1504                                  index + 1, frame->addr, frame->count, status);
1505                         goto errrelfw;
1506                 }
1507                 outsw(base, frame->data, word_count);
1508
1509                 InterruptTheCard(base);
1510
1511                 udelay(50); /* 0x0f */
1512
1513                 if (WaitTillCardIsFree(base))
1514                         goto errrelfw;
1515
1516                 status = inw(base + 0x4);
1517                 if (status != 0) {
1518                         dev_err(&pdev->dev, "Card%d got out of sync.Card "
1519                                 "Status:0x%x\n", index + 1, status);
1520                         goto errrelfw;
1521                 }
1522         }
1523
1524 /* XXX: should we test it by reading it back and comparing with original like
1525  * in load firmware package? */
1526         for (frame = (struct stframe *)fw->data;
1527                         frame < (struct stframe *)(fw->data + fw->size);
1528                         frame = (struct stframe *)((u8 *)(frame + 1) +
1529                                 frame->count)) {
1530                 if (WaitTillCardIsFree(base))
1531                         goto errrelfw;
1532
1533                 outw(0xf1, base); /* start download sequence */
1534                 outw(0x00, base);
1535                 outw(frame->addr, base); /* lsb of address */
1536
1537                 word_count = (frame->count >> 1) + frame->count % 2;
1538                 outw(word_count + 1, base);
1539                 InterruptTheCard(base);
1540
1541                 udelay(50); /* 0xf */
1542
1543                 if (WaitTillCardIsFree(base))
1544                         goto errrelfw;
1545
1546                 status = inw(base + 0x4);
1547                 if (status != 0) {
1548                         dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
1549                                  "Address:0x%x\n"
1550                                  "Count:0x%x\n"
1551                                  "Status: 0x%x\n",
1552                                  index + 1, frame->addr, frame->count, status);
1553                         goto errrelfw;
1554                 }
1555
1556                 data = kmalloc(word_count * 2, GFP_KERNEL);
1557                 if (data == NULL) {
1558                         dev_err(&pdev->dev, "Card%d, firmware upload "
1559                                 "failed, not enough memory\n", index + 1);
1560                         goto errrelfw;
1561                 }
1562                 inw(base);
1563                 insw(base, data, word_count);
1564                 InterruptTheCard(base);
1565
1566                 for (a = 0; a < frame->count; a++)
1567                         if (data[a] != frame->data[a]) {
1568                                 kfree(data);
1569                                 dev_err(&pdev->dev, "Card%d, firmware upload "
1570                                         "failed\n", index + 1);
1571                                 goto errrelfw;
1572                         }
1573                 kfree(data);
1574
1575                 udelay(50); /* 0xf */
1576
1577                 if (WaitTillCardIsFree(base))
1578                         goto errrelfw;
1579
1580                 status = inw(base + 0x4);
1581                 if (status != 0) {
1582                         dev_err(&pdev->dev, "Card%d verify got out of sync. "
1583                                 "Card Status:0x%x\n", index + 1, status);
1584                         goto errrelfw;
1585                 }
1586         }
1587
1588         /* xfer ctrl */
1589         if (WaitTillCardIsFree(base))
1590                 goto errrelfw;
1591
1592         outw(0xf2, base);
1593         outw(0x800, base);
1594         outw(0x0, base);
1595         outw(0x0, base);
1596         InterruptTheCard(base);
1597         outw(0x0, base + 0x4); /* for ISI4608 cards */
1598
1599         board->status |= FIRMWARE_LOADED;
1600         retval = 0;
1601
1602 errrelfw:
1603         release_firmware(fw);
1604 end:
1605         return retval;
1606 }
1607
1608 /*
1609  *      Insmod can set static symbols so keep these static
1610  */
1611 static unsigned int card_count;
1612
1613 static int __devinit isicom_probe(struct pci_dev *pdev,
1614         const struct pci_device_id *ent)
1615 {
1616         unsigned int uninitialized_var(signature), index;
1617         int retval = -EPERM;
1618         struct isi_board *board = NULL;
1619
1620         if (card_count >= BOARD_COUNT)
1621                 goto err;
1622
1623         retval = pci_enable_device(pdev);
1624         if (retval) {
1625                 dev_err(&pdev->dev, "failed to enable\n");
1626                 goto err;
1627         }
1628
1629         dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
1630
1631         /* allot the first empty slot in the array */
1632         for (index = 0; index < BOARD_COUNT; index++)
1633                 if (isi_card[index].base == 0) {
1634                         board = &isi_card[index];
1635                         break;
1636                 }
1637
1638         board->index = index;
1639         board->base = pci_resource_start(pdev, 3);
1640         board->irq = pdev->irq;
1641         card_count++;
1642
1643         pci_set_drvdata(pdev, board);
1644
1645         retval = pci_request_region(pdev, 3, ISICOM_NAME);
1646         if (retval) {
1647                 dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
1648                         "will be disabled.\n", board->base, board->base + 15,
1649                         index + 1);
1650                 retval = -EBUSY;
1651                 goto errdec;
1652         }
1653
1654         retval = request_irq(board->irq, isicom_interrupt,
1655                         IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
1656         if (retval < 0) {
1657                 dev_err(&pdev->dev, "Could not install handler at Irq %d. "
1658                         "Card%d will be disabled.\n", board->irq, index + 1);
1659                 goto errunrr;
1660         }
1661
1662         retval = reset_card(pdev, index, &signature);
1663         if (retval < 0)
1664                 goto errunri;
1665
1666         retval = load_firmware(pdev, index, signature);
1667         if (retval < 0)
1668                 goto errunri;
1669
1670         for (index = 0; index < board->port_count; index++)
1671                 tty_register_device(isicom_normal, board->index * 16 + index,
1672                                 &pdev->dev);
1673
1674         return 0;
1675
1676 errunri:
1677         free_irq(board->irq, board);
1678 errunrr:
1679         pci_release_region(pdev, 3);
1680 errdec:
1681         board->base = 0;
1682         card_count--;
1683         pci_disable_device(pdev);
1684 err:
1685         return retval;
1686 }
1687
1688 static void __devexit isicom_remove(struct pci_dev *pdev)
1689 {
1690         struct isi_board *board = pci_get_drvdata(pdev);
1691         unsigned int i;
1692
1693         for (i = 0; i < board->port_count; i++)
1694                 tty_unregister_device(isicom_normal, board->index * 16 + i);
1695
1696         free_irq(board->irq, board);
1697         pci_release_region(pdev, 3);
1698         board->base = 0;
1699         card_count--;
1700         pci_disable_device(pdev);
1701 }
1702
1703 static int __init isicom_init(void)
1704 {
1705         int retval, idx, channel;
1706         struct isi_port *port;
1707
1708         for (idx = 0; idx < BOARD_COUNT; idx++) {
1709                 port = &isi_ports[idx * 16];
1710                 isi_card[idx].ports = port;
1711                 spin_lock_init(&isi_card[idx].card_lock);
1712                 for (channel = 0; channel < 16; channel++, port++) {
1713                         tty_port_init(&port->port);
1714                         port->port.ops = &isicom_port_ops;
1715                         port->magic = ISICOM_MAGIC;
1716                         port->card = &isi_card[idx];
1717                         port->channel = channel;
1718                         port->port.close_delay = 50 * HZ/100;
1719                         port->port.closing_wait = 3000 * HZ/100;
1720                         port->status = 0;
1721                         /*  . . .  */
1722                 }
1723                 isi_card[idx].base = 0;
1724                 isi_card[idx].irq = 0;
1725         }
1726
1727         /* tty driver structure initialization */
1728         isicom_normal = alloc_tty_driver(PORT_COUNT);
1729         if (!isicom_normal) {
1730                 retval = -ENOMEM;
1731                 goto error;
1732         }
1733
1734         isicom_normal->owner                    = THIS_MODULE;
1735         isicom_normal->name                     = "ttyM";
1736         isicom_normal->major                    = ISICOM_NMAJOR;
1737         isicom_normal->minor_start              = 0;
1738         isicom_normal->type                     = TTY_DRIVER_TYPE_SERIAL;
1739         isicom_normal->subtype                  = SERIAL_TYPE_NORMAL;
1740         isicom_normal->init_termios             = tty_std_termios;
1741         isicom_normal->init_termios.c_cflag     = B9600 | CS8 | CREAD | HUPCL |
1742                 CLOCAL;
1743         isicom_normal->flags                    = TTY_DRIVER_REAL_RAW |
1744                 TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK;
1745         tty_set_operations(isicom_normal, &isicom_ops);
1746
1747         retval = tty_register_driver(isicom_normal);
1748         if (retval) {
1749                 pr_dbg("Couldn't register the dialin driver\n");
1750                 goto err_puttty;
1751         }
1752
1753         retval = pci_register_driver(&isicom_driver);
1754         if (retval < 0) {
1755                 printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
1756                 goto err_unrtty;
1757         }
1758
1759         mod_timer(&tx, jiffies + 1);
1760
1761         return 0;
1762 err_unrtty:
1763         tty_unregister_driver(isicom_normal);
1764 err_puttty:
1765         put_tty_driver(isicom_normal);
1766 error:
1767         return retval;
1768 }
1769
1770 static void __exit isicom_exit(void)
1771 {
1772         del_timer_sync(&tx);
1773
1774         pci_unregister_driver(&isicom_driver);
1775         tty_unregister_driver(isicom_normal);
1776         put_tty_driver(isicom_normal);
1777 }
1778
1779 module_init(isicom_init);
1780 module_exit(isicom_exit);
1781
1782 MODULE_AUTHOR("MultiTech");
1783 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
1784 MODULE_LICENSE("GPL");