Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / char / istallion.c
index 1a5a2df..84dfc42 100644 (file)
@@ -3,7 +3,7 @@
 /*
  *     istallion.c  -- stallion intelligent multiport serial driver.
  *
- *     Copyright (C) 1996-1999  Stallion Technologies (support@stallion.oz.au).
+ *     Copyright (C) 1996-1999  Stallion Technologies
  *     Copyright (C) 1994-1996  Greg Ungerer.
  *
  *     This code is loosely based on the Linux serial driver, written by
@@ -26,7 +26,6 @@
 
 /*****************************************************************************/
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/eisa.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_PCI
 #include <linux/pci.h>
-#endif
 
 /*****************************************************************************/
 
@@ -134,7 +132,11 @@ static stlconf_t   stli_brdconf[] = {
        /*{ BRD_ECP, 0x2a0, 0, 0xcc000, 0, 0 },*/
 };
 
-static int     stli_nrbrds = sizeof(stli_brdconf) / sizeof(stlconf_t);
+static int     stli_nrbrds = ARRAY_SIZE(stli_brdconf);
+
+/* stli_lock must NOT be taken holding brd_lock */
+static spinlock_t stli_lock;   /* TTY logic lock */
+static spinlock_t brd_lock;    /* Board logic lock */
 
 /*
  *     There is some experimental EISA board detection code in this driver.
@@ -172,15 +174,6 @@ static char        *stli_serialname = "ttyE";
 
 static struct tty_driver       *stli_serial;
 
-/*
- *     We will need to allocate a temporary write buffer for chars that
- *     come direct from user space. The problem is that a copy from user
- *     space might cause a page fault (typically on a system that is
- *     swapping!). All ports will share one buffer - since if the system
- *     is already swapping a shared buffer won't make things any worse.
- */
-static char                    *stli_tmpwritebuf;
-static DECLARE_MUTEX(stli_tmpwritesem);
 
 #define        STLI_TXBUFSIZE          4096
 
@@ -288,7 +281,6 @@ static char *stli_brdnames[] = {
 
 /*****************************************************************************/
 
-#ifdef MODULE
 /*
  *     Define some string labels for arguments passed from the module
  *     load line. These allow for easy board definitions, and easy
@@ -378,17 +370,15 @@ MODULE_DESCRIPTION("Stallion Intelligent Multiport Serial Driver");
 MODULE_LICENSE("GPL");
 
 
-MODULE_PARM(board0, "1-3s");
+module_param_array(board0, charp, NULL, 0);
 MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,memaddr]");
-MODULE_PARM(board1, "1-3s");
+module_param_array(board1, charp, NULL, 0);
 MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,memaddr]");
-MODULE_PARM(board2, "1-3s");
+module_param_array(board2, charp, NULL, 0);
 MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,memaddr]");
-MODULE_PARM(board3, "1-3s");
+module_param_array(board3, charp, NULL, 0);
 MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,memaddr]");
 
-#endif
-
 /*
  *     Set up a default memory address table for EISA board probing.
  *     The default addresses are all bellow 1Mbyte, which has to be the
@@ -405,8 +395,7 @@ static unsigned long        stli_eisamemprobeaddrs[] = {
        0xff000000, 0xff010000, 0xff020000, 0xff030000,
 };
 
-static int     stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long);
-int            stli_eisaprobe = STLI_EISAPROBE;
+static int     stli_eisamempsize = ARRAY_SIZE(stli_eisamemprobeaddrs);
 
 /*
  *     Define the Stallion PCI vendor and device IDs.
@@ -420,7 +409,7 @@ int         stli_eisaprobe = STLI_EISAPROBE;
 #endif
 
 static struct pci_device_id istallion_pci_tbl[] = {
-       { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA), },
        { 0 }
 };
 MODULE_DEVICE_TABLE(pci, istallion_pci_tbl);
@@ -650,17 +639,11 @@ static unsigned int       stli_baudrates[] = {
  *     Prototype all functions in this driver!
  */
 
-#ifdef MODULE
-static void    stli_argbrds(void);
 static int     stli_parsebrd(stlconf_t *confp, char **argp);
-
-static unsigned long   stli_atol(char *str);
-#endif
-
-int            stli_init(void);
+static int     stli_init(void);
 static int     stli_open(struct tty_struct *tty, struct file *filp);
 static void    stli_close(struct tty_struct *tty, struct file *filp);
-static int     stli_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count);
+static int     stli_write(struct tty_struct *tty, const unsigned char *buf, int count);
 static void    stli_putchar(struct tty_struct *tty, unsigned char ch);
 static void    stli_flushchars(struct tty_struct *tty);
 static int     stli_writeroom(struct tty_struct *tty);
@@ -680,10 +663,10 @@ static int        stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *p
 
 static int     stli_brdinit(stlibrd_t *brdp);
 static int     stli_startbrd(stlibrd_t *brdp);
-static ssize_t stli_memread(struct file *fp, char *buf, size_t count, loff_t *offp);
-static ssize_t stli_memwrite(struct file *fp, const char *buf, size_t count, loff_t *offp);
+static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp);
+static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp);
 static int     stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
-static void    stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp);
+static void    stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp);
 static void    stli_poll(unsigned long arg);
 static int     stli_hostcmd(stlibrd_t *brdp, stliport_t *portp);
 static int     stli_initopen(stlibrd_t *brdp, stliport_t *portp);
@@ -691,24 +674,23 @@ static int        stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i
 static int     stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait);
 static int     stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp);
 static void    stli_dohangup(void *arg);
-static void    stli_delay(int len);
 static int     stli_setport(stliport_t *portp);
 static int     stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);
 static void    stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);
-static void    stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp);
+static void    __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);
+static void    stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp);
 static void    stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp);
 static void    stli_mkasysigs(asysigs_t *sp, int dtr, int rts);
 static long    stli_mktiocm(unsigned long sigvalue);
 static void    stli_read(stlibrd_t *brdp, stliport_t *portp);
-static int     stli_getserial(stliport_t *portp, struct serial_struct *sp);
-static int     stli_setserial(stliport_t *portp, struct serial_struct *sp);
-static int     stli_getbrdstats(combrd_t *bp);
-static int     stli_getportstats(stliport_t *portp, comstats_t *cp);
+static int     stli_getserial(stliport_t *portp, struct serial_struct __user *sp);
+static int     stli_setserial(stliport_t *portp, struct serial_struct __user *sp);
+static int     stli_getbrdstats(combrd_t __user *bp);
+static int     stli_getportstats(stliport_t *portp, comstats_t __user *cp);
 static int     stli_portcmdstats(stliport_t *portp);
-static int     stli_clrportstats(stliport_t *portp, comstats_t *cp);
-static int     stli_getportstruct(unsigned long arg);
-static int     stli_getbrdstruct(unsigned long arg);
-static void    *stli_memalloc(int len);
+static int     stli_clrportstats(stliport_t *portp, comstats_t __user *cp);
+static int     stli_getportstruct(stliport_t __user *arg);
+static int     stli_getbrdstruct(stlibrd_t __user *arg);
 static stlibrd_t *stli_allocbrd(void);
 
 static void    stli_ecpinit(stlibrd_t *brdp);
@@ -749,17 +731,13 @@ static void       stli_stalreset(stlibrd_t *brdp);
 
 static stliport_t *stli_getport(int brdnr, int panelnr, int portnr);
 
-static inline int      stli_initbrds(void);
-static inline int      stli_initecp(stlibrd_t *brdp);
-static inline int      stli_initonb(stlibrd_t *brdp);
-static inline int      stli_findeisabrds(void);
-static inline int      stli_eisamemprobe(stlibrd_t *brdp);
-static inline int      stli_initports(stlibrd_t *brdp);
-static inline int      stli_getbrdnr(void);
+static int     stli_initecp(stlibrd_t *brdp);
+static int     stli_initonb(stlibrd_t *brdp);
+static int     stli_eisamemprobe(stlibrd_t *brdp);
+static int     stli_initports(stlibrd_t *brdp);
 
 #ifdef CONFIG_PCI
-static inline int      stli_findpcibrds(void);
-static inline int      stli_initpcibrd(int brdtype, struct pci_dev *devp);
+static int     stli_initpcibrd(int brdtype, struct pci_dev *devp);
 #endif
 
 /*****************************************************************************/
@@ -770,7 +748,7 @@ static inline int   stli_initpcibrd(int brdtype, struct pci_dev *devp);
  *     will give access to the shared memory on the Stallion intelligent
  *     board. This is also a very useful debugging tool.
  */
-static struct file_operations  stli_fsiomem = {
+static const struct file_operations    stli_fsiomem = {
        .owner          = THIS_MODULE,
        .read           = stli_memread,
        .write          = stli_memwrite,
@@ -785,7 +763,7 @@ static struct file_operations       stli_fsiomem = {
  *     much cheaper on host cpu than using interrupts. It turns out to
  *     not increase character latency by much either...
  */
-static struct timer_list stli_timerlist = TIMER_INITIALIZER(stli_poll, 0, 0);
+static DEFINE_TIMER(stli_timerlist, stli_poll, 0, 0);
 
 static int     stli_timeron;
 
@@ -796,9 +774,7 @@ static int  stli_timeron;
 
 /*****************************************************************************/
 
-static struct class_simple *istallion_class;
-
-#ifdef MODULE
+static struct class *istallion_class;
 
 /*
  *     Loadable module initialization stuff.
@@ -806,18 +782,8 @@ static struct class_simple *istallion_class;
 
 static int __init istallion_module_init(void)
 {
-       unsigned long   flags;
-
-#if DEBUG
-       printk("init_module()\n");
-#endif
-
-       save_flags(flags);
-       cli();
        stli_init();
-       restore_flags(flags);
-
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -826,57 +792,43 @@ static void __exit istallion_module_exit(void)
 {
        stlibrd_t       *brdp;
        stliport_t      *portp;
-       unsigned long   flags;
        int             i, j;
 
-#if DEBUG
-       printk("cleanup_module()\n");
-#endif
-
        printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle,
                stli_drvversion);
 
-       save_flags(flags);
-       cli();
-
-/*
- *     Free up all allocated resources used by the ports. This includes
- *     memory and interrupts.
- */
+       /*
+        *      Free up all allocated resources used by the ports. This includes
+        *      memory and interrupts.
+        */
        if (stli_timeron) {
                stli_timeron = 0;
-               del_timer(&stli_timerlist);
+               del_timer_sync(&stli_timerlist);
        }
 
        i = tty_unregister_driver(stli_serial);
        if (i) {
                printk("STALLION: failed to un-register tty driver, "
-                       "errno=%d,%d\n", -i);
-               restore_flags(flags);
+                       "errno=%d\n", -i);
                return;
        }
        put_tty_driver(stli_serial);
-       for (i = 0; i < 4; i++) {
-               devfs_remove("staliomem/%d", i);
-               class_simple_device_remove(MKDEV(STL_SIOMEMMAJOR, i));
-       }
-       devfs_remove("staliomem");
-       class_simple_destroy(istallion_class);
+       for (i = 0; i < 4; i++)
+               class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, i));
+       class_destroy(istallion_class);
        if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
                printk("STALLION: failed to un-register serial memory device, "
                        "errno=%d\n", -i);
-       if (stli_tmpwritebuf != (char *) NULL)
-               kfree(stli_tmpwritebuf);
-       if (stli_txcookbuf != (char *) NULL)
-               kfree(stli_txcookbuf);
+
+       kfree(stli_txcookbuf);
 
        for (i = 0; (i < stli_nrbrds); i++) {
-               if ((brdp = stli_brds[i]) == (stlibrd_t *) NULL)
+               if ((brdp = stli_brds[i]) == NULL)
                        continue;
                for (j = 0; (j < STL_MAXPORTS); j++) {
                        portp = brdp->ports[j];
-                       if (portp != (stliport_t *) NULL) {
-                               if (portp->tty != (struct tty_struct *) NULL)
+                       if (portp != NULL) {
+                               if (portp->tty != NULL)
                                        tty_hangup(portp->tty);
                                kfree(portp);
                        }
@@ -886,10 +838,8 @@ static void __exit istallion_module_exit(void)
                if (brdp->iosize > 0)
                        release_region(brdp->iobase, brdp->iosize);
                kfree(brdp);
-               stli_brds[i] = (stlibrd_t *) NULL;
+               stli_brds[i] = NULL;
        }
-
-       restore_flags(flags);
 }
 
 module_init(istallion_module_init);
@@ -901,23 +851,17 @@ module_exit(istallion_module_exit);
  *     Check for any arguments passed in on the module load command line.
  */
 
-static void stli_argbrds()
+static void stli_argbrds(void)
 {
-       stlconf_t       conf;
-       stlibrd_t       *brdp;
-       int             nrargs, i;
-
-#if DEBUG
-       printk("stli_argbrds()\n");
-#endif
-
-       nrargs = sizeof(stli_brdsp) / sizeof(char **);
+       stlconf_t conf;
+       stlibrd_t *brdp;
+       int i;
 
-       for (i = stli_nrbrds; (i < nrargs); i++) {
+       for (i = stli_nrbrds; i < ARRAY_SIZE(stli_brdsp); i++) {
                memset(&conf, 0, sizeof(conf));
                if (stli_parsebrd(&conf, stli_brdsp[i]) == 0)
                        continue;
-               if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)
+               if ((brdp = stli_allocbrd()) == NULL)
                        continue;
                stli_nrbrds = i + 1;
                brdp->brdnr = i;
@@ -936,9 +880,9 @@ static void stli_argbrds()
 
 static unsigned long stli_atol(char *str)
 {
-       unsigned long   val;
-       int             base, c;
-       char            *sp;
+       unsigned long val;
+       int base, c;
+       char *sp;
 
        val = 0;
        sp = str;
@@ -972,82 +916,59 @@ static unsigned long stli_atol(char *str)
 
 static int stli_parsebrd(stlconf_t *confp, char **argp)
 {
-       char    *sp;
-       int     nrbrdnames, i;
-
-#if DEBUG
-       printk("stli_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp);
-#endif
+       char *sp;
+       int i;
 
-       if ((argp[0] == (char *) NULL) || (*argp[0] == 0))
-               return(0);
+       if (argp[0] == NULL || *argp[0] == 0)
+               return 0;
 
        for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)
                *sp = TOLOWER(*sp);
 
-       nrbrdnames = sizeof(stli_brdstr) / sizeof(stlibrdtype_t);
-       for (i = 0; (i < nrbrdnames); i++) {
+       for (i = 0; i < ARRAY_SIZE(stli_brdstr); i++) {
                if (strcmp(stli_brdstr[i].name, argp[0]) == 0)
                        break;
        }
-       if (i >= nrbrdnames) {
+       if (i == ARRAY_SIZE(stli_brdstr)) {
                printk("STALLION: unknown board name, %s?\n", argp[0]);
-               return(0);
+               return 0;
        }
 
        confp->brdtype = stli_brdstr[i].type;
-       if ((argp[1] != (char *) NULL) && (*argp[1] != 0))
+       if (argp[1] != NULL && *argp[1] != 0)
                confp->ioaddr1 = stli_atol(argp[1]);
-       if ((argp[2] != (char *) NULL) && (*argp[2] != 0))
+       if (argp[2] !=  NULL && *argp[2] != 0)
                confp->memaddr = stli_atol(argp[2]);
        return(1);
 }
 
-#endif
-
-/*****************************************************************************/
-
-/*
- *     Local driver kernel malloc routine.
- */
-
-static void *stli_memalloc(int len)
-{
-       return((void *) kmalloc(len, GFP_KERNEL));
-}
-
 /*****************************************************************************/
 
 static int stli_open(struct tty_struct *tty, struct file *filp)
 {
-       stlibrd_t       *brdp;
-       stliport_t      *portp;
-       unsigned int    minordev;
-       int             brdnr, portnr, rc;
-
-#if DEBUG
-       printk("stli_open(tty=%x,filp=%x): device=%s\n", (int) tty,
-               (int) filp, tty->name);
-#endif
+       stlibrd_t *brdp;
+       stliport_t *portp;
+       unsigned int minordev;
+       int brdnr, portnr, rc;
 
        minordev = tty->index;
        brdnr = MINOR2BRD(minordev);
        if (brdnr >= stli_nrbrds)
-               return(-ENODEV);
+               return -ENODEV;
        brdp = stli_brds[brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(-ENODEV);
+       if (brdp == NULL)
+               return -ENODEV;
        if ((brdp->state & BST_STARTED) == 0)
-               return(-ENODEV);
+               return -ENODEV;
        portnr = MINOR2PORT(minordev);
        if ((portnr < 0) || (portnr > brdp->nrports))
-               return(-ENODEV);
+               return -ENODEV;
 
        portp = brdp->ports[portnr];
-       if (portp == (stliport_t *) NULL)
-               return(-ENODEV);
+       if (portp == NULL)
+               return -ENODEV;
        if (portp->devnr < 1)
-               return(-ENODEV);
+               return -ENODEV;
 
 
 /*
@@ -1059,8 +980,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
        if (portp->flags & ASYNC_CLOSING) {
                interruptible_sleep_on(&portp->close_wait);
                if (portp->flags & ASYNC_HUP_NOTIFY)
-                       return(-EAGAIN);
-               return(-ERESTARTSYS);
+                       return -EAGAIN;
+               return -ERESTARTSYS;
        }
 
 /*
@@ -1073,11 +994,10 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
        tty->driver_data = portp;
        portp->refcount++;
 
-       while (test_bit(ST_INITIALIZING, &portp->state)) {
-               if (signal_pending(current))
-                       return(-ERESTARTSYS);
-               interruptible_sleep_on(&portp->raw_wait);
-       }
+       wait_event_interruptible(portp->raw_wait,
+                       !test_bit(ST_INITIALIZING, &portp->state));
+       if (signal_pending(current))
+               return -ERESTARTSYS;
 
        if ((portp->flags & ASYNC_INITIALIZED) == 0) {
                set_bit(ST_INITIALIZING, &portp->state);
@@ -1088,7 +1008,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
                clear_bit(ST_INITIALIZING, &portp->state);
                wake_up_interruptible(&portp->raw_wait);
                if (rc < 0)
-                       return(rc);
+                       return rc;
        }
 
 /*
@@ -1100,8 +1020,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
        if (portp->flags & ASYNC_CLOSING) {
                interruptible_sleep_on(&portp->close_wait);
                if (portp->flags & ASYNC_HUP_NOTIFY)
-                       return(-EAGAIN);
-               return(-ERESTARTSYS);
+                       return -EAGAIN;
+               return -ERESTARTSYS;
        }
 
 /*
@@ -1111,38 +1031,33 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
  */
        if (!(filp->f_flags & O_NONBLOCK)) {
                if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0)
-                       return(rc);
+                       return rc;
        }
        portp->flags |= ASYNC_NORMAL_ACTIVE;
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
 
 static void stli_close(struct tty_struct *tty, struct file *filp)
 {
-       stlibrd_t       *brdp;
-       stliport_t      *portp;
-       unsigned long   flags;
-
-#if DEBUG
-       printk("stli_close(tty=%x,filp=%x)\n", (int) tty, (int) filp);
-#endif
+       stlibrd_t *brdp;
+       stliport_t *portp;
+       unsigned long flags;
 
        portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
+       if (portp == NULL)
                return;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&stli_lock, flags);
        if (tty_hung_up_p(filp)) {
-               restore_flags(flags);
+               spin_unlock_irqrestore(&stli_lock, flags);
                return;
        }
        if ((tty->count == 1) && (portp->refcount != 1))
                portp->refcount = 1;
        if (portp->refcount-- > 1) {
-               restore_flags(flags);
+               spin_unlock_irqrestore(&stli_lock, flags);
                return;
        }
 
@@ -1157,6 +1072,8 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
        if (tty == stli_txcooktty)
                stli_flushchars(tty);
        tty->closing = 1;
+       spin_unlock_irqrestore(&stli_lock, flags);
+
        if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
                tty_wait_until_sent(tty, portp->closing_wait);
 
@@ -1180,17 +1097,16 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
        stli_flushbuffer(tty);
 
        tty->closing = 0;
-       portp->tty = (struct tty_struct *) NULL;
+       portp->tty = NULL;
 
        if (portp->openwaitcnt) {
                if (portp->close_delay)
-                       stli_delay(portp->close_delay);
+                       msleep_interruptible(jiffies_to_msecs(portp->close_delay));
                wake_up_interruptible(&portp->open_wait);
        }
 
        portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
        wake_up_interruptible(&portp->close_wait);
-       restore_flags(flags);
 }
 
 /*****************************************************************************/
@@ -1205,45 +1121,41 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
 
 static int stli_initopen(stlibrd_t *brdp, stliport_t *portp)
 {
-       struct tty_struct       *tty;
-       asynotify_t             nt;
-       asyport_t               aport;
-       int                     rc;
-
-#if DEBUG
-       printk("stli_initopen(brdp=%x,portp=%x)\n", (int) brdp, (int) portp);
-#endif
+       struct tty_struct *tty;
+       asynotify_t nt;
+       asyport_t aport;
+       int rc;
 
        if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0)
-               return(rc);
+               return rc;
 
        memset(&nt, 0, sizeof(asynotify_t));
        nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK);
        nt.signal = SG_DCD;
        if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt,
            sizeof(asynotify_t), 0)) < 0)
-               return(rc);
+               return rc;
 
        tty = portp->tty;
-       if (tty == (struct tty_struct *) NULL)
-               return(-ENODEV);
+       if (tty == NULL)
+               return -ENODEV;
        stli_mkasyport(portp, &aport, tty->termios);
        if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport,
            sizeof(asyport_t), 0)) < 0)
