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