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