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