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