-               return(rc);
+               return rc;
 
        set_bit(ST_GETSIGS, &portp->state);
        if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig,
            sizeof(asysigs_t), 1)) < 0)
-               return(rc);
+               return rc;
        if (test_and_clear_bit(ST_GETSIGS, &portp->state))
                portp->sigs = stli_mktiocm(portp->asig.sigvalue);
        stli_mkasysigs(&portp->asig, 1, 1);
        if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
            sizeof(asysigs_t), 0)) < 0)
-               return(rc);
+               return rc;
 
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -1257,22 +1169,15 @@ static int stli_initopen(stlibrd_t *brdp, stliport_t *portp)
 
 static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)
 {
-       volatile cdkhdr_t       *hdrp;
-       volatile cdkctrl_t      *cp;
-       volatile unsigned char  *bits;
-       unsigned long           flags;
-       int                     rc;
-
-#if DEBUG
-       printk("stli_rawopen(brdp=%x,portp=%x,arg=%x,wait=%d)\n",
-               (int) brdp, (int) portp, (int) arg, wait);
-#endif
+       cdkhdr_t __iomem *hdrp;
+       cdkctrl_t __iomem *cp;
+       unsigned char __iomem *bits;
+       unsigned long flags;
+       int rc;
 
 /*
  *     Send a message to the slave to open this port.
  */
-       save_flags(flags);
-       cli();
 
 /*
  *     Slave is already closing this port. This can happen if a hangup
@@ -1280,12 +1185,10 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i
  *     order of opens and closes may not be preserved across shared
  *     memory, so we must wait until it is complete.
  */
-       while (test_bit(ST_CLOSING, &portp->state)) {
-               if (signal_pending(current)) {
-                       restore_flags(flags);
-                       return(-ERESTARTSYS);
-               }
-               interruptible_sleep_on(&portp->raw_wait);
+       wait_event_interruptible(portp->raw_wait,
+                       !test_bit(ST_CLOSING, &portp->state));
+       if (signal_pending(current)) {
+               return -ERESTARTSYS;
        }
 
 /*
@@ -1293,19 +1196,20 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i
  *     memory. Once the message is in set the service bits to say that
  *     this port wants service.
  */
+       spin_lock_irqsave(&brd_lock, flags);
        EBRDENABLE(brdp);
-       cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
-       cp->openarg = arg;
-       cp->open = 1;
-       hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
-       bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+       cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
+       writel(arg, &cp->openarg);
+       writeb(1, &cp->open);
+       hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+       bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
                portp->portidx;
-       *bits |= portp->portbit;
+       writeb(readb(bits) | portp->portbit, bits);
        EBRDDISABLE(brdp);
 
        if (wait == 0) {
-               restore_flags(flags);
-               return(0);
+               spin_unlock_irqrestore(&brd_lock, flags);
+               return 0;
        }
 
 /*
@@ -1314,18 +1218,16 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i
  */
        rc = 0;
        set_bit(ST_OPENING, &portp->state);
-       while (test_bit(ST_OPENING, &portp->state)) {
-               if (signal_pending(current)) {
-                       rc = -ERESTARTSYS;
-                       break;
-               }
-               interruptible_sleep_on(&portp->raw_wait);
-       }
-       restore_flags(flags);
+       spin_unlock_irqrestore(&brd_lock, flags);
+
+       wait_event_interruptible(portp->raw_wait,
+                       !test_bit(ST_OPENING, &portp->state));
+       if (signal_pending(current))
+               rc = -ERESTARTSYS;
 
        if ((rc == 0) && (portp->rc != 0))
                rc = -EIO;
-       return(rc);
+       return rc;
 }
 
 /*****************************************************************************/
@@ -1338,70 +1240,57 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i
 
 static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)
 {
-       volatile cdkhdr_t       *hdrp;
-       volatile cdkctrl_t      *cp;
-       volatile unsigned char  *bits;
-       unsigned long           flags;
-       int                     rc;
-
-#if DEBUG
-       printk("stli_rawclose(brdp=%x,portp=%x,arg=%x,wait=%d)\n",
-               (int) brdp, (int) portp, (int) arg, wait);
-#endif
-
-       save_flags(flags);
-       cli();
+       cdkhdr_t __iomem *hdrp;
+       cdkctrl_t __iomem *cp;
+       unsigned char __iomem *bits;
+       unsigned long flags;
+       int rc;
 
 /*
  *     Slave is already closing this port. This can happen if a hangup
  *     occurs on this port.
  */
        if (wait) {
-               while (test_bit(ST_CLOSING, &portp->state)) {
-                       if (signal_pending(current)) {
-                               restore_flags(flags);
-                               return(-ERESTARTSYS);
-                       }
-                       interruptible_sleep_on(&portp->raw_wait);
+               wait_event_interruptible(portp->raw_wait,
+                               !test_bit(ST_CLOSING, &portp->state));
+               if (signal_pending(current)) {
+                       return -ERESTARTSYS;
                }
        }
 
 /*
  *     Write the close command into shared memory.
  */
+       spin_lock_irqsave(&brd_lock, flags);
        EBRDENABLE(brdp);
-       cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
-       cp->closearg = arg;
-       cp->close = 1;
-       hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
-       bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+       cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
+       writel(arg, &cp->closearg);
+       writeb(1, &cp->close);
+       hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+       bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
                portp->portidx;
-       *bits |= portp->portbit;
+       writeb(readb(bits) |portp->portbit, bits);
        EBRDDISABLE(brdp);
 
        set_bit(ST_CLOSING, &portp->state);
-       if (wait == 0) {
-               restore_flags(flags);
-               return(0);
-       }
+       spin_unlock_irqrestore(&brd_lock, flags);
+
+       if (wait == 0)
+               return 0;
 
 /*
  *     Slave is in action, so now we must wait for the open acknowledgment
  *     to come back.
  */
        rc = 0;
-       while (test_bit(ST_CLOSING, &portp->state)) {
-               if (signal_pending(current)) {
-                       rc = -ERESTARTSYS;
-                       break;
-               }
-               interruptible_sleep_on(&portp->raw_wait);
-       }
-       restore_flags(flags);
+       wait_event_interruptible(portp->raw_wait,
+                       !test_bit(ST_CLOSING, &portp->state));
+       if (signal_pending(current))
+               rc = -ERESTARTSYS;
 
        if ((rc == 0) && (portp->rc != 0))
                rc = -EIO;
-       return(rc);
+       return rc;
 }
 
 /*****************************************************************************/
@@ -1415,38 +1304,21 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg,
 
 static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
 {
-       unsigned long   flags;
-
-#if DEBUG
-       printk("stli_cmdwait(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,"
-               "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd,
-               (int) arg, size, copyback);
-#endif
-
-       save_flags(flags);
-       cli();
-       while (test_bit(ST_CMDING, &portp->state)) {
-               if (signal_pending(current)) {
-                       restore_flags(flags);
-                       return(-ERESTARTSYS);
-               }
-               interruptible_sleep_on(&portp->raw_wait);
-       }
+       wait_event_interruptible(portp->raw_wait,
+                       !test_bit(ST_CMDING, &portp->state));
+       if (signal_pending(current))
+               return -ERESTARTSYS;
 
        stli_sendcmd(brdp, portp, cmd, arg, size, copyback);
 
-       while (test_bit(ST_CMDING, &portp->state)) {
-               if (signal_pending(current)) {
-                       restore_flags(flags);
-                       return(-ERESTARTSYS);
-               }
-               interruptible_sleep_on(&portp->raw_wait);
-       }
-       restore_flags(flags);
+       wait_event_interruptible(portp->raw_wait,
+                       !test_bit(ST_CMDING, &portp->state));
+       if (signal_pending(current))
+               return -ERESTARTSYS;
 
        if (portp->rc != 0)
-               return(-EIO);
-       return(0);
+               return -EIO;
+       return 0;
 }
 
 /*****************************************************************************/
@@ -1458,22 +1330,18 @@ static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, v
 
 static int stli_setport(stliport_t *portp)
 {
-       stlibrd_t       *brdp;
-       asyport_t       aport;
-
-#if DEBUG
-       printk("stli_setport(portp=%x)\n", (int) portp);
-#endif
-
-       if (portp == (stliport_t *) NULL)
-               return(-ENODEV);
-       if (portp->tty == (struct tty_struct *) NULL)
-               return(-ENODEV);
-       if ((portp->brdnr < 0) && (portp->brdnr >= stli_nrbrds))
-               return(-ENODEV);
+       stlibrd_t *brdp;
+       asyport_t aport;
+
+       if (portp == NULL)
+               return -ENODEV;
+       if (portp->tty == NULL)
+               return -ENODEV;
+       if (portp->brdnr < 0 && portp->brdnr >= stli_nrbrds)
+               return -ENODEV;
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(-ENODEV);
+       if (brdp == NULL)
+               return -ENODEV;
 
        stli_mkasyport(portp, &aport, portp->tty->termios);
        return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0));
@@ -1481,25 +1349,6 @@ static int stli_setport(stliport_t *portp)
 
 /*****************************************************************************/
 
-/*
- *     Wait for a specified delay period, this is not a busy-loop. It will
- *     give up the processor while waiting. Unfortunately this has some
- *     rather intimate knowledge of the process management stuff.
- */
-
-static void stli_delay(int len)
-{
-#if DEBUG
-       printk("stli_delay(len=%d)\n", len);
-#endif
-       if (len > 0) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(len);
-       }
-}
-
-/*****************************************************************************/
-
 /*
  *     Possibly need to wait for carrier (DCD signal) to come high. Say
  *     maybe because if we are clocal then we don't need to wait...
@@ -1507,13 +1356,8 @@ static void stli_delay(int len)
 
 static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp)
 {
-       unsigned long   flags;
-       int             rc, doclocal;
-
-#if DEBUG
-       printk("stli_waitcarrier(brdp=%x,portp=%x,filp=%x)\n",
-               (int) brdp, (int) portp, (int) filp);
-#endif
+       unsigned long flags;
+       int rc, doclocal;
 
        rc = 0;
        doclocal = 0;
@@ -1521,11 +1365,11 @@ static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *fil
        if (portp->tty->termios->c_cflag & CLOCAL)
                doclocal++;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&stli_lock, flags);
        portp->openwaitcnt++;
        if (! tty_hung_up_p(filp))
                portp->refcount--;
+       spin_unlock_irqrestore(&stli_lock, flags);
 
        for (;;) {
                stli_mkasysigs(&portp->asig, 1, 1);
@@ -1551,12 +1395,13 @@ static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *fil
                interruptible_sleep_on(&portp->open_wait);
        }
 
+       spin_lock_irqsave(&stli_lock, flags);
        if (! tty_hung_up_p(filp))
                portp->refcount++;
        portp->openwaitcnt--;
-       restore_flags(flags);
+       spin_unlock_irqrestore(&stli_lock, flags);
 
-       return(rc);
+       return rc;
 }
 
 /*****************************************************************************/
@@ -1567,80 +1412,40 @@ static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *fil
  *     service bits for this port.
  */
 
-static int stli_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
+static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
-       volatile cdkasy_t       *ap;
-       volatile cdkhdr_t       *hdrp;
-       volatile unsigned char  *bits;
-       unsigned char           *shbuf, *chbuf;
-       stliport_t              *portp;
-       stlibrd_t               *brdp;
-       unsigned int            len, stlen, head, tail, size;
-       unsigned long           flags;
-
-#if DEBUG
-       printk("stli_write(tty=%x,from_user=%d,buf=%x,count=%d)\n",
-               (int) tty, from_user, (int) buf, count);
-#endif
+       cdkasy_t __iomem *ap;
+       cdkhdr_t __iomem *hdrp;
+       unsigned char __iomem *bits;
+       unsigned char __iomem *shbuf;
+       unsigned char *chbuf;
+       stliport_t *portp;
+       stlibrd_t *brdp;
+       unsigned int len, stlen, head, tail, size;
+       unsigned long flags;
 
-       if ((tty == (struct tty_struct *) NULL) ||
-           (stli_tmpwritebuf == (char *) NULL))
-               return(0);
        if (tty == stli_txcooktty)
                stli_flushchars(tty);
        portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
-               return(0);
+       if (portp == NULL)
+               return 0;
        if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
-               return(0);
+               return 0;
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(0);
+       if (brdp == NULL)
+               return 0;
        chbuf = (unsigned char *) buf;
 
-/*
- *     If copying direct from user space we need to be able to handle page
- *     faults while we are copying. To do this copy as much as we can now
- *     into a kernel buffer. From there we copy it into shared memory. The
- *     big problem is that we do not want shared memory enabled when we are
- *     sleeping (other boards may be serviced while asleep). Something else
- *     to note here is the reading of the tail twice. Since the boards
- *     shared memory can be on an 8-bit bus then we need to be very careful
- *     reading 16 bit quantities - since both the board (slave) and host
- *     could be writing and reading at the same time.
- */
-       if (from_user) {
-               save_flags(flags);
-               cli();
-               EBRDENABLE(brdp);
-               ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
-               head = (unsigned int) ap->txq.head;
-               tail = (unsigned int) ap->txq.tail;
-               if (tail != ((unsigned int) ap->txq.tail))
-                       tail = (unsigned int) ap->txq.tail;
-               len = (head >= tail) ? (portp->txsize - (head - tail) - 1) :
-                       (tail - head - 1);
-               count = MIN(len, count);
-               EBRDDISABLE(brdp);
-               restore_flags(flags);
-
-               down(&stli_tmpwritesem);
-               if (copy_from_user(stli_tmpwritebuf, chbuf, count)) 
-                       return -EFAULT;
-               chbuf = &stli_tmpwritebuf[0];
-       }
-
 /*
  *     All data is now local, shove as much as possible into shared memory.
  */
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&brd_lock, flags);
        EBRDENABLE(brdp);
