headers: smp_lock.h redux
[safe/jmp/linux-2.6] / drivers / char / sx.c
index 1da92a6..a81ec4f 100644 (file)
@@ -1,4 +1,3 @@
-
 /* sx.c -- driver for the Specialix SX series cards. 
  *
  *  This driver will also support the older SI, and XIO cards.
 #include <linux/eisa.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/bitops.h>
@@ -280,15 +280,15 @@ static void sx_disable_tx_interrupts(void *ptr);
 static void sx_enable_tx_interrupts(void *ptr);
 static void sx_disable_rx_interrupts(void *ptr);
 static void sx_enable_rx_interrupts(void *ptr);
-static int sx_get_CD(void *ptr);
+static int sx_carrier_raised(struct tty_port *port);
 static void sx_shutdown_port(void *ptr);
 static int sx_set_real_termios(void *ptr);
 static void sx_close(void *ptr);
 static int sx_chars_in_buffer(void *ptr);
 static int sx_init_board(struct sx_board *board);
 static int sx_init_portstructs(int nboards, int nports);
-static int sx_fw_ioctl(struct inode *inode, struct file *filp,
-               unsigned int cmd, unsigned long arg);
+static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
+                                               unsigned long arg);
 static int sx_init_drivers(void);
 
 static struct tty_driver *sx_driver;
@@ -361,7 +361,6 @@ static struct real_driver sx_real_driver = {
        sx_enable_tx_interrupts,
        sx_disable_rx_interrupts,
        sx_enable_rx_interrupts,
-       sx_get_CD,
        sx_shutdown_port,
        sx_set_real_termios,
        sx_chars_in_buffer,
@@ -384,11 +383,11 @@ static struct real_driver sx_real_driver = {
 #define sx_dprintk(f, str...)  /* nothing */
 #endif
 
-#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_enter()   sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s\n",__func__)
+#define func_exit()    sx_dprintk(SX_DEBUG_FLOW, "sx: exit  %s\n",__func__)
 
 #define func_enter2()  sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \
