tty: Remove some pointless casts
[firefly-linux-kernel-4.4.55.git] / drivers / char / rocket.c
index f585bc8579e9929aba1e6f6d35b00991844e0f39..1e68cc2296fa1e4d9d1a23b3eb249fd9a806410a 100644 (file)
@@ -72,6 +72,7 @@
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
+#include <linux/serial.h>
 #include <linux/string.h>
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
@@ -81,7 +82,7 @@
 #include <linux/completion.h>
 #include <linux/wait.h>
 #include <linux/pci.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <asm/atomic.h>
 #include <asm/unaligned.h>
 #include <linux/bitops.h>
@@ -134,6 +135,7 @@ static int rcktpt_type[NUM_BOARDS];
 static int is_PCI[NUM_BOARDS];
 static rocketModel_t rocketModel[NUM_BOARDS];
 static int max_board;
+static const struct tty_port_operations rocket_port_ops;
 
 /*
  * The following arrays define the interrupt bits corresponding to each AIOP.
@@ -434,22 +436,23 @@ static void rp_do_transmit(struct r_port *info)
 #endif
        if (!info)
                return;
-       if (!info->tty) {
+       if (!info->port.tty) {
                printk(KERN_WARNING "rp: WARNING %s called with "
-                               "info->tty==NULL\n", __func__);
+                               "info->port.tty==NULL\n", __func__);
                clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
                return;
        }
 
        spin_lock_irqsave(&info->slock, flags);
-       tty = info->tty;
+       tty = info->port.tty;
        info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
 
        /*  Loop sending data to FIFO until done or FIFO full */
        while (1) {
                if (tty->stopped || tty->hw_stopped)
                        break;
-               c = min(info->xmit_fifo_room, min(info->xmit_cnt, XMIT_BUF_SIZE - info->xmit_tail));
+               c = min(info->xmit_fifo_room, info->xmit_cnt);
+               c = min(c, XMIT_BUF_SIZE - info->xmit_tail);
                if (c <= 0 || info->xmit_fifo_room <= 0)
                        break;
                sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) (info->xmit_buf + info->xmit_tail), c / 2);
@@ -496,18 +499,18 @@ static void rp_handle_port(struct r_port *info)
        if (!info)
                return;
 
-       if ((info->flags & ROCKET_INITIALIZED) == 0) {
+       if ((info->flags & ASYNC_INITIALIZED) == 0) {
                printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
                                "info->flags & NOT_INIT\n");
                return;
        }
-       if (!info->tty) {
+       if (!info->port.tty) {
                printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
-                               "info->tty==NULL\n");
+                               "info->port.tty==NULL\n");
                return;
        }
        cp = &info->channel;
-       tty = info->tty;
+       tty = info->port.tty;
 
        IntMask = sGetChanIntID(cp) & info->intmask;
 #ifdef ROCKET_DEBUG_INTR
@@ -529,7 +532,7 @@ static void rp_handle_port(struct r_port *info)
                        tty_hangup(tty);
                }
                info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0;
-               wake_up_interruptible(&info->open_wait);
+               wake_up_interruptible(&info->port.open_wait);
        }
 #ifdef ROCKET_DEBUG_INTR
        if (IntMask & DELTA_CTS) {      /* CTS change */
@@ -647,9 +650,8 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
        info->board = board;
        info->aiop = aiop;
        info->chan = chan;
-       info->closing_wait = 3000;
-       info->close_delay = 50;
-       init_waitqueue_head(&info->open_wait);
+       tty_port_init(&info->port);
+       info->port.ops = &rocket_port_ops;
        init_completion(&info->close_wait);
        info->flags &= ~ROCKET_MODE_MASK;
        switch (pc104[board][line]) {
@@ -716,7 +718,7 @@ static void configure_r_port(struct r_port *info,
        unsigned rocketMode;
        int bits, baud, divisor;
        CHANNEL_t *cp;
-       struct ktermios *t = info->tty->termios;
+       struct ktermios *t = info->port.tty->termios;
 
        cp = &info->channel;
        cflag = t->c_cflag;
@@ -749,7 +751,7 @@ static void configure_r_port(struct r_port *info,
        }
 
        /* baud rate */
-       baud = tty_get_baud_rate(info->tty);
+       baud = tty_get_baud_rate(info->port.tty);
        if (!baud)
                baud = 9600;
        divisor = ((rp_baud_base[info->board] + (baud >> 1)) / baud) - 1;
@@ -767,7 +769,7 @@ static void configure_r_port(struct r_port *info,
        sSetBaud(cp, divisor);
 
        /* FIXME: Should really back compute a baud rate from the divisor */
-       tty_encode_baud_rate(info->tty, baud, baud);
+       tty_encode_baud_rate(info->port.tty, baud, baud);
 
        if (cflag & CRTSCTS) {
                info->intmask |= DELTA_CTS;
@@ -792,15 +794,15 @@ static void configure_r_port(struct r_port *info,
         * Handle software flow control in the board
         */
 #ifdef ROCKET_SOFT_FLOW
-       if (I_IXON(info->tty)) {
+       if (I_IXON(info->port.tty)) {
                sEnTxSoftFlowCtl(cp);
-               if (I_IXANY(info->tty)) {
+               if (I_IXANY(info->port.tty)) {
                        sEnIXANY(cp);
                } else {
                        sDisIXANY(cp);
                }
-               sSetTxXONChar(cp, START_CHAR(info->tty));
-               sSetTxXOFFChar(cp, STOP_CHAR(info->tty));
+               sSetTxXONChar(cp, START_CHAR(info->port.tty));
+               sSetTxXOFFChar(cp, STOP_CHAR(info->port.tty));
        } else {
                sDisTxSoftFlowCtl(cp);
                sDisIXANY(cp);
@@ -812,24 +814,24 @@ static void configure_r_port(struct r_port *info,
         * Set up ignore/read mask words
         */
        info->read_status_mask = STMRCVROVRH | 0xFF;
-       if (I_INPCK(info->tty))
+       if (I_INPCK(info->port.tty))
                info->read_status_mask |= STMFRAMEH | STMPARITYH;
-       if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+       if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
                info->read_status_mask |= STMBREAKH;
 
        /*
         * Characters to ignore
         */
        info->ignore_status_mask = 0;
-       if (I_IGNPAR(info->tty))
+       if (I_IGNPAR(info->port.tty))
                info->ignore_status_mask |= STMFRAMEH | STMPARITYH;
-       if (I_IGNBRK(info->tty)) {
+       if (I_IGNBRK(info->port.tty)) {
                info->ignore_status_mask |= STMBREAKH;
                /*
                 * If we're ignoring parity and break indicators,
                 * ignore overruns too.  (For real raw support).
                 */
-               if (I_IGNPAR(info->tty))
+               if (I_IGNPAR(info->port.tty))
                        info->ignore_status_mask |= STMRCVROVRH;
        }
 
@@ -862,11 +864,25 @@ static void configure_r_port(struct r_port *info,
        }
 }
 
-/*  info->count is considered critical, protected by spinlocks.  */
+static int carrier_raised(struct tty_port *port)
+{
+       struct r_port *info = container_of(port, struct r_port, port);
+       return (sGetChanStatusLo(&info->channel) & CD_ACT) ? 1 : 0;
+}
+
+static void raise_dtr_rts(struct tty_port *port)
+{
+       struct r_port *info = container_of(port, struct r_port, port);
+       sSetDTR(&info->channel);
+       sSetRTS(&info->channel);
+}
+
+/*  info->port.count is considered critical, protected by spinlocks.  */
 static int block_til_ready(struct tty_struct *tty, struct file *filp,
                           struct r_port *info)
 {
        DECLARE_WAITQUEUE(wait, current);
+       struct tty_port *port = &info->port;
        int retval;
        int do_clocal = 0, extra_count = 0;
        unsigned long flags;
@@ -876,11 +892,11 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
         * until it's done, and then try again.
         */
        if (tty_hung_up_p(filp))
-               return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
-       if (info->flags & ROCKET_CLOSING) {
+               return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
+       if (info->flags & ASYNC_CLOSING) {
                if (wait_for_completion_interruptible(&info->close_wait))
                        return -ERESTARTSYS;
-               return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
+               return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
        }
 
        /*
@@ -888,7 +904,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
         * then make the check up front and then exit.
         */
        if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
-               info->flags |= ROCKET_NORMAL_ACTIVE;
+               info->flags |= ASYNC_NORMAL_ACTIVE;
                return 0;
        }
        if (tty->termios->c_cflag & CLOCAL)
@@ -896,42 +912,41 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
 
        /*
         * Block waiting for the carrier detect and the line to become free.  While we are in
-        * this loop, info->count is dropped by one, so that rp_close() knows when to free things.  
+        * this loop, port->count is dropped by one, so that rp_close() knows when to free things.
          * We restore it upon exit, either normal or abnormal.
         */
        retval = 0;
-       add_wait_queue(&info->open_wait, &wait);
+       add_wait_queue(&port->open_wait, &wait);
 #ifdef ROCKET_DEBUG_OPEN
-       printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, info->count);
+       printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, port->count);
 #endif
        spin_lock_irqsave(&info->slock, flags);
 
 #ifdef ROCKET_DISABLE_SIMUSAGE
-       info->flags |= ROCKET_NORMAL_ACTIVE;
+       info->flags |= ASYNC_NORMAL_ACTIVE;
 #else
        if (!tty_hung_up_p(filp)) {
                extra_count = 1;
-               info->count--;
+               port->count--;
        }
 #endif
-       info->blocked_open++;
+       port->blocked_open++;
 
        spin_unlock_irqrestore(&info->slock, flags);
 
        while (1) {
-               if (tty->termios->c_cflag & CBAUD) {
-                       sSetDTR(&info->channel);
-                       sSetRTS(&info->channel);
-               }
+               if (tty->termios->c_cflag & CBAUD)
+                       tty_port_raise_dtr_rts(port);
                set_current_state(TASK_INTERRUPTIBLE);
-               if (tty_hung_up_p(filp) || !(info->flags & ROCKET_INITIALIZED)) {
-                       if (info->flags & ROCKET_HUP_NOTIFY)
+               if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)) {
+                       if (info->flags & ASYNC_HUP_NOTIFY)
                                retval = -EAGAIN;
                        else
                                retval = -ERESTARTSYS;
                        break;
                }
-               if (!(info->flags & ROCKET_CLOSING) && (do_clocal || (sGetChanStatusLo(&info->channel) & CD_ACT)))
+               if (!(info->flags & ASYNC_CLOSING) &&
+                       (do_clocal || tty_port_carrier_raised(port)))
                        break;
                if (signal_pending(current)) {
                        retval = -ERESTARTSYS;
@@ -939,28 +954,28 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
                }
 #ifdef ROCKET_DEBUG_OPEN
                printk(KERN_INFO "block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n",
-                    info->line, info->count, info->flags);
+                    info->line, port->count, info->flags);
 #endif
                schedule();     /*  Don't hold spinlock here, will hang PC */
        }
        __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&info->open_wait, &wait);
+       remove_wait_queue(&port->open_wait, &wait);
 
        spin_lock_irqsave(&info->slock, flags);
 
        if (extra_count)
-               info->count++;
-       info->blocked_open--;
+               port->count++;
+       port->blocked_open--;
 
        spin_unlock_irqrestore(&info->slock, flags);
 
 #ifdef ROCKET_DEBUG_OPEN
        printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n",
-              info->line, info->count);
+              info->line, port->count);
 #endif
        if (retval)
                return retval;
-       info->flags |= ROCKET_NORMAL_ACTIVE;
+       info->flags |= ASYNC_NORMAL_ACTIVE;
        return 0;
 }
 
@@ -983,12 +998,12 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
        if (!page)
                return -ENOMEM;
 
-       if (info->flags & ROCKET_CLOSING) {
+       if (info->flags & ASYNC_CLOSING) {
                retval = wait_for_completion_interruptible(&info->close_wait);
                free_page(page);
                if (retval)
                        return retval;
-               return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
+               return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
        }
 
        /*
@@ -1000,9 +1015,9 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
                info->xmit_buf = (unsigned char *) page;
 
        tty->driver_data = info;
-       info->tty = tty;
+       info->port.tty = tty;
 
-       if (info->count++ == 0) {
+       if (info->port.count++ == 0) {
                atomic_inc(&rp_num_ports_open);
 
 #ifdef ROCKET_DEBUG_OPEN
@@ -1011,13 +1026,13 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
 #endif
        }
 #ifdef ROCKET_DEBUG_OPEN
-       printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->count);
+       printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->port.count);
 #endif
 
        /*
         * Info->count is now 1; so it's safe to sleep now.
         */
-       if ((info->flags & ROCKET_INITIALIZED) == 0) {
+       if ((info->flags & ASYNC_INITIALIZED) == 0) {
                cp = &info->channel;
                sSetRxTrigger(cp, TRIG_1);
                if (sGetChanStatus(cp) & CD_ACT)
@@ -1041,19 +1056,19 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
                sEnRxFIFO(cp);
                sEnTransmit(cp);
 
-               info->flags |= ROCKET_INITIALIZED;
+               info->flags |= ASYNC_INITIALIZED;
 
                /*
                 * Set up the tty->alt_speed kludge
                 */
                if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
-                       info->tty->alt_speed = 57600;
+                       info->port.tty->alt_speed = 57600;
                if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
-                       info->tty->alt_speed = 115200;
+                       info->port.tty->alt_speed = 115200;
                if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
-                       info->tty->alt_speed = 230400;
+                       info->port.tty->alt_speed = 230400;
                if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
-                       info->tty->alt_speed = 460800;
+                       info->port.tty->alt_speed = 460800;
 
                configure_r_port(info, NULL);
                if (tty->termios->c_cflag & CBAUD) {
@@ -1075,11 +1090,11 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
 }
 
 /*
- *  Exception handler that closes a serial port. info->count is considered critical. 
+ *  Exception handler that closes a serial port. info->port.count is considered critical.
  */
 static void rp_close(struct tty_struct *tty, struct file *filp)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
        unsigned long flags;
        int timeout;
        CHANNEL_t *cp;
@@ -1088,14 +1103,14 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
                return;
 
 #ifdef ROCKET_DEBUG_OPEN
-       printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->count);
+       printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->port.count);
 #endif
 
        if (tty_hung_up_p(filp))
                return;
        spin_lock_irqsave(&info->slock, flags);
 
-       if ((tty->count == 1) && (info->count != 1)) {
+       if ((tty->count == 1) && (info->port.count != 1)) {
                /*
                 * Uh, oh.  tty->count is 1, which means that the tty
                 * structure will be freed.  Info->count should always
@@ -1104,19 +1119,19 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
                 * serial port won't be shutdown.
                 */
                printk(KERN_WARNING "rp_close: bad serial port count; "
-                       "tty->count is 1, info->count is %d\n", info->count);
-               info->count = 1;
+                       "tty->count is 1, info->port.count is %d\n", info->port.count);
+               info->port.count = 1;
        }
-       if (--info->count < 0) {
+       if (--info->port.count < 0) {
                printk(KERN_WARNING "rp_close: bad serial port count for "
-                               "ttyR%d: %d\n", info->line, info->count);
-               info->count = 0;
+                               "ttyR%d: %d\n", info->line, info->port.count);
+               info->port.count = 0;
        }
-       if (info->count) {
+       if (info->port.count) {
                spin_unlock_irqrestore(&info->slock, flags);
                return;
        }
-       info->flags |= ROCKET_CLOSING;
+       info->flags |= ASYNC_CLOSING;
        spin_unlock_irqrestore(&info->slock, flags);
 
        cp = &info->channel;
@@ -1136,8 +1151,8 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
        /*
         * Wait for the transmit buffer to clear
         */
-       if (info->closing_wait != ROCKET_CLOSING_WAIT_NONE)
-               tty_wait_until_sent(tty, info->closing_wait);
+       if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
+               tty_wait_until_sent(tty, info->port.closing_wait);
        /*
         * Before we drop DTR, make sure the UART transmitter
         * has completely drained; this is especially
@@ -1166,18 +1181,18 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
 
        clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
 
-       if (info->blocked_open) {
-               if (info->close_delay) {
-                       msleep_interruptible(jiffies_to_msecs(info->close_delay));
+       if (info->port.blocked_open) {
+               if (info->port.close_delay) {
+                       msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
                }
-               wake_up_interruptible(&info->open_wait);
+               wake_up_interruptible(&info->port.open_wait);
        } else {
                if (info->xmit_buf) {
                        free_page((unsigned long) info->xmit_buf);
                        info->xmit_buf = NULL;
                }
        }
-       info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE);
+       info->flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE);
        tty->closing = 0;
        complete_all(&info->close_wait);
        atomic_dec(&rp_num_ports_open);
@@ -1193,7 +1208,7 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
 static void rp_set_termios(struct tty_struct *tty,
                           struct ktermios *old_termios)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
        CHANNEL_t *cp;
        unsigned cflag;
 
@@ -1234,13 +1249,13 @@ static void rp_set_termios(struct tty_struct *tty,
        }
 }
 
-static void rp_break(struct tty_struct *tty, int break_state)
+static int rp_break(struct tty_struct *tty, int break_state)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
        unsigned long flags;
 
        if (rocket_paranoia_check(info, "rp_break"))
-               return;
+               return -EINVAL;
 
        spin_lock_irqsave(&info->slock, flags);
        if (break_state == -1)
@@ -1248,6 +1263,7 @@ static void rp_break(struct tty_struct *tty, int break_state)
        else
                sClrBreak(&info->channel);
        spin_unlock_irqrestore(&info->slock, flags);
+       return 0;
 }
 
 /*
@@ -1281,7 +1297,7 @@ static int sGetChanRI(CHANNEL_T * ChP)
  */
 static int rp_tiocmget(struct tty_struct *tty, struct file *file)
 {
-       struct r_port *info = (struct r_port *)tty->driver_data;
+       struct r_port *info = tty->driver_data;
        unsigned int control, result, ChanStatus;
 
        ChanStatus = sGetChanStatusLo(&info->channel);
@@ -1302,7 +1318,7 @@ static int rp_tiocmget(struct tty_struct *tty, struct file *file)
 static int rp_tiocmset(struct tty_struct *tty, struct file *file,
                    unsigned int set, unsigned int clear)
 {
-       struct r_port *info = (struct r_port *)tty->driver_data;
+       struct r_port *info = tty->driver_data;
 
        if (set & TIOCM_RTS)
                info->channel.TxControl[3] |= SET_RTS;
@@ -1326,8 +1342,8 @@ static int get_config(struct r_port *info, struct rocket_config __user *retinfo)
        memset(&tmp, 0, sizeof (tmp));
        tmp.line = info->line;
        tmp.flags = info->flags;
-       tmp.close_delay = info->close_delay;
-       tmp.closing_wait = info->closing_wait;
+       tmp.close_delay = info->port.close_delay;
+       tmp.closing_wait = info->port.closing_wait;
        tmp.port = rcktpt_io_addr[(info->line >> 5) & 3];
 
        if (copy_to_user(retinfo, &tmp, sizeof (*retinfo)))
@@ -1352,17 +1368,17 @@ static int set_config(struct r_port *info, struct rocket_config __user *new_info
        }
 
        info->flags = ((info->flags & ~ROCKET_FLAGS) | (new_serial.flags & ROCKET_FLAGS));
-       info->close_delay = new_serial.close_delay;
-       info->closing_wait = new_serial.closing_wait;
+       info->port.close_delay = new_serial.close_delay;
+       info->port.closing_wait = new_serial.closing_wait;
 
        if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
-               info->tty->alt_speed = 57600;
+               info->port.tty->alt_speed = 57600;
        if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
-               info->tty->alt_speed = 115200;
+               info->port.tty->alt_speed = 115200;
        if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
-               info->tty->alt_speed = 230400;
+               info->port.tty->alt_speed = 230400;
        if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
-               info->tty->alt_speed = 460800;
+               info->port.tty->alt_speed = 460800;
 
        configure_r_port(info, NULL);
        return 0;
@@ -1431,36 +1447,45 @@ static int get_version(struct r_port *info, struct rocket_version __user *retver
 static int rp_ioctl(struct tty_struct *tty, struct file *file,
                    unsigned int cmd, unsigned long arg)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
        void __user *argp = (void __user *)arg;
+       int ret = 0;
 
        if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl"))
                return -ENXIO;
 
+       lock_kernel();
+
        switch (cmd) {
        case RCKP_GET_STRUCT:
                if (copy_to_user(argp, info, sizeof (struct r_port)))
-                       return -EFAULT;
-               return 0;
+                       ret = -EFAULT;
+               break;
        case RCKP_GET_CONFIG:
-               return get_config(info, argp);
+               ret = get_config(info, argp);
+               break;
        case RCKP_SET_CONFIG:
-               return set_config(info, argp);
+               ret = set_config(info, argp);
+               break;
        case RCKP_GET_PORTS:
-               return get_ports(info, argp);
+               ret = get_ports(info, argp);
+               break;
        case RCKP_RESET_RM2:
-               return reset_rm2(info, argp);
+               ret = reset_rm2(info, argp);
+               break;
        case RCKP_GET_VERSION:
-               return get_version(info, argp);
+               ret = get_version(info, argp);
+               break;
        default:
-               return -ENOIOCTLCMD;
+               ret = -ENOIOCTLCMD;
        }
-       return 0;
+       unlock_kernel();
+       return ret;
 }
 
 static void rp_send_xchar(struct tty_struct *tty, char ch)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
        CHANNEL_t *cp;
 
        if (rocket_paranoia_check(info, "rp_send_xchar"))
@@ -1475,7 +1500,7 @@ static void rp_send_xchar(struct tty_struct *tty, char ch)
 
 static void rp_throttle(struct tty_struct *tty)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
        CHANNEL_t *cp;
 
 #ifdef ROCKET_DEBUG_THROTTLE
@@ -1495,7 +1520,7 @@ static void rp_throttle(struct tty_struct *tty)
 
 static void rp_unthrottle(struct tty_struct *tty)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
        CHANNEL_t *cp;
 #ifdef ROCKET_DEBUG_THROTTLE
        printk(KERN_INFO "unthrottle %s: %d....\n", tty->name,
@@ -1522,7 +1547,7 @@ static void rp_unthrottle(struct tty_struct *tty)
  */
 static void rp_stop(struct tty_struct *tty)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
 
 #ifdef ROCKET_DEBUG_FLOW
        printk(KERN_INFO "stop %s: %d %d....\n", tty->name,
@@ -1538,7 +1563,7 @@ static void rp_stop(struct tty_struct *tty)
 
 static void rp_start(struct tty_struct *tty)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
 
 #ifdef ROCKET_DEBUG_FLOW
        printk(KERN_INFO "start %s: %d %d....\n", tty->name,
@@ -1558,7 +1583,7 @@ static void rp_start(struct tty_struct *tty)
  */
 static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
        CHANNEL_t *cp;
        unsigned long orig_jiffies;
        int check_time, exit_time;
@@ -1575,6 +1600,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
               jiffies);
        printk(KERN_INFO "cps=%d...\n", info->cps);
 #endif
+       lock_kernel();
        while (1) {
                txcnt = sGetTxCnt(cp);
                if (!txcnt) {
@@ -1602,6 +1628,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
                        break;
        }
        __set_current_state(TASK_RUNNING);
+       unlock_kernel();
 #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
        printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
 #endif
@@ -1613,7 +1640,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
 static void rp_hangup(struct tty_struct *tty)
 {
        CHANNEL_t *cp;
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
 
        if (rocket_paranoia_check(info, "rp_hangup"))
                return;
@@ -1622,15 +1649,15 @@ static void rp_hangup(struct tty_struct *tty)
        printk(KERN_INFO "rp_hangup of ttyR%d...\n", info->line);
 #endif
        rp_flush_buffer(tty);
-       if (info->flags & ROCKET_CLOSING)
+       if (info->flags & ASYNC_CLOSING)
                return;
-       if (info->count) 
+       if (info->port.count)
                atomic_dec(&rp_num_ports_open);
        clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
 
-       info->count = 0;
-       info->flags &= ~ROCKET_NORMAL_ACTIVE;
-       info->tty = NULL;
+       info->port.count = 0;
+       info->flags &= ~ASYNC_NORMAL_ACTIVE;
+       info->port.tty = NULL;
 
        cp = &info->channel;
        sDisRxFIFO(cp);
@@ -1639,9 +1666,9 @@ static void rp_hangup(struct tty_struct *tty)
        sDisCTSFlowCtl(cp);
        sDisTxSoftFlowCtl(cp);
        sClrTxXOFF(cp);
-       info->flags &= ~ROCKET_INITIALIZED;
+       info->flags &= ~ASYNC_INITIALIZED;
 
-       wake_up_interruptible(&info->open_wait);
+       wake_up_interruptible(&info->port.open_wait);
 }
 
 /*
@@ -1651,14 +1678,14 @@ static void rp_hangup(struct tty_struct *tty)
  *  writing routines will write directly to transmit FIFO.
  *  Write buffer and counters protected by spinlocks
  */
-static void rp_put_char(struct tty_struct *tty, unsigned char ch)
+static int rp_put_char(struct tty_struct *tty, unsigned char ch)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
        CHANNEL_t *cp;
        unsigned long flags;
 
        if (rocket_paranoia_check(info, "rp_put_char"))
-               return;
+               return 0;
 
        /*
         * Grab the port write mutex, locking out other processes that try to
@@ -1687,6 +1714,7 @@ static void rp_put_char(struct tty_struct *tty, unsigned char ch)
        }
        spin_unlock_irqrestore(&info->slock, flags);
        mutex_unlock(&info->write_mtx);
+       return 1;
 }
 
 /*
@@ -1699,7 +1727,7 @@ static void rp_put_char(struct tty_struct *tty, unsigned char ch)
 static int rp_write(struct tty_struct *tty,
                    const unsigned char *buf, int count)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
        CHANNEL_t *cp;
        const unsigned char *b;
        int c, retval = 0;
@@ -1749,10 +1777,10 @@ static int rp_write(struct tty_struct *tty,
 
        /*  Write remaining data into the port's xmit_buf */
        while (1) {
-               if (!info->tty) /*   Seemingly obligatory check... */
+               if (!info->port.tty)            /* Seemingly obligatory check... */
                        goto end;
-
-               c = min(count, min(XMIT_BUF_SIZE - info->xmit_cnt - 1, XMIT_BUF_SIZE - info->xmit_head));
+               c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
+               c = min(c, XMIT_BUF_SIZE - info->xmit_head);
                if (c <= 0)
                        break;
 
@@ -1791,7 +1819,7 @@ end:
  */
 static int rp_write_room(struct tty_struct *tty)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
        int ret;
 
        if (rocket_paranoia_check(info, "rp_write_room"))
@@ -1812,7 +1840,7 @@ static int rp_write_room(struct tty_struct *tty)
  */
 static int rp_chars_in_buffer(struct tty_struct *tty)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
        CHANNEL_t *cp;
 
        if (rocket_paranoia_check(info, "rp_chars_in_buffer"))
@@ -1833,7 +1861,7 @@ static int rp_chars_in_buffer(struct tty_struct *tty)
  */
 static void rp_flush_buffer(struct tty_struct *tty)
 {
-       struct r_port *info = (struct r_port *) tty->driver_data;
+       struct r_port *info = tty->driver_data;
        CHANNEL_t *cp;
        unsigned long flags;
 
@@ -2356,6 +2384,11 @@ static const struct tty_operations rocket_ops = {
        .tiocmset = rp_tiocmset,
 };
 
+static const struct tty_port_operations rocket_port_ops = {
+       .carrier_raised = carrier_raised,
+       .raise_dtr_rts = raise_dtr_rts,
+};
+
 /*
  * The module "startup" routine; it's run when the module is loaded.
  */