-       ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
-       head = (unsigned int) ap->txq.head;
-       tail = (unsigned int) ap->txq.tail;
-       if (tail != ((unsigned int) ap->txq.tail))
-               tail = (unsigned int) ap->txq.tail;
+       ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
+       head = (unsigned int) readw(&ap->txq.head);
+       tail = (unsigned int) readw(&ap->txq.tail);
+       if (tail != ((unsigned int) readw(&ap->txq.tail)))
+               tail = (unsigned int) readw(&ap->txq.tail);
        size = portp->txsize;
        if (head >= tail) {
                len = size - (head - tail) - 1;
@@ -1652,11 +1457,11 @@ static int stli_write(struct tty_struct *tty, int from_user, const unsigned char
 
        len = MIN(len, count);
        count = 0;
-       shbuf = (char *) EBRDGETMEMPTR(brdp, portp->txoffset);
+       shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->txoffset);
 
        while (len > 0) {
                stlen = MIN(len, stlen);
-               memcpy((shbuf + head), chbuf, stlen);
+               memcpy_toio(shbuf + head, chbuf, stlen);
                chbuf += stlen;
                len -= stlen;
                count += stlen;
@@ -1667,22 +1472,19 @@ static int stli_write(struct tty_struct *tty, int from_user, const unsigned char
                }
        }
 
-       ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
-       ap->txq.head = head;
+       ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
+       writew(head, &ap->txq.head);
        if (test_bit(ST_TXBUSY, &portp->state)) {
-               if (ap->changed.data & DT_TXEMPTY)
-                       ap->changed.data &= ~DT_TXEMPTY;
+               if (readl(&ap->changed.data) & DT_TXEMPTY)
+                       writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data);
        }
-       hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
-       bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+       hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+       bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
                portp->portidx;
-       *bits |= portp->portbit;
+       writeb(readb(bits) | portp->portbit, bits);
        set_bit(ST_TXBUSY, &portp->state);
        EBRDDISABLE(brdp);
-
-       if (from_user)
-               up(&stli_tmpwritesem);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&brd_lock, flags);
 
        return(count);
 }
@@ -1699,14 +1501,8 @@ static int stli_write(struct tty_struct *tty, int from_user, const unsigned char
 
 static void stli_putchar(struct tty_struct *tty, unsigned char ch)
 {
-#if DEBUG
-       printk("stli_putchar(tty=%x,ch=%x)\n", (int) tty, (int) ch);
-#endif
-
-       if (tty == (struct tty_struct *) NULL)
-               return;
        if (tty != stli_txcooktty) {
-               if (stli_txcooktty != (struct tty_struct *) NULL)
+               if (stli_txcooktty != NULL)
                        stli_flushchars(stli_txcooktty);
                stli_txcooktty = tty;
        }
@@ -1726,29 +1522,26 @@ static void stli_putchar(struct tty_struct *tty, unsigned char ch)
 
 static void stli_flushchars(struct tty_struct *tty)
 {
-       volatile cdkhdr_t       *hdrp;
-       volatile unsigned char  *bits;
-       volatile cdkasy_t       *ap;
-       struct tty_struct       *cooktty;
-       stliport_t              *portp;
-       stlibrd_t               *brdp;
-       unsigned int            len, stlen, head, tail, size, count, cooksize;
-       unsigned char           *buf, *shbuf;
-       unsigned long           flags;
-
-#if DEBUG
-       printk("stli_flushchars(tty=%x)\n", (int) tty);
-#endif
+       cdkhdr_t __iomem *hdrp;
+       unsigned char __iomem *bits;
+       cdkasy_t __iomem *ap;
+       struct tty_struct *cooktty;
+       stliport_t *portp;
+       stlibrd_t *brdp;
+       unsigned int len, stlen, head, tail, size, count, cooksize;
+       unsigned char *buf;
+       unsigned char __iomem *shbuf;
+       unsigned long flags;
 
        cooksize = stli_txcooksize;
        cooktty = stli_txcooktty;
        stli_txcooksize = 0;
        stli_txcookrealsize = 0;
-       stli_txcooktty = (struct tty_struct *) NULL;
+       stli_txcooktty = NULL;
 
-       if (tty == (struct tty_struct *) NULL)
+       if (tty == NULL)
                return;
-       if (cooktty == (struct tty_struct *) NULL)
+       if (cooktty == NULL)
                return;
        if (tty != cooktty)
                tty = cooktty;
@@ -1756,23 +1549,22 @@ static void stli_flushchars(struct tty_struct *tty)
                return;
 
        portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
+       if (portp == NULL)
                return;
        if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
                return;
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
+       if (brdp == NULL)
                return;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&brd_lock, flags);
        EBRDENABLE(brdp);
 
-       ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
-       head = (unsigned int) ap->txq.head;
-       tail = (unsigned int) ap->txq.tail;
-       if (tail != ((unsigned int) ap->txq.tail))
-               tail = (unsigned int) ap->txq.tail;
+       ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
+       head = (unsigned int) readw(&ap->txq.head);
+       tail = (unsigned int) readw(&ap->txq.tail);
+       if (tail != ((unsigned int) readw(&ap->txq.tail)))
+               tail = (unsigned int) readw(&ap->txq.tail);
        size = portp->txsize;
        if (head >= tail) {
                len = size - (head - tail) - 1;
@@ -1789,7 +1581,7 @@ static void stli_flushchars(struct tty_struct *tty)
 
        while (len > 0) {
                stlen = MIN(len, stlen);
-               memcpy((shbuf + head), buf, stlen);
+               memcpy_toio(shbuf + head, buf, stlen);
                buf += stlen;
                len -= stlen;
                count += stlen;
@@ -1800,73 +1592,66 @@ static void stli_flushchars(struct tty_struct *tty)
                }
        }
 
-       ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
-       ap->txq.head = head;
+       ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
+       writew(head, &ap->txq.head);
 
        if (test_bit(ST_TXBUSY, &portp->state)) {
-               if (ap->changed.data & DT_TXEMPTY)
-                       ap->changed.data &= ~DT_TXEMPTY;
+               if (readl(&ap->changed.data) & DT_TXEMPTY)
+                       writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data);
        }
-       hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
-       bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+       hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+       bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
                portp->portidx;
-       *bits |= portp->portbit;
+       writeb(readb(bits) | portp->portbit, bits);
        set_bit(ST_TXBUSY, &portp->state);
 
        EBRDDISABLE(brdp);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&brd_lock, flags);
 }
 
 /*****************************************************************************/
 
 static int stli_writeroom(struct tty_struct *tty)
 {
-       volatile cdkasyrq_t     *rp;
-       stliport_t              *portp;
-       stlibrd_t               *brdp;
-       unsigned int            head, tail, len;
-       unsigned long           flags;
-
-#if DEBUG
-       printk("stli_writeroom(tty=%x)\n", (int) tty);
-#endif
+       cdkasyrq_t __iomem *rp;
+       stliport_t *portp;
+       stlibrd_t *brdp;
+       unsigned int head, tail, len;
+       unsigned long flags;
 
-       if (tty == (struct tty_struct *) NULL)
-               return(0);
        if (tty == stli_txcooktty) {
                if (stli_txcookrealsize != 0) {
                        len = stli_txcookrealsize - stli_txcooksize;
-                       return(len);
+                       return len;
                }
        }
 
        portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
-               return(0);
+       if (portp == NULL)
+               return 0;
        if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
-               return(0);
+               return 0;
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(0);
+       if (brdp == NULL)
+               return 0;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&brd_lock, flags);
        EBRDENABLE(brdp);
-       rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->txq;
-       head = (unsigned int) rp->head;
-       tail = (unsigned int) rp->tail;
-       if (tail != ((unsigned int) rp->tail))
-               tail = (unsigned int) rp->tail;
+       rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq;
+       head = (unsigned int) readw(&rp->head);
+       tail = (unsigned int) readw(&rp->tail);
+       if (tail != ((unsigned int) readw(&rp->tail)))
+               tail = (unsigned int) readw(&rp->tail);
        len = (head >= tail) ? (portp->txsize - (head - tail)) : (tail - head);
        len--;
        EBRDDISABLE(brdp);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&brd_lock, flags);
 
        if (tty == stli_txcooktty) {
                stli_txcookrealsize = len;
                len -= stli_txcooksize;
        }
-       return(len);
+       return len;
 }
 
 /*****************************************************************************/
@@ -1881,44 +1666,37 @@ static int stli_writeroom(struct tty_struct *tty)
 
 static int stli_charsinbuffer(struct tty_struct *tty)
 {
-       volatile cdkasyrq_t     *rp;
-       stliport_t              *portp;
-       stlibrd_t               *brdp;
-       unsigned int            head, tail, len;
-       unsigned long           flags;
-
-#if DEBUG
-       printk("stli_charsinbuffer(tty=%x)\n", (int) tty);
-#endif
+       cdkasyrq_t __iomem *rp;
+       stliport_t *portp;
+       stlibrd_t *brdp;
+       unsigned int head, tail, len;
+       unsigned long flags;
 
-       if (tty == (struct tty_struct *) NULL)
-               return(0);
        if (tty == stli_txcooktty)
                stli_flushchars(tty);
        portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
-               return(0);
+       if (portp == NULL)
+               return 0;
        if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
-               return(0);
+               return 0;
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(0);
+       if (brdp == NULL)
+               return 0;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&brd_lock, flags);
        EBRDENABLE(brdp);
-       rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->txq;
-       head = (unsigned int) rp->head;
-       tail = (unsigned int) rp->tail;
-       if (tail != ((unsigned int) rp->tail))
-               tail = (unsigned int) rp->tail;
+       rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq;
+       head = (unsigned int) readw(&rp->head);
+       tail = (unsigned int) readw(&rp->tail);
+       if (tail != ((unsigned int) readw(&rp->tail)))
+               tail = (unsigned int) readw(&rp->tail);
        len = (head >= tail) ? (head - tail) : (portp->txsize - (tail - head));
        if ((len == 0) && test_bit(ST_TXBUSY, &portp->state))
                len = 1;
        EBRDDISABLE(brdp);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&brd_lock, flags);
 
-       return(len);
+       return len;
 }
 
 /*****************************************************************************/
@@ -1927,14 +1705,10 @@ static int stli_charsinbuffer(struct tty_struct *tty)
  *     Generate the serial struct info.
  */
 
-static int stli_getserial(stliport_t *portp, struct serial_struct *sp)
+static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp)
 {
-       struct serial_struct    sio;
-       stlibrd_t               *brdp;
-
-#if DEBUG
-       printk("stli_getserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
-#endif
+       struct serial_struct sio;
+       stlibrd_t *brdp;
 
        memset(&sio, 0, sizeof(struct serial_struct));
        sio.type = PORT_UNKNOWN;
@@ -1949,7 +1723,7 @@ static int stli_getserial(stliport_t *portp, struct serial_struct *sp)
        sio.hub6 = 0;
 
        brdp = stli_brds[portp->brdnr];
-       if (brdp != (stlibrd_t *) NULL)
+       if (brdp != NULL)
                sio.port = brdp->iobase;
                
        return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ?
@@ -1964,14 +1738,10 @@ static int stli_getserial(stliport_t *portp, struct serial_struct *sp)
  *     just quietly ignore any requests to change irq, etc.
  */
 
-static int stli_setserial(stliport_t *portp, struct serial_struct *sp)
+static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp)
 {
-       struct serial_struct    sio;
-       int                     rc;
-
-#if DEBUG
-       printk("stli_setserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
-#endif
+       struct serial_struct sio;
+       int rc;
 
        if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
                return -EFAULT;
@@ -1980,7 +1750,7 @@ static int stli_setserial(stliport_t *portp, struct serial_struct *sp)
                    (sio.close_delay != portp->close_delay) ||
                    ((sio.flags & ~ASYNC_USR_MASK) !=
                    (portp->flags & ~ASYNC_USR_MASK)))
-                       return(-EPERM);
+                       return -EPERM;
        } 
 
        portp->flags = (portp->flags & ~ASYNC_USR_MASK) |
@@ -1991,8 +1761,8 @@ static int stli_setserial(stliport_t *portp, struct serial_struct *sp)
        portp->custom_divisor = sio.custom_divisor;
 
        if ((rc = stli_setport(portp)) < 0)
-               return(rc);
-       return(0);
+               return rc;
+       return 0;
 }
 
 /*****************************************************************************/
@@ -2003,19 +1773,19 @@ static int stli_tiocmget(struct tty_struct *tty, struct file *file)
        stlibrd_t *brdp;
        int rc;
 
-       if (portp == (stliport_t *) NULL)
-               return(-ENODEV);
-       if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
-               return(0);
+       if (portp == NULL)
+               return -ENODEV;
+       if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
+               return 0;
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(0);
+       if (brdp == NULL)
+               return 0;
        if (tty->flags & (1 << TTY_IO_ERROR))
-               return(-EIO);
+               return -EIO;
 
        if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS,
                               &portp->asig, sizeof(asysigs_t), 1)) < 0)
-               return(rc);
+               return rc;
 
        return stli_mktiocm(portp->asig.sigvalue);
 }
@@ -2027,15 +1797,15 @@ static int stli_tiocmset(struct tty_struct *tty, struct file *file,
        stlibrd_t *brdp;
        int rts = -1, dtr = -1;
 
-       if (portp == (stliport_t *) NULL)
-               return(-ENODEV);
-       if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
-               return(0);
+       if (portp == NULL)
+               return -ENODEV;
+       if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
+               return 0;
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(0);
+       if (brdp == NULL)
+               return 0;
        if (tty->flags & (1 << TTY_IO_ERROR))
-               return(-EIO);
+               return -EIO;
 
        if (set & TIOCM_RTS)
                rts = 1;
@@ -2054,31 +1824,25 @@ static int stli_tiocmset(struct tty_struct *tty, struct file *file,
 
 static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
 {
-       stliport_t      *portp;
-       stlibrd_t       *brdp;
-       unsigned int    ival;
-       int             rc;
-
-#if DEBUG
-       printk("stli_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n",
-               (int) tty, (int) file, cmd, (int) arg);
-#endif
+       stliport_t *portp;
+       stlibrd_t *brdp;
+       unsigned int ival;
+       int rc;
+       void __user *argp = (void __user *)arg;
 
-       if (tty == (struct tty_struct *) NULL)
-               return(-ENODEV);
        portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
-               return(-ENODEV);
-       if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
-               return(0);
+       if (portp == NULL)
+               return -ENODEV;
+       if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
+               return 0;
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(0);
+       if (brdp == NULL)
+               return 0;
 
        if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
            (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) {
                if (tty->flags & (1 << TTY_IO_ERROR))
-                       return(-EIO);
+                       return -EIO;
        }
 
        rc = 0;
@@ -2086,40 +1850,32 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
        switch (cmd) {
        case TIOCGSOFTCAR:
                rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
-                       (unsigned int *) arg);
+                       (unsigned __user *) arg);
                break;
        case TIOCSSOFTCAR:
-               if ((rc = get_user(ival, (unsigned int *) arg)) == 0)
+               if ((rc = get_user(ival, (unsigned __user *) arg)) == 0)
                        tty->termios->c_cflag =
                                (tty->termios->c_cflag & ~CLOCAL) |
                                (ival ? CLOCAL : 0);
                break;
        case TIOCGSERIAL:
-               if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
-                   sizeof(struct serial_struct))) == 0)
-                       rc = stli_getserial(portp, (struct serial_struct *) arg);
+               rc = stli_getserial(portp, argp);
                break;
        case TIOCSSERIAL:
-               if ((rc = verify_area(VERIFY_READ, (void *) arg,
-                   sizeof(struct serial_struct))) == 0)
-                       rc = stli_setserial(portp, (struct serial_struct *)arg);
+               rc = stli_setserial(portp, argp);
                break;
        case STL_GETPFLAG:
-               rc = put_user(portp->pflag, (unsigned int *) arg);
+               rc = put_user(portp->pflag, (unsigned __user *)argp);
                break;
        case STL_SETPFLAG:
-               if ((rc = get_user(portp->pflag, (unsigned int *) arg)) == 0)
+               if ((rc = get_user(portp->pflag, (unsigned __user *)argp)) == 0)
                        stli_setport(portp);
                break;
        case COM_GETPORTSTATS:
-               if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
-                   sizeof(comstats_t))) == 0)
-                       rc = stli_getportstats(portp, (comstats_t *) arg);
+               rc = stli_getportstats(portp, argp);
                break;
        case COM_CLRPORTSTATS:
-               if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
-                   sizeof(comstats_t))) == 0)
-                       rc = stli_clrportstats(portp, (comstats_t *) arg);
+               rc = stli_clrportstats(portp, argp);
                break;
        case TIOCSERCONFIG:
        case TIOCSERGWILD:
@@ -2133,7 +1889,7 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
                break;
        }
 
