|
@@ -13,13 +13,9 @@
|
|
|
* 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>
|
|
@@ -42,19 +38,18 @@
|
|
|
#include "dgnc_sysfs.h"
|
|
|
#include "dgnc_utils.h"
|
|
|
|
|
|
-/*
|
|
|
- * Default transparent print information.
|
|
|
- */
|
|
|
+/* 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 */
|
|
|
+ .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 */
|
|
|
};
|
|
|
|
|
|
/*
|
|
@@ -132,11 +127,7 @@ static const struct tty_operations dgnc_tty_ops = {
|
|
|
.send_xchar = dgnc_tty_send_xchar
|
|
|
};
|
|
|
|
|
|
-/************************************************************************
|
|
|
- *
|
|
|
- * TTY Initialization/Cleanup Functions
|
|
|
- *
|
|
|
- ************************************************************************/
|
|
|
+/* TTY Initialization/Cleanup Functions */
|
|
|
|
|
|
/*
|
|
|
* dgnc_tty_register()
|
|
@@ -255,9 +246,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;
|
|
|
|
|
@@ -396,9 +385,9 @@ 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;
|
|
@@ -468,9 +457,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;
|
|
|
|
|
@@ -583,10 +571,10 @@ exit_unlock:
|
|
|
tty_ldisc_deref(ld);
|
|
|
}
|
|
|
|
|
|
-/************************************************************************
|
|
|
+/*
|
|
|
* Determines when CARRIER changes state and takes appropriate
|
|
|
* action.
|
|
|
- ************************************************************************/
|
|
|
+ */
|
|
|
void dgnc_carrier(struct channel_t *ch)
|
|
|
{
|
|
|
int virt_carrier = 0;
|
|
@@ -604,9 +592,8 @@ 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
|
|
@@ -617,9 +604,8 @@ void dgnc_carrier(struct channel_t *ch)
|
|
|
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
|
|
@@ -663,9 +649,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
|
|
@@ -677,9 +662,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;
|
|
@@ -823,9 +807,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;
|
|
@@ -907,16 +890,10 @@ static struct dgnc_board *find_board_by_major(unsigned int major)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-/************************************************************************
|
|
|
- *
|
|
|
- * TTY Entry points and helper functions
|
|
|
- *
|
|
|
- ************************************************************************/
|
|
|
+/* 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;
|
|
@@ -1015,9 +992,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;
|
|
@@ -1054,13 +1030,12 @@ 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;
|
|
@@ -1096,16 +1071,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);
|
|
|
|
|
@@ -1206,9 +1178,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
|
|
@@ -1262,10 +1233,8 @@ static void dgnc_tty_hangup(struct tty_struct *tty)
|
|
|
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;
|
|
@@ -1335,9 +1304,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);
|
|
@@ -1357,9 +1325,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);
|
|
@@ -1382,9 +1349,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);
|
|
@@ -1556,9 +1522,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;
|
|
|
}
|
|
@@ -1625,9 +1590,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;
|
|
|
|
|
@@ -1670,9 +1634,9 @@ 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;
|
|
@@ -1707,9 +1671,7 @@ exit_retry:
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Return modem signals to ld.
|
|
|
- */
|
|
|
+/* Return modem signals to ld. */
|
|
|
|
|
|
static int dgnc_tty_tiocmget(struct tty_struct *tty)
|
|
|
{
|
|
@@ -1918,9 +1880,8 @@ 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;
|
|
@@ -1952,9 +1913,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,9 +1988,6 @@ static int dgnc_set_modem_info(struct channel_t *ch,
|
|
|
* dgnc_tty_digigeta()
|
|
|
*
|
|
|
* Ioctl to get the information for ditty.
|
|
|
- *
|
|
|
- *
|
|
|
- *
|
|
|
*/
|
|
|
static int dgnc_tty_digigeta(struct tty_struct *tty,
|
|
|
struct digi_t __user *retinfo)
|
|
@@ -2070,9 +2027,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)
|
|
@@ -2103,9 +2057,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 transistions 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);
|
|
@@ -2113,9 +2066,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 transistions 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);
|
|
@@ -2153,9 +2105,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)
|
|
|
{
|
|
@@ -2386,11 +2337,7 @@ 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
|
|
|
- *
|
|
|
- *****************************************************************************/
|
|
|
+/* The IOCTL function and all of its helpers */
|
|
|
|
|
|
/*
|
|
|
* dgnc_tty_ioctl()
|
|
@@ -2464,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.
|
|
@@ -2541,9 +2489,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
|
|
|
spin_unlock_irqrestore(&ch->ch_lock, flags);
|
|
|
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:
|
|
|
/*
|
|
@@ -2663,7 +2609,8 @@ 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);
|
|
@@ -2789,23 +2736,20 @@ 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);
|
|
|
|
|
|
/*
|
|
@@ -2825,9 +2769,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
|