diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-04-28 01:09:25 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-04-28 01:09:25 +0000 |
commit | b9ba7aeb165cffecdffb60aec8c3fa8d590d9ca9 (patch) | |
tree | 42d07b0c7246ae2536a702e7c5de9e2732341116 /drivers/char/sx.c | |
parent | 7406b0a326f2d70ade2671c37d1beef62249db97 (diff) |
Merge with 2.3.99-pre6.
Diffstat (limited to 'drivers/char/sx.c')
-rw-r--r-- | drivers/char/sx.c | 66 |
1 files changed, 49 insertions, 17 deletions
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 1b8583034..a5c94927a 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c @@ -33,7 +33,12 @@ * * Revision history: * $Log: sx.c,v $ - * Revision 1.32 2000/03/07 90:00:00 wolff,pvdl + * Revision 1.33 2000/03/09 10:00:00 pvdl,wolff + * - Fixed module and port counting + * - Fixed signal handling + * - Fixed an Ooops + * + * Revision 1.32 2000/03/07 09:00:00 wolff,pvdl * - Fixed some sx_dprintk typos * - added detection for an invalid board/module configuration * @@ -195,8 +200,8 @@ * */ -#define RCS_ID "$Id: sx.c,v 1.32 2000/03/07 17:01:02 wolff, pvdl Exp $" -#define RCS_REV "$Revision: 1.32 $" +#define RCS_ID "$Id: sx.c,v 1.33 2000/03/08 10:01:02 wolff, pvdl Exp $" +#define RCS_REV "$Revision: 1.33 $" #include <linux/module.h> @@ -231,8 +236,9 @@ #include "sxboards.h" #include "sxwindow.h" -#include <linux/generic_serial.h> + #include <linux/compatmac.h> +#include <linux/generic_serial.h> #include "sx.h" @@ -241,11 +247,11 @@ if you want more than 4 boards. */ - /* Why the hell am I defining these here? */ #define SX_TYPE_NORMAL 1 #define SX_TYPE_CALLOUT 2 + #ifndef PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 #define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 #endif @@ -767,6 +773,7 @@ static void sx_setsignals (struct sx_port *port, int dtr, int rts) if (rts >= 0) t = rts? (t | OP_RTS): (t & ~OP_RTS); sx_write_channel_byte (port, hi_op, t); sx_dprintk (SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts); + func_exit (); } @@ -882,6 +889,9 @@ static int sx_set_real_termios (void *ptr) func_enter2(); + if (!port->gs.tty) + return 0; + /* What is this doing here? -- REW Ha! figured it out. It is to allow you to get DTR active again if you've dropped it with stty 0. Moved to set_baud, where it @@ -1043,7 +1053,7 @@ void sx_transmit_chars (struct sx_port *port) sx_disable_tx_interrupts (port); } - if (port->gs.xmit_cnt <= port->gs.wakeup_chars) { + if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) { if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && port->gs.tty->ldisc.write_wakeup) (port->gs.tty->ldisc.write_wakeup)(port->gs.tty); @@ -1294,6 +1304,8 @@ static void sx_pollfunc (unsigned long data) sx_interrupt (0, board, NULL); + init_timer(&board->timer); + board->timer.expires = jiffies + sx_poll; add_timer (&board->timer); func_exit (); @@ -1389,7 +1401,7 @@ static void sx_shutdown_port (void * ptr) func_enter(); port->gs.flags &= ~ GS_ACTIVE; - if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL) { + if (port->gs.tty && (port->gs.tty->termios->c_cflag & HUPCL)) { sx_setsignals (port, 0, 0); sx_reconfigure_port(port); } @@ -1452,6 +1464,8 @@ static int sx_open (struct tty_struct * tty, struct file * filp) tty->driver_data = port; port->gs.tty = tty; + if (!port->gs.count) + MOD_INC_USE_COUNT; port->gs.count++; sx_dprintk (SX_DEBUG_OPEN, "starting port\n"); @@ -1463,19 +1477,13 @@ static int sx_open (struct tty_struct * tty, struct file * filp) sx_dprintk (SX_DEBUG_OPEN, "done gs_init\n"); if (retval) { port->gs.count--; + if (port->gs.count) MOD_DEC_USE_COUNT; return retval; } port->gs.flags |= GS_ACTIVE; sx_setsignals (port, 1,1); - sx_dprintk (SX_DEBUG_OPEN, "before inc_use_count (count=%d.\n", - port->gs.count); - if (port->gs.count == 1) { - MOD_INC_USE_COUNT; - } - sx_dprintk (SX_DEBUG_OPEN, "after inc_use_count\n"); - #if 0 if (sx_debug & SX_DEBUG_OPEN) my_hd ((unsigned char *)port, sizeof (*port)); @@ -1487,8 +1495,8 @@ static int sx_open (struct tty_struct * tty, struct file * filp) if (sx_send_command (port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) { printk (KERN_ERR "sx: Card didn't respond to LOPEN command.\n"); - MOD_DEC_USE_COUNT; port->gs.count--; + if (!port->gs.count) MOD_DEC_USE_COUNT; return -EIO; } @@ -1497,8 +1505,10 @@ static int sx_open (struct tty_struct * tty, struct file * filp) retval, port->gs.count); if (retval) { - MOD_DEC_USE_COUNT; - port->gs.count--; + /* + * Don't lower gs.count here because sx_close() will be called later + */ + return retval; } /* tty->low_latency = 1; */ @@ -1530,7 +1540,21 @@ static int sx_open (struct tty_struct * tty, struct file * filp) exit minicom. I expect an "oops". -- REW */ static void sx_hungup (void *ptr) { + struct sx_port *port = ptr; func_enter (); + + sx_setsignals (port, 0, 0); + sx_reconfigure_port(port); + sx_send_command (port, HS_CLOSE, 0, 0); + + if (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED) { + if (sx_send_command (port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) != 1) { + printk (KERN_ERR + "sx: sent the force_close command, but card didn't react\n"); + } else + sx_dprintk (SX_DEBUG_CLOSE, "sent the force_close command.\n"); + } + MOD_DEC_USE_COUNT; func_exit (); } @@ -1543,6 +1567,9 @@ static void sx_close (void *ptr) int to = 5 * HZ; func_enter (); + + sx_setsignals (port, 0, 0); + sx_reconfigure_port(port); sx_send_command (port, HS_CLOSE, 0, 0); while (to-- && (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED)) { @@ -1563,6 +1590,11 @@ static void sx_close (void *ptr) sx_dprintk (SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", 5 * HZ - to - 1, port->gs.count); + if(port->gs.count) { + sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", port->gs.count); + port->gs.count = 0; + } + MOD_DEC_USE_COUNT; func_exit (); } |