tty/serial: lay the foundations for the next set of reworks
[pandora-kernel.git] / drivers / char / isicom.c
1 /*
2  *      This program is free software; you can redistribute it and/or
3  *      modify it under the terms of the GNU General Public License
4  *      as published by the Free Software Foundation; either version
5  *      2 of the License, or (at your option) any later version.
6  *
7  *      Original driver code supplied by Multi-Tech
8  *
9  *      Changes
10  *      1/9/98  alan@redhat.com         Merge to 2.0.x kernel tree
11  *                                      Obtain and use official major/minors
12  *                                      Loader switched to a misc device
13  *                                      (fixed range check bug as a side effect)
14  *                                      Printk clean up
15  *      9/12/98 alan@redhat.com         Rough port to 2.1.x
16  *
17  *      10/6/99 sameer                  Merged the ISA and PCI drivers to
18  *                                      a new unified driver.
19  *
20  *      3/9/99  sameer                  Added support for ISI4616 cards.
21  *
22  *      16/9/99 sameer                  We do not force RTS low anymore.
23  *                                      This is to prevent the firmware
24  *                                      from getting confused.
25  *
26  *      26/10/99 sameer                 Cosmetic changes:The driver now
27  *                                      dumps the Port Count information
28  *                                      along with I/O address and IRQ.
29  *
30  *      13/12/99 sameer                 Fixed the problem with IRQ sharing.
31  *
32  *      10/5/00  sameer                 Fixed isicom_shutdown_board()
33  *                                      to not lower DTR on all the ports
34  *                                      when the last port on the card is
35  *                                      closed.
36  *
37  *      10/5/00  sameer                 Signal mask setup command added
38  *                                      to  isicom_setup_port and
39  *                                      isicom_shutdown_port.
40  *
41  *      24/5/00  sameer                 The driver is now SMP aware.
42  *
43  *
44  *      27/11/00 Vinayak P Risbud       Fixed the Driver Crash Problem
45  *
46  *
47  *      03/01/01  anil .s               Added support for resetting the
48  *                                      internal modems on ISI cards.
49  *
50  *      08/02/01  anil .s               Upgraded the driver for kernel
51  *                                      2.4.x
52  *
53  *      11/04/01  Kevin                 Fixed firmware load problem with
54  *                                      ISIHP-4X card
55  *
56  *      30/04/01  anil .s               Fixed the remote login through
57  *                                      ISI port problem. Now the link
58  *                                      does not go down before password
59  *                                      prompt.
60  *
61  *      03/05/01  anil .s               Fixed the problem with IRQ sharing
62  *                                      among ISI-PCI cards.
63  *
64  *      03/05/01  anil .s               Added support to display the version
65  *                                      info during insmod as well as module
66  *                                      listing by lsmod.
67  *
68  *      10/05/01  anil .s               Done the modifications to the source
69  *                                      file and Install script so that the
70  *                                      same installation can be used for
71  *                                      2.2.x and 2.4.x kernel.
72  *
73  *      06/06/01  anil .s               Now we drop both dtr and rts during
74  *                                      shutdown_port as well as raise them
75  *                                      during isicom_config_port.
76  *
77  *      09/06/01 acme@conectiva.com.br  use capable, not suser, do
78  *                                      restore_flags on failure in
79  *                                      isicom_send_break, verify put_user
80  *                                      result
81  *
82  *      11/02/03  ranjeeth              Added support for 230 Kbps and 460 Kbps
83  *                                      Baud index extended to 21
84  *
85  *      20/03/03  ranjeeth              Made to work for Linux Advanced server.
86  *                                      Taken care of license warning.
87  *
88  *      10/12/03  Ravindra              Made to work for Fedora Core 1 of
89  *                                      Red Hat Distribution
90  *
91  *      06/01/05  Alan Cox              Merged the ISI and base kernel strands
92  *                                      into a single 2.6 driver
93  *
94  *      ***********************************************************
95  *
96  *      To use this driver you also need the support package. You
97  *      can find this in RPM format on
98  *              ftp://ftp.linux.org.uk/pub/linux/alan
99  *
100  *      You can find the original tools for this direct from Multitech
101  *              ftp://ftp.multitech.com/ISI-Cards/
102  *
103  *      Having installed the cards the module options (/etc/modprobe.conf)
104  *
105  *      options isicom   io=card1,card2,card3,card4 irq=card1,card2,card3,card4
106  *
107  *      Omit those entries for boards you don't have installed.
108  *
109  *      TODO
110  *              Merge testing
111  *              64-bit verification
112  */
113
114 #include <linux/module.h>
115 #include <linux/firmware.h>
116 #include <linux/kernel.h>
117 #include <linux/tty.h>
118 #include <linux/tty_flip.h>
119 #include <linux/termios.h>
120 #include <linux/fs.h>
121 #include <linux/sched.h>
122 #include <linux/serial.h>
123 #include <linux/mm.h>
124 #include <linux/interrupt.h>
125 #include <linux/timer.h>
126 #include <linux/delay.h>
127 #include <linux/ioport.h>
128
129 #include <asm/uaccess.h>
130 #include <asm/io.h>
131 #include <asm/system.h>
132
133 #include <linux/pci.h>
134
135 #include <linux/isicom.h>
136
137 #define InterruptTheCard(base) outw(0, (base) + 0xc)
138 #define ClearInterrupt(base) inw((base) + 0x0a)
139
140 #define pr_dbg(str...) pr_debug("ISICOM: " str)
141 #ifdef DEBUG
142 #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c))
143 #else
144 #define isicom_paranoia_check(a, b, c) 0
145 #endif
146
147 static int isicom_probe(struct pci_dev *, const struct pci_device_id *);
148 static void __devexit isicom_remove(struct pci_dev *);
149
150 static struct pci_device_id isicom_pci_tbl[] = {
151         { PCI_DEVICE(VENDOR_ID, 0x2028) },
152         { PCI_DEVICE(VENDOR_ID, 0x2051) },
153         { PCI_DEVICE(VENDOR_ID, 0x2052) },
154         { PCI_DEVICE(VENDOR_ID, 0x2053) },
155         { PCI_DEVICE(VENDOR_ID, 0x2054) },
156         { PCI_DEVICE(VENDOR_ID, 0x2055) },
157         { PCI_DEVICE(VENDOR_ID, 0x2056) },
158         { PCI_DEVICE(VENDOR_ID, 0x2057) },
159         { PCI_DEVICE(VENDOR_ID, 0x2058) },
160         { 0 }
161 };
162 MODULE_DEVICE_TABLE(pci, isicom_pci_tbl);
163
164 static struct pci_driver isicom_driver = {
165         .name           = "isicom",
166         .id_table       = isicom_pci_tbl,
167         .probe          = isicom_probe,
168         .remove         = __devexit_p(isicom_remove)
169 };
170
171 static int prev_card = 3;       /*      start servicing isi_card[0]     */
172 static struct tty_driver *isicom_normal;
173
174 static 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) break;
475                         word_count = cnt >> 1;
476                         outsw(base, port->xmit_buf+port->xmit_tail,word_count);
477                         port->xmit_tail = (port->xmit_tail
478                                 + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
479                         txcount -= (word_count << 1);
480                         port->xmit_cnt -= (word_count << 1);
481                         if (cnt & 0x0001) {
482                                 residue = YES;
483                                 wrd = port->xmit_buf[port->xmit_tail];
484                                 port->xmit_tail = (port->xmit_tail + 1)
485                                         & (SERIAL_XMIT_SIZE - 1);
486                                 port->xmit_cnt--;
487                                 txcount--;
488                         }
489                 }
490
491                 InterruptTheCard(base);
492                 if (port->xmit_cnt <= 0)
493                         port->status &= ~ISI_TXOK;
494                 if (port->xmit_cnt <= WAKEUP_CHARS)
495                         tty_wakeup(tty);
496         }
497
498 unlock:
499         spin_unlock_irqrestore(&isi_card[card].card_lock, flags);
500         /*      schedule another tx for hopefully in about 10ms */
501 sched_again:
502         mod_timer(&tx, jiffies + msecs_to_jiffies(10));
503 }
504
505 /*
506  *      Main interrupt handler routine
507  */
508
509 static irqreturn_t isicom_interrupt(int irq, void *dev_id)
510 {
511         struct isi_board *card = dev_id;
512         struct isi_port *port;
513         struct tty_struct *tty;
514         unsigned long base;
515         u16 header, word_count, count, channel;
516         short byte_count;
517         unsigned char *rp;
518
519         if (!card || !(card->status & FIRMWARE_LOADED))
520                 return IRQ_NONE;
521
522         base = card->base;
523
524         /* did the card interrupt us? */
525         if (!(inw(base + 0x0e) & 0x02))
526                 return IRQ_NONE;
527
528         spin_lock(&card->card_lock);
529
530         /*
531          * disable any interrupts from the PCI card and lower the
532          * interrupt line
533          */
534         outw(0x8000, base+0x04);
535         ClearInterrupt(base);
536
537         inw(base);              /* get the dummy word out */
538         header = inw(base);
539         channel = (header & 0x7800) >> card->shift_count;
540         byte_count = header & 0xff;
541
542         if (channel + 1 > card->port_count) {
543                 printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): "
544                         "%d(channel) > port_count.\n", base, channel+1);
545                 outw(0x0000, base+0x04); /* enable interrupts */
546                 spin_unlock(&card->card_lock);
547                 return IRQ_HANDLED;
548         }
549         port = card->ports + channel;
550         if (!(port->flags & ASYNC_INITIALIZED)) {
551                 outw(0x0000, base+0x04); /* enable interrupts */
552                 spin_unlock(&card->card_lock);
553                 return IRQ_HANDLED;
554         }
555
556         tty = port->tty;
557         if (tty == NULL) {
558                 word_count = byte_count >> 1;
559                 while(byte_count > 1) {
560                         inw(base);
561                         byte_count -= 2;
562                 }
563                 if (byte_count & 0x01)
564                         inw(base);
565                 outw(0x0000, base+0x04); /* enable interrupts */
566                 spin_unlock(&card->card_lock);
567                 return IRQ_HANDLED;
568         }
569
570         if (header & 0x8000) {          /* Status Packet */
571                 header = inw(base);
572                 switch(header & 0xff) {
573                 case 0: /* Change in EIA signals */
574                         if (port->flags & ASYNC_CHECK_CD) {
575                                 if (port->status & ISI_DCD) {
576                                         if (!(header & ISI_DCD)) {
577                                         /* Carrier has been lost  */
578                                                 pr_dbg("interrupt: DCD->low.\n"
579                                                         );
580                                                 port->status &= ~ISI_DCD;
581                                                 tty_hangup(tty);
582                                         }
583                                 } else if (header & ISI_DCD) {
584                                 /* Carrier has been detected */
585                                         pr_dbg("interrupt: DCD->high.\n");
586                                         port->status |= ISI_DCD;
587                                         wake_up_interruptible(&port->open_wait);
588                                 }
589                         } else {
590                                 if (header & ISI_DCD)
591                                         port->status |= ISI_DCD;
592                                 else
593                                         port->status &= ~ISI_DCD;
594                         }
595
596                         if (port->flags & ASYNC_CTS_FLOW) {
597                                 if (port->tty->hw_stopped) {
598                                         if (header & ISI_CTS) {
599                                                 port->tty->hw_stopped = 0;
600                                                 /* start tx ing */
601                                                 port->status |= (ISI_TXOK
602                                                         | ISI_CTS);
603                                                 tty_wakeup(tty);
604                                         }
605                                 } else if (!(header & ISI_CTS)) {
606                                         port->tty->hw_stopped = 1;
607                                         /* stop tx ing */
608                                         port->status &= ~(ISI_TXOK | ISI_CTS);
609                                 }
610                         } else {
611                                 if (header & ISI_CTS)
612                                         port->status |= ISI_CTS;
613                                 else
614                                         port->status &= ~ISI_CTS;
615                         }
616
617                         if (header & ISI_DSR)
618                                 port->status |= ISI_DSR;
619                         else
620                                 port->status &= ~ISI_DSR;
621
622                         if (header & ISI_RI)
623                                 port->status |= ISI_RI;
624                         else
625                                 port->status &= ~ISI_RI;
626
627                         break;
628
629                 case 1: /* Received Break !!! */
630                         tty_insert_flip_char(tty, 0, TTY_BREAK);
631                         if (port->flags & ASYNC_SAK)
632                                 do_SAK(tty);
633                         tty_flip_buffer_push(tty);
634                         break;
635
636                 case 2: /* Statistics            */
637                         pr_dbg("isicom_interrupt: stats!!!.\n");
638                         break;
639
640                 default:
641                         pr_dbg("Intr: Unknown code in status packet.\n");
642                         break;
643                 }
644         } else {                                /* Data   Packet */
645
646                 count = tty_prepare_flip_string(tty, &rp, byte_count & ~1);
647                 pr_dbg("Intr: Can rx %d of %d bytes.\n", count, byte_count);
648                 word_count = count >> 1;
649                 insw(base, rp, word_count);
650                 byte_count -= (word_count << 1);
651                 if (count & 0x0001) {
652                         tty_insert_flip_char(tty,  inw(base) & 0xff,
653                                 TTY_NORMAL);
654                         byte_count -= 2;
655                 }
656                 if (byte_count > 0) {
657                         pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping "
658                                 "bytes...\n", base, channel + 1);
659                         while(byte_count > 0) { /* drain out unread xtra data */
660                                 inw(base);
661                                 byte_count -= 2;
662                         }
663                 }
664                 tty_flip_buffer_push(tty);
665         }
666         outw(0x0000, base+0x04); /* enable interrupts */
667         spin_unlock(&card->card_lock);
668
669         return IRQ_HANDLED;
670 }
671
672 static void isicom_config_port(struct isi_port *port)
673 {
674         struct isi_board *card = port->card;
675         struct tty_struct *tty;
676         unsigned long baud;
677         unsigned long base = card->base;
678         u16 channel_setup, channel = port->channel,
679                 shift_count = card->shift_count;
680         unsigned char flow_ctrl;
681
682         if (!(tty = port->tty) || !tty->termios)
683                 return;
684         baud = C_BAUD(tty);
685         if (baud & CBAUDEX) {
686                 baud &= ~CBAUDEX;
687
688                 /*  if CBAUDEX bit is on and the baud is set to either 50 or 75
689                  *  then the card is programmed for 57.6Kbps or 115Kbps
690                  *  respectively.
691                  */
692
693                 /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
694                 if (baud < 1 || baud > 4)
695                         port->tty->termios->c_cflag &= ~CBAUDEX;
696                 else
697                         baud += 15;
698         }
699         if (baud == 15) {
700
701                 /*  the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set
702                  *  by the set_serial_info ioctl ... this is done by
703                  *  the 'setserial' utility.
704                  */
705
706                 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
707                         baud++; /*  57.6 Kbps */
708                 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
709                         baud +=2; /*  115  Kbps */
710                 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
711                         baud += 3; /* 230 kbps*/
712                 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
713                         baud += 4; /* 460 kbps*/
714         }
715         if (linuxb_to_isib[baud] == -1) {
716                 /* hang up */
717                 drop_dtr(port);
718                 return;
719         }
720         else
721                 raise_dtr(port);
722
723         if (WaitTillCardIsFree(base) == 0) {
724                 outw(0x8000 | (channel << shift_count) |0x03, base);
725                 outw(linuxb_to_isib[baud] << 8 | 0x03, base);
726                 channel_setup = 0;
727                 switch(C_CSIZE(tty)) {
728                 case CS5:
729                         channel_setup |= ISICOM_CS5;
730                         break;
731                 case CS6:
732                         channel_setup |= ISICOM_CS6;
733                         break;
734                 case CS7:
735                         channel_setup |= ISICOM_CS7;
736                         break;
737                 case CS8:
738                         channel_setup |= ISICOM_CS8;
739                         break;
740                 }
741
742                 if (C_CSTOPB(tty))
743                         channel_setup |= ISICOM_2SB;
744                 if (C_PARENB(tty)) {
745                         channel_setup |= ISICOM_EVPAR;
746                         if (C_PARODD(tty))
747                                 channel_setup |= ISICOM_ODPAR;
748                 }
749                 outw(channel_setup, base);
750                 InterruptTheCard(base);
751         }
752         if (C_CLOCAL(tty))
753                 port->flags &= ~ASYNC_CHECK_CD;
754         else
755                 port->flags |= ASYNC_CHECK_CD;
756
757         /* flow control settings ...*/
758         flow_ctrl = 0;
759         port->flags &= ~ASYNC_CTS_FLOW;
760         if (C_CRTSCTS(tty)) {
761                 port->flags |= ASYNC_CTS_FLOW;
762                 flow_ctrl |= ISICOM_CTSRTS;
763         }
764         if (I_IXON(tty))
765                 flow_ctrl |= ISICOM_RESPOND_XONXOFF;
766         if (I_IXOFF(tty))
767                 flow_ctrl |= ISICOM_INITIATE_XONXOFF;
768
769         if (WaitTillCardIsFree(base) == 0) {
770                 outw(0x8000 | (channel << shift_count) |0x04, base);
771                 outw(flow_ctrl << 8 | 0x05, base);
772                 outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
773                 InterruptTheCard(base);
774         }
775
776         /*      rx enabled -> enable port for rx on the card    */
777         if (C_CREAD(tty)) {
778                 card->port_status |= (1 << channel);
779                 outw(card->port_status, base + 0x02);
780         }
781 }
782
783 /* open et all */
784
785 static inline void isicom_setup_board(struct isi_board *bp)
786 {
787         int channel;
788         struct isi_port *port;
789         unsigned long flags;
790
791         spin_lock_irqsave(&bp->card_lock, flags);
792         if (bp->status & BOARD_ACTIVE) {
793                 spin_unlock_irqrestore(&bp->card_lock, flags);
794                 return;
795         }
796         port = bp->ports;
797         bp->status |= BOARD_ACTIVE;
798         for (channel = 0; channel < bp->port_count; channel++, port++)
799                 drop_dtr_rts(port);
800         spin_unlock_irqrestore(&bp->card_lock, flags);
801 }
802
803 static int isicom_setup_port(struct isi_port *port)
804 {
805         struct isi_board *card = port->card;
806         unsigned long flags;
807
808         if (port->flags & ASYNC_INITIALIZED) {
809                 return 0;
810         }
811         if (!port->xmit_buf) {
812                 unsigned long page;
813
814                 if (!(page = get_zeroed_page(GFP_KERNEL)))
815                         return -ENOMEM;
816
817                 if (port->xmit_buf) {
818                         free_page(page);
819                         return -ERESTARTSYS;
820                 }
821                 port->xmit_buf = (unsigned char *) page;
822         }
823
824         spin_lock_irqsave(&card->card_lock, flags);
825         if (port->tty)
826                 clear_bit(TTY_IO_ERROR, &port->tty->flags);
827         if (port->count == 1)
828                 card->count++;
829
830         port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
831
832         /*      discard any residual data       */
833         if (WaitTillCardIsFree(card->base) == 0) {
834                 outw(0x8000 | (port->channel << card->shift_count) | 0x02,
835                                 card->base);
836                 outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base);
837                 InterruptTheCard(card->base);
838         }
839
840         isicom_config_port(port);
841         port->flags |= ASYNC_INITIALIZED;
842         spin_unlock_irqrestore(&card->card_lock, flags);
843
844         return 0;
845 }
846
847 static int block_til_ready(struct tty_struct *tty, struct file *filp,
848         struct isi_port *port)
849 {
850         struct isi_board *card = port->card;
851         int do_clocal = 0, retval;
852         unsigned long flags;
853         DECLARE_WAITQUEUE(wait, current);
854
855         /* block if port is in the process of being closed */
856
857         if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
858                 pr_dbg("block_til_ready: close in progress.\n");
859                 interruptible_sleep_on(&port->close_wait);
860                 if (port->flags & ASYNC_HUP_NOTIFY)
861                         return -EAGAIN;
862                 else
863                         return -ERESTARTSYS;
864         }
865
866         /* if non-blocking mode is set ... */
867
868         if ((filp->f_flags & O_NONBLOCK) ||
869                         (tty->flags & (1 << TTY_IO_ERROR))) {
870                 pr_dbg("block_til_ready: non-block mode.\n");
871                 port->flags |= ASYNC_NORMAL_ACTIVE;
872                 return 0;
873         }
874
875         if (C_CLOCAL(tty))
876                 do_clocal = 1;
877
878         /* block waiting for DCD to be asserted, and while
879                                                 callout dev is busy */
880         retval = 0;
881         add_wait_queue(&port->open_wait, &wait);
882
883         spin_lock_irqsave(&card->card_lock, flags);
884         if (!tty_hung_up_p(filp))
885                 port->count--;
886         port->blocked_open++;
887         spin_unlock_irqrestore(&card->card_lock, flags);
888
889         while (1) {
890                 raise_dtr_rts(port);
891
892                 set_current_state(TASK_INTERRUPTIBLE);
893                 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
894                         if (port->flags & ASYNC_HUP_NOTIFY)
895                                 retval = -EAGAIN;
896                         else
897                                 retval = -ERESTARTSYS;
898                         break;
899                 }
900                 if (!(port->flags & ASYNC_CLOSING) &&
901                                 (do_clocal || (port->status & ISI_DCD))) {
902                         break;
903                 }
904                 if (signal_pending(current)) {
905                         retval = -ERESTARTSYS;
906                         break;
907                 }
908                 schedule();
909         }
910         set_current_state(TASK_RUNNING);
911         remove_wait_queue(&port->open_wait, &wait);
912         spin_lock_irqsave(&card->card_lock, flags);
913         if (!tty_hung_up_p(filp))
914                 port->count++;
915         port->blocked_open--;
916         spin_unlock_irqrestore(&card->card_lock, flags);
917         if (retval)
918                 return retval;
919         port->flags |= ASYNC_NORMAL_ACTIVE;
920         return 0;
921 }
922
923 static int isicom_open(struct tty_struct *tty, struct file *filp)
924 {
925         struct isi_port *port;
926         struct isi_board *card;
927         unsigned int board;
928         int error, line;
929
930         line = tty->index;
931         if (line < 0 || line > PORT_COUNT-1)
932                 return -ENODEV;
933         board = BOARD(line);
934         card = &isi_card[board];
935
936         if (!(card->status & FIRMWARE_LOADED))
937                 return -ENODEV;
938
939         /*  open on a port greater than the port count for the card !!! */
940         if (line > ((board * 16) + card->port_count - 1))
941                 return -ENODEV;
942
943         port = &isi_ports[line];
944         if (isicom_paranoia_check(port, tty->name, "isicom_open"))
945                 return -ENODEV;
946
947         isicom_setup_board(card);
948
949         port->count++;
950         tty->driver_data = port;
951         port->tty = tty;
952         if ((error = isicom_setup_port(port))!=0)
953                 return error;
954         if ((error = block_til_ready(tty, filp, port))!=0)
955                 return error;
956
957         return 0;
958 }
959
960 /* close et all */
961
962 static inline void isicom_shutdown_board(struct isi_board *bp)
963 {
964         if (bp->status & BOARD_ACTIVE) {
965                 bp->status &= ~BOARD_ACTIVE;
966         }
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                 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         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         }
1292         else {
1293                 port->close_delay = newinfo.close_delay;
1294                 port->closing_wait = newinfo.closing_wait;
1295                 port->flags = ((port->flags & ~ASYNC_FLAGS) |
1296                                 (newinfo.flags & ASYNC_FLAGS));
1297         }
1298         if (reconfig_port) {
1299                 unsigned long flags;
1300                 spin_lock_irqsave(&port->card->card_lock, flags);
1301                 isicom_config_port(port);
1302                 spin_unlock_irqrestore(&port->card->card_lock, flags);
1303         }
1304         unlock_kernel();
1305         return 0;
1306 }
1307
1308 static int isicom_get_serial_info(struct isi_port *port,
1309         struct serial_struct __user *info)
1310 {
1311         struct serial_struct out_info;
1312
1313         lock_kernel();
1314         memset(&out_info, 0, sizeof(out_info));
1315 /*      out_info.type = ? */
1316         out_info.line = port - isi_ports;
1317         out_info.port = port->card->base;
1318         out_info.irq = port->card->irq;
1319         out_info.flags = port->flags;
1320 /*      out_info.baud_base = ? */
1321         out_info.close_delay = port->close_delay;
1322         out_info.closing_wait = port->closing_wait;
1323         unlock_kernel();
1324         if (copy_to_user(info, &out_info, sizeof(out_info)))
1325                 return -EFAULT;
1326         return 0;
1327 }
1328
1329 static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1330         unsigned int cmd, unsigned long arg)
1331 {
1332         struct isi_port *port = tty->driver_data;
1333         void __user *argp = (void __user *)arg;
1334         int retval;
1335
1336         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1337                 return -ENODEV;
1338
1339         switch(cmd) {
1340         case TCSBRK:
1341                 retval = tty_check_change(tty);
1342                 if (retval)
1343                         return retval;
1344                 tty_wait_until_sent(tty, 0);
1345                 if (!arg)
1346                         isicom_send_break(port, HZ/4);
1347                 return 0;
1348
1349         case TCSBRKP:
1350                 retval = tty_check_change(tty);
1351                 if (retval)
1352                         return retval;
1353                 tty_wait_until_sent(tty, 0);
1354                 isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4);
1355                 return 0;
1356         case TIOCGSERIAL:
1357                 return isicom_get_serial_info(port, argp);
1358
1359         case TIOCSSERIAL:
1360                 return isicom_set_serial_info(port, argp);
1361
1362         default:
1363                 return -ENOIOCTLCMD;
1364         }
1365         return 0;
1366 }
1367
1368 /* set_termios et all */
1369 static void isicom_set_termios(struct tty_struct *tty,
1370         struct ktermios *old_termios)
1371 {
1372         struct isi_port *port = tty->driver_data;
1373         unsigned long flags;
1374
1375         if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
1376                 return;
1377
1378         if (tty->termios->c_cflag == old_termios->c_cflag &&
1379                         tty->termios->c_iflag == old_termios->c_iflag)
1380                 return;
1381
1382         spin_lock_irqsave(&port->card->card_lock, flags);
1383         isicom_config_port(port);
1384         spin_unlock_irqrestore(&port->card->card_lock, flags);
1385
1386         if ((old_termios->c_cflag & CRTSCTS) &&
1387                         !(tty->termios->c_cflag & CRTSCTS)) {
1388                 tty->hw_stopped = 0;
1389                 isicom_start(tty);
1390         }
1391 }
1392
1393 /* throttle et all */
1394 static void isicom_throttle(struct tty_struct *tty)
1395 {
1396         struct isi_port *port = tty->driver_data;
1397         struct isi_board *card = port->card;
1398
1399         if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
1400                 return;
1401
1402         /* tell the card that this port cannot handle any more data for now */
1403         card->port_status &= ~(1 << port->channel);
1404         outw(card->port_status, card->base + 0x02);
1405 }
1406
1407 /* unthrottle et all */
1408 static void isicom_unthrottle(struct tty_struct *tty)
1409 {
1410         struct isi_port *port = tty->driver_data;
1411         struct isi_board *card = port->card;
1412
1413         if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
1414                 return;
1415
1416         /* tell the card that this port is ready to accept more data */
1417         card->port_status |= (1 << port->channel);
1418         outw(card->port_status, card->base + 0x02);
1419 }
1420
1421 /* stop et all */
1422 static void isicom_stop(struct tty_struct *tty)
1423 {
1424         struct isi_port *port = tty->driver_data;
1425
1426         if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
1427                 return;
1428
1429         /* this tells the transmitter not to consider this port for
1430            data output to the card. */
1431         port->status &= ~ISI_TXOK;
1432 }
1433
1434 /* start et all */
1435 static void isicom_start(struct tty_struct *tty)
1436 {
1437         struct isi_port *port = tty->driver_data;
1438
1439         if (isicom_paranoia_check(port, tty->name, "isicom_start"))
1440                 return;
1441
1442         /* this tells the transmitter to consider this port for
1443            data output to the card. */
1444         port->status |= ISI_TXOK;
1445 }
1446
1447 static void isicom_hangup(struct tty_struct *tty)
1448 {
1449         struct isi_port *port = tty->driver_data;
1450         unsigned long flags;
1451
1452         if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
1453                 return;
1454
1455         spin_lock_irqsave(&port->card->card_lock, flags);
1456         isicom_shutdown_port(port);
1457         spin_unlock_irqrestore(&port->card->card_lock, flags);
1458
1459         port->count = 0;
1460         port->flags &= ~ASYNC_NORMAL_ACTIVE;
1461         port->tty = NULL;
1462         wake_up_interruptible(&port->open_wait);
1463 }
1464
1465
1466 /*
1467  * Driver init and deinit functions
1468  */
1469
1470 static const struct tty_operations isicom_ops = {
1471         .open                   = isicom_open,
1472         .close                  = isicom_close,
1473         .write                  = isicom_write,
1474         .put_char               = isicom_put_char,
1475         .flush_chars            = isicom_flush_chars,
1476         .write_room             = isicom_write_room,
1477         .chars_in_buffer        = isicom_chars_in_buffer,
1478         .ioctl                  = isicom_ioctl,
1479         .set_termios            = isicom_set_termios,
1480         .throttle               = isicom_throttle,
1481         .unthrottle             = isicom_unthrottle,
1482         .stop                   = isicom_stop,
1483         .start                  = isicom_start,
1484         .hangup                 = isicom_hangup,
1485         .flush_buffer           = isicom_flush_buffer,
1486         .tiocmget               = isicom_tiocmget,
1487         .tiocmset               = isicom_tiocmset,
1488 };
1489
1490 static int __devinit reset_card(struct pci_dev *pdev,
1491         const unsigned int card, unsigned int *signature)
1492 {
1493         struct isi_board *board = pci_get_drvdata(pdev);
1494         unsigned long base = board->base;
1495         unsigned int sig, portcount = 0;
1496         int retval = 0;
1497
1498         dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
1499                 base);
1500
1501         inw(base + 0x8);
1502
1503         msleep(10);
1504
1505         outw(0, base + 0x8); /* Reset */
1506
1507         msleep(1000);
1508
1509         sig = inw(base + 0x4) & 0xff;
1510
1511         if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd &&
1512                         sig != 0xee) {
1513                 dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible "
1514                         "bad I/O Port Address 0x%lx).\n", card + 1, base);
1515                 dev_dbg(&pdev->dev, "Sig=0x%x\n", sig);
1516                 retval = -EIO;
1517                 goto end;
1518         }
1519
1520         msleep(10);
1521
1522         portcount = inw(base + 0x2);
1523         if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 &&
1524                                 portcount != 8 && portcount != 16)) {
1525                 dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
1526                         card + 1);
1527                 retval = -EIO;
1528                 goto end;
1529         }
1530
1531         switch (sig) {
1532         case 0xa5:
1533         case 0xbb:
1534         case 0xdd:
1535                 board->port_count = (portcount == 4) ? 4 : 8;
1536                 board->shift_count = 12;
1537                 break;
1538         case 0xcc:
1539         case 0xee:
1540                 board->port_count = 16;
1541                 board->shift_count = 11;
1542                 break;
1543         }
1544         dev_info(&pdev->dev, "-Done\n");
1545         *signature = sig;
1546
1547 end:
1548         return retval;
1549 }
1550
1551 static int __devinit load_firmware(struct pci_dev *pdev,
1552         const unsigned int index, const unsigned int signature)
1553 {
1554         struct isi_board *board = pci_get_drvdata(pdev);
1555         const struct firmware *fw;
1556         unsigned long base = board->base;
1557         unsigned int a;
1558         u16 word_count, status;
1559         int retval = -EIO;
1560         char *name;
1561         u8 *data;
1562
1563         struct stframe {
1564                 u16     addr;
1565                 u16     count;
1566                 u8      data[0];
1567         } *frame;
1568
1569         switch (signature) {
1570         case 0xa5:
1571                 name = "isi608.bin";
1572                 break;
1573         case 0xbb:
1574                 name = "isi608em.bin";
1575                 break;
1576         case 0xcc:
1577                 name = "isi616em.bin";
1578                 break;
1579         case 0xdd:
1580                 name = "isi4608.bin";
1581                 break;
1582         case 0xee:
1583                 name = "isi4616.bin";
1584                 break;
1585         default:
1586                 dev_err(&pdev->dev, "Unknown signature.\n");
1587                 goto end;
1588         }
1589
1590         retval = request_firmware(&fw, name, &pdev->dev);
1591         if (retval)
1592                 goto end;
1593
1594         retval = -EIO;
1595
1596         for (frame = (struct stframe *)fw->data;
1597                         frame < (struct stframe *)(fw->data + fw->size);
1598                         frame = (struct stframe *)((u8 *)(frame + 1) +
1599                                 frame->count)) {
1600                 if (WaitTillCardIsFree(base))
1601                         goto errrelfw;
1602
1603                 outw(0xf0, base);       /* start upload sequence */
1604                 outw(0x00, base);
1605                 outw(frame->addr, base); /* lsb of address */
1606
1607                 word_count = frame->count / 2 + frame->count % 2;
1608                 outw(word_count, base);
1609                 InterruptTheCard(base);
1610
1611                 udelay(100); /* 0x2f */
1612
1613                 if (WaitTillCardIsFree(base))
1614                         goto errrelfw;
1615
1616                 if ((status = inw(base + 0x4)) != 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                 if ((status = inw(base + 0x4)) != 0) {
1634                         dev_err(&pdev->dev, "Card%d got out of sync.Card "
1635                                 "Status:0x%x\n", index + 1, status);
1636                         goto errrelfw;
1637                 }
1638         }
1639
1640 /* XXX: should we test it by reading it back and comparing with original like
1641  * in load firmware package? */
1642         for (frame = (struct stframe *)fw->data;
1643                         frame < (struct stframe *)(fw->data + fw->size);
1644                         frame = (struct stframe *)((u8 *)(frame + 1) +
1645                                 frame->count)) {
1646                 if (WaitTillCardIsFree(base))
1647                         goto errrelfw;
1648
1649                 outw(0xf1, base); /* start download sequence */
1650                 outw(0x00, base);
1651                 outw(frame->addr, base); /* lsb of address */
1652
1653                 word_count = (frame->count >> 1) + frame->count % 2;
1654                 outw(word_count + 1, base);
1655                 InterruptTheCard(base);
1656
1657                 udelay(50); /* 0xf */
1658
1659                 if (WaitTillCardIsFree(base))
1660                         goto errrelfw;
1661
1662                 if ((status = inw(base + 0x4)) != 0) {
1663                         dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
1664                                 KERN_WARNING "Address:0x%x\n"
1665                                 KERN_WARNING "Count:0x%x\n"
1666                                 KERN_WARNING "Status: 0x%x\n",
1667                                 index + 1, frame->addr, frame->count, status);
1668                         goto errrelfw;
1669                 }
1670
1671                 data = kmalloc(word_count * 2, GFP_KERNEL);
1672                 if (data == NULL) {
1673                         dev_err(&pdev->dev, "Card%d, firmware upload "
1674                                 "failed, not enough memory\n", index + 1);
1675                         goto errrelfw;
1676                 }
1677                 inw(base);
1678                 insw(base, data, word_count);
1679                 InterruptTheCard(base);
1680
1681                 for (a = 0; a < frame->count; a++)
1682                         if (data[a] != frame->data[a]) {
1683                                 kfree(data);
1684                                 dev_err(&pdev->dev, "Card%d, firmware upload "
1685                                         "failed\n", index + 1);
1686                                 goto errrelfw;
1687                         }
1688                 kfree(data);
1689
1690                 udelay(50); /* 0xf */
1691
1692                 if (WaitTillCardIsFree(base))
1693                         goto errrelfw;
1694
1695                 if ((status = inw(base + 0x4)) != 0) {
1696                         dev_err(&pdev->dev, "Card%d verify got out of sync. "
1697                                 "Card Status:0x%x\n", index + 1, status);
1698                         goto errrelfw;
1699                 }
1700         }
1701
1702         /* xfer ctrl */
1703         if (WaitTillCardIsFree(base))
1704                 goto errrelfw;
1705
1706         outw(0xf2, base);
1707         outw(0x800, base);
1708         outw(0x0, base);
1709         outw(0x0, base);
1710         InterruptTheCard(base);
1711         outw(0x0, base + 0x4); /* for ISI4608 cards */
1712
1713         board->status |= FIRMWARE_LOADED;
1714         retval = 0;
1715
1716 errrelfw:
1717         release_firmware(fw);
1718 end:
1719         return retval;
1720 }
1721
1722 /*
1723  *      Insmod can set static symbols so keep these static
1724  */
1725 static unsigned int card_count;
1726
1727 static int __devinit isicom_probe(struct pci_dev *pdev,
1728         const struct pci_device_id *ent)
1729 {
1730         unsigned int signature, index;
1731         int retval = -EPERM;
1732         struct isi_board *board = NULL;
1733
1734         if (card_count >= BOARD_COUNT)
1735                 goto err;
1736
1737         dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
1738
1739         /* allot the first empty slot in the array */
1740         for (index = 0; index < BOARD_COUNT; index++)
1741                 if (isi_card[index].base == 0) {
1742                         board = &isi_card[index];
1743                         break;
1744                 }
1745
1746         board->index = index;
1747         board->base = pci_resource_start(pdev, 3);
1748         board->irq = pdev->irq;
1749         card_count++;
1750
1751         pci_set_drvdata(pdev, board);
1752
1753         retval = pci_request_region(pdev, 3, ISICOM_NAME);
1754         if (retval) {
1755                 dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
1756                         "will be disabled.\n", board->base, board->base + 15,
1757                         index + 1);
1758                 retval = -EBUSY;
1759                 goto errdec;
1760         }
1761
1762         retval = request_irq(board->irq, isicom_interrupt,
1763                         IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
1764         if (retval < 0) {
1765                 dev_err(&pdev->dev, "Could not install handler at Irq %d. "
1766                         "Card%d will be disabled.\n", board->irq, index + 1);
1767                 goto errunrr;
1768         }
1769
1770         retval = reset_card(pdev, index, &signature);
1771         if (retval < 0)
1772                 goto errunri;
1773
1774         retval = load_firmware(pdev, index, signature);
1775         if (retval < 0)
1776                 goto errunri;
1777
1778         for (index = 0; index < board->port_count; index++)
1779                 tty_register_device(isicom_normal, board->index * 16 + index,
1780                                 &pdev->dev);
1781
1782         return 0;
1783
1784 errunri:
1785         free_irq(board->irq, board);
1786 errunrr:
1787         pci_release_region(pdev, 3);
1788 errdec:
1789         board->base = 0;
1790         card_count--;
1791 err:
1792         return retval;
1793 }
1794
1795 static void __devexit isicom_remove(struct pci_dev *pdev)
1796 {
1797         struct isi_board *board = pci_get_drvdata(pdev);
1798         unsigned int i;
1799
1800         for (i = 0; i < board->port_count; i++)
1801                 tty_unregister_device(isicom_normal, board->index * 16 + i);
1802
1803         free_irq(board->irq, board);
1804         pci_release_region(pdev, 3);
1805         board->base = 0;
1806         card_count--;
1807 }
1808
1809 static int __init isicom_init(void)
1810 {
1811         int retval, idx, channel;
1812         struct isi_port *port;
1813
1814         for(idx = 0; idx < BOARD_COUNT; idx++) {
1815                 port = &isi_ports[idx * 16];
1816                 isi_card[idx].ports = port;
1817                 spin_lock_init(&isi_card[idx].card_lock);
1818                 for (channel = 0; channel < 16; channel++, port++) {
1819                         port->magic = ISICOM_MAGIC;
1820                         port->card = &isi_card[idx];
1821                         port->channel = channel;
1822                         port->close_delay = 50 * HZ/100;
1823                         port->closing_wait = 3000 * HZ/100;
1824                         port->status = 0;
1825                         init_waitqueue_head(&port->open_wait);
1826                         init_waitqueue_head(&port->close_wait);
1827                         /*  . . .  */
1828                 }
1829                 isi_card[idx].base = 0;
1830                 isi_card[idx].irq = 0;
1831         }
1832
1833         /* tty driver structure initialization */
1834         isicom_normal = alloc_tty_driver(PORT_COUNT);
1835         if (!isicom_normal) {
1836                 retval = -ENOMEM;
1837                 goto error;
1838         }
1839
1840         isicom_normal->owner                    = THIS_MODULE;
1841         isicom_normal->name                     = "ttyM";
1842         isicom_normal->major                    = ISICOM_NMAJOR;
1843         isicom_normal->minor_start              = 0;
1844         isicom_normal->type                     = TTY_DRIVER_TYPE_SERIAL;
1845         isicom_normal->subtype                  = SERIAL_TYPE_NORMAL;
1846         isicom_normal->init_termios             = tty_std_termios;
1847         isicom_normal->init_termios.c_cflag     = B9600 | CS8 | CREAD | HUPCL |
1848                 CLOCAL;
1849         isicom_normal->flags                    = TTY_DRIVER_REAL_RAW |
1850                 TTY_DRIVER_DYNAMIC_DEV;
1851         tty_set_operations(isicom_normal, &isicom_ops);
1852
1853         retval = tty_register_driver(isicom_normal);
1854         if (retval) {
1855                 pr_dbg("Couldn't register the dialin driver\n");
1856                 goto err_puttty;
1857         }
1858
1859         retval = pci_register_driver(&isicom_driver);
1860         if (retval < 0) {
1861                 printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
1862                 goto err_unrtty;
1863         }
1864
1865         mod_timer(&tx, jiffies + 1);
1866
1867         return 0;
1868 err_unrtty:
1869         tty_unregister_driver(isicom_normal);
1870 err_puttty:
1871         put_tty_driver(isicom_normal);
1872 error:
1873         return retval;
1874 }
1875
1876 static void __exit isicom_exit(void)
1877 {
1878         del_timer_sync(&tx);
1879
1880         pci_unregister_driver(&isicom_driver);
1881         tty_unregister_driver(isicom_normal);
1882         put_tty_driver(isicom_normal);
1883 }
1884
1885 module_init(isicom_init);
1886 module_exit(isicom_exit);
1887
1888 MODULE_AUTHOR("MultiTech");
1889 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
1890 MODULE_LICENSE("GPL");