Commit 0b064cdf authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] Resurrect ISICOM serial

The isicom driver had bitrotted badly and although it had some 2.6
cleanup work didn't actually do anything useful.  ISIcom had their own
2.4 driver which didn't work with 2.6 either but had done the hard work
like the locking rewrites.  So I nailed them together and then fixed
some obvious bugs in the ISIcom driver version.
parent e34626dd
......@@ -203,7 +203,7 @@ config MOXA_SMARTIO
config ISI
tristate "Multi-Tech multiport card support (EXPERIMENTAL)"
depends on SERIAL_NONSTANDARD && PCI && EXPERIMENTAL && BROKEN_ON_SMP && m
depends on SERIAL_NONSTANDARD
help
This is a driver for the Multi-Tech cards which provide several
serial ports. The driver is experimental and can currently only be
......
This diff is collapsed.
......@@ -125,179 +125,6 @@ typedef struct {
#define ISI_TXOK 0x0001
struct isi_board {
unsigned short base;
unsigned char irq;
unsigned char port_count;
unsigned short status;
unsigned short port_status; /* each bit represents a single port */
unsigned short shift_count;
struct isi_port * ports;
signed char count;
unsigned char isa;
};
struct isi_port {
unsigned short magic;
unsigned int flags;
int count;
int blocked_open;
int close_delay;
unsigned short channel;
unsigned short status;
unsigned short closing_wait;
struct isi_board * card;
struct tty_struct * tty;
wait_queue_head_t close_wait;
wait_queue_head_t open_wait;
struct work_struct hangup_tq;
struct work_struct bh_tqueue;
unsigned char * xmit_buf;
int xmit_head;
int xmit_tail;
int xmit_cnt;
};
/*
* ISI Card specific ops ...
*/
static inline void raise_dtr(struct isi_port * port)
{
struct isi_board * card = port->card;
unsigned short base = card->base;
unsigned char channel = port->channel;
short wait=400;
while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
if (wait <= 0) {
printk(KERN_WARNING "ISICOM: Card found busy in raise_dtr.\n");
return;
}
#ifdef ISICOM_DEBUG_DTR_RTS
printk(KERN_DEBUG "ISICOM: raise_dtr.\n");
#endif
outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
outw(0x0504, base);
InterruptTheCard(base);
port->status |= ISI_DTR;
}
static inline void drop_dtr(struct isi_port * port)
{
struct isi_board * card = port->card;
unsigned short base = card->base;
unsigned char channel = port->channel;
short wait=400;
while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
if (wait <= 0) {
printk(KERN_WARNING "ISICOM: Card found busy in drop_dtr.\n");
return;
}
#ifdef ISICOM_DEBUG_DTR_RTS
printk(KERN_DEBUG "ISICOM: drop_dtr.\n");
#endif
outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
outw(0x0404, base);
InterruptTheCard(base);
port->status &= ~ISI_DTR;
}
static inline void raise_rts(struct isi_port * port)
{
struct isi_board * card = port->card;
unsigned short base = card->base;
unsigned char channel = port->channel;
short wait=400;
while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
if (wait <= 0) {
printk(KERN_WARNING "ISICOM: Card found busy in raise_rts.\n");
return;
}
#ifdef ISICOM_DEBUG_DTR_RTS
printk(KERN_DEBUG "ISICOM: raise_rts.\n");
#endif
outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
outw(0x0a04, base);
InterruptTheCard(base);
port->status |= ISI_RTS;
}
static inline void drop_rts(struct isi_port * port)
{
struct isi_board * card = port->card;
unsigned short base = card->base;
unsigned char channel = port->channel;
short wait=400;
while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
if (wait <= 0) {
printk(KERN_WARNING "ISICOM: Card found busy in drop_rts.\n");
return;
}
#ifdef ISICOM_DEBUG_DTR_RTS
printk(KERN_DEBUG "ISICOM: drop_rts.\n");
#endif
outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
outw(0x0804, base);
InterruptTheCard(base);
port->status &= ~ISI_RTS;
}
static inline void raise_dtr_rts(struct isi_port * port)
{
struct isi_board * card = port->card;
unsigned short base = card->base;
unsigned char channel = port->channel;
short wait=400;
while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
if (wait <= 0) {
printk(KERN_WARNING "ISICOM: Card found busy in raise_dtr_rts.\n");
return;
}
#ifdef ISICOM_DEBUG_DTR_RTS
printk(KERN_DEBUG "ISICOM: raise_dtr_rts.\n");
#endif
outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
outw(0x0f04, base);
InterruptTheCard(base);
port->status |= (ISI_DTR | ISI_RTS);
}
static inline void drop_dtr_rts(struct isi_port * port)
{
struct isi_board * card = port->card;
unsigned short base = card->base;
unsigned char channel = port->channel;
short wait=400;
while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
if (wait <= 0) {
printk(KERN_WARNING "ISICOM: Card found busy in drop_dtr_rts.\n");
return;
}
#ifdef ISICOM_DEBUG_DTR_RTS
printk(KERN_DEBUG "ISICOM: drop_dtr_rts.\n");
#endif
outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
outw(0x0c04, base);
InterruptTheCard(base);
port->status &= ~(ISI_RTS | ISI_DTR);
}
static inline void kill_queue(struct isi_port * port, short queue)
{
struct isi_board * card = port->card;
unsigned short base = card->base;
unsigned char channel = port->channel;
short wait=400;
while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
if (wait <= 0) {
printk(KERN_WARNING "ISICOM: Card found busy in kill_queue.\n");
return;
}
#ifdef ISICOM_DEBUG
printk(KERN_DEBUG "ISICOM: kill_queue 0x%x.\n", queue);
#endif
outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
outw((queue << 8) | 0x06, base);
InterruptTheCard(base);
}
#endif /* __KERNEL__ */
#endif /* ISICOM_H */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment