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