]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/staging/dgnc/dgnc_tty.c
Merge tag 'watchdog-for-linus-v4.10' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / drivers / staging / dgnc / dgnc_tty.c
index 4eeecc992a02e3e60492d807f082e6e304fe5877..1e10c0fe47453083012cd460dfbc764ac1d6c802 100644 (file)
  * PURPOSE.  See the GNU General Public License for more details.
  */
 
-/************************************************************************
- *
+/*
  * This file implements the tty driver functionality for the
  * Neo and ClassicBoard PCI based product lines.
- *
- ************************************************************************
- *
  */
 
 #include <linux/kernel.h>
 #include "dgnc_tty.h"
 #include "dgnc_neo.h"
 #include "dgnc_cls.h"
-#include "dgnc_sysfs.h"
 #include "dgnc_utils.h"
 
-/*
- * internal variables
- */
-static struct dgnc_board       *dgnc_BoardsByMajor[256];
-static unsigned char           *dgnc_TmpWriteBuf;
-
-/*
- * Default transparent print information.
- */
-static struct digi_t dgnc_digi_init = {
-       .digi_flags =   DIGI_COOK,      /* Flags                        */
-       .digi_maxcps =  100,            /* Max CPS                      */
-       .digi_maxchar = 50,             /* Max chars in print queue     */
-       .digi_bufsize = 100,            /* Printer buffer size          */
-       .digi_onlen =   4,              /* size of printer on string    */
-       .digi_offlen =  4,              /* size of printer off string   */
-       .digi_onstr =   "\033[5i",      /* ANSI printer on string ]     */
-       .digi_offstr =  "\033[4i",      /* ANSI printer off string ]    */
-       .digi_term =    "ansi"          /* default terminal type        */
+/* Default transparent print information. */
+
+static const struct digi_t dgnc_digi_init = {
+       .digi_flags =   DIGI_COOK,      /* Flags */
+       .digi_maxcps =  100,            /* Max CPS */
+       .digi_maxchar = 50,             /* Max chars in print queue */
+       .digi_bufsize = 100,            /* Printer buffer size */
+       .digi_onlen =   4,              /* size of printer on string */
+       .digi_offlen =  4,              /* size of printer off string */
+       .digi_onstr =   "\033[5i",      /* ANSI printer on string ] */
+       .digi_offstr =  "\033[4i",      /* ANSI printer off string ] */
+       .digi_term =    "ansi"          /* default terminal type */
 };
 
 /*
@@ -70,7 +58,7 @@ static struct digi_t dgnc_digi_init = {
  * This defines a raw port at 9600 baud, 8 data bits, no parity,
  * 1 stop bit.
  */
-static struct ktermios DgncDefaultTermios = {
+static struct ktermios default_termios = {
        .c_iflag =      (DEFAULT_IFLAGS),       /* iflags */
        .c_oflag =      (DEFAULT_OFLAGS),       /* oflags */
        .c_cflag =      (DEFAULT_CFLAGS),       /* cflags */
@@ -100,7 +88,7 @@ static void dgnc_tty_unthrottle(struct tty_struct *tty);
 static void dgnc_tty_flush_chars(struct tty_struct *tty);
 static void dgnc_tty_flush_buffer(struct tty_struct *tty);
 static void dgnc_tty_hangup(struct tty_struct *tty);
-static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command,
+static int dgnc_set_modem_info(struct channel_t *ch, unsigned int command,
                               unsigned int __user *value);
 static int dgnc_get_modem_info(struct channel_t *ch,
                               unsigned int __user *value);
@@ -114,6 +102,8 @@ static int dgnc_tty_write(struct tty_struct *tty, const unsigned char *buf,
 static void dgnc_tty_set_termios(struct tty_struct *tty,
                                 struct ktermios *old_termios);
 static void dgnc_tty_send_xchar(struct tty_struct *tty, char ch);
+static void dgnc_set_signal_low(struct channel_t *ch, const unsigned char line);
+static void dgnc_wake_up_unit(struct un_t *unit);
 
 static const struct tty_operations dgnc_tty_ops = {
        .open = dgnc_tty_open,
@@ -138,36 +128,7 @@ static const struct tty_operations dgnc_tty_ops = {
        .send_xchar = dgnc_tty_send_xchar
 };
 
-/************************************************************************
- *
- * TTY Initialization/Cleanup Functions
- *
- ************************************************************************/
-
-/*
- * dgnc_tty_preinit()
- *
- * Initialize any global tty related data before we download any boards.
- */
-int dgnc_tty_preinit(void)
-{
-       /*
-        * Allocate a buffer for doing the copy from user space to
-        * kernel space in dgnc_write().  We only use one buffer and
-        * control access to it with a semaphore.  If we are paging, we
-        * are already in trouble so one buffer won't hurt much anyway.
-        *
-        * We are okay to sleep in the malloc, as this routine
-        * is only called during module load, (not in interrupt context),
-        * and with no locks held.
-        */
-       dgnc_TmpWriteBuf = kmalloc(WRITEBUFLEN, GFP_KERNEL);
-
-       if (!dgnc_TmpWriteBuf)
-               return -ENOMEM;
-
-       return 0;
-}
+/* TTY Initialization/Cleanup Functions */
 
 /*
  * dgnc_tty_register()
@@ -186,7 +147,8 @@ int dgnc_tty_register(struct dgnc_board *brd)
        if (IS_ERR(brd->serial_driver))
                return PTR_ERR(brd->serial_driver);
 
-       snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgnc_%d_", brd->boardnum);
+       snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgnc_%d_",
+                brd->boardnum);
 
        brd->serial_driver->name = brd->serial_name;
        brd->serial_driver->name_base = 0;
@@ -194,7 +156,7 @@ int dgnc_tty_register(struct dgnc_board *brd)
        brd->serial_driver->minor_start = 0;
        brd->serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
        brd->serial_driver->subtype = SERIAL_TYPE_NORMAL;
-       brd->serial_driver->init_termios = DgncDefaultTermios;
+       brd->serial_driver->init_termios = default_termios;
        brd->serial_driver->driver_name = DRVSTR;
 
        /*
@@ -203,15 +165,11 @@ int dgnc_tty_register(struct dgnc_board *brd)
         */
        tty_set_operations(brd->serial_driver, &dgnc_tty_ops);
 
-       if (!brd->dgnc_major_serial_registered) {
-               /* Register tty devices */
-               rc = tty_register_driver(brd->serial_driver);
-               if (rc < 0) {
-                       dev_dbg(&brd->pdev->dev,
-                               "Can't register tty device (%d)\n", rc);
-                       goto free_serial_driver;
-               }
-               brd->dgnc_major_serial_registered = true;
+       rc = tty_register_driver(brd->serial_driver);
+       if (rc < 0) {
+               dev_dbg(&brd->pdev->dev,
+                       "Can't register tty device (%d)\n", rc);
+               goto free_serial_driver;
        }
 
        /*
@@ -237,7 +195,7 @@ int dgnc_tty_register(struct dgnc_board *brd)
        brd->print_driver->minor_start = 0x80;
        brd->print_driver->type = TTY_DRIVER_TYPE_SERIAL;
        brd->print_driver->subtype = SERIAL_TYPE_NORMAL;
-       brd->print_driver->init_termios = DgncDefaultTermios;
+       brd->print_driver->init_termios = default_termios;
        brd->print_driver->driver_name = DRVSTR;
 
        /*
@@ -246,20 +204,14 @@ int dgnc_tty_register(struct dgnc_board *brd)
         */
        tty_set_operations(brd->print_driver, &dgnc_tty_ops);
 
-       if (!brd->dgnc_major_transparent_print_registered) {
-               /* Register Transparent Print devices */
-               rc = tty_register_driver(brd->print_driver);
-               if (rc < 0) {
-                       dev_dbg(&brd->pdev->dev,
-                               "Can't register Transparent Print device(%d)\n",
-                               rc);
-                       goto free_print_driver;
-               }
-               brd->dgnc_major_transparent_print_registered = true;
+       rc = tty_register_driver(brd->print_driver);
+       if (rc < 0) {
+               dev_dbg(&brd->pdev->dev,
+                       "Can't register Transparent Print device(%d)\n",
+                       rc);
+               goto free_print_driver;
        }
 
-       dgnc_BoardsByMajor[brd->serial_driver->major] = brd;
-
        return 0;
 
 free_print_driver:
@@ -272,6 +224,14 @@ free_serial_driver:
        return rc;
 }
 
+void dgnc_tty_unregister(struct dgnc_board *brd)
+{
+       tty_unregister_driver(brd->print_driver);
+       tty_unregister_driver(brd->serial_driver);
+       put_tty_driver(brd->print_driver);
+       put_tty_driver(brd->serial_driver);
+}
+
 /*
  * dgnc_tty_init()
  *
@@ -287,9 +247,7 @@ int dgnc_tty_init(struct dgnc_board *brd)
        if (!brd)
                return -ENXIO;
 
-       /*
-        * Initialize board structure elements.
-        */
+       /* Initialize board structure elements. */
 
        vaddr = brd->re_map_membase;
 
@@ -347,12 +305,10 @@ int dgnc_tty_init(struct dgnc_board *brd)
                        classp = tty_register_device(brd->serial_driver, i,
                                                     &ch->ch_bd->pdev->dev);
                        ch->ch_tun.un_sysfs = classp;
-                       dgnc_create_tty_sysfs(&ch->ch_tun, classp);
 
                        classp = tty_register_device(brd->print_driver, i,
                                                     &ch->ch_bd->pdev->dev);
                        ch->ch_pun.un_sysfs = classp;
-                       dgnc_create_tty_sysfs(&ch->ch_pun, classp);
                }
        }
 
@@ -367,49 +323,24 @@ err_free_channels:
 }
 
 /*
- * dgnc_tty_post_uninit()
- *
- * UnInitialize any global tty related data.
- */
-void dgnc_tty_post_uninit(void)
-{
-       kfree(dgnc_TmpWriteBuf);
-       dgnc_TmpWriteBuf = NULL;
-}
-
-/*
- * dgnc_tty_uninit()
+ * dgnc_cleanup_tty()
  *
  * Uninitialize the TTY portion of this driver.  Free all memory and
  * resources.
  */
-void dgnc_tty_uninit(struct dgnc_board *brd)
+void dgnc_cleanup_tty(struct dgnc_board *brd)
 {
        int i = 0;
 
-       if (brd->dgnc_major_serial_registered) {
-               dgnc_BoardsByMajor[brd->serial_driver->major] = NULL;
-               for (i = 0; i < brd->nasync; i++) {
-                       if (brd->channels[i])
-                               dgnc_remove_tty_sysfs(brd->channels[i]->
-                                                     ch_tun.un_sysfs);
-                       tty_unregister_device(brd->serial_driver, i);
-               }
-               tty_unregister_driver(brd->serial_driver);
-               brd->dgnc_major_serial_registered = false;
-       }
+       for (i = 0; i < brd->nasync; i++)
+               tty_unregister_device(brd->serial_driver, i);
 
-       if (brd->dgnc_major_transparent_print_registered) {
-               dgnc_BoardsByMajor[brd->print_driver->major] = NULL;
-               for (i = 0; i < brd->nasync; i++) {
-                       if (brd->channels[i])
-                               dgnc_remove_tty_sysfs(brd->channels[i]->
-                                                     ch_pun.un_sysfs);
-                       tty_unregister_device(brd->print_driver, i);
-               }
-               tty_unregister_driver(brd->print_driver);
-               brd->dgnc_major_transparent_print_registered = false;
-       }
+       tty_unregister_driver(brd->serial_driver);
+
+       for (i = 0; i < brd->nasync; i++)
+               tty_unregister_device(brd->print_driver, i);
+
+       tty_unregister_driver(brd->print_driver);
 
        put_tty_driver(brd->serial_driver);
        put_tty_driver(brd->print_driver);
@@ -447,9 +378,7 @@ static void dgnc_wmove(struct channel_t *ch, char *buf, uint n)
        }
 
        if (n > 0) {
-               /*
-                * Move rest of data.
-                */
+               /* Move rest of data. */
                remain = n;
                memcpy(ch->ch_wqueue + head, buf, remain);
                head += remain;
@@ -519,9 +448,8 @@ void dgnc_input(struct channel_t *ch)
                goto exit_unlock;
        }
 
-       /*
-        * If we are throttled, simply don't read any data.
-        */
+       /* If we are throttled, simply don't read any data. */
+
        if (ch->ch_flags & CH_FORCED_STOPI)
                goto exit_unlock;
 
@@ -634,25 +562,18 @@ exit_unlock:
                tty_ldisc_deref(ld);
 }
 
-/************************************************************************
+/*
  * Determines when CARRIER changes state and takes appropriate
  * action.
- ************************************************************************/
+ */
 void dgnc_carrier(struct channel_t *ch)
 {
-       struct dgnc_board *bd;
-
        int virt_carrier = 0;
        int phys_carrier = 0;
 
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
                return;
 
-       bd = ch->ch_bd;
-
-       if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return;
-
        if (ch->ch_mistat & UART_MSR_DCD)
                phys_carrier = 1;
 
@@ -662,28 +583,24 @@ void dgnc_carrier(struct channel_t *ch)
        if (ch->ch_c_cflag & CLOCAL)
                virt_carrier = 1;
 
-       /*
-        * Test for a VIRTUAL carrier transition to HIGH.
-        */
+       /* Test for a VIRTUAL carrier transition to HIGH. */
+
        if (((ch->ch_flags & CH_FCAR) == 0) && (virt_carrier == 1)) {
                /*
                 * When carrier rises, wake any threads waiting
                 * for carrier in the open routine.
                 */
-
                if (waitqueue_active(&ch->ch_flags_wait))
                        wake_up_interruptible(&ch->ch_flags_wait);
        }
 
-       /*
-        * Test for a PHYSICAL carrier transition to HIGH.
-        */
+       /* Test for a PHYSICAL carrier transition to HIGH. */
+
        if (((ch->ch_flags & CH_CD) == 0) && (phys_carrier == 1)) {
                /*
                 * When carrier rises, wake any threads waiting
                 * for carrier in the open routine.
                 */
-
                if (waitqueue_active(&ch->ch_flags_wait))
                        wake_up_interruptible(&ch->ch_flags_wait);
        }
@@ -721,9 +638,8 @@ void dgnc_carrier(struct channel_t *ch)
                        tty_hangup(ch->ch_pun.un_tty);
        }
 
-       /*
-        *  Make sure that our cached values reflect the current reality.
-        */
+       /*  Make sure that our cached values reflect the current reality. */
+
        if (virt_carrier == 1)
                ch->ch_flags |= CH_FCAR;
        else
@@ -735,9 +651,8 @@ void dgnc_carrier(struct channel_t *ch)
                ch->ch_flags &= ~CH_CD;
 }
 
-/*
- *  Assign the custom baud rate to the channel structure
- */
+/*  Assign the custom baud rate to the channel structure */
+
 static void dgnc_set_custom_speed(struct channel_t *ch, uint newrate)
 {
        int testdiv;
@@ -871,6 +786,12 @@ void dgnc_check_queue_flow_control(struct channel_t *ch)
        }
 }
 
