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