-                               __FUNCTION__, port->line)
+                               __func__, port->line)
 
 /* 
  *  Firmware loader driver specific routines
@@ -397,7 +396,7 @@ static struct real_driver sx_real_driver = {
 
 static const struct file_operations sx_fw_fops = {
        .owner = THIS_MODULE,
-       .ioctl = sx_fw_ioctl,
+       .unlocked_ioctl = sx_fw_ioctl,
 };
 
 static struct miscdevice sx_fw_device = {
@@ -792,7 +791,7 @@ static int sx_getsignals(struct sx_port *port)
        sx_dprintk(SX_DEBUG_MODEMSIGNALS, "getsignals: %d/%d  (%d/%d) "
                        "%02x/%02x\n",
                        (o_stat & OP_DTR) != 0, (o_stat & OP_RTS) != 0,
-                       port->c_dcd, sx_get_CD(port),
+                       port->c_dcd, tty_port_carrier_raised(&port->gs.port),
                        sx_read_channel_byte(port, hi_ip),
                        sx_read_channel_byte(port, hi_state));
 
@@ -930,7 +929,7 @@ static int sx_set_real_termios(void *ptr)
 
        func_enter2();
 
-       if (!port->gs.tty)
+       if (!port->gs.port.tty)
                return 0;
 
        /* What is this doing here? -- REW
@@ -941,19 +940,19 @@ static int sx_set_real_termios(void *ptr)
 
        sx_set_baud(port);
 
-#define CFLAG port->gs.tty->termios->c_cflag
+#define CFLAG port->gs.port.tty->termios->c_cflag
        sx_write_channel_byte(port, hi_mr1,
-                       (C_PARENB(port->gs.tty) ? MR1_WITH : MR1_NONE) |
-                       (C_PARODD(port->gs.tty) ? MR1_ODD : MR1_EVEN) |
-                       (C_CRTSCTS(port->gs.tty) ? MR1_RTS_RXFLOW : 0) |
+                       (C_PARENB(port->gs.port.tty) ? MR1_WITH : MR1_NONE) |
+                       (C_PARODD(port->gs.port.tty) ? MR1_ODD : MR1_EVEN) |
+                       (C_CRTSCTS(port->gs.port.tty) ? MR1_RTS_RXFLOW : 0) |
                        (((CFLAG & CSIZE) == CS8) ? MR1_8_BITS : 0) |
                        (((CFLAG & CSIZE) == CS7) ? MR1_7_BITS : 0) |
                        (((CFLAG & CSIZE) == CS6) ? MR1_6_BITS : 0) |
                        (((CFLAG & CSIZE) == CS5) ? MR1_5_BITS : 0));
 
        sx_write_channel_byte(port, hi_mr2,
-                       (C_CRTSCTS(port->gs.tty) ? MR2_CTS_TXFLOW : 0) |
-                       (C_CSTOPB(port->gs.tty) ? MR2_2_STOP :
+                       (C_CRTSCTS(port->gs.port.tty) ? MR2_CTS_TXFLOW : 0) |
+                       (C_CSTOPB(port->gs.port.tty) ? MR2_2_STOP :
                        MR2_1_STOP));
 
        switch (CFLAG & CSIZE) {
@@ -970,47 +969,50 @@ static int sx_set_real_termios(void *ptr)
                sx_write_channel_byte(port, hi_mask, 0x1f);
                break;
        default:
-               printk(KERN_INFO "sx: Invalid wordsize: %u\n", CFLAG & CSIZE);
+               printk(KERN_INFO "sx: Invalid wordsize: %u\n",
+                       (unsigned int)CFLAG & CSIZE);
                break;
        }
 
        sx_write_channel_byte(port, hi_prtcl,
-                       (I_IXON(port->gs.tty) ? SP_TXEN : 0) |
-                       (I_IXOFF(port->gs.tty) ? SP_RXEN : 0) |
-                       (I_IXANY(port->gs.tty) ? SP_TANY : 0) | SP_DCEN);
+                       (I_IXON(port->gs.port.tty) ? SP_TXEN : 0) |
+                       (I_IXOFF(port->gs.port.tty) ? SP_RXEN : 0) |
+                       (I_IXANY(port->gs.port.tty) ? SP_TANY : 0) | SP_DCEN);
 
        sx_write_channel_byte(port, hi_break,
-                       (I_IGNBRK(port->gs.tty) ? BR_IGN : 0 |
-                       I_BRKINT(port->gs.tty) ? BR_INT : 0));
+                       (I_IGNBRK(port->gs.port.tty) ? BR_IGN : 0 |
+                       I_BRKINT(port->gs.port.tty) ? BR_INT : 0));
 
-       sx_write_channel_byte(port, hi_txon, START_CHAR(port->gs.tty));
-       sx_write_channel_byte(port, hi_rxon, START_CHAR(port->gs.tty));
-       sx_write_channel_byte(port, hi_txoff, STOP_CHAR(port->gs.tty));
-       sx_write_channel_byte(port, hi_rxoff, STOP_CHAR(port->gs.tty));
+       sx_write_channel_byte(port, hi_txon, START_CHAR(port->gs.port.tty));
+       sx_write_channel_byte(port, hi_rxon, START_CHAR(port->gs.port.tty));
+       sx_write_channel_byte(port, hi_txoff, STOP_CHAR(port->gs.port.tty));
+       sx_write_channel_byte(port, hi_rxoff, STOP_CHAR(port->gs.port.tty));
 
        sx_reconfigure_port(port);
 
        /* Tell line discipline whether we will do input cooking */