+static void dgnc_set_signal_low(struct channel_t *ch, const unsigned char sig)
+{
+       ch->ch_mostat &= ~(sig);
+       ch->ch_bd->bd_ops->assert_modem_signals(ch);
+}
+
 void dgnc_wakeup_writes(struct channel_t *ch)
 {
        int qlen = 0;
@@ -881,9 +802,8 @@ void dgnc_wakeup_writes(struct channel_t *ch)
 
        spin_lock_irqsave(&ch->ch_lock, flags);
 
-       /*
-        * If channel now has space, wake up anyone waiting on the condition.
-        */
+       /* If channel now has space, wake up anyone waiting on the condition. */
+
        qlen = ch->ch_w_head - ch->ch_w_tail;
        if (qlen < 0)
                qlen += WQUEUESIZE;
@@ -909,19 +829,15 @@ void dgnc_wakeup_writes(struct channel_t *ch)
                                 * If RTS Toggle mode is on, whenever
                                 * the queue and UART is empty, keep RTS low.
                                 */
-                               if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) {
-                                       ch->ch_mostat &= ~(UART_MCR_RTS);
-                                       ch->ch_bd->bd_ops->assert_modem_signals(ch);
-                               }
+                               if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)
+                                       dgnc_set_signal_low(ch, UART_MCR_RTS);
 
                                /*
                                 * If DTR Toggle mode is on, whenever
                                 * the queue and UART is empty, keep DTR low.
                                 */
