nfsd: do_probe_callback should not clear rpc stats
[safe/jmp/linux-2.6] / drivers / char / stallion.c
index 8c73ccb..19db1eb 100644 (file)
@@ -145,8 +145,7 @@ static struct stlbrd                *stl_brds[STL_MAXBRDS];
  */
 #define        ASYI_TXBUSY     1
 #define        ASYI_TXLOW      2
-#define        ASYI_DCDCHANGE  3
-#define        ASYI_TXFLOWED   4
+#define        ASYI_TXFLOWED   3
 
 /*
  *     Define an array of board names as printable strings. Handy for
@@ -610,6 +609,23 @@ static const struct file_operations        stl_fsiomem = {
 
 static struct class *stallion_class;
 
+static void stl_cd_change(struct stlport *portp)
+{
+       unsigned int oldsigs = portp->sigs;
+
+       if (!portp->port.tty)
+               return;
+
+       portp->sigs = stl_getsignals(portp);
+
+       if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0))
+               wake_up_interruptible(&portp->port.open_wait);
+
+       if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0))
+               if (portp->port.flags & ASYNC_CHECK_CD)
+                       tty_hangup(portp->port.tty);
+}
+
 /*
  *     Check for any arguments passed in on the module load command line.
  */
@@ -718,11 +734,11 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
  *     On the first open of the device setup the port hardware, and
  *     initialize the per port data structure.
  */
-       portp->tty = tty;
+       portp->port.tty = tty;
        tty->driver_data = portp;
-       portp->refcount++;
+       portp->port.count++;
 
-       if ((portp->flags & ASYNC_INITIALIZED) == 0) {
+       if ((portp->port.flags & ASYNC_INITIALIZED) == 0) {
                if (!portp->tx.buf) {
                        portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
                        if (!portp->tx.buf)
@@ -736,7 +752,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
                stl_enablerxtx(portp, 1, 1);
                stl_startrxtx(portp, 1, 0);
                clear_bit(TTY_IO_ERROR, &tty->flags);
-               portp->flags |= ASYNC_INITIALIZED;
+               portp->port.flags |= ASYNC_INITIALIZED;
        }
 
 /*
@@ -745,9 +761,9 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
  *     The sleep here does not need interrupt protection since the wakeup
  *     for it is done with the same context.
  */
-       if (portp->flags & ASYNC_CLOSING) {
-               interruptible_sleep_on(&portp->close_wait);
-               if (portp->flags & ASYNC_HUP_NOTIFY)
+       if (portp->port.flags & ASYNC_CLOSING) {
+               interruptible_sleep_on(&portp->port.close_wait);
+               if (portp->port.flags & ASYNC_HUP_NOTIFY)
                        return -EAGAIN;
                return -ERESTARTSYS;
        }
@@ -761,7 +777,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
                if ((rc = stl_waitcarrier(portp, filp)) != 0)
                        return rc;
 
-       portp->flags |= ASYNC_NORMAL_ACTIVE;
+       portp->port.flags |= ASYNC_NORMAL_ACTIVE;
 
        return 0;
 }
@@ -785,25 +801,25 @@ static int stl_waitcarrier(struct stlport *portp, struct file *filp)
 
        spin_lock_irqsave(&stallion_lock, flags);
 
-       if (portp->tty->termios->c_cflag & CLOCAL)
+       if (portp->port.tty->termios->c_cflag & CLOCAL)
                doclocal++;
 
        portp->openwaitcnt++;
        if (! tty_hung_up_p(filp))
-               portp->refcount--;
+               portp->port.count--;
 
        for (;;) {
                /* Takes brd_lock internally */
                stl_setsignals(portp, 1, 1);
                if (tty_hung_up_p(filp) ||
-                   ((portp->flags & ASYNC_INITIALIZED) == 0)) {
-                       if (portp->flags & ASYNC_HUP_NOTIFY)
+                   ((portp->port.flags & ASYNC_INITIALIZED) == 0)) {
+                       if (portp->port.flags & ASYNC_HUP_NOTIFY)
                                rc = -EBUSY;
                        else
                                rc = -ERESTARTSYS;
                        break;
                }
-               if (((portp->flags & ASYNC_CLOSING) == 0) &&
+               if (((portp->port.flags & ASYNC_CLOSING) == 0) &&
                    (doclocal || (portp->sigs & TIOCM_CD)))
                        break;
                if (signal_pending(current)) {
@@ -811,11 +827,11 @@ static int stl_waitcarrier(struct stlport *portp, struct file *filp)
                        break;
                }
                /* FIXME */
-               interruptible_sleep_on(&portp->open_wait);
+               interruptible_sleep_on(&portp->port.open_wait);
        }
 
        if (! tty_hung_up_p(filp))
-               portp->refcount++;
+               portp->port.count++;
        portp->openwaitcnt--;
        spin_unlock_irqrestore(&stallion_lock, flags);
 
@@ -859,6 +875,7 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout)
                timeout = HZ;
        tend = jiffies + timeout;
 
+       lock_kernel();
        while (stl_datastate(portp)) {
                if (signal_pending(current))
                        break;
@@ -866,6 +883,7 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout)
                if (time_after_eq(jiffies, tend))
                        break;
        }
+       unlock_kernel();
 }
 
 /*****************************************************************************/
