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