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