@@ -886,15 +904,15 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
                spin_unlock_irqrestore(&stallion_lock, flags);
                return;
        }
-       if ((tty->count == 1) && (portp->refcount != 1))
-               portp->refcount = 1;
-       if (portp->refcount-- > 1) {
+       if ((tty->count == 1) && (portp->port.count != 1))
+               portp->port.count = 1;
+       if (portp->port.count-- > 1) {
                spin_unlock_irqrestore(&stallion_lock, flags);
                return;
        }
 
-       portp->refcount = 0;
-       portp->flags |= ASYNC_CLOSING;
+       portp->port.count = 0;
+       portp->port.flags |= ASYNC_CLOSING;
 
 /*
  *     May want to wait for any data to drain before closing. The BUSY
@@ -912,7 +930,7 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
 
 
        spin_lock_irqsave(&stallion_lock, flags);
-       portp->flags &= ~ASYNC_INITIALIZED;
+       portp->port.flags &= ~ASYNC_INITIALIZED;
        spin_unlock_irqrestore(&stallion_lock, flags);
 
        stl_disableintrs(portp);
@@ -931,16 +949,16 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
        tty_ldisc_flush(tty);
 
        tty->closing = 0;
-       portp->tty = NULL;
+       portp->port.tty = NULL;
 
        if (portp->openwaitcnt) {
                if (portp->close_delay)
                        msleep_interruptible(jiffies_to_msecs(portp->close_delay));
-               wake_up_interruptible(&portp->open_wait);
+               wake_up_interruptible(&portp->port.open_wait);
        }
 
-       portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
-       wake_up_interruptible(&portp->close_wait);
+       portp->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+       wake_up_interruptible(&portp->port.close_wait);
 }
 
 /*****************************************************************************/
@@ -1007,7 +1025,7 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count
 
 /*****************************************************************************/
 
-static void stl_putchar(struct tty_struct *tty, unsigned char ch)
+static int stl_putchar(struct tty_struct *tty, unsigned char ch)
 {
        struct stlport  *portp;
        unsigned int    len;
@@ -1016,12 +1034,12 @@ static void stl_putchar(struct tty_struct *tty, unsigned char ch)
        pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch);
 
        if (tty == NULL)
-               return;
+               return -EINVAL;
        portp = tty->driver_data;
        if (portp == NULL)
-               return;
+               return -EINVAL;
        if (portp->tx.buf == NULL)
-               return;
+               return -EINVAL;
 
        head = portp->tx.head;
        tail = portp->tx.tail;
@@ -1035,6 +1053,7 @@ static void stl_putchar(struct tty_struct *tty, unsigned char ch)
                        head = portp->tx.buf;
        }       
        portp->tx.head = head;
+       return 0;
 }
 
 /*****************************************************************************/
@@ -1135,7 +1154,7 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp)
        memset(&sio, 0, sizeof(struct serial_struct));
        sio.line = portp->portnr;
        sio.port = portp->ioaddr;
-       sio.flags = portp->flags;
+       sio.flags = portp->port.flags;
        sio.baud_base = portp->baud_base;
        sio.close_delay = portp->close_delay;
        sio.closing_wait = portp->closing_wait;
@@ -1176,17 +1195,17 @@ static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp)
                if ((sio.baud_base != portp->baud_base) ||
                    (sio.close_delay != portp->close_delay) ||
                    ((sio.flags & ~ASYNC_USR_MASK) !=
-                   (portp->flags & ~ASYNC_USR_MASK)))
+                   (portp->port.flags & ~ASYNC_USR_MASK)))
                        return -EPERM;
        } 
 
