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