tty_port: Add a port level carrier detect operation
[safe/jmp/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 isicom_carrier_raised(struct tty_port *port)
834 {
835         struct isi_port *ip = container_of(port, struct isi_port, port);
836         return (ip->status & ISI_DCD)?1 : 0;
837 }
838
839 static int block_til_ready(struct tty_struct *tty, struct file *filp,
840         struct isi_port *ip)
841 {
842         struct isi_board *card = ip->card;
843         struct tty_port *port = &ip->port;
844         int do_clocal = 0, retval;
845         unsigned long flags;
846         DECLARE_WAITQUEUE(wait, current);
847         int cd;
848
849         /* block if port is in the process of being closed */
850
851         if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
852                 pr_dbg("block_til_ready: close in progress.\n");
853                 interruptible_sleep_on(&port->close_wait);
854                 if (port->flags & ASYNC_HUP_NOTIFY)
855                         return -EAGAIN;
856                 else
857                         return -ERESTARTSYS;
858         }
859
860         /* if non-blocking mode is set ... */
861
862         if ((filp->f_flags & O_NONBLOCK) ||
863                         (tty->flags & (1 << TTY_IO_ERROR))) {
864                 pr_dbg("block_til_ready: non-block mode.\n");
865                 port->flags |= ASYNC_NORMAL_ACTIVE;
866                 return 0;
867         }
868
869         if (C_CLOCAL(tty))
870                 do_clocal = 1;
871
872         /* block waiting for DCD to be asserted, and while
873                                                 callout dev is busy */
874         retval = 0;
875         add_wait_queue(&port->open_wait, &wait);
876
877         spin_lock_irqsave(&card->card_lock, flags);
878         if (!tty_hung_up_p(filp))
879                 port->count--;
880         port->blocked_open++;
881         spin_unlock_irqrestore(&card->card_lock, flags);
882
883         while (1) {
884                 raise_dtr_rts(ip);
885
886                 set_current_state(TASK_INTERRUPTIBLE);
887                 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
888                         if (port->flags & ASYNC_HUP_NOTIFY)
889                                 retval = -EAGAIN;
890                         else
891                                 retval = -ERESTARTSYS;
892                         break;
893                 }
894                 cd = tty_port_carrier_raised(port);
895                 if (!(port->flags & ASYNC_CLOSING) &&
896                                 (do_clocal || cd))
897                         break;
898                 if (signal_pending(current)) {
899                         retval = -ERESTARTSYS;
900                         break;
901                 }
902                 schedule();
903         }
904         set_current_state(TASK_RUNNING);
905         remove_wait_queue(&port->open_wait, &wait);
906         spin_lock_irqsave(&card->card_lock, flags);
907         if (!tty_hung_up_p(filp))
908                 port->count++;
909         port->blocked_open--;
910         spin_unlock_irqrestore(&card->card_lock, flags);
911         if (retval)
912                 return retval;
913         port->flags |= ASYNC_NORMAL_ACTIVE;
914         return 0;
915 }
916
917 static int isicom_open(struct tty_struct *tty, struct file *filp)
918 {
919         struct isi_port *port;
920         struct isi_board *card;
921         unsigned int board;
922         int error, line;
923
924         line = tty->index;
925         if (line < 0 || line > PORT_COUNT-1)
926                 return -ENODEV;
927         board = BOARD(line);
928         card = &isi_card[board];
929
930         if (!(card->status & FIRMWARE_LOADED))
931                 return -ENODEV;
932
933         /*  open on a port greater than the port count for the card !!! */
934         if (line > ((board * 16) + card->port_count - 1))
935                 return -ENODEV;
936
937         port = &isi_ports[line];
938         if (isicom_paranoia_check(port, tty->name, "isicom_open"))
939                 return -ENODEV;
940
941         isicom_setup_board(card);
942
943         port->port.count++;
944         tty->driver_data = port;
945         tty_port_tty_set(&port->port, tty);
946         error = isicom_setup_port(tty);
947         if (error == 0)
948                 error = block_til_ready(tty, filp, port);
949         return error;
950 }
951
952 /* close et all */
953
954 static inline void isicom_shutdown_board(struct isi_board *bp)
955 {
956         if (bp->status & BOARD_ACTIVE)
957                 bp->status &= ~BOARD_ACTIVE;
958 }
959
960 /* card->lock HAS to be held */
961 static void isicom_shutdown_port(struct isi_port *port)
962 {
963         struct isi_board *card = port->card;
964         struct tty_struct *tty;
965
966         tty = tty_port_tty_get(&port->port);
967
968         if (!(port->port.flags & ASYNC_INITIALIZED)) {
969                 tty_kref_put(tty);
970                 return;
971         }
972
973         tty_port_free_xmit_buf(&port->port);
974         port->port.flags &= ~ASYNC_INITIALIZED;
975         /* 3rd October 2000 : Vinayak P Risbud */
976         tty_port_tty_set(&port->port, NULL);
977
978         /*Fix done by Anil .S on 30-04-2001
979         remote login through isi port has dtr toggle problem
980         due to which the carrier drops before the password prompt
981         appears on the remote end. Now we drop the dtr only if the
982         HUPCL(Hangup on close) flag is set for the tty*/
983
984         if (C_HUPCL(tty))
985                 /* drop dtr on this port */
986                 drop_dtr(port);
987
988         /* any other port uninits  */
989         if (tty)
990                 set_bit(TTY_IO_ERROR, &tty->flags);
991
992         if (--card->count < 0) {
993                 pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n",
994                         card->base, card->count);
995                 card->count = 0;
996         }
997
998         /* last port was closed, shutdown that boad too */
999         if (C_HUPCL(tty)) {
1000                 if (!card->count)
1001                         isicom_shutdown_board(card);
1002         }
1003 }
1004
1005 static void isicom_flush_buffer(struct tty_struct *tty)
1006 {
1007         struct isi_port *port = tty->driver_data;
1008         struct isi_board *card = port->card;
1009         unsigned long flags;
1010
1011         if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
1012                 return;
1013
1014         spin_lock_irqsave(&card->card_lock, flags);
1015         port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1016         spin_unlock_irqrestore(&card->card_lock, flags);
1017
1018         tty_wakeup(tty);
1019 }
1020
1021 static void isicom_close(struct tty_struct *tty, struct file *filp)
1022 {
1023         struct isi_port *port = tty->driver_data;
1024         struct isi_board *card;
1025         unsigned long flags;
1026
1027         if (!port)
1028                 return;
1029         card = port->card;
1030         if (isicom_paranoia_check(port, tty->name, "isicom_close"))
1031                 return;
1032
1033         pr_dbg("Close start!!!.\n");
1034
1035         spin_lock_irqsave(&card->card_lock, flags);
1036         if (tty_hung_up_p(filp)) {
1037                 spin_unlock_irqrestore(&card->card_lock, flags);
1038                 return;
1039         }
1040
1041         if (tty->count == 1 && port->port.count != 1) {
1042                 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1043                         "count tty->count = 1 port count = %d.\n",
1044                         card->base, port->port.count);
1045                 port->port.count = 1;
1046         }
1047         if (--port->port.count < 0) {
1048                 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1049                         "count for channel%d = %d", card->base, port->channel,
1050                         port->port.count);
1051                 port->port.count = 0;
1052         }
1053
1054         if (port->port.count) {
1055                 spin_unlock_irqrestore(&card->card_lock, flags);
1056                 return;
1057         }
1058         port->port.flags |= ASYNC_CLOSING;
1059         tty->closing = 1;
1060         spin_unlock_irqrestore(&card->card_lock, flags);
1061
1062         if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1063                 tty_wait_until_sent(tty, port->port.closing_wait);
1064         /* indicate to the card that no more data can be received
1065            on this port */
1066         spin_lock_irqsave(&card->card_lock, flags);
1067         if (port->port.flags & ASYNC_INITIALIZED) {
1068                 card->port_status &= ~(1 << port->channel);
1069                 outw(card->port_status, card->base + 0x02);
1070         }
1071         isicom_shutdown_port(port);
1072         spin_unlock_irqrestore(&card->card_lock, flags);
1073
1074         isicom_flush_buffer(tty);
1075         tty_ldisc_flush(tty);
1076
1077         spin_lock_irqsave(&card->card_lock, flags);
1078         tty->closing = 0;
1079
1080         if (port->port.blocked_open) {
1081                 spin_unlock_irqrestore(&card->card_lock, flags);
1082                 if (port->port.close_delay) {
1083                         pr_dbg("scheduling until time out.\n");
1084                         msleep_interruptible(
1085                                 jiffies_to_msecs(port->port.close_delay));
1086                 }
1087                 spin_lock_irqsave(&card->card_lock, flags);
1088                 wake_up_interruptible(&port->port.open_wait);
1089         }
1090         port->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1091         wake_up_interruptible(&port->port.close_wait);
1092         spin_unlock_irqrestore(&card->card_lock, flags);
1093 }
1094
1095 /* write et all */
1096 static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
1097         int count)
1098 {
1099         struct isi_port *port = tty->driver_data;
1100         struct isi_board *card = port->card;
1101         unsigned long flags;
1102         int cnt, total = 0;
1103
1104         if (isicom_paranoia_check(port, tty->name, "isicom_write"))
1105                 return 0;
1106
1107         spin_lock_irqsave(&card->card_lock, flags);
1108
1109         while (1) {
1110                 cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
1111                                 - 1, SERIAL_XMIT_SIZE - port->xmit_head));
1112                 if (cnt <= 0)
1113                         break;
1114
1115                 memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt);
1116                 port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
1117                         - 1);
1118                 port->xmit_cnt += cnt;
1119                 buf += cnt;
1120                 count -= cnt;
1121                 total += cnt;
1122         }
1123         if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped)
1124                 port->status |= ISI_TXOK;
1125         spin_unlock_irqrestore(&card->card_lock, flags);
1126         return total;
1127 }
1128
1129 /* put_char et all */
1130 static int isicom_put_char(struct tty_struct *tty, unsigned char ch)
1131 {
1132         struct isi_port *port = tty->driver_data;
1133         struct isi_board *card = port->card;
1134         unsigned long flags;
1135
1136         if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
1137                 return 0;
1138
1139         spin_lock_irqsave(&card->card_lock, flags);
1140         if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
1141                 spin_unlock_irqrestore(&card->card_lock, flags);
1142                 return 0;
1143         }
1144
1145         port->port.xmit_buf[port->xmit_head++] = ch;
1146         port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
1147         port->xmit_cnt++;
1148         spin_unlock_irqrestore(&card->card_lock, flags);
1149         return 1;
1150 }
1151
1152 /* flush_chars et all */
1153 static void isicom_flush_chars(struct tty_struct *tty)
1154 {
1155         struct isi_port *port = tty->driver_data;
1156
1157         if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars"))
1158                 return;
1159
1160         if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1161                         !port->port.xmit_buf)
1162                 return;
1163
1164         /* this tells the transmitter to consider this port for
1165            data output to the card ... that's the best we can do. */
1166         port->status |= ISI_TXOK;
1167 }
1168
1169 /* write_room et all */
1170 static int isicom_write_room(struct tty_struct *tty)
1171 {
1172         struct isi_port *port = tty->driver_data;
1173         int free;
1174
1175         if (isicom_paranoia_check(port, tty->name, "isicom_write_room"))
1176                 return 0;
1177
1178         free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1179         if (free < 0)
1180                 free = 0;
1181         return free;
1182 }
1183
1184 /* chars_in_buffer et all */
1185 static int isicom_chars_in_buffer(struct tty_struct *tty)
1186 {
1187         struct isi_port *port = tty->driver_data;
1188         if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer"))
1189                 return 0;
1190         return port->xmit_cnt;
1191 }
1192
1193 /* ioctl et all */
1194 static int isicom_send_break(struct tty_struct *tty, int length)
1195 {
1196         struct isi_port *port = tty->driver_data;
1197         struct isi_board *card = port->card;
1198         unsigned long base = card->base;
1199
1200         if (length == -1)
1201                 return -EOPNOTSUPP;
1202
1203         if (!lock_card(card))
1204                 return -EINVAL;
1205
1206         outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
1207         outw((length & 0xff) << 8 | 0x00, base);
1208         outw((length & 0xff00), base);
1209         InterruptTheCard(base);
1210
1211         unlock_card(card);
1212         return 0;
1213 }
1214
1215 static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
1216 {
1217         struct isi_port *port = tty->driver_data;
1218         /* just send the port status */
1219         u16 status = port->status;
1220
1221         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1222                 return -ENODEV;
1223
1224         return  ((status & ISI_RTS) ? TIOCM_RTS : 0) |
1225                 ((status & ISI_DTR) ? TIOCM_DTR : 0) |
1226                 ((status & ISI_DCD) ? TIOCM_CAR : 0) |
1227                 ((status & ISI_DSR) ? TIOCM_DSR : 0) |
1228                 ((status & ISI_CTS) ? TIOCM_CTS : 0) |
1229                 ((status & ISI_RI ) ? TIOCM_RI  : 0);
1230 }
1231
1232 static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
1233         unsigned int set, unsigned int clear)
1234 {
1235         struct isi_port *port = tty->driver_data;
1236         unsigned long flags;
1237
1238         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1239                 return -ENODEV;
1240
1241         spin_lock_irqsave(&port->card->card_lock, flags);
1242         if (set & TIOCM_RTS)
1243                 raise_rts(port);
1244         if (set & TIOCM_DTR)
1245                 raise_dtr(port);
1246
1247         if (clear & TIOCM_RTS)
1248                 drop_rts(port);
1249         if (clear & TIOCM_DTR)
1250                 drop_dtr(port);
1251         spin_unlock_irqrestore(&port->card->card_lock, flags);
1252
1253         return 0;
1254 }
1255
1256 static int isicom_set_serial_info(struct tty_struct *tty,
1257                                         struct serial_struct __user *info)
1258 {
1259         struct isi_port *port = tty->driver_data;
1260         struct serial_struct newinfo;
1261         int reconfig_port;
1262
1263         if (copy_from_user(&newinfo, info, sizeof(newinfo)))
1264                 return -EFAULT;
1265
1266         lock_kernel();
1267
1268         reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) !=
1269                 (newinfo.flags & ASYNC_SPD_MASK));
1270
1271         if (!capable(CAP_SYS_ADMIN)) {
1272                 if ((newinfo.close_delay != port->port.close_delay) ||
1273                                 (newinfo.closing_wait != port->port.closing_wait) ||
1274                                 ((newinfo.flags & ~ASYNC_USR_MASK) !=
1275                                 (port->port.flags & ~ASYNC_USR_MASK))) {
1276                         unlock_kernel();
1277                         return -EPERM;
1278                 }
1279                 port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1280                                 (newinfo.flags & ASYNC_USR_MASK));
1281         } else {
1282                 port->port.close_delay = newinfo.close_delay;
1283                 port->port.closing_wait = newinfo.closing_wait;
1284                 port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1285                                 (newinfo.flags & ASYNC_FLAGS));
1286         }
1287         if (reconfig_port) {
1288                 unsigned long flags;
1289                 spin_lock_irqsave(&port->card->card_lock, flags);
1290                 isicom_config_port(tty);
1291                 spin_unlock_irqrestore(&port->card->card_lock, flags);
1292         }
1293         unlock_kernel();
1294         return 0;
1295 }
1296
1297 static int isicom_get_serial_info(struct isi_port *port,
1298         struct serial_struct __user *info)
1299 {
1300         struct serial_struct out_info;
1301
1302         lock_kernel();
1303         memset(&out_info, 0, sizeof(out_info));
1304 /*      out_info.type = ? */
1305         out_info.line = port - isi_ports;
1306         out_info.port = port->card->base;
1307         out_info.irq = port->card->irq;
1308         out_info.flags = port->port.flags;
1309 /*      out_info.baud_base = ? */
1310         out_info.close_delay = port->port.close_delay;
1311         out_info.closing_wait = port->port.closing_wait;
1312         unlock_kernel();
1313         if (copy_to_user(info, &out_info, sizeof(out_info)))
1314                 return -EFAULT;
1315         return 0;
1316 }
1317
1318 static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1319         unsigned int cmd, unsigned long arg)
1320 {
1321         struct isi_port *port = tty->driver_data;
1322         void __user *argp = (void __user *)arg;
1323
1324         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1325                 return -ENODEV;
1326
1327         switch (cmd) {
1328         case TIOCGSERIAL:
1329                 return isicom_get_serial_info(port, argp);
1330
1331         case TIOCSSERIAL:
1332                 return isicom_set_serial_info(tty, argp);
1333
1334         default:
1335                 return -ENOIOCTLCMD;
1336         }
1337         return 0;
1338 }
1339
1340 /* set_termios et all */
1341 static void isicom_set_termios(struct tty_struct *tty,
1342         struct ktermios *old_termios)
1343 {
1344         struct isi_port *port = tty->driver_data;
1345         unsigned long flags;
1346
1347         if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
1348                 return;
1349
1350         if (tty->termios->c_cflag == old_termios->c_cflag &&
1351                         tty->termios->c_iflag == old_termios->c_iflag)
1352                 return;
1353
1354         spin_lock_irqsave(&port->card->card_lock, flags);
1355         isicom_config_port(tty);
1356         spin_unlock_irqrestore(&port->card->card_lock, flags);
1357
1358         if ((old_termios->c_cflag & CRTSCTS) &&
1359                         !(tty->termios->c_cflag & CRTSCTS)) {
1360                 tty->hw_stopped = 0;
1361                 isicom_start(tty);
1362         }
1363 }
1364
1365 /* throttle et all */
1366 static void isicom_throttle(struct tty_struct *tty)
1367 {
1368         struct isi_port *port = tty->driver_data;
1369         struct isi_board *card = port->card;
1370
1371         if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
1372                 return;
1373
1374         /* tell the card that this port cannot handle any more data for now */
1375         card->port_status &= ~(1 << port->channel);
1376         outw(card->port_status, card->base + 0x02);
1377 }
1378
1379 /* unthrottle et all */
1380 static void isicom_unthrottle(struct tty_struct *tty)
1381 {
1382         struct isi_port *port = tty->driver_data;
1383         struct isi_board *card = port->card;
1384
1385         if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
1386                 return;
1387
1388         /* tell the card that this port is ready to accept more data */
1389         card->port_status |= (1 << port->channel);
1390         outw(card->port_status, card->base + 0x02);
1391 }
1392
1393 /* stop et all */
1394 static void isicom_stop(struct tty_struct *tty)
1395 {
1396         struct isi_port *port = tty->driver_data;
1397
1398         if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
1399                 return;
1400
1401         /* this tells the transmitter not to consider this port for
1402            data output to the card. */
1403         port->status &= ~ISI_TXOK;
1404 }
1405
1406 /* start et all */
1407 static void isicom_start(struct tty_struct *tty)
1408 {
1409         struct isi_port *port = tty->driver_data;
1410
1411         if (isicom_paranoia_check(port, tty->name, "isicom_start"))
1412                 return;
1413
1414         /* this tells the transmitter to consider this port for
1415            data output to the card. */
1416         port->status |= ISI_TXOK;
1417 }
1418
1419 static void isicom_hangup(struct tty_struct *tty)
1420 {
1421         struct isi_port *port = tty->driver_data;
1422         unsigned long flags;
1423
1424         if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
1425                 return;
1426
1427         spin_lock_irqsave(&port->card->card_lock, flags);
1428         isicom_shutdown_port(port);
1429         spin_unlock_irqrestore(&port->card->card_lock, flags);
1430
1431         port->port.count = 0;
1432         port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1433         tty_port_tty_set(&port->port, NULL);
1434         wake_up_interruptible(&port->port.open_wait);
1435 }
1436
1437
1438 /*
1439  * Driver init and deinit functions
1440  */
1441
1442 static const struct tty_operations isicom_ops = {
1443         .open                   = isicom_open,
1444         .close                  = isicom_close,
1445         .write                  = isicom_write,
1446         .put_char               = isicom_put_char,
1447         .flush_chars            = isicom_flush_chars,
1448         .write_room             = isicom_write_room,
1449         .chars_in_buffer        = isicom_chars_in_buffer,
1450         .ioctl                  = isicom_ioctl,
1451         .set_termios            = isicom_set_termios,
1452         .throttle               = isicom_throttle,
1453         .unthrottle             = isicom_unthrottle,
1454         .stop                   = isicom_stop,
1455         .start                  = isicom_start,
1456         .hangup                 = isicom_hangup,
1457         .flush_buffer           = isicom_flush_buffer,
1458         .tiocmget               = isicom_tiocmget,
1459         .tiocmset               = isicom_tiocmset,
1460         .break_ctl              = isicom_send_break,
1461 };
1462
1463 static const struct tty_port_operations isicom_port_ops = {
1464         .carrier_raised         = isicom_carrier_raised,
1465 };
1466
1467 static int __devinit reset_card(struct pci_dev *pdev,
1468         const unsigned int card, unsigned int *signature)
1469 {
1470         struct isi_board *board = pci_get_drvdata(pdev);
1471         unsigned long base = board->base;
1472         unsigned int sig, portcount = 0;
1473         int retval = 0;
1474
1475         dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
1476                 base);
1477
1478         inw(base + 0x8);
1479
1480         msleep(10);
1481
1482         outw(0, base + 0x8); /* Reset */
1483
1484         msleep(1000);
1485
1486         sig = inw(base + 0x4) & 0xff;
1487
1488         if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd &&
1489                         sig != 0xee) {
1490                 dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible "
1491                         "bad I/O Port Address 0x%lx).\n", card + 1, base);
1492                 dev_dbg(&pdev->dev, "Sig=0x%x\n", sig);
1493                 retval = -EIO;
1494                 goto end;
1495         }
1496
1497         msleep(10);
1498
1499         portcount = inw(base + 0x2);
1500         if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 &&
1501                                 portcount != 8 && portcount != 16)) {
1502                 dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
1503                         card + 1);
1504                 retval = -EIO;
1505                 goto end;
1506         }
1507
1508         switch (sig) {
1509         case 0xa5:
1510         case 0xbb:
1511         case 0xdd:
1512                 board->port_count = (portcount == 4) ? 4 : 8;
1513                 board->shift_count = 12;
1514                 break;
1515         case 0xcc:
1516         case 0xee:
1517                 board->port_count = 16;
1518                 board->shift_count = 11;
1519                 break;
1520         }
1521         dev_info(&pdev->dev, "-Done\n");
1522         *signature = sig;
1523
1524 end:
1525         return retval;
1526 }
1527
1528 static int __devinit load_firmware(struct pci_dev *pdev,
1529         const unsigned int index, const unsigned int signature)
1530 {
1531         struct isi_board *board = pci_get_drvdata(pdev);
1532         const struct firmware *fw;
1533         unsigned long base = board->base;
1534         unsigned int a;
1535         u16 word_count, status;
1536         int retval = -EIO;
1537         char *name;
1538         u8 *data;
1539
1540         struct stframe {
1541                 u16     addr;
1542                 u16     count;
1543                 u8      data[0];
1544         } *frame;
1545
1546         switch (signature) {
1547         case 0xa5:
1548                 name = "isi608.bin";
1549                 break;
1550         case 0xbb:
1551                 name = "isi608em.bin";
1552                 break;
1553         case 0xcc:
1554                 name = "isi616em.bin";
1555                 break;
1556         case 0xdd:
1557                 name = "isi4608.bin";
1558                 break;
1559         case 0xee:
1560                 name = "isi4616.bin";
1561                 break;
1562         default:
1563                 dev_err(&pdev->dev, "Unknown signature.\n");
1564                 goto end;
1565         }
1566
1567         retval = request_firmware(&fw, name, &pdev->dev);
1568         if (retval)
1569                 goto end;
1570
1571         retval = -EIO;
1572
1573         for (frame = (struct stframe *)fw->data;
1574                         frame < (struct stframe *)(fw->data + fw->size);
1575                         frame = (struct stframe *)((u8 *)(frame + 1) +
1576                                 frame->count)) {
1577                 if (WaitTillCardIsFree(base))
1578                         goto errrelfw;
1579
1580                 outw(0xf0, base);       /* start upload sequence */
1581                 outw(0x00, base);
1582                 outw(frame->addr, base); /* lsb of address */
1583
1584                 word_count = frame->count / 2 + frame->count % 2;
1585                 outw(word_count, base);
1586                 InterruptTheCard(base);
1587
1588                 udelay(100); /* 0x2f */
1589
1590                 if (WaitTillCardIsFree(base))
1591                         goto errrelfw;
1592
1593                 status = inw(base + 0x4);
1594                 if (status != 0) {
1595                         dev_warn(&pdev->dev, "Card%d rejected load header:\n"
1596                                 KERN_WARNING "Address:0x%x\n"
1597                                 KERN_WARNING "Count:0x%x\n"
1598                                 KERN_WARNING "Status:0x%x\n",
1599                                 index + 1, frame->addr, frame->count, status);
1600                         goto errrelfw;
1601                 }
1602                 outsw(base, frame->data, word_count);
1603
1604                 InterruptTheCard(base);
1605
1606                 udelay(50); /* 0x0f */
1607
1608                 if (WaitTillCardIsFree(base))
1609                         goto errrelfw;
1610
1611                 status = inw(base + 0x4);
1612                 if (status != 0) {
1613                         dev_err(&pdev->dev, "Card%d got out of sync.Card "
1614                                 "Status:0x%x\n", index + 1, status);
1615                         goto errrelfw;
1616                 }
1617         }
1618
1619 /* XXX: should we test it by reading it back and comparing with original like
1620  * in load firmware package? */
1621         for (frame = (struct stframe *)fw->data;
1622                         frame < (struct stframe *)(fw->data + fw->size);
1623                         frame = (struct stframe *)((u8 *)(frame + 1) +
1624                                 frame->count)) {
1625                 if (WaitTillCardIsFree(base))
1626                         goto errrelfw;
1627
1628                 outw(0xf1, base); /* start download sequence */
1629                 outw(0x00, base);
1630                 outw(frame->addr, base); /* lsb of address */
1631
1632                 word_count = (frame->count >> 1) + frame->count % 2;
1633                 outw(word_count + 1, base);
1634                 InterruptTheCard(base);
1635
1636                 udelay(50); /* 0xf */
1637
1638                 if (WaitTillCardIsFree(base))
1639                         goto errrelfw;
1640
1641                 status = inw(base + 0x4);
1642                 if (status != 0) {
1643                         dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
1644                                 KERN_WARNING "Address:0x%x\n"
1645                                 KERN_WARNING "Count:0x%x\n"
1646                                 KERN_WARNING "Status: 0x%x\n",
1647                                 index + 1, frame->addr, frame->count, status);
1648                         goto errrelfw;
1649                 }
1650
1651                 data = kmalloc(word_count * 2, GFP_KERNEL);
1652                 if (data == NULL) {
1653                         dev_err(&pdev->dev, "Card%d, firmware upload "
1654                                 "failed, not enough memory\n", index + 1);
1655                         goto errrelfw;
1656                 }
1657                 inw(base);
1658                 insw(base, data, word_count);
1659                 InterruptTheCard(base);
1660
1661                 for (a = 0; a < frame->count; a++)
1662                         if (data[a] != frame->data[a]) {
1663                                 kfree(data);
1664                                 dev_err(&pdev->dev, "Card%d, firmware upload "
1665                                         "failed\n", index + 1);
1666                                 goto errrelfw;
1667                         }
1668                 kfree(data);
1669
1670                 udelay(50); /* 0xf */
1671
1672                 if (WaitTillCardIsFree(base))
1673                         goto errrelfw;
1674
1675                 status = inw(base + 0x4);
1676                 if (status != 0) {
1677                         dev_err(&pdev->dev, "Card%d verify got out of sync. "
1678                                 "Card Status:0x%x\n", index + 1, status);
1679                         goto errrelfw;
1680                 }
1681         }
1682
1683         /* xfer ctrl */
1684         if (WaitTillCardIsFree(base))
1685                 goto errrelfw;
1686
1687         outw(0xf2, base);
1688         outw(0x800, base);
1689         outw(0x0, base);
1690         outw(0x0, base);
1691         InterruptTheCard(base);
1692         outw(0x0, base + 0x4); /* for ISI4608 cards */
1693
1694         board->status |= FIRMWARE_LOADED;
1695         retval = 0;
1696
1697 errrelfw:
1698         release_firmware(fw);
1699 end:
1700         return retval;
1701 }
1702
1703 /*
1704  *      Insmod can set static symbols so keep these static
1705  */
1706 static unsigned int card_count;
1707
1708 static int __devinit isicom_probe(struct pci_dev *pdev,
1709         const struct pci_device_id *ent)
1710 {
1711         unsigned int signature, index;
1712         int retval = -EPERM;
1713         struct isi_board *board = NULL;
1714
1715         if (card_count >= BOARD_COUNT)
1716                 goto err;
1717
1718         retval = pci_enable_device(pdev);
1719         if (retval) {
1720                 dev_err(&pdev->dev, "failed to enable\n");
1721                 goto err;
1722         }
1723
1724         dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
1725
1726         /* allot the first empty slot in the array */
1727         for (index = 0; index < BOARD_COUNT; index++)
1728                 if (isi_card[index].base == 0) {
1729                         board = &isi_card[index];
1730                         break;
1731                 }
1732
1733         board->index = index;
1734         board->base = pci_resource_start(pdev, 3);
1735         board->irq = pdev->irq;
1736         card_count++;
1737
1738         pci_set_drvdata(pdev, board);
1739
1740         retval = pci_request_region(pdev, 3, ISICOM_NAME);
1741         if (retval) {
1742                 dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
1743                         "will be disabled.\n", board->base, board->base + 15,
1744                         index + 1);
1745                 retval = -EBUSY;
1746                 goto errdec;
1747         }
1748
1749         retval = request_irq(board->irq, isicom_interrupt,
1750                         IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
1751         if (retval < 0) {
1752                 dev_err(&pdev->dev, "Could not install handler at Irq %d. "
1753                         "Card%d will be disabled.\n", board->irq, index + 1);
1754                 goto errunrr;
1755         }
1756
1757         retval = reset_card(pdev, index, &signature);
1758         if (retval < 0)
1759                 goto errunri;
1760
1761         retval = load_firmware(pdev, index, signature);
1762         if (retval < 0)
1763                 goto errunri;
1764
1765         for (index = 0; index < board->port_count; index++)
1766                 tty_register_device(isicom_normal, board->index * 16 + index,
1767                                 &pdev->dev);
1768
1769         return 0;
1770
1771 errunri:
1772         free_irq(board->irq, board);
1773 errunrr:
1774         pci_release_region(pdev, 3);
1775 errdec:
1776         board->base = 0;
1777         card_count--;
1778         pci_disable_device(pdev);
1779 err:
1780         return retval;
1781 }
1782
1783 static void __devexit isicom_remove(struct pci_dev *pdev)
1784 {
1785         struct isi_board *board = pci_get_drvdata(pdev);
1786         unsigned int i;
1787
1788         for (i = 0; i < board->port_count; i++)
1789                 tty_unregister_device(isicom_normal, board->index * 16 + i);
1790
1791         free_irq(board->irq, board);
1792         pci_release_region(pdev, 3);
1793         board->base = 0;
1794         card_count--;
1795         pci_disable_device(pdev);
1796 }
1797
1798 static int __init isicom_init(void)
1799 {
1800         int retval, idx, channel;
1801         struct isi_port *port;
1802
1803         for (idx = 0; idx < BOARD_COUNT; idx++) {
1804                 port = &isi_ports[idx * 16];
1805                 isi_card[idx].ports = port;
1806                 spin_lock_init(&isi_card[idx].card_lock);
1807                 for (channel = 0; channel < 16; channel++, port++) {
1808                         tty_port_init(&port->port);
1809                         port->port.ops = &isicom_port_ops;
1810                         port->magic = ISICOM_MAGIC;
1811                         port->card = &isi_card[idx];
1812                         port->channel = channel;
1813                         port->port.close_delay = 50 * HZ/100;
1814                         port->port.closing_wait = 3000 * HZ/100;
1815                         port->status = 0;
1816                         /*  . . .  */
1817                 }
1818                 isi_card[idx].base = 0;
1819                 isi_card[idx].irq = 0;
1820         }
1821
1822         /* tty driver structure initialization */
1823         isicom_normal = alloc_tty_driver(PORT_COUNT);
1824         if (!isicom_normal) {
1825                 retval = -ENOMEM;
1826                 goto error;
1827         }
1828
1829         isicom_normal->owner                    = THIS_MODULE;
1830         isicom_normal->name                     = "ttyM";
1831         isicom_normal->major                    = ISICOM_NMAJOR;
1832         isicom_normal->minor_start              = 0;
1833         isicom_normal->type                     = TTY_DRIVER_TYPE_SERIAL;
1834         isicom_normal->subtype                  = SERIAL_TYPE_NORMAL;
1835         isicom_normal->init_termios             = tty_std_termios;
1836         isicom_normal->init_termios.c_cflag     = B9600 | CS8 | CREAD | HUPCL |
1837                 CLOCAL;
1838         isicom_normal->flags                    = TTY_DRIVER_REAL_RAW |
1839                 TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK;
1840         tty_set_operations(isicom_normal, &isicom_ops);
1841
1842         retval = tty_register_driver(isicom_normal);
1843         if (retval) {
1844                 pr_dbg("Couldn't register the dialin driver\n");
1845                 goto err_puttty;
1846         }
1847
1848         retval = pci_register_driver(&isicom_driver);
1849         if (retval < 0) {
1850                 printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
1851                 goto err_unrtty;
1852         }
1853
1854         mod_timer(&tx, jiffies + 1);
1855
1856         return 0;
1857 err_unrtty:
1858         tty_unregister_driver(isicom_normal);
1859 err_puttty:
1860         put_tty_driver(isicom_normal);
1861 error:
1862         return retval;
1863 }
1864
1865 static void __exit isicom_exit(void)
1866 {
1867         del_timer_sync(&tx);
1868
1869         pci_unregister_driver(&isicom_driver);
1870         tty_unregister_driver(isicom_normal);
1871         put_tty_driver(isicom_normal);
1872 }
1873
1874 module_init(isicom_init);
1875 module_exit(isicom_exit);
1876
1877 MODULE_AUTHOR("MultiTech");
1878 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
1879 MODULE_LICENSE("GPL");