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