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