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