-       if (I_OTHER(port->gs.tty)) {
-               clear_bit(TTY_HW_COOK_IN, &port->gs.tty->flags);
+       if (I_OTHER(port->gs.port.tty)) {
+               clear_bit(TTY_HW_COOK_IN, &port->gs.port.tty->flags);
        } else {
-               set_bit(TTY_HW_COOK_IN, &port->gs.tty->flags);
+               set_bit(TTY_HW_COOK_IN, &port->gs.port.tty->flags);
        }
        sx_dprintk(SX_DEBUG_TERMIOS, "iflags: %x(%d) ",
-                       port->gs.tty->termios->c_iflag, I_OTHER(port->gs.tty));
+                       (unsigned int)port->gs.port.tty->termios->c_iflag,
+                       I_OTHER(port->gs.port.tty));
 
 /* Tell line discipline whether we will do output cooking.
  * If OPOST is set and no other output flags are set then we can do output
  * processing.  Even if only *one* other flag in the O_OTHER group is set
  * we do cooking in software.
  */
-       if (O_OPOST(port->gs.tty) && !O_OTHER(port->gs.tty)) {
-               set_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags);
+       if (O_OPOST(port->gs.port.tty) && !O_OTHER(port->gs.port.tty)) {
+               set_bit(TTY_HW_COOK_OUT, &port->gs.port.tty->flags);
        } else {
-               clear_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags);
+               clear_bit(TTY_HW_COOK_OUT, &port->gs.port.tty->flags);
        }
        sx_dprintk(SX_DEBUG_TERMIOS, "oflags: %x(%d)\n",
-                       port->gs.tty->termios->c_oflag, O_OTHER(port->gs.tty));
+                       (unsigned int)port->gs.port.tty->termios->c_oflag,
+                       O_OTHER(port->gs.port.tty));
        /* port->c_dcd = sx_get_CD (port); */
        func_exit();
        return 0;
@@ -1099,8 +1101,8 @@ static void sx_transmit_chars(struct sx_port *port)
                sx_disable_tx_interrupts(port);
        }
 
-       if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) {
-               tty_wakeup(port->gs.tty);
+       if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.port.tty) {
+               tty_wakeup(port->gs.port.tty);
                sx_dprintk(SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
                                port->gs.wakeup_chars);
        }
@@ -1123,7 +1125,7 @@ static inline void sx_receive_chars(struct sx_port *port)
        unsigned char *rp;
 
        func_enter2();
