x86: make headers files the same in io_apic_xx.c
[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 tty = tty_port_tty_get(&port->port);
425 if (tty == NULL)
426 goto put_unlock;
427
428 for (; count > 0; count--, port++) {
429 /* port not active or tx disabled to force flow control */
430 if (!(port->port.flags & ASYNC_INITIALIZED) ||
431 !(port->status & ISI_TXOK))
432 continue;
433
434 txcount = min_t(short, TX_SIZE, port->xmit_cnt);
435 if (txcount <= 0 || tty->stopped || tty->hw_stopped)
436 continue;
437
438 if (!(inw(base + 0x02) & (1 << port->channel)))
439 continue;
440
441 pr_dbg("txing %d bytes, port%d.\n", txcount,
442 port->channel + 1);
443 outw((port->channel << isi_card[card].shift_count) | txcount,
444 base);
445 residue = NO;
446 wrd = 0;
447 while (1) {
448 cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE
449 - port->xmit_tail));
450 if (residue == YES) {
451 residue = NO;
452 if (cnt > 0) {
453 wrd |= (port->port.xmit_buf[port->xmit_tail]
454 << 8);
455 port->xmit_tail = (port->xmit_tail + 1)
456 & (SERIAL_XMIT_SIZE - 1);
457 port->xmit_cnt--;
458 txcount--;
459 cnt--;
460 outw(wrd, base);
461 } else {
462 outw(wrd, base);
463 break;
464 }
465 }
466 if (cnt <= 0)
467 break;
468 word_count = cnt >> 1;
469 outsw(base, port->port.xmit_buf+port->xmit_tail, word_count);
470 port->xmit_tail = (port->xmit_tail
471 + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
472 txcount -= (word_count << 1);
473 port->xmit_cnt -= (word_count << 1);
474 if (cnt & 0x0001) {
475 residue = YES;
476 wrd = port->port.xmit_buf[port->xmit_tail];
477 port->xmit_tail = (port->xmit_tail + 1)
478 & (SERIAL_XMIT_SIZE - 1);
479 port->xmit_cnt--;
480 txcount--;
481 }
482 }
483
484 InterruptTheCard(base);
485 if (port->xmit_cnt <= 0)
486 port->status &= ~ISI_TXOK;
487 if (port->xmit_cnt <= WAKEUP_CHARS)
488 tty_wakeup(tty);
489 }
490
491 put_unlock:
492 tty_kref_put(tty);
493 unlock:
494 spin_unlock_irqrestore(&isi_card[card].card_lock, flags);
495 /* schedule another tx for hopefully in about 10ms */
496 sched_again:
497 mod_timer(&tx, jiffies + msecs_to_jiffies(10));
498 }
499
500 /*
501 * Main interrupt handler routine
502 */
503
504 static irqreturn_t isicom_interrupt(int irq, void *dev_id)
505 {
506 struct isi_board *card = dev_id;
507 struct isi_port *port;
508 struct tty_struct *tty;
509 unsigned long base;
510 u16 header, word_count, count, channel;
511 short byte_count;
512 unsigned char *rp;
513
514 if (!card || !(card->status & FIRMWARE_LOADED))
515 return IRQ_NONE;
516
517 base = card->base;
518
519 /* did the card interrupt us? */
520 if (!(inw(base + 0x0e) & 0x02))
521 return IRQ_NONE;
522
523 spin_lock(&card->card_lock);
524
525 /*
526 * disable any interrupts from the PCI card and lower the
527 * interrupt line
528 */
529 outw(0x8000, base+0x04);
530 ClearInterrupt(base);
531
532 inw(base); /* get the dummy word out */
533 header = inw(base);
534 channel = (header & 0x7800) >> card->shift_count;
535 byte_count = header & 0xff;
536
537 if (channel + 1 > card->port_count) {
538 printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): "
539 "%d(channel) > port_count.\n", base, channel+1);
540 outw(0x0000, base+0x04); /* enable interrupts */
541 spin_unlock(&card->card_lock);
542 return IRQ_HANDLED;
543 }
544 port = card->ports + channel;
545 if (!(port->port.flags & ASYNC_INITIALIZED)) {
546 outw(0x0000, base+0x04); /* enable interrupts */
547 spin_unlock(&card->card_lock);
548 return IRQ_HANDLED;
549 }
550
551 tty = tty_port_tty_get(&port->port);
552 if (tty == NULL) {
553 word_count = byte_count >> 1;
554 while (byte_count > 1) {
555 inw(base);
556 byte_count -= 2;
557 }
558 if (byte_count & 0x01)
559 inw(base);
560 outw(0x0000, base+0x04); /* enable interrupts */
561 spin_unlock(&card->card_lock);
562 return IRQ_HANDLED;
563 }
564
565 if (header & 0x8000) { /* Status Packet */
566 header = inw(base);
567 switch (header & 0xff) {
568 case 0: /* Change in EIA signals */
569 if (port->port.flags & ASYNC_CHECK_CD) {
570 if (port->status & ISI_DCD) {
571 if (!(header & ISI_DCD)) {
572 /* Carrier has been lost */
573 pr_dbg("interrupt: DCD->low.\n"
574 );
575 port->status &= ~ISI_DCD;
576 tty_hangup(tty);
577 }
578 } else if (header & ISI_DCD) {
579 /* Carrier has been detected */
580 pr_dbg("interrupt: DCD->high.\n");
581 port->status |= ISI_DCD;
582 wake_up_interruptible(&port->port.open_wait);
583 }
584 } else {
585 if (header & ISI_DCD)
586 port->status |= ISI_DCD;
587 else
588 port->status &= ~ISI_DCD;
589 }
590
591 if (port->port.flags & ASYNC_CTS_FLOW) {
592 if (tty->hw_stopped) {
593 if (header & ISI_CTS) {
594 port->port.tty->hw_stopped = 0;
595 /* start tx ing */
596 port->status |= (ISI_TXOK
597 | ISI_CTS);
598 tty_wakeup(tty);
599 }
600 } else if (!(header & ISI_CTS)) {
601 tty->hw_stopped = 1;
602 /* stop tx ing */
603 port->status &= ~(ISI_TXOK | ISI_CTS);
604 }
605 } else {
606 if (header & ISI_CTS)
607 port->status |= ISI_CTS;
608 else
609 port->status &= ~ISI_CTS;
610 }
611
612 if (header & ISI_DSR)
613 port->status |= ISI_DSR;
614 else
615 port->status &= ~ISI_DSR;
616
617 if (header & ISI_RI)
618 port->status |= ISI_RI;
619 else
620 port->status &= ~ISI_RI;
621
622 break;
623
624 case 1: /* Received Break !!! */
625 tty_insert_flip_char(tty, 0, TTY_BREAK);
626 if (port->port.flags & ASYNC_SAK)
627 do_SAK(tty);
628 tty_flip_buffer_push(tty);
629 break;
630
631 case 2: /* Statistics */
632 pr_dbg("isicom_interrupt: stats!!!.\n");
633 break;
634
635 default:
636 pr_dbg("Intr: Unknown code in status packet.\n");
637 break;
638 }
639 } else { /* Data Packet */
640
641 count = tty_prepare_flip_string(tty, &rp, byte_count & ~1);
642 pr_dbg("Intr: Can rx %d of %d bytes.\n", count, byte_count);
643 word_count = count >> 1;
644 insw(base, rp, word_count);
645 byte_count -= (word_count << 1);
646 if (count & 0x0001) {
647 tty_insert_flip_char(tty, inw(base) & 0xff,
648 TTY_NORMAL);
649 byte_count -= 2;
650 }
651 if (byte_count > 0) {
652 pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping "
653 "bytes...\n", base, channel + 1);
654 /* drain out unread xtra data */
655 while (byte_count > 0) {
656 inw(base);
657 byte_count -= 2;
658 }
659 }
660 tty_flip_buffer_push(tty);
661 }
662 outw(0x0000, base+0x04); /* enable interrupts */
663 spin_unlock(&card->card_lock);
664 tty_kref_put(tty);
665
666 return IRQ_HANDLED;
667 }
668
669 static void isicom_config_port(struct tty_struct *tty)
670 {
671 struct isi_port *port = tty->driver_data;
672 struct isi_board *card = port->card;
673 unsigned long baud;
674 unsigned long base = card->base;
675 u16 channel_setup, channel = port->channel,
676 shift_count = card->shift_count;
677 unsigned char flow_ctrl;
678
679 /* FIXME: Switch to new tty baud API */
680 baud = C_BAUD(tty);
681 if (baud & CBAUDEX) {
682 baud &= ~CBAUDEX;
683
684 /* if CBAUDEX bit is on and the baud is set to either 50 or 75
685 * then the card is programmed for 57.6Kbps or 115Kbps
686 * respectively.
687 */
688
689 /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
690 if (baud < 1 || baud > 4)
691 tty->termios->c_cflag &= ~CBAUDEX;
692 else
693 baud += 15;
694 }
695 if (baud == 15) {
696
697 /* the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set
698 * by the set_serial_info ioctl ... this is done by
699 * the 'setserial' utility.
700 */
701
702 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
703 baud++; /* 57.6 Kbps */
704 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
705 baud += 2; /* 115 Kbps */
706 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
707 baud += 3; /* 230 kbps*/
708 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
709 baud += 4; /* 460 kbps*/
710 }
711 if (linuxb_to_isib[baud] == -1) {
712 /* hang up */
713 drop_dtr(port);
714 return;
715 } else
716 raise_dtr(port);
717
718 if (WaitTillCardIsFree(base) == 0) {
719 outw(0x8000 | (channel << shift_count) | 0x03, base);
720 outw(linuxb_to_isib[baud] << 8 | 0x03, base);
721 channel_setup = 0;
722 switch (C_CSIZE(tty)) {
723 case CS5:
724 channel_setup |= ISICOM_CS5;
725 break;
726 case CS6:
727 channel_setup |= ISICOM_CS6;
728 break;
729 case CS7:
730 channel_setup |= ISICOM_CS7;
731 break;
732 case CS8:
733 channel_setup |= ISICOM_CS8;
734 break;
735 }
736
737 if (C_CSTOPB(tty))
738 channel_setup |= ISICOM_2SB;
739 if (C_PARENB(tty)) {
740 channel_setup |= ISICOM_EVPAR;
741 if (C_PARODD(tty))
742 channel_setup |= ISICOM_ODPAR;
743 }
744 outw(channel_setup, base);
745 InterruptTheCard(base);
746 }
747 if (C_CLOCAL(tty))
748 port->port.flags &= ~ASYNC_CHECK_CD;
749 else
750 port->port.flags |= ASYNC_CHECK_CD;
751
752 /* flow control settings ...*/
753 flow_ctrl = 0;
754 port->port.flags &= ~ASYNC_CTS_FLOW;
755 if (C_CRTSCTS(tty)) {
756 port->port.flags |= ASYNC_CTS_FLOW;
757 flow_ctrl |= ISICOM_CTSRTS;
758 }
759 if (I_IXON(tty))
760 flow_ctrl |= ISICOM_RESPOND_XONXOFF;
761 if (I_IXOFF(tty))
762 flow_ctrl |= ISICOM_INITIATE_XONXOFF;
763
764 if (WaitTillCardIsFree(base) == 0) {
765 outw(0x8000 | (channel << shift_count) | 0x04, base);
766 outw(flow_ctrl << 8 | 0x05, base);
767 outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
768 InterruptTheCard(base);
769 }
770
771 /* rx enabled -> enable port for rx on the card */
772 if (C_CREAD(tty)) {
773 card->port_status |= (1 << channel);
774 outw(card->port_status, base + 0x02);
775 }
776 }
777
778 /* open et all */
779
780 static inline void isicom_setup_board(struct isi_board *bp)
781 {
782 int channel;
783 struct isi_port *port;
784 unsigned long flags;
785
786 spin_lock_irqsave(&bp->card_lock, flags);
787 if (bp->status & BOARD_ACTIVE) {
788 spin_unlock_irqrestore(&bp->card_lock, flags);
789 return;
790 }
791 port = bp->ports;
792 bp->status |= BOARD_ACTIVE;
793 for (channel = 0; channel < bp->port_count; channel++, port++)
794 drop_dtr_rts(port);
795 spin_unlock_irqrestore(&bp->card_lock, flags);
796 }
797
798 static int isicom_setup_port(struct tty_struct *tty)
799 {
800 struct isi_port *port = tty->driver_data;
801 struct isi_board *card = port->card;
802 unsigned long flags;
803
804 if (port->port.flags & ASYNC_INITIALIZED)
805 return 0;
806 if (tty_port_alloc_xmit_buf(&port->port) < 0)
807 return -ENOMEM;
808
809 spin_lock_irqsave(&card->card_lock, flags);
810 clear_bit(TTY_IO_ERROR, &tty->flags);
811 if (port->port.count == 1)
812 card->count++;
813
814 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
815
816 /* discard any residual data */
817 if (WaitTillCardIsFree(card->base) == 0) {
818 outw(0x8000 | (port->channel << card->shift_count) | 0x02,
819 card->base);
820 outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base);
821 InterruptTheCard(card->base);
822 }
823
824 isicom_config_port(tty);
825 port->port.flags |= ASYNC_INITIALIZED;
826 spin_unlock_irqrestore(&card->card_lock, flags);
827
828 return 0;
829 }
830
831 static int block_til_ready(struct tty_struct *tty, struct file *filp,
832 struct isi_port *port)
833 {
834 struct isi_board *card = port->card;
835 int do_clocal = 0, retval;
836 unsigned long flags;
837 DECLARE_WAITQUEUE(wait, current);
838
839 /* block if port is in the process of being closed */
840
841 if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
842 pr_dbg("block_til_ready: close in progress.\n");
843 interruptible_sleep_on(&port->port.close_wait);
844 if (port->port.flags & ASYNC_HUP_NOTIFY)
845 return -EAGAIN;
846 else
847 return -ERESTARTSYS;
848 }
849
850 /* if non-blocking mode is set ... */
851
852 if ((filp->f_flags & O_NONBLOCK) ||
853 (tty->flags & (1 << TTY_IO_ERROR))) {
854 pr_dbg("block_til_ready: non-block mode.\n");
855 port->port.flags |= ASYNC_NORMAL_ACTIVE;
856 return 0;
857 }
858
859 if (C_CLOCAL(tty))
860 do_clocal = 1;
861
862 /* block waiting for DCD to be asserted, and while
863 callout dev is busy */
864 retval = 0;
865 add_wait_queue(&port->port.open_wait, &wait);
866
867 spin_lock_irqsave(&card->card_lock, flags);
868 if (!tty_hung_up_p(filp))
869 port->port.count--;
870 port->port.blocked_open++;
871 spin_unlock_irqrestore(&card->card_lock, flags);
872
873 while (1) {
874 raise_dtr_rts(port);
875
876 set_current_state(TASK_INTERRUPTIBLE);
877 if (tty_hung_up_p(filp) || !(port->port.flags & ASYNC_INITIALIZED)) {
878 if (port->port.flags & ASYNC_HUP_NOTIFY)
879 retval = -EAGAIN;
880 else
881 retval = -ERESTARTSYS;
882 break;
883 }
884 if (!(port->port.flags & ASYNC_CLOSING) &&
885 (do_clocal || (port->status & ISI_DCD))) {
886 break;
887 }
888 if (signal_pending(current)) {
889 retval = -ERESTARTSYS;
890 break;
891 }
892 schedule();
893 }
894 set_current_state(TASK_RUNNING);
895 remove_wait_queue(&port->port.open_wait, &wait);
896 spin_lock_irqsave(&card->card_lock, flags);
897 if (!tty_hung_up_p(filp))
898 port->port.count++;
899 port->port.blocked_open--;
900 spin_unlock_irqrestore(&card->card_lock, flags);
901 if (retval)
902 return retval;
903 port->port.flags |= ASYNC_NORMAL_ACTIVE;
904 return 0;
905 }
906
907 static int isicom_open(struct tty_struct *tty, struct file *filp)
908 {
909 struct isi_port *port;
910 struct isi_board *card;
911 unsigned int board;
912 int error, line;
913
914 line = tty->index;
915 if (line < 0 || line > PORT_COUNT-1)
916 return -ENODEV;
917 board = BOARD(line);
918 card = &isi_card[board];
919
920 if (!(card->status & FIRMWARE_LOADED))
921 return -ENODEV;
922
923 /* open on a port greater than the port count for the card !!! */
924 if (line > ((board * 16) + card->port_count - 1))
925 return -ENODEV;
926
927 port = &isi_ports[line];
928 if (isicom_paranoia_check(port, tty->name, "isicom_open"))
929 return -ENODEV;
930
931 isicom_setup_board(card);
932
933 port->port.count++;
934 tty->driver_data = port;
935 tty_port_tty_set(&port->port, tty);
936 error = isicom_setup_port(tty);
937 if (error == 0)
938 error = block_til_ready(tty, filp, port);
939 return error;
940 }
941
942 /* close et all */
943
944 static inline void isicom_shutdown_board(struct isi_board *bp)
945 {
946 if (bp->status & BOARD_ACTIVE)
947 bp->status &= ~BOARD_ACTIVE;
948 }
949
950 /* card->lock HAS to be held */
951 static void isicom_shutdown_port(struct isi_port *port)
952 {
953 struct isi_board *card = port->card;
954 struct tty_struct *tty;
955
956 tty = tty_port_tty_get(&port->port);
957
958 if (!(port->port.flags & ASYNC_INITIALIZED)) {
959 tty_kref_put(tty);
960 return;
961 }
962
963 tty_port_free_xmit_buf(&port->port);
964 port->port.flags &= ~ASYNC_INITIALIZED;
965 /* 3rd October 2000 : Vinayak P Risbud */
966 tty_port_tty_set(&port->port, 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 tty_struct *tty,
1247 struct serial_struct __user *info)
1248 {
1249 struct isi_port *port = tty->driver_data;
1250 struct serial_struct newinfo;
1251 int reconfig_port;
1252
1253 if (copy_from_user(&newinfo, info, sizeof(newinfo)))
1254 return -EFAULT;
1255
1256 lock_kernel();
1257
1258 reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) !=
1259 (newinfo.flags & ASYNC_SPD_MASK));
1260
1261 if (!capable(CAP_SYS_ADMIN)) {
1262 if ((newinfo.close_delay != port->port.close_delay) ||
1263 (newinfo.closing_wait != port->port.closing_wait) ||
1264 ((newinfo.flags & ~ASYNC_USR_MASK) !=
1265 (port->port.flags & ~ASYNC_USR_MASK))) {
1266 unlock_kernel();
1267 return -EPERM;
1268 }
1269 port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1270 (newinfo.flags & ASYNC_USR_MASK));
1271 } else {
1272 port->port.close_delay = newinfo.close_delay;
1273 port->port.closing_wait = newinfo.closing_wait;
1274 port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1275 (newinfo.flags & ASYNC_FLAGS));
1276 }
1277 if (reconfig_port) {
1278 unsigned long flags;
1279 spin_lock_irqsave(&port->card->card_lock, flags);
1280 isicom_config_port(tty);
1281 spin_unlock_irqrestore(&port->card->card_lock, flags);
1282 }
1283 unlock_kernel();
1284 return 0;
1285 }
1286
1287 static int isicom_get_serial_info(struct isi_port *port,
1288 struct serial_struct __user *info)
1289 {
1290 struct serial_struct out_info;
1291
1292 lock_kernel();
1293 memset(&out_info, 0, sizeof(out_info));
1294 /* out_info.type = ? */
1295 out_info.line = port - isi_ports;
1296 out_info.port = port->card->base;
1297 out_info.irq = port->card->irq;
1298 out_info.flags = port->port.flags;
1299 /* out_info.baud_base = ? */
1300 out_info.close_delay = port->port.close_delay;
1301 out_info.closing_wait = port->port.closing_wait;
1302 unlock_kernel();
1303 if (copy_to_user(info, &out_info, sizeof(out_info)))
1304 return -EFAULT;
1305 return 0;
1306 }
1307
1308 static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1309 unsigned int cmd, unsigned long arg)
1310 {
1311 struct isi_port *port = tty->driver_data;
1312 void __user *argp = (void __user *)arg;
1313
1314 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1315 return -ENODEV;
1316
1317 switch (cmd) {
1318 case TIOCGSERIAL:
1319 return isicom_get_serial_info(port, argp);
1320
1321 case TIOCSSERIAL:
1322 return isicom_set_serial_info(tty, argp);
1323
1324 default:
1325 return -ENOIOCTLCMD;
1326 }
1327 return 0;
1328 }
1329
1330 /* set_termios et all */
1331 static void isicom_set_termios(struct tty_struct *tty,
1332 struct ktermios *old_termios)
1333 {
1334 struct isi_port *port = tty->driver_data;
1335 unsigned long flags;
1336
1337 if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
1338 return;
1339
1340 if (tty->termios->c_cflag == old_termios->c_cflag &&
1341 tty->termios->c_iflag == old_termios->c_iflag)
1342 return;
1343
1344 spin_lock_irqsave(&port->card->card_lock, flags);
1345 isicom_config_port(tty);
1346 spin_unlock_irqrestore(&port->card->card_lock, flags);
1347
1348 if ((old_termios->c_cflag & CRTSCTS) &&
1349 !(tty->termios->c_cflag & CRTSCTS)) {
1350 tty->hw_stopped = 0;
1351 isicom_start(tty);
1352 }
1353 }
1354
1355 /* throttle et all */
1356 static void isicom_throttle(struct tty_struct *tty)
1357 {
1358 struct isi_port *port = tty->driver_data;
1359 struct isi_board *card = port->card;
1360
1361 if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
1362 return;
1363
1364 /* tell the card that this port cannot handle any more data for now */
1365 card->port_status &= ~(1 << port->channel);
1366 outw(card->port_status, card->base + 0x02);
1367 }
1368
1369 /* unthrottle et all */
1370 static void isicom_unthrottle(struct tty_struct *tty)
1371 {
1372 struct isi_port *port = tty->driver_data;
1373 struct isi_board *card = port->card;
1374
1375 if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
1376 return;
1377
1378 /* tell the card that this port is ready to accept more data */
1379 card->port_status |= (1 << port->channel);
1380 outw(card->port_status, card->base + 0x02);
1381 }
1382
1383 /* stop et all */
1384 static void isicom_stop(struct tty_struct *tty)
1385 {
1386 struct isi_port *port = tty->driver_data;
1387
1388 if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
1389 return;
1390
1391 /* this tells the transmitter not to consider this port for
1392 data output to the card. */
1393 port->status &= ~ISI_TXOK;
1394 }
1395
1396 /* start et all */
1397 static void isicom_start(struct tty_struct *tty)
1398 {
1399 struct isi_port *port = tty->driver_data;
1400
1401 if (isicom_paranoia_check(port, tty->name, "isicom_start"))
1402 return;
1403
1404 /* this tells the transmitter to consider this port for
1405 data output to the card. */
1406 port->status |= ISI_TXOK;
1407 }
1408
1409 static void isicom_hangup(struct tty_struct *tty)
1410 {
1411 struct isi_port *port = tty->driver_data;
1412 unsigned long flags;
1413
1414 if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
1415 return;
1416
1417 spin_lock_irqsave(&port->card->card_lock, flags);
1418 isicom_shutdown_port(port);
1419 spin_unlock_irqrestore(&port->card->card_lock, flags);
1420
1421 port->port.count = 0;
1422 port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1423 tty_port_tty_set(&port->port, NULL);
1424 wake_up_interruptible(&port->port.open_wait);
1425 }
1426
1427
1428 /*
1429 * Driver init and deinit functions
1430 */
1431
1432 static const struct tty_operations isicom_ops = {
1433 .open = isicom_open,
1434 .close = isicom_close,
1435 .write = isicom_write,
1436 .put_char = isicom_put_char,
1437 .flush_chars = isicom_flush_chars,
1438 .write_room = isicom_write_room,
1439 .chars_in_buffer = isicom_chars_in_buffer,
1440 .ioctl = isicom_ioctl,
1441 .set_termios = isicom_set_termios,
1442 .throttle = isicom_throttle,
1443 .unthrottle = isicom_unthrottle,
1444 .stop = isicom_stop,
1445 .start = isicom_start,
1446 .hangup = isicom_hangup,
1447 .flush_buffer = isicom_flush_buffer,
1448 .tiocmget = isicom_tiocmget,
1449 .tiocmset = isicom_tiocmset,
1450 .break_ctl = isicom_send_break,
1451 };
1452
1453 static int __devinit reset_card(struct pci_dev *pdev,
1454 const unsigned int card, unsigned int *signature)
1455 {
1456 struct isi_board *board = pci_get_drvdata(pdev);
1457 unsigned long base = board->base;
1458 unsigned int sig, portcount = 0;
1459 int retval = 0;
1460
1461 dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
1462 base);
1463
1464 inw(base + 0x8);
1465
1466 msleep(10);
1467
1468 outw(0, base + 0x8); /* Reset */
1469
1470 msleep(1000);
1471
1472 sig = inw(base + 0x4) & 0xff;
1473
1474 if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd &&
1475 sig != 0xee) {
1476 dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible "
1477 "bad I/O Port Address 0x%lx).\n", card + 1, base);
1478 dev_dbg(&pdev->dev, "Sig=0x%x\n", sig);
1479 retval = -EIO;
1480 goto end;
1481 }
1482
1483 msleep(10);
1484
1485 portcount = inw(base + 0x2);
1486 if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 &&
1487 portcount != 8 && portcount != 16)) {
1488 dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
1489 card + 1);
1490 retval = -EIO;
1491 goto end;
1492 }
1493
1494 switch (sig) {
1495 case 0xa5:
1496 case 0xbb:
1497 case 0xdd:
1498 board->port_count = (portcount == 4) ? 4 : 8;
1499 board->shift_count = 12;
1500 break;
1501 case 0xcc:
1502 case 0xee:
1503 board->port_count = 16;
1504 board->shift_count = 11;
1505 break;
1506 }
1507 dev_info(&pdev->dev, "-Done\n");
1508 *signature = sig;
1509
1510 end:
1511 return retval;
1512 }
1513
1514 static int __devinit load_firmware(struct pci_dev *pdev,
1515 const unsigned int index, const unsigned int signature)
1516 {
1517 struct isi_board *board = pci_get_drvdata(pdev);
1518 const struct firmware *fw;
1519 unsigned long base = board->base;
1520 unsigned int a;
1521 u16 word_count, status;
1522 int retval = -EIO;
1523 char *name;
1524 u8 *data;
1525
1526 struct stframe {
1527 u16 addr;
1528 u16 count;
1529 u8 data[0];
1530 } *frame;
1531
1532 switch (signature) {
1533 case 0xa5:
1534 name = "isi608.bin";
1535 break;
1536 case 0xbb:
1537 name = "isi608em.bin";
1538 break;
1539 case 0xcc:
1540 name = "isi616em.bin";
1541 break;
1542 case 0xdd:
1543 name = "isi4608.bin";
1544 break;
1545 case 0xee:
1546 name = "isi4616.bin";
1547 break;
1548 default:
1549 dev_err(&pdev->dev, "Unknown signature.\n");
1550 goto end;
1551 }
1552
1553 retval = request_firmware(&fw, name, &pdev->dev);
1554 if (retval)
1555 goto end;
1556
1557 retval = -EIO;
1558
1559 for (frame = (struct stframe *)fw->data;
1560 frame < (struct stframe *)(fw->data + fw->size);
1561 frame = (struct stframe *)((u8 *)(frame + 1) +
1562 frame->count)) {
1563 if (WaitTillCardIsFree(base))
1564 goto errrelfw;
1565
1566 outw(0xf0, base); /* start upload sequence */
1567 outw(0x00, base);
1568 outw(frame->addr, base); /* lsb of address */
1569
1570 word_count = frame->count / 2 + frame->count % 2;
1571 outw(word_count, base);
1572 InterruptTheCard(base);
1573
1574 udelay(100); /* 0x2f */
1575
1576 if (WaitTillCardIsFree(base))
1577 goto errrelfw;
1578
1579 status = inw(base + 0x4);
1580 if (status != 0) {
1581 dev_warn(&pdev->dev, "Card%d rejected load header:\n"
1582 KERN_WARNING "Address:0x%x\n"
1583 KERN_WARNING "Count:0x%x\n"
1584 KERN_WARNING "Status:0x%x\n",
1585 index + 1, frame->addr, frame->count, status);
1586 goto errrelfw;
1587 }
1588 outsw(base, frame->data, word_count);
1589
1590 InterruptTheCard(base);
1591
1592 udelay(50); /* 0x0f */
1593
1594 if (WaitTillCardIsFree(base))
1595 goto errrelfw;
1596
1597 status = inw(base + 0x4);
1598 if (status != 0) {
1599 dev_err(&pdev->dev, "Card%d got out of sync.Card "
1600 "Status:0x%x\n", index + 1, status);
1601 goto errrelfw;
1602 }
1603 }
1604
1605 /* XXX: should we test it by reading it back and comparing with original like
1606 * in load firmware package? */
1607 for (frame = (struct stframe *)fw->data;
1608 frame < (struct stframe *)(fw->data + fw->size);
1609 frame = (struct stframe *)((u8 *)(frame + 1) +
1610 frame->count)) {
1611 if (WaitTillCardIsFree(base))
1612 goto errrelfw;
1613
1614 outw(0xf1, base); /* start download sequence */
1615 outw(0x00, base);
1616 outw(frame->addr, base); /* lsb of address */
1617
1618 word_count = (frame->count >> 1) + frame->count % 2;
1619 outw(word_count + 1, base);
1620 InterruptTheCard(base);
1621
1622 udelay(50); /* 0xf */
1623
1624 if (WaitTillCardIsFree(base))
1625 goto errrelfw;
1626
1627 status = inw(base + 0x4);
1628 if (status != 0) {
1629 dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
1630 KERN_WARNING "Address:0x%x\n"
1631 KERN_WARNING "Count:0x%x\n"
1632 KERN_WARNING "Status: 0x%x\n",
1633 index + 1, frame->addr, frame->count, status);
1634 goto errrelfw;
1635 }
1636
1637 data = kmalloc(word_count * 2, GFP_KERNEL);
1638 if (data == NULL) {
1639 dev_err(&pdev->dev, "Card%d, firmware upload "
1640 "failed, not enough memory\n", index + 1);
1641 goto errrelfw;
1642 }
1643 inw(base);
1644 insw(base, data, word_count);
1645 InterruptTheCard(base);
1646
1647 for (a = 0; a < frame->count; a++)
1648 if (data[a] != frame->data[a]) {
1649 kfree(data);
1650 dev_err(&pdev->dev, "Card%d, firmware upload "
1651 "failed\n", index + 1);
1652 goto errrelfw;
1653 }
1654 kfree(data);
1655
1656 udelay(50); /* 0xf */
1657
1658 if (WaitTillCardIsFree(base))
1659 goto errrelfw;
1660
1661 status = inw(base + 0x4);
1662 if (status != 0) {
1663 dev_err(&pdev->dev, "Card%d verify got out of sync. "
1664 "Card Status:0x%x\n", index + 1, status);
1665 goto errrelfw;
1666 }
1667 }
1668
1669 /* xfer ctrl */
1670 if (WaitTillCardIsFree(base))
1671 goto errrelfw;
1672
1673 outw(0xf2, base);
1674 outw(0x800, base);
1675 outw(0x0, base);
1676 outw(0x0, base);
1677 InterruptTheCard(base);
1678 outw(0x0, base + 0x4); /* for ISI4608 cards */
1679
1680 board->status |= FIRMWARE_LOADED;
1681 retval = 0;
1682
1683 errrelfw:
1684 release_firmware(fw);
1685 end:
1686 return retval;
1687 }
1688
1689 /*
1690 * Insmod can set static symbols so keep these static
1691 */
1692 static unsigned int card_count;
1693
1694 static int __devinit isicom_probe(struct pci_dev *pdev,
1695 const struct pci_device_id *ent)
1696 {
1697 unsigned int signature, index;
1698 int retval = -EPERM;
1699 struct isi_board *board = NULL;
1700
1701 if (card_count >= BOARD_COUNT)
1702 goto err;
1703
1704 retval = pci_enable_device(pdev);
1705 if (retval) {
1706 dev_err(&pdev->dev, "failed to enable\n");
1707 goto err;
1708 }
1709
1710 dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
1711
1712 /* allot the first empty slot in the array */
1713 for (index = 0; index < BOARD_COUNT; index++)
1714 if (isi_card[index].base == 0) {
1715 board = &isi_card[index];
1716 break;
1717 }
1718
1719 board->index = index;
1720 board->base = pci_resource_start(pdev, 3);
1721 board->irq = pdev->irq;
1722 card_count++;
1723
1724 pci_set_drvdata(pdev, board);
1725
1726 retval = pci_request_region(pdev, 3, ISICOM_NAME);
1727 if (retval) {
1728 dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
1729 "will be disabled.\n", board->base, board->base + 15,
1730 index + 1);
1731 retval = -EBUSY;
1732 goto errdec;
1733 }
1734
1735 retval = request_irq(board->irq, isicom_interrupt,
1736 IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
1737 if (retval < 0) {
1738 dev_err(&pdev->dev, "Could not install handler at Irq %d. "
1739 "Card%d will be disabled.\n", board->irq, index + 1);
1740 goto errunrr;
1741 }
1742
1743 retval = reset_card(pdev, index, &signature);
1744 if (retval < 0)
1745 goto errunri;
1746
1747 retval = load_firmware(pdev, index, signature);
1748 if (retval < 0)
1749 goto errunri;
1750
1751 for (index = 0; index < board->port_count; index++)
1752 tty_register_device(isicom_normal, board->index * 16 + index,
1753 &pdev->dev);
1754
1755 return 0;
1756
1757 errunri:
1758 free_irq(board->irq, board);
1759 errunrr:
1760 pci_release_region(pdev, 3);
1761 errdec:
1762 board->base = 0;
1763 card_count--;
1764 pci_disable_device(pdev);
1765 err:
1766 return retval;
1767 }
1768
1769 static void __devexit isicom_remove(struct pci_dev *pdev)
1770 {
1771 struct isi_board *board = pci_get_drvdata(pdev);
1772 unsigned int i;
1773
1774 for (i = 0; i < board->port_count; i++)
1775 tty_unregister_device(isicom_normal, board->index * 16 + i);
1776
1777 free_irq(board->irq, board);
1778 pci_release_region(pdev, 3);
1779 board->base = 0;
1780 card_count--;
1781 pci_disable_device(pdev);
1782 }
1783
1784 static int __init isicom_init(void)
1785 {
1786 int retval, idx, channel;
1787 struct isi_port *port;
1788
1789 for (idx = 0; idx < BOARD_COUNT; idx++) {
1790 port = &isi_ports[idx * 16];
1791 isi_card[idx].ports = port;
1792 spin_lock_init(&isi_card[idx].card_lock);
1793 for (channel = 0; channel < 16; channel++, port++) {
1794 tty_port_init(&port->port);
1795 port->magic = ISICOM_MAGIC;
1796 port->card = &isi_card[idx];
1797 port->channel = channel;
1798 port->port.close_delay = 50 * HZ/100;
1799 port->port.closing_wait = 3000 * HZ/100;
1800 port->status = 0;
1801 /* . . . */
1802 }
1803 isi_card[idx].base = 0;
1804 isi_card[idx].irq = 0;
1805 }
1806
1807 /* tty driver structure initialization */
1808 isicom_normal = alloc_tty_driver(PORT_COUNT);
1809 if (!isicom_normal) {
1810 retval = -ENOMEM;
1811 goto error;
1812 }
1813
1814 isicom_normal->owner = THIS_MODULE;
1815 isicom_normal->name = "ttyM";
1816 isicom_normal->major = ISICOM_NMAJOR;
1817 isicom_normal->minor_start = 0;
1818 isicom_normal->type = TTY_DRIVER_TYPE_SERIAL;
1819 isicom_normal->subtype = SERIAL_TYPE_NORMAL;
1820 isicom_normal->init_termios = tty_std_termios;
1821 isicom_normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
1822 CLOCAL;
1823 isicom_normal->flags = TTY_DRIVER_REAL_RAW |
1824 TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK;
1825 tty_set_operations(isicom_normal, &isicom_ops);
1826
1827 retval = tty_register_driver(isicom_normal);
1828 if (retval) {
1829 pr_dbg("Couldn't register the dialin driver\n");
1830 goto err_puttty;
1831 }
1832
1833 retval = pci_register_driver(&isicom_driver);
1834 if (retval < 0) {
1835 printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
1836 goto err_unrtty;
1837 }
1838
1839 mod_timer(&tx, jiffies + 1);
1840
1841 return 0;
1842 err_unrtty:
1843 tty_unregister_driver(isicom_normal);
1844 err_puttty:
1845 put_tty_driver(isicom_normal);
1846 error:
1847 return retval;
1848 }
1849
1850 static void __exit isicom_exit(void)
1851 {
1852 del_timer_sync(&tx);
1853
1854 pci_unregister_driver(&isicom_driver);
1855 tty_unregister_driver(isicom_normal);
1856 put_tty_driver(isicom_normal);
1857 }
1858
1859 module_init(isicom_init);
1860 module_exit(isicom_exit);
1861
1862 MODULE_AUTHOR("MultiTech");
1863 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
1864 MODULE_LICENSE("GPL");
This page took 0.088526 seconds and 5 git commands to generate.