ChangeSet 1.2265, 2005/03/31 08:38:17-08:00, [EMAIL PROTECTED]

        [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 <[EMAIL PROTECTED]>
        Signed-off-by: Rogier Wolff <[EMAIL PROTECTED]>
        Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
        Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>



 Kconfig |    2 +-
 sx.c    |   60 ++++++++++++++++++++++++++++++++++++++++--------------------
 2 files changed, 41 insertions(+), 21 deletions(-)


diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig
--- a/drivers/char/Kconfig      2005-03-31 10:18:51 -08:00
+++ b/drivers/char/Kconfig      2005-03-31 10:18:51 -08:00
@@ -271,7 +271,7 @@
 
 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 -Nru a/drivers/char/sx.c b/drivers/char/sx.c
--- a/drivers/char/sx.c 2005-03-31 10:18:51 -08:00
+++ b/drivers/char/sx.c 2005-03-31 10:18:51 -08:00
@@ -4,7 +4,7 @@
  *  This driver will also support the older SI, and XIO cards.
  *
  *
- *   (C) 1998 - 2000  [EMAIL PROTECTED]
+ *   (C) 1998 - 2004  [EMAIL PROTECTED]
  *
  *  Simon Allen ([EMAIL PROTECTED]) wrote a previous
  *  version of this driver. Some fragments may have been copied. (none
@@ -354,13 +354,13 @@
    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 @@
 
 
 
-#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 @@
        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 @@
        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 @@
        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 @@
 {
        struct sx_port *port;
        int retval, line;
+       unsigned long flags;
 
        func_enter();
 
@@ -1449,9 +1449,12 @@
 
        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 @@
        }
 
        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 @@
                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 @@
 
        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 @@
 
        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 @@
        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 @@
                }
 
                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 @@
            }
                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 @@
                /* 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 @@
                /* 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 @@
 #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 @@
                        found++;
                        fix_sx_pci (pdev, board);
                } else 
-                       iounmap(board->base);
+                       iounmap(board->base2);
        }
 #endif
 
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to