-       return(rc);
+       return rc;
 }
 
 /*****************************************************************************/
@@ -2145,24 +1901,20 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
 
 static void stli_settermios(struct tty_struct *tty, struct termios *old)
 {
-       stliport_t      *portp;
-       stlibrd_t       *brdp;
-       struct termios  *tiosp;
-       asyport_t       aport;
-
-#if DEBUG
-       printk("stli_settermios(tty=%x,old=%x)\n", (int) tty, (int) old);
-#endif
+       stliport_t *portp;
+       stlibrd_t *brdp;
+       struct termios *tiosp;
+       asyport_t aport;
 
-       if (tty == (struct tty_struct *) NULL)
+       if (tty == NULL)
                return;
        portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
+       if (portp == NULL)
                return;
-       if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
+       if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
                return;
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
+       if (brdp == NULL)
                return;
 
        tiosp = tty->termios;
@@ -2195,18 +1947,9 @@ static void stli_settermios(struct tty_struct *tty, struct termios *old)
 
 static void stli_throttle(struct tty_struct *tty)
 {
-       stliport_t      *portp;
-
-#if DEBUG
-       printk("stli_throttle(tty=%x)\n", (int) tty);
-#endif
-
-       if (tty == (struct tty_struct *) NULL)
-               return;
-       portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
+       stliport_t      *portp = tty->driver_data;
+       if (portp == NULL)
                return;
-
        set_bit(ST_RXSTOP, &portp->state);
 }
 
@@ -2220,88 +1963,30 @@ static void stli_throttle(struct tty_struct *tty)
 
 static void stli_unthrottle(struct tty_struct *tty)
 {
-       stliport_t      *portp;
-
-#if DEBUG
-       printk("stli_unthrottle(tty=%x)\n", (int) tty);
-#endif
-
-       if (tty == (struct tty_struct *) NULL)
-               return;
-       portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
+       stliport_t      *portp = tty->driver_data;
+       if (portp == NULL)
                return;
-
        clear_bit(ST_RXSTOP, &portp->state);
 }
 
 /*****************************************************************************/
 
 /*
- *     Stop the transmitter. Basically to do this we will just turn TX
- *     interrupts off.
+ *     Stop the transmitter.
  */
 
 static void stli_stop(struct tty_struct *tty)
 {
-       stlibrd_t       *brdp;
-       stliport_t      *portp;
-       asyctrl_t       actrl;
-
-#if DEBUG
-       printk("stli_stop(tty=%x)\n", (int) tty);
-#endif
-
-       if (tty == (struct tty_struct *) NULL)
-               return;
-       portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
-               return;
-       if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
-               return;
-       brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return;
-
-       memset(&actrl, 0, sizeof(asyctrl_t));
-       actrl.txctrl = CT_STOPFLOW;
-#if 0
-       stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
-#endif
 }
 
 /*****************************************************************************/
 
 /*
- *     Start the transmitter again. Just turn TX interrupts back on.
+ *     Start the transmitter again.
  */
 
 static void stli_start(struct tty_struct *tty)
 {
-       stliport_t      *portp;
-       stlibrd_t       *brdp;
-       asyctrl_t       actrl;
-
-#if DEBUG
-       printk("stli_start(tty=%x)\n", (int) tty);
-#endif
-
-       if (tty == (struct tty_struct *) NULL)
-               return;
-       portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
-               return;
-       if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
-               return;
-       brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return;
-
-       memset(&actrl, 0, sizeof(asyctrl_t));
-       actrl.txctrl = CT_STARTFLOW;
-#if 0
-       stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
-#endif
 }
 
 /*****************************************************************************/
@@ -2317,22 +2002,9 @@ static void stli_start(struct tty_struct *tty)
 
 static void stli_dohangup(void *arg)
 {
-       stliport_t      *portp;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_dohangup(portp=%x)\n", (int) arg);
-#endif
-
-       /*
-        * FIXME: There's a module removal race here: tty_hangup
-        * calls schedule_work which will call into this
-        * driver later.
-        */
-       portp = (stliport_t *) arg;
-       if (portp != (stliport_t *) NULL) {
-               if (portp->tty != (struct tty_struct *) NULL) {
-                       tty_hangup(portp->tty);
-               }
+       stliport_t *portp = (stliport_t *) arg;
+       if (portp->tty != NULL) {
+               tty_hangup(portp->tty);
        }
 }
 
@@ -2347,31 +2019,25 @@ static void stli_dohangup(void *arg)
 
 static void stli_hangup(struct tty_struct *tty)
 {
-       stliport_t      *portp;
-       stlibrd_t       *brdp;
-       unsigned long   flags;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_hangup(tty=%x)\n", (int) tty);
-#endif
+       stliport_t *portp;
+       stlibrd_t *brdp;
+       unsigned long flags;
 
-       if (tty == (struct tty_struct *) NULL)
-               return;
        portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
+       if (portp == NULL)
                return;
-       if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
+       if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
                return;
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
+       if (brdp == NULL)
                return;
 
        portp->flags &= ~ASYNC_INITIALIZED;
 
-       save_flags(flags);
-       cli();
-       if (! test_bit(ST_CLOSING, &portp->state))
+       if (!test_bit(ST_CLOSING, &portp->state))
                stli_rawclose(brdp, portp, 0, 0);
+
+       spin_lock_irqsave(&stli_lock, flags);
        if (tty->termios->c_cflag & HUPCL) {
                stli_mkasysigs(&portp->asig, 0, 0);
                if (test_bit(ST_CMDING, &portp->state)) {
@@ -2383,14 +2049,15 @@ static void stli_hangup(struct tty_struct *tty)
                                &portp->asig, sizeof(asysigs_t), 0);
                }
        }
-       restore_flags(flags);
 
        clear_bit(ST_TXBUSY, &portp->state);
        clear_bit(ST_RXSTOP, &portp->state);
        set_bit(TTY_IO_ERROR, &tty->flags);
-       portp->tty = (struct tty_struct *) NULL;
+       portp->tty = NULL;
        portp->flags &= ~ASYNC_NORMAL_ACTIVE;
        portp->refcount = 0;
+       spin_unlock_irqrestore(&stli_lock, flags);
+
        wake_up_interruptible(&portp->open_wait);
 }
 
@@ -2405,29 +2072,22 @@ static void stli_hangup(struct tty_struct *tty)
 
 static void stli_flushbuffer(struct tty_struct *tty)
 {
-       stliport_t      *portp;
-       stlibrd_t       *brdp;
-       unsigned long   ftype, flags;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_flushbuffer(tty=%x)\n", (int) tty);
-#endif
+       stliport_t *portp;
+       stlibrd_t *brdp;
+       unsigned long ftype, flags;
 
-       if (tty == (struct tty_struct *) NULL)
-               return;
        portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
+       if (portp == NULL)
                return;
-       if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
+       if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
                return;
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
+       if (brdp == NULL)
                return;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&brd_lock, flags);
        if (tty == stli_txcooktty) {
-               stli_txcooktty = (struct tty_struct *) NULL;
+               stli_txcooktty = NULL;
                stli_txcooksize = 0;
                stli_txcookrealsize = 0;
        }
@@ -2439,15 +2099,10 @@ static void stli_flushbuffer(struct tty_struct *tty)
                        ftype |= FLUSHRX;
                        clear_bit(ST_DOFLUSHRX, &portp->state);
                }
-               stli_sendcmd(brdp, portp, A_FLUSH, &ftype,
-                       sizeof(unsigned long), 0);
+               __stli_sendcmd(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0);
        }
-       restore_flags(flags);
-
-       wake_up_interruptible(&tty->write_wait);
-       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-           tty->ldisc.write_wakeup)
-               (tty->ldisc.write_wakeup)(tty);
+       spin_unlock_irqrestore(&brd_lock, flags);
+       tty_wakeup(tty);
 }
 
 /*****************************************************************************/
@@ -2457,55 +2112,31 @@ static void stli_breakctl(struct tty_struct *tty, int state)
        stlibrd_t       *brdp;
        stliport_t      *portp;
        long            arg;
-       /* long savestate, savetime; */
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_breakctl(tty=%x,state=%d)\n", (int) tty, state);
-#endif
 
-       if (tty == (struct tty_struct *) NULL)
-               return;
        portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
+       if (portp == NULL)
                return;
-       if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
+       if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
                return;
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
+       if (brdp == NULL)
                return;
 
-/*
- *     Due to a bug in the tty send_break() code we need to preserve
- *     the current process state and timeout...
-       savetime = current->timeout;
-       savestate = current->state;
- */
-
        arg = (state == -1) ? BREAKON : BREAKOFF;
        stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0);
-
-/*
- *
-       current->timeout = savetime;
-       current->state = savestate;
- */
 }
 
 /*****************************************************************************/
 
 static void stli_waituntilsent(struct tty_struct *tty, int timeout)
 {
-       stliport_t      *portp;
-       unsigned long   tend;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_waituntilsent(tty=%x,timeout=%x)\n", (int) tty, timeout);
-#endif
+       stliport_t *portp;
+       unsigned long tend;
 
-       if (tty == (struct tty_struct *) NULL)
+       if (tty == NULL)
                return;
        portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
+       if (portp == NULL)
                return;
 
        if (timeout == 0)
@@ -2515,7 +2146,7 @@ static void stli_waituntilsent(struct tty_struct *tty, int timeout)
        while (test_bit(ST_TXBUSY, &portp->state)) {
                if (signal_pending(current))
                        break;
-               stli_delay(2);
+               msleep_interruptible(20);
                if (time_after_eq(jiffies, tend))
                        break;
        }
@@ -2529,19 +2160,13 @@ static void stli_sendxchar(struct tty_struct *tty, char ch)
        stliport_t      *portp;
        asyctrl_t       actrl;
 
-#if DEBUG
-       printk(KERN_DEBUG "stli_sendxchar(tty=%x,ch=%x)\n", (int) tty, ch);
-#endif
-
-       if (tty == (struct tty_struct *) NULL)
-               return;
        portp = tty->driver_data;
-       if (portp == (stliport_t *) NULL)
+       if (portp == NULL)
                return;
-       if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
+       if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
                return;
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
+       if (brdp == NULL)
                return;
 
        memset(&actrl, 0, sizeof(asyctrl_t));
@@ -2553,7 +2178,6 @@ static void stli_sendxchar(struct tty_struct *tty, char ch)
                actrl.txctrl = CT_SENDCHR;
                actrl.tximdch = ch;
        }
-
        stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
 }
 
@@ -2569,17 +2193,17 @@ static void stli_sendxchar(struct tty_struct *tty, char ch)
 
 static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos)
 {
-       char    *sp, *uart;
-       int     rc, cnt;
+       char *sp, *uart;
+       int rc, cnt;
 
        rc = stli_portcmdstats(portp);
 
        uart = "UNKNOWN";
        if (brdp->state & BST_STARTED) {
                switch (stli_comstats.hwid) {
-               case 0:         uart = "2681"; break;
-               case 1:         uart = "SC26198"; break;
-               default:        uart = "CD1400"; break;
+               case 0: uart = "2681"; break;
+               case 1: uart = "SC26198"; break;
+               default:uart = "CD1400"; break;
                }
        }
 
@@ -2630,17 +2254,11 @@ static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *p
 
 static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-       stlibrd_t       *brdp;
-       stliport_t      *portp;
-       int             brdnr, portnr, totalport;
-       int             curoff, maxoff;
-       char            *pos;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_readproc(page=%x,start=%x,off=%x,count=%d,eof=%x,"
-               "data=%x\n", (int) page, (int) start, (int) off, count,
-               (int) eof, (int) data);
-#endif
+       stlibrd_t *brdp;
+       stliport_t *portp;
+       int brdnr, portnr, totalport;
+       int curoff, maxoff;
+       char *pos;
 
        pos = page;
        totalport = 0;
@@ -2661,7 +2279,7 @@ static int stli_readproc(char *page, char **start, off_t off, int count, int *eo
  */
        for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) {
                brdp = stli_brds[brdnr];
-               if (brdp == (stlibrd_t *) NULL)
+               if (brdp == NULL)
                        continue;
                if (brdp->state == 0)
                        continue;
@@ -2676,7 +2294,7 @@ static int stli_readproc(char *page, char **start, off_t off, int count, int *eo
                for (portnr = 0; (portnr < brdp->nrports); portnr++,
                    totalport++) {
                        portp = brdp->ports[portnr];
-                       if (portp == (stliport_t *) NULL)
+                       if (portp == NULL)
                                continue;
                        if (off >= (curoff += MAXLINE))
                                continue;
@@ -2703,49 +2321,54 @@ stli_readdone:
  *     a poll routine that does not have user context. Therefore you cannot
  *     copy back directly into user space, or to the kernel stack of a
  *     process. This routine does not sleep, so can be called from anywhere.
+ *
+ *     The caller must hold the brd_lock (see also stli_sendcmd the usual
+ *     entry point)
  */
 
-static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
+static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
 {
-       volatile cdkhdr_t       *hdrp;
-       volatile cdkctrl_t      *cp;
-       volatile unsigned char  *bits;
-       unsigned long           flags;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_sendcmd(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,"
-               "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd,
-               (int) arg, size, copyback);
-#endif
+       cdkhdr_t __iomem *hdrp;
+       cdkctrl_t __iomem *cp;
+       unsigned char __iomem *bits;
+       unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&brd_lock, flags);
 
        if (test_bit(ST_CMDING, &portp->state)) {
                printk(KERN_ERR "STALLION: command already busy, cmd=%x!\n",
                                (int) cmd);
-               restore_flags(flags);
+               spin_unlock_irqrestore(&brd_lock, flags);
                return;
        }
 
        EBRDENABLE(brdp);
-       cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
+       cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
        if (size > 0) {
-               memcpy((void *) &(cp->args[0]), arg, size);
+               memcpy_toio((void __iomem *) &(cp->args[0]), arg, size);
                if (copyback) {
                        portp->argp = arg;
                        portp->argsize = size;
                }
        }
-       cp->status = 0;
-       cp->cmd = cmd;
-       hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
-       bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+       writel(0, &cp->status);
+       writel(cmd, &cp->cmd);
+       hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+       bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
                portp->portidx;
-       *bits |= portp->portbit;
+       writeb(readb(bits) | portp->portbit, bits);
        set_bit(ST_CMDING, &portp->state);
        EBRDDISABLE(brdp);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&brd_lock, flags);
+}
+
+static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
+{
+       unsigned long           flags;
+
+       spin_lock_irqsave(&brd_lock, flags);
+       __stli_sendcmd(brdp, portp, cmd, arg, size, copyback);
+       spin_unlock_irqrestore(&brd_lock, flags);
 }
 
 /*****************************************************************************/
@@ -2758,30 +2381,25 @@ static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd,
  *     more chars to unload.
  */
 
-static inline void stli_read(stlibrd_t *brdp, stliport_t *portp)
+static void stli_read(stlibrd_t *brdp, stliport_t *portp)
 {
-       volatile cdkasyrq_t     *rp;
-       volatile char           *shbuf;
+       cdkasyrq_t __iomem *rp;
+       char __iomem *shbuf;
        struct tty_struct       *tty;
-       unsigned int            head, tail, size;
-       unsigned int            len, stlen;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_read(brdp=%x,portp=%d)\n",
-                       (int) brdp, (int) portp);
-#endif
+       unsigned int head, tail, size;
+       unsigned int len, stlen;
 
        if (test_bit(ST_RXSTOP, &portp->state))
                return;
        tty = portp->tty;
-       if (tty == (struct tty_struct *) NULL)
+       if (tty == NULL)
                return;
 
-       rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;
-       head = (unsigned int) rp->head;
-       if (head != ((unsigned int) rp->head))
-               head = (unsigned int) rp->head;
-       tail = (unsigned int) rp->tail;
+       rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;
+       head = (unsigned int) readw(&rp->head);
+       if (head != ((unsigned int) readw(&rp->head)))
+               head = (unsigned int) readw(&rp->head);
+       tail = (unsigned int) readw(&rp->tail);
        size = portp->rxsize;
        if (head >= tail) {
                len = head - tail;
@@ -2791,17 +2409,16 @@ static inline void stli_read(stlibrd_t *brdp, stliport_t *portp)
                stlen = size - tail;
        }
 
-       len = MIN(len, (TTY_FLIPBUF_SIZE - tty->flip.count));
-       shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset);
+       len = tty_buffer_request_room(tty, len);
+
+       shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->rxoffset);
 
        while (len > 0) {
-               stlen = MIN(len, stlen);
-               memcpy(tty->flip.char_buf_ptr, (char *) (shbuf + tail), stlen);
-               memset(tty->flip.flag_buf_ptr, 0, stlen);
-               tty->flip.char_buf_ptr += stlen;
-               tty->flip.flag_buf_ptr += stlen;
-               tty->flip.count += stlen;
+               unsigned char *cptr;
 
+               stlen = MIN(len, stlen);
+               tty_prepare_flip_string(tty, &cptr, stlen);
+               memcpy_fromio(cptr, shbuf + tail, stlen);
                len -= stlen;
                tail += stlen;
                if (tail >= size) {
@@ -2809,8 +2426,8 @@ static inline void stli_read(stlibrd_t *brdp, stliport_t *portp)
                        stlen = head;
                }
        }
-       rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;
-       rp->tail = tail;
+       rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;
+       writew(tail, &rp->tail);
 
        if (head != tail)
                set_bit(ST_RXING, &portp->state);