-       tty = port->gs.tty;
+       tty = port->gs.port.tty;
        while (1) {
                rx_op = sx_read_channel_byte(port, hi_rxopos);
                c = (sx_read_channel_byte(port, hi_rxipos) - rx_op) & 0xff;
@@ -1188,7 +1190,7 @@ static inline void sx_check_modem_signals(struct sx_port *port)
 
        hi_state = sx_read_channel_byte(port, hi_state);
        sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Checking modem signals (%d/%d)\n",
-                       port->c_dcd, sx_get_CD(port));
+                       port->c_dcd, tty_port_carrier_raised(&port->gs.port));
 
        if (hi_state & ST_BREAK) {
                hi_state &= ~ST_BREAK;
@@ -1200,20 +1202,20 @@ static inline void sx_check_modem_signals(struct sx_port *port)
                hi_state &= ~ST_DCD;
                sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a DCD change.\n");
                sx_write_channel_byte(port, hi_state, hi_state);
-               c_dcd = sx_get_CD(port);
+               c_dcd = tty_port_carrier_raised(&port->gs.port);
                sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD is now %d\n", c_dcd);
                if (c_dcd != port->c_dcd) {
                        port->c_dcd = c_dcd;
-                       if (sx_get_CD(port)) {
+                       if (tty_port_carrier_raised(&port->gs.port)) {
                                /* DCD went UP */
                                if ((sx_read_channel_byte(port, hi_hstat) !=
                                                HS_IDLE_CLOSED) &&
-                                               !(port->gs.tty->termios->
+                                               !(port->gs.port.tty->termios->
                                                        c_cflag & CLOCAL)) {
                                        /* Are we blocking in open? */
                                        sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
                                                "active, unblocking open\n");
-                                       wake_up_interruptible(&port->gs.
+                                       wake_up_interruptible(&port->gs.port.
                                                        open_wait);
                                } else {
                                        sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
@@ -1221,10 +1223,10 @@ static inline void sx_check_modem_signals(struct sx_port *port)
                                }
                        } else {
                                /* DCD went down! */
-                               if (!(port->gs.tty->termios->c_cflag & CLOCAL)){
+                               if (!(port->gs.port.tty->termios->c_cflag & CLOCAL)){
                                        sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
                                                "dropped. hanging up....\n");
-                                       tty_hangup(port->gs.tty);
+                                       tty_hangup(port->gs.port.tty);
                                } else {
                                        sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
                                                "dropped. ignoring.\n");
@@ -1322,7 +1324,7 @@ static irqreturn_t sx_interrupt(int irq, void *ptr)
 
        for (i = 0; i < board->nports; i++) {
                port = &board->ports[i];
-               if (port->gs.flags & GS_ACTIVE) {
+               if (port->gs.port.flags & GS_ACTIVE) {
                        if (sx_read_channel_byte(port, hi_state)) {
                                sx_dprintk(SX_DEBUG_INTERRUPTS, "Port %d: "
                                                "modem signal change?... \n",i);
@@ -1331,7 +1333,7 @@ static irqreturn_t sx_interrupt(int irq, void *ptr)
                        if (port->gs.xmit_cnt) {
                                sx_transmit_chars(port);
                        }
-                       if (!(port->gs.flags & SX_RX_THROTTLE)) {
+                       if (!(port->gs.port.flags & SX_RX_THROTTLE)) {
                                sx_receive_chars(port);
                        }
                }
@@ -1370,7 +1372,7 @@ static void sx_disable_tx_interrupts(void *ptr)
        struct sx_port *port = ptr;
        func_enter2();
 
-       port->gs.flags &= ~GS_TX_INTEN;
+       port->gs.port.flags &= ~GS_TX_INTEN;
 
        func_exit();
 }
@@ -1391,7 +1393,7 @@ static void sx_enable_tx_interrupts(void *ptr)
 
        /* XXX Must be "HIGH_WATER" for SI card according to doc. */
        if (data_in_buffer < LOW_WATER)
-               port->gs.flags &= ~GS_TX_INTEN;
+               port->gs.port.flags &= ~GS_TX_INTEN;
 
        func_exit();
 }
@@ -1413,13 +1415,10 @@ static void sx_enable_rx_interrupts(void *ptr)
 }
 
 /* Jeez. Isn't this simple? */
-static int sx_get_CD(void *ptr)
+static int sx_carrier_raised(struct tty_port *port)
 {
-       struct sx_port *port = ptr;
-       func_enter2();
-
-       func_exit();
-       return ((sx_read_channel_byte(port, hi_ip) & IP_DCD) != 0);
+       struct sx_port *sp = container_of(port, struct sx_port, gs.port);
+       return ((sx_read_channel_byte(sp, hi_ip) & IP_DCD) != 0);
 }
 
 /* Jeez. Isn't this simple? */
@@ -1439,8 +1438,8 @@ 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)) {
+       port->gs.port.flags &= ~GS_ACTIVE;
+       if (port->gs.port.tty && (port->gs.port.tty->termios->c_cflag & HUPCL)) {
                sx_setsignals(port, 0, 0);
                sx_reconfigure_port(port);
        }
@@ -1467,7 +1466,7 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
 
        line = tty->index;
        sx_dprintk(SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, "
-                       "np=%d)\n", current->pid, line, tty,
+                       "np=%d)\n", task_pid_nr(current), line, tty,
                        current->signal->tty, sx_nports);
 
        if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports))
@@ -1482,8 +1481,8 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
        spin_lock_irqsave(&port->gs.driver_lock, flags);
 
        tty->driver_data = port;
-       port->gs.tty = tty;
-       port->gs.count++;
+       port->gs.port.tty = tty;
+       port->gs.port.count++;
        spin_unlock_irqrestore(&port->gs.driver_lock, flags);
 
        sx_dprintk(SX_DEBUG_OPEN, "starting port\n");
@@ -1494,12 +1493,12 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
        retval = gs_init_port(&port->gs);
        sx_dprintk(SX_DEBUG_OPEN, "done gs_init\n");
        if (retval) {
-               port->gs.count--;
+               port->gs.port.count--;
                return retval;
        }
 
-       port->gs.flags |= GS_ACTIVE;
-       if (port->gs.count <= 1)
+       port->gs.port.flags |= GS_ACTIVE;
+       if (port->gs.port.count <= 1)
                sx_setsignals(port, 1, 1);
 
 #if 0
@@ -1510,12 +1509,12 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
                my_hd_io(port->board->base + port->ch_base, sizeof(*port));
 #endif
 
-       if (port->gs.count <= 1) {
+       if (port->gs.port.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--;
+                       port->gs.port.count--;
                        spin_unlock_irqrestore(&port->gs.driver_lock, flags);
                        return -EIO;
                }
@@ -1523,18 +1522,18 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
 
        retval = gs_block_til_ready(port, filp);
        sx_dprintk(SX_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n",
-                       retval, port->gs.count);
+                       retval, port->gs.port.count);
 
        if (retval) {
 /*
- * Don't lower gs.count here because sx_close() will be called later
+ * Don't lower gs.port.count here because sx_close() will be called later
  */
 
                return retval;
        }
        /* tty->low_latency = 1; */
 
-       port->c_dcd = sx_get_CD(port);
+       port->c_dcd = sx_carrier_raised(&port->gs.port);
        sx_dprintk(SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd);
 
        func_exit();
@@ -1568,14 +1567,14 @@ 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);
+                       5 * HZ - to - 1, port->gs.port.count);
 
-       if (port->gs.count) {
+       if (port->gs.port.count) {
                sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n",
-                               port->gs.count);
+                               port->gs.port.count);
                /*printk("%s SETTING port count to zero: %p count: %d\n",
-                               __FUNCTION__, port, port->gs.count);
-               port->gs.count = 0;*/
+                               __func__, port, port->gs.port.count);
+               port->gs.port.count = 0;*/
        }
 
        func_exit();
