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