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