@@ -2826,9 +2443,9 @@ static inline void stli_read(stlibrd_t *brdp, stliport_t *portp)
  *     difficult to deal with them here.
  */
 
-static inline void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp)
+static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp)
 {
-       int     cmd;
+       int cmd;
 
        if (test_bit(ST_DOSIGS, &portp->state)) {
                if (test_bit(ST_DOFLUSHTX, &portp->state) &&
@@ -2843,10 +2460,10 @@ static inline void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp)
                clear_bit(ST_DOFLUSHTX, &portp->state);
                clear_bit(ST_DOFLUSHRX, &portp->state);
                clear_bit(ST_DOSIGS, &portp->state);
-               memcpy((void *) &(cp->args[0]), (void *) &portp->asig,
+               memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &portp->asig,
                        sizeof(asysigs_t));
-               cp->status = 0;
-               cp->cmd = cmd;
+               writel(0, &cp->status);
+               writel(cmd, &cp->cmd);
                set_bit(ST_CMDING, &portp->state);
        } else if (test_bit(ST_DOFLUSHTX, &portp->state) ||
            test_bit(ST_DOFLUSHRX, &portp->state)) {
@@ -2854,9 +2471,9 @@ static inline void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp)
                cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0);
                clear_bit(ST_DOFLUSHTX, &portp->state);
                clear_bit(ST_DOFLUSHRX, &portp->state);
-               memcpy((void *) &(cp->args[0]), (void *) &cmd, sizeof(int));
-               cp->status = 0;
-               cp->cmd = A_FLUSH;
+               memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &cmd, sizeof(int));
+               writel(0, &cp->status);
+               writel(A_FLUSH, &cp->cmd);
                set_bit(ST_CMDING, &portp->state);
        }
 }
@@ -2874,32 +2491,27 @@ static inline void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp)
  *     then port is still busy, otherwise no longer busy.
  */
 
-static inline int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
+static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
 {
-       volatile cdkasy_t       *ap;
-       volatile cdkctrl_t      *cp;
-       struct tty_struct       *tty;
-       asynotify_t             nt;
-       unsigned long           oldsigs;
-       int                     rc, donerx;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_hostcmd(brdp=%x,channr=%d)\n",
-                       (int) brdp, channr);
-#endif
-
-       ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
+       cdkasy_t __iomem *ap;
+       cdkctrl_t __iomem *cp;
+       struct tty_struct *tty;
+       asynotify_t nt;
+       unsigned long oldsigs;
+       int rc, donerx;
+
+       ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
        cp = &ap->ctrl;
 
 /*
  *     Check if we are waiting for an open completion message.
  */
        if (test_bit(ST_OPENING, &portp->state)) {
-               rc = (int) cp->openarg;
-               if ((cp->open == 0) && (rc != 0)) {
+               rc = readl(&cp->openarg);
+               if (readb(&cp->open) == 0 && rc != 0) {
                        if (rc > 0)
                                rc--;
-                       cp->openarg = 0;
+                       writel(0, &cp->openarg);
                        portp->rc = rc;
                        clear_bit(ST_OPENING, &portp->state);
                        wake_up_interruptible(&portp->raw_wait);
@@ -2910,11 +2522,11 @@ static inline int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
  *     Check if we are waiting for a close completion message.
  */
        if (test_bit(ST_CLOSING, &portp->state)) {
-               rc = (int) cp->closearg;
-               if ((cp->close == 0) && (rc != 0)) {
+               rc = (int) readl(&cp->closearg);
+               if (readb(&cp->close) == 0 && rc != 0) {
                        if (rc > 0)
                                rc--;
-                       cp->closearg = 0;
+                       writel(0, &cp->closearg);
                        portp->rc = rc;
                        clear_bit(ST_CLOSING, &portp->state);
                        wake_up_interruptible(&portp->raw_wait);
@@ -2926,16 +2538,16 @@ static inline int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
  *     need to copy out the command results associated with this command.
  */
        if (test_bit(ST_CMDING, &portp->state)) {
-               rc = cp->status;
-               if ((cp->cmd == 0) && (rc != 0)) {
+               rc = readl(&cp->status);
+               if (readl(&cp->cmd) == 0 && rc != 0) {
                        if (rc > 0)
                                rc--;
-                       if (portp->argp != (void *) NULL) {
-                               memcpy(portp->argp, (void *) &(cp->args[0]),
+                       if (portp->argp != NULL) {
+                               memcpy_fromio(portp->argp, (void __iomem *) &(cp->args[0]),
                                        portp->argsize);
-                               portp->argp = (void *) NULL;
+                               portp->argp = NULL;
                        }
-                       cp->status = 0;
+                       writel(0, &cp->status);
                        portp->rc = rc;
                        clear_bit(ST_CMDING, &portp->state);
                        stli_dodelaycmd(portp, cp);
@@ -2974,28 +2586,21 @@ static inline int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
                if (nt.data & DT_TXEMPTY)
                        clear_bit(ST_TXBUSY, &portp->state);
                if (nt.data & (DT_TXEMPTY | DT_TXLOW)) {
-                       if (tty != (struct tty_struct *) NULL) {
-                               if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                                   tty->ldisc.write_wakeup) {
-                                       (tty->ldisc.write_wakeup)(tty);
-                                       EBRDENABLE(brdp);
-                               }
+                       if (tty != NULL) {
+                               tty_wakeup(tty);
+                               EBRDENABLE(brdp);
                                wake_up_interruptible(&tty->write_wait);
                        }
                }
 
                if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) {
-                       if (tty != (struct tty_struct *) NULL) {
-                               if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-                                       tty->flip.count++;
-                                       *tty->flip.flag_buf_ptr++ = TTY_BREAK;
-                                       *tty->flip.char_buf_ptr++ = 0;
-                                       if (portp->flags & ASYNC_SAK) {
-                                               do_SAK(tty);
-                                               EBRDENABLE(brdp);
-                                       }
-                                       tty_schedule_flip(tty);
+                       if (tty != NULL) {
+                               tty_insert_flip_char(tty, 0, TTY_BREAK);
+                               if (portp->flags & ASYNC_SAK) {
+                                       do_SAK(tty);
+                                       EBRDENABLE(brdp);
                                }
+                               tty_schedule_flip(tty);
                        }
                }
 
@@ -3033,14 +2638,14 @@ static inline int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
  *     at the cdk header structure.
  */
 
-static inline void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp)
+static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp)
 {
-       stliport_t      *portp;
-       unsigned char   hostbits[(STL_MAXCHANS / 8) + 1];
-       unsigned char   slavebits[(STL_MAXCHANS / 8) + 1];
-       unsigned char   *slavep;
-       int             bitpos, bitat, bitsize;
-       int             channr, nrdevs, slavebitchange;
+       stliport_t *portp;
+       unsigned char hostbits[(STL_MAXCHANS / 8) + 1];
+       unsigned char slavebits[(STL_MAXCHANS / 8) + 1];
+       unsigned char __iomem *slavep;
+       int bitpos, bitat, bitsize;
+       int channr, nrdevs, slavebitchange;
 
        bitsize = brdp->bitsize;
        nrdevs = brdp->nrdevs;
@@ -3052,7 +2657,7 @@ static inline void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp)
  *     8 service bits at a time in the inner loop, so we can bypass
  *     the lot if none of them want service.
  */
-       memcpy(&hostbits[0], (((unsigned char *) hdrp) + brdp->hostoffset),
+       memcpy_fromio(&hostbits[0], (((unsigned char __iomem *) hdrp) + brdp->hostoffset),
                bitsize);
 
        memset(&slavebits[0], 0, bitsize);
@@ -3079,11 +2684,11 @@ static inline void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp)
  *     service may initiate more slave requests.
  */
        if (slavebitchange) {
-               hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
-               slavep = ((unsigned char *) hdrp) + brdp->slaveoffset;
+               hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+               slavep = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset;
                for (bitpos = 0; (bitpos < bitsize); bitpos++) {
-                       if (slavebits[bitpos])
-                               slavep[bitpos] &= ~slavebits[bitpos];
+                       if (readb(slavebits + bitpos))
+                               writeb(readb(slavep + bitpos) & ~slavebits[bitpos], slavebits + bitpos);
                }
        }
 }
@@ -3101,9 +2706,9 @@ static inline void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp)
 
 static void stli_poll(unsigned long arg)
 {
-       volatile cdkhdr_t       *hdrp;
-       stlibrd_t               *brdp;
-       int                     brdnr;
+       cdkhdr_t __iomem *hdrp;
+       stlibrd_t *brdp;
+       int brdnr;
 
        stli_timerlist.expires = STLI_TIMEOUT;
        add_timer(&stli_timerlist);
@@ -3113,16 +2718,18 @@ static void stli_poll(unsigned long arg)
  */
        for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) {
                brdp = stli_brds[brdnr];
-               if (brdp == (stlibrd_t *) NULL)
+               if (brdp == NULL)
                        continue;
                if ((brdp->state & BST_STARTED) == 0)
                        continue;
 
+               spin_lock(&brd_lock);
                EBRDENABLE(brdp);
-               hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
-               if (hdrp->hostreq)
+               hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+               if (readb(&hdrp->hostreq))
                        stli_brdpoll(brdp, hdrp);
                EBRDDISABLE(brdp);
+               spin_unlock(&brd_lock);
        }
 }
 
@@ -3135,11 +2742,6 @@ static void stli_poll(unsigned long arg)
 
 static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp)
 {
-#if DEBUG
-       printk(KERN_DEBUG "stli_mkasyport(portp=%x,pp=%x,tiosp=%d)\n",
-               (int) portp, (int) pp, (int) tiosp);
-#endif
-
        memset(pp, 0, sizeof(asyport_t));
 
 /*
@@ -3258,11 +2860,6 @@ static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tio
 
 static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts)
 {
-#if DEBUG
-       printk(KERN_DEBUG "stli_mkasysigs(sp=%x,dtr=%d,rts=%d)\n",
-                       (int) sp, dtr, rts);
-#endif
-
        memset(sp, 0, sizeof(asysigs_t));
        if (dtr >= 0) {
                sp->signal |= SG_DTR;
@@ -3283,13 +2880,7 @@ static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts)
 
 static long stli_mktiocm(unsigned long sigvalue)
 {
-       long    tiocm;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_mktiocm(sigvalue=%x)\n", (int) sigvalue);
-#endif
-
-       tiocm = 0;
+       long    tiocm = 0;
        tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0);
        tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0);
        tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0);
@@ -3306,23 +2897,18 @@ static long stli_mktiocm(unsigned long sigvalue)
  *     we need to do here is set up the appropriate per port data structures.
  */
 
-static inline int stli_initports(stlibrd_t *brdp)
+static int stli_initports(stlibrd_t *brdp)
 {
        stliport_t      *portp;
        int             i, panelnr, panelport;
 
-#if DEBUG
-       printk(KERN_DEBUG "stli_initports(brdp=%x)\n", (int) brdp);
-#endif
-
        for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {
-               portp = (stliport_t *) stli_memalloc(sizeof(stliport_t));
-               if (portp == (stliport_t *) NULL) {
+               portp = kzalloc(sizeof(stliport_t), GFP_KERNEL);
+               if (!portp) {
                        printk("STALLION: failed to allocate port structure\n");
                        continue;
                }
 
-               memset(portp, 0, sizeof(stliport_t));
                portp->magic = STLI_PORTMAGIC;
                portp->portnr = i;
                portp->brdnr = brdp->brdnr;
@@ -3342,7 +2928,7 @@ static inline int stli_initports(stlibrd_t *brdp)
                brdp->ports[i] = portp;
        }
 
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -3355,10 +2941,6 @@ static void stli_ecpinit(stlibrd_t *brdp)
 {
        unsigned long   memconf;
 
-#if DEBUG
-       printk(KERN_DEBUG "stli_ecpinit(brdp=%d)\n", (int) brdp);
-#endif
-
        outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR));
        udelay(10);
        outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));
@@ -3372,9 +2954,6 @@ static void stli_ecpinit(stlibrd_t *brdp)
 
 static void stli_ecpenable(stlibrd_t *brdp)
 {      
-#if DEBUG
-       printk(KERN_DEBUG "stli_ecpenable(brdp=%x)\n", (int) brdp);
-#endif
        outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR));
 }
 
@@ -3382,9 +2961,6 @@ static void stli_ecpenable(stlibrd_t *brdp)
 
 static void stli_ecpdisable(stlibrd_t *brdp)
 {      
-#if DEBUG
-       printk(KERN_DEBUG "stli_ecpdisable(brdp=%x)\n", (int) brdp);
-#endif
        outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));
 }
 
@@ -3392,19 +2968,14 @@ static void stli_ecpdisable(stlibrd_t *brdp)
 
 static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 {      
-       void            *ptr;
-       unsigned char   val;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_ecpgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
-               (int) offset);
-#endif
+       void *ptr;
+       unsigned char val;
 
        if (offset > brdp->memsize) {
                printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
                                "range at line=%d(%d), brd=%d\n",
                        (int) offset, line, __LINE__, brdp->brdnr);
-               ptr = 0;
+               ptr = NULL;
                val = 0;
        } else {
                ptr = brdp->membase + (offset % ECP_ATPAGESIZE);
@@ -3418,10 +2989,6 @@ static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 
 static void stli_ecpreset(stlibrd_t *brdp)
 {      
-#if DEBUG
-       printk(KERN_DEBUG "stli_ecpreset(brdp=%x)\n", (int) brdp);
-#endif
-
        outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR));
        udelay(10);
        outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));
@@ -3432,9 +2999,6 @@ static void stli_ecpreset(stlibrd_t *brdp)
 
 static void stli_ecpintr(stlibrd_t *brdp)
 {      
-#if DEBUG
-       printk(KERN_DEBUG "stli_ecpintr(brdp=%x)\n", (int) brdp);
-#endif
        outb(0x1, brdp->iobase);
 }
 
@@ -3448,10 +3012,6 @@ static void stli_ecpeiinit(stlibrd_t *brdp)
 {
        unsigned long   memconf;
 
-#if DEBUG
-       printk(KERN_DEBUG "stli_ecpeiinit(brdp=%x)\n", (int) brdp);
-#endif
-
        outb(0x1, (brdp->iobase + ECP_EIBRDENAB));
        outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR));
        udelay(10);
@@ -3485,16 +3045,11 @@ static char *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line
        void            *ptr;
        unsigned char   val;
 
-#if DEBUG
-       printk(KERN_DEBUG "stli_ecpeigetmemptr(brdp=%x,offset=%x,line=%d)\n",
-               (int) brdp, (int) offset, line);
-#endif
-
        if (offset > brdp->memsize) {
                printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
                                "range at line=%d(%d), brd=%d\n",
                        (int) offset, line, __LINE__, brdp->brdnr);
-               ptr = 0;
+               ptr = NULL;
                val = 0;
        } else {
                ptr = brdp->membase + (offset % ECP_EIPAGESIZE);
@@ -3539,14 +3094,14 @@ static void stli_ecpmcdisable(stlibrd_t *brdp)
 
 static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 {      
-       void            *ptr;
-       unsigned char   val;
+       void *ptr;
+       unsigned char val;
 
        if (offset > brdp->memsize) {
                printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
                                "range at line=%d(%d), brd=%d\n",
                        (int) offset, line, __LINE__, brdp->brdnr);
-               ptr = 0;
+               ptr = NULL;
                val = 0;
        } else {
                ptr = brdp->membase + (offset % ECP_MCPAGESIZE);
@@ -3574,10 +3129,6 @@ static void stli_ecpmcreset(stlibrd_t *brdp)
 
 static void stli_ecppciinit(stlibrd_t *brdp)
 {
-#if DEBUG
-       printk(KERN_DEBUG "stli_ecppciinit(brdp=%x)\n", (int) brdp);
-#endif
-
        outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR));
        udelay(10);
        outb(0, (brdp->iobase + ECP_PCICONFR));
@@ -3591,16 +3142,11 @@ static char *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int lin
        void            *ptr;
        unsigned char   val;
 
-#if DEBUG
-       printk(KERN_DEBUG "stli_ecppcigetmemptr(brdp=%x,offset=%x,line=%d)\n",
-               (int) brdp, (int) offset, line);
-#endif
-
        if (offset > brdp->memsize) {
                printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
                                "range at line=%d(%d), board=%d\n",
                                (int) offset, line, __LINE__, brdp->brdnr);
-               ptr = 0;
+               ptr = NULL;
                val = 0;
        } else {
                ptr = brdp->membase + (offset % ECP_PCIPAGESIZE);
@@ -3630,10 +3176,6 @@ static void stli_onbinit(stlibrd_t *brdp)
 {
        unsigned long   memconf;
 
-#if DEBUG
-       printk(KERN_DEBUG "stli_onbinit(brdp=%d)\n", (int) brdp);
-#endif
-
        outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));
        udelay(10);
        outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR));
@@ -3649,9 +3191,6 @@ static void stli_onbinit(stlibrd_t *brdp)
 
 static void stli_onbenable(stlibrd_t *brdp)
 {      
-#if DEBUG
-       printk(KERN_DEBUG "stli_onbenable(brdp=%x)\n", (int) brdp);
-#endif
        outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR));
 }
 
@@ -3659,9 +3198,6 @@ static void stli_onbenable(stlibrd_t *brdp)
 
 static void stli_onbdisable(stlibrd_t *brdp)
 {      
-#if DEBUG
-       printk(KERN_DEBUG "stli_onbdisable(brdp=%x)\n", (int) brdp);
-#endif
        outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR));
 }
 
