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