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