-                               if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) {
-                                       ch->ch_mostat &= ~(UART_MCR_DTR);
-                                       ch->ch_bd->bd_ops->assert_modem_signals(ch);
-                               }
+                               if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE)
+                                       dgnc_set_signal_low(ch, UART_MCR_DTR);
                        }
                }
 
@@ -947,16 +863,28 @@ void dgnc_wakeup_writes(struct channel_t *ch)
        spin_unlock_irqrestore(&ch->ch_lock, flags);
 }
 
-/************************************************************************
- *
- * TTY Entry points and helper functions
- *
- ************************************************************************/
+static struct dgnc_board *find_board_by_major(unsigned int major)
+{
+       int i;
+
+       for (i = 0; i < MAXBOARDS; i++) {
+               struct dgnc_board *brd = dgnc_board[i];
+
+               if (!brd)
+                       return NULL;
+
+               if (major == brd->serial_driver->major ||
+                   major == brd->print_driver->major)
+                       return brd;
+       }
+
+       return NULL;
+}
+
+/* TTY Entry points and helper functions */
+
+/* dgnc_tty_open() */
 
-/*
- * dgnc_tty_open()
- *
- */
 static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
 {
        struct dgnc_board       *brd;
@@ -976,7 +904,7 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
                return -ENXIO;
 
        /* Get board pointer from our array of majors we have allocated */
-       brd = dgnc_BoardsByMajor[major];
+       brd = find_board_by_major(major);
        if (!brd)
                return -ENXIO;
 
@@ -1044,8 +972,8 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
         * ch_flags_wait to wake us back up.
         */
        rc = wait_event_interruptible(ch->ch_flags_wait,
-               (((ch->ch_tun.un_flags | ch->ch_pun.un_flags) &
-                 UN_CLOSING) == 0));
+                       (((ch->ch_tun.un_flags |
+                          ch->ch_pun.un_flags) & UN_CLOSING) == 0));
 
        /* If ret is non-zero, user ctrl-c'ed us */
        if (rc)
