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