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