@@ -1056,9 +984,8 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
        /* Store our unit into driver_data, so we always have it available. */
        tty->driver_data = un;
 
-       /*
-        * Initialize tty's
-        */
+       /* Initialize tty's */
+
        if (!(un->un_flags & UN_ISOPEN)) {
                /* Store important variables. */
                un->un_tty     = tty;
@@ -1095,13 +1022,10 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
        ch->ch_flags &= ~(CH_OPENING);
        wake_up_interruptible(&ch->ch_flags_wait);
 
-       /*
-        * Initialize if neither terminal or printer is open.
-        */
+       /* Initialize if neither terminal or printer is open. */
+
        if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_ISOPEN)) {
-               /*
-                * Flush input queues.
-                */
+               /* Flush input queues. */
                ch->ch_r_head = 0;
                ch->ch_r_tail = 0;
                ch->ch_e_head = 0;
@@ -1137,16 +1061,13 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
                brd->bd_ops->uart_init(ch);
        }
 
-       /*
-        * Run param in case we changed anything
-        */
+       /* Run param in case we changed anything */
+
        brd->bd_ops->param(tty);
 
        dgnc_carrier(ch);
 
-       /*
-        * follow protocol for opening port
-        */
+       /* follow protocol for opening port */
 
        spin_unlock_irqrestore(&ch->ch_lock, flags);
 
