[PATCH] clean up computone remaining cli use
[linux-2.6/kmemtrace.git] / drivers / char / isicom.c
blob86033bed5d6c7e9d062bab442605aedd338a33ab
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.
7 * Original driver code supplied by Multi-Tech
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
17 * 10/6/99 sameer Merged the ISA and PCI drivers to
18 * a new unified driver.
20 * 3/9/99 sameer Added support for ISI4616 cards.
22 * 16/9/99 sameer We do not force RTS low anymore.
23 * This is to prevent the firmware
24 * from getting confused.
26 * 26/10/99 sameer Cosmetic changes:The driver now
27 * dumps the Port Count information
28 * along with I/O address and IRQ.
30 * 13/12/99 sameer Fixed the problem with IRQ sharing.
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.
37 * 10/5/00 sameer Signal mask setup command added
38 * to isicom_setup_port and
39 * isicom_shutdown_port.
41 * 24/5/00 sameer The driver is now SMP aware.
44 * 27/11/00 Vinayak P Risbud Fixed the Driver Crash Problem
47 * 03/01/01 anil .s Added support for resetting the
48 * internal modems on ISI cards.
50 * 08/02/01 anil .s Upgraded the driver for kernel
51 * 2.4.x
53 * 11/04/01 Kevin Fixed firmware load problem with
54 * ISIHP-4X card
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.
61 * 03/05/01 anil .s Fixed the problem with IRQ sharing
62 * among ISI-PCI cards.
64 * 03/05/01 anil .s Added support to display the version
65 * info during insmod as well as module
66 * listing by lsmod.
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.
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.
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
82 * 11/02/03 ranjeeth Added support for 230 Kbps and 460 Kbps
83 * Baud index extended to 21
85 * 20/03/03 ranjeeth Made to work for Linux Advanced server.
86 * Taken care of license warning.
88 * 10/12/03 Ravindra Made to work for Fedora Core 1 of
89 * Red Hat Distribution
91 * 06/01/05 Alan Cox Merged the ISI and base kernel strands
92 * into a single 2.6 driver
94 * ***********************************************************
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
100 * You can find the original tools for this direct from Multitech
101 * ftp://ftp.multitech.com/ISI-Cards/
103 * Having installed the cards the module options (/etc/modprobe.conf)
105 * options isicom io=card1,card2,card3,card4 irq=card1,card2,card3,card4
107 * Omit those entries for boards you don't have installed.
109 * TODO
110 * Hotplug
111 * Merge testing
112 * 64-bit verification
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>
130 #include <asm/uaccess.h>
131 #include <asm/io.h>
132 #include <asm/system.h>
134 #include <linux/pci.h>
136 #include <linux/isicom.h>
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 }
150 MODULE_DEVICE_TABLE(pci, isicom_pci_tbl);
152 static int prev_card = 3; /* start servicing isi_card[0] */
153 static struct tty_driver *isicom_normal;
155 static struct timer_list tx;
156 static char re_schedule = 1;
157 #ifdef ISICOM_DEBUG
158 static unsigned long tx_count = 0;
159 #endif
161 static int ISILoad_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
163 static void isicom_tx(unsigned long _data);
164 static void isicom_start(struct tty_struct * tty);
166 static unsigned char * tmp_buf;
167 static DECLARE_MUTEX(tmp_buf_sem);
169 /* baud index mappings from linux defns to isi */
171 static signed char linuxb_to_isib[] = {
172 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17,
173 18, 19
176 struct isi_board {
177 unsigned short base;
178 unsigned char irq;
179 unsigned char port_count;
180 unsigned short status;
181 unsigned short port_status; /* each bit represents a single port */
182 unsigned short shift_count;
183 struct isi_port * ports;
184 signed char count;
185 unsigned char isa;
186 spinlock_t card_lock; /* Card wide lock 11/5/00 -sameer */
187 unsigned long flags;
190 struct isi_port {
191 unsigned short magic;
192 unsigned int flags;
193 int count;
194 int blocked_open;
195 int close_delay;
196 unsigned short channel;
197 unsigned short status;
198 unsigned short closing_wait;
199 struct isi_board * card;
200 struct tty_struct * tty;
201 wait_queue_head_t close_wait;
202 wait_queue_head_t open_wait;
203 struct work_struct hangup_tq;
204 struct work_struct bh_tqueue;
205 unsigned char * xmit_buf;
206 int xmit_head;
207 int xmit_tail;
208 int xmit_cnt;
211 static struct isi_board isi_card[BOARD_COUNT];
212 static struct isi_port isi_ports[PORT_COUNT];
215 * Locking functions for card level locking. We need to own both
216 * the kernel lock for the card and have the card in a position that
217 * it wants to talk.
220 static int lock_card(struct isi_board *card)
222 char retries;
223 unsigned short base = card->base;
225 for (retries = 0; retries < 100; retries++) {
226 spin_lock_irqsave(&card->card_lock, card->flags);
227 if (inw(base + 0xe) & 0x1) {
228 return 1;
229 } else {
230 spin_unlock_irqrestore(&card->card_lock, card->flags);
231 udelay(1000); /* 1ms */
234 printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%x)\n", card->base);
235 return 0; /* Failed to aquire the card! */
238 static int lock_card_at_interrupt(struct isi_board *card)
240 unsigned char retries;
241 unsigned short base = card->base;
243 for (retries = 0; retries < 200; retries++) {
244 spin_lock_irqsave(&card->card_lock, card->flags);
246 if (inw(base + 0xe) & 0x1)
247 return 1;
248 else
249 spin_unlock_irqrestore(&card->card_lock, card->flags);
251 /* Failing in interrupt is an acceptable event */
252 return 0; /* Failed to aquire the card! */
255 static void unlock_card(struct isi_board *card)
257 spin_unlock_irqrestore(&card->card_lock, card->flags);
261 * ISI Card specific ops ...
264 static void raise_dtr(struct isi_port * port)
266 struct isi_board * card = port->card;
267 unsigned short base = card->base;
268 unsigned char channel = port->channel;
270 if (!lock_card(card))
271 return;
273 outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
274 outw(0x0504, base);
275 InterruptTheCard(base);
276 port->status |= ISI_DTR;
277 unlock_card(card);
280 static inline void drop_dtr(struct isi_port * port)
282 struct isi_board * card = port->card;
283 unsigned short base = card->base;
284 unsigned char channel = port->channel;
286 if (!lock_card(card))
287 return;
289 outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
290 outw(0x0404, base);
291 InterruptTheCard(base);
292 port->status &= ~ISI_DTR;
293 unlock_card(card);
296 static inline void raise_rts(struct isi_port * port)
298 struct isi_board * card = port->card;
299 unsigned short base = card->base;
300 unsigned char channel = port->channel;
302 if (!lock_card(card))
303 return;
305 outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
306 outw(0x0a04, base);
307 InterruptTheCard(base);
308 port->status |= ISI_RTS;
309 unlock_card(card);
311 static inline void drop_rts(struct isi_port * port)
313 struct isi_board * card = port->card;
314 unsigned short base = card->base;
315 unsigned char channel = port->channel;
317 if (!lock_card(card))
318 return;
320 outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
321 outw(0x0804, base);
322 InterruptTheCard(base);
323 port->status &= ~ISI_RTS;
324 unlock_card(card);
327 static inline void raise_dtr_rts(struct isi_port * port)
329 struct isi_board * card = port->card;
330 unsigned short base = card->base;
331 unsigned char channel = port->channel;
333 if (!lock_card(card))
334 return;
336 outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
337 outw(0x0f04, base);
338 InterruptTheCard(base);
339 port->status |= (ISI_DTR | ISI_RTS);
340 unlock_card(card);
343 static void drop_dtr_rts(struct isi_port * port)
345 struct isi_board * card = port->card;
346 unsigned short base = card->base;
347 unsigned char channel = port->channel;
349 if (!lock_card(card))
350 return;
352 outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
353 outw(0x0c04, base);
354 InterruptTheCard(base);
355 port->status &= ~(ISI_RTS | ISI_DTR);
356 unlock_card(card);
359 static inline void kill_queue(struct isi_port * port, short queue)
361 struct isi_board * card = port->card;
362 unsigned short base = card->base;
363 unsigned char channel = port->channel;
365 if (!lock_card(card))
366 return;
368 outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
369 outw((queue << 8) | 0x06, base);
370 InterruptTheCard(base);
371 unlock_card(card);
376 * Firmware loader driver specific routines. This needs to mostly die
377 * and be replaced with request_firmware.
380 static struct file_operations ISILoad_fops = {
381 .owner = THIS_MODULE,
382 .ioctl = ISILoad_ioctl,
385 static struct miscdevice isiloader_device = {
386 ISILOAD_MISC_MINOR, "isictl", &ISILoad_fops
390 static inline int WaitTillCardIsFree(unsigned short base)
392 unsigned long count=0;
393 while( (!(inw(base+0xe) & 0x1)) && (count++ < 6000000));
394 if (inw(base+0xe)&0x1)
395 return 0;
396 else
397 return 1;
400 static int ISILoad_ioctl(struct inode *inode, struct file *filp,
401 unsigned int cmd, unsigned long arg)
403 unsigned int card, i, j, signature, status, portcount = 0;
404 unsigned long t;
405 unsigned short word_count, base;
406 bin_frame frame;
407 void __user *argp = (void __user *)arg;
408 /* exec_record exec_rec; */
410 if(get_user(card, (int __user *)argp))
411 return -EFAULT;
413 if(card < 0 || card >= BOARD_COUNT)
414 return -ENXIO;
416 base=isi_card[card].base;
418 if(base==0)
419 return -ENXIO; /* disabled or not used */
421 switch(cmd) {
422 case MIOCTL_RESET_CARD:
423 if (!capable(CAP_SYS_ADMIN))
424 return -EPERM;
425 printk(KERN_DEBUG "ISILoad:Resetting Card%d at 0x%x ",card+1,base);
427 inw(base+0x8);
429 for(t=jiffies+HZ/100;time_before(jiffies, t););
431 outw(0,base+0x8); /* Reset */
433 for(j=1;j<=3;j++) {
434 for(t=jiffies+HZ;time_before(jiffies, t););
435 printk(".");
437 signature=(inw(base+0x4)) & 0xff;
438 if (isi_card[card].isa) {
440 if (!(inw(base+0xe) & 0x1) || (inw(base+0x2))) {
441 #ifdef ISICOM_DEBUG
442 printk("\nbase+0x2=0x%x , base+0xe=0x%x",inw(base+0x2),inw(base+0xe));
443 #endif
444 printk("\nISILoad:ISA Card%d reset failure (Possible bad I/O Port Address 0x%x).\n",card+1,base);
445 return -EIO;
448 else {
449 portcount = inw(base+0x2);
450 if (!(inw(base+0xe) & 0x1) || ((portcount!=0) && (portcount!=4) && (portcount!=8))) {
451 #ifdef ISICOM_DEBUG
452 printk("\nbase+0x2=0x%x , base+0xe=0x%x",inw(base+0x2),inw(base+0xe));
453 #endif
454 printk("\nISILoad:PCI Card%d reset failure (Possible bad I/O Port Address 0x%x).\n",card+1,base);
455 return -EIO;
458 switch(signature) {
459 case 0xa5:
460 case 0xbb:
461 case 0xdd:
462 if (isi_card[card].isa)
463 isi_card[card].port_count = 8;
464 else {
465 if (portcount == 4)
466 isi_card[card].port_count = 4;
467 else
468 isi_card[card].port_count = 8;
470 isi_card[card].shift_count = 12;
471 break;
473 case 0xcc: isi_card[card].port_count = 16;
474 isi_card[card].shift_count = 11;
475 break;
477 default: printk("ISILoad:Card%d reset failure (Possible bad I/O Port Address 0x%x).\n",card+1,base);
478 #ifdef ISICOM_DEBUG
479 printk("Sig=0x%x\n",signature);
480 #endif
481 return -EIO;
483 printk("-Done\n");
484 return put_user(signature,(unsigned __user *)argp);
486 case MIOCTL_LOAD_FIRMWARE:
487 if (!capable(CAP_SYS_ADMIN))
488 return -EPERM;
490 if(copy_from_user(&frame, argp, sizeof(bin_frame)))
491 return -EFAULT;
493 if (WaitTillCardIsFree(base))
494 return -EIO;
496 outw(0xf0,base); /* start upload sequence */
497 outw(0x00,base);
498 outw((frame.addr), base);/* lsb of adderess */
500 word_count=(frame.count >> 1) + frame.count % 2;
501 outw(word_count, base);
502 InterruptTheCard(base);
504 for(i=0;i<=0x2f;i++); /* a wee bit of delay */
506 if (WaitTillCardIsFree(base))
507 return -EIO;
509 if ((status=inw(base+0x4))!=0) {
510 printk(KERN_WARNING "ISILoad:Card%d rejected load header:\nAddress:0x%x \nCount:0x%x \nStatus:0x%x \n",
511 card+1, frame.addr, frame.count, status);
512 return -EIO;
514 outsw(base, (void *) frame.bin_data, word_count);
516 InterruptTheCard(base);
518 for(i=0;i<=0x0f;i++); /* another wee bit of delay */
520 if (WaitTillCardIsFree(base))
521 return -EIO;
523 if ((status=inw(base+0x4))!=0) {
524 printk(KERN_ERR "ISILoad:Card%d got out of sync.Card Status:0x%x\n",card+1, status);
525 return -EIO;
527 return 0;
529 case MIOCTL_READ_FIRMWARE:
530 if (!capable(CAP_SYS_ADMIN))
531 return -EPERM;
533 if(copy_from_user(&frame, argp, sizeof(bin_header)))
534 return -EFAULT;
536 if (WaitTillCardIsFree(base))
537 return -EIO;
539 outw(0xf1,base); /* start download sequence */
540 outw(0x00,base);
541 outw((frame.addr), base);/* lsb of adderess */
543 word_count=(frame.count >> 1) + frame.count % 2;
544 outw(word_count+1, base);
545 InterruptTheCard(base);
547 for(i=0;i<=0xf;i++); /* a wee bit of delay */
549 if (WaitTillCardIsFree(base))
550 return -EIO;
552 if ((status=inw(base+0x4))!=0) {
553 printk(KERN_WARNING "ISILoad:Card%d rejected verify header:\nAddress:0x%x \nCount:0x%x \nStatus:0x%x \n",
554 card+1, frame.addr, frame.count, status);
555 return -EIO;
558 inw(base);
559 insw(base, frame.bin_data, word_count);
560 InterruptTheCard(base);
562 for(i=0;i<=0x0f;i++); /* another wee bit of delay */
564 if (WaitTillCardIsFree(base))
565 return -EIO;
567 if ((status=inw(base+0x4))!=0) {
568 printk(KERN_ERR "ISILoad:Card%d verify got out of sync.Card Status:0x%x\n",card+1, status);
569 return -EIO;
572 if(copy_to_user(argp, &frame, sizeof(bin_frame)))
573 return -EFAULT;
574 return 0;
576 case MIOCTL_XFER_CTRL:
577 if (!capable(CAP_SYS_ADMIN))
578 return -EPERM;
579 if (WaitTillCardIsFree(base))
580 return -EIO;
582 outw(0xf2, base);
583 outw(0x800, base);
584 outw(0x0, base);
585 outw(0x0, base);
586 InterruptTheCard(base);
587 outw(0x0, base+0x4); /* for ISI4608 cards */
589 isi_card[card].status |= FIRMWARE_LOADED;
590 return 0;
592 default:
593 #ifdef ISICOM_DEBUG
594 printk(KERN_DEBUG "ISILoad: Received Ioctl cmd 0x%x.\n", cmd);
595 #endif
596 return -ENOIOCTLCMD;
604 * ISICOM Driver specific routines ...
608 static inline int isicom_paranoia_check(struct isi_port const * port, char *name,
609 const char * routine)
611 #ifdef ISICOM_DEBUG
612 static const char * badmagic =
613 KERN_WARNING "ISICOM: Warning: bad isicom magic for dev %s in %s.\n";
614 static const char * badport =
615 KERN_WARNING "ISICOM: Warning: NULL isicom port for dev %s in %s.\n";
616 if (!port) {
617 printk(badport, name, routine);
618 return 1;
620 if (port->magic != ISICOM_MAGIC) {
621 printk(badmagic, name, routine);
622 return 1;
624 #endif
625 return 0;
629 * Transmitter.
631 * We shovel data into the card buffers on a regular basis. The card
632 * will do the rest of the work for us.
635 static void isicom_tx(unsigned long _data)
637 short count = (BOARD_COUNT-1), card, base;
638 short txcount, wrd, residue, word_count, cnt;
639 struct isi_port * port;
640 struct tty_struct * tty;
642 #ifdef ISICOM_DEBUG
643 ++tx_count;
644 #endif
646 /* find next active board */
647 card = (prev_card + 1) & 0x0003;
648 while(count-- > 0) {
649 if (isi_card[card].status & BOARD_ACTIVE)
650 break;
651 card = (card + 1) & 0x0003;
653 if (!(isi_card[card].status & BOARD_ACTIVE))
654 goto sched_again;
656 prev_card = card;
658 count = isi_card[card].port_count;
659 port = isi_card[card].ports;
660 base = isi_card[card].base;
661 for (;count > 0;count--, port++) {
662 if (!lock_card_at_interrupt(&isi_card[card]))
663 continue;
664 /* port not active or tx disabled to force flow control */
665 if (!(port->flags & ASYNC_INITIALIZED) ||
666 !(port->status & ISI_TXOK))
667 unlock_card(&isi_card[card]);
668 continue;
670 tty = port->tty;
673 if(tty == NULL) {
674 unlock_card(&isi_card[card]);
675 continue;
678 txcount = min_t(short, TX_SIZE, port->xmit_cnt);
679 if (txcount <= 0 || tty->stopped || tty->hw_stopped) {
680 unlock_card(&isi_card[card]);
681 continue;
683 if (!(inw(base + 0x02) & (1 << port->channel))) {
684 unlock_card(&isi_card[card]);
685 continue;
687 #ifdef ISICOM_DEBUG
688 printk(KERN_DEBUG "ISICOM: txing %d bytes, port%d.\n",
689 txcount, port->channel+1);
690 #endif
691 outw((port->channel << isi_card[card].shift_count) | txcount
692 , base);
693 residue = NO;
694 wrd = 0;
695 while (1) {
696 cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE - port->xmit_tail));
697 if (residue == YES) {
698 residue = NO;
699 if (cnt > 0) {
700 wrd |= (port->xmit_buf[port->xmit_tail] << 8);
701 port->xmit_tail = (port->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
702 port->xmit_cnt--;
703 txcount--;
704 cnt--;
705 outw(wrd, base);
707 else {
708 outw(wrd, base);
709 break;
712 if (cnt <= 0) break;
713 word_count = cnt >> 1;
714 outsw(base, port->xmit_buf+port->xmit_tail, word_count);
715 port->xmit_tail = (port->xmit_tail + (word_count << 1)) &
716 (SERIAL_XMIT_SIZE - 1);
717 txcount -= (word_count << 1);
718 port->xmit_cnt -= (word_count << 1);
719 if (cnt & 0x0001) {
720 residue = YES;
721 wrd = port->xmit_buf[port->xmit_tail];
722 port->xmit_tail = (port->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
723 port->xmit_cnt--;
724 txcount--;
728 InterruptTheCard(base);
729 if (port->xmit_cnt <= 0)
730 port->status &= ~ISI_TXOK;
731 if (port->xmit_cnt <= WAKEUP_CHARS)
732 schedule_work(&port->bh_tqueue);
733 unlock_card(&isi_card[card]);
736 /* schedule another tx for hopefully in about 10ms */
737 sched_again:
738 if (!re_schedule)
739 return;
740 init_timer(&tx);
741 tx.expires = jiffies + HZ/100;
742 tx.data = 0;
743 tx.function = isicom_tx;
744 add_timer(&tx);
746 return;
749 /* Interrupt handlers */
752 static void isicom_bottomhalf(void * data)
754 struct isi_port * port = (struct isi_port *) data;
755 struct tty_struct * tty = port->tty;
757 if (!tty)
758 return;
760 tty_wakeup(tty);
761 wake_up_interruptible(&tty->write_wait);
765 * Main interrupt handler routine
768 static irqreturn_t isicom_interrupt(int irq, void *dev_id,
769 struct pt_regs *regs)
771 struct isi_board * card;
772 struct isi_port * port;
773 struct tty_struct * tty;
774 unsigned short base, header, word_count, count;
775 unsigned char channel;
776 short byte_count;
777 unsigned char *rp;
779 card = (struct isi_board *) dev_id;
781 if (!card || !(card->status & FIRMWARE_LOADED))
782 return IRQ_NONE;
784 base = card->base;
785 spin_lock(&card->card_lock);
787 if (card->isa == NO) {
789 * disable any interrupts from the PCI card and lower the
790 * interrupt line
792 outw(0x8000, base+0x04);
793 ClearInterrupt(base);
796 inw(base); /* get the dummy word out */
797 header = inw(base);
798 channel = (header & 0x7800) >> card->shift_count;
799 byte_count = header & 0xff;
801 if (channel + 1 > card->port_count) {
802 printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%x): %d(channel) > port_count.\n",
803 base, channel+1);
804 if (card->isa)
805 ClearInterrupt(base);
806 else
807 outw(0x0000, base+0x04); /* enable interrupts */
808 spin_unlock(&card->card_lock);
809 return IRQ_HANDLED;
811 port = card->ports + channel;
812 if (!(port->flags & ASYNC_INITIALIZED)) {
813 if (card->isa)
814 ClearInterrupt(base);
815 else
816 outw(0x0000, base+0x04); /* enable interrupts */
817 return IRQ_HANDLED;
820 tty = port->tty;
821 if (tty == NULL) {
822 word_count = byte_count >> 1;
823 while(byte_count > 1) {
824 inw(base);
825 byte_count -= 2;
827 if (byte_count & 0x01)
828 inw(base);
829 if (card->isa == YES)
830 ClearInterrupt(base);
831 else
832 outw(0x0000, base+0x04); /* enable interrupts */
833 spin_unlock(&card->card_lock);
834 return IRQ_HANDLED;
837 if (header & 0x8000) { /* Status Packet */
838 header = inw(base);
839 switch(header & 0xff) {
840 case 0: /* Change in EIA signals */
842 if (port->flags & ASYNC_CHECK_CD) {
843 if (port->status & ISI_DCD) {
844 if (!(header & ISI_DCD)) {
845 /* Carrier has been lost */
846 #ifdef ISICOM_DEBUG
847 printk(KERN_DEBUG "ISICOM: interrupt: DCD->low.\n");
848 #endif
849 port->status &= ~ISI_DCD;
850 schedule_work(&port->hangup_tq);
853 else {
854 if (header & ISI_DCD) {
855 /* Carrier has been detected */
856 #ifdef ISICOM_DEBUG
857 printk(KERN_DEBUG "ISICOM: interrupt: DCD->high.\n");
858 #endif
859 port->status |= ISI_DCD;
860 wake_up_interruptible(&port->open_wait);
864 else {
865 if (header & ISI_DCD)
866 port->status |= ISI_DCD;
867 else
868 port->status &= ~ISI_DCD;
871 if (port->flags & ASYNC_CTS_FLOW) {
872 if (port->tty->hw_stopped) {
873 if (header & ISI_CTS) {
874 port->tty->hw_stopped = 0;
875 /* start tx ing */
876 port->status |= (ISI_TXOK | ISI_CTS);
877 schedule_work(&port->bh_tqueue);
880 else {
881 if (!(header & ISI_CTS)) {
882 port->tty->hw_stopped = 1;
883 /* stop tx ing */
884 port->status &= ~(ISI_TXOK | ISI_CTS);
888 else {
889 if (header & ISI_CTS)
890 port->status |= ISI_CTS;
891 else
892 port->status &= ~ISI_CTS;
895 if (header & ISI_DSR)
896 port->status |= ISI_DSR;
897 else
898 port->status &= ~ISI_DSR;
900 if (header & ISI_RI)
901 port->status |= ISI_RI;
902 else
903 port->status &= ~ISI_RI;
905 break;
907 case 1: /* Received Break !!! */
908 tty_insert_flip_char(tty, 0, TTY_BREAK);
909 if (port->flags & ASYNC_SAK)
910 do_SAK(tty);
911 tty_flip_buffer_push(tty);
912 break;
914 case 2: /* Statistics */
915 printk(KERN_DEBUG "ISICOM: isicom_interrupt: stats!!!.\n");
916 break;
918 default:
919 printk(KERN_WARNING "ISICOM: Intr: Unknown code in status packet.\n");
920 break;
923 else { /* Data Packet */
925 count = tty_prepare_flip_string(tty, &rp, byte_count & ~1);
926 #ifdef ISICOM_DEBUG
927 printk(KERN_DEBUG "ISICOM: Intr: Can rx %d of %d bytes.\n",
928 count, byte_count);
929 #endif
930 word_count = count >> 1;
931 insw(base, rp, word_count);
932 byte_count -= (word_count << 1);
933 if (count & 0x0001) {
934 tty_insert_flip_char(tty, inw(base) & 0xff, TTY_NORMAL);
935 byte_count -= 2;
937 if (byte_count > 0) {
938 printk(KERN_DEBUG "ISICOM: Intr(0x%x:%d): Flip buffer overflow! dropping bytes...\n",
939 base, channel+1);
940 while(byte_count > 0) { /* drain out unread xtra data */
941 inw(base);
942 byte_count -= 2;
945 tty_flip_buffer_push(tty);
947 if (card->isa == YES)
948 ClearInterrupt(base);
949 else
950 outw(0x0000, base+0x04); /* enable interrupts */
951 return IRQ_HANDLED;
954 static void isicom_config_port(struct isi_port * port)
956 struct isi_board * card = port->card;
957 struct tty_struct * tty;
958 unsigned long baud;
959 unsigned short channel_setup, base = card->base;
960 unsigned short channel = port->channel, shift_count = card->shift_count;
961 unsigned char flow_ctrl;
963 if (!(tty = port->tty) || !tty->termios)
964 return;
965 baud = C_BAUD(tty);
966 if (baud & CBAUDEX) {
967 baud &= ~CBAUDEX;
969 /* if CBAUDEX bit is on and the baud is set to either 50 or 75
970 * then the card is programmed for 57.6Kbps or 115Kbps
971 * respectively.
974 if (baud < 1 || baud > 2)
975 port->tty->termios->c_cflag &= ~CBAUDEX;
976 else
977 baud += 15;
979 if (baud == 15) {
981 /* the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set
982 * by the set_serial_info ioctl ... this is done by
983 * the 'setserial' utility.
986 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
987 baud++; /* 57.6 Kbps */
988 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
989 baud +=2; /* 115 Kbps */
991 if (linuxb_to_isib[baud] == -1) {
992 /* hang up */
993 drop_dtr(port);
994 return;
996 else
997 raise_dtr(port);
999 if (lock_card(card)) {
1000 outw(0x8000 | (channel << shift_count) |0x03, base);
1001 outw(linuxb_to_isib[baud] << 8 | 0x03, base);
1002 channel_setup = 0;
1003 switch(C_CSIZE(tty)) {
1004 case CS5:
1005 channel_setup |= ISICOM_CS5;
1006 break;
1007 case CS6:
1008 channel_setup |= ISICOM_CS6;
1009 break;
1010 case CS7:
1011 channel_setup |= ISICOM_CS7;
1012 break;
1013 case CS8:
1014 channel_setup |= ISICOM_CS8;
1015 break;
1018 if (C_CSTOPB(tty))
1019 channel_setup |= ISICOM_2SB;
1020 if (C_PARENB(tty)) {
1021 channel_setup |= ISICOM_EVPAR;
1022 if (C_PARODD(tty))
1023 channel_setup |= ISICOM_ODPAR;
1025 outw(channel_setup, base);
1026 InterruptTheCard(base);
1027 unlock_card(card);
1029 if (C_CLOCAL(tty))
1030 port->flags &= ~ASYNC_CHECK_CD;
1031 else
1032 port->flags |= ASYNC_CHECK_CD;
1034 /* flow control settings ...*/
1035 flow_ctrl = 0;
1036 port->flags &= ~ASYNC_CTS_FLOW;
1037 if (C_CRTSCTS(tty)) {
1038 port->flags |= ASYNC_CTS_FLOW;
1039 flow_ctrl |= ISICOM_CTSRTS;
1041 if (I_IXON(tty))
1042 flow_ctrl |= ISICOM_RESPOND_XONXOFF;
1043 if (I_IXOFF(tty))
1044 flow_ctrl |= ISICOM_INITIATE_XONXOFF;
1046 if (lock_card(card)) {
1047 outw(0x8000 | (channel << shift_count) |0x04, base);
1048 outw(flow_ctrl << 8 | 0x05, base);
1049 outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
1050 InterruptTheCard(base);
1051 unlock_card(card);
1054 /* rx enabled -> enable port for rx on the card */
1055 if (C_CREAD(tty)) {
1056 card->port_status |= (1 << channel);
1057 outw(card->port_status, base + 0x02);
1061 /* open et all */
1063 static inline void isicom_setup_board(struct isi_board * bp)
1065 int channel;
1066 struct isi_port * port;
1067 unsigned long flags;
1069 spin_lock_irqsave(&bp->card_lock, flags);
1070 if (bp->status & BOARD_ACTIVE) {
1071 spin_unlock_irqrestore(&bp->card_lock, flags);
1072 return;
1074 port = bp->ports;
1075 bp->status |= BOARD_ACTIVE;
1076 spin_unlock_irqrestore(&bp->card_lock, flags);
1077 for(channel = 0; channel < bp->port_count; channel++, port++)
1078 drop_dtr_rts(port);
1079 return;
1082 static int isicom_setup_port(struct isi_port * port)
1084 struct isi_board * card = port->card;
1085 unsigned long flags;
1087 if (port->flags & ASYNC_INITIALIZED) {
1088 return 0;
1090 if (!port->xmit_buf) {
1091 unsigned long page;
1093 if (!(page = get_zeroed_page(GFP_KERNEL)))
1094 return -ENOMEM;
1096 if (port->xmit_buf) {
1097 free_page(page);
1098 return -ERESTARTSYS;
1100 port->xmit_buf = (unsigned char *) page;
1103 spin_lock_irqsave(&card->card_lock, flags);
1104 if (port->tty)
1105 clear_bit(TTY_IO_ERROR, &port->tty->flags);
1106 if (port->count == 1)
1107 card->count++;
1109 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1111 /* discard any residual data */
1112 kill_queue(port, ISICOM_KILLTX | ISICOM_KILLRX);
1114 isicom_config_port(port);
1115 port->flags |= ASYNC_INITIALIZED;
1116 spin_unlock_irqrestore(&card->card_lock, flags);
1118 return 0;
1121 static int block_til_ready(struct tty_struct * tty, struct file * filp, struct isi_port * port)
1123 struct isi_board * card = port->card;
1124 int do_clocal = 0, retval;
1125 unsigned long flags;
1126 DECLARE_WAITQUEUE(wait, current);
1128 /* block if port is in the process of being closed */
1130 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
1131 #ifdef ISICOM_DEBUG
1132 printk(KERN_DEBUG "ISICOM: block_til_ready: close in progress.\n");
1133 #endif
1134 interruptible_sleep_on(&port->close_wait);
1135 if (port->flags & ASYNC_HUP_NOTIFY)
1136 return -EAGAIN;
1137 else
1138 return -ERESTARTSYS;
1141 /* if non-blocking mode is set ... */
1143 if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
1144 #ifdef ISICOM_DEBUG
1145 printk(KERN_DEBUG "ISICOM: block_til_ready: non-block mode.\n");
1146 #endif
1147 port->flags |= ASYNC_NORMAL_ACTIVE;
1148 return 0;
1151 if (C_CLOCAL(tty))
1152 do_clocal = 1;
1154 /* block waiting for DCD to be asserted, and while
1155 callout dev is busy */
1156 retval = 0;
1157 add_wait_queue(&port->open_wait, &wait);
1159 spin_lock_irqsave(&card->card_lock, flags);
1160 if (!tty_hung_up_p(filp))
1161 port->count--;
1162 port->blocked_open++;
1163 spin_unlock_irqrestore(&card->card_lock, flags);
1165 while (1) {
1166 raise_dtr_rts(port);
1168 set_current_state(TASK_INTERRUPTIBLE);
1169 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
1170 if (port->flags & ASYNC_HUP_NOTIFY)
1171 retval = -EAGAIN;
1172 else
1173 retval = -ERESTARTSYS;
1174 break;
1176 if (!(port->flags & ASYNC_CLOSING) &&
1177 (do_clocal || (port->status & ISI_DCD))) {
1178 break;
1180 if (signal_pending(current)) {
1181 retval = -ERESTARTSYS;
1182 break;
1184 schedule();
1186 set_current_state(TASK_RUNNING);
1187 remove_wait_queue(&port->open_wait, &wait);
1188 spin_lock_irqsave(&card->card_lock, flags);
1189 if (!tty_hung_up_p(filp))
1190 port->count++;
1191 port->blocked_open--;
1192 spin_unlock_irqrestore(&card->card_lock, flags);
1193 if (retval)
1194 return retval;
1195 port->flags |= ASYNC_NORMAL_ACTIVE;
1196 return 0;
1199 static int isicom_open(struct tty_struct * tty, struct file * filp)
1201 struct isi_port * port;
1202 struct isi_board * card;
1203 unsigned int line, board;
1204 int error;
1206 line = tty->index;
1207 if (line < 0 || line > PORT_COUNT-1)
1208 return -ENODEV;
1209 board = BOARD(line);
1210 card = &isi_card[board];
1212 if (!(card->status & FIRMWARE_LOADED))
1213 return -ENODEV;
1215 /* open on a port greater than the port count for the card !!! */
1216 if (line > ((board * 16) + card->port_count - 1))
1217 return -ENODEV;
1219 port = &isi_ports[line];
1220 if (isicom_paranoia_check(port, tty->name, "isicom_open"))
1221 return -ENODEV;
1223 isicom_setup_board(card);
1225 port->count++;
1226 tty->driver_data = port;
1227 port->tty = tty;
1228 if ((error = isicom_setup_port(port))!=0)
1229 return error;
1230 if ((error = block_til_ready(tty, filp, port))!=0)
1231 return error;
1233 return 0;
1236 /* close et all */
1238 static inline void isicom_shutdown_board(struct isi_board * bp)
1240 unsigned long flags;
1242 spin_lock_irqsave(&bp->card_lock, flags);
1243 if (bp->status & BOARD_ACTIVE) {
1244 bp->status &= ~BOARD_ACTIVE;
1246 spin_unlock_irqrestore(&bp->card_lock, flags);
1249 static void isicom_shutdown_port(struct isi_port * port)
1251 struct isi_board * card = port->card;
1252 struct tty_struct * tty;
1253 unsigned long flags;
1255 tty = port->tty;
1257 spin_lock_irqsave(&card->card_lock, flags);
1258 if (!(port->flags & ASYNC_INITIALIZED)) {
1259 spin_unlock_irqrestore(&card->card_lock, flags);
1260 return;
1262 if (port->xmit_buf) {
1263 free_page((unsigned long) port->xmit_buf);
1264 port->xmit_buf = NULL;
1266 port->flags &= ~ASYNC_INITIALIZED;
1267 /* 3rd October 2000 : Vinayak P Risbud */
1268 port->tty = NULL;
1269 spin_unlock_irqrestore(&card->card_lock, flags);
1271 /*Fix done by Anil .S on 30-04-2001
1272 remote login through isi port has dtr toggle problem
1273 due to which the carrier drops before the password prompt
1274 appears on the remote end. Now we drop the dtr only if the
1275 HUPCL(Hangup on close) flag is set for the tty*/
1277 if (C_HUPCL(tty))
1278 /* drop dtr on this port */
1279 drop_dtr(port);
1281 /* any other port uninits */
1282 if (tty)
1283 set_bit(TTY_IO_ERROR, &tty->flags);
1285 if (--card->count < 0) {
1286 printk(KERN_DEBUG "ISICOM: isicom_shutdown_port: bad board(0x%x) count %d.\n",
1287 card->base, card->count);
1288 card->count = 0;
1291 /* last port was closed , shutdown that boad too */
1292 if(C_HUPCL(tty)) {
1293 if (!card->count)
1294 isicom_shutdown_board(card);
1298 static void isicom_close(struct tty_struct * tty, struct file * filp)
1300 struct isi_port * port = (struct isi_port *) tty->driver_data;
1301 struct isi_board * card = port->card;
1302 unsigned long flags;
1304 if (!port)
1305 return;
1306 if (isicom_paranoia_check(port, tty->name, "isicom_close"))
1307 return;
1309 #ifdef ISICOM_DEBUG
1310 printk(KERN_DEBUG "ISICOM: Close start!!!.\n");
1311 #endif
1313 spin_lock_irqsave(&card->card_lock, flags);
1314 if (tty_hung_up_p(filp)) {
1315 spin_unlock_irqrestore(&card->card_lock, flags);
1316 return;
1319 if (tty->count == 1 && port->count != 1) {
1320 printk(KERN_WARNING "ISICOM:(0x%x) isicom_close: bad port count"
1321 "tty->count = 1 port count = %d.\n",
1322 card->base, port->count);
1323 port->count = 1;
1325 if (--port->count < 0) {
1326 printk(KERN_WARNING "ISICOM:(0x%x) isicom_close: bad port count for"
1327 "channel%d = %d", card->base, port->channel,
1328 port->count);
1329 port->count = 0;
1332 if (port->count) {
1333 spin_unlock_irqrestore(&card->card_lock, flags);
1334 return;
1336 port->flags |= ASYNC_CLOSING;
1337 tty->closing = 1;
1338 spin_unlock_irqrestore(&card->card_lock, flags);
1340 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1341 tty_wait_until_sent(tty, port->closing_wait);
1342 /* indicate to the card that no more data can be received
1343 on this port */
1344 spin_lock_irqsave(&card->card_lock, flags);
1345 if (port->flags & ASYNC_INITIALIZED) {
1346 card->port_status &= ~(1 << port->channel);
1347 outw(card->port_status, card->base + 0x02);
1349 isicom_shutdown_port(port);
1350 spin_unlock_irqrestore(&card->card_lock, flags);
1352 if (tty->driver->flush_buffer)
1353 tty->driver->flush_buffer(tty);
1354 tty_ldisc_flush(tty);
1356 spin_lock_irqsave(&card->card_lock, flags);
1357 tty->closing = 0;
1359 if (port->blocked_open) {
1360 spin_unlock_irqrestore(&card->card_lock, flags);
1361 if (port->close_delay) {
1362 #ifdef ISICOM_DEBUG
1363 printk(KERN_DEBUG "ISICOM: scheduling until time out.\n");
1364 #endif
1365 msleep_interruptible(jiffies_to_msecs(port->close_delay));
1367 spin_lock_irqsave(&card->card_lock, flags);
1368 wake_up_interruptible(&port->open_wait);
1370 port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1371 wake_up_interruptible(&port->close_wait);
1372 spin_unlock_irqrestore(&card->card_lock, flags);
1375 /* write et all */
1376 static int isicom_write(struct tty_struct * tty,
1377 const unsigned char * buf, int count)
1379 struct isi_port * port = (struct isi_port *) tty->driver_data;
1380 struct isi_board * card = port->card;
1381 unsigned long flags;
1382 int cnt, total = 0;
1384 if (isicom_paranoia_check(port, tty->name, "isicom_write"))
1385 return 0;
1387 if (!tty || !port->xmit_buf || !tmp_buf)
1388 return 0;
1390 spin_lock_irqsave(&card->card_lock, flags);
1392 while(1) {
1393 cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1394 SERIAL_XMIT_SIZE - port->xmit_head));
1395 if (cnt <= 0)
1396 break;
1398 memcpy(port->xmit_buf + port->xmit_head, buf, cnt);
1399 port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE - 1);
1400 port->xmit_cnt += cnt;
1401 buf += cnt;
1402 count -= cnt;
1403 total += cnt;
1405 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped)
1406 port->status |= ISI_TXOK;
1407 spin_unlock_irqrestore(&card->card_lock, flags);
1408 return total;
1411 /* put_char et all */
1412 static void isicom_put_char(struct tty_struct * tty, unsigned char ch)
1414 struct isi_port * port = (struct isi_port *) tty->driver_data;
1415 struct isi_board * card = port->card;
1416 unsigned long flags;
1418 if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
1419 return;
1421 if (!tty || !port->xmit_buf)
1422 return;
1424 spin_lock_irqsave(&card->card_lock, flags);
1425 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
1426 spin_unlock_irqrestore(&card->card_lock, flags);
1427 return;
1430 port->xmit_buf[port->xmit_head++] = ch;
1431 port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
1432 port->xmit_cnt++;
1433 spin_unlock_irqrestore(&card->card_lock, flags);
1436 /* flush_chars et all */
1437 static void isicom_flush_chars(struct tty_struct * tty)
1439 struct isi_port * port = (struct isi_port *) tty->driver_data;
1441 if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars"))
1442 return;
1444 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !port->xmit_buf)
1445 return;
1447 /* this tells the transmitter to consider this port for
1448 data output to the card ... that's the best we can do. */
1449 port->status |= ISI_TXOK;
1452 /* write_room et all */
1453 static int isicom_write_room(struct tty_struct * tty)
1455 struct isi_port * port = (struct isi_port *) tty->driver_data;
1456 int free;
1458 if (isicom_paranoia_check(port, tty->name, "isicom_write_room"))
1459 return 0;
1461 free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1462 if (free < 0)
1463 free = 0;
1464 return free;
1467 /* chars_in_buffer et all */
1468 static int isicom_chars_in_buffer(struct tty_struct * tty)
1470 struct isi_port * port = (struct isi_port *) tty->driver_data;
1471 if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer"))
1472 return 0;
1473 return port->xmit_cnt;
1476 /* ioctl et all */
1477 static inline void isicom_send_break(struct isi_port * port, unsigned long length)
1479 struct isi_board * card = port->card;
1480 unsigned short base = card->base;
1482 if(!lock_card(card))
1483 return;
1485 outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
1486 outw((length & 0xff) << 8 | 0x00, base);
1487 outw((length & 0xff00), base);
1488 InterruptTheCard(base);
1490 unlock_card(card);
1493 static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
1495 struct isi_port * port = (struct isi_port *) tty->driver_data;
1496 /* just send the port status */
1497 unsigned short status = port->status;
1499 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1500 return -ENODEV;
1502 return ((status & ISI_RTS) ? TIOCM_RTS : 0) |
1503 ((status & ISI_DTR) ? TIOCM_DTR : 0) |
1504 ((status & ISI_DCD) ? TIOCM_CAR : 0) |
1505 ((status & ISI_DSR) ? TIOCM_DSR : 0) |
1506 ((status & ISI_CTS) ? TIOCM_CTS : 0) |
1507 ((status & ISI_RI ) ? TIOCM_RI : 0);
1510 static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
1511 unsigned int set, unsigned int clear)
1513 struct isi_port * port = (struct isi_port *) tty->driver_data;
1515 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1516 return -ENODEV;
1518 if (set & TIOCM_RTS)
1519 raise_rts(port);
1520 if (set & TIOCM_DTR)
1521 raise_dtr(port);
1523 if (clear & TIOCM_RTS)
1524 drop_rts(port);
1525 if (clear & TIOCM_DTR)
1526 drop_dtr(port);
1528 return 0;
1531 static int isicom_set_serial_info(struct isi_port * port,
1532 struct serial_struct __user *info)
1534 struct serial_struct newinfo;
1535 int reconfig_port;
1537 if(copy_from_user(&newinfo, info, sizeof(newinfo)))
1538 return -EFAULT;
1540 reconfig_port = ((port->flags & ASYNC_SPD_MASK) !=
1541 (newinfo.flags & ASYNC_SPD_MASK));
1543 if (!capable(CAP_SYS_ADMIN)) {
1544 if ((newinfo.close_delay != port->close_delay) ||
1545 (newinfo.closing_wait != port->closing_wait) ||
1546 ((newinfo.flags & ~ASYNC_USR_MASK) !=
1547 (port->flags & ~ASYNC_USR_MASK)))
1548 return -EPERM;
1549 port->flags = ((port->flags & ~ ASYNC_USR_MASK) |
1550 (newinfo.flags & ASYNC_USR_MASK));
1552 else {
1553 port->close_delay = newinfo.close_delay;
1554 port->closing_wait = newinfo.closing_wait;
1555 port->flags = ((port->flags & ~ASYNC_FLAGS) |
1556 (newinfo.flags & ASYNC_FLAGS));
1558 if (reconfig_port) {
1559 isicom_config_port(port);
1561 return 0;
1564 static int isicom_get_serial_info(struct isi_port * port,
1565 struct serial_struct __user *info)
1567 struct serial_struct out_info;
1569 memset(&out_info, 0, sizeof(out_info));
1570 /* out_info.type = ? */
1571 out_info.line = port - isi_ports;
1572 out_info.port = port->card->base;
1573 out_info.irq = port->card->irq;
1574 out_info.flags = port->flags;
1575 /* out_info.baud_base = ? */
1576 out_info.close_delay = port->close_delay;
1577 out_info.closing_wait = port->closing_wait;
1578 if(copy_to_user(info, &out_info, sizeof(out_info)))
1579 return -EFAULT;
1580 return 0;
1583 static int isicom_ioctl(struct tty_struct * tty, struct file * filp,
1584 unsigned int cmd, unsigned long arg)
1586 struct isi_port * port = (struct isi_port *) tty->driver_data;
1587 void __user *argp = (void __user *)arg;
1588 int retval;
1590 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1591 return -ENODEV;
1593 switch(cmd) {
1594 case TCSBRK:
1595 retval = tty_check_change(tty);
1596 if (retval)
1597 return retval;
1598 tty_wait_until_sent(tty, 0);
1599 if (!arg)
1600 isicom_send_break(port, HZ/4);
1601 return 0;
1603 case TCSBRKP:
1604 retval = tty_check_change(tty);
1605 if (retval)
1606 return retval;
1607 tty_wait_until_sent(tty, 0);
1608 isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4);
1609 return 0;
1611 case TIOCGSOFTCAR:
1612 return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
1614 case TIOCSSOFTCAR:
1615 if(get_user(arg, (unsigned long __user *) argp))
1616 return -EFAULT;
1617 tty->termios->c_cflag =
1618 ((tty->termios->c_cflag & ~CLOCAL) |
1619 (arg ? CLOCAL : 0));
1620 return 0;
1622 case TIOCGSERIAL:
1623 return isicom_get_serial_info(port, argp);
1625 case TIOCSSERIAL:
1626 return isicom_set_serial_info(port, argp);
1628 default:
1629 return -ENOIOCTLCMD;
1631 return 0;
1634 /* set_termios et all */
1635 static void isicom_set_termios(struct tty_struct * tty, struct termios * old_termios)
1637 struct isi_port * port = (struct isi_port *) tty->driver_data;
1639 if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
1640 return;
1642 if (tty->termios->c_cflag == old_termios->c_cflag &&
1643 tty->termios->c_iflag == old_termios->c_iflag)
1644 return;
1646 isicom_config_port(port);
1648 if ((old_termios->c_cflag & CRTSCTS) &&
1649 !(tty->termios->c_cflag & CRTSCTS)) {
1650 tty->hw_stopped = 0;
1651 isicom_start(tty);
1655 /* throttle et all */
1656 static void isicom_throttle(struct tty_struct * tty)
1658 struct isi_port * port = (struct isi_port *) tty->driver_data;
1659 struct isi_board * card = port->card;
1661 if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
1662 return;
1664 /* tell the card that this port cannot handle any more data for now */
1665 card->port_status &= ~(1 << port->channel);
1666 outw(card->port_status, card->base + 0x02);
1669 /* unthrottle et all */
1670 static void isicom_unthrottle(struct tty_struct * tty)
1672 struct isi_port * port = (struct isi_port *) tty->driver_data;
1673 struct isi_board * card = port->card;
1675 if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
1676 return;
1678 /* tell the card that this port is ready to accept more data */
1679 card->port_status |= (1 << port->channel);
1680 outw(card->port_status, card->base + 0x02);
1683 /* stop et all */
1684 static void isicom_stop(struct tty_struct * tty)
1686 struct isi_port * port = (struct isi_port *) tty->driver_data;
1688 if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
1689 return;
1691 /* this tells the transmitter not to consider this port for
1692 data output to the card. */
1693 port->status &= ~ISI_TXOK;
1696 /* start et all */
1697 static void isicom_start(struct tty_struct * tty)
1699 struct isi_port * port = (struct isi_port *) tty->driver_data;
1701 if (isicom_paranoia_check(port, tty->name, "isicom_start"))
1702 return;
1704 /* this tells the transmitter to consider this port for
1705 data output to the card. */
1706 port->status |= ISI_TXOK;
1709 /* hangup et all */
1710 static void do_isicom_hangup(void * data)
1712 struct isi_port * port = (struct isi_port *) data;
1713 struct tty_struct * tty;
1715 tty = port->tty;
1716 if (tty)
1717 tty_hangup(tty);
1720 static void isicom_hangup(struct tty_struct * tty)
1722 struct isi_port * port = (struct isi_port *) tty->driver_data;
1724 if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
1725 return;
1727 isicom_shutdown_port(port);
1728 port->count = 0;
1729 port->flags &= ~ASYNC_NORMAL_ACTIVE;
1730 port->tty = NULL;
1731 wake_up_interruptible(&port->open_wait);
1734 /* flush_buffer et all */
1735 static void isicom_flush_buffer(struct tty_struct * tty)
1737 struct isi_port * port = (struct isi_port *) tty->driver_data;
1738 struct isi_board * card = port->card;
1739 unsigned long flags;
1741 if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
1742 return;
1744 spin_lock_irqsave(&card->card_lock, flags);
1745 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1746 spin_unlock_irqrestore(&card->card_lock, flags);
1748 wake_up_interruptible(&tty->write_wait);
1749 tty_wakeup(tty);
1753 static int __devinit register_ioregion(void)
1755 int count, done=0;
1756 for (count=0; count < BOARD_COUNT; count++ ) {
1757 if (isi_card[count].base)
1758 if (!request_region(isi_card[count].base,16,ISICOM_NAME)) {
1759 printk(KERN_DEBUG "ISICOM: I/O Region 0x%x-0x%x is busy. Card%d will be disabled.\n",
1760 isi_card[count].base,isi_card[count].base+15,count+1);
1761 isi_card[count].base=0;
1762 done++;
1765 return done;
1768 static void unregister_ioregion(void)
1770 int count;
1771 for (count=0; count < BOARD_COUNT; count++ )
1772 if (isi_card[count].base) {
1773 release_region(isi_card[count].base,16);
1774 #ifdef ISICOM_DEBUG
1775 printk(KERN_DEBUG "ISICOM: I/O Region 0x%x-0x%x released for Card%d.\n",isi_card[count].base,isi_card[count].base+15,count+1);
1776 #endif
1780 static struct tty_operations isicom_ops = {
1781 .open = isicom_open,
1782 .close = isicom_close,
1783 .write = isicom_write,
1784 .put_char = isicom_put_char,
1785 .flush_chars = isicom_flush_chars,
1786 .write_room = isicom_write_room,
1787 .chars_in_buffer = isicom_chars_in_buffer,
1788 .ioctl = isicom_ioctl,
1789 .set_termios = isicom_set_termios,
1790 .throttle = isicom_throttle,
1791 .unthrottle = isicom_unthrottle,
1792 .stop = isicom_stop,
1793 .start = isicom_start,
1794 .hangup = isicom_hangup,
1795 .flush_buffer = isicom_flush_buffer,
1796 .tiocmget = isicom_tiocmget,
1797 .tiocmset = isicom_tiocmset,
1800 static int __devinit register_drivers(void)
1802 int error;
1804 /* tty driver structure initialization */
1805 isicom_normal = alloc_tty_driver(PORT_COUNT);
1806 if (!isicom_normal)
1807 return -ENOMEM;
1809 isicom_normal->owner = THIS_MODULE;
1810 isicom_normal->name = "ttyM";
1811 isicom_normal->devfs_name = "isicom/";
1812 isicom_normal->major = ISICOM_NMAJOR;
1813 isicom_normal->minor_start = 0;
1814 isicom_normal->type = TTY_DRIVER_TYPE_SERIAL;
1815 isicom_normal->subtype = SERIAL_TYPE_NORMAL;
1816 isicom_normal->init_termios = tty_std_termios;
1817 isicom_normal->init_termios.c_cflag =
1818 B9600 | CS8 | CREAD | HUPCL |CLOCAL;
1819 isicom_normal->flags = TTY_DRIVER_REAL_RAW;
1820 tty_set_operations(isicom_normal, &isicom_ops);
1822 if ((error=tty_register_driver(isicom_normal))!=0) {
1823 printk(KERN_DEBUG "ISICOM: Couldn't register the dialin driver, error=%d\n",
1824 error);
1825 put_tty_driver(isicom_normal);
1826 return error;
1828 return 0;
1831 static void unregister_drivers(void)
1833 int error = tty_unregister_driver(isicom_normal);
1834 if (error)
1835 printk(KERN_DEBUG "ISICOM: couldn't unregister normal driver error=%d.\n",error);
1836 put_tty_driver(isicom_normal);
1839 static int __devinit register_isr(void)
1841 int count, done=0;
1842 unsigned long irqflags;
1844 for (count=0; count < BOARD_COUNT; count++ ) {
1845 if (isi_card[count].base) {
1846 irqflags = (isi_card[count].isa == YES) ?
1847 SA_INTERRUPT :
1848 (SA_INTERRUPT | SA_SHIRQ);
1850 if (request_irq(isi_card[count].irq,
1851 isicom_interrupt,
1852 irqflags,
1853 ISICOM_NAME, &isi_card[count])) {
1855 printk(KERN_WARNING "ISICOM: Could not"
1856 " install handler at Irq %d."
1857 " Card%d will be disabled.\n",
1858 isi_card[count].irq, count+1);
1860 release_region(isi_card[count].base,16);
1861 isi_card[count].base=0;
1863 else
1864 done++;
1867 return done;
1870 static void __exit unregister_isr(void)
1872 int count;
1874 for (count=0; count < BOARD_COUNT; count++ ) {
1875 if (isi_card[count].base)
1876 free_irq(isi_card[count].irq, &isi_card[count]);
1880 static int __devinit isicom_init(void)
1882 int card, channel, base;
1883 struct isi_port * port;
1884 unsigned long page;
1886 if (!tmp_buf) {
1887 page = get_zeroed_page(GFP_KERNEL);
1888 if (!page) {
1889 #ifdef ISICOM_DEBUG
1890 printk(KERN_DEBUG "ISICOM: Couldn't allocate page for tmp_buf.\n");
1891 #else
1892 printk(KERN_ERR "ISICOM: Not enough memory...\n");
1893 #endif
1894 return 0;
1896 tmp_buf = (unsigned char *) page;
1899 if (!register_ioregion())
1901 printk(KERN_ERR "ISICOM: All required I/O space found busy.\n");
1902 free_page((unsigned long)tmp_buf);
1903 return 0;
1905 if (register_drivers())
1907 unregister_ioregion();
1908 free_page((unsigned long)tmp_buf);
1909 return 0;
1911 if (!register_isr())
1913 unregister_drivers();
1914 /* ioports already uregistered in register_isr */
1915 free_page((unsigned long)tmp_buf);
1916 return 0;
1919 memset(isi_ports, 0, sizeof(isi_ports));
1920 for (card = 0; card < BOARD_COUNT; card++) {
1921 port = &isi_ports[card * 16];
1922 isi_card[card].ports = port;
1923 spin_lock_init(&isi_card[card].card_lock);
1924 base = isi_card[card].base;
1925 for (channel = 0; channel < 16; channel++, port++) {
1926 port->magic = ISICOM_MAGIC;
1927 port->card = &isi_card[card];
1928 port->channel = channel;
1929 port->close_delay = 50 * HZ/100;
1930 port->closing_wait = 3000 * HZ/100;
1931 INIT_WORK(&port->hangup_tq, do_isicom_hangup, port);
1932 INIT_WORK(&port->bh_tqueue, isicom_bottomhalf, port);
1933 port->status = 0;
1934 init_waitqueue_head(&port->open_wait);
1935 init_waitqueue_head(&port->close_wait);
1936 /* . . . */
1940 return 1;
1944 * Insmod can set static symbols so keep these static
1947 static int io[4];
1948 static int irq[4];
1950 MODULE_AUTHOR("MultiTech");
1951 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
1952 MODULE_LICENSE("GPL");
1953 module_param_array(io, int, NULL, 0);
1954 MODULE_PARM_DESC(io, "I/O ports for the cards");
1955 module_param_array(irq, int, NULL, 0);
1956 MODULE_PARM_DESC(irq, "Interrupts for the cards");
1958 static int __devinit isicom_setup(void)
1960 struct pci_dev *dev = NULL;
1961 int retval, card, idx, count;
1962 unsigned char pciirq;
1963 unsigned int ioaddr;
1965 card = 0;
1966 for(idx=0; idx < BOARD_COUNT; idx++) {
1967 if (io[idx]) {
1968 isi_card[idx].base=io[idx];
1969 isi_card[idx].irq=irq[idx];
1970 isi_card[idx].isa=YES;
1971 card++;
1973 else {
1974 isi_card[idx].base = 0;
1975 isi_card[idx].irq = 0;
1979 for (idx=0 ;idx < card; idx++) {
1980 if (!((isi_card[idx].irq==2)||(isi_card[idx].irq==3)||
1981 (isi_card[idx].irq==4)||(isi_card[idx].irq==5)||
1982 (isi_card[idx].irq==7)||(isi_card[idx].irq==10)||
1983 (isi_card[idx].irq==11)||(isi_card[idx].irq==12)||
1984 (isi_card[idx].irq==15))) {
1986 if (isi_card[idx].base) {
1987 printk(KERN_ERR "ISICOM: Irq %d unsupported. Disabling Card%d...\n",
1988 isi_card[idx].irq, idx+1);
1989 isi_card[idx].base=0;
1990 card--;
1995 if (card < BOARD_COUNT) {
1996 for (idx=0; idx < DEVID_COUNT; idx++) {
1997 dev = NULL;
1998 for (;;){
1999 if (!(dev = pci_find_device(VENDOR_ID, isicom_pci_tbl[idx].device, dev)))
2000 break;
2001 if (card >= BOARD_COUNT)
2002 break;
2004 if (pci_enable_device(dev))
2005 break;
2007 /* found a PCI ISI card! */
2008 ioaddr = pci_resource_start (dev, 3); /* i.e at offset 0x1c in the
2009 * PCI configuration register
2010 * space.
2012 pciirq = dev->irq;
2013 printk(KERN_INFO "ISI PCI Card(Device ID 0x%x)\n", isicom_pci_tbl[idx].device);
2015 * allot the first empty slot in the array
2017 for (count=0; count < BOARD_COUNT; count++) {
2018 if (isi_card[count].base == 0) {
2019 isi_card[count].base = ioaddr;
2020 isi_card[count].irq = pciirq;
2021 isi_card[count].isa = NO;
2022 card++;
2023 break;
2027 if (card >= BOARD_COUNT) break;
2031 if (!(isi_card[0].base || isi_card[1].base || isi_card[2].base || isi_card[3].base)) {
2032 printk(KERN_ERR "ISICOM: No valid card configuration. Driver cannot be initialized...\n");
2033 return -EIO;
2036 retval = misc_register(&isiloader_device);
2037 if (retval < 0) {
2038 printk(KERN_ERR "ISICOM: Unable to register firmware loader driver.\n");
2039 return retval;
2042 if (!isicom_init()) {
2043 if (misc_deregister(&isiloader_device))
2044 printk(KERN_ERR "ISICOM: Unable to unregister Firmware Loader driver\n");
2045 return -EIO;
2048 init_timer(&tx);
2049 tx.expires = jiffies + 1;
2050 tx.data = 0;
2051 tx.function = isicom_tx;
2052 re_schedule = 1;
2053 add_timer(&tx);
2055 return 0;
2058 static void __exit isicom_exit(void)
2060 re_schedule = 0;
2061 /* FIXME */
2062 msleep(1000);
2063 unregister_isr();
2064 unregister_drivers();
2065 unregister_ioregion();
2066 if(tmp_buf)
2067 free_page((unsigned long)tmp_buf);
2068 if (misc_deregister(&isiloader_device))
2069 printk(KERN_ERR "ISICOM: Unable to unregister Firmware Loader driver\n");
2072 module_init(isicom_setup);
2073 module_exit(isicom_exit);