@@ -3671,16 +3207,11 @@ static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 {      
        void    *ptr;
 
-#if DEBUG
-       printk(KERN_DEBUG "stli_onbgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
-               (int) offset);
-#endif
-
        if (offset > brdp->memsize) {
                printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
                                "range at line=%d(%d), brd=%d\n",
                                (int) offset, line, __LINE__, brdp->brdnr);
-               ptr = 0;
+               ptr = NULL;
        } else {
                ptr = brdp->membase + (offset % ONB_ATPAGESIZE);
        }
@@ -3691,11 +3222,6 @@ static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 
 static void stli_onbreset(stlibrd_t *brdp)
 {      
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_onbreset(brdp=%x)\n", (int) brdp);
-#endif
-
        outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));
        udelay(10);
        outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR));
@@ -3712,10 +3238,6 @@ static void stli_onbeinit(stlibrd_t *brdp)
 {
        unsigned long   memconf;
 
-#if DEBUG
-       printk(KERN_DEBUG "stli_onbeinit(brdp=%d)\n", (int) brdp);
-#endif
-
        outb(0x1, (brdp->iobase + ONB_EIBRDENAB));
        outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));
        udelay(10);
@@ -3734,9 +3256,6 @@ static void stli_onbeinit(stlibrd_t *brdp)
 
 static void stli_onbeenable(stlibrd_t *brdp)
 {      
-#if DEBUG
-       printk(KERN_DEBUG "stli_onbeenable(brdp=%x)\n", (int) brdp);
-#endif
        outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR));
 }
 
@@ -3744,9 +3263,6 @@ static void stli_onbeenable(stlibrd_t *brdp)
 
 static void stli_onbedisable(stlibrd_t *brdp)
 {      
-#if DEBUG
-       printk(KERN_DEBUG "stli_onbedisable(brdp=%x)\n", (int) brdp);
-#endif
        outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
 }
 
@@ -3754,19 +3270,14 @@ static void stli_onbedisable(stlibrd_t *brdp)
 
 static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 {      
-       void            *ptr;
-       unsigned char   val;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_onbegetmemptr(brdp=%x,offset=%x,line=%d)\n",
-               (int) brdp, (int) offset, line);
-#endif
+       void *ptr;
+       unsigned char val;
 
        if (offset > brdp->memsize) {
                printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
                                "range at line=%d(%d), brd=%d\n",
                        (int) offset, line, __LINE__, brdp->brdnr);
-               ptr = 0;
+               ptr = NULL;
                val = 0;
        } else {
                ptr = brdp->membase + (offset % ONB_EIPAGESIZE);
@@ -3783,11 +3294,6 @@ static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 
 static void stli_onbereset(stlibrd_t *brdp)
 {      
-
-#if DEBUG
-       printk(KERN_ERR "stli_onbereset(brdp=%x)\n", (int) brdp);
-#endif
-
        outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));
        udelay(10);
        outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
@@ -3802,11 +3308,6 @@ static void stli_onbereset(stlibrd_t *brdp)
 
 static void stli_bbyinit(stlibrd_t *brdp)
 {
-
-#if DEBUG
-       printk(KERN_ERR "stli_bbyinit(brdp=%d)\n", (int) brdp);
-#endif
-
        outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));
        udelay(10);
        outb(0, (brdp->iobase + BBY_ATCONFR));
@@ -3819,24 +3320,13 @@ static void stli_bbyinit(stlibrd_t *brdp)
 
 static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 {      
-       void            *ptr;
-       unsigned char   val;
+       void *ptr;
+       unsigned char val;
 
-#if DEBUG
-       printk(KERN_ERR "stli_bbygetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
-               (int) offset);
-#endif
+       BUG_ON(offset > brdp->memsize);
 
-       if (offset > brdp->memsize) {
-               printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
-                               "range at line=%d(%d), brd=%d\n",
-                               (int) offset, line, __LINE__, brdp->brdnr);
-               ptr = 0;
-               val = 0;
-       } else {
-               ptr = brdp->membase + (offset % BBY_PAGESIZE);
-               val = (unsigned char) (offset / BBY_PAGESIZE);
-       }
+       ptr = brdp->membase + (offset % BBY_PAGESIZE);
+       val = (unsigned char) (offset / BBY_PAGESIZE);
        outb(val, (brdp->iobase + BBY_ATCONFR));
        return(ptr);
 }
@@ -3845,11 +3335,6 @@ static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 
 static void stli_bbyreset(stlibrd_t *brdp)
 {      
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_bbyreset(brdp=%x)\n", (int) brdp);
-#endif
-
        outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));
        udelay(10);
        outb(0, (brdp->iobase + BBY_ATCONFR));
@@ -3864,11 +3349,6 @@ static void stli_bbyreset(stlibrd_t *brdp)
 
 static void stli_stalinit(stlibrd_t *brdp)
 {
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_stalinit(brdp=%d)\n", (int) brdp);
-#endif
-
        outb(0x1, brdp->iobase);
        mdelay(1000);
 }
@@ -3877,36 +3357,18 @@ static void stli_stalinit(stlibrd_t *brdp)
 
 static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 {      
-       void    *ptr;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_stalgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
-               (int) offset);
-#endif
-
-       if (offset > brdp->memsize) {
-               printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
-                               "range at line=%d(%d), brd=%d\n",
-                               (int) offset, line, __LINE__, brdp->brdnr);
-               ptr = 0;
-       } else {
-               ptr = brdp->membase + (offset % STAL_PAGESIZE);
-       }
-       return(ptr);
+       BUG_ON(offset > brdp->memsize);
+       return brdp->membase + (offset % STAL_PAGESIZE);
 }
 
 /*****************************************************************************/
 
 static void stli_stalreset(stlibrd_t *brdp)
 {      
-       volatile unsigned long  *vecp;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_stalreset(brdp=%x)\n", (int) brdp);
-#endif
+       u32 __iomem *vecp;
 
-       vecp = (volatile unsigned long *) (brdp->membase + 0x30);
-       *vecp = 0xffff0000;
+       vecp = (u32 __iomem *) (brdp->membase + 0x30);
+       writel(0xffff0000, vecp);
        outb(0, brdp->iobase);
        mdelay(1000);
 }
@@ -3918,17 +3380,13 @@ static void stli_stalreset(stlibrd_t *brdp)
  *     board types.
  */
 
-static inline int stli_initecp(stlibrd_t *brdp)
+static int stli_initecp(stlibrd_t *brdp)
 {
-       cdkecpsig_t     sig;
-       cdkecpsig_t     *sigsp;
-       unsigned int    status, nxtid;
-       char            *name;
-       int             panelnr, nrports;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_initecp(brdp=%x)\n", (int) brdp);
-#endif
+       cdkecpsig_t sig;
+       cdkecpsig_t __iomem *sigsp;
+       unsigned int status, nxtid;
+       char *name;
+       int panelnr, nrports;
 
        if (!request_region(brdp->iobase, brdp->iosize, "istallion"))
                return -EIO;
@@ -3936,7 +3394,7 @@ static inline int stli_initecp(stlibrd_t *brdp)
        if ((brdp->iobase == 0) || (brdp->memaddr == 0))
        {
                release_region(brdp->iobase, brdp->iosize);
-               return(-ENODEV);
+               return -ENODEV;
        }
 
        brdp->iosize = ECP_IOSIZE;
@@ -4005,7 +3463,7 @@ static inline int stli_initecp(stlibrd_t *brdp)
 
        default:
                release_region(brdp->iobase, brdp->iosize);
-               return(-EINVAL);
+               return -EINVAL;
        }
 
 /*
@@ -4017,10 +3475,10 @@ static inline int stli_initecp(stlibrd_t *brdp)
        EBRDINIT(brdp);
 
        brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
-       if (brdp->membase == (void *) NULL)
+       if (brdp->membase == NULL)
        {
                release_region(brdp->iobase, brdp->iosize);
-               return(-ENOMEM);
+               return -ENOMEM;
        }
 
 /*
@@ -4029,23 +3487,14 @@ static inline int stli_initecp(stlibrd_t *brdp)
  *     this is, and what it is connected to it.
  */
        EBRDENABLE(brdp);
-       sigsp = (cdkecpsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
+       sigsp = (cdkecpsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
        memcpy(&sig, sigsp, sizeof(cdkecpsig_t));
        EBRDDISABLE(brdp);
 
-#if 0
-       printk("%s(%d): sig-> magic=%x rom=%x panel=%x,%x,%x,%x,%x,%x,%x,%x\n",
-               __FILE__, __LINE__, (int) sig.magic, sig.romver, sig.panelid[0],
-               (int) sig.panelid[1], (int) sig.panelid[2],
-               (int) sig.panelid[3], (int) sig.panelid[4],
-               (int) sig.panelid[5], (int) sig.panelid[6],
-               (int) sig.panelid[7]);
-#endif
-
-       if (sig.magic != ECP_MAGIC)
+       if (sig.magic != cpu_to_le32(ECP_MAGIC))
        {
                release_region(brdp->iobase, brdp->iosize);
-               return(-ENODEV);
+               return -ENODEV;
        }
 
 /*
@@ -4069,7 +3518,7 @@ static inline int stli_initecp(stlibrd_t *brdp)
 
 
        brdp->state |= BST_FOUND;
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -4079,22 +3528,18 @@ static inline int stli_initecp(stlibrd_t *brdp)
  *     This handles only these board types.
  */
 
-static inline int stli_initonb(stlibrd_t *brdp)
+static int stli_initonb(stlibrd_t *brdp)
 {
-       cdkonbsig_t     sig;
-       cdkonbsig_t     *sigsp;
-       char            *name;
-       int             i;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_initonb(brdp=%x)\n", (int) brdp);
-#endif
+       cdkonbsig_t sig;
+       cdkonbsig_t __iomem *sigsp;
+       char *name;
+       int i;
 
 /*
  *     Do a basic sanity check on the IO and memory addresses.
  */
-       if ((brdp->iobase == 0) || (brdp->memaddr == 0))
-               return(-ENODEV);
+       if (brdp->iobase == 0 || brdp->memaddr == 0)
+               return -ENODEV;
 
        brdp->iosize = ONB_IOSIZE;
        
@@ -4112,7 +3557,6 @@ static inline int stli_initonb(stlibrd_t *brdp)
        case BRD_ONBOARD2:
        case BRD_ONBOARD2_32:
        case BRD_ONBOARDRS:
-               brdp->membase = (void *) brdp->memaddr;
                brdp->memsize = ONB_MEMSIZE;
                brdp->pagesize = ONB_ATPAGESIZE;
                brdp->init = stli_onbinit;
@@ -4130,7 +3574,6 @@ static inline int stli_initonb(stlibrd_t *brdp)
                break;
 
        case BRD_ONBOARDE:
-               brdp->membase = (void *) brdp->memaddr;
                brdp->memsize = ONB_EIMEMSIZE;
                brdp->pagesize = ONB_EIPAGESIZE;
                brdp->init = stli_onbeinit;
@@ -4146,7 +3589,6 @@ static inline int stli_initonb(stlibrd_t *brdp)
        case BRD_BRUMBY4:
        case BRD_BRUMBY8:
        case BRD_BRUMBY16:
-               brdp->membase = (void *) brdp->memaddr;
                brdp->memsize = BBY_MEMSIZE;
                brdp->pagesize = BBY_PAGESIZE;
                brdp->init = stli_bbyinit;
@@ -4160,7 +3602,6 @@ static inline int stli_initonb(stlibrd_t *brdp)
                break;
 
        case BRD_STALLION:
-               brdp->membase = (void *) brdp->memaddr;
                brdp->memsize = STAL_MEMSIZE;
                brdp->pagesize = STAL_PAGESIZE;
                brdp->init = stli_stalinit;
@@ -4175,7 +3616,7 @@ static inline int stli_initonb(stlibrd_t *brdp)
 
        default:
                release_region(brdp->iobase, brdp->iosize);
-               return(-EINVAL);
+               return -EINVAL;
        }
 
 /*
@@ -4187,10 +3628,10 @@ static inline int stli_initonb(stlibrd_t *brdp)
        EBRDINIT(brdp);
 
        brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
-       if (brdp->membase == (void *) NULL)
+       if (brdp->membase == NULL)
        {
                release_region(brdp->iobase, brdp->iosize);
-               return(-ENOMEM);
+               return -ENOMEM;
        }
 
 /*
@@ -4199,21 +3640,17 @@ static inline int stli_initonb(stlibrd_t *brdp)
  *     this is, and how many ports.
  */
        EBRDENABLE(brdp);
-       sigsp = (cdkonbsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
-       memcpy(&sig, sigsp, sizeof(cdkonbsig_t));
+       sigsp = (cdkonbsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
+       memcpy_fromio(&sig, sigsp, sizeof(cdkonbsig_t));
        EBRDDISABLE(brdp);
 
-#if 0
-       printk("%s(%d): sig-> magic=%x:%x:%x:%x romver=%x amask=%x:%x:%x\n",
-               __FILE__, __LINE__, sig.magic0, sig.magic1, sig.magic2,
-               sig.magic3, sig.romver, sig.amask0, sig.amask1, sig.amask2);
-#endif
-
-       if ((sig.magic0 != ONB_MAGIC0) || (sig.magic1 != ONB_MAGIC1) ||
-           (sig.magic2 != ONB_MAGIC2) || (sig.magic3 != ONB_MAGIC3))
+       if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) ||
+           sig.magic1 != cpu_to_le16(ONB_MAGIC1) ||
+           sig.magic2 != cpu_to_le16(ONB_MAGIC2) ||
+           sig.magic3 != cpu_to_le16(ONB_MAGIC3))
        {
                release_region(brdp->iobase, brdp->iosize);
-               return(-ENODEV);
+               return -ENODEV;
        }
 
 /*
@@ -4234,7 +3671,7 @@ static inline int stli_initonb(stlibrd_t *brdp)
 
 
        brdp->state |= BST_FOUND;
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -4247,31 +3684,25 @@ static inline int stli_initonb(stlibrd_t *brdp)
 
 static int stli_startbrd(stlibrd_t *brdp)
 {
-       volatile cdkhdr_t       *hdrp;
-       volatile cdkmem_t       *memp;
-       volatile cdkasy_t       *ap;
-       unsigned long           flags;
-       stliport_t              *portp;
-       int                     portnr, nrdevs, i, rc;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_startbrd(brdp=%x)\n", (int) brdp);
-#endif
-
-       rc = 0;
-
-       save_flags(flags);
-       cli();
+       cdkhdr_t __iomem *hdrp;
+       cdkmem_t __iomem *memp;
+       cdkasy_t __iomem *ap;
+       unsigned long flags;
+       stliport_t *portp;
+       int portnr, nrdevs, i, rc = 0;
+       u32 memoff;
+
+       spin_lock_irqsave(&brd_lock, flags);
        EBRDENABLE(brdp);
-       hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+       hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
        nrdevs = hdrp->nrdevs;
 
 #if 0
        printk("%s(%d): CDK version %d.%d.%d --> "
                "nrdevs=%d memp=%x hostp=%x slavep=%x\n",
-                __FILE__, __LINE__, hdrp->ver_release, hdrp->ver_modification,
-                hdrp->ver_fix, nrdevs, (int) hdrp->memp, (int) hdrp->hostp,
-                (int) hdrp->slavep);
+                __FILE__, __LINE__, readb(&hdrp->ver_release), readb(&hdrp->ver_modification),
+                readb(&hdrp->ver_fix), nrdevs, (int) readl(&hdrp->memp), readl(&hdrp->hostp),
+                readl(&hdrp->slavep));
 #endif
 
        if (nrdevs < (brdp->nrports + 1)) {
@@ -4283,14 +3714,14 @@ static int stli_startbrd(stlibrd_t *brdp)
        brdp->hostoffset = hdrp->hostp - CDK_CDKADDR;
        brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR;
        brdp->bitsize = (nrdevs + 7) / 8;
-       memp = (volatile cdkmem_t *) hdrp->memp;
-       if (((unsigned long) memp) > brdp->memsize) {
+       memoff = readl(&hdrp->memp);
+       if (memoff > brdp->memsize) {
                printk(KERN_ERR "STALLION: corrupted shared memory region?\n");
                rc = -EIO;
                goto stli_donestartup;
        }
-       memp = (volatile cdkmem_t *) EBRDGETMEMPTR(brdp, (unsigned long) memp);
-       if (memp->dtype != TYP_ASYNCTRL) {
+       memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff);
+       if (readw(&memp->dtype) != TYP_ASYNCTRL) {
                printk(KERN_ERR "STALLION: no slave control device found\n");
                goto stli_donestartup;
        }
@@ -4302,19 +3733,19 @@ static int stli_startbrd(stlibrd_t *brdp)
  *     change pages while reading memory map.
  */
        for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) {
-               if (memp->dtype != TYP_ASYNC)
+               if (readw(&memp->dtype) != TYP_ASYNC)
                        break;
                portp = brdp->ports[portnr];
-               if (portp == (stliport_t *) NULL)
+               if (portp == NULL)
                        break;
                portp->devnr = i;
-               portp->addr = memp->offset;
+               portp->addr = readl(&memp->offset);
                portp->reqbit = (unsigned char) (0x1 << (i * 8 / nrdevs));
                portp->portidx = (unsigned char) (i / 8);
                portp->portbit = (unsigned char) (0x1 << (i % 8));
        }
 
-       hdrp->slavereq = 0xff;
+       writeb(0xff, &hdrp->slavereq);
 
 /*
  *     For each port setup a local copy of the RX and TX buffer offsets
@@ -4323,22 +3754,22 @@ static int stli_startbrd(stlibrd_t *brdp)
  */
        for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) {
                portp = brdp->ports[portnr];
-               if (portp == (stliport_t *) NULL)
+               if (portp == NULL)
                        break;
                if (portp->addr == 0)
                        break;
-               ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
-               if (ap != (volatile cdkasy_t *) NULL) {
-                       portp->rxsize = ap->rxq.size;
-                       portp->txsize = ap->txq.size;
-                       portp->rxoffset = ap->rxq.offset;
-                       portp->txoffset = ap->txq.offset;
+               ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
+               if (ap != NULL) {
+                       portp->rxsize = readw(&ap->rxq.size);
+                       portp->txsize = readw(&ap->txq.size);
+                       portp->rxoffset = readl(&ap->rxq.offset);
+                       portp->txoffset = readl(&ap->txq.offset);
                }
        }
 
 stli_donestartup:
        EBRDDISABLE(brdp);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&brd_lock, flags);
 
        if (rc == 0)
                brdp->state |= BST_STARTED;