-       portp->flags = (portp->flags & ~ASYNC_USR_MASK) |
+       portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) |
                (sio.flags & ASYNC_USR_MASK);
        portp->baud_base = sio.baud_base;
        portp->close_delay = sio.close_delay;
        portp->closing_wait = sio.closing_wait;
        portp->custom_divisor = sio.custom_divisor;
-       stl_setport(portp, portp->tty->termios);
+       stl_setport(portp, portp->port.tty->termios);
        return 0;
 }
 
@@ -1237,7 +1256,6 @@ static int stl_tiocmset(struct tty_struct *tty, struct file *file,
 static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct stlport  *portp;
-       unsigned int    ival;
        int             rc;
        void __user *argp = (void __user *)arg;
 
@@ -1257,18 +1275,9 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd
 
        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 (get_user(ival, (unsigned int __user *) arg))
-                       return -EFAULT;
-               tty->termios->c_cflag =
-                               (tty->termios->c_cflag & ~CLOCAL) |
-                               (ival ? CLOCAL : 0);
-               break;
        case TIOCGSERIAL:
                rc = stl_getserial(portp, argp);
                break;
@@ -1292,7 +1301,7 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd
                rc = -ENOIOCTLCMD;
                break;
        }
-
+       unlock_kernel();
        return rc;
 }
 
@@ -1344,7 +1353,7 @@ static void stl_settermios(struct tty_struct *tty, struct ktermios *old)
                stl_start(tty);
        }
        if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL))
-               wake_up_interruptible(&portp->open_wait);
+               wake_up_interruptible(&portp->port.open_wait);
 }
 
 /*****************************************************************************/
@@ -1429,7 +1438,7 @@ static void stl_hangup(struct tty_struct *tty)
        if (portp == NULL)
                return;
 
-       portp->flags &= ~ASYNC_INITIALIZED;
+       portp->port.flags &= ~ASYNC_INITIALIZED;
        stl_disableintrs(portp);
        if (tty->termios->c_cflag & HUPCL)
                stl_setsignals(portp, 0, 0);
@@ -1443,27 +1452,28 @@ static void stl_hangup(struct tty_struct *tty)
                portp->tx.head = NULL;
                portp->tx.tail = NULL;
        }
-       portp->tty = NULL;
-       portp->flags &= ~ASYNC_NORMAL_ACTIVE;
-       portp->refcount = 0;
-       wake_up_interruptible(&portp->open_wait);
+       portp->port.tty = NULL;
+       portp->port.flags &= ~ASYNC_NORMAL_ACTIVE;
+       portp->port.count = 0;
+       wake_up_interruptible(&portp->port.open_wait);
 }
 
 /*****************************************************************************/
 
-static void stl_breakctl(struct tty_struct *tty, int state)
+static int stl_breakctl(struct tty_struct *tty, int state)
 {
        struct stlport  *portp;
 
        pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state);
 
        if (tty == NULL)
-               return;
+               return -EINVAL;
        portp = tty->driver_data;
        if (portp == NULL)
-               return;
+               return -EINVAL;
 
        stl_sendbreak(portp, ((state == -1) ? 1 : 2));
+       return 0;
 }
 
 /*****************************************************************************/
@@ -1629,7 +1639,7 @@ static irqreturn_t stl_intr(int irq, void *dev_id)
 {
        struct stlbrd *brdp = dev_id;
 
-       pr_debug("stl_intr(brdp=%p,irq=%d)\n", brdp, irq);
+       pr_debug("stl_intr(brdp=%p,irq=%d)\n", brdp, brdp->irq);
 
        return IRQ_RETVAL((* brdp->isr)(brdp));
 }
@@ -1771,43 +1781,6 @@ static int stl_echpci64intr(struct stlbrd *brdp)
 /*****************************************************************************/
 
 /*
- *     Service an off-level request for some channel.
- */
-static void stl_offintr(struct work_struct *work)
-{
-       struct stlport          *portp = container_of(work, struct stlport, tqueue);
-       struct tty_struct       *tty;
-       unsigned int            oldsigs;
-
-       pr_debug("stl_offintr(portp=%p)\n", portp);
-
-       if (portp == NULL)
-               return;
-
-       tty = portp->tty;
-       if (tty == NULL)
-               return;
-
-       lock_kernel();
-       if (test_bit(ASYI_TXLOW, &portp->istate))
-               tty_wakeup(tty);
-
-       if (test_bit(ASYI_DCDCHANGE, &portp->istate)) {
-               clear_bit(ASYI_DCDCHANGE, &portp->istate);
-               oldsigs = portp->sigs;
-               portp->sigs = stl_getsignals(portp);
-               if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0))
-                       wake_up_interruptible(&portp->open_wait);
-               if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0))
-                       if (portp->flags & ASYNC_CHECK_CD)
-                               tty_hangup(tty);        /* FIXME: module removal race here - AKPM */
-       }
-       unlock_kernel();
-}
-
-/*****************************************************************************/
-
-/*
  *     Initialize all the ports on a panel.
  */
 
