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