@@ -4349,7 +3780,7 @@ stli_donestartup:
                add_timer(&stli_timerlist);
        }
 
-       return(rc);
+       return rc;
 }
 
 /*****************************************************************************/
@@ -4360,10 +3791,6 @@ stli_donestartup:
 
 static int __init stli_brdinit(stlibrd_t *brdp)
 {
-#if DEBUG
-       printk(KERN_DEBUG "stli_brdinit(brdp=%x)\n", (int) brdp);
-#endif
-
        stli_brds[brdp->brdnr] = brdp;
 
        switch (brdp->brdtype) {
@@ -4391,11 +3818,11 @@ static int __init stli_brdinit(stlibrd_t *brdp)
        case BRD_ECHPCI:
                printk(KERN_ERR "STALLION: %s board type not supported in "
                                "this driver\n", stli_brdnames[brdp->brdtype]);
-               return(ENODEV);
+               return -ENODEV;
        default:
                printk(KERN_ERR "STALLION: board=%d is unknown board "
                                "type=%d\n", brdp->brdnr, brdp->brdtype);
-               return(ENODEV);
+               return -ENODEV;
        }
 
        if ((brdp->state & BST_FOUND) == 0) {
@@ -4403,7 +3830,7 @@ static int __init stli_brdinit(stlibrd_t *brdp)
                                "io=%x mem=%x\n",
                        stli_brdnames[brdp->brdtype], brdp->brdnr,
                        brdp->iobase, (int) brdp->memaddr);
-               return(ENODEV);
+               return -ENODEV;
        }
 
        stli_initports(brdp);
@@ -4411,7 +3838,7 @@ static int __init stli_brdinit(stlibrd_t *brdp)
                "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype],
                brdp->brdnr, brdp->iobase, (int) brdp->memaddr,
                brdp->nrpanels, brdp->nrports);
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -4421,16 +3848,12 @@ static int __init stli_brdinit(stlibrd_t *brdp)
  *     might be. This is a bit if hack, but it is the best we can do.
  */
 
-static inline int stli_eisamemprobe(stlibrd_t *brdp)
+static int stli_eisamemprobe(stlibrd_t *brdp)
 {
-       cdkecpsig_t     ecpsig, *ecpsigp;
-       cdkonbsig_t     onbsig, *onbsigp;
+       cdkecpsig_t     ecpsig, __iomem *ecpsigp;
+       cdkonbsig_t     onbsig, __iomem *onbsigp;
        int             i, foundit;
 
-#if DEBUG
-       printk(KERN_DEBUG "stli_eisamemprobe(brdp=%x)\n", (int) brdp);
-#endif
-
 /*
  *     First up we reset the board, to get it into a known state. There
  *     is only 2 board types here we need to worry about. Don;t use the
@@ -4454,7 +3877,7 @@ static inline int stli_eisamemprobe(stlibrd_t *brdp)
                mdelay(1);
                stli_onbeenable(brdp);
        } else {
-               return(-ENODEV);
+               return -ENODEV;
        }
 
        foundit = 0;
@@ -4466,25 +3889,24 @@ static inline int stli_eisamemprobe(stlibrd_t *brdp)
  */
        for (i = 0; (i < stli_eisamempsize); i++) {
                brdp->memaddr = stli_eisamemprobeaddrs[i];
-               brdp->membase = (void *) brdp->memaddr;
                brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
-               if (brdp->membase == (void *) NULL)
+               if (brdp->membase == NULL)
                        continue;
 
                if (brdp->brdtype == BRD_ECPE) {
-                       ecpsigp = (cdkecpsig_t *) stli_ecpeigetmemptr(brdp,
+                       ecpsigp = (cdkecpsig_t __iomem *) stli_ecpeigetmemptr(brdp,
                                CDK_SIGADDR, __LINE__);
-                       memcpy(&ecpsig, ecpsigp, sizeof(cdkecpsig_t));
-                       if (ecpsig.magic == ECP_MAGIC)
+                       memcpy_fromio(&ecpsig, ecpsigp, sizeof(cdkecpsig_t));
+                       if (ecpsig.magic == cpu_to_le32(ECP_MAGIC))
                                foundit = 1;
                } else {
-                       onbsigp = (cdkonbsig_t *) stli_onbegetmemptr(brdp,
+                       onbsigp = (cdkonbsig_t __iomem *) stli_onbegetmemptr(brdp,
                                CDK_SIGADDR, __LINE__);
-                       memcpy(&onbsig, onbsigp, sizeof(cdkonbsig_t));
-                       if ((onbsig.magic0 == ONB_MAGIC0) &&
-                           (onbsig.magic1 == ONB_MAGIC1) &&
-                           (onbsig.magic2 == ONB_MAGIC2) &&
-                           (onbsig.magic3 == ONB_MAGIC3))
+                       memcpy_fromio(&onbsig, onbsigp, sizeof(cdkonbsig_t));
+                       if ((onbsig.magic0 == cpu_to_le16(ONB_MAGIC0)) &&
+                           (onbsig.magic1 == cpu_to_le16(ONB_MAGIC1)) &&
+                           (onbsig.magic2 == cpu_to_le16(ONB_MAGIC2)) &&
+                           (onbsig.magic3 == cpu_to_le16(ONB_MAGIC3)))
                                foundit = 1;
                }
 
@@ -4504,13 +3926,27 @@ static inline int stli_eisamemprobe(stlibrd_t *brdp)
 
        if (! foundit) {
                brdp->memaddr = 0;
-               brdp->membase = 0;
+               brdp->membase = NULL;
                printk(KERN_ERR "STALLION: failed to probe shared memory "
                                "region for %s in EISA slot=%d\n",
                        stli_brdnames[brdp->brdtype], (brdp->iobase >> 12));
-               return(-ENODEV);
+               return -ENODEV;
+       }
+       return 0;
+}
+
+static int stli_getbrdnr(void)
+{
+       int i;
+
+       for (i = 0; i < STL_MAXBRDS; i++) {
+               if (!stli_brds[i]) {
+                       if (i >= stli_nrbrds)
+                               stli_nrbrds = i + 1;
+                       return i;
+               }
        }
-       return(0);
+       return -1;
 }
 
 /*****************************************************************************/
@@ -4525,24 +3961,18 @@ static inline int stli_eisamemprobe(stlibrd_t *brdp)
  *     do is go probing around in the usual places hoping we can find it.
  */
 
-static inline int stli_findeisabrds()
+static int stli_findeisabrds(void)
 {
-       stlibrd_t       *brdp;
-       unsigned int    iobase, eid;
-       int             i;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_findeisabrds()\n");
-#endif
+       stlibrd_t *brdp;
+       unsigned int iobase, eid;
+       int i;
 
 /*
- *     Firstly check if this is an EISA system. Do this by probing for
- *     the system board EISA ID. If this is not an EISA system then
+ *     Firstly check if this is an EISA system.  If this is not an EISA system then
  *     don't bother going any further!
  */
-       outb(0xff, 0xc80);
-       if (inb(0xc80) == 0xff)
-               return(0);
+       if (EISA_bus)
+               return 0;
 
 /*
  *     Looks like an EISA system, so go searching for EISA boards.
@@ -4560,7 +3990,7 @@ static inline int stli_findeisabrds()
  */
                for (i = 0; (i < STL_MAXBRDS); i++) {
                        brdp = stli_brds[i];
-                       if (brdp == (stlibrd_t *) NULL)
+                       if (brdp == NULL)
                                continue;
                        if (brdp->iobase == iobase)
                                break;
@@ -4572,10 +4002,10 @@ static inline int stli_findeisabrds()
  *             We have found a Stallion board and it is not configured already.
  *             Allocate a board structure and initialize it.
  */
-               if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)
-                       return(-ENOMEM);
+               if ((brdp = stli_allocbrd()) == NULL)
+                       return -ENOMEM;
                if ((brdp->brdnr = stli_getbrdnr()) < 0)
-                       return(-ENOMEM);
+                       return -ENOMEM;
                eid = inb(iobase + 0xc82);
                if (eid == ECP_EISAID)
                        brdp->brdtype = BRD_ECPE;
@@ -4590,7 +4020,7 @@ static inline int stli_findeisabrds()
                stli_brdinit(brdp);
        }
 
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -4599,20 +4029,6 @@ static inline int stli_findeisabrds()
  *     Find the next available board number that is free.
  */
 
-static inline int stli_getbrdnr()
-{
-       int     i;
-
-       for (i = 0; (i < STL_MAXBRDS); i++) {
-               if (stli_brds[i] == (stlibrd_t *) NULL) {
-                       if (i >= stli_nrbrds)
-                               stli_nrbrds = i + 1;
-                       return(i);
-               }
-       }
-       return(-1);
-}
-
 /*****************************************************************************/
 
 #ifdef CONFIG_PCI
@@ -4623,34 +4039,20 @@ static inline int stli_getbrdnr()
  *     configuration space.
  */
 
-static inline int stli_initpcibrd(int brdtype, struct pci_dev *devp)
+static int stli_initpcibrd(int brdtype, struct pci_dev *devp)
 {
-       stlibrd_t       *brdp;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n",
-               brdtype, dev->bus->number, dev->devfn);
-#endif
+       stlibrd_t *brdp;
 
        if (pci_enable_device(devp))
-               return(-EIO);
-       if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)
-               return(-ENOMEM);
+               return -EIO;
+       if ((brdp = stli_allocbrd()) == NULL)
+               return -ENOMEM;
        if ((brdp->brdnr = stli_getbrdnr()) < 0) {
                printk(KERN_INFO "STALLION: too many boards found, "
                        "maximum supported %d\n", STL_MAXBRDS);
-               return(0);
+               return 0;
        }
        brdp->brdtype = brdtype;
-
-#if DEBUG
-       printk(KERN_DEBUG "%s(%d): BAR[]=%lx,%lx,%lx,%lx\n", __FILE__, __LINE__,
-               pci_resource_start(devp, 0),
-               pci_resource_start(devp, 1),
-               pci_resource_start(devp, 2),
-               pci_resource_start(devp, 3));
-#endif
-
 /*
  *     We have all resources from the board, so lets setup the actual
  *     board structure now.
@@ -4659,7 +4061,7 @@ static inline int stli_initpcibrd(int brdtype, struct pci_dev *devp)
        brdp->memaddr = pci_resource_start(devp, 2);
        stli_brdinit(brdp);
 
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -4669,22 +4071,14 @@ static inline int stli_initpcibrd(int brdtype, struct pci_dev *devp)
  *     one as it is found.
  */
 
-static inline int stli_findpcibrds()
+static int stli_findpcibrds(void)
 {
-       struct pci_dev  *dev = NULL;
-       int             rc;
+       struct pci_dev *dev = NULL;
 
-#if DEBUG
-       printk("stli_findpcibrds()\n");
-#endif
-
-       while ((dev = pci_find_device(PCI_VENDOR_ID_STALLION,
-           PCI_DEVICE_ID_ECRA, dev))) {
-               if ((rc = stli_initpcibrd(BRD_ECPPCI, dev)))
-                       return(rc);
+       while ((dev = pci_get_device(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, dev))) {
+               stli_initpcibrd(BRD_ECPPCI, dev);
        }
-
-       return(0);
+       return 0;
 }
 
 #endif
@@ -4695,20 +4089,18 @@ static inline int stli_findpcibrds()
  *     Allocate a new board structure. Fill out the basic info in it.
  */
 
-static stlibrd_t *stli_allocbrd()
+static stlibrd_t *stli_allocbrd(void)
 {
-       stlibrd_t       *brdp;
+       stlibrd_t *brdp;
 
-       brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t));
-       if (brdp == (stlibrd_t *) NULL) {
+       brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL);
+       if (!brdp) {
                printk(KERN_ERR "STALLION: failed to allocate memory "
-                               "(size=%d)\n", sizeof(stlibrd_t));
-               return((stlibrd_t *) NULL);
+                               "(size=%Zd)\n", sizeof(stlibrd_t));
+               return NULL;
        }
-
-       memset(brdp, 0, sizeof(stlibrd_t));
        brdp->magic = STLI_BOARDMAGIC;
-       return(brdp);
+       return brdp;
 }
 
 /*****************************************************************************/
@@ -4718,15 +4110,11 @@ static stlibrd_t *stli_allocbrd()
  *     can find.
  */
 
-static inline int stli_initbrds()
+static int stli_initbrds(void)
 {
-       stlibrd_t       *brdp, *nxtbrdp;
-       stlconf_t       *confp;
-       int             i, j;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_initbrds()\n");
-#endif
+       stlibrd_t *brdp, *nxtbrdp;
+       stlconf_t *confp;
+       int i, j;
 
        if (stli_nrbrds > STL_MAXBRDS) {
                printk(KERN_INFO "STALLION: too many boards in configuration "
@@ -4741,11 +4129,9 @@ static inline int stli_initbrds()
  */
        for (i = 0; (i < stli_nrbrds); i++) {
                confp = &stli_brdconf[i];
-#ifdef MODULE
                stli_parsebrd(confp, stli_brdsp[i]);
-#endif
-               if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)
-                       return(-ENOMEM);
+               if ((brdp = stli_allocbrd()) == NULL)
+                       return -ENOMEM;
                brdp->brdnr = i;
                brdp->brdtype = confp->brdtype;
                brdp->iobase = confp->ioaddr1;
@@ -4757,10 +4143,8 @@ static inline int stli_initbrds()
  *     Static configuration table done, so now use dynamic methods to
  *     see if any more boards should be configured.
  */
-#ifdef MODULE
        stli_argbrds();
-#endif
-       if (stli_eisaprobe)
+       if (STLI_EISAPROBE)
                stli_findeisabrds();
 #ifdef CONFIG_PCI
        stli_findpcibrds();
@@ -4775,11 +4159,11 @@ static inline int stli_initbrds()
        if (stli_nrbrds > 1) {
                for (i = 0; (i < stli_nrbrds); i++) {
                        brdp = stli_brds[i];
-                       if (brdp == (stlibrd_t *) NULL)
+                       if (brdp == NULL)
                                continue;
                        for (j = i + 1; (j < stli_nrbrds); j++) {
                                nxtbrdp = stli_brds[j];
-                               if (nxtbrdp == (stlibrd_t *) NULL)
+                               if (nxtbrdp == NULL)
                                        continue;
                                if ((brdp->membase >= nxtbrdp->membase) &&
                                    (brdp->membase <= (nxtbrdp->membase +
@@ -4794,7 +4178,7 @@ static inline int stli_initbrds()
        if (stli_shared == 0) {
                for (i = 0; (i < stli_nrbrds); i++) {
                        brdp = stli_brds[i];
-                       if (brdp == (stlibrd_t *) NULL)
+                       if (brdp == NULL)
                                continue;
                        if (brdp->state & BST_FOUND) {
                                EBRDENABLE(brdp);
@@ -4804,7 +4188,7 @@ static inline int stli_initbrds()
                }
        }
 
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -4815,50 +4199,57 @@ static inline int stli_initbrds()
  *     the slave image (and debugging :-)
  */
 
-static ssize_t stli_memread(struct file *fp, char *buf, size_t count, loff_t *offp)
+static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp)
 {
-       unsigned long   flags;
-       void            *memptr;
-       stlibrd_t       *brdp;
-       int             brdnr, size, n;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_memread(fp=%x,buf=%x,count=%x,offp=%x)\n",
-                       (int) fp, (int) buf, count, (int) offp);
-#endif
+       unsigned long flags;
+       void *memptr;
+       stlibrd_t *brdp;
+       int brdnr, size, n;
+       void *p;
+       loff_t off = *offp;
 
        brdnr = iminor(fp->f_dentry->d_inode);
        if (brdnr >= stli_nrbrds)
-               return(-ENODEV);
+               return -ENODEV;
        brdp = stli_brds[brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(-ENODEV);
+       if (brdp == NULL)
+               return -ENODEV;
        if (brdp->state == 0)
-               return(-ENODEV);
-       if (fp->f_pos >= brdp->memsize)
-               return(0);
+               return -ENODEV;
+       if (off >= brdp->memsize || off + count < off)
+               return 0;
 
-       size = MIN(count, (brdp->memsize - fp->f_pos));
+       size = MIN(count, (brdp->memsize - off));
+
+       /*
+        *      Copy the data a page at a time
+        */
+
+       p = (void *)__get_free_page(GFP_KERNEL);
+       if(p == NULL)
+               return -ENOMEM;
 
-       save_flags(flags);
-       cli();
-       EBRDENABLE(brdp);
        while (size > 0) {
-               memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos);
-               n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize)));
-               if (copy_to_user(buf, memptr, n)) {
+               spin_lock_irqsave(&brd_lock, flags);
+               EBRDENABLE(brdp);
+               memptr = (void *) EBRDGETMEMPTR(brdp, off);
+               n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize)));
+               n = MIN(n, PAGE_SIZE);
+               memcpy_fromio(p, memptr, n);
+               EBRDDISABLE(brdp);
+               spin_unlock_irqrestore(&brd_lock, flags);
+               if (copy_to_user(buf, p, n)) {
                        count = -EFAULT;
                        goto out;
                }
-               fp->f_pos += n;
+               off += n;
                buf += n;
                size -= n;
        }
 out:
-       EBRDDISABLE(brdp);
-       restore_flags(flags);
-
-       return(count);
+       *offp = off;
+       free_page((unsigned long)p);
+       return count;
 }
 
 /*****************************************************************************/
@@ -4867,54 +4258,65 @@ out:
  *     Code to handle an "staliomem" write operation. This device is the 
  *     contents of the board shared memory. It is used for down loading
  *     the slave image (and debugging :-)
+ *
+ *     FIXME: copy under lock
  */
 
-static ssize_t stli_memwrite(struct file *fp, const char *buf, size_t count, loff_t *offp)
+static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp)
 {
-       unsigned long   flags;
-       void            *memptr;
-       stlibrd_t       *brdp;
-       char            *chbuf;
-       int             brdnr, size, n;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_memwrite(fp=%x,buf=%x,count=%x,offp=%x)\n",
-                       (int) fp, (int) buf, count, (int) offp);
-#endif
+       unsigned long flags;
+       void *memptr;
+       stlibrd_t *brdp;
+       char __user *chbuf;
+       int brdnr, size, n;
+       void *p;
+       loff_t off = *offp;
 
        brdnr = iminor(fp->f_dentry->d_inode);
+
        if (brdnr >= stli_nrbrds)
-               return(-ENODEV);
+               return -ENODEV;
        brdp = stli_brds[brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(-ENODEV);
+       if (brdp == NULL)
+               return -ENODEV;
        if (brdp->state == 0)
-               return(-ENODEV);
-       if (fp->f_pos >= brdp->memsize)
-               return(0);
+               return -ENODEV;
+       if (off >= brdp->memsize || off + count < off)
+               return 0;
 
-       chbuf = (char *) buf;
-       size = MIN(count, (brdp->memsize - fp->f_pos));
+       chbuf = (char __user *) buf;
+       size = MIN(count, (brdp->memsize - off));
+
+       /*
+        *      Copy the data a page at a time
+        */
+
+       p = (void *)__get_free_page(GFP_KERNEL);
+       if(p == NULL)
+               return -ENOMEM;
 
-       save_flags(flags);
-       cli();
-       EBRDENABLE(brdp);
        while (size > 0) {
-               memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos);
-               n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize)));
-               if (copy_from_user(memptr, chbuf, n)) {
-                       count = -EFAULT;
+               n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize)));
+               n = MIN(n, PAGE_SIZE);
+               if (copy_from_user(p, chbuf, n)) {
+                       if (count == 0)
+                               count = -EFAULT;
                        goto out;
                }
