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