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