-               fp->f_pos += n;
+               spin_lock_irqsave(&brd_lock, flags);
+               EBRDENABLE(brdp);
+               memptr = (void *) EBRDGETMEMPTR(brdp, off);
+               memcpy_toio(memptr, p, n);
+               EBRDDISABLE(brdp);
+               spin_unlock_irqrestore(&brd_lock, flags);
+               off += n;
                chbuf += n;
                size -= n;
        }
 out:
-       EBRDDISABLE(brdp);
-       restore_flags(flags);
-
-       return(count);
+       free_page((unsigned long) p);
+       *offp = off;
+       return count;
 }
 
 /*****************************************************************************/
@@ -4923,18 +4325,18 @@ out:
  *     Return the board stats structure to user app.
  */
 
-static int stli_getbrdstats(combrd_t *bp)
+static int stli_getbrdstats(combrd_t __user *bp)
 {
-       stlibrd_t       *brdp;
-       int             i;
+       stlibrd_t *brdp;
+       int i;
 
        if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t)))
                return -EFAULT;
        if (stli_brdstats.brd >= STL_MAXBRDS)
-               return(-ENODEV);
+               return -ENODEV;
        brdp = stli_brds[stli_brdstats.brd];
-       if (brdp == (stlibrd_t *) NULL)
-               return(-ENODEV);
+       if (brdp == NULL)
+               return -ENODEV;
 
        memset(&stli_brdstats, 0, sizeof(combrd_t));
        stli_brdstats.brd = brdp->brdnr;
@@ -4953,7 +4355,7 @@ static int stli_getbrdstats(combrd_t *bp)
 
        if (copy_to_user(bp, &stli_brdstats, sizeof(combrd_t)))
                return -EFAULT;
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -4964,19 +4366,19 @@ static int stli_getbrdstats(combrd_t *bp)
 
 static stliport_t *stli_getport(int brdnr, int panelnr, int portnr)
 {
-       stlibrd_t       *brdp;
-       int             i;
+       stlibrd_t *brdp;
+       int i;
 
-       if ((brdnr < 0) || (brdnr >= STL_MAXBRDS))
-               return((stliport_t *) NULL);
+       if (brdnr < 0 || brdnr >= STL_MAXBRDS)
+               return NULL;
        brdp = stli_brds[brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return((stliport_t *) NULL);
+       if (brdp == NULL)
+               return NULL;
        for (i = 0; (i < panelnr); i++)
                portnr += brdp->panels[i];
        if ((portnr < 0) || (portnr >= brdp->nrports))
-               return((stliport_t *) NULL);
-       return(brdp->ports[portnr]);
+               return NULL;
+       return brdp->ports[portnr];
 }
 
 /*****************************************************************************/
@@ -4995,16 +4397,16 @@ static int stli_portcmdstats(stliport_t *portp)
 
        memset(&stli_comstats, 0, sizeof(comstats_t));
 
-       if (portp == (stliport_t *) NULL)
-               return(-ENODEV);
+       if (portp == NULL)
+               return -ENODEV;
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(-ENODEV);
+       if (brdp == NULL)
+               return -ENODEV;
 
        if (brdp->state & BST_STARTED) {
                if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS,
                    &stli_cdkstats, sizeof(asystats_t), 1)) < 0)
-                       return(rc);
+                       return rc;
        } else {
                memset(&stli_cdkstats, 0, sizeof(asystats_t));
        }
@@ -5015,13 +4417,12 @@ static int stli_portcmdstats(stliport_t *portp)
        stli_comstats.state = portp->state;
        stli_comstats.flags = portp->flags;
 
-       save_flags(flags);
-       cli();
-       if (portp->tty != (struct tty_struct *) NULL) {
+       spin_lock_irqsave(&brd_lock, flags);
+       if (portp->tty != NULL) {
                if (portp->tty->driver_data == portp) {
                        stli_comstats.ttystate = portp->tty->flags;
-                       stli_comstats.rxbuffered = portp->tty->flip.count;
-                       if (portp->tty->termios != (struct termios *) NULL) {
+                       stli_comstats.rxbuffered = -1;
+                       if (portp->tty->termios != NULL) {
                                stli_comstats.cflags = portp->tty->termios->c_cflag;
                                stli_comstats.iflags = portp->tty->termios->c_iflag;
                                stli_comstats.oflags = portp->tty->termios->c_oflag;
@@ -5029,7 +4430,7 @@ static int stli_portcmdstats(stliport_t *portp)
                        }
                }
        }
-       restore_flags(flags);
+       spin_unlock_irqrestore(&brd_lock, flags);
 
        stli_comstats.txtotal = stli_cdkstats.txchars;
        stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover;
@@ -5051,7 +4452,7 @@ static int stli_portcmdstats(stliport_t *portp)
        stli_comstats.hwid = stli_cdkstats.hwid;
        stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals);
 
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -5062,26 +4463,26 @@ static int stli_portcmdstats(stliport_t *portp)
  *     what port to get stats for (used through board control device).
  */
 
-static int stli_getportstats(stliport_t *portp, comstats_t *cp)
+static int stli_getportstats(stliport_t *portp, comstats_t __user *cp)
 {
-       stlibrd_t       *brdp;
-       int             rc;
+       stlibrd_t *brdp;
+       int rc;
 
-       if (portp == (stliport_t *) NULL) {
+       if (!portp) {
                if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t)))
                        return -EFAULT;
                portp = stli_getport(stli_comstats.brd, stli_comstats.panel,
                        stli_comstats.port);
-               if (portp == (stliport_t *) NULL)
-                       return(-ENODEV);
+               if (!portp)
+                       return -ENODEV;
        }
 
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(-ENODEV);
+       if (!brdp)
+               return -ENODEV;
 
        if ((rc = stli_portcmdstats(portp)) < 0)
-               return(rc);
+               return rc;
 
        return copy_to_user(cp, &stli_comstats, sizeof(comstats_t)) ?
                        -EFAULT : 0;
@@ -5093,27 +4494,27 @@ static int stli_getportstats(stliport_t *portp, comstats_t *cp)
  *     Clear the port stats structure. We also return it zeroed out...
  */
 
-static int stli_clrportstats(stliport_t *portp, comstats_t *cp)
+static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp)
 {
-       stlibrd_t       *brdp;
-       int             rc;
+       stlibrd_t *brdp;
+       int rc;
 
-       if (portp == (stliport_t *) NULL) {
+       if (!portp) {
                if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t)))
                        return -EFAULT;
                portp = stli_getport(stli_comstats.brd, stli_comstats.panel,
                        stli_comstats.port);
-               if (portp == (stliport_t *) NULL)
-                       return(-ENODEV);
+               if (!portp)
+                       return -ENODEV;
        }
 
        brdp = stli_brds[portp->brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(-ENODEV);
+       if (!brdp)
+               return -ENODEV;
 
        if (brdp->state & BST_STARTED) {
-               if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, 0, 0, 0)) < 0)
-                       return(rc);
+               if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, NULL, 0, 0)) < 0)
+                       return rc;
        }
 
        memset(&stli_comstats, 0, sizeof(comstats_t));
@@ -5123,7 +4524,7 @@ static int stli_clrportstats(stliport_t *portp, comstats_t *cp)
 
        if (copy_to_user(cp, &stli_comstats, sizeof(comstats_t)))
                return -EFAULT;
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -5132,19 +4533,19 @@ static int stli_clrportstats(stliport_t *portp, comstats_t *cp)
  *     Return the entire driver ports structure to a user app.
  */
 
-static int stli_getportstruct(unsigned long arg)
+static int stli_getportstruct(stliport_t __user *arg)
 {
-       stliport_t      *portp;
+       stliport_t *portp;
 
-       if (copy_from_user(&stli_dummyport, (void *)arg, sizeof(stliport_t)))
+       if (copy_from_user(&stli_dummyport, arg, sizeof(stliport_t)))
                return -EFAULT;
        portp = stli_getport(stli_dummyport.brdnr, stli_dummyport.panelnr,
                 stli_dummyport.portnr);
-       if (portp == (stliport_t *) NULL)
-               return(-ENODEV);
-       if (copy_to_user((void *) arg, portp, sizeof(stliport_t)))
+       if (!portp)
+               return -ENODEV;
+       if (copy_to_user(arg, portp, sizeof(stliport_t)))
                return -EFAULT;
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -5153,20 +4554,20 @@ static int stli_getportstruct(unsigned long arg)
  *     Return the entire driver board structure to a user app.
  */
 
-static int stli_getbrdstruct(unsigned long arg)
+static int stli_getbrdstruct(stlibrd_t __user *arg)
 {
-       stlibrd_t       *brdp;
+       stlibrd_t *brdp;
 
-       if (copy_from_user(&stli_dummybrd, (void *)arg, sizeof(stlibrd_t)))
+       if (copy_from_user(&stli_dummybrd, arg, sizeof(stlibrd_t)))
                return -EFAULT;
        if ((stli_dummybrd.brdnr < 0) || (stli_dummybrd.brdnr >= STL_MAXBRDS))
-               return(-ENODEV);
+               return -ENODEV;
        brdp = stli_brds[stli_dummybrd.brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(-ENODEV);
-       if (copy_to_user((void *) arg, brdp, sizeof(stlibrd_t)))
+       if (!brdp)
+               return -ENODEV;
+       if (copy_to_user(arg, brdp, sizeof(stlibrd_t)))
                return -EFAULT;
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -5179,13 +4580,9 @@ static int stli_getbrdstruct(unsigned long arg)
 
 static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
 {
-       stlibrd_t       *brdp;
-       int             brdnr, rc, done;
-
-#if DEBUG
-       printk(KERN_DEBUG "stli_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n",
-                       (int) ip, (int) fp, cmd, (int) arg);
-#endif
+       stlibrd_t *brdp;
+       int brdnr, rc, done;
+       void __user *argp = (void __user *)arg;
 
 /*
  *     First up handle the board independent ioctls.
@@ -5195,29 +4592,29 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un
 
        switch (cmd) {
        case COM_GETPORTSTATS:
-               rc = stli_getportstats((stliport_t *)NULL, (comstats_t *)arg);
+               rc = stli_getportstats(NULL, argp);
                done++;
                break;
        case COM_CLRPORTSTATS:
-               rc = stli_clrportstats((stliport_t *)NULL, (comstats_t *)arg);
+               rc = stli_clrportstats(NULL, argp);
                done++;
                break;
        case COM_GETBRDSTATS:
-               rc = stli_getbrdstats((combrd_t *) arg);
+               rc = stli_getbrdstats(argp);
                done++;
                break;
        case COM_READPORT:
-               rc = stli_getportstruct(arg);
+               rc = stli_getportstruct(argp);
                done++;
                break;
        case COM_READBOARD:
-               rc = stli_getbrdstruct(arg);
+               rc = stli_getbrdstruct(argp);
                done++;
                break;
        }
 
        if (done)
-               return(rc);
+               return rc;
 
 /*
  *     Now handle the board specific ioctls. These all depend on the
@@ -5225,12 +4622,12 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un
  */
        brdnr = iminor(ip);
        if (brdnr >= STL_MAXBRDS)
-               return(-ENODEV);
+               return -ENODEV;
        brdp = stli_brds[brdnr];
-       if (brdp == (stlibrd_t *) NULL)
-               return(-ENODEV);
+       if (!brdp)
+               return -ENODEV;
        if (brdp->state == 0)
-               return(-ENODEV);
+               return -ENODEV;
 
        switch (cmd) {
        case STL_BINTR:
@@ -5254,8 +4651,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un
                rc = -ENOIOCTLCMD;
                break;
        }
-
-       return(rc);
+       return rc;
 }
 
 static struct tty_operations stli_ops = {
@@ -5284,11 +4680,14 @@ static struct tty_operations stli_ops = {
 
 /*****************************************************************************/
 
-int __init stli_init(void)
+static int __init stli_init(void)
 {
        int i;
        printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion);
 
+       spin_lock_init(&stli_lock);
+       spin_lock_init(&brd_lock);
+
        stli_initbrds();
 
        stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
@@ -5298,12 +4697,8 @@ int __init stli_init(void)
 /*
  *     Allocate a temporary write buffer.
  */
-       stli_tmpwritebuf = (char *) stli_memalloc(STLI_TXBUFSIZE);
-       if (stli_tmpwritebuf == (char *) NULL)
-               printk(KERN_ERR "STALLION: failed to allocate memory "
-                               "(size=%d)\n", STLI_TXBUFSIZE);
-       stli_txcookbuf = stli_memalloc(STLI_TXBUFSIZE);
-       if (stli_txcookbuf == (char *) NULL)
+       stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);
+       if (!stli_txcookbuf)
                printk(KERN_ERR "STALLION: failed to allocate memory "
                                "(size=%d)\n", STLI_TXBUFSIZE);
 
@@ -5315,15 +4710,11 @@ int __init stli_init(void)
                printk(KERN_ERR "STALLION: failed to register serial memory "
                                "device\n");
 
-       devfs_mk_dir("staliomem");
-       istallion_class = class_simple_create(THIS_MODULE, "staliomem");
-       for (i = 0; i < 4; i++) {
-               devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
-                              S_IFCHR | S_IRUSR | S_IWUSR,
-                              "staliomem/%d", i);
-               class_simple_device_add(istallion_class, MKDEV(STL_SIOMEMMAJOR, i), 
+       istallion_class = class_create(THIS_MODULE, "staliomem");
+       for (i = 0; i < 4; i++)
+               class_device_create(istallion_class, NULL,
+                               MKDEV(STL_SIOMEMMAJOR, i),
                                NULL, "staliomem%d", i);
-       }
 
 /*
  *     Set up the tty driver structure and register us as a driver.
@@ -5344,7 +4735,7 @@ int __init stli_init(void)
                printk(KERN_ERR "STALLION: failed to register serial driver\n");
                return -EBUSY;
        }
-       return(0);
+       return 0;
 }
 
 /*****************************************************************************/