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