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