@@ -1684,10 +1683,10 @@ static int do_memtest_w(struct sx_board *board, int min, int max)
 }
 #endif
 
-static int sx_fw_ioctl(struct inode *inode, struct file *filp,
-               unsigned int cmd, unsigned long arg)
+static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
+                                                       unsigned long arg)
 {
-       int rc = 0;
+       long rc = 0;
        int __user *descr = (int __user *)arg;
        int i;
        static struct sx_board *board = NULL;
@@ -1697,13 +1696,10 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
 
        func_enter();
 
-#if 0
-       /* Removed superuser check: Sysops can use the permissions on the device
-          file to restrict access. Recommendation: Root only. (root.root 600) */
-       if (!capable(CAP_SYS_ADMIN)) {
+       if (!capable(CAP_SYS_RAWIO))
                return -EPERM;
-       }
-#endif
+
+       lock_kernel();
 
        sx_dprintk(SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg);
 
@@ -1718,19 +1714,23 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
                for (i = 0; i < SX_NBOARDS; i++)
                        sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags);
                sx_dprintk(SX_DEBUG_FIRMWARE, "\n");
-               return -EIO;
+               rc = -EIO;
+               goto out;
        }
 
        switch (cmd) {
        case SXIO_SET_BOARD:
                sx_dprintk(SX_DEBUG_FIRMWARE, "set board to %ld\n", arg);
+               rc = -EIO;
                if (arg >= SX_NBOARDS)
-                       return -EIO;
+                       break;
                sx_dprintk(SX_DEBUG_FIRMWARE, "not out of range\n");
                if (!(boards[arg].flags & SX_BOARD_PRESENT))
-                       return -EIO;
+                       break;
                sx_dprintk(SX_DEBUG_FIRMWARE, ".. and present!\n");
                board = &boards[arg];
+               rc = 0;
+               /* FIXME: And this does ... nothing?? */
                break;
        case SXIO_GET_TYPE:
                rc = -ENOENT;   /* If we manage to miss one, return error. */
@@ -1744,11 +1744,13 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
                        rc = SX_TYPE_SI;
                if (IS_EISA_BOARD(board))
                        rc = SX_TYPE_SI;
-               sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %d\n", rc);
+               sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %ld\n", rc);
                break;
        case SXIO_DO_RAMTEST:
-               if (sx_initialized)     /* Already initialized: better not ramtest the board.  */
-                       return -EPERM;
+               if (sx_initialized) {   /* Already initialized: better not ramtest the board.  */
+                       rc = -EPERM;
+                       break;
+               }
                if (IS_SX_BOARD(board)) {
                        rc = do_memtest(board, 0, 0x7000);
                        if (!rc)
@@ -1758,19 +1760,26 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
                        rc = do_memtest(board, 0, 0x7ff8);
                        /* if (!rc) rc = do_memtest_w (board, 0, 0x7ff8); */
                }
-               sx_dprintk(SX_DEBUG_FIRMWARE, "returning memtest result= %d\n",
-                          rc);
+               sx_dprintk(SX_DEBUG_FIRMWARE,
+                               "returning memtest result= %ld\n", rc);
                break;
        case SXIO_DOWNLOAD:
-               if (sx_initialized)     /* Already initialized */
-                       return -EEXIST;
-               if (!sx_reset(board))
-                       return -EIO;
+               if (sx_initialized) {/* Already initialized */
+                       rc = -EEXIST;
+                       break;
+               }
+               if (!sx_reset(board)) {
+                       rc = -EIO;
+                       break;
+               }
                sx_dprintk(SX_DEBUG_INIT, "reset the board...\n");
 
                tmp = kmalloc(SX_CHUNK_SIZE, GFP_USER);
-               if (!tmp)
-                       return -ENOMEM;
+               if (!tmp) {
+                       rc = -ENOMEM;
+                       break;
+               }
+               /* FIXME: check returns */
                get_user(nbytes, descr++);
                get_user(offset, descr++);
                get_user(data, descr++);
@@ -1780,7 +1789,8 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
                                                (i + SX_CHUNK_SIZE > nbytes) ?
                                                nbytes - i : SX_CHUNK_SIZE)) {
                                        kfree(tmp);
-                                       return -EFAULT;
+                                       rc = -EFAULT;
+                                       goto out;
                                }
                                memcpy_toio(board->base2 + offset + i, tmp,
                                                (i + SX_CHUNK_SIZE > nbytes) ?
@@ -1796,13 +1806,17 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
                rc = sx_nports;
                break;
        case SXIO_INIT:
-               if (sx_initialized)     /* Already initialized */
-                       return -EEXIST;
+               if (sx_initialized) {   /* Already initialized */
+                       rc = -EEXIST;
+                       break;
+               }
                /* This is not allowed until all boards are initialized... */
                for (i = 0; i < SX_NBOARDS; i++) {
                        if ((boards[i].flags & SX_BOARD_PRESENT) &&
-                               !(boards[i].flags & SX_BOARD_INITIALIZED))
-                               return -EIO;
+                               !(boards[i].flags & SX_BOARD_INITIALIZED)) {
+                               rc = -EIO;
+                               break;
+                       }
                }
                for (i = 0; i < SX_NBOARDS; i++)
                        if (!(boards[i].flags & SX_BOARD_PRESENT))
