aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick vd Lageweg <patrick@bitwizard.nl>2005-03-30 16:38:17 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-03-30 16:38:17 -0800
commitf1c949ef8cb362968dc32abfe0bc314e51445067 (patch)
treecfa0cd17ede99f901a313b4f73acfba56ee8466a
parentbdc98a74f9b8e27f98064cf4383dbaf011d64fec (diff)
downloadhistory-f1c949ef8cb362968dc32abfe0bc314e51445067.tar.gz
[PATCH] SX cli() conversion
This patch converts all save_flags/restore_flags to the new spin_lock_irqsave/spin_unlock_irqrestore calls, as well as some other 2.6.X cleanups. This allows the "sx" driver to become SMP safe. Signed-off-by: Patrick vd Lageweg <patrick@bitwizard.nl> Signed-off-by: Rogier Wolff <R.E.Wolff@BitWizard.nl> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/sx.c60
2 files changed, 41 insertions, 21 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 3dfcaffd37ccd9..096a1202ea077d 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -271,7 +271,7 @@ config SPECIALIX_RTSCTS
config SX
tristate "Specialix SX (and SI) card support"
- depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
+ depends on SERIAL_NONSTANDARD
help
This is a driver for the SX and SI multiport serial cards.
Please read the file <file:Documentation/sx.txt> for details.
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 5a250be53fa78f..3ad758a9a1dc10 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -4,7 +4,7 @@
* This driver will also support the older SI, and XIO cards.
*
*
- * (C) 1998 - 2000 R.E.Wolff@BitWizard.nl
+ * (C) 1998 - 2004 R.E.Wolff@BitWizard.nl
*
* Simon Allen (simonallen@cix.compulink.co.uk) wrote a previous
* version of this driver. Some fragments may have been copied. (none
@@ -354,13 +354,13 @@ static int si1_probe_addrs[]= { 0xd0000};
Some architectures may need more. */
static int sx_irqmask = -1;
-MODULE_PARM(sx_probe_addrs, "i");
-MODULE_PARM(si_probe_addrs, "i");
-MODULE_PARM(sx_poll, "i");
-MODULE_PARM(sx_slowpoll, "i");
-MODULE_PARM(sx_maxints, "i");
-MODULE_PARM(sx_debug, "i");
-MODULE_PARM(sx_irqmask, "i");
+module_param_array(sx_probe_addrs, int, NULL, 0);
+module_param_array(si_probe_addrs, int, NULL, 0);
+module_param(sx_poll, int, 0);
+module_param(sx_slowpoll, int, 0);
+module_param(sx_maxints, int, 0);
+module_param(sx_debug, int, 0);
+module_param(sx_irqmask, int, 0);
MODULE_LICENSE("GPL");
@@ -396,7 +396,7 @@ static struct real_driver sx_real_driver = {
-#define func_enter() sx_dprintk (SX_DEBUG_FLOW, "sx: enter %s\b",__FUNCTION__)
+#define func_enter() sx_dprintk (SX_DEBUG_FLOW, "sx: enter %s\n",__FUNCTION__)
#define func_exit() sx_dprintk (SX_DEBUG_FLOW, "sx: exit %s\n", __FUNCTION__)
#define func_enter2() sx_dprintk (SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \
@@ -1158,7 +1158,6 @@ static inline void sx_check_modem_signals (struct sx_port *port)
if (hi_state & ST_BREAK) {
hi_state &= ~ST_BREAK;
sx_dprintk (SX_DEBUG_MODEMSIGNALS, "got a break.\n");
-
sx_write_channel_byte (port, hi_state, hi_state);
gs_got_break (&port->gs);
}
@@ -1206,7 +1205,7 @@ static irqreturn_t sx_interrupt (int irq, void *ptr, struct pt_regs *regs)
struct sx_port *port;
int i;
- /* func_enter (); */
+ func_enter ();
sx_dprintk (SX_DEBUG_FLOW, "sx: enter sx_interrupt (%d/%d)\n", irq, board->irq);
/* AAargh! The order in which to do these things is essential and
@@ -1297,7 +1296,7 @@ static irqreturn_t sx_interrupt (int irq, void *ptr, struct pt_regs *regs)
clear_bit (SX_BOARD_INTR_LOCK, &board->locks);
sx_dprintk (SX_DEBUG_FLOW, "sx: exit sx_interrupt (%d/%d)\n", irq, board->irq);
- /* func_exit (); */
+ func_exit ();
return IRQ_HANDLED;
}
@@ -1428,6 +1427,7 @@ static int sx_open (struct tty_struct * tty, struct file * filp)
{
struct sx_port *port;
int retval, line;
+ unsigned long flags;
func_enter();
@@ -1449,9 +1449,12 @@ static int sx_open (struct tty_struct * tty, struct file * filp)
sx_dprintk (SX_DEBUG_OPEN, "port = %p c_dcd = %d\n", port, port->c_dcd);
+ spin_lock_irqsave(&port->gs.driver_lock, flags);
+
tty->driver_data = port;
port->gs.tty = tty;
port->gs.count++;
+ spin_unlock_irqrestore(&port->gs.driver_lock, flags);
sx_dprintk (SX_DEBUG_OPEN, "starting port\n");
@@ -1466,7 +1469,8 @@ static int sx_open (struct tty_struct * tty, struct file * filp)
}
port->gs.flags |= GS_ACTIVE;
- sx_setsignals (port, 1,1);
+ if (port->gs.count <= 1)
+ sx_setsignals (port, 1,1);
#if 0
if (sx_debug & SX_DEBUG_OPEN)
@@ -1476,10 +1480,14 @@ static int sx_open (struct tty_struct * tty, struct file * filp)
my_hd_io (port->board->base + port->ch_base, sizeof (*port));
#endif
- if (sx_send_command (port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) {
- printk (KERN_ERR "sx: Card didn't respond to LOPEN command.\n");
- port->gs.count--;
- return -EIO;
+ if (port->gs.count <= 1) {
+ if (sx_send_command (port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) {
+ printk (KERN_ERR "sx: Card didn't respond to LOPEN command.\n");
+ spin_lock_irqsave(&port->gs.driver_lock, flags);
+ port->gs.count--;
+ spin_unlock_irqrestore(&port->gs.driver_lock, flags);
+ return -EIO;
+ }
}
retval = gs_block_til_ready(port, filp);
@@ -1497,6 +1505,7 @@ static int sx_open (struct tty_struct * tty, struct file * filp)
port->c_dcd = sx_get_CD (port);
sx_dprintk (SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd);
+
func_exit();
return 0;
@@ -1531,7 +1540,8 @@ static void sx_close (void *ptr)
if(port->gs.count) {
sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", port->gs.count);
- port->gs.count = 0;
+ //printk ("%s SETTING port count to zero: %p count: %d\n", __FUNCTION__, port, port->gs.count);
+ //port->gs.count = 0;
}
func_exit ();
@@ -1747,12 +1757,16 @@ static void sx_break (struct tty_struct * tty, int flag)
struct sx_port *port = tty->driver_data;
int rv;
+ func_enter ();
+
if (flag)
rv = sx_send_command (port, HS_START, -1, HS_IDLE_BREAK);
else
rv = sx_send_command (port, HS_STOP, -1, HS_IDLE_OPEN);
if (rv != 1) printk (KERN_ERR "sx: couldn't send break (%x).\n",
read_sx_byte (port->board, CHAN_OFFSET (port, hi_hstat)));
+
+ func_exit ();
}
@@ -2101,7 +2115,7 @@ static int probe_sx (struct sx_board *board)
}
if (((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) == SX_ISA_UNIQUEID1) {
- if (board->hw_base & 0x8000) {
+ if (((unsigned long)board->hw_base) & 0x8000) {
printk (KERN_WARNING "sx: Warning: There may be hardware problems with the card at %lx.\n", board->hw_base);
printk (KERN_WARNING "sx: Read sx.txt for more info.\n");
}
@@ -2150,6 +2164,7 @@ static int probe_si (struct sx_board *board)
}
for (i=0;i<8;i++) {
if ((read_sx_byte (board, SI2_ISA_ID_BASE+7-i) & 7) != i) {
+ func_exit ();
return 0;
}
}
@@ -2164,11 +2179,13 @@ static int probe_si (struct sx_board *board)
/* This should be an SI1 board, which has this
location writable... */
if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10)
+ func_exit ();
return 0;
} else {
/* This should be an SI2 board, which has the bottom
3 bits non-writable... */
if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10)
+ func_exit ();
return 0;
}
@@ -2181,11 +2198,13 @@ static int probe_si (struct sx_board *board)
/* This should be an SI1 board, which has this
location writable... */
if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10)
+ func_exit();
return 0;
} else {
/* This should be an SI2 board, which has the bottom
3 bits non-writable... */
if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10)
+ func_exit ();
return 0;
}
@@ -2302,6 +2321,7 @@ static int sx_init_portstructs (int nboards, int nports)
#ifdef NEW_WRITE_LOCKING
port->gs.port_write_sem = MUTEX;
#endif
+ port->gs.driver_lock = SPIN_LOCK_UNLOCKED;
/*
* Initializing wait queue
*/
@@ -2473,7 +2493,7 @@ static int __init sx_init(void)
found++;
fix_sx_pci (pdev, board);
} else
- iounmap(board->base);
+ iounmap(board->base2);
}
#endif