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