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