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
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)
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.
19 * ***********************************************************
21 * To use this driver you also need the support package. You
22 * can find this in RPM format on
23 * ftp://ftp.linux.org.uk/pub/linux/alan
25 * You can find the original tools for this direct from Multitech
26 * ftp://ftp.multitech.com/ISI-Cards/
28 * Having installed the cards the module options (/etc/conf.modules)
30 * options isicom io=card1,card2,card3,card4 irq=card1,card2,card3,card4
32 * Omit those entries for boards you don't have installed.
36 #include <linux/module.h>
37 #include <linux/version.h>
38 #include <linux/kernel.h>
39 #include <linux/tty.h>
40 #include <linux/termios.h>
42 #include <linux/sched.h>
43 #include <linux/serial.h>
45 #include <linux/miscdevice.h>
46 #include <linux/interrupt.h>
47 #include <linux/timer.h>
48 #include <linux/ioport.h>
50 #include <asm/segment.h>
51 #include <asm/uaccess.h>
53 #include <asm/system.h>
55 #include <linux/pci.h>
57 #include <linux/isicom.h>
59 static int device_id
[] = { 0x2028,
70 static int isicom_refcount
= 0;
71 static int prev_card
= 3; /* start servicing isi_card[0] */
72 static struct isi_board
* irq_to_board
[16] = { NULL
, };
73 static struct tty_driver isicom_normal
, isicom_callout
;
74 static struct tty_struct
* isicom_table
[PORT_COUNT
] = { NULL
, };
75 static struct termios
* isicom_termios
[PORT_COUNT
] = { NULL
, };
76 static struct termios
* isicom_termios_locked
[PORT_COUNT
] = { NULL
, };
78 static struct isi_board isi_card
[BOARD_COUNT
];
79 static struct isi_port isi_ports
[PORT_COUNT
];
81 DECLARE_TASK_QUEUE(tq_isicom
);
83 static struct timer_list tx
;
84 static char re_schedule
= 1;
86 static unsigned long tx_count
= 0;
89 static int ISILoad_open(struct inode
*inode
, struct file
*filp
);
90 static int ISILoad_release(struct inode
*inode
, struct file
*filp
);
91 static int ISILoad_ioctl(struct inode
*inode
, struct file
*filp
, unsigned int cmd
, unsigned long arg
);
93 static void isicom_tx(unsigned long _data
);
94 static void isicom_start(struct tty_struct
* tty
);
96 static unsigned char * tmp_buf
= 0;
97 static DECLARE_MUTEX(tmp_buf_sem
);
99 /* baud index mappings from linux defns to isi */
101 static char linuxb_to_isib
[] = {
102 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17,
107 * Firmware loader driver specific routines
111 static struct file_operations ISILoad_fops
= {
124 NULL
, /* check_media_change */
125 NULL
, /* revalidate */
128 struct miscdevice isiloader_device
= {
129 ISILOAD_MISC_MINOR
, "isictl", &ISILoad_fops
133 extern inline int WaitTillCardIsFree(unsigned short base
)
135 unsigned long count
=0;
136 while( (!(inw(base
+0xe) & 0x1)) && (count
++ < 6000000));
137 if (inw(base
+0xe)&0x1)
143 static int ISILoad_open(struct inode
*inode
, struct file
*filp
)
146 printk(KERN_DEBUG
"ISILoad:Firmware loader Opened!!!\n");
152 static int ISILoad_release(struct inode
*inode
, struct file
*filp
)
155 printk(KERN_DEBUG
"ISILoad:Firmware loader Close(Release)d\n",);
161 static int ISILoad_ioctl(struct inode
*inode
, struct file
*filp
,
162 unsigned int cmd
, unsigned long arg
)
164 unsigned int card
, i
, j
, signature
, status
, portcount
= 0;
165 unsigned short word_count
, base
;
167 /* exec_record exec_rec; */
169 if(get_user(card
, (int *)arg
))
172 if(card
< 0 || card
>= BOARD_COUNT
)
175 base
=isi_card
[card
].base
;
178 return -ENXIO
; /* disabled or not used */
181 case MIOCTL_RESET_CARD
:
182 if (!capable(CAP_SYS_ADMIN
))
184 printk(KERN_DEBUG
"ISILoad:Resetting Card%d at 0x%x ",card
+1,base
);
188 for(i
=jiffies
+HZ
/100;time_before(jiffies
, i
););
190 outw(0,base
+0x8); /* Reset */
193 for(i
=jiffies
+HZ
;time_before(jiffies
, i
););
196 signature
=(inw(base
+0x4)) & 0xff;
197 if (isi_card
[card
].isa
) {
199 if (!(inw(base
+0xe) & 0x1) || (inw(base
+0x2))) {
201 printk("\nbase+0x2=0x%x , base+0xe=0x%x",inw(base
+0x2),inw(base
+0xe));
203 printk("\nISILoad:ISA Card%d reset failure (Possible bad I/O Port Address 0x%x).\n",card
+1,base
);
208 portcount
= inw(base
+0x2);
209 if (!(inw(base
+0xe) & 0x1) || ((portcount
!=0) && (portcount
!=4) && (portcount
!=8))) {
211 printk("\nbase+0x2=0x%x , base+0xe=0x%x",inw(base
+0x2),inw(base
+0xe));
213 printk("\nISILoad:PCI Card%d reset failure (Possible bad I/O Port Address 0x%x).\n",card
+1,base
);
221 if (isi_card
[card
].isa
)
222 isi_card
[card
].port_count
= 8;
225 isi_card
[card
].port_count
= 4;
227 isi_card
[card
].port_count
= 8;
229 isi_card
[card
].shift_count
= 12;
232 case 0xcc: isi_card
[card
].port_count
= 16;
233 isi_card
[card
].shift_count
= 11;
236 default: printk("ISILoad:Card%d reset failure (Possible bad I/O Port Address 0x%x).\n",card
+1,base
);
238 printk("Sig=0x%x\n",signature
);
243 return put_user(signature
,(unsigned int*)arg
);
245 case MIOCTL_LOAD_FIRMWARE
:
246 if (!capable(CAP_SYS_ADMIN
))
249 if(copy_from_user(&frame
, (void *) arg
, sizeof(bin_frame
)))
252 if (WaitTillCardIsFree(base
))
255 outw(0xf0,base
); /* start upload sequence */
257 outw((frame
.addr
), base
);/* lsb of adderess */
259 word_count
=(frame
.count
>> 1) + frame
.count
% 2;
260 outw(word_count
, base
);
261 InterruptTheCard(base
);
263 for(i
=0;i
<=0x2f;i
++); /* a wee bit of delay */
265 if (WaitTillCardIsFree(base
))
268 if ((status
=inw(base
+0x4))!=0) {
269 printk(KERN_WARNING
"ISILoad:Card%d rejected load header:\nAddress:0x%x \nCount:0x%x \nStatus:0x%x \n",
270 card
+1, frame
.addr
, frame
.count
, status
);
273 outsw(base
, (void *) frame
.bin_data
, word_count
);
275 InterruptTheCard(base
);
277 for(i
=0;i
<=0x0f;i
++); /* another wee bit of delay */
279 if (WaitTillCardIsFree(base
))
282 if ((status
=inw(base
+0x4))!=0) {
283 printk(KERN_ERR
"ISILoad:Card%d got out of sync.Card Status:0x%x\n",card
+1, status
);
288 case MIOCTL_READ_FIRMWARE
:
289 if (!capable(CAP_SYS_ADMIN
))
292 if(copy_from_user(&frame
, (void *) arg
, sizeof(bin_header
)))
295 if (WaitTillCardIsFree(base
))
298 outw(0xf1,base
); /* start download sequence */
300 outw((frame
.addr
), base
);/* lsb of adderess */
302 word_count
=(frame
.count
>> 1) + frame
.count
% 2;
303 outw(word_count
+1, base
);
304 InterruptTheCard(base
);
306 for(i
=0;i
<=0xf;i
++); /* a wee bit of delay */
308 if (WaitTillCardIsFree(base
))
311 if ((status
=inw(base
+0x4))!=0) {
312 printk(KERN_WARNING
"ISILoad:Card%d rejected verify header:\nAddress:0x%x \nCount:0x%x \nStatus:0x%x \n",
313 card
+1, frame
.addr
, frame
.count
, status
);
318 insw(base
, frame
.bin_data
, word_count
);
319 InterruptTheCard(base
);
321 for(i
=0;i
<=0x0f;i
++); /* another wee bit of delay */
323 if (WaitTillCardIsFree(base
))
326 if ((status
=inw(base
+0x4))!=0) {
327 printk(KERN_ERR
"ISILoad:Card%d verify got out of sync.Card Status:0x%x\n",card
+1, status
);
331 if(copy_to_user((void *) arg
, &frame
, sizeof(bin_frame
)))
335 case MIOCTL_XFER_CTRL
:
336 if (!capable(CAP_SYS_ADMIN
))
338 if (WaitTillCardIsFree(base
))
345 InterruptTheCard(base
);
346 outw(0x0, base
+0x4); /* for ISI4608 cards */
348 isi_card
[card
].status
|= FIRMWARE_LOADED
;
353 printk(KERN_DEBUG
"ISILoad: Received Ioctl cmd 0x%x.\n", cmd
);
363 * ISICOM Driver specific routines ...
367 static inline int isicom_paranoia_check(struct isi_port
const * port
, kdev_t dev
,
368 const char * routine
)
371 static const char * badmagic
=
372 KERN_WARNING
"ISICOM: Warning: bad isicom magic for dev %s in %s.\n";
373 static const char * badport
=
374 KERN_WARNING
"ISICOM: Warning: NULL isicom port for dev %s in %s.\n";
376 printk(badport
, kdevname(dev
), routine
);
379 if (port
->magic
!= ISICOM_MAGIC
) {
380 printk(badmagic
, kdevname(dev
), routine
);
387 extern inline void schedule_bh(struct isi_port
* port
)
389 queue_task(&port
->bh_tqueue
, &tq_isicom
);
395 static void isicom_tx(unsigned long _data
)
397 short count
= (BOARD_COUNT
-1), card
, base
;
398 short txcount
, wait
, wrd
, residue
, word_count
, cnt
;
399 struct isi_port
* port
;
400 struct tty_struct
* tty
;
407 /* find next active board */
408 card
= (prev_card
+ 1) & 0x0003;
410 if (isi_card
[card
].status
& BOARD_ACTIVE
)
412 card
= (card
+ 1) & 0x0003;
414 if (!(isi_card
[card
].status
& BOARD_ACTIVE
))
419 count
= isi_card
[card
].port_count
;
420 port
= isi_card
[card
].ports
;
421 base
= isi_card
[card
].base
;
422 for (;count
> 0;count
--, port
++) {
423 /* port not active or tx disabled to force flow control */
424 if (!(port
->status
& ISI_TXOK
))
428 save_flags(flags
); cli();
429 txcount
= MIN(TX_SIZE
, port
->xmit_cnt
);
430 if ((txcount
<= 0) || tty
->stopped
|| tty
->hw_stopped
) {
431 restore_flags(flags
);
435 while(((inw(base
+0x0e) & 0x01) == 0) && (wait
-- > 0));
437 restore_flags(flags
);
439 printk(KERN_DEBUG
"ISICOM: isicom_tx:Card(0x%x) found busy.\n",
444 if (!(inw(base
+ 0x02) & (1 << port
->channel
))) {
445 restore_flags(flags
);
447 printk(KERN_DEBUG
"ISICOM: isicom_tx: cannot tx to 0x%x:%d.\n",
448 base
, port
->channel
+ 1);
453 printk(KERN_DEBUG
"ISICOM: txing %d bytes, port%d.\n",
454 txcount
, port
->channel
+1);
456 outw((port
->channel
<< isi_card
[card
].shift_count
) | txcount
461 cnt
= MIN(txcount
, (SERIAL_XMIT_SIZE
- port
->xmit_tail
));
462 if (residue
== YES
) {
465 wrd
|= (port
->xmit_buf
[port
->xmit_tail
] << 8);
466 port
->xmit_tail
= (port
->xmit_tail
+ 1) & (SERIAL_XMIT_SIZE
- 1);
478 word_count
= cnt
>> 1;
479 outsw(base
, port
->xmit_buf
+port
->xmit_tail
, word_count
);
480 port
->xmit_tail
= (port
->xmit_tail
+ (word_count
<< 1)) &
481 (SERIAL_XMIT_SIZE
- 1);
482 txcount
-= (word_count
<< 1);
483 port
->xmit_cnt
-= (word_count
<< 1);
486 wrd
= port
->xmit_buf
[port
->xmit_tail
];
487 port
->xmit_tail
= (port
->xmit_tail
+ 1) & (SERIAL_XMIT_SIZE
- 1);
493 InterruptTheCard(base
);
494 if (port
->xmit_cnt
<= 0)
495 port
->status
&= ~ISI_TXOK
;
496 if (port
->xmit_cnt
<= WAKEUP_CHARS
)
498 restore_flags(flags
);
501 /* schedule another tx for hopefully in about 10ms */
506 tx
.expires
= jiffies
+ HZ
/100;
508 tx
.function
= isicom_tx
;
514 /* Interrupt handlers */
516 static void do_isicom_bh(void)
518 run_task_queue(&tq_isicom
);
523 static void isicom_bottomhalf(void * data
)
525 struct isi_port
* port
= (struct isi_port
*) data
;
526 struct tty_struct
* tty
= port
->tty
;
531 if ((tty
->flags
& (1 << TTY_DO_WRITE_WAKEUP
)) &&
532 tty
->ldisc
.write_wakeup
)
533 (tty
->ldisc
.write_wakeup
)(tty
);
534 wake_up_interruptible(&tty
->write_wait
);
537 /* main interrupt handler routine */
538 static void isicom_interrupt(int irq
, void * dev_id
, struct pt_regs
* regs
)
540 struct isi_board
* card
;
541 struct isi_port
* port
;
542 struct tty_struct
* tty
;
543 unsigned short base
, header
, word_count
, count
;
544 unsigned char channel
;
548 * find the source of interrupt
551 for(count
= 0; count
< BOARD_COUNT
; count
++) {
552 card
= &isi_card
[count
];
553 if (card
->base
!= 0) {
554 if (((card
->isa
== YES
) && (card
->irq
== irq
)) ||
555 ((card
->isa
== NO
) && (card
->irq
== irq
) && (inw(card
->base
+0x0e) & 0x02)))
561 if (!card
|| !(card
->status
& FIRMWARE_LOADED
)) {
562 /* printk(KERN_DEBUG "ISICOM: interrupt: not handling irq%d!.\n", irq);*/
567 if (card
->isa
== NO
) {
569 * disable any interrupts from the PCI card and lower the
572 outw(0x8000, base
+0x04);
573 ClearInterrupt(base
);
576 inw(base
); /* get the dummy word out */
578 channel
= (header
& 0x7800) >> card
->shift_count
;
579 byte_count
= header
& 0xff;
581 printk(KERN_DEBUG
"ISICOM:Intr:(0x%x:%d).\n", base
, channel
+1);
583 if ((channel
+1) > card
->port_count
) {
584 printk(KERN_WARNING
"ISICOM: isicom_interrupt(0x%x): %d(channel) > port_count.\n",
587 ClearInterrupt(base
);
589 outw(0x0000, base
+0x04); /* enable interrupts */
592 port
= card
->ports
+ channel
;
593 if (!(port
->flags
& ASYNC_INITIALIZED
)) {
595 ClearInterrupt(base
);
597 outw(0x0000, base
+0x04); /* enable interrupts */
603 if (header
& 0x8000) { /* Status Packet */
605 switch(header
& 0xff) {
606 case 0: /* Change in EIA signals */
608 if (port
->flags
& ASYNC_CHECK_CD
) {
609 if (port
->status
& ISI_DCD
) {
610 if (!(header
& ISI_DCD
)) {
611 /* Carrier has been lost */
613 printk(KERN_DEBUG
"ISICOM: interrupt: DCD->low.\n");
615 port
->status
&= ~ISI_DCD
;
616 if (!((port
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
617 (port
->flags
& ASYNC_CALLOUT_NOHUP
)))
618 queue_task(&port
->hangup_tq
,
623 if (header
& ISI_DCD
) {
624 /* Carrier has been detected */
626 printk(KERN_DEBUG
"ISICOM: interrupt: DCD->high.\n");
628 port
->status
|= ISI_DCD
;
629 wake_up_interruptible(&port
->open_wait
);
634 if (header
& ISI_DCD
)
635 port
->status
|= ISI_DCD
;
637 port
->status
&= ~ISI_DCD
;
640 if (port
->flags
& ASYNC_CTS_FLOW
) {
641 if (port
->tty
->hw_stopped
) {
642 if (header
& ISI_CTS
) {
643 port
->tty
->hw_stopped
= 0;
645 port
->status
|= (ISI_TXOK
| ISI_CTS
);
650 if (!(header
& ISI_CTS
)) {
651 port
->tty
->hw_stopped
= 1;
653 port
->status
&= ~(ISI_TXOK
| ISI_CTS
);
658 if (header
& ISI_CTS
)
659 port
->status
|= ISI_CTS
;
661 port
->status
&= ~ISI_CTS
;
664 if (header
& ISI_DSR
)
665 port
->status
|= ISI_DSR
;
667 port
->status
&= ~ISI_DSR
;
670 port
->status
|= ISI_RI
;
672 port
->status
&= ~ISI_RI
;
676 case 1: /* Received Break !!! */
677 if (tty
->flip
.count
>= TTY_FLIPBUF_SIZE
)
679 *tty
->flip
.flag_buf_ptr
++ = TTY_BREAK
;
680 /* dunno if this is right */
681 *tty
->flip
.char_buf_ptr
++ = 0;
683 if (port
->flags
& ASYNC_SAK
)
685 queue_task(&tty
->flip
.tqueue
, &tq_timer
);
688 case 2: /* Statistics */
689 printk(KERN_DEBUG
"ISICOM: isicom_interrupt: stats!!!.\n");
693 printk(KERN_WARNING
"ISICOM: Intr: Unknown code in status packet.\n");
697 else { /* Data Packet */
698 count
= MIN(byte_count
, (TTY_FLIPBUF_SIZE
- tty
->flip
.count
));
700 printk(KERN_DEBUG
"ISICOM: Intr: Can rx %d of %d bytes.\n",
703 word_count
= count
>> 1;
704 insw(base
, tty
->flip
.char_buf_ptr
, word_count
);
705 tty
->flip
.char_buf_ptr
+= (word_count
<< 1);
706 byte_count
-= (word_count
<< 1);
707 if (count
& 0x0001) {
708 *tty
->flip
.char_buf_ptr
++ = (char)(inw(base
) & 0xff);
711 memset(tty
->flip
.flag_buf_ptr
, 0, count
);
712 tty
->flip
.flag_buf_ptr
+= count
;
713 tty
->flip
.count
+= count
;
715 if (byte_count
> 0) {
716 printk(KERN_DEBUG
"ISICOM: Intr(0x%x:%d): Flip buffer overflow! dropping bytes...\n",
718 while(byte_count
> 0) { /* drain out unread xtra data */
723 queue_task(&tty
->flip
.tqueue
, &tq_timer
);
725 if (card
->isa
== YES
)
726 ClearInterrupt(base
);
728 outw(0x0000, base
+0x04); /* enable interrupts */
732 /* called with interrupts disabled */
733 static void isicom_config_port(struct isi_port
* port
)
735 struct isi_board
* card
= port
->card
;
736 struct tty_struct
* tty
;
738 unsigned short channel_setup
, wait
, base
= card
->base
;
739 unsigned short channel
= port
->channel
, shift_count
= card
->shift_count
;
740 unsigned char flow_ctrl
;
742 if (!(tty
= port
->tty
) || !tty
->termios
)
745 if (baud
& CBAUDEX
) {
748 /* if CBAUDEX bit is on and the baud is set to either 50 or 75
749 * then the card is programmed for 57.6Kbps or 115Kbps
753 if (baud
< 1 || baud
> 2)
754 port
->tty
->termios
->c_cflag
&= ~CBAUDEX
;
760 /* the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set
761 * by the set_serial_info ioctl ... this is done by
762 * the 'setserial' utility.
765 if ((port
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_HI
)
766 baud
++; /* 57.6 Kbps */
767 if ((port
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_VHI
)
768 baud
+=2; /* 115 Kbps */
770 if (linuxb_to_isib
[baud
] == -1) {
779 while (((inw(base
+ 0x0e) & 0x0001) == 0) && (wait
-- > 0));
781 printk(KERN_WARNING
"ISICOM: Card found busy in isicom_config_port at channel setup.\n");
784 outw(0x8000 | (channel
<< shift_count
) |0x03, base
);
785 outw(linuxb_to_isib
[baud
] << 8 | 0x03, base
);
787 switch(C_CSIZE(tty
)) {
789 channel_setup
|= ISICOM_CS5
;
792 channel_setup
|= ISICOM_CS6
;
795 channel_setup
|= ISICOM_CS7
;
798 channel_setup
|= ISICOM_CS8
;
803 channel_setup
|= ISICOM_2SB
;
806 channel_setup
|= ISICOM_EVPAR
;
808 channel_setup
|= ISICOM_ODPAR
;
809 outw(channel_setup
, base
);
810 InterruptTheCard(base
);
813 port
->flags
&= ~ASYNC_CHECK_CD
;
815 port
->flags
|= ASYNC_CHECK_CD
;
817 /* flow control settings ...*/
819 port
->flags
&= ~ASYNC_CTS_FLOW
;
820 if (C_CRTSCTS(tty
)) {
821 port
->flags
|= ASYNC_CTS_FLOW
;
822 flow_ctrl
|= ISICOM_CTSRTS
;
825 flow_ctrl
|= ISICOM_RESPOND_XONXOFF
;
827 flow_ctrl
|= ISICOM_INITIATE_XONXOFF
;
830 while (((inw(base
+ 0x0e) & 0x0001) == 0) && (wait
-- > 0));
832 printk(KERN_WARNING
"ISICOM: Card found busy in isicom_config_port at flow setup.\n");
835 outw(0x8000 | (channel
<< shift_count
) |0x04, base
);
836 outw(flow_ctrl
<< 8 | 0x05, base
);
837 outw((STOP_CHAR(tty
)) << 8 | (START_CHAR(tty
)), base
);
838 InterruptTheCard(base
);
840 /* rx enabled -> enable port for rx on the card */
842 card
->port_status
|= (1 << channel
);
843 outw(card
->port_status
, base
+ 0x02);
850 extern inline void isicom_setup_board(struct isi_board
* bp
)
853 struct isi_port
* port
;
856 if (bp
->status
& BOARD_ACTIVE
)
860 printk(KERN_DEBUG
"ISICOM: setup_board: drop_dtr_rts start, port_count %d...\n", bp
->port_count
);
862 for(channel
= 0; channel
< bp
->port_count
; channel
++, port
++) {
863 save_flags(flags
); cli();
865 restore_flags(flags
);
868 printk(KERN_DEBUG
"ISICOM: setup_board: drop_dtr_rts stop...\n");
871 bp
->status
|= BOARD_ACTIVE
;
876 static int isicom_setup_port(struct isi_port
* port
)
878 struct isi_board
* card
= port
->card
;
881 if (port
->flags
& ASYNC_INITIALIZED
)
883 if (!port
->xmit_buf
) {
886 if (!(page
= get_free_page(GFP_KERNEL
)))
889 if (port
->xmit_buf
) {
893 port
->xmit_buf
= (unsigned char *) page
;
895 save_flags(flags
); cli();
897 clear_bit(TTY_IO_ERROR
, &port
->tty
->flags
);
898 if (port
->count
== 1)
901 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
903 /* discard any residual data */
904 kill_queue(port
, ISICOM_KILLTX
| ISICOM_KILLRX
);
906 isicom_config_port(port
);
907 port
->flags
|= ASYNC_INITIALIZED
;
909 restore_flags(flags
);
914 static int block_til_ready(struct tty_struct
* tty
, struct file
* filp
, struct isi_port
* port
)
916 int do_clocal
= 0, retval
;
917 DECLARE_WAITQUEUE(wait
, current
);
919 /* block if port is in the process of being closed */
921 if (tty_hung_up_p(filp
) || port
->flags
& ASYNC_CLOSING
) {
923 printk(KERN_DEBUG
"ISICOM: block_til_ready: close in progress.\n");
925 interruptible_sleep_on(&port
->close_wait
);
926 if (port
->flags
& ASYNC_HUP_NOTIFY
)
932 /* trying to open a callout device... check for constraints */
934 if (tty
->driver
.subtype
== SERIAL_TYPE_CALLOUT
) {
936 printk(KERN_DEBUG
"ISICOM: bl_ti_rdy: callout open.\n");
938 if (port
->flags
& ASYNC_NORMAL_ACTIVE
)
940 if ((port
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
941 (port
->flags
& ASYNC_SESSION_LOCKOUT
) &&
942 (port
->session
!= current
->session
))
945 if ((port
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
946 (port
->flags
& ASYNC_PGRP_LOCKOUT
) &&
947 (port
->pgrp
!= current
->pgrp
))
949 port
->flags
|= ASYNC_CALLOUT_ACTIVE
;
956 /* if non-blocking mode is set ... */
958 if ((filp
->f_flags
& O_NONBLOCK
) || (tty
->flags
& (1 << TTY_IO_ERROR
))) {
960 printk(KERN_DEBUG
"ISICOM: block_til_ready: non-block mode.\n");
962 if (port
->flags
& ASYNC_CALLOUT_ACTIVE
)
964 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
968 if (port
->flags
& ASYNC_CALLOUT_ACTIVE
) {
969 if (port
->normal_termios
.c_cflag
& CLOCAL
)
977 printk(KERN_DEBUG
"ISICOM: block_til_ready: CLOCAL set.\n");
980 /* block waiting for DCD to be asserted, and while
981 callout dev is busy */
983 add_wait_queue(&port
->open_wait
, &wait
);
985 if (!tty_hung_up_p(filp
))
988 port
->blocked_open
++;
990 printk(KERN_DEBUG
"ISICOM: block_til_ready: waiting for DCD...\n");
994 if (!(port
->flags
& ASYNC_CALLOUT_ACTIVE
))
998 set_current_state(TASK_INTERRUPTIBLE
);
999 if (tty_hung_up_p(filp
) || !(port
->flags
& ASYNC_INITIALIZED
)) {
1000 if (port
->flags
& ASYNC_HUP_NOTIFY
)
1003 retval
= -ERESTARTSYS
;
1005 printk(KERN_DEBUG
"ISICOM: block_til_ready: tty_hung_up_p || not init.\n");
1009 if (!(port
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
1010 !(port
->flags
& ASYNC_CLOSING
) &&
1011 (do_clocal
|| (port
->status
& ISI_DCD
))) {
1013 printk(KERN_DEBUG
"ISICOM: block_til_ready: do_clocal || DCD.\n");
1017 if (signal_pending(current
)) {
1019 printk(KERN_DEBUG
"ISICOM: block_til_ready: sig blocked.\n");
1021 retval
= -ERESTARTSYS
;
1026 current
->state
= TASK_RUNNING
;
1027 remove_wait_queue(&port
->open_wait
, &wait
);
1028 if (!tty_hung_up_p(filp
))
1030 port
->blocked_open
--;
1033 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
1037 static int isicom_open(struct tty_struct
* tty
, struct file
* filp
)
1039 struct isi_port
* port
;
1040 struct isi_board
* card
;
1041 unsigned int line
, board
;
1042 unsigned long flags
;
1046 printk(KERN_DEBUG
"ISICOM: open start!!!.\n");
1048 line
= MINOR(tty
->device
) - tty
->driver
.minor_start
;
1051 printk(KERN_DEBUG
"line = %d.\n", line
);
1054 if ((line
< 0) || (line
> (PORT_COUNT
-1)))
1056 board
= BOARD(line
);
1059 printk(KERN_DEBUG
"board = %d.\n", board
);
1062 card
= &isi_card
[board
];
1063 if (!(card
->status
& FIRMWARE_LOADED
)) {
1065 printk(KERN_DEBUG
"ISICOM: Firmware not loaded to card%d.\n", board
);
1070 /* open on a port greater than the port count for the card !!! */
1071 if (line
> ((board
* 16) + card
->port_count
- 1)) {
1072 printk(KERN_ERR
"ISICOM: Open on a port which exceeds the port_count of the card!\n");
1075 port
= &isi_ports
[line
];
1076 if (isicom_paranoia_check(port
, tty
->device
, "isicom_open"))
1080 printk(KERN_DEBUG
"ISICOM: isicom_setup_board ...\n");
1082 isicom_setup_board(card
);
1085 tty
->driver_data
= port
;
1088 printk(KERN_DEBUG
"ISICOM: isicom_setup_port ...\n");
1090 if ((error
= isicom_setup_port(port
))!=0)
1093 printk(KERN_DEBUG
"ISICOM: block_til_ready ...\n");
1095 if ((error
= block_til_ready(tty
, filp
, port
))!=0)
1098 if ((port
->count
== 1) && (port
->flags
& ASYNC_SPLIT_TERMIOS
)) {
1099 if (tty
->driver
.subtype
== SERIAL_TYPE_NORMAL
)
1100 *tty
->termios
= port
->normal_termios
;
1102 *tty
->termios
= port
->callout_termios
;
1103 save_flags(flags
); cli();
1104 isicom_config_port(port
);
1105 restore_flags(flags
);
1108 port
->session
= current
->session
;
1109 port
->pgrp
= current
->pgrp
;
1111 printk(KERN_DEBUG
"ISICOM: open end!!!.\n");
1118 extern inline void isicom_shutdown_board(struct isi_board
* bp
)
1121 struct isi_port
* port
;
1123 if (!(bp
->status
& BOARD_ACTIVE
))
1125 bp
->status
&= ~BOARD_ACTIVE
;
1127 for(channel
= 0; channel
< bp
->port_count
; channel
++, port
++) {
1133 static void isicom_shutdown_port(struct isi_port
* port
)
1135 struct isi_board
* card
= port
->card
;
1136 struct tty_struct
* tty
;
1138 if (!(port
->flags
& ASYNC_INITIALIZED
))
1140 if (port
->xmit_buf
) {
1141 free_page((unsigned long) port
->xmit_buf
);
1142 port
->xmit_buf
= NULL
;
1144 if (!(tty
= port
->tty
) || C_HUPCL(tty
))
1145 /* drop dtr on this port */
1148 /* any other port uninits */
1151 set_bit(TTY_IO_ERROR
, &tty
->flags
);
1152 port
->flags
&= ~ASYNC_INITIALIZED
;
1154 if (--card
->count
< 0) {
1155 printk(KERN_DEBUG
"ISICOM: isicom_shutdown_port: bad board(0x%x) count %d.\n",
1156 card
->base
, card
->count
);
1160 /* last port was closed , shutdown that boad too */
1162 isicom_shutdown_board(card
);
1165 static void isicom_close(struct tty_struct
* tty
, struct file
* filp
)
1167 struct isi_port
* port
= (struct isi_port
*) tty
->driver_data
;
1168 struct isi_board
* card
= port
->card
;
1169 unsigned long flags
;
1173 if (isicom_paranoia_check(port
, tty
->device
, "isicom_close"))
1177 printk(KERN_DEBUG
"ISICOM: Close start!!!.\n");
1180 save_flags(flags
); cli();
1181 if (tty_hung_up_p(filp
)) {
1182 restore_flags(flags
);
1186 if ((tty
->count
== 1) && (port
->count
!= 1)) {
1187 printk(KERN_WARNING
"ISICOM:(0x%x) isicom_close: bad port count"
1188 "tty->count = 1 port count = %d.\n",
1189 card
->base
, port
->count
);
1192 if (--port
->count
< 0) {
1193 printk(KERN_WARNING
"ISICOM:(0x%x) isicom_close: bad port count for"
1194 "channel%d = %d", card
->base
, port
->channel
,
1200 restore_flags(flags
);
1203 port
->flags
|= ASYNC_CLOSING
;
1205 * save termios struct since callout and dialin termios may be
1208 if (port
->flags
& ASYNC_NORMAL_ACTIVE
)
1209 port
->normal_termios
= *tty
->termios
;
1210 if (port
->flags
& ASYNC_CALLOUT_ACTIVE
)
1211 port
->callout_termios
= *tty
->termios
;
1214 if (port
->closing_wait
!= ASYNC_CLOSING_WAIT_NONE
)
1215 tty_wait_until_sent(tty
, port
->closing_wait
);
1216 /* indicate to the card that no more data can be received
1218 if (port
->flags
& ASYNC_INITIALIZED
) {
1219 card
->port_status
&= ~(1 << port
->channel
);
1220 outw(card
->port_status
, card
->base
+ 0x02);
1222 isicom_shutdown_port(port
);
1223 if (tty
->driver
.flush_buffer
)
1224 tty
->driver
.flush_buffer(tty
);
1225 if (tty
->ldisc
.flush_buffer
)
1226 tty
->ldisc
.flush_buffer(tty
);
1229 if (port
->blocked_open
) {
1230 if (port
->close_delay
) {
1231 current
->state
= TASK_INTERRUPTIBLE
;
1233 printk(KERN_DEBUG
"ISICOM: scheduling until time out.\n");
1235 schedule_timeout(port
->close_delay
);
1237 wake_up_interruptible(&port
->open_wait
);
1239 port
->flags
&= ~(ASYNC_NORMAL_ACTIVE
| ASYNC_CALLOUT_ACTIVE
|
1241 wake_up_interruptible(&port
->close_wait
);
1242 restore_flags(flags
);
1244 printk(KERN_DEBUG
"ISICOM: Close end!!!.\n");
1249 static int isicom_write(struct tty_struct
* tty
, int from_user
,
1250 const unsigned char * buf
, int count
)
1252 struct isi_port
* port
= (struct isi_port
*) tty
->driver_data
;
1253 unsigned long flags
;
1256 printk(KERN_DEBUG
"ISICOM: isicom_write for port%d: %d bytes.\n",
1257 port
->channel
+1, count
);
1259 if (isicom_paranoia_check(port
, tty
->device
, "isicom_write"))
1262 if (!tty
|| !port
->xmit_buf
|| !tmp_buf
)
1265 down(&tmp_buf_sem
); /* acquire xclusive access to tmp_buf */
1270 cnt
= MIN(count
, MIN(SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1,
1271 SERIAL_XMIT_SIZE
- port
->xmit_head
));
1276 /* the following may block for paging... hence
1277 enabling interrupts but tx routine may have
1278 created more space in xmit_buf when the ctrl
1281 copy_from_user(tmp_buf
, buf
, cnt
);
1283 cnt
= MIN(cnt
, MIN(SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1,
1284 SERIAL_XMIT_SIZE
- port
->xmit_head
));
1285 memcpy(port
->xmit_buf
+ port
->xmit_head
, tmp_buf
, cnt
);
1288 memcpy(port
->xmit_buf
+ port
->xmit_head
, buf
, cnt
);
1289 port
->xmit_head
= (port
->xmit_head
+ cnt
) & (SERIAL_XMIT_SIZE
- 1);
1290 port
->xmit_cnt
+= cnt
;
1291 restore_flags(flags
);
1298 if (port
->xmit_cnt
&& !tty
->stopped
&& !tty
->hw_stopped
)
1299 port
->status
|= ISI_TXOK
;
1300 restore_flags(flags
);
1302 printk(KERN_DEBUG
"ISICOM: isicom_write %d bytes written.\n", total
);
1307 /* put_char et all */
1308 static void isicom_put_char(struct tty_struct
* tty
, unsigned char ch
)
1310 struct isi_port
* port
= (struct isi_port
*) tty
->driver_data
;
1311 unsigned long flags
;
1313 if (isicom_paranoia_check(port
, tty
->device
, "isicom_put_char"))
1316 if (!tty
|| !port
->xmit_buf
)
1319 printk(KERN_DEBUG
"ISICOM: put_char, port %d, char %c.\n", port
->channel
+1, ch
);
1322 save_flags(flags
); cli();
1324 if (port
->xmit_cnt
>= (SERIAL_XMIT_SIZE
- 1)) {
1325 restore_flags(flags
);
1329 port
->xmit_buf
[port
->xmit_head
++] = ch
;
1330 port
->xmit_head
&= (SERIAL_XMIT_SIZE
- 1);
1332 restore_flags(flags
);
1335 /* flush_chars et all */
1336 static void isicom_flush_chars(struct tty_struct
* tty
)
1338 struct isi_port
* port
= (struct isi_port
*) tty
->driver_data
;
1340 if (isicom_paranoia_check(port
, tty
->device
, "isicom_flush_chars"))
1343 if (port
->xmit_cnt
<= 0 || tty
->stopped
|| tty
->hw_stopped
||
1347 /* this tells the transmitter to consider this port for
1348 data output to the card ... that's the best we can do. */
1349 port
->status
|= ISI_TXOK
;
1352 /* write_room et all */
1353 static int isicom_write_room(struct tty_struct
* tty
)
1355 struct isi_port
* port
= (struct isi_port
*) tty
->driver_data
;
1357 if (isicom_paranoia_check(port
, tty
->device
, "isicom_write_room"))
1360 free
= SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1;
1366 /* chars_in_buffer et all */
1367 static int isicom_chars_in_buffer(struct tty_struct
* tty
)
1369 struct isi_port
* port
= (struct isi_port
*) tty
->driver_data
;
1370 if (isicom_paranoia_check(port
, tty
->device
, "isicom_chars_in_buffer"))
1372 return port
->xmit_cnt
;
1376 extern inline void isicom_send_break(struct isi_port
* port
, unsigned long length
)
1378 struct isi_board
* card
= port
->card
;
1380 unsigned short base
= card
->base
;
1381 unsigned long flags
;
1383 save_flags(flags
); cli();
1384 while (((inw(base
+ 0x0e) & 0x0001) == 0) && (wait
-- > 0));
1386 printk(KERN_DEBUG
"ISICOM: Card found busy in isicom_send_break.\n");
1389 outw(0x8000 | ((port
->channel
) << (card
->shift_count
)) | 0x3, base
);
1390 outw((length
& 0xff) << 8 | 0x00, base
);
1391 outw((length
& 0xff00), base
);
1392 InterruptTheCard(base
);
1393 restore_flags(flags
);
1396 static int isicom_get_modem_info(struct isi_port
* port
, unsigned int * value
)
1398 /* just send the port status */
1400 unsigned short status
= port
->status
;
1402 info
= ((status
& ISI_RTS
) ? TIOCM_RTS
: 0) |
1403 ((status
& ISI_DTR
) ? TIOCM_DTR
: 0) |
1404 ((status
& ISI_DCD
) ? TIOCM_CAR
: 0) |
1405 ((status
& ISI_DSR
) ? TIOCM_DSR
: 0) |
1406 ((status
& ISI_CTS
) ? TIOCM_CTS
: 0) |
1407 ((status
& ISI_RI
) ? TIOCM_RI
: 0);
1408 put_user(info
, (unsigned int *) value
);
1412 static int isicom_set_modem_info(struct isi_port
* port
, unsigned int cmd
,
1413 unsigned int * value
)
1416 unsigned long flags
;
1418 if(get_user(arg
, value
))
1421 save_flags(flags
); cli();
1425 if (arg
& TIOCM_RTS
)
1427 if (arg
& TIOCM_DTR
)
1432 if (arg
& TIOCM_RTS
)
1434 if (arg
& TIOCM_DTR
)
1439 if (arg
& TIOCM_RTS
)
1444 if (arg
& TIOCM_DTR
)
1451 restore_flags(flags
);
1454 restore_flags(flags
);
1458 static int isicom_set_serial_info(struct isi_port
* port
,
1459 struct serial_struct
* info
)
1461 struct serial_struct newinfo
;
1462 unsigned long flags
;
1465 if(copy_from_user(&newinfo
, info
, sizeof(newinfo
)))
1468 reconfig_port
= ((port
->flags
& ASYNC_SPD_MASK
) !=
1469 (newinfo
.flags
& ASYNC_SPD_MASK
));
1472 if ((newinfo
.close_delay
!= port
->close_delay
) ||
1473 (newinfo
.closing_wait
!= port
->closing_wait
) ||
1474 ((newinfo
.flags
& ~ASYNC_USR_MASK
) !=
1475 (port
->flags
& ~ASYNC_USR_MASK
)))
1477 port
->flags
= ((port
->flags
& ~ ASYNC_USR_MASK
) |
1478 (newinfo
.flags
& ASYNC_USR_MASK
));
1481 port
->close_delay
= newinfo
.close_delay
;
1482 port
->closing_wait
= newinfo
.closing_wait
;
1483 port
->flags
= ((port
->flags
& ~ASYNC_FLAGS
) |
1484 (newinfo
.flags
& ASYNC_FLAGS
));
1486 if (reconfig_port
) {
1487 save_flags(flags
); cli();
1488 isicom_config_port(port
);
1489 restore_flags(flags
);
1494 static int isicom_get_serial_info(struct isi_port
* port
,
1495 struct serial_struct
* info
)
1497 struct serial_struct out_info
;
1499 memset(&out_info
, 0, sizeof(out_info
));
1500 /* out_info.type = ? */
1501 out_info
.line
= port
- isi_ports
;
1502 out_info
.port
= port
->card
->base
;
1503 out_info
.irq
= port
->card
->irq
;
1504 out_info
.flags
= port
->flags
;
1505 /* out_info.baud_base = ? */
1506 out_info
.close_delay
= port
->close_delay
;
1507 out_info
.closing_wait
= port
->closing_wait
;
1508 if(copy_to_user(info
, &out_info
, sizeof(out_info
)))
1513 static int isicom_ioctl(struct tty_struct
* tty
, struct file
* filp
,
1514 unsigned int cmd
, unsigned long arg
)
1516 struct isi_port
* port
= (struct isi_port
*) tty
->driver_data
;
1519 if (isicom_paranoia_check(port
, tty
->device
, "isicom_ioctl"))
1524 retval
= tty_check_change(tty
);
1527 tty_wait_until_sent(tty
, 0);
1529 isicom_send_break(port
, HZ
/4);
1533 retval
= tty_check_change(tty
);
1536 tty_wait_until_sent(tty
, 0);
1537 isicom_send_break(port
, arg
? arg
* (HZ
/10) : HZ
/4);
1541 return put_user(C_CLOCAL(tty
) ? 1 : 0, (unsigned long *) arg
);
1544 if(get_user(arg
, (unsigned long *) arg
))
1546 tty
->termios
->c_cflag
=
1547 ((tty
->termios
->c_cflag
& ~CLOCAL
) |
1548 (arg
? CLOCAL
: 0));
1552 return isicom_get_modem_info(port
, (unsigned int*) arg
);
1557 return isicom_set_modem_info(port
, cmd
,
1558 (unsigned int *) arg
);
1561 return isicom_get_serial_info(port
,
1562 (struct serial_struct
*) arg
);
1565 return isicom_set_serial_info(port
,
1566 (struct serial_struct
*) arg
);
1569 return -ENOIOCTLCMD
;
1574 /* set_termios et all */
1575 static void isicom_set_termios(struct tty_struct
* tty
, struct termios
* old_termios
)
1577 struct isi_port
* port
= (struct isi_port
*) tty
->driver_data
;
1578 unsigned long flags
;
1580 if (isicom_paranoia_check(port
, tty
->device
, "isicom_set_termios"))
1583 if (tty
->termios
->c_cflag
== old_termios
->c_cflag
&&
1584 tty
->termios
->c_iflag
== old_termios
->c_iflag
)
1587 save_flags(flags
); cli();
1588 isicom_config_port(port
);
1589 restore_flags(flags
);
1591 if ((old_termios
->c_cflag
& CRTSCTS
) &&
1592 !(tty
->termios
->c_cflag
& CRTSCTS
)) {
1593 tty
->hw_stopped
= 0;
1598 /* throttle et all */
1599 static void isicom_throttle(struct tty_struct
* tty
)
1601 struct isi_port
* port
= (struct isi_port
*) tty
->driver_data
;
1602 struct isi_board
* card
= port
->card
;
1603 unsigned long flags
;
1605 if (isicom_paranoia_check(port
, tty
->device
, "isicom_throttle"))
1608 /* tell the card that this port cannot handle any more data for now */
1609 save_flags(flags
); cli();
1610 card
->port_status
&= ~(1 << port
->channel
);
1611 outw(card
->port_status
, card
->base
+ 0x02);
1612 restore_flags(flags
);
1615 /* unthrottle et all */
1616 static void isicom_unthrottle(struct tty_struct
* tty
)
1618 struct isi_port
* port
= (struct isi_port
*) tty
->driver_data
;
1619 struct isi_board
* card
= port
->card
;
1620 unsigned long flags
;
1622 if (isicom_paranoia_check(port
, tty
->device
, "isicom_unthrottle"))
1625 /* tell the card that this port is ready to accept more data */
1626 save_flags(flags
); cli();
1627 card
->port_status
|= (1 << port
->channel
);
1628 outw(card
->port_status
, card
->base
+ 0x02);
1629 restore_flags(flags
);
1633 static void isicom_stop(struct tty_struct
* tty
)
1635 struct isi_port
* port
= (struct isi_port
*) tty
->driver_data
;
1637 if (isicom_paranoia_check(port
, tty
->device
, "isicom_stop"))
1640 /* this tells the transmitter not to consider this port for
1641 data output to the card. */
1642 port
->status
&= ~ISI_TXOK
;
1646 static void isicom_start(struct tty_struct
* tty
)
1648 struct isi_port
* port
= (struct isi_port
*) tty
->driver_data
;
1650 if (isicom_paranoia_check(port
, tty
->device
, "isicom_start"))
1653 /* this tells the transmitter to consider this port for
1654 data output to the card. */
1655 port
->status
|= ISI_TXOK
;
1659 static void do_isicom_hangup(void * data
)
1661 struct isi_port
* port
= (struct isi_port
*) data
;
1662 struct tty_struct
* tty
;
1671 static void isicom_hangup(struct tty_struct
* tty
)
1673 struct isi_port
* port
= (struct isi_port
*) tty
->driver_data
;
1675 if (isicom_paranoia_check(port
, tty
->device
, "isicom_hangup"))
1678 isicom_shutdown_port(port
);
1680 port
->flags
&= ~(ASYNC_NORMAL_ACTIVE
| ASYNC_CALLOUT_ACTIVE
);
1682 wake_up_interruptible(&port
->open_wait
);
1685 /* flush_buffer et all */
1686 static void isicom_flush_buffer(struct tty_struct
* tty
)
1688 struct isi_port
* port
= (struct isi_port
*) tty
->driver_data
;
1689 unsigned long flags
;
1691 if (isicom_paranoia_check(port
, tty
->device
, "isicom_flush_buffer"))
1694 save_flags(flags
); cli();
1695 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1696 restore_flags(flags
);
1698 wake_up_interruptible(&tty
->write_wait
);
1699 if ((tty
->flags
& (1 << TTY_DO_WRITE_WAKEUP
)) &&
1700 tty
->ldisc
.write_wakeup
)
1701 (tty
->ldisc
.write_wakeup
)(tty
);
1705 static int register_ioregion(void)
1708 for (count
=0; count
< BOARD_COUNT
; count
++ ) {
1709 if (isi_card
[count
].base
) {
1710 if (check_region(isi_card
[count
].base
,16)) {
1711 printk(KERN_DEBUG
"ISICOM: I/O Region 0x%x-0x%x is busy. Card%d will be disabled.\n",
1712 isi_card
[count
].base
,isi_card
[count
].base
+15,count
+1);
1713 isi_card
[count
].base
=0;
1716 request_region(isi_card
[count
].base
,16,ISICOM_NAME
);
1718 printk(KERN_DEBUG
"ISICOM: I/O Region 0x%x-0x%x requested for Card%d.\n",isi_card
[count
].base
,isi_card
[count
].base
+15,count
+1);
1727 static void unregister_ioregion(void)
1730 for (count
=0; count
< BOARD_COUNT
; count
++ )
1731 if (isi_card
[count
].base
) {
1732 release_region(isi_card
[count
].base
,16);
1734 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);
1739 static int register_drivers(void)
1743 /* tty driver structure initialization */
1744 memset(&isicom_normal
, 0, sizeof(struct tty_driver
));
1745 isicom_normal
.magic
= TTY_DRIVER_MAGIC
;
1746 isicom_normal
.name
= "ttyM";
1747 isicom_normal
.major
= ISICOM_NMAJOR
;
1748 isicom_normal
.minor_start
= 0;
1749 isicom_normal
.num
= PORT_COUNT
;
1750 isicom_normal
.type
= TTY_DRIVER_TYPE_SERIAL
;
1751 isicom_normal
.subtype
= SERIAL_TYPE_NORMAL
;
1752 isicom_normal
.init_termios
= tty_std_termios
;
1753 isicom_normal
.init_termios
.c_cflag
=
1754 B9600
| CS8
| CREAD
| HUPCL
|CLOCAL
;
1755 isicom_normal
.flags
= TTY_DRIVER_REAL_RAW
;
1756 isicom_normal
.refcount
= &isicom_refcount
;
1758 isicom_normal
.table
= isicom_table
;
1759 isicom_normal
.termios
= isicom_termios
;
1760 isicom_normal
.termios_locked
= isicom_termios_locked
;
1762 isicom_normal
.open
= isicom_open
;
1763 isicom_normal
.close
= isicom_close
;
1764 isicom_normal
.write
= isicom_write
;
1765 isicom_normal
.put_char
= isicom_put_char
;
1766 isicom_normal
.flush_chars
= isicom_flush_chars
;
1767 isicom_normal
.write_room
= isicom_write_room
;
1768 isicom_normal
.chars_in_buffer
= isicom_chars_in_buffer
;
1769 isicom_normal
.ioctl
= isicom_ioctl
;
1770 isicom_normal
.set_termios
= isicom_set_termios
;
1771 isicom_normal
.throttle
= isicom_throttle
;
1772 isicom_normal
.unthrottle
= isicom_unthrottle
;
1773 isicom_normal
.stop
= isicom_stop
;
1774 isicom_normal
.start
= isicom_start
;
1775 isicom_normal
.hangup
= isicom_hangup
;
1776 isicom_normal
.flush_buffer
= isicom_flush_buffer
;
1778 /* callout device */
1780 isicom_callout
= isicom_normal
;
1781 isicom_callout
.name
= "cum";
1782 isicom_callout
.major
= ISICOM_CMAJOR
;
1783 isicom_callout
.subtype
= SERIAL_TYPE_CALLOUT
;
1785 if ((error
=tty_register_driver(&isicom_normal
))!=0) {
1786 printk(KERN_DEBUG
"ISICOM: Couldn't register the dialin driver, error=%d\n",
1790 if ((error
=tty_register_driver(&isicom_callout
))!=0) {
1791 tty_unregister_driver(&isicom_normal
);
1792 printk(KERN_DEBUG
"ISICOM: Couldn't register the callout driver, error=%d\n",
1799 static void unregister_drivers(void)
1802 if ((error
=tty_unregister_driver(&isicom_callout
))!=0)
1803 printk(KERN_DEBUG
"ISICOM: couldn't unregister callout driver error=%d.\n",error
);
1804 if (tty_unregister_driver(&isicom_normal
))
1805 printk(KERN_DEBUG
"ISICOM: couldn't unregister normal driver error=%d.\n",error
);
1808 static int register_isr(void)
1810 int count
, done
=0, card
;
1812 unsigned char request
;
1813 for (count
=0; count
< BOARD_COUNT
; count
++ ) {
1814 if (isi_card
[count
].base
) {
1816 * verify if the required irq has already been requested for
1817 * another ISI Card, if so we already have it, else request it
1820 for(card
= 0; card
< count
; card
++)
1821 if ((isi_card
[card
].base
) && (isi_card
[card
].irq
== isi_card
[count
].irq
)) {
1823 if ((isi_card
[count
].isa
== NO
) && (isi_card
[card
].isa
== NO
))
1826 * ISA cards cannot share interrupts with other
1827 * PCI or ISA devices hence disable this card.
1829 release_region(isi_card
[count
].base
,16);
1830 isi_card
[count
].base
= 0;
1834 if(isi_card
[count
].isa
== NO
)
1837 if (request
== YES
) {
1838 if (request_irq(isi_card
[count
].irq
, isicom_interrupt
, SA_INTERRUPT
|flag
, ISICOM_NAME
, NULL
)) {
1839 printk(KERN_WARNING
"ISICOM: Could not install handler at Irq %d. Card%d will be disabled.\n",
1840 isi_card
[count
].irq
, count
+1);
1841 release_region(isi_card
[count
].base
,16);
1842 isi_card
[count
].base
=0;
1845 printk(KERN_INFO
"ISICOM: Card%d at 0x%x using irq %d.\n",
1846 count
+1, isi_card
[count
].base
, isi_card
[count
].irq
);
1848 irq_to_board
[isi_card
[count
].irq
]=&isi_card
[count
];
1857 static void unregister_isr(void)
1860 unsigned char freeirq
;
1861 for (count
=0; count
< BOARD_COUNT
; count
++ ) {
1862 if (isi_card
[count
].base
) {
1864 for(card
= 0; card
< count
; card
++)
1865 if ((isi_card
[card
].base
) && (isi_card
[card
].irq
== isi_card
[count
].irq
)) {
1869 if (freeirq
== YES
) {
1870 free_irq(isi_card
[count
].irq
, NULL
);
1872 printk(KERN_DEBUG
"ISICOM: Irq %d released for Card%d.\n",isi_card
[count
].irq
, count
+1);
1879 static int isicom_init(void)
1881 int card
, channel
, base
;
1882 struct isi_port
* port
;
1886 page
= get_free_page(GFP_KERNEL
);
1889 printk(KERN_DEBUG
"ISICOM: Couldn't allocate page for tmp_buf.\n");
1891 printk(KERN_ERR
"ISICOM: Not enough memory...\n");
1895 tmp_buf
= (unsigned char *) page
;
1898 if (!register_ioregion())
1900 printk(KERN_ERR
"ISICOM: All required I/O space found busy.\n");
1901 free_page((unsigned long)tmp_buf
);
1904 if (register_drivers())
1906 unregister_ioregion();
1907 free_page((unsigned long)tmp_buf
);
1910 if (!register_isr())
1912 unregister_drivers();
1913 /* ioports already uregistered in register_isr */
1914 free_page((unsigned long)tmp_buf
);
1918 /* initialize bottom half */
1919 init_bh(ISICOM_BH
, do_isicom_bh
);
1922 memset(isi_ports
, 0, sizeof(isi_ports
));
1923 for (card
= 0; card
< BOARD_COUNT
; card
++) {
1924 port
= &isi_ports
[card
* 16];
1925 isi_card
[card
].ports
= port
;
1926 base
= isi_card
[card
].base
;
1927 for (channel
= 0; channel
< 16; channel
++, port
++) {
1928 port
->magic
= ISICOM_MAGIC
;
1929 port
->card
= &isi_card
[card
];
1930 port
->channel
= channel
;
1931 port
->normal_termios
= isicom_normal
.init_termios
;
1932 port
->callout_termios
= isicom_callout
.init_termios
;
1933 port
->close_delay
= 50 * HZ
/100;
1934 port
->closing_wait
= 3000 * HZ
/100;
1935 port
->hangup_tq
.routine
= do_isicom_hangup
;
1936 port
->hangup_tq
.data
= port
;
1937 port
->bh_tqueue
.routine
= isicom_bottomhalf
;
1938 port
->bh_tqueue
.data
= port
;
1940 init_waitqueue_head(&port
->open_wait
);
1941 init_waitqueue_head(&port
->close_wait
);
1950 * Insmod can set static symbols so keep these static
1956 MODULE_AUTHOR("MultiTech");
1957 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
1958 MODULE_PARM(io
, "1-4i");
1959 MODULE_PARM_DESC(io
, "I/O ports for the cards");
1960 MODULE_PARM(irq
, "1-4i");
1961 MODULE_PARM_DESC(irq
, "Interrupts for the cards");
1963 int init_module(void)
1965 struct pci_dev
*dev
= NULL
;
1966 int retval
, card
, idx
, count
;
1967 unsigned char pciirq
;
1968 unsigned int ioaddr
;
1971 for(idx
=0; idx
< BOARD_COUNT
; idx
++) {
1973 isi_card
[idx
].base
=io
[idx
];
1974 isi_card
[idx
].irq
=irq
[idx
];
1975 isi_card
[idx
].isa
=YES
;
1979 isi_card
[idx
].base
= 0;
1980 isi_card
[idx
].irq
= 0;
1984 for (idx
=0 ;idx
< card
; idx
++) {
1985 if (!((isi_card
[idx
].irq
==2)||(isi_card
[idx
].irq
==3)||
1986 (isi_card
[idx
].irq
==4)||(isi_card
[idx
].irq
==5)||
1987 (isi_card
[idx
].irq
==7)||(isi_card
[idx
].irq
==10)||
1988 (isi_card
[idx
].irq
==11)||(isi_card
[idx
].irq
==12)||
1989 (isi_card
[idx
].irq
==15))) {
1991 if (isi_card
[idx
].base
) {
1992 printk(KERN_ERR
"ISICOM: Irq %d unsupported. Disabling Card%d...\n",
1993 isi_card
[idx
].irq
, idx
+1);
1994 isi_card
[idx
].base
=0;
2000 if (pci_present() && (card
< BOARD_COUNT
)) {
2001 for (idx
=0; idx
< DEVID_COUNT
; idx
++) {
2004 if (!(dev
= pci_find_device(VENDOR_ID
, device_id
[idx
], dev
)))
2006 if (card
>= BOARD_COUNT
)
2009 /* found a PCI ISI card! */
2010 ioaddr
= dev
->resource
[3].start
; /* i.e at offset 0x1c in the
2011 * PCI configuration register
2014 ioaddr
&= PCI_BASE_ADDRESS_IO_MASK
;
2016 printk(KERN_INFO
"ISI PCI Card(Device ID 0x%x)\n", device_id
[idx
]);
2018 * allot the first empty slot in the array
2020 for (count
=0; count
< BOARD_COUNT
; count
++) {
2021 if (isi_card
[count
].base
== 0) {
2022 isi_card
[count
].base
= ioaddr
;
2023 isi_card
[count
].irq
= pciirq
;
2024 isi_card
[count
].isa
= NO
;
2030 if (card
>= BOARD_COUNT
) break;
2034 if (!(isi_card
[0].base
|| isi_card
[1].base
|| isi_card
[2].base
|| isi_card
[3].base
)) {
2035 printk(KERN_ERR
"ISICOM: No valid card configuration. Driver cannot be initialized...\n");
2038 retval
=misc_register(&isiloader_device
);
2040 printk(KERN_ERR
"ISICOM: Unable to register firmware loader driver.\n");
2044 if (!isicom_init()) {
2045 if (misc_deregister(&isiloader_device
))
2046 printk(KERN_ERR
"ISICOM: Unable to unregister Firmware Loader driver\n");
2051 tx
.expires
= jiffies
+ 1;
2053 tx
.function
= isicom_tx
;
2060 void cleanup_module(void)
2063 current
->state
= TASK_INTERRUPTIBLE
;
2064 schedule_timeout(HZ
);
2065 disable_bh(ISICOM_BH
);
2068 printk("ISICOM: isicom_tx tx_count = %ld.\n", tx_count
);
2072 printk("ISICOM: uregistering isr ...\n");
2077 printk("ISICOM: unregistering drivers ...\n");
2079 unregister_drivers();
2082 printk("ISICOM: unregistering ioregion ...\n");
2084 unregister_ioregion();
2087 printk("ISICOM: freeing tmp_buf ...\n");
2089 free_page((unsigned long)tmp_buf
);
2092 printk("ISICOM: unregistering firmware loader ...\n");
2094 if (misc_deregister(&isiloader_device
))
2095 printk(KERN_ERR
"ISICOM: Unable to unregister Firmware Loader driver\n");