[PATCH] const struct tty_operations
[linux-3.10.git] / drivers / char / isicom.c
1 /*
2  *      This program is free software; you can redistribute it and/or
3  *      modify it under the terms of the GNU General Public License
4  *      as published by the Free Software Foundation; either version
5  *      2 of the License, or (at your option) any later version.
6  *
7  *      Original driver code supplied by Multi-Tech
8  *
9  *      Changes
10  *      1/9/98  alan@redhat.com         Merge to 2.0.x kernel tree
11  *                                      Obtain and use official major/minors
12  *                                      Loader switched to a misc device
13  *                                      (fixed range check bug as a side effect)
14  *                                      Printk clean up
15  *      9/12/98 alan@redhat.com         Rough port to 2.1.x
16  *
17  *      10/6/99 sameer                  Merged the ISA and PCI drivers to
18  *                                      a new unified driver.
19  *
20  *      3/9/99  sameer                  Added support for ISI4616 cards.
21  *
22  *      16/9/99 sameer                  We do not force RTS low anymore.
23  *                                      This is to prevent the firmware
24  *                                      from getting confused.
25  *
26  *      26/10/99 sameer                 Cosmetic changes:The driver now
27  *                                      dumps the Port Count information
28  *                                      along with I/O address and IRQ.
29  *
30  *      13/12/99 sameer                 Fixed the problem with IRQ sharing.
31  *
32  *      10/5/00  sameer                 Fixed isicom_shutdown_board()
33  *                                      to not lower DTR on all the ports
34  *                                      when the last port on the card is
35  *                                      closed.
36  *
37  *      10/5/00  sameer                 Signal mask setup command added
38  *                                      to  isicom_setup_port and
39  *                                      isicom_shutdown_port.
40  *
41  *      24/5/00  sameer                 The driver is now SMP aware.
42  *
43  *
44  *      27/11/00 Vinayak P Risbud       Fixed the Driver Crash Problem
45  *
46  *
47  *      03/01/01  anil .s               Added support for resetting the
48  *                                      internal modems on ISI cards.
49  *
50  *      08/02/01  anil .s               Upgraded the driver for kernel
51  *                                      2.4.x
52  *
53  *      11/04/01  Kevin                 Fixed firmware load problem with
54  *                                      ISIHP-4X card
55  *
56  *      30/04/01  anil .s               Fixed the remote login through
57  *                                      ISI port problem. Now the link
58  *                                      does not go down before password
59  *                                      prompt.
60  *
61  *      03/05/01  anil .s               Fixed the problem with IRQ sharing
62  *                                      among ISI-PCI cards.
63  *
64  *      03/05/01  anil .s               Added support to display the version
65  *                                      info during insmod as well as module
66  *                                      listing by lsmod.
67  *
68  *      10/05/01  anil .s               Done the modifications to the source
69  *                                      file and Install script so that the
70  *                                      same installation can be used for
71  *                                      2.2.x and 2.4.x kernel.
72  *
73  *      06/06/01  anil .s               Now we drop both dtr and rts during
74  *                                      shutdown_port as well as raise them
75  *                                      during isicom_config_port.
76  *
77  *      09/06/01 acme@conectiva.com.br  use capable, not suser, do
78  *                                      restore_flags on failure in
79  *                                      isicom_send_break, verify put_user
80  *                                      result
81  *
82  *      11/02/03  ranjeeth              Added support for 230 Kbps and 460 Kbps
83  *                                      Baud index extended to 21
84  *
85  *      20/03/03  ranjeeth              Made to work for Linux Advanced server.
86  *                                      Taken care of license warning.
87  *
88  *      10/12/03  Ravindra              Made to work for Fedora Core 1 of
89  *                                      Red Hat Distribution
90  *
91  *      06/01/05  Alan Cox              Merged the ISI and base kernel strands
92  *                                      into a single 2.6 driver
93  *
94  *      ***********************************************************
95  *
96  *      To use this driver you also need the support package. You
97  *      can find this in RPM format on
98  *              ftp://ftp.linux.org.uk/pub/linux/alan
99  *
100  *      You can find the original tools for this direct from Multitech
101  *              ftp://ftp.multitech.com/ISI-Cards/
102  *
103  *      Having installed the cards the module options (/etc/modprobe.conf)
104  *
105  *      options isicom   io=card1,card2,card3,card4 irq=card1,card2,card3,card4
106  *
107  *      Omit those entries for boards you don't have installed.
108  *
109  *      TODO
110  *              Merge testing
111  *              64-bit verification
112  */
113
114 #include <linux/module.h>
115 #include <linux/firmware.h>
116 #include <linux/kernel.h>
117 #include <linux/tty.h>
118 #include <linux/tty_flip.h>
119 #include <linux/termios.h>
120 #include <linux/fs.h>
121 #include <linux/sched.h>
122 #include <linux/serial.h>
123 #include <linux/mm.h>
124 #include <linux/interrupt.h>
125 #include <linux/timer.h>
126 #include <linux/delay.h>
127 #include <linux/ioport.h>
128
129 #include <asm/uaccess.h>
130 #include <asm/io.h>
131 #include <asm/system.h>
132
133 #include <linux/pci.h>
134
135 #include <linux/isicom.h>
136
137 #define InterruptTheCard(base) outw(0, (base) + 0xc)
138 #define ClearInterrupt(base) inw((base) + 0x0a)
139
140 #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, struct pt_regs *regs)
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 = port->card;
1066         unsigned long flags;
1067
1068         if (!port)
1069                 return;
1070         if (isicom_paranoia_check(port, tty->name, "isicom_close"))
1071                 return;
1072
1073         pr_dbg("Close start!!!.\n");
1074
1075         spin_lock_irqsave(&card->card_lock, flags);
1076         if (tty_hung_up_p(filp)) {
1077                 spin_unlock_irqrestore(&card->card_lock, flags);
1078                 return;
1079         }
1080
1081         if (tty->count == 1 && port->count != 1) {
1082                 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1083                         "count tty->count = 1 port count = %d.\n",
1084                         card->base, port->count);
1085                 port->count = 1;
1086         }
1087         if (--port->count < 0) {
1088                 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1089                         "count for channel%d = %d", card->base, port->channel,
1090                         port->count);
1091                 port->count = 0;
1092         }
1093
1094         if (port->count) {
1095                 spin_unlock_irqrestore(&card->card_lock, flags);
1096                 return;
1097         }
1098         port->flags |= ASYNC_CLOSING;
1099         tty->closing = 1;
1100         spin_unlock_irqrestore(&card->card_lock, flags);
1101
1102         if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1103                 tty_wait_until_sent(tty, port->closing_wait);
1104         /* indicate to the card that no more data can be received
1105            on this port */
1106         spin_lock_irqsave(&card->card_lock, flags);
1107         if (port->flags & ASYNC_INITIALIZED) {
1108                 card->port_status &= ~(1 << port->channel);
1109                 outw(card->port_status, card->base + 0x02);
1110         }
1111         isicom_shutdown_port(port);
1112         spin_unlock_irqrestore(&card->card_lock, flags);
1113
1114         if (tty->driver->flush_buffer)
1115                 tty->driver->flush_buffer(tty);
1116         tty_ldisc_flush(tty);
1117
1118         spin_lock_irqsave(&card->card_lock, flags);
1119         tty->closing = 0;
1120
1121         if (port->blocked_open) {
1122                 spin_unlock_irqrestore(&card->card_lock, flags);
1123                 if (port->close_delay) {
1124                         pr_dbg("scheduling until time out.\n");
1125                         msleep_interruptible(
1126                                 jiffies_to_msecs(port->close_delay));
1127                 }
1128                 spin_lock_irqsave(&card->card_lock, flags);
1129                 wake_up_interruptible(&port->open_wait);
1130         }
1131         port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1132         wake_up_interruptible(&port->close_wait);
1133         spin_unlock_irqrestore(&card->card_lock, flags);
1134 }
1135
1136 /* write et all */
1137 static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
1138         int count)
1139 {
1140         struct isi_port *port = tty->driver_data;
1141         struct isi_board *card = port->card;
1142         unsigned long flags;
1143         int cnt, total = 0;
1144
1145         if (isicom_paranoia_check(port, tty->name, "isicom_write"))
1146                 return 0;
1147
1148         if (!port->xmit_buf)
1149                 return 0;
1150
1151         spin_lock_irqsave(&card->card_lock, flags);
1152
1153         while(1) {
1154                 cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
1155                                 - 1, SERIAL_XMIT_SIZE - port->xmit_head));
1156                 if (cnt <= 0)
1157                         break;
1158
1159                 memcpy(port->xmit_buf + port->xmit_head, buf, cnt);
1160                 port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
1161                         - 1);
1162                 port->xmit_cnt += cnt;
1163                 buf += cnt;
1164                 count -= cnt;
1165                 total += cnt;
1166         }
1167         if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped)
1168                 port->status |= ISI_TXOK;
1169         spin_unlock_irqrestore(&card->card_lock, flags);
1170         return total;
1171 }
1172
1173 /* put_char et all */
1174 static void isicom_put_char(struct tty_struct *tty, unsigned char ch)
1175 {
1176         struct isi_port *port = tty->driver_data;
1177         struct isi_board *card = port->card;
1178         unsigned long flags;
1179
1180         if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
1181                 return;
1182
1183         if (!port->xmit_buf)
1184                 return;
1185
1186         spin_lock_irqsave(&card->card_lock, flags);
1187         if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
1188                 spin_unlock_irqrestore(&card->card_lock, flags);
1189                 return;
1190         }
1191
1192         port->xmit_buf[port->xmit_head++] = ch;
1193         port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
1194         port->xmit_cnt++;
1195         spin_unlock_irqrestore(&card->card_lock, flags);
1196 }
1197
1198 /* flush_chars et all */
1199 static void isicom_flush_chars(struct tty_struct *tty)
1200 {
1201         struct isi_port *port = tty->driver_data;
1202
1203         if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars"))
1204                 return;
1205
1206         if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1207                         !port->xmit_buf)
1208                 return;
1209
1210         /* this tells the transmitter to consider this port for
1211            data output to the card ... that's the best we can do. */
1212         port->status |= ISI_TXOK;
1213 }
1214
1215 /* write_room et all */
1216 static int isicom_write_room(struct tty_struct *tty)
1217 {
1218         struct isi_port *port = tty->driver_data;
1219         int free;
1220
1221         if (isicom_paranoia_check(port, tty->name, "isicom_write_room"))
1222                 return 0;
1223
1224         free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1225         if (free < 0)
1226                 free = 0;
1227         return free;
1228 }
1229
1230 /* chars_in_buffer et all */
1231 static int isicom_chars_in_buffer(struct tty_struct *tty)
1232 {
1233         struct isi_port *port = tty->driver_data;
1234         if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer"))
1235                 return 0;
1236         return port->xmit_cnt;
1237 }
1238
1239 /* ioctl et all */
1240 static inline void isicom_send_break(struct isi_port *port,
1241         unsigned long length)
1242 {
1243         struct isi_board *card = port->card;
1244         unsigned long base = card->base;
1245
1246         if (!lock_card(card))
1247                 return;
1248
1249         outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
1250         outw((length & 0xff) << 8 | 0x00, base);
1251         outw((length & 0xff00), base);
1252         InterruptTheCard(base);
1253
1254         unlock_card(card);
1255 }
1256
1257 static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
1258 {
1259         struct isi_port *port = tty->driver_data;
1260         /* just send the port status */
1261         u16 status = port->status;
1262
1263         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1264                 return -ENODEV;
1265
1266         return  ((status & ISI_RTS) ? TIOCM_RTS : 0) |
1267                 ((status & ISI_DTR) ? TIOCM_DTR : 0) |
1268                 ((status & ISI_DCD) ? TIOCM_CAR : 0) |
1269                 ((status & ISI_DSR) ? TIOCM_DSR : 0) |
1270                 ((status & ISI_CTS) ? TIOCM_CTS : 0) |
1271                 ((status & ISI_RI ) ? TIOCM_RI  : 0);
1272 }
1273
1274 static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
1275         unsigned int set, unsigned int clear)
1276 {
1277         struct isi_port *port = tty->driver_data;
1278
1279         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1280                 return -ENODEV;
1281
1282         if (set & TIOCM_RTS)
1283                 raise_rts(port);
1284         if (set & TIOCM_DTR)
1285                 raise_dtr(port);
1286
1287         if (clear & TIOCM_RTS)
1288                 drop_rts(port);
1289         if (clear & TIOCM_DTR)
1290                 drop_dtr(port);
1291
1292         return 0;
1293 }
1294
1295 static int isicom_set_serial_info(struct isi_port *port,
1296         struct serial_struct __user *info)
1297 {
1298         struct serial_struct newinfo;
1299         int reconfig_port;
1300
1301         if (copy_from_user(&newinfo, info, sizeof(newinfo)))
1302                 return -EFAULT;
1303
1304         reconfig_port = ((port->flags & ASYNC_SPD_MASK) !=
1305                 (newinfo.flags & ASYNC_SPD_MASK));
1306
1307         if (!capable(CAP_SYS_ADMIN)) {
1308                 if ((newinfo.close_delay != port->close_delay) ||
1309                                 (newinfo.closing_wait != port->closing_wait) ||
1310                                 ((newinfo.flags & ~ASYNC_USR_MASK) !=
1311                                 (port->flags & ~ASYNC_USR_MASK)))
1312                         return -EPERM;
1313                 port->flags = ((port->flags & ~ ASYNC_USR_MASK) |
1314                                 (newinfo.flags & ASYNC_USR_MASK));
1315         }
1316         else {
1317                 port->close_delay = newinfo.close_delay;
1318                 port->closing_wait = newinfo.closing_wait;
1319                 port->flags = ((port->flags & ~ASYNC_FLAGS) |
1320                                 (newinfo.flags & ASYNC_FLAGS));
1321         }
1322         if (reconfig_port) {
1323                 isicom_config_port(port);
1324         }
1325         return 0;
1326 }
1327
1328 static int isicom_get_serial_info(struct isi_port *port,
1329         struct serial_struct __user *info)
1330 {
1331         struct serial_struct out_info;
1332
1333         memset(&out_info, 0, sizeof(out_info));
1334 /*      out_info.type = ? */
1335         out_info.line = port - isi_ports;
1336         out_info.port = port->card->base;
1337         out_info.irq = port->card->irq;
1338         out_info.flags = port->flags;
1339 /*      out_info.baud_base = ? */
1340         out_info.close_delay = port->close_delay;
1341         out_info.closing_wait = port->closing_wait;
1342         if (copy_to_user(info, &out_info, sizeof(out_info)))
1343                 return -EFAULT;
1344         return 0;
1345 }
1346
1347 static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1348         unsigned int cmd, unsigned long arg)
1349 {
1350         struct isi_port *port = tty->driver_data;
1351         void __user *argp = (void __user *)arg;
1352         int retval;
1353
1354         if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1355                 return -ENODEV;
1356
1357         switch(cmd) {
1358         case TCSBRK:
1359                 retval = tty_check_change(tty);
1360                 if (retval)
1361                         return retval;
1362                 tty_wait_until_sent(tty, 0);
1363                 if (!arg)
1364                         isicom_send_break(port, HZ/4);
1365                 return 0;
1366
1367         case TCSBRKP:
1368                 retval = tty_check_change(tty);
1369                 if (retval)
1370                         return retval;
1371                 tty_wait_until_sent(tty, 0);
1372                 isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4);
1373                 return 0;
1374
1375         case TIOCGSOFTCAR:
1376                 return put_user(C_CLOCAL(tty) ? 1 : 0,
1377                                 (unsigned long __user *)argp);
1378
1379         case TIOCSSOFTCAR:
1380                 if (get_user(arg, (unsigned long __user *) argp))
1381                         return -EFAULT;
1382                 tty->termios->c_cflag =
1383                         ((tty->termios->c_cflag & ~CLOCAL) |
1384                         (arg ? CLOCAL : 0));
1385                 return 0;
1386
1387         case TIOCGSERIAL:
1388                 return isicom_get_serial_info(port, argp);
1389
1390         case TIOCSSERIAL:
1391                 return isicom_set_serial_info(port, argp);
1392
1393         default:
1394                 return -ENOIOCTLCMD;
1395         }
1396         return 0;
1397 }
1398
1399 /* set_termios et all */
1400 static void isicom_set_termios(struct tty_struct *tty,
1401         struct termios *old_termios)
1402 {
1403         struct isi_port *port = tty->driver_data;
1404
1405         if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
1406                 return;
1407
1408         if (tty->termios->c_cflag == old_termios->c_cflag &&
1409                         tty->termios->c_iflag == old_termios->c_iflag)
1410                 return;
1411
1412         isicom_config_port(port);
1413
1414         if ((old_termios->c_cflag & CRTSCTS) &&
1415                         !(tty->termios->c_cflag & CRTSCTS)) {
1416                 tty->hw_stopped = 0;
1417                 isicom_start(tty);
1418         }
1419 }
1420
1421 /* throttle et all */
1422 static void isicom_throttle(struct tty_struct *tty)
1423 {
1424         struct isi_port *port = tty->driver_data;
1425         struct isi_board *card = port->card;
1426
1427         if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
1428                 return;
1429
1430         /* tell the card that this port cannot handle any more data for now */
1431         card->port_status &= ~(1 << port->channel);
1432         outw(card->port_status, card->base + 0x02);
1433 }
1434
1435 /* unthrottle et all */
1436 static void isicom_unthrottle(struct tty_struct *tty)
1437 {
1438         struct isi_port *port = tty->driver_data;
1439         struct isi_board *card = port->card;
1440
1441         if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
1442                 return;
1443
1444         /* tell the card that this port is ready to accept more data */
1445         card->port_status |= (1 << port->channel);
1446         outw(card->port_status, card->base + 0x02);
1447 }
1448
1449 /* stop et all */
1450 static void isicom_stop(struct tty_struct *tty)
1451 {
1452         struct isi_port *port = tty->driver_data;
1453
1454         if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
1455                 return;
1456
1457         /* this tells the transmitter not to consider this port for
1458            data output to the card. */
1459         port->status &= ~ISI_TXOK;
1460 }
1461
1462 /* start et all */
1463 static void isicom_start(struct tty_struct *tty)
1464 {
1465         struct isi_port *port = tty->driver_data;
1466
1467         if (isicom_paranoia_check(port, tty->name, "isicom_start"))
1468                 return;
1469
1470         /* this tells the transmitter to consider this port for
1471            data output to the card. */
1472         port->status |= ISI_TXOK;
1473 }
1474
1475 /* hangup et all */
1476 static void do_isicom_hangup(void *data)
1477 {
1478         struct isi_port *port = data;
1479         struct tty_struct *tty;
1480
1481         tty = port->tty;
1482         if (tty)
1483                 tty_hangup(tty);
1484 }
1485
1486 static void isicom_hangup(struct tty_struct *tty)
1487 {
1488         struct isi_port *port = tty->driver_data;
1489
1490         if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
1491                 return;
1492
1493         isicom_shutdown_port(port);
1494         port->count = 0;
1495         port->flags &= ~ASYNC_NORMAL_ACTIVE;
1496         port->tty = NULL;
1497         wake_up_interruptible(&port->open_wait);
1498 }
1499
1500 /* flush_buffer et all */
1501 static void isicom_flush_buffer(struct tty_struct *tty)
1502 {
1503         struct isi_port *port = tty->driver_data;
1504         struct isi_board *card = port->card;
1505         unsigned long flags;
1506
1507         if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
1508                 return;
1509
1510         spin_lock_irqsave(&card->card_lock, flags);
1511         port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1512         spin_unlock_irqrestore(&card->card_lock, flags);
1513
1514         wake_up_interruptible(&tty->write_wait);
1515         tty_wakeup(tty);
1516 }
1517
1518 /*
1519  * Driver init and deinit functions
1520  */
1521
1522 static int __devinit isicom_register_ioregion(struct pci_dev *pdev,
1523         const unsigned int index)
1524 {
1525         struct isi_board *board = pci_get_drvdata(pdev);
1526
1527         if (!board->base)
1528                 return -EINVAL;
1529
1530         if (!request_region(board->base, 16, ISICOM_NAME)) {
1531                 dev_dbg(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
1532                         "will be disabled.\n", board->base, board->base + 15,
1533                         index + 1);
1534                 return -EBUSY;
1535         }
1536
1537         return 0;
1538 }
1539
1540 static void isicom_unregister_ioregion(struct pci_dev *pdev)
1541 {
1542         struct isi_board *board = pci_get_drvdata(pdev);
1543
1544         if (!board->base)
1545                 return;
1546
1547         release_region(board->base, 16);
1548         dev_dbg(&pdev->dev, "I/O Region 0x%lx-0x%lx released.\n",
1549                 board->base, board->base + 15);
1550         board->base = 0;
1551 }
1552
1553 static const struct tty_operations isicom_ops = {
1554         .open                   = isicom_open,
1555         .close                  = isicom_close,
1556         .write                  = isicom_write,
1557         .put_char               = isicom_put_char,
1558         .flush_chars            = isicom_flush_chars,
1559         .write_room             = isicom_write_room,
1560         .chars_in_buffer        = isicom_chars_in_buffer,
1561         .ioctl                  = isicom_ioctl,
1562         .set_termios            = isicom_set_termios,
1563         .throttle               = isicom_throttle,
1564         .unthrottle             = isicom_unthrottle,
1565         .stop                   = isicom_stop,
1566         .start                  = isicom_start,
1567         .hangup                 = isicom_hangup,
1568         .flush_buffer           = isicom_flush_buffer,
1569         .tiocmget               = isicom_tiocmget,
1570         .tiocmset               = isicom_tiocmset,
1571 };
1572
1573 static int __devinit isicom_register_tty_driver(void)
1574 {
1575         int error = -ENOMEM;
1576
1577         /* tty driver structure initialization */
1578         isicom_normal = alloc_tty_driver(PORT_COUNT);
1579         if (!isicom_normal)
1580                 goto end;
1581
1582         isicom_normal->owner                    = THIS_MODULE;
1583         isicom_normal->name                     = "ttyM";
1584         isicom_normal->major                    = ISICOM_NMAJOR;
1585         isicom_normal->minor_start              = 0;
1586         isicom_normal->type                     = TTY_DRIVER_TYPE_SERIAL;
1587         isicom_normal->subtype                  = SERIAL_TYPE_NORMAL;
1588         isicom_normal->init_termios             = tty_std_termios;
1589         isicom_normal->init_termios.c_cflag     = B9600 | CS8 | CREAD | HUPCL |
1590                 CLOCAL;
1591         isicom_normal->flags                    = TTY_DRIVER_REAL_RAW;
1592         tty_set_operations(isicom_normal, &isicom_ops);
1593
1594         if ((error = tty_register_driver(isicom_normal))) {
1595                 pr_dbg("Couldn't register the dialin driver, error=%d\n",
1596                         error);
1597                 put_tty_driver(isicom_normal);
1598         }
1599 end:
1600         return error;
1601 }
1602
1603 static void isicom_unregister_tty_driver(void)
1604 {
1605         int error;
1606
1607         if ((error = tty_unregister_driver(isicom_normal)))
1608                 pr_dbg("couldn't unregister normal driver, error=%d.\n", error);
1609
1610         put_tty_driver(isicom_normal);
1611 }
1612
1613 static int __devinit isicom_register_isr(struct pci_dev *pdev,
1614         const unsigned int index)
1615 {
1616         struct isi_board *board = pci_get_drvdata(pdev);
1617         unsigned long irqflags = IRQF_DISABLED;
1618         int retval = -EINVAL;
1619
1620         if (!board->base)
1621                 goto end;
1622
1623         if (board->isa == NO)
1624                 irqflags |= IRQF_SHARED;
1625
1626         retval = request_irq(board->irq, isicom_interrupt, irqflags,
1627                 ISICOM_NAME, board);
1628         if (retval < 0)
1629                 dev_warn(&pdev->dev, "Could not install handler at Irq %d. "
1630                         "Card%d will be disabled.\n", board->irq, index + 1);
1631         else
1632                 retval = 0;
1633 end:
1634         return retval;
1635 }
1636
1637 static int __devinit reset_card(struct pci_dev *pdev,
1638         const unsigned int card, unsigned int *signature)
1639 {
1640         struct isi_board *board = pci_get_drvdata(pdev);
1641         unsigned long base = board->base;
1642         unsigned int portcount = 0;
1643         int retval = 0;
1644
1645         dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
1646                 base);
1647
1648         inw(base + 0x8);
1649
1650         mdelay(10);
1651
1652         outw(0, base + 0x8); /* Reset */
1653
1654         msleep(3000);
1655
1656         *signature = inw(base + 0x4) & 0xff;
1657
1658         if (board->isa == YES) {
1659                 if (!(inw(base + 0xe) & 0x1) || (inw(base + 0x2))) {
1660                         dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n",
1661                                 inw(base + 0x2), inw(base + 0xe));
1662                         dev_err(&pdev->dev, "ISILoad:ISA Card%d reset failure "
1663                                 "(Possible bad I/O Port Address 0x%lx).\n",
1664                                 card + 1, base);
1665                         retval = -EIO;
1666                         goto end;
1667                 }
1668         } else {
1669                 portcount = inw(base + 0x2);
1670                 if (!(inw(base + 0xe) & 0x1) || ((portcount != 0) &&
1671                                 (portcount != 4) && (portcount != 8))) {
1672                         dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n",
1673                                 inw(base + 0x2), inw(base + 0xe));
1674                         dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure "
1675                                 "(Possible bad I/O Port Address 0x%lx).\n",
1676                                 card + 1, base);
1677                         retval = -EIO;
1678                         goto end;
1679                 }
1680         }
1681
1682         switch (*signature) {
1683         case 0xa5:
1684         case 0xbb:
1685         case 0xdd:
1686                 board->port_count = (board->isa == NO && portcount == 4) ? 4 :
1687                         8;
1688                 board->shift_count = 12;
1689                 break;
1690         case 0xcc:
1691                 board->port_count = 16;
1692                 board->shift_count = 11;
1693                 break;
1694         default:
1695                 dev_warn(&pdev->dev, "ISILoad:Card%d reset failure (Possible "
1696                         "bad I/O Port Address 0x%lx).\n", card + 1, base);
1697                 dev_dbg(&pdev->dev, "Sig=0x%lx\n", signature);
1698                 retval = -EIO;
1699         }
1700         dev_info(&pdev->dev, "-Done\n");
1701
1702 end:
1703         return retval;
1704 }
1705
1706 static inline int WaitTillCardIsFree(u16 base)
1707 {
1708         unsigned long count = 0;
1709
1710         while (!(inw(base + 0xe) & 0x1) && count++ < 100)
1711                 msleep(5);
1712
1713         return !(inw(base + 0xe) & 0x1);
1714 }
1715
1716 static int __devinit load_firmware(struct pci_dev *pdev,
1717         const unsigned int index, const unsigned int signature)
1718 {
1719         struct isi_board *board = pci_get_drvdata(pdev);
1720         const struct firmware *fw;
1721         unsigned long base = board->base;
1722         unsigned int a;
1723         u16 word_count, status;
1724         int retval = -EIO;
1725         char *name;
1726         u8 *data;
1727
1728         struct stframe {
1729                 u16     addr;
1730                 u16     count;
1731                 u8      data[0];
1732         } *frame;
1733
1734         switch (signature) {
1735         case 0xa5:
1736                 name = "isi608.bin";
1737                 break;
1738         case 0xbb:
1739                 name = "isi608em.bin";
1740                 break;
1741         case 0xcc:
1742                 name = "isi616em.bin";
1743                 break;
1744         case 0xdd:
1745                 name = "isi4608.bin";
1746                 break;
1747         case 0xee:
1748                 name = "isi4616.bin";
1749                 break;
1750         default:
1751                 dev_err(&pdev->dev, "Unknown signature.\n");
1752                 goto end;
1753         }
1754
1755         retval = request_firmware(&fw, name, &pdev->dev);
1756         if (retval)
1757                 goto end;
1758
1759         retval = -EIO;
1760
1761         for (frame = (struct stframe *)fw->data;
1762                         frame < (struct stframe *)(fw->data + fw->size);
1763                         frame = (struct stframe *)((u8 *)(frame + 1) +
1764                                 frame->count)) {
1765                 if (WaitTillCardIsFree(base))
1766                         goto errrelfw;
1767
1768                 outw(0xf0, base);       /* start upload sequence */
1769                 outw(0x00, base);
1770                 outw(frame->addr, base); /* lsb of address */
1771
1772                 word_count = frame->count / 2 + frame->count % 2;
1773                 outw(word_count, base);
1774                 InterruptTheCard(base);
1775
1776                 udelay(100); /* 0x2f */
1777
1778                 if (WaitTillCardIsFree(base))
1779                         goto errrelfw;
1780
1781                 if ((status = inw(base + 0x4)) != 0) {
1782                         dev_warn(&pdev->dev, "Card%d rejected load header:\n"
1783                                 "Address:0x%x\nCount:0x%x\nStatus:0x%x\n",
1784                                 index + 1, frame->addr, frame->count, status);
1785                         goto errrelfw;
1786                 }
1787                 outsw(base, frame->data, word_count);
1788
1789                 InterruptTheCard(base);
1790
1791                 udelay(50); /* 0x0f */
1792
1793                 if (WaitTillCardIsFree(base))
1794                         goto errrelfw;
1795
1796                 if ((status = inw(base + 0x4)) != 0) {
1797                         dev_err(&pdev->dev, "Card%d got out of sync.Card "
1798                                 "Status:0x%x\n", index + 1, status);
1799                         goto errrelfw;
1800                 }
1801         }
1802
1803 /* XXX: should we test it by reading it back and comparing with original like
1804  * in load firmware package? */
1805         for (frame = (struct stframe *)fw->data;
1806                         frame < (struct stframe *)(fw->data + fw->size);
1807                         frame = (struct stframe *)((u8 *)(frame + 1) +
1808                                 frame->count)) {
1809                 if (WaitTillCardIsFree(base))
1810                         goto errrelfw;
1811
1812                 outw(0xf1, base); /* start download sequence */
1813                 outw(0x00, base);
1814                 outw(frame->addr, base); /* lsb of address */
1815
1816                 word_count = (frame->count >> 1) + frame->count % 2;
1817                 outw(word_count + 1, base);
1818                 InterruptTheCard(base);
1819
1820                 udelay(50); /* 0xf */
1821
1822                 if (WaitTillCardIsFree(base))
1823                         goto errrelfw;
1824
1825                 if ((status = inw(base + 0x4)) != 0) {
1826                         dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
1827                                 "Address:0x%x\nCount:0x%x\nStatus: 0x%x\n",
1828                                 index + 1, frame->addr, frame->count, status);
1829                         goto errrelfw;
1830                 }
1831
1832                 data = kmalloc(word_count * 2, GFP_KERNEL);
1833                 inw(base);
1834                 insw(base, data, word_count);
1835                 InterruptTheCard(base);
1836
1837                 for (a = 0; a < frame->count; a++)
1838                         if (data[a] != frame->data[a]) {
1839                                 kfree(data);
1840                                 dev_err(&pdev->dev, "Card%d, firmware upload "
1841                                         "failed\n", index + 1);
1842                                 goto errrelfw;
1843                         }
1844                 kfree(data);
1845
1846                 udelay(50); /* 0xf */
1847
1848                 if (WaitTillCardIsFree(base))
1849                         goto errrelfw;
1850
1851                 if ((status = inw(base + 0x4)) != 0) {
1852                         dev_err(&pdev->dev, "Card%d verify got out of sync. "
1853                                 "Card Status:0x%x\n", index + 1, status);
1854                         goto errrelfw;
1855                 }
1856         }
1857
1858         /* xfer ctrl */
1859         if (WaitTillCardIsFree(base))
1860                 goto errrelfw;
1861
1862         outw(0xf2, base);
1863         outw(0x800, base);
1864         outw(0x0, base);
1865         outw(0x0, base);
1866         InterruptTheCard(base);
1867         outw(0x0, base + 0x4); /* for ISI4608 cards */
1868
1869         board->status |= FIRMWARE_LOADED;
1870         retval = 0;
1871
1872 errrelfw:
1873         release_firmware(fw);
1874 end:
1875         return retval;
1876 }
1877
1878 /*
1879  *      Insmod can set static symbols so keep these static
1880  */
1881 static int io[4];
1882 static int irq[4];
1883 static int card;
1884
1885 static int __devinit isicom_probe(struct pci_dev *pdev,
1886         const struct pci_device_id *ent)
1887 {
1888         unsigned int ioaddr, signature, index;
1889         int retval = -EPERM;
1890         u8 pciirq;
1891         struct isi_board *board = NULL;
1892
1893         if (card >= BOARD_COUNT)
1894                 goto err;
1895
1896         ioaddr = pci_resource_start(pdev, 3);
1897         /* i.e at offset 0x1c in the PCI configuration register space. */
1898         pciirq = pdev->irq;
1899         dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
1900
1901         /* allot the first empty slot in the array */
1902         for (index = 0; index < BOARD_COUNT; index++)
1903                 if (isi_card[index].base == 0) {
1904                         board = &isi_card[index];
1905                         break;
1906                 }
1907
1908         board->base = ioaddr;
1909         board->irq = pciirq;
1910         board->isa = NO;
1911         card++;
1912
1913         pci_set_drvdata(pdev, board);
1914
1915         retval = isicom_register_ioregion(pdev, index);
1916         if (retval < 0)
1917                 goto err;
1918
1919         retval = isicom_register_isr(pdev, index);
1920         if (retval < 0)
1921                 goto errunrr;
1922
1923         retval = reset_card(pdev, index, &signature);
1924         if (retval < 0)
1925                 goto errunri;
1926
1927         retval = load_firmware(pdev, index, signature);
1928         if (retval < 0)
1929                 goto errunri;
1930
1931         return 0;
1932
1933 errunri:
1934         free_irq(board->irq, board);
1935 errunrr:
1936         isicom_unregister_ioregion(pdev);
1937 err:
1938         board->base = 0;
1939         return retval;
1940 }
1941
1942 static void __devexit isicom_remove(struct pci_dev *pdev)
1943 {
1944         struct isi_board *board = pci_get_drvdata(pdev);
1945
1946         free_irq(board->irq, board);
1947         isicom_unregister_ioregion(pdev);
1948 }
1949
1950 static int __devinit isicom_setup(void)
1951 {
1952         int retval, idx, channel;
1953         struct isi_port *port;
1954
1955         card = 0;
1956         memset(isi_ports, 0, sizeof(isi_ports));
1957
1958         for(idx = 0; idx < BOARD_COUNT; idx++) {
1959                 port = &isi_ports[idx * 16];
1960                 isi_card[idx].ports = port;
1961                 spin_lock_init(&isi_card[idx].card_lock);
1962                 for (channel = 0; channel < 16; channel++, port++) {
1963                         port->magic = ISICOM_MAGIC;
1964                         port->card = &isi_card[idx];
1965                         port->channel = channel;
1966                         port->close_delay = 50 * HZ/100;
1967                         port->closing_wait = 3000 * HZ/100;
1968                         INIT_WORK(&port->hangup_tq, do_isicom_hangup, port);
1969                         INIT_WORK(&port->bh_tqueue, isicom_bottomhalf, port);
1970                         port->status = 0;
1971                         init_waitqueue_head(&port->open_wait);
1972                         init_waitqueue_head(&port->close_wait);
1973                         /*  . . .  */
1974                 }
1975                 isi_card[idx].base = 0;
1976                 isi_card[idx].irq = 0;
1977
1978                 if (!io[idx])
1979                         continue;
1980
1981                 if (irq[idx] == 2 || irq[idx] == 3 || irq[idx] == 4     ||
1982                                 irq[idx] == 5   || irq[idx] == 7        ||
1983                                 irq[idx] == 10  || irq[idx] == 11       ||
1984                                 irq[idx] == 12  || irq[idx] == 15) {
1985                         printk(KERN_ERR "ISICOM: ISA not supported yet.\n");
1986                         retval = -EINVAL;
1987                         goto error;
1988                 } else
1989                         printk(KERN_ERR "ISICOM: Irq %d unsupported. "
1990                                 "Disabling Card%d...\n", irq[idx], idx + 1);
1991         }
1992
1993         retval = isicom_register_tty_driver();
1994         if (retval < 0)
1995                 goto error;
1996
1997         retval = pci_register_driver(&isicom_driver);
1998         if (retval < 0) {
1999                 printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
2000                 goto errtty;
2001         }
2002
2003         init_timer(&tx);
2004         tx.expires = jiffies + 1;
2005         tx.data = 0;
2006         tx.function = isicom_tx;
2007         re_schedule = 1;
2008         add_timer(&tx);
2009
2010         return 0;
2011 errtty:
2012         isicom_unregister_tty_driver();
2013 error:
2014         return retval;
2015 }
2016
2017 static void __exit isicom_exit(void)
2018 {
2019         unsigned int index = 0;
2020
2021         re_schedule = 0;
2022
2023         while (re_schedule != 2 && index++ < 100)
2024                 msleep(10);
2025
2026         pci_unregister_driver(&isicom_driver);
2027         isicom_unregister_tty_driver();
2028 }
2029
2030 module_init(isicom_setup);
2031 module_exit(isicom_exit);
2032
2033 MODULE_AUTHOR("MultiTech");
2034 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
2035 MODULE_LICENSE("GPL");
2036 module_param_array(io, int, NULL, 0);
2037 MODULE_PARM_DESC(io, "I/O ports for the cards");
2038 module_param_array(irq, int, NULL, 0);
2039 MODULE_PARM_DESC(irq, "Interrupts for the cards");