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