@@ -1172,17 +1093,12 @@ static int dgnc_block_til_ready(struct tty_struct *tty,
                                struct channel_t *ch)
 {
        int retval = 0;
-       struct un_t *un = NULL;
+       struct un_t *un = tty->driver_data;
        unsigned long flags;
        uint    old_flags = 0;
        int     sleep_on_un_flags = 0;
 
-       if (!tty || tty->magic != TTY_MAGIC || !file || !ch ||
-           ch->magic != DGNC_CHANNEL_MAGIC)
-               return -ENXIO;
-
-       un = tty->driver_data;
-       if (!un || un->magic != DGNC_UNIT_MAGIC)
+       if (!file)
                return -ENXIO;
 
        spin_lock_irqsave(&ch->ch_lock, flags);
@@ -1252,9 +1168,8 @@ static int dgnc_block_til_ready(struct tty_struct *tty,
                        break;
                }
 
-               /*
-                * Store the flags before we let go of channel lock
-                */
+               /* Store the flags before we let go of channel lock */
+
                if (sleep_on_un_flags)
                        old_flags = ch->ch_tun.un_flags | ch->ch_pun.un_flags;
                else
@@ -1273,12 +1188,13 @@ static int dgnc_block_til_ready(struct tty_struct *tty,
                 * from the current value.
                 */
                if (sleep_on_un_flags)
-                       retval = wait_event_interruptible(un->un_flags_wait,
-                               (old_flags != (ch->ch_tun.un_flags |
-                                              ch->ch_pun.un_flags)));
+                       retval = wait_event_interruptible
+                               (un->un_flags_wait,
+                                (old_flags != (ch->ch_tun.un_flags |
+                                               ch->ch_pun.un_flags)));
                else
                        retval = wait_event_interruptible(ch->ch_flags_wait,
-                               (old_flags != ch->ch_flags));
+                                       (old_flags != ch->ch_flags));
 
                /*
                 * We got woken up for some reason.
@@ -1301,23 +1217,15 @@ static int dgnc_block_til_ready(struct tty_struct *tty,
  */
 static void dgnc_tty_hangup(struct tty_struct *tty)
 {
-       struct un_t     *un;
-
        if (!tty || tty->magic != TTY_MAGIC)
                return;
 
-       un = tty->driver_data;
-       if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return;
-
        /* flush the transmit queues */
        dgnc_tty_flush_buffer(tty);
 }
 
-/*
- * dgnc_tty_close()
- *
- */
+/* dgnc_tty_close() */
+
 static void dgnc_tty_close(struct tty_struct *tty, struct file *file)
 {
        struct dgnc_board *bd;
@@ -1387,9 +1295,8 @@ static void dgnc_tty_close(struct tty_struct *tty, struct file *file)
            !(ch->ch_digi.digi_flags & DIGI_PRINTER)) {
                ch->ch_flags &= ~(CH_STOPI | CH_FORCED_STOPI);
 
-               /*
-                * turn off print device when closing print device.
-                */
+               /* turn off print device when closing print device. */
+
                if ((un->un_type == DGNC_PRINT) && (ch->ch_flags & CH_PRON)) {
                        dgnc_wmove(ch, ch->ch_digi.digi_offstr,
                                   (int)ch->ch_digi.digi_offlen);
@@ -1409,9 +1316,8 @@ static void dgnc_tty_close(struct tty_struct *tty, struct file *file)
 
                tty->closing = 0;
 
-               /*
-                * If we have HUPCL set, lower DTR and RTS
-                */
+               /* If we have HUPCL set, lower DTR and RTS */
+
                if (ch->ch_c_cflag & HUPCL) {
                        /* Drop RTS/DTR */
                        ch->ch_mostat &= ~(UART_MCR_DTR | UART_MCR_RTS);
@@ -1434,9 +1340,8 @@ static void dgnc_tty_close(struct tty_struct *tty, struct file *file)
                /* Turn off UART interrupts for this port */
                ch->ch_bd->bd_ops->uart_off(ch);
        } else {
-               /*
-                * turn off print device when closing print device.
-                */
+               /* turn off print device when closing print device. */
+
                if ((un->un_type == DGNC_PRINT) && (ch->ch_flags & CH_PRON)) {
                        dgnc_wmove(ch, ch->ch_digi.digi_offstr,
                                   (int)ch->ch_digi.digi_offlen);
@@ -1510,18 +1415,8 @@ static int dgnc_tty_chars_in_buffer(struct tty_struct *tty)
  * returns the new bytes_available.  This only affects printer
  * output.
  */
-static int dgnc_maxcps_room(struct tty_struct *tty, int bytes_available)
+static int dgnc_maxcps_room(struct channel_t *ch, int bytes_available)
 {
-       struct un_t *un = tty->driver_data;
-       struct channel_t *ch = un->un_ch;
-
-       /*
-        * If its not the Transparent print device, return
-        * the full data amount.
-        */
-       if (un->un_type != DGNC_PRINT)
-               return bytes_available;
-
        if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0) {
                int cps_limit = 0;
                unsigned long current_time = jiffies;
@@ -1563,7 +1458,7 @@ static int dgnc_tty_write_room(struct tty_struct *tty)
        int ret = 0;
        unsigned long flags;
 
-       if (!tty || !dgnc_TmpWriteBuf)
+       if (!tty)
                return 0;
 
        un = tty->driver_data;
@@ -1585,7 +1480,8 @@ static int dgnc_tty_write_room(struct tty_struct *tty)
                ret += WQUEUESIZE;
 
        /* Limit printer to maxcps */
-       ret = dgnc_maxcps_room(tty, ret);
+       if (un->un_type != DGNC_PRINT)
+               ret = dgnc_maxcps_room(ch, ret);
 
        /*
         * If we are printer device, leave space for
@@ -1617,9 +1513,8 @@ static int dgnc_tty_write_room(struct tty_struct *tty)
  */
 static int dgnc_tty_put_char(struct tty_struct *tty, unsigned char c)
 {
-       /*
-        * Simply call tty_write.
-        */
+       /* Simply call tty_write. */
+
        dgnc_tty_write(tty, &c, 1);
        return 1;
 }
@@ -1642,7 +1537,7 @@ static int dgnc_tty_write(struct tty_struct *tty,
        ushort tmask;
        uint remain;
 
-       if (!tty || !dgnc_TmpWriteBuf)
+       if (!tty)
                return 0;
 
        un = tty->driver_data;
@@ -1677,7 +1572,8 @@ static int dgnc_tty_write(struct tty_struct *tty,
         * Limit printer output to maxcps overall, with bursts allowed
         * up to bufsize characters.
         */
-       bufcount = dgnc_maxcps_room(tty, bufcount);
+       if (un->un_type != DGNC_PRINT)
+               bufcount = dgnc_maxcps_room(ch, bufcount);
 
        /*
         * Take minimum of what the user wants to send, and the
@@ -1685,9 +1581,8 @@ static int dgnc_tty_write(struct tty_struct *tty,
         */
        count = min(count, bufcount);
 
-       /*
-        * Bail if no space left.
-        */
+       /* Bail if no space left. */
+
        if (count <= 0)
                goto exit_retry;
 
@@ -1730,9 +1625,7 @@ static int dgnc_tty_write(struct tty_struct *tty,
        }
 
        if (n > 0) {
-               /*
-                * Move rest of data.
-                */
+               /* Move rest of data. */
                remain = n;
                memcpy(ch->ch_wqueue + head, buf, remain);
                head += remain;
@@ -1767,9 +1660,7 @@ exit_retry:
        return 0;
 }
 
-/*
- * Return modem signals to ld.
- */
+/* Return modem signals to ld. */
 
 static int dgnc_tty_tiocmget(struct tty_struct *tty)
 {
@@ -1978,13 +1869,12 @@ static void dgnc_tty_send_xchar(struct tty_struct *tty, char c)
        dev_dbg(tty->dev, "dgnc_tty_send_xchar finish\n");
 }
 
-/*
- * Return modem signals to ld.
- */
+/* Return modem signals to ld. */
+
 static inline int dgnc_get_mstat(struct channel_t *ch)
 {
        unsigned char mstat;
-       int result = -EIO;
+       int result = 0;
        unsigned long flags;
 
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
@@ -1996,8 +1886,6 @@ static inline int dgnc_get_mstat(struct channel_t *ch)
 
        spin_unlock_irqrestore(&ch->ch_lock, flags);
 
-       result = 0;
-
        if (mstat & UART_MCR_DTR)
                result |= TIOCM_DTR;
        if (mstat & UART_MCR_RTS)
@@ -2014,9 +1902,8 @@ static inline int dgnc_get_mstat(struct channel_t *ch)
        return result;
 }
 
-/*
- * Return modem signals to ld.
- */
+/* Return modem signals to ld. */
+
 static int dgnc_get_modem_info(struct channel_t *ch,
                               unsigned int  __user *value)
 {
@@ -2028,32 +1915,14 @@ static int dgnc_get_modem_info(struct channel_t *ch,
  *
  * Set modem signals, called by ld.
  */
-static int dgnc_set_modem_info(struct tty_struct *tty,
+static int dgnc_set_modem_info(struct channel_t *ch,
                               unsigned int command,
                               unsigned int __user *value)
 {
-       struct dgnc_board *bd;
-       struct channel_t *ch;
-       struct un_t *un;
        int ret = -ENXIO;
        unsigned int arg = 0;
        unsigned long flags;
 
-       if (!tty || tty->magic != TTY_MAGIC)
-               return ret;
-
-       un = tty->driver_data;
-       if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return ret;
-
-       ch = un->un_ch;
-       if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return ret;
-
-       bd = ch->ch_bd;
-       if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return ret;
-
        ret = get_user(arg, value);
        if (ret)
                return ret;
@@ -2108,9 +1977,6 @@ static int dgnc_set_modem_info(struct tty_struct *tty,
  * dgnc_tty_digigeta()
  *
  * Ioctl to get the information for ditty.
- *
- *
- *
  */
 static int dgnc_tty_digigeta(struct tty_struct *tty,
                             struct digi_t __user *retinfo)
@@ -2150,9 +2016,6 @@ static int dgnc_tty_digigeta(struct tty_struct *tty,
  * dgnc_tty_digiseta()
  *
  * Ioctl to set the information for ditty.
- *
- *
- *
  */
 static int dgnc_tty_digiseta(struct tty_struct *tty,
                             struct digi_t __user *new_info)
@@ -2183,9 +2046,8 @@ static int dgnc_tty_digiseta(struct tty_struct *tty,
 
        spin_lock_irqsave(&ch->ch_lock, flags);
 
-       /*
-        * Handle transistions to and from RTS Toggle.
-        */
+       /* Handle transitions to and from RTS Toggle. */
+
        if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) &&
            (new_digi.digi_flags & DIGI_RTS_TOGGLE))
                ch->ch_mostat &= ~(UART_MCR_RTS);
@@ -2193,9 +2055,8 @@ static int dgnc_tty_digiseta(struct tty_struct *tty,
            !(new_digi.digi_flags & DIGI_RTS_TOGGLE))
                ch->ch_mostat |= (UART_MCR_RTS);
 
-       /*
-        * Handle transistions to and from DTR Toggle.
-        */
+       /* Handle transitions to and from DTR Toggle. */
+
        if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) &&
            (new_digi.digi_flags & DIGI_DTR_TOGGLE))
                ch->ch_mostat &= ~(UART_MCR_DTR);
@@ -2233,9 +2094,8 @@ static int dgnc_tty_digiseta(struct tty_struct *tty,
        return 0;
 }
 
-/*
- * dgnc_set_termios()
- */
+/* dgnc_set_termios() */
+
 static void dgnc_tty_set_termios(struct tty_struct *tty,
                                 struct ktermios *old_termios)
 {
@@ -2466,11 +2326,18 @@ static void dgnc_tty_flush_buffer(struct tty_struct *tty)
        spin_unlock_irqrestore(&ch->ch_lock, flags);
 }
 
-/*****************************************************************************
- *
- * The IOCTL function and all of its helpers
+/*
+ * dgnc_wake_up_unit()
  *
- *****************************************************************************/
+ * Wakes up processes waiting in the unit's (teminal/printer) wait queue
+ */
+static void dgnc_wake_up_unit(struct un_t *unit)
+{
+       unit->un_flags &= ~(UN_LOW | UN_EMPTY);
+       wake_up_interruptible(&unit->un_flags_wait);
+}
+
+/* The IOCTL function and all of its helpers */
 
 /*
  * dgnc_tty_ioctl()
@@ -2544,7 +2411,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                return 0;
 
        case TCSBRKP:
-               /* support for POSIX tcsendbreak()
+               /*
+                * support for POSIX tcsendbreak()
                 * According to POSIX.1 spec (7.2.2.1.2) breaks should be
                 * between 0.25 and 0.5 seconds so we'll ask for something
                 * in the middle: 0.375 seconds.
@@ -2593,9 +2461,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                spin_unlock_irqrestore(&ch->ch_lock, flags);
 
-               rc = put_user(C_CLOCAL(tty) ? 1 : 0,
-                             (unsigned long __user *)arg);
-               return rc;
+               return put_user(C_CLOCAL(tty) ? 1 : 0,
+                               (unsigned long __user *)arg);
 
        case TIOCSSOFTCAR:
 
@@ -2620,11 +2487,9 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
        case TIOCMBIC:
        case TIOCMSET:
                spin_unlock_irqrestore(&ch->ch_lock, flags);
-               return dgnc_set_modem_info(tty, cmd, uarg);
+               return dgnc_set_modem_info(ch, cmd, uarg);
 
-               /*
-                * Here are any additional ioctl's that we want to implement
-                */
+               /* Here are any additional ioctl's that we want to implement */
 
        case TCFLSH:
                /*
@@ -2654,17 +2519,11 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                                ch->ch_w_head = ch->ch_w_tail;
                                ch_bd_ops->flush_uart_write(ch);
 
-                               if (ch->ch_tun.un_flags & (UN_LOW | UN_EMPTY)) {
-                                       ch->ch_tun.un_flags &=
-                                               ~(UN_LOW | UN_EMPTY);
-                                       wake_up_interruptible(&ch->ch_tun.un_flags_wait);
-                               }
-
-                               if (ch->ch_pun.un_flags & (UN_LOW|UN_EMPTY)) {
-                                       ch->ch_pun.un_flags &=
-                                               ~(UN_LOW | UN_EMPTY);
-                                       wake_up_interruptible(&ch->ch_pun.un_flags_wait);
-                               }
+                               if (ch->ch_tun.un_flags & (UN_LOW | UN_EMPTY))
+                                       dgnc_wake_up_unit(&ch->ch_tun);
+
+                               if (ch->ch_pun.un_flags & (UN_LOW | UN_EMPTY))
+                                       dgnc_wake_up_unit(&ch->ch_pun);
                        }
                }
 
@@ -2744,9 +2603,10 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
        case DIGI_LOOPBACK:
                {
                        uint loopback = 0;
-                       /* Let go of locks when accessing user space,
+                       /*
+                        * Let go of locks when accessing user space,
                         * could sleep
-                       */
+                        */
                        spin_unlock_irqrestore(&ch->ch_lock, flags);
                        rc = get_user(loopback, (unsigned int __user *)arg);
                        if (rc)
@@ -2766,8 +2626,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
        case DIGI_GETCUSTOMBAUD:
                spin_unlock_irqrestore(&ch->ch_lock, flags);
-               rc = put_user(ch->ch_custom_speed, (unsigned int __user *)arg);
-               return rc;
+               return put_user(ch->ch_custom_speed,
+                               (unsigned int __user *)arg);
 
        case DIGI_SETCUSTOMBAUD:
        {
@@ -2788,7 +2648,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
         * This ioctl allows insertion of a character into the front
         * of any pending data to be transmitted.
         *
-        * This ioctl is to satify the "Send Character Immediate"
+        * This ioctl is to satisfy the "Send Character Immediate"
         * call that the RealPort protocol spec requires.
         */
        case DIGI_REALPORT_SENDIMMEDIATE:
@@ -2808,7 +2668,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
        /*
         * This ioctl returns all the current counts for the port.
         *
-        * This ioctl is to satify the "Line Error Counters"
+        * This ioctl is to satisfy the "Line Error Counters"
         * call that the RealPort protocol spec requires.
         */
        case DIGI_REALPORT_GETCOUNTERS:
@@ -2834,7 +2694,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
        /*
         * This ioctl returns all current events.
         *
-        * This ioctl is to satify the "Event Reporting"
+        * This ioctl is to satisfy the "Event Reporting"
         * call that the RealPort protocol spec requires.
         */
        case DIGI_REALPORT_GETEVENTS:
@@ -2853,8 +2713,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                        events |= (EV_IPU | EV_IPS);
 
                spin_unlock_irqrestore(&ch->ch_lock, flags);
-               rc = put_user(events, (unsigned int __user *)arg);
-               return rc;
+               return put_user(events, (unsigned int __user *)arg);
        }
 
        /*
@@ -2871,23 +2730,23 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                spin_unlock_irqrestore(&ch->ch_lock, flags);
 
-               /*
-                * Get data from user first.
-                */
+               /* Get data from user first. */
+
                if (copy_from_user(&buf, uarg, sizeof(buf)))
                        return -EFAULT;
 
                spin_lock_irqsave(&ch->ch_lock, flags);
 
-               /*
-                * Figure out how much data is in our RX and TX queues.
-                */
+               /* Figure out how much data is in our RX and TX queues. */
+
                buf.rxbuf = (ch->ch_r_head - ch->ch_r_tail) & RQUEUEMASK;
                buf.txbuf = (ch->ch_w_head - ch->ch_w_tail) & WQUEUEMASK;
 
                /*
-                * Is the UART empty? Add that value to whats in our TX queue.
+                * Is the UART empty?
+                * Add that value to whats in our TX queue.
                 */
+
                count = buf.txbuf + ch_bd_ops->get_uart_bytes_left(ch);
 
                /*
@@ -2907,9 +2766,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                if (buf.txbuf > tdist)
                        buf.txbuf = tdist;
 
-               /*
-                * Report whether our queue and UART TX are completely empty.
-                */
+               /* Report whether our queue and UART TX are completely empty. */
+
                if (count)
                        buf.txdone = 0;
                else