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