@@ -1830,20 +1844,22 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
                rc = sx_nports;
                break;
        default:
-               printk(KERN_WARNING "Unknown ioctl on firmware device (%x).\n",
-                               cmd);
+               rc = -ENOTTY;
                break;
        }
+out:
+       unlock_kernel();
        func_exit();
        return rc;
 }
 
-static void sx_break(struct tty_struct *tty, int flag)
+static int sx_break(struct tty_struct *tty, int flag)
 {
        struct sx_port *port = tty->driver_data;
        int rv;
 
        func_enter();
+       lock_kernel();
 
        if (flag)
                rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK);
@@ -1852,8 +1868,9 @@ static void sx_break(struct tty_struct *tty, int flag)
        if (rv != 1)
                printk(KERN_ERR "sx: couldn't send break (%x).\n",
                        read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat)));
-
+       unlock_kernel();
        func_exit();
+       return 0;
 }
 
 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
@@ -1888,23 +1905,12 @@ static int sx_ioctl(struct tty_struct *tty, struct file *filp,
        int rc;
        struct sx_port *port = tty->driver_data;
        void __user *argp = (void __user *)arg;
-       int ival;
 
        /* func_enter2(); */
 
        rc = 0;
+       lock_kernel();
        switch (cmd) {
-       case TIOCGSOFTCAR:
-               rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
-                               (unsigned __user *)argp);
-               break;
-       case TIOCSSOFTCAR:
-               if ((rc = get_user(ival, (unsigned __user *)argp)) == 0) {
-                       tty->termios->c_cflag =
-                               (tty->termios->c_cflag & ~CLOCAL) |
-                               (ival ? CLOCAL : 0);
-               }
-               break;
        case TIOCGSERIAL:
                rc = gs_getserial(&port->gs, argp);
                break;
@@ -1915,6 +1921,7 @@ static int sx_ioctl(struct tty_struct *tty, struct file *filp,
                rc = -ENOIOCTLCMD;
                break;
        }
+       unlock_kernel();
 
        /* func_exit(); */
        return rc;
@@ -1938,28 +1945,28 @@ static int sx_ioctl(struct tty_struct *tty, struct file *filp,
 
 static void sx_throttle(struct tty_struct *tty)
 {
-       struct sx_port *port = (struct sx_port *)tty->driver_data;
+       struct sx_port *port = tty->driver_data;
 
        func_enter2();
        /* If the port is using any type of input flow
         * control then throttle the port.
         */
        if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) {
-               port->gs.flags |= SX_RX_THROTTLE;
+               port->gs.port.flags |= SX_RX_THROTTLE;
        }
        func_exit();
 }
 
 static void sx_unthrottle(struct tty_struct *tty)
 {
-       struct sx_port *port = (struct sx_port *)tty->driver_data;
+       struct sx_port *port = tty->driver_data;
 
        func_enter2();
        /* Always unthrottle even if flow control is not enabled on
         * this port in case we disabled flow control while the port
         * was throttled
         */
-       port->gs.flags &= ~SX_RX_THROTTLE;
+       port->gs.port.flags &= ~SX_RX_THROTTLE;
        func_exit();
        return;
 }
@@ -2347,6 +2354,10 @@ static const struct tty_operations sx_ops = {
        .tiocmset = sx_tiocmset,
 };
 
+static const struct tty_port_operations sx_port_ops = {
+       .carrier_raised = sx_carrier_raised,
+};
+
 static int sx_init_drivers(void)
 {
        int error;
@@ -2402,6 +2413,8 @@ static int sx_init_portstructs(int nboards, int nports)
                board->ports = port;
                for (j = 0; j < boards[i].nports; j++) {
                        sx_dprintk(SX_DEBUG_INIT, "initing port %d\n", j);
+                       tty_port_init(&port->gs.port);
+                       port->gs.port.ops = &sx_port_ops;
                        port->gs.magic = SX_MAGIC;
                        port->gs.close_delay = HZ / 2;
                        port->gs.closing_wait = 30 * HZ;
@@ -2414,9 +2427,6 @@ static int sx_init_portstructs(int nboards, int nports)
                        /*
                         * Initializing wait queue
                         */
-                       init_waitqueue_head(&port->gs.open_wait);
-                       init_waitqueue_head(&port->gs.close_wait);
-
                        port++;
                }
        }
@@ -2499,7 +2509,7 @@ static void __devexit sx_remove_card(struct sx_board *board,
                del_timer(&board->timer);
                if (pdev) {
 #ifdef CONFIG_PCI
-                       pci_iounmap(pdev, board->base);
+                       iounmap(board->base2);
                        pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2);
 #endif
                } else {
@@ -2549,7 +2559,7 @@ static int __devinit sx_eisa_probe(struct device *dev)
                goto err_flag;
        }
        board->base2 =
-       board->base = ioremap(board->hw_base, SI2_EISA_WINDOW_LEN);
+       board->base = ioremap_nocache(board->hw_base, SI2_EISA_WINDOW_LEN);
        if (!board->base) {
                dev_err(dev, "can't remap memory\n");
                goto err_reg;
@@ -2626,7 +2636,7 @@ static void __devinit fix_sx_pci(struct pci_dev *pdev, struct sx_board *board)
 
        pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase);
        hwbase &= PCI_BASE_ADDRESS_MEM_MASK;
-       rebase = ioremap(hwbase, 0x80);
+       rebase = ioremap_nocache(hwbase, 0x80);
        t = readl(rebase + CNTRL_REG_OFFSET);
        if (t != CNTRL_REG_GOODVALUE) {
                printk(KERN_DEBUG "sx: performing cntrl reg fix: %08x -> "
@@ -2672,7 +2682,7 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev,
        }
        board->hw_base = pci_resource_start(pdev, reg);
        board->base2 =
-       board->base = pci_iomap(pdev, reg, WINDOW_LEN(board));
+       board->base = ioremap_nocache(board->hw_base, WINDOW_LEN(board));
        if (!board->base) {
                dev_err(&pdev->dev, "ioremap failed\n");
                goto err_reg;
@@ -2698,7 +2708,7 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev,
 
        return 0;
 err_unmap:
-       pci_iounmap(pdev, board->base);
+       iounmap(board->base2);
 err_reg:
        pci_release_region(pdev, reg);
 err_flag:
@@ -2721,9 +2731,9 @@ static void __devexit sx_pci_remove(struct pci_dev *pdev)
    its because the standard requires it. So check for SUBVENDOR_ID. */
 static struct pci_device_id sx_pci_tbl[] = {
        { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
-               .subvendor = 0x0200,.subdevice = PCI_ANY_ID },
+               .subvendor = PCI_ANY_ID, .subdevice = 0x0200 },
        { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
-               .subvendor = 0x0300,.subdevice = PCI_ANY_ID },
+               .subvendor = PCI_ANY_ID, .subdevice = 0x0300 },
        { 0 }
 };
 
@@ -2770,7 +2780,7 @@ static int __init sx_init(void)
                if (!request_region(board->hw_base, board->hw_len, "sx"))
                        continue;
                board->base2 =
-               board->base = ioremap(board->hw_base, board->hw_len);
+               board->base = ioremap_nocache(board->hw_base, board->hw_len);
                if (!board->base)
                        goto err_sx_reg;
                board->flags &= ~SX_BOARD_TYPE;
@@ -2794,7 +2804,7 @@ err_sx_reg:
                if (!request_region(board->hw_base, board->hw_len, "sx"))
                        continue;
                board->base2 =
-               board->base = ioremap(board->hw_base, board->hw_len);
+               board->base = ioremap_nocache(board->hw_base, board->hw_len);
                if (!board->base)
                        goto err_si_reg;
                board->flags &= ~SX_BOARD_TYPE;
@@ -2817,7 +2827,7 @@ err_si_reg:
                if (!request_region(board->hw_base, board->hw_len, "sx"))
                        continue;
                board->base2 =
-               board->base = ioremap(board->hw_base, board->hw_len);
+               board->base = ioremap_nocache(board->hw_base, board->hw_len);
                if (!board->base)
                        goto err_si1_reg;
                board->flags &= ~SX_BOARD_TYPE;