@@ -1842,9 +1815,8 @@ static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp)
                portp->baud_base = STL_BAUDBASE;
                portp->close_delay = STL_CLOSEDELAY;
                portp->closing_wait = 30 * HZ;
-               INIT_WORK(&portp->tqueue, stl_offintr);
-               init_waitqueue_head(&portp->open_wait);
-               init_waitqueue_head(&portp->close_wait);
+               init_waitqueue_head(&portp->port.open_wait);
+               init_waitqueue_head(&portp->port.close_wait);
                portp->stats.brd = portp->brdnr;
                portp->stats.panel = portp->panelnr;
                portp->stats.port = portp->portnr;
@@ -1869,8 +1841,8 @@ static void stl_cleanup_panels(struct stlbrd *brdp)
                        portp = panelp->ports[k];
                        if (portp == NULL)
                                continue;
-                       if (portp->tty != NULL)
-                               stl_hangup(portp->tty);
+                       if (portp->port.tty != NULL)
+                               stl_hangup(portp->port.tty);
                        kfree(portp->tx.buf);
                        kfree(portp);
                }
@@ -2357,9 +2329,6 @@ static int __devinit stl_pciprobe(struct pci_dev *pdev,
        if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE)
                goto err;
 
-       dev_info(&pdev->dev, "please, report this to LKML: %x/%x/%x\n",
-                       pdev->vendor, pdev->device, pdev->class);
-
        retval = pci_enable_device(pdev);
        if (retval)
                goto err;
@@ -2545,7 +2514,7 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp)
        }
 
        portp->stats.state = portp->istate;
-       portp->stats.flags = portp->flags;
+       portp->stats.flags = portp->port.flags;
        portp->stats.hwid = portp->hwid;
 
        portp->stats.ttystate = 0;
@@ -2556,16 +2525,16 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp)
        portp->stats.rxbuffered = 0;
 
        spin_lock_irqsave(&stallion_lock, flags);
-       if (portp->tty != NULL)
-               if (portp->tty->driver_data == portp) {
-                       portp->stats.ttystate = portp->tty->flags;
+       if (portp->port.tty != NULL)
+               if (portp->port.tty->driver_data == portp) {
+                       portp->stats.ttystate = portp->port.tty->flags;
                        /* No longer available as a statistic */
-                       portp->stats.rxbuffered = 1; /*portp->tty->flip.count; */
-                       if (portp->tty->termios != NULL) {
-                               portp->stats.cflags = portp->tty->termios->c_cflag;
-                               portp->stats.iflags = portp->tty->termios->c_iflag;
-                               portp->stats.oflags = portp->tty->termios->c_oflag;
-                               portp->stats.lflags = portp->tty->termios->c_lflag;
+                       portp->stats.rxbuffered = 1; /*portp->port.tty->flip.count; */
+                       if (portp->port.tty->termios != NULL) {
+                               portp->stats.cflags = portp->port.tty->termios->c_cflag;
+                               portp->stats.iflags = portp->port.tty->termios->c_iflag;
+                               portp->stats.oflags = portp->port.tty->termios->c_oflag;
+                               portp->stats.lflags = portp->port.tty->termios->c_lflag;
                        }
                }
        spin_unlock_irqrestore(&stallion_lock, flags);
@@ -2971,15 +2940,15 @@ static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp)
        }
        baudrate = stl_baudrates[baudrate];
        if ((tiosp->c_cflag & CBAUD) == B38400) {
-               if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+               if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
                        baudrate = 57600;
-               else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+               else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
                        baudrate = 115200;
-               else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+               else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
                        baudrate = 230400;
-               else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+               else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
                        baudrate = 460800;
-               else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
+               else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
                        baudrate = (portp->baud_base / portp->custom_divisor);
        }
        if (baudrate > STL_CD1400MAXBAUD)
