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