Merge branch 'fix/hda' into for-linus
[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 int isicom_open(struct tty_struct *tty, struct file *filp)
850 {
851         struct isi_port *port;
852         struct isi_board *card;
853         unsigned int board;
854         int error, line;
855
856         line = tty->index;
857         if (line < 0 || line > PORT_COUNT-1)
858                 return -ENODEV;
859         board = BOARD(line);
860         card = &isi_card[board];
861
862         if (!(card->status & FIRMWARE_LOADED))
863                 return -ENODEV;
864
865         /*  open on a port greater than the port count for the card !!! */
866         if (line > ((board * 16) + card->port_count - 1))
867                 return -ENODEV;
868
869         port = &isi_ports[line];
870         if (isicom_paranoia_check(port, tty->name, "isicom_open"))
871                 return -ENODEV;
872
873         isicom_setup_board(card);
874
875         /* FIXME: locking on port.count etc */
876         port->port.count++;
877         tty->driver_data = port;
878         tty_port_tty_set(&port->port, tty);
879         error = isicom_setup_port(tty);
880         if (error == 0)
881                 error = tty_port_block_til_ready(&port->port, tty, filp);
882         return error;
883 }
884
885 /* close et all */
886
887 static inline void isicom_shutdown_board(struct isi_board *bp)
888 {
889         if (bp->status & BOARD_ACTIVE)
890                 bp->status &= ~BOARD_ACTIVE;
891 }
892
893 /* card->lock HAS to be held */
894 static void isicom_shutdown_port(struct isi_port *port)
895 {
896         struct isi_board *card = port->card;
897         struct tty_struct *tty;
898
899         tty = tty_port_tty_get(&port->port);
900
901         if (!(port->port.flags & ASYNC_INITIALIZED)) {
902                 tty_kref_put(tty);
903                 return;
904         }
905
906         tty_port_free_xmit_buf(&port->port);
907         port->port.flags &= ~ASYNC_INITIALIZED;
908         /* 3rd October 2000 : Vinayak P Risbud */
909         tty_port_tty_set(&port->port, NULL);
910
911         /*Fix done by Anil .S on 30-04-2001
912         remote login through isi port has dtr toggle problem
913         due to which the carrier drops before the password prompt
914         appears on the remote end. Now we drop the dtr only if the
915         HUPCL(Hangup on close) flag is set for the tty*/
916
917         if (C_HUPCL(tty))
918                 /* drop dtr on this port */
919                 drop_dtr(port);
920
921         /* any other port uninits  */
922         if (tty)
923                 set_bit(TTY_IO_ERROR, &tty->flags);
924
925         if (--card->count < 0) {
926                 pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n",
927                         card->base, card->count);
928                 card->count = 0;
929         }
930
931         /* last port was closed, shutdown that boad too */
932         if (C_HUPCL(tty)) {
933                 if (!card->count)
934                         isicom_shutdown_board(card);
935         }
936         tty_kref_put(tty);
937 }
938
939 static void isicom_flush_buffer(struct tty_struct *tty)
940 {
941         struct isi_port *port = tty->driver_data;
942         struct isi_board *card = port->card;
943         unsigned long flags;
944
945         if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
946                 return;
947
948         spin_lock_irqsave(&card->card_lock, flags);
949         port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
950         spin_unlock_irqrestore(&card->card_lock, flags);
951
952         tty_wakeup(tty);
953 }
954
955 static void isicom_close(struct tty_struct *tty, struct file *filp)
956 {
957         struct isi_port *ip = tty->driver_data;
958         struct tty_port *port = &ip->port;
959         struct isi_board *card;
960         unsigned long flags;
961
962         BUG_ON(!ip);
963
964         card = ip->card;
965         if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
966                 return;
967
968         /* indicate to the card that no more data can be received
969            on this port */
970         spin_lock_irqsave(&card->card_lock, flags);
971         if (port->flags & ASYNC_INITIALIZED) {
972                 card->port_status &= ~(1 << ip->channel);
973                 outw(card->port_status, card->base + 0x02);
974         }
975         isicom_shutdown_port(ip);
976         spin_unlock_irqrestore(&card->card_lock, flags);
977
978         isicom_flush_buffer(tty);
979         
980         tty_port_close_end(port, tty);
981 }
982
983 /* write et all */
984 static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
985         int count)
986 {
987         struct isi_port *port = tty->driver_data;
988         struct isi_board *card = port->card;
989         unsigned long flags;
990         int cnt, total = 0;
991
992         if (isicom_paranoia_check(port, tty->name, "isicom_write"))
993                 return 0;
994
995         spin_lock_irqsave(&card->card_lock, flags);
996
997         while (1) {
998                 cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
999                                 - 1, SERIAL_XMIT_SIZE - port->xmit_head));
1000                 if (cnt <= 0)
1001                         break;
1002
1003                 memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt);
1004                 port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
1005                         - 1);
1006                 port->xmit_cnt += cnt;
1007                 buf += cnt;
1008                 count -= cnt;
1009                 total += cnt;
1010         }
1011         if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped)
1012                 port->status |= ISI_TXOK;
1013         spin_unlock_irqrestore(&card->card_lock, flags);
1014         return total;
1015 }
1016
1017 /* put_char et all */
1018 static int isicom_put_char(struct tty_struct *tty, unsigned char ch)
1019 {
1020         struct isi_port *port = tty->driver_data;
1021         struct isi_board *card = port->card;
1022         unsigned long flags;
1023
1024         if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
1025                 return 0;
1026
1027         spin_lock_irqsave(&card->card_lock, flags);
1028         if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
1029                 spin_unlock_irqrestore(&card->card_lock, flags);
1030                 return 0;
1031         }
1032
1033         port->port.xmit_buf[port->xmit_head++] = ch;
1034         port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
1035         port->xmit_cnt++;
1036         spin_unlock_irqrestore(&card->card_lock, flags);
1037         return 1;
1038 }
1039
1040 /* flush_chars et all */
1041 static void isicom_flush_chars(struct tty_struct *tty)
1042 {
1043         struct isi_port *port = tty->driver_data;
1044
1045         if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars"))
1046                 return;
1047
1048         if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1049                         !port->port.xmit_buf)
1050                 return;
1051
1052         /* this tells the transmitter to consider this port for
1053            data output to the card ... that's the best we can do. */
1054         port->status |= ISI_TXOK;
1055 }
1056
1057 /* write_room et all */
1058 static int isicom_write_room(struct tty_struct *tty)
1059 {
1060         struct isi_port *port = tty->driver_data;
1061         int free;
1062
1063         if (isicom_paranoia_check(port, tty->name, "isicom_write_room"))
1064                 return 0;
1065
1066         free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1067         if (free < 0)
1068                 free = 0;
1069         return free;
1070 }
1071
1072 /* chars_in_buffer et all */
1073 static int isicom_chars_in_buffer(struct tty_struct *tty)
1074 {
1075         struct isi_port *port = tty->driver_data;
1076         if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer"))
1077                 return 0;
1078         return port->xmit_cnt;
1079 }
1080
1081 /* ioctl et all */
1082 static int isicom_send_break(struct tty_struct *tty, int length)
1083 {
1084         struct isi_port *port = tty->driver_data;
1085         struct isi_board *card = port->card;
1086         unsigned long base = card->base;
1087
1088         if (length == -1)
1089                 return -EOPNOTSUPP;
1090
1091         if (!lock_card(card))
1092                 return -EINVAL;
1093
1094         outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
1095         outw((length & 0xff) << 8 | 0x00, base);
1096         outw((length & 0xff00), base);
1097         InterruptTheCard(base);
1098
1099         unlock_card(card);
1100         return 0;
1101 }
1102
1103 static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
1104 {
1105         struct isi_port *port = tty->driver_data;
1106         /* just send the port status */
1107         u16 status = port->status;
1108
1109         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1110                 return -ENODEV;
1111
1112         return  ((status & ISI_RTS) ? TIOCM_RTS : 0) |
1113                 ((status & ISI_DTR) ? TIOCM_DTR : 0) |
1114                 ((status & ISI_DCD) ? TIOCM_CAR : 0) |
1115                 ((status & ISI_DSR) ? TIOCM_DSR : 0) |
1116                 ((status & ISI_CTS) ? TIOCM_CTS : 0) |
1117                 ((status & ISI_RI ) ? TIOCM_RI  : 0);
1118 }
1119
1120 static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
1121         unsigned int set, unsigned int clear)
1122 {
1123         struct isi_port *port = tty->driver_data;
1124         unsigned long flags;
1125
1126         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1127                 return -ENODEV;
1128
1129         spin_lock_irqsave(&port->card->card_lock, flags);
1130         if (set & TIOCM_RTS)
1131                 raise_rts(port);
1132         if (set & TIOCM_DTR)
1133                 raise_dtr(port);
1134
1135         if (clear & TIOCM_RTS)
1136                 drop_rts(port);
1137         if (clear & TIOCM_DTR)
1138                 drop_dtr(port);
1139         spin_unlock_irqrestore(&port->card->card_lock, flags);
1140
1141         return 0;
1142 }
1143
1144 static int isicom_set_serial_info(struct tty_struct *tty,
1145                                         struct serial_struct __user *info)
1146 {
1147         struct isi_port *port = tty->driver_data;
1148         struct serial_struct newinfo;
1149         int reconfig_port;
1150
1151         if (copy_from_user(&newinfo, info, sizeof(newinfo)))
1152                 return -EFAULT;
1153
1154         lock_kernel();
1155
1156         reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) !=
1157                 (newinfo.flags & ASYNC_SPD_MASK));
1158
1159         if (!capable(CAP_SYS_ADMIN)) {
1160                 if ((newinfo.close_delay != port->port.close_delay) ||
1161                                 (newinfo.closing_wait != port->port.closing_wait) ||
1162                                 ((newinfo.flags & ~ASYNC_USR_MASK) !=
1163                                 (port->port.flags & ~ASYNC_USR_MASK))) {
1164                         unlock_kernel();
1165                         return -EPERM;
1166                 }
1167                 port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1168                                 (newinfo.flags & ASYNC_USR_MASK));
1169         } else {
1170                 port->port.close_delay = newinfo.close_delay;
1171                 port->port.closing_wait = newinfo.closing_wait;
1172                 port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1173                                 (newinfo.flags & ASYNC_FLAGS));
1174         }
1175         if (reconfig_port) {
1176                 unsigned long flags;
1177                 spin_lock_irqsave(&port->card->card_lock, flags);
1178                 isicom_config_port(tty);
1179                 spin_unlock_irqrestore(&port->card->card_lock, flags);
1180         }
1181         unlock_kernel();
1182         return 0;
1183 }
1184
1185 static int isicom_get_serial_info(struct isi_port *port,
1186         struct serial_struct __user *info)
1187 {
1188         struct serial_struct out_info;
1189
1190         lock_kernel();
1191         memset(&out_info, 0, sizeof(out_info));
1192 /*      out_info.type = ? */
1193         out_info.line = port - isi_ports;
1194         out_info.port = port->card->base;
1195         out_info.irq = port->card->irq;
1196         out_info.flags = port->port.flags;
1197 /*      out_info.baud_base = ? */
1198         out_info.close_delay = port->port.close_delay;
1199         out_info.closing_wait = port->port.closing_wait;
1200         unlock_kernel();
1201         if (copy_to_user(info, &out_info, sizeof(out_info)))
1202                 return -EFAULT;
1203         return 0;
1204 }
1205
1206 static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1207         unsigned int cmd, unsigned long arg)
1208 {
1209         struct isi_port *port = tty->driver_data;
1210         void __user *argp = (void __user *)arg;
1211
1212         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1213                 return -ENODEV;
1214
1215         switch (cmd) {
1216         case TIOCGSERIAL:
1217                 return isicom_get_serial_info(port, argp);
1218
1219         case TIOCSSERIAL:
1220                 return isicom_set_serial_info(tty, argp);
1221
1222         default:
1223                 return -ENOIOCTLCMD;
1224         }
1225         return 0;
1226 }
1227
1228 /* set_termios et all */
1229 static void isicom_set_termios(struct tty_struct *tty,
1230         struct ktermios *old_termios)
1231 {
1232         struct isi_port *port = tty->driver_data;
1233         unsigned long flags;
1234
1235         if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
1236                 return;
1237
1238         if (tty->termios->c_cflag == old_termios->c_cflag &&
1239                         tty->termios->c_iflag == old_termios->c_iflag)
1240                 return;
1241
1242         spin_lock_irqsave(&port->card->card_lock, flags);
1243         isicom_config_port(tty);
1244         spin_unlock_irqrestore(&port->card->card_lock, flags);
1245
1246         if ((old_termios->c_cflag & CRTSCTS) &&
1247                         !(tty->termios->c_cflag & CRTSCTS)) {
1248                 tty->hw_stopped = 0;
1249                 isicom_start(tty);
1250         }
1251 }
1252
1253 /* throttle et all */
1254 static void isicom_throttle(struct tty_struct *tty)
1255 {
1256         struct isi_port *port = tty->driver_data;
1257         struct isi_board *card = port->card;
1258
1259         if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
1260                 return;
1261
1262         /* tell the card that this port cannot handle any more data for now */
1263         card->port_status &= ~(1 << port->channel);
1264         outw(card->port_status, card->base + 0x02);
1265 }
1266
1267 /* unthrottle et all */
1268 static void isicom_unthrottle(struct tty_struct *tty)
1269 {
1270         struct isi_port *port = tty->driver_data;
1271         struct isi_board *card = port->card;
1272
1273         if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
1274                 return;
1275
1276         /* tell the card that this port is ready to accept more data */
1277         card->port_status |= (1 << port->channel);
1278         outw(card->port_status, card->base + 0x02);
1279 }
1280
1281 /* stop et all */
1282 static void isicom_stop(struct tty_struct *tty)
1283 {
1284         struct isi_port *port = tty->driver_data;
1285
1286         if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
1287                 return;
1288
1289         /* this tells the transmitter not to consider this port for
1290            data output to the card. */
1291         port->status &= ~ISI_TXOK;
1292 }
1293
1294 /* start et all */
1295 static void isicom_start(struct tty_struct *tty)
1296 {
1297         struct isi_port *port = tty->driver_data;
1298
1299         if (isicom_paranoia_check(port, tty->name, "isicom_start"))
1300                 return;
1301
1302         /* this tells the transmitter to consider this port for
1303            data output to the card. */
1304         port->status |= ISI_TXOK;
1305 }
1306
1307 static void isicom_hangup(struct tty_struct *tty)
1308 {
1309         struct isi_port *port = tty->driver_data;
1310         unsigned long flags;
1311
1312         if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
1313                 return;
1314
1315         spin_lock_irqsave(&port->card->card_lock, flags);
1316         isicom_shutdown_port(port);
1317         spin_unlock_irqrestore(&port->card->card_lock, flags);
1318
1319         tty_port_hangup(&port->port);
1320 }
1321
1322
1323 /*
1324  * Driver init and deinit functions
1325  */
1326
1327 static const struct tty_operations isicom_ops = {
1328         .open                   = isicom_open,
1329         .close                  = isicom_close,
1330         .write                  = isicom_write,
1331         .put_char               = isicom_put_char,
1332         .flush_chars            = isicom_flush_chars,
1333         .write_room             = isicom_write_room,
1334         .chars_in_buffer        = isicom_chars_in_buffer,
1335         .ioctl                  = isicom_ioctl,
1336         .set_termios            = isicom_set_termios,
1337         .throttle               = isicom_throttle,
1338         .unthrottle             = isicom_unthrottle,
1339         .stop                   = isicom_stop,
1340         .start                  = isicom_start,
1341         .hangup                 = isicom_hangup,
1342         .flush_buffer           = isicom_flush_buffer,
1343         .tiocmget               = isicom_tiocmget,
1344         .tiocmset               = isicom_tiocmset,
1345         .break_ctl              = isicom_send_break,
1346 };
1347
1348 static const struct tty_port_operations isicom_port_ops = {
1349         .carrier_raised         = isicom_carrier_raised,
1350         .dtr_rts                = isicom_dtr_rts,
1351 };
1352
1353 static int __devinit reset_card(struct pci_dev *pdev,
1354         const unsigned int card, unsigned int *signature)
1355 {
1356         struct isi_board *board = pci_get_drvdata(pdev);
1357         unsigned long base = board->base;
1358         unsigned int sig, portcount = 0;
1359         int retval = 0;
1360
1361         dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
1362                 base);
1363
1364         inw(base + 0x8);
1365
1366         msleep(10);
1367
1368         outw(0, base + 0x8); /* Reset */
1369
1370         msleep(1000);
1371
1372         sig = inw(base + 0x4) & 0xff;
1373
1374         if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd &&
1375                         sig != 0xee) {
1376                 dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible "
1377                         "bad I/O Port Address 0x%lx).\n", card + 1, base);
1378                 dev_dbg(&pdev->dev, "Sig=0x%x\n", sig);
1379                 retval = -EIO;
1380                 goto end;
1381         }
1382
1383         msleep(10);
1384
1385         portcount = inw(base + 0x2);
1386         if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 &&
1387                                 portcount != 8 && portcount != 16)) {
1388                 dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
1389                         card + 1);
1390                 retval = -EIO;
1391                 goto end;
1392         }
1393
1394         switch (sig) {
1395         case 0xa5:
1396         case 0xbb:
1397         case 0xdd:
1398                 board->port_count = (portcount == 4) ? 4 : 8;
1399                 board->shift_count = 12;
1400                 break;
1401         case 0xcc:
1402         case 0xee:
1403                 board->port_count = 16;
1404                 board->shift_count = 11;
1405                 break;
1406         }
1407         dev_info(&pdev->dev, "-Done\n");
1408         *signature = sig;
1409
1410 end:
1411         return retval;
1412 }
1413
1414 static int __devinit load_firmware(struct pci_dev *pdev,
1415         const unsigned int index, const unsigned int signature)
1416 {
1417         struct isi_board *board = pci_get_drvdata(pdev);
1418         const struct firmware *fw;
1419         unsigned long base = board->base;
1420         unsigned int a;
1421         u16 word_count, status;
1422         int retval = -EIO;
1423         char *name;
1424         u8 *data;
1425
1426         struct stframe {
1427                 u16     addr;
1428                 u16     count;
1429                 u8      data[0];
1430         } *frame;
1431
1432         switch (signature) {
1433         case 0xa5:
1434                 name = "isi608.bin";
1435                 break;
1436         case 0xbb:
1437                 name = "isi608em.bin";
1438                 break;
1439         case 0xcc:
1440                 name = "isi616em.bin";
1441                 break;
1442         case 0xdd:
1443                 name = "isi4608.bin";
1444                 break;
1445         case 0xee:
1446                 name = "isi4616.bin";
1447                 break;
1448         default:
1449                 dev_err(&pdev->dev, "Unknown signature.\n");
1450                 goto end;
1451         }
1452
1453         retval = request_firmware(&fw, name, &pdev->dev);
1454         if (retval)
1455                 goto end;
1456
1457         retval = -EIO;
1458
1459         for (frame = (struct stframe *)fw->data;
1460                         frame < (struct stframe *)(fw->data + fw->size);
1461                         frame = (struct stframe *)((u8 *)(frame + 1) +
1462                                 frame->count)) {
1463                 if (WaitTillCardIsFree(base))
1464                         goto errrelfw;
1465
1466                 outw(0xf0, base);       /* start upload sequence */
1467                 outw(0x00, base);
1468                 outw(frame->addr, base); /* lsb of address */
1469
1470                 word_count = frame->count / 2 + frame->count % 2;
1471                 outw(word_count, base);
1472                 InterruptTheCard(base);
1473
1474                 udelay(100); /* 0x2f */
1475
1476                 if (WaitTillCardIsFree(base))
1477                         goto errrelfw;
1478
1479                 status = inw(base + 0x4);
1480                 if (status != 0) {
1481                         dev_warn(&pdev->dev, "Card%d rejected load header:\n"
1482                                  "Address:0x%x\n"
1483                                  "Count:0x%x\n"
1484                                  "Status:0x%x\n",
1485                                  index + 1, frame->addr, frame->count, status);
1486                         goto errrelfw;
1487                 }
1488                 outsw(base, frame->data, word_count);
1489
1490                 InterruptTheCard(base);
1491
1492                 udelay(50); /* 0x0f */
1493
1494                 if (WaitTillCardIsFree(base))
1495                         goto errrelfw;
1496
1497                 status = inw(base + 0x4);
1498                 if (status != 0) {
1499                         dev_err(&pdev->dev, "Card%d got out of sync.Card "
1500                                 "Status:0x%x\n", index + 1, status);
1501                         goto errrelfw;
1502                 }
1503         }
1504
1505 /* XXX: should we test it by reading it back and comparing with original like
1506  * in load firmware package? */
1507         for (frame = (struct stframe *)fw->data;
1508                         frame < (struct stframe *)(fw->data + fw->size);
1509                         frame = (struct stframe *)((u8 *)(frame + 1) +
1510                                 frame->count)) {
1511                 if (WaitTillCardIsFree(base))
1512                         goto errrelfw;
1513
1514                 outw(0xf1, base); /* start download sequence */
1515                 outw(0x00, base);
1516                 outw(frame->addr, base); /* lsb of address */
1517
1518                 word_count = (frame->count >> 1) + frame->count % 2;
1519                 outw(word_count + 1, base);
1520                 InterruptTheCard(base);
1521
1522                 udelay(50); /* 0xf */
1523
1524                 if (WaitTillCardIsFree(base))
1525                         goto errrelfw;
1526
1527                 status = inw(base + 0x4);
1528                 if (status != 0) {
1529                         dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
1530                                  "Address:0x%x\n"
1531                                  "Count:0x%x\n"
1532                                  "Status: 0x%x\n",
1533                                  index + 1, frame->addr, frame->count, status);
1534                         goto errrelfw;
1535                 }
1536
1537                 data = kmalloc(word_count * 2, GFP_KERNEL);
1538                 if (data == NULL) {
1539                         dev_err(&pdev->dev, "Card%d, firmware upload "
1540                                 "failed, not enough memory\n", index + 1);
1541                         goto errrelfw;
1542                 }
1543                 inw(base);
1544                 insw(base, data, word_count);
1545                 InterruptTheCard(base);
1546
1547                 for (a = 0; a < frame->count; a++)
1548                         if (data[a] != frame->data[a]) {
1549                                 kfree(data);
1550                                 dev_err(&pdev->dev, "Card%d, firmware upload "
1551                                         "failed\n", index + 1);
1552                                 goto errrelfw;
1553                         }
1554                 kfree(data);
1555
1556                 udelay(50); /* 0xf */
1557
1558                 if (WaitTillCardIsFree(base))
1559                         goto errrelfw;
1560
1561                 status = inw(base + 0x4);
1562                 if (status != 0) {
1563                         dev_err(&pdev->dev, "Card%d verify got out of sync. "
1564                                 "Card Status:0x%x\n", index + 1, status);
1565                         goto errrelfw;
1566                 }
1567         }
1568
1569         /* xfer ctrl */
1570         if (WaitTillCardIsFree(base))
1571                 goto errrelfw;
1572
1573         outw(0xf2, base);
1574         outw(0x800, base);
1575         outw(0x0, base);
1576         outw(0x0, base);
1577         InterruptTheCard(base);
1578         outw(0x0, base + 0x4); /* for ISI4608 cards */
1579
1580         board->status |= FIRMWARE_LOADED;
1581         retval = 0;
1582
1583 errrelfw:
1584         release_firmware(fw);
1585 end:
1586         return retval;
1587 }
1588
1589 /*
1590  *      Insmod can set static symbols so keep these static
1591  */
1592 static unsigned int card_count;
1593
1594 static int __devinit isicom_probe(struct pci_dev *pdev,
1595         const struct pci_device_id *ent)
1596 {
1597         unsigned int uninitialized_var(signature), index;
1598         int retval = -EPERM;
1599         struct isi_board *board = NULL;
1600
1601         if (card_count >= BOARD_COUNT)
1602                 goto err;
1603
1604         retval = pci_enable_device(pdev);
1605         if (retval) {
1606                 dev_err(&pdev->dev, "failed to enable\n");
1607                 goto err;
1608         }
1609
1610         dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
1611
1612         /* allot the first empty slot in the array */
1613         for (index = 0; index < BOARD_COUNT; index++)
1614                 if (isi_card[index].base == 0) {
1615                         board = &isi_card[index];
1616                         break;
1617                 }
1618
1619         board->index = index;
1620         board->base = pci_resource_start(pdev, 3);
1621         board->irq = pdev->irq;
1622         card_count++;
1623
1624         pci_set_drvdata(pdev, board);
1625
1626         retval = pci_request_region(pdev, 3, ISICOM_NAME);
1627         if (retval) {
1628                 dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
1629                         "will be disabled.\n", board->base, board->base + 15,
1630                         index + 1);
1631                 retval = -EBUSY;
1632                 goto errdec;
1633         }
1634
1635         retval = request_irq(board->irq, isicom_interrupt,
1636                         IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
1637         if (retval < 0) {
1638                 dev_err(&pdev->dev, "Could not install handler at Irq %d. "
1639                         "Card%d will be disabled.\n", board->irq, index + 1);
1640                 goto errunrr;
1641         }
1642
1643         retval = reset_card(pdev, index, &signature);
1644         if (retval < 0)
1645                 goto errunri;
1646
1647         retval = load_firmware(pdev, index, signature);
1648         if (retval < 0)
1649                 goto errunri;
1650
1651         for (index = 0; index < board->port_count; index++)
1652                 tty_register_device(isicom_normal, board->index * 16 + index,
1653                                 &pdev->dev);
1654
1655         return 0;
1656
1657 errunri:
1658         free_irq(board->irq, board);
1659 errunrr:
1660         pci_release_region(pdev, 3);
1661 errdec:
1662         board->base = 0;
1663         card_count--;
1664         pci_disable_device(pdev);
1665 err:
1666         return retval;
1667 }
1668
1669 static void __devexit isicom_remove(struct pci_dev *pdev)
1670 {
1671         struct isi_board *board = pci_get_drvdata(pdev);
1672         unsigned int i;
1673
1674         for (i = 0; i < board->port_count; i++)
1675                 tty_unregister_device(isicom_normal, board->index * 16 + i);
1676
1677         free_irq(board->irq, board);
1678         pci_release_region(pdev, 3);
1679         board->base = 0;
1680         card_count--;
1681         pci_disable_device(pdev);
1682 }
1683
1684 static int __init isicom_init(void)
1685 {
1686         int retval, idx, channel;
1687         struct isi_port *port;
1688
1689         for (idx = 0; idx < BOARD_COUNT; idx++) {
1690                 port = &isi_ports[idx * 16];
1691                 isi_card[idx].ports = port;
1692                 spin_lock_init(&isi_card[idx].card_lock);
1693                 for (channel = 0; channel < 16; channel++, port++) {
1694                         tty_port_init(&port->port);
1695                         port->port.ops = &isicom_port_ops;
1696                         port->magic = ISICOM_MAGIC;
1697                         port->card = &isi_card[idx];
1698                         port->channel = channel;
1699                         port->port.close_delay = 50 * HZ/100;
1700                         port->port.closing_wait = 3000 * HZ/100;
1701                         port->status = 0;
1702                         /*  . . .  */
1703                 }
1704                 isi_card[idx].base = 0;
1705                 isi_card[idx].irq = 0;
1706         }
1707
1708         /* tty driver structure initialization */
1709         isicom_normal = alloc_tty_driver(PORT_COUNT);
1710         if (!isicom_normal) {
1711                 retval = -ENOMEM;
1712                 goto error;
1713         }
1714
1715         isicom_normal->owner                    = THIS_MODULE;
1716         isicom_normal->name                     = "ttyM";
1717         isicom_normal->major                    = ISICOM_NMAJOR;
1718         isicom_normal->minor_start              = 0;
1719         isicom_normal->type                     = TTY_DRIVER_TYPE_SERIAL;
1720         isicom_normal->subtype                  = SERIAL_TYPE_NORMAL;
1721         isicom_normal->init_termios             = tty_std_termios;
1722         isicom_normal->init_termios.c_cflag     = B9600 | CS8 | CREAD | HUPCL |
1723                 CLOCAL;
1724         isicom_normal->flags                    = TTY_DRIVER_REAL_RAW |
1725                 TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK;
1726         tty_set_operations(isicom_normal, &isicom_ops);
1727
1728         retval = tty_register_driver(isicom_normal);
1729         if (retval) {
1730                 pr_dbg("Couldn't register the dialin driver\n");
1731                 goto err_puttty;
1732         }
1733
1734         retval = pci_register_driver(&isicom_driver);
1735         if (retval < 0) {
1736                 printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
1737                 goto err_unrtty;
1738         }
1739
1740         mod_timer(&tx, jiffies + 1);
1741
1742         return 0;
1743 err_unrtty:
1744         tty_unregister_driver(isicom_normal);
1745 err_puttty:
1746         put_tty_driver(isicom_normal);
1747 error:
1748         return retval;
1749 }
1750
1751 static void __exit isicom_exit(void)
1752 {
1753         del_timer_sync(&tx);
1754
1755         pci_unregister_driver(&isicom_driver);
1756         tty_unregister_driver(isicom_normal);
1757         put_tty_driver(isicom_normal);
1758 }
1759
1760 module_init(isicom_init);
1761 module_exit(isicom_exit);
1762
1763 MODULE_AUTHOR("MultiTech");
1764 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
1765 MODULE_LICENSE("GPL");