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