Merge branch 'next' into for-linus
[linux-2.6] / drivers / char / isicom.c
1 /*
2  *      This program is free software; you can redistribute it and/or
3  *      modify it under the terms of the GNU General Public License
4  *      as published by the Free Software Foundation; either version
5  *      2 of the License, or (at your option) any later version.
6  *
7  *      Original driver code supplied by Multi-Tech
8  *
9  *      Changes
10  *      1/9/98  alan@lxorguk.ukuu.org.uk
11  *                                      Merge to 2.0.x kernel tree
12  *                                      Obtain and use official major/minors
13  *                                      Loader switched to a misc device
14  *                                      (fixed range check bug as a side effect)
15  *                                      Printk clean up
16  *      9/12/98 alan@lxorguk.ukuu.org.uk
17  *                                      Rough port to 2.1.x
18  *
19  *      10/6/99 sameer                  Merged the ISA and PCI drivers to
20  *                                      a new unified driver.
21  *
22  *      3/9/99  sameer                  Added support for ISI4616 cards.
23  *
24  *      16/9/99 sameer                  We do not force RTS low anymore.
25  *                                      This is to prevent the firmware
26  *                                      from getting confused.
27  *
28  *      26/10/99 sameer                 Cosmetic changes:The driver now
29  *                                      dumps the Port Count information
30  *                                      along with I/O address and IRQ.
31  *
32  *      13/12/99 sameer                 Fixed the problem with IRQ sharing.
33  *
34  *      10/5/00  sameer                 Fixed isicom_shutdown_board()
35  *                                      to not lower DTR on all the ports
36  *                                      when the last port on the card is
37  *                                      closed.
38  *
39  *      10/5/00  sameer                 Signal mask setup command added
40  *                                      to  isicom_setup_port and
41  *                                      isicom_shutdown_port.
42  *
43  *      24/5/00  sameer                 The driver is now SMP aware.
44  *
45  *
46  *      27/11/00 Vinayak P Risbud       Fixed the Driver Crash Problem
47  *
48  *
49  *      03/01/01  anil .s               Added support for resetting the
50  *                                      internal modems on ISI cards.
51  *
52  *      08/02/01  anil .s               Upgraded the driver for kernel
53  *                                      2.4.x
54  *
55  *      11/04/01  Kevin                 Fixed firmware load problem with
56  *                                      ISIHP-4X card
57  *
58  *      30/04/01  anil .s               Fixed the remote login through
59  *                                      ISI port problem. Now the link
60  *                                      does not go down before password
61  *                                      prompt.
62  *
63  *      03/05/01  anil .s               Fixed the problem with IRQ sharing
64  *                                      among ISI-PCI cards.
65  *
66  *      03/05/01  anil .s               Added support to display the version
67  *                                      info during insmod as well as module
68  *                                      listing by lsmod.
69  *
70  *      10/05/01  anil .s               Done the modifications to the source
71  *                                      file and Install script so that the
72  *                                      same installation can be used for
73  *                                      2.2.x and 2.4.x kernel.
74  *
75  *      06/06/01  anil .s               Now we drop both dtr and rts during
76  *                                      shutdown_port as well as raise them
77  *                                      during isicom_config_port.
78  *
79  *      09/06/01 acme@conectiva.com.br  use capable, not suser, do
80  *                                      restore_flags on failure in
81  *                                      isicom_send_break, verify put_user
82  *                                      result
83  *
84  *      11/02/03  ranjeeth              Added support for 230 Kbps and 460 Kbps
85  *                                      Baud index extended to 21
86  *
87  *      20/03/03  ranjeeth              Made to work for Linux Advanced server.
88  *                                      Taken care of license warning.
89  *
90  *      10/12/03  Ravindra              Made to work for Fedora Core 1 of
91  *                                      Red Hat Distribution
92  *
93  *      06/01/05  Alan Cox              Merged the ISI and base kernel strands
94  *                                      into a single 2.6 driver
95  *
96  *      ***********************************************************
97  *
98  *      To use this driver you also need the support package. You
99  *      can find this in RPM format on
100  *              ftp://ftp.linux.org.uk/pub/linux/alan
101  *
102  *      You can find the original tools for this direct from Multitech
103  *              ftp://ftp.multitech.com/ISI-Cards/
104  *
105  *      Having installed the cards the module options (/etc/modprobe.conf)
106  *
107  *      options isicom   io=card1,card2,card3,card4 irq=card1,card2,card3,card4
108  *
109  *      Omit those entries for boards you don't have installed.
110  *
111  *      TODO
112  *              Merge testing
113  *              64-bit verification
114  */
115
116 #include <linux/module.h>
117 #include <linux/firmware.h>
118 #include <linux/kernel.h>
119 #include <linux/tty.h>
120 #include <linux/tty_flip.h>
121 #include <linux/termios.h>
122 #include <linux/fs.h>
123 #include <linux/sched.h>
124 #include <linux/serial.h>
125 #include <linux/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         tty_kref_put(tty);
929 }
930
931 static void isicom_flush_buffer(struct tty_struct *tty)
932 {
933         struct isi_port *port = tty->driver_data;
934         struct isi_board *card = port->card;
935         unsigned long flags;
936
937         if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
938                 return;
939
940         spin_lock_irqsave(&card->card_lock, flags);
941         port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
942         spin_unlock_irqrestore(&card->card_lock, flags);
943
944         tty_wakeup(tty);
945 }
946
947 static void isicom_close(struct tty_struct *tty, struct file *filp)
948 {
949         struct isi_port *ip = tty->driver_data;
950         struct tty_port *port = &ip->port;
951         struct isi_board *card;
952         unsigned long flags;
953
954         BUG_ON(!ip);
955
956         card = ip->card;
957         if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
958                 return;
959
960         /* indicate to the card that no more data can be received
961            on this port */
962         spin_lock_irqsave(&card->card_lock, flags);
963         if (port->flags & ASYNC_INITIALIZED) {
964                 card->port_status &= ~(1 << ip->channel);
965                 outw(card->port_status, card->base + 0x02);
966         }
967         isicom_shutdown_port(ip);
968         spin_unlock_irqrestore(&card->card_lock, flags);
969
970         isicom_flush_buffer(tty);
971         
972         tty_port_close_end(port, tty);
973 }
974
975 /* write et all */
976 static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
977         int count)
978 {
979         struct isi_port *port = tty->driver_data;
980         struct isi_board *card = port->card;
981         unsigned long flags;
982         int cnt, total = 0;
983
984         if (isicom_paranoia_check(port, tty->name, "isicom_write"))
985                 return 0;
986
987         spin_lock_irqsave(&card->card_lock, flags);
988
989         while (1) {
990                 cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
991                                 - 1, SERIAL_XMIT_SIZE - port->xmit_head));
992                 if (cnt <= 0)
993                         break;
994
995                 memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt);
996                 port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
997                         - 1);
998                 port->xmit_cnt += cnt;
999                 buf += cnt;
1000                 count -= cnt;
1001                 total += cnt;
1002         }
1003         if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped)
1004                 port->status |= ISI_TXOK;
1005         spin_unlock_irqrestore(&card->card_lock, flags);
1006         return total;
1007 }
1008
1009 /* put_char et all */
1010 static int isicom_put_char(struct tty_struct *tty, unsigned char ch)
1011 {
1012         struct isi_port *port = tty->driver_data;
1013         struct isi_board *card = port->card;
1014         unsigned long flags;
1015
1016         if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
1017                 return 0;
1018
1019         spin_lock_irqsave(&card->card_lock, flags);
1020         if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
1021                 spin_unlock_irqrestore(&card->card_lock, flags);
1022                 return 0;
1023         }
1024
1025         port->port.xmit_buf[port->xmit_head++] = ch;
1026         port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
1027         port->xmit_cnt++;
1028         spin_unlock_irqrestore(&card->card_lock, flags);
1029         return 1;
1030 }
1031
1032 /* flush_chars et all */
1033 static void isicom_flush_chars(struct tty_struct *tty)
1034 {
1035         struct isi_port *port = tty->driver_data;
1036
1037         if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars"))
1038                 return;
1039
1040         if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1041                         !port->port.xmit_buf)
1042                 return;
1043
1044         /* this tells the transmitter to consider this port for
1045            data output to the card ... that's the best we can do. */
1046         port->status |= ISI_TXOK;
1047 }
1048
1049 /* write_room et all */
1050 static int isicom_write_room(struct tty_struct *tty)
1051 {
1052         struct isi_port *port = tty->driver_data;
1053         int free;
1054
1055         if (isicom_paranoia_check(port, tty->name, "isicom_write_room"))
1056                 return 0;
1057
1058         free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1059         if (free < 0)
1060                 free = 0;
1061         return free;
1062 }
1063
1064 /* chars_in_buffer et all */
1065 static int isicom_chars_in_buffer(struct tty_struct *tty)
1066 {
1067         struct isi_port *port = tty->driver_data;
1068         if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer"))
1069                 return 0;
1070         return port->xmit_cnt;
1071 }
1072
1073 /* ioctl et all */
1074 static int isicom_send_break(struct tty_struct *tty, int length)
1075 {
1076         struct isi_port *port = tty->driver_data;
1077         struct isi_board *card = port->card;
1078         unsigned long base = card->base;
1079
1080         if (length == -1)
1081                 return -EOPNOTSUPP;
1082
1083         if (!lock_card(card))
1084                 return -EINVAL;
1085
1086         outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
1087         outw((length & 0xff) << 8 | 0x00, base);
1088         outw((length & 0xff00), base);
1089         InterruptTheCard(base);
1090
1091         unlock_card(card);
1092         return 0;
1093 }
1094
1095 static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
1096 {
1097         struct isi_port *port = tty->driver_data;
1098         /* just send the port status */
1099         u16 status = port->status;
1100
1101         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1102                 return -ENODEV;
1103
1104         return  ((status & ISI_RTS) ? TIOCM_RTS : 0) |
1105                 ((status & ISI_DTR) ? TIOCM_DTR : 0) |
1106                 ((status & ISI_DCD) ? TIOCM_CAR : 0) |
1107                 ((status & ISI_DSR) ? TIOCM_DSR : 0) |
1108                 ((status & ISI_CTS) ? TIOCM_CTS : 0) |
1109                 ((status & ISI_RI ) ? TIOCM_RI  : 0);
1110 }
1111
1112 static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
1113         unsigned int set, unsigned int clear)
1114 {
1115         struct isi_port *port = tty->driver_data;
1116         unsigned long flags;
1117
1118         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1119                 return -ENODEV;
1120
1121         spin_lock_irqsave(&port->card->card_lock, flags);
1122         if (set & TIOCM_RTS)
1123                 raise_rts(port);
1124         if (set & TIOCM_DTR)
1125                 raise_dtr(port);
1126
1127         if (clear & TIOCM_RTS)
1128                 drop_rts(port);
1129         if (clear & TIOCM_DTR)
1130                 drop_dtr(port);
1131         spin_unlock_irqrestore(&port->card->card_lock, flags);
1132
1133         return 0;
1134 }
1135
1136 static int isicom_set_serial_info(struct tty_struct *tty,
1137                                         struct serial_struct __user *info)
1138 {
1139         struct isi_port *port = tty->driver_data;
1140         struct serial_struct newinfo;
1141         int reconfig_port;
1142
1143         if (copy_from_user(&newinfo, info, sizeof(newinfo)))
1144                 return -EFAULT;
1145
1146         lock_kernel();
1147
1148         reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) !=
1149                 (newinfo.flags & ASYNC_SPD_MASK));
1150
1151         if (!capable(CAP_SYS_ADMIN)) {
1152                 if ((newinfo.close_delay != port->port.close_delay) ||
1153                                 (newinfo.closing_wait != port->port.closing_wait) ||
1154                                 ((newinfo.flags & ~ASYNC_USR_MASK) !=
1155                                 (port->port.flags & ~ASYNC_USR_MASK))) {
1156                         unlock_kernel();
1157                         return -EPERM;
1158                 }
1159                 port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1160                                 (newinfo.flags & ASYNC_USR_MASK));
1161         } else {
1162                 port->port.close_delay = newinfo.close_delay;
1163                 port->port.closing_wait = newinfo.closing_wait;
1164                 port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1165                                 (newinfo.flags & ASYNC_FLAGS));
1166         }
1167         if (reconfig_port) {
1168                 unsigned long flags;
1169                 spin_lock_irqsave(&port->card->card_lock, flags);
1170                 isicom_config_port(tty);
1171                 spin_unlock_irqrestore(&port->card->card_lock, flags);
1172         }
1173         unlock_kernel();
1174         return 0;
1175 }
1176
1177 static int isicom_get_serial_info(struct isi_port *port,
1178         struct serial_struct __user *info)
1179 {
1180         struct serial_struct out_info;
1181
1182         lock_kernel();
1183         memset(&out_info, 0, sizeof(out_info));
1184 /*      out_info.type = ? */
1185         out_info.line = port - isi_ports;
1186         out_info.port = port->card->base;
1187         out_info.irq = port->card->irq;
1188         out_info.flags = port->port.flags;
1189 /*      out_info.baud_base = ? */
1190         out_info.close_delay = port->port.close_delay;
1191         out_info.closing_wait = port->port.closing_wait;
1192         unlock_kernel();
1193         if (copy_to_user(info, &out_info, sizeof(out_info)))
1194                 return -EFAULT;
1195         return 0;
1196 }
1197
1198 static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1199         unsigned int cmd, unsigned long arg)
1200 {
1201         struct isi_port *port = tty->driver_data;
1202         void __user *argp = (void __user *)arg;
1203
1204         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1205                 return -ENODEV;
1206
1207         switch (cmd) {
1208         case TIOCGSERIAL:
1209                 return isicom_get_serial_info(port, argp);
1210
1211         case TIOCSSERIAL:
1212                 return isicom_set_serial_info(tty, argp);
1213
1214         default:
1215                 return -ENOIOCTLCMD;
1216         }
1217         return 0;
1218 }
1219
1220 /* set_termios et all */
1221 static void isicom_set_termios(struct tty_struct *tty,
1222         struct ktermios *old_termios)
1223 {
1224         struct isi_port *port = tty->driver_data;
1225         unsigned long flags;
1226
1227         if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
1228                 return;
1229
1230         if (tty->termios->c_cflag == old_termios->c_cflag &&
1231                         tty->termios->c_iflag == old_termios->c_iflag)
1232                 return;
1233
1234         spin_lock_irqsave(&port->card->card_lock, flags);
1235         isicom_config_port(tty);
1236         spin_unlock_irqrestore(&port->card->card_lock, flags);
1237
1238         if ((old_termios->c_cflag & CRTSCTS) &&
1239                         !(tty->termios->c_cflag & CRTSCTS)) {
1240                 tty->hw_stopped = 0;
1241                 isicom_start(tty);
1242         }
1243 }
1244
1245 /* throttle et all */
1246 static void isicom_throttle(struct tty_struct *tty)
1247 {
1248         struct isi_port *port = tty->driver_data;
1249         struct isi_board *card = port->card;
1250
1251         if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
1252                 return;
1253
1254         /* tell the card that this port cannot handle any more data for now */
1255         card->port_status &= ~(1 << port->channel);
1256         outw(card->port_status, card->base + 0x02);
1257 }
1258
1259 /* unthrottle et all */
1260 static void isicom_unthrottle(struct tty_struct *tty)
1261 {
1262         struct isi_port *port = tty->driver_data;
1263         struct isi_board *card = port->card;
1264
1265         if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
1266                 return;
1267
1268         /* tell the card that this port is ready to accept more data */
1269         card->port_status |= (1 << port->channel);
1270         outw(card->port_status, card->base + 0x02);
1271 }
1272
1273 /* stop et all */
1274 static void isicom_stop(struct tty_struct *tty)
1275 {
1276         struct isi_port *port = tty->driver_data;
1277
1278         if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
1279                 return;
1280
1281         /* this tells the transmitter not to consider this port for
1282            data output to the card. */
1283         port->status &= ~ISI_TXOK;
1284 }
1285
1286 /* start et all */
1287 static void isicom_start(struct tty_struct *tty)
1288 {
1289         struct isi_port *port = tty->driver_data;
1290
1291         if (isicom_paranoia_check(port, tty->name, "isicom_start"))
1292                 return;
1293
1294         /* this tells the transmitter to consider this port for
1295            data output to the card. */
1296         port->status |= ISI_TXOK;
1297 }
1298
1299 static void isicom_hangup(struct tty_struct *tty)
1300 {
1301         struct isi_port *port = tty->driver_data;
1302         unsigned long flags;
1303
1304         if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
1305                 return;
1306
1307         spin_lock_irqsave(&port->card->card_lock, flags);
1308         isicom_shutdown_port(port);
1309         spin_unlock_irqrestore(&port->card->card_lock, flags);
1310
1311         tty_port_hangup(&port->port);
1312 }
1313
1314
1315 /*
1316  * Driver init and deinit functions
1317  */
1318
1319 static const struct tty_operations isicom_ops = {
1320         .open                   = isicom_open,
1321         .close                  = isicom_close,
1322         .write                  = isicom_write,
1323         .put_char               = isicom_put_char,
1324         .flush_chars            = isicom_flush_chars,
1325         .write_room             = isicom_write_room,
1326         .chars_in_buffer        = isicom_chars_in_buffer,
1327         .ioctl                  = isicom_ioctl,
1328         .set_termios            = isicom_set_termios,
1329         .throttle               = isicom_throttle,
1330         .unthrottle             = isicom_unthrottle,
1331         .stop                   = isicom_stop,
1332         .start                  = isicom_start,
1333         .hangup                 = isicom_hangup,
1334         .flush_buffer           = isicom_flush_buffer,
1335         .tiocmget               = isicom_tiocmget,
1336         .tiocmset               = isicom_tiocmset,
1337         .break_ctl              = isicom_send_break,
1338 };
1339
1340 static const struct tty_port_operations isicom_port_ops = {
1341         .carrier_raised         = isicom_carrier_raised,
1342         .raise_dtr_rts          = isicom_raise_dtr_rts,
1343 };
1344
1345 static int __devinit reset_card(struct pci_dev *pdev,
1346         const unsigned int card, unsigned int *signature)
1347 {
1348         struct isi_board *board = pci_get_drvdata(pdev);
1349         unsigned long base = board->base;
1350         unsigned int sig, portcount = 0;
1351         int retval = 0;
1352
1353         dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
1354                 base);
1355
1356         inw(base + 0x8);
1357
1358         msleep(10);
1359
1360         outw(0, base + 0x8); /* Reset */
1361
1362         msleep(1000);
1363
1364         sig = inw(base + 0x4) & 0xff;
1365
1366         if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd &&
1367                         sig != 0xee) {
1368                 dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible "
1369                         "bad I/O Port Address 0x%lx).\n", card + 1, base);
1370                 dev_dbg(&pdev->dev, "Sig=0x%x\n", sig);
1371                 retval = -EIO;
1372                 goto end;
1373         }
1374
1375         msleep(10);
1376
1377         portcount = inw(base + 0x2);
1378         if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 &&
1379                                 portcount != 8 && portcount != 16)) {
1380                 dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
1381                         card + 1);
1382                 retval = -EIO;
1383                 goto end;
1384         }
1385
1386         switch (sig) {
1387         case 0xa5:
1388         case 0xbb:
1389         case 0xdd:
1390                 board->port_count = (portcount == 4) ? 4 : 8;
1391                 board->shift_count = 12;
1392                 break;
1393         case 0xcc:
1394         case 0xee:
1395                 board->port_count = 16;
1396                 board->shift_count = 11;
1397                 break;
1398         }
1399         dev_info(&pdev->dev, "-Done\n");
1400         *signature = sig;
1401
1402 end:
1403         return retval;
1404 }
1405
1406 static int __devinit load_firmware(struct pci_dev *pdev,
1407         const unsigned int index, const unsigned int signature)
1408 {
1409         struct isi_board *board = pci_get_drvdata(pdev);
1410         const struct firmware *fw;
1411         unsigned long base = board->base;
1412         unsigned int a;
1413         u16 word_count, status;
1414         int retval = -EIO;
1415         char *name;
1416         u8 *data;
1417
1418         struct stframe {
1419                 u16     addr;
1420                 u16     count;
1421                 u8      data[0];
1422         } *frame;
1423
1424         switch (signature) {
1425         case 0xa5:
1426                 name = "isi608.bin";
1427                 break;
1428         case 0xbb:
1429                 name = "isi608em.bin";
1430                 break;
1431         case 0xcc:
1432                 name = "isi616em.bin";
1433                 break;
1434         case 0xdd:
1435                 name = "isi4608.bin";
1436                 break;
1437         case 0xee:
1438                 name = "isi4616.bin";
1439                 break;
1440         default:
1441                 dev_err(&pdev->dev, "Unknown signature.\n");
1442                 goto end;
1443         }
1444
1445         retval = request_firmware(&fw, name, &pdev->dev);
1446         if (retval)
1447                 goto end;
1448
1449         retval = -EIO;
1450
1451         for (frame = (struct stframe *)fw->data;
1452                         frame < (struct stframe *)(fw->data + fw->size);
1453                         frame = (struct stframe *)((u8 *)(frame + 1) +
1454                                 frame->count)) {
1455                 if (WaitTillCardIsFree(base))
1456                         goto errrelfw;
1457
1458                 outw(0xf0, base);       /* start upload sequence */
1459                 outw(0x00, base);
1460                 outw(frame->addr, base); /* lsb of address */
1461
1462                 word_count = frame->count / 2 + frame->count % 2;
1463                 outw(word_count, base);
1464                 InterruptTheCard(base);
1465
1466                 udelay(100); /* 0x2f */
1467
1468                 if (WaitTillCardIsFree(base))
1469                         goto errrelfw;
1470
1471                 status = inw(base + 0x4);
1472                 if (status != 0) {
1473                         dev_warn(&pdev->dev, "Card%d rejected load header:\n"
1474                                 KERN_WARNING "Address:0x%x\n"
1475                                 KERN_WARNING "Count:0x%x\n"
1476                                 KERN_WARNING "Status:0x%x\n",
1477                                 index + 1, frame->addr, frame->count, status);
1478                         goto errrelfw;
1479                 }
1480                 outsw(base, frame->data, word_count);
1481
1482                 InterruptTheCard(base);
1483
1484                 udelay(50); /* 0x0f */
1485
1486                 if (WaitTillCardIsFree(base))
1487                         goto errrelfw;
1488
1489                 status = inw(base + 0x4);
1490                 if (status != 0) {
1491                         dev_err(&pdev->dev, "Card%d got out of sync.Card "
1492                                 "Status:0x%x\n", index + 1, status);
1493                         goto errrelfw;
1494                 }
1495         }
1496
1497 /* XXX: should we test it by reading it back and comparing with original like
1498  * in load firmware package? */
1499         for (frame = (struct stframe *)fw->data;
1500                         frame < (struct stframe *)(fw->data + fw->size);
1501                         frame = (struct stframe *)((u8 *)(frame + 1) +
1502                                 frame->count)) {
1503                 if (WaitTillCardIsFree(base))
1504                         goto errrelfw;
1505
1506                 outw(0xf1, base); /* start download sequence */
1507                 outw(0x00, base);
1508                 outw(frame->addr, base); /* lsb of address */
1509
1510                 word_count = (frame->count >> 1) + frame->count % 2;
1511                 outw(word_count + 1, base);
1512                 InterruptTheCard(base);
1513
1514                 udelay(50); /* 0xf */
1515
1516                 if (WaitTillCardIsFree(base))
1517                         goto errrelfw;
1518
1519                 status = inw(base + 0x4);
1520                 if (status != 0) {
1521                         dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
1522                                 KERN_WARNING "Address:0x%x\n"
1523                                 KERN_WARNING "Count:0x%x\n"
1524                                 KERN_WARNING "Status: 0x%x\n",
1525                                 index + 1, frame->addr, frame->count, status);
1526                         goto errrelfw;
1527                 }
1528
1529                 data = kmalloc(word_count * 2, GFP_KERNEL);
1530                 if (data == NULL) {
1531                         dev_err(&pdev->dev, "Card%d, firmware upload "
1532                                 "failed, not enough memory\n", index + 1);
1533                         goto errrelfw;
1534                 }
1535                 inw(base);
1536                 insw(base, data, word_count);
1537                 InterruptTheCard(base);
1538
1539                 for (a = 0; a < frame->count; a++)
1540                         if (data[a] != frame->data[a]) {
1541                                 kfree(data);
1542                                 dev_err(&pdev->dev, "Card%d, firmware upload "
1543                                         "failed\n", index + 1);
1544                                 goto errrelfw;
1545                         }
1546                 kfree(data);
1547
1548                 udelay(50); /* 0xf */
1549
1550                 if (WaitTillCardIsFree(base))
1551                         goto errrelfw;
1552
1553                 status = inw(base + 0x4);
1554                 if (status != 0) {
1555                         dev_err(&pdev->dev, "Card%d verify got out of sync. "
1556                                 "Card Status:0x%x\n", index + 1, status);
1557                         goto errrelfw;
1558                 }
1559         }
1560
1561         /* xfer ctrl */
1562         if (WaitTillCardIsFree(base))
1563                 goto errrelfw;
1564
1565         outw(0xf2, base);
1566         outw(0x800, base);
1567         outw(0x0, base);
1568         outw(0x0, base);
1569         InterruptTheCard(base);
1570         outw(0x0, base + 0x4); /* for ISI4608 cards */
1571
1572         board->status |= FIRMWARE_LOADED;
1573         retval = 0;
1574
1575 errrelfw:
1576         release_firmware(fw);
1577 end:
1578         return retval;
1579 }
1580
1581 /*
1582  *      Insmod can set static symbols so keep these static
1583  */
1584 static unsigned int card_count;
1585
1586 static int __devinit isicom_probe(struct pci_dev *pdev,
1587         const struct pci_device_id *ent)
1588 {
1589         unsigned int signature, index;
1590         int retval = -EPERM;
1591         struct isi_board *board = NULL;
1592
1593         if (card_count >= BOARD_COUNT)
1594                 goto err;
1595
1596         retval = pci_enable_device(pdev);
1597         if (retval) {
1598                 dev_err(&pdev->dev, "failed to enable\n");
1599                 goto err;
1600         }
1601
1602         dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
1603
1604         /* allot the first empty slot in the array */
1605         for (index = 0; index < BOARD_COUNT; index++)
1606                 if (isi_card[index].base == 0) {
1607                         board = &isi_card[index];
1608                         break;
1609                 }
1610
1611         board->index = index;
1612         board->base = pci_resource_start(pdev, 3);
1613         board->irq = pdev->irq;
1614         card_count++;
1615
1616         pci_set_drvdata(pdev, board);
1617
1618         retval = pci_request_region(pdev, 3, ISICOM_NAME);
1619         if (retval) {
1620                 dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
1621                         "will be disabled.\n", board->base, board->base + 15,
1622                         index + 1);
1623                 retval = -EBUSY;
1624                 goto errdec;
1625         }
1626
1627         retval = request_irq(board->irq, isicom_interrupt,
1628                         IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
1629         if (retval < 0) {
1630                 dev_err(&pdev->dev, "Could not install handler at Irq %d. "
1631                         "Card%d will be disabled.\n", board->irq, index + 1);
1632                 goto errunrr;
1633         }
1634
1635         retval = reset_card(pdev, index, &signature);
1636         if (retval < 0)
1637                 goto errunri;
1638
1639         retval = load_firmware(pdev, index, signature);
1640         if (retval < 0)
1641                 goto errunri;
1642
1643         for (index = 0; index < board->port_count; index++)
1644                 tty_register_device(isicom_normal, board->index * 16 + index,
1645                                 &pdev->dev);
1646
1647         return 0;
1648
1649 errunri:
1650         free_irq(board->irq, board);
1651 errunrr:
1652         pci_release_region(pdev, 3);
1653 errdec:
1654         board->base = 0;
1655         card_count--;
1656         pci_disable_device(pdev);
1657 err:
1658         return retval;
1659 }
1660
1661 static void __devexit isicom_remove(struct pci_dev *pdev)
1662 {
1663         struct isi_board *board = pci_get_drvdata(pdev);
1664         unsigned int i;
1665
1666         for (i = 0; i < board->port_count; i++)
1667                 tty_unregister_device(isicom_normal, board->index * 16 + i);
1668
1669         free_irq(board->irq, board);
1670         pci_release_region(pdev, 3);
1671         board->base = 0;
1672         card_count--;
1673         pci_disable_device(pdev);
1674 }
1675
1676 static int __init isicom_init(void)
1677 {
1678         int retval, idx, channel;
1679         struct isi_port *port;
1680
1681         for (idx = 0; idx < BOARD_COUNT; idx++) {
1682                 port = &isi_ports[idx * 16];
1683                 isi_card[idx].ports = port;
1684                 spin_lock_init(&isi_card[idx].card_lock);
1685                 for (channel = 0; channel < 16; channel++, port++) {
1686                         tty_port_init(&port->port);
1687                         port->port.ops = &isicom_port_ops;
1688                         port->magic = ISICOM_MAGIC;
1689                         port->card = &isi_card[idx];
1690                         port->channel = channel;
1691                         port->port.close_delay = 50 * HZ/100;
1692                         port->port.closing_wait = 3000 * HZ/100;
1693                         port->status = 0;
1694                         /*  . . .  */
1695                 }
1696                 isi_card[idx].base = 0;
1697                 isi_card[idx].irq = 0;
1698         }
1699
1700         /* tty driver structure initialization */
1701         isicom_normal = alloc_tty_driver(PORT_COUNT);
1702         if (!isicom_normal) {
1703                 retval = -ENOMEM;
1704                 goto error;
1705         }
1706
1707         isicom_normal->owner                    = THIS_MODULE;
1708         isicom_normal->name                     = "ttyM";
1709         isicom_normal->major                    = ISICOM_NMAJOR;
1710         isicom_normal->minor_start              = 0;
1711         isicom_normal->type                     = TTY_DRIVER_TYPE_SERIAL;
1712         isicom_normal->subtype                  = SERIAL_TYPE_NORMAL;
1713         isicom_normal->init_termios             = tty_std_termios;
1714         isicom_normal->init_termios.c_cflag     = B9600 | CS8 | CREAD | HUPCL |
1715                 CLOCAL;
1716         isicom_normal->flags                    = TTY_DRIVER_REAL_RAW |
1717                 TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK;
1718         tty_set_operations(isicom_normal, &isicom_ops);
1719
1720         retval = tty_register_driver(isicom_normal);
1721         if (retval) {
1722                 pr_dbg("Couldn't register the dialin driver\n");
1723                 goto err_puttty;
1724         }
1725
1726         retval = pci_register_driver(&isicom_driver);
1727         if (retval < 0) {
1728                 printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
1729                 goto err_unrtty;
1730         }
1731
1732         mod_timer(&tx, jiffies + 1);
1733
1734         return 0;
1735 err_unrtty:
1736         tty_unregister_driver(isicom_normal);
1737 err_puttty:
1738         put_tty_driver(isicom_normal);
1739 error:
1740         return retval;
1741 }
1742
1743 static void __exit isicom_exit(void)
1744 {
1745         del_timer_sync(&tx);
1746
1747         pci_unregister_driver(&isicom_driver);
1748         tty_unregister_driver(isicom_normal);
1749         put_tty_driver(isicom_normal);
1750 }
1751
1752 module_init(isicom_init);
1753 module_exit(isicom_exit);
1754
1755 MODULE_AUTHOR("MultiTech");
1756 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
1757 MODULE_LICENSE("GPL");