@@ -3001,9 +2970,9 @@ static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp)
                mcor1 |= MCOR1_DCD;
                mcor2 |= MCOR2_DCD;
                sreron |= SRER_MODEM;
-               portp->flags |= ASYNC_CHECK_CD;
+               portp->port.flags |= ASYNC_CHECK_CD;
        } else
-               portp->flags &= ~ASYNC_CHECK_CD;
+               portp->port.flags &= ~ASYNC_CHECK_CD;
 
 /*
  *     Setup cd1400 enhanced modes if we can. In particular we want to
@@ -3274,7 +3243,7 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state)
 
        if (portp == NULL)
                return;
-       tty = portp->tty;
+       tty = portp->port.tty;
        if (tty == NULL)
                return;
 
@@ -3336,7 +3305,7 @@ static void stl_cd1400sendflow(struct stlport *portp, int state)
 
        if (portp == NULL)
                return;
-       tty = portp->tty;
+       tty = portp->port.tty;
        if (tty == NULL)
                return;
 
@@ -3535,7 +3504,8 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr)
        if ((len == 0) || ((len < STL_TXBUFLOW) &&
            (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
                set_bit(ASYI_TXLOW, &portp->istate);
-               schedule_work(&portp->tqueue);
+               if (portp->port.tty)
+                       tty_wakeup(portp->port.tty);
        }
 
        if (len == 0) {
@@ -3551,7 +3521,8 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr)
        } else {
                len = min(len, CD1400_TXFIFOSIZE);
                portp->stats.txtotal += len;
-               stlen = min(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
+               stlen = min_t(unsigned int, len,
+                               (portp->tx.buf + STL_TXBUFSIZE) - tail);
                outb((TDR + portp->uartaddr), ioaddr);
                outsb((ioaddr + EREG_DATA), tail, stlen);
                len -= stlen;
@@ -3598,13 +3569,13 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr)
                return;
        }
        portp = panelp->ports[(ioack >> 3)];
-       tty = portp->tty;
+       tty = portp->port.tty;
 
        if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) {
                outb((RDCR + portp->uartaddr), ioaddr);
                len = inb(ioaddr + EREG_DATA);
                if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) {
-                       len = min(len, sizeof(stl_unwanted));
+                       len = min_t(unsigned int, len, sizeof(stl_unwanted));
                        outb((RDSR + portp->uartaddr), ioaddr);
                        insb((ioaddr + EREG_DATA), &stl_unwanted[0], len);
                        portp->stats.rxlost += len;
@@ -3643,7 +3614,7 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr)
                        if (portp->rxmarkmsk & status) {
                                if (status & ST_BREAK) {
                                        status = TTY_BREAK;
-                                       if (portp->flags & ASYNC_SAK) {
+                                       if (portp->port.flags & ASYNC_SAK) {
                                                do_SAK(tty);
                                                BRDENABLE(portp->brdnr, portp->pagenr);
                                        }
@@ -3697,8 +3668,7 @@ static void stl_cd1400mdmisr(struct stlpanel *panelp, int ioaddr)
        outb((MISR + portp->uartaddr), ioaddr);
        misr = inb(ioaddr + EREG_DATA);
        if (misr & MISR_DCD) {
-               set_bit(ASYI_DCDCHANGE, &portp->istate);
-               schedule_work(&portp->tqueue);
+               stl_cd_change(portp);
                portp->stats.modem++;
        }
 
@@ -3930,15 +3900,15 @@ static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp)
        }
        baudrate = stl_baudrates[baudrate];
        if ((tiosp->c_cflag & CBAUD) == B38400) {
-               if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+               if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
                        baudrate = 57600;
-               else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+               else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
                        baudrate = 115200;
-               else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+               else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
                        baudrate = 230400;
-               else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+               else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
                        baudrate = 460800;
-               else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
+               else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
                        baudrate = (portp->baud_base / portp->custom_divisor);
        }
        if (baudrate > STL_SC26198MAXBAUD)
@@ -3953,11 +3923,11 @@ static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp)
  *     Check what form of modem signaling is required and set it up.
  */
        if (tiosp->c_cflag & CLOCAL) {
-               portp->flags &= ~ASYNC_CHECK_CD;
+               portp->port.flags &= ~ASYNC_CHECK_CD;
        } else {
                iopr |= IOPR_DCDCOS;
                imron |= IR_IOPORT;
-               portp->flags |= ASYNC_CHECK_CD;
+               portp->port.flags |= ASYNC_CHECK_CD;
        }
 
 /*
@@ -4205,7 +4175,7 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state)
 
        if (portp == NULL)
                return;
-       tty = portp->tty;
+       tty = portp->port.tty;
        if (tty == NULL)
                return;
 
@@ -4274,7 +4244,7 @@ static void stl_sc26198sendflow(struct stlport *portp, int state)
 
        if (portp == NULL)
                return;
-       tty = portp->tty;
+       tty = portp->port.tty;
        if (tty == NULL)
                return;
 
@@ -4452,7 +4422,8 @@ static void stl_sc26198txisr(struct stlport *portp)
        if ((len == 0) || ((len < STL_TXBUFLOW) &&
            (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
                set_bit(ASYI_TXLOW, &portp->istate);
-               schedule_work(&portp->tqueue); 
+               if (portp->port.tty)
+                       tty_wakeup(portp->port.tty);
        }
 
        if (len == 0) {
@@ -4470,7 +4441,8 @@ static void stl_sc26198txisr(struct stlport *portp)
        } else {
                len = min(len, SC26198_TXFIFOSIZE);
                portp->stats.txtotal += len;
-               stlen = min(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
+               stlen = min_t(unsigned int, len,
+                               (portp->tx.buf + STL_TXBUFSIZE) - tail);
                outb(GTXFIFO, (ioaddr + XP_ADDR));
                outsb((ioaddr + XP_DATA), tail, stlen);
                len -= stlen;
@@ -4504,14 +4476,14 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack)
 
        pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack);
 
-       tty = portp->tty;
+       tty = portp->port.tty;
        ioaddr = portp->ioaddr;
        outb(GIBCR, (ioaddr + XP_ADDR));
        len = inb(ioaddr + XP_DATA) + 1;
 
        if ((iack & IVR_TYPEMASK) == IVR_RXDATA) {
                if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) {
-                       len = min(len, sizeof(stl_unwanted));
+                       len = min_t(unsigned int, len, sizeof(stl_unwanted));
                        outb(GRXFIFO, (ioaddr + XP_ADDR));
                        insb((ioaddr + XP_DATA), &stl_unwanted[0], len);
                        portp->stats.rxlost += len;
@@ -4556,7 +4528,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char
        struct tty_struct       *tty;
        unsigned int            ioaddr;
 
-       tty = portp->tty;
+       tty = portp->port.tty;
        ioaddr = portp->ioaddr;
 
        if (status & SR_RXPARITY)
@@ -4573,7 +4545,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char
                if (portp->rxmarkmsk & status) {
                        if (status & SR_RXBREAK) {
                                status = TTY_BREAK;
-                               if (portp->flags & ASYNC_SAK) {
+                               if (portp->port.flags & ASYNC_SAK) {
                                        do_SAK(tty);
                                        BRDENABLE(portp->brdnr, portp->pagenr);
                                }
@@ -4652,8 +4624,7 @@ static void stl_sc26198otherisr(struct stlport *portp, unsigned int iack)
        case CIR_SUBCOS:
                ipr = stl_sc26198getreg(portp, IPR);
                if (ipr & IPR_DCDCHANGE) {
-                       set_bit(ASYI_DCDCHANGE, &portp->istate);
-                       schedule_work(&portp->tqueue); 
+                       stl_cd_change(portp);
                        portp->stats.modem++;
                }
                break;
@@ -4783,9 +4754,8 @@ static int __init stallion_module_init(void)
        if (IS_ERR(stallion_class))
                printk("STALLION: failed to create class\n");
        for (i = 0; i < 4; i++)
-               class_device_create(stallion_class, NULL,
-                                   MKDEV(STL_SIOMEMMAJOR, i), NULL,
-                                   "staliomem%d", i);
+               device_create_drvdata(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
+                                     NULL, "staliomem%d", i);
 
        return 0;
 err_unrtty:
@@ -4800,7 +4770,6 @@ static void __exit stallion_module_exit(void)
 {
        struct stlbrd *brdp;
        unsigned int i, j;
-       int retval;
 
        pr_debug("cleanup_module()\n");
 
@@ -4822,10 +4791,8 @@ static void __exit stallion_module_exit(void)
        }
 
        for (i = 0; i < 4; i++)
-               class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
-       if ((retval = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
-               printk("STALLION: failed to un-register serial memory device, "
-                       "errno=%d\n", -retval);
+               device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
+       unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
        class_destroy(stallion_class);
 
        pci_unregister_driver(&stl_pcidriver);