LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [RFT 1/9] Char: moxa, merge 2 poll functions
@ 2008-02-07 19:11 Jiri Slaby
2008-02-07 19:11 ` [RFT 2/9] Char: moxa, cleanup rx/tx Jiri Slaby
` (7 more replies)
0 siblings, 8 replies; 9+ messages in thread
From: Jiri Slaby @ 2008-02-07 19:11 UTC (permalink / raw)
To: Oyvind Aabling; +Cc: linux-kernel, Jiri Slaby
- merge 2 timers into one -- one can handle the emptywait as good as the other
- merge 2 separated poll functions into one, this allows handle the actions
directly and simplifies the code
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
drivers/char/moxa.c | 422 +++++++++++++++++----------------------------------
drivers/char/moxa.h | 10 +-
2 files changed, 142 insertions(+), 290 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index b61d14a..bdd5fd9 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -129,25 +129,22 @@ struct moxaq_str {
struct moxa_port {
struct moxa_board_conf *board;
+ struct tty_struct *tty;
+ void __iomem *tableAddr;
+
int type;
int close_delay;
int count;
int blocked_open;
int asyncflags;
- unsigned long statusflags;
- struct tty_struct *tty;
int cflag;
+ unsigned long statusflags;
wait_queue_head_t open_wait;
struct completion close_wait;
- struct timer_list emptyTimer;
-
- char lineCtrl;
- void __iomem *tableAddr;
- char DCDState;
- char lowChkFlag;
-
- ushort breakCnt;
+ u8 DCDState;
+ u8 lineCtrl;
+ u8 lowChkFlag;
};
struct mon_str {
@@ -169,6 +166,7 @@ struct mon_str {
static int ttymajor = MOXAMAJOR;
static struct mon_str moxaLog;
static unsigned int moxaFuncTout = HZ / 2;
+static unsigned int moxaLowWaterChk;
/* Variables for insmod */
#ifdef MODULE
static unsigned long baseaddr[MAX_BOARDS];
@@ -214,13 +212,10 @@ static void moxa_set_tty_param(struct tty_struct *, struct ktermios *);
static int moxa_block_till_ready(struct tty_struct *, struct file *,
struct moxa_port *);
static void moxa_setup_empty_event(struct tty_struct *);
-static void moxa_check_xmit_empty(unsigned long);
static void moxa_shut_down(struct moxa_port *);
-static void moxa_receive_data(struct moxa_port *);
/*
* moxa board interface functions:
*/
-static int MoxaDriverPoll(void);
static void MoxaPortEnable(struct moxa_port *);
static void MoxaPortDisable(struct moxa_port *);
static int MoxaPortSetTermio(struct moxa_port *, struct ktermios *, speed_t);
@@ -228,17 +223,14 @@ static int MoxaPortGetLineOut(struct moxa_port *, int *, int *);
static void MoxaPortLineCtrl(struct moxa_port *, int, int);
static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int);
static int MoxaPortLineStatus(struct moxa_port *);
-static int MoxaPortDCDChange(struct moxa_port *);
-static int MoxaPortDCDON(struct moxa_port *);
static void MoxaPortFlushData(struct moxa_port *, int);
static int MoxaPortWriteData(struct moxa_port *, unsigned char *, int);
-static int MoxaPortReadData(struct moxa_port *, struct tty_struct *tty);
+static int MoxaPortReadData(struct moxa_port *);
static int MoxaPortTxQueue(struct moxa_port *);
static int MoxaPortRxQueue(struct moxa_port *);
static int MoxaPortTxFree(struct moxa_port *);
static void MoxaPortTxDisable(struct moxa_port *);
static void MoxaPortTxEnable(struct moxa_port *);
-static int MoxaPortResetBrkCnt(struct moxa_port *);
static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *);
static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *);
static void MoxaSetFifo(struct moxa_port *port, int enable);
@@ -265,6 +257,20 @@ static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg)
moxa_wait_finish(ofsAddr);
}
+static void moxa_low_water_check(void __iomem *ofsAddr)
+{
+ u16 rptr, wptr, mask, len;
+
+ if (readb(ofsAddr + FlagStat) & Xoff_state) {
+ rptr = readw(ofsAddr + RXrptr);
+ wptr = readw(ofsAddr + RXwptr);
+ mask = readw(ofsAddr + RX_mask);
+ len = (wptr - rptr) & mask;
+ if (len <= Low_water)
+ moxafunc(ofsAddr, FC_SendXon, 0);
+ }
+}
+
/*
* TTY operations
*/
@@ -812,9 +818,6 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
init_waitqueue_head(&p->open_wait);
init_completion(&p->close_wait);
-
- setup_timer(&p->emptyTimer, moxa_check_xmit_empty,
- (unsigned long)p);
}
switch (brd->boardType) {
@@ -857,12 +860,9 @@ err:
static void moxa_board_deinit(struct moxa_board_conf *brd)
{
- unsigned int i;
-
+ spin_lock_bh(&moxa_lock);
brd->ready = 0;
- for (i = 0; i < MAX_PORTS_PER_BOARD; i++)
- del_timer_sync(&brd->ports[i].emptyTimer);
-
+ spin_unlock_bh(&moxa_lock);
iounmap(brd->basemem);
brd->basemem = NULL;
kfree(brd->ports);
@@ -1134,7 +1134,6 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
if (ch->asyncflags & ASYNC_INITIALIZED) {
moxa_setup_empty_event(tty);
tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
- del_timer_sync(&ch->emptyTimer);
}
moxa_shut_down(ch);
MoxaPortFlushData(ch, 2);
@@ -1159,15 +1158,14 @@ static int moxa_write(struct tty_struct *tty,
const unsigned char *buf, int count)
{
struct moxa_port *ch = tty->driver_data;
- unsigned long flags;
int len;
if (ch == NULL)
return 0;
- spin_lock_irqsave(&moxa_lock, flags);
+ spin_lock_bh(&moxa_lock);
len = MoxaPortWriteData(ch, (unsigned char *) buf, count);
- spin_unlock_irqrestore(&moxa_lock, flags);
+ spin_unlock_bh(&moxa_lock);
/*********************************************
if ( !(ch->statusflags & LOWWAIT) &&
@@ -1235,13 +1233,12 @@ static void moxa_flush_chars(struct tty_struct *tty)
static void moxa_put_char(struct tty_struct *tty, unsigned char c)
{
struct moxa_port *ch = tty->driver_data;
- unsigned long flags;
if (ch == NULL)
return;
- spin_lock_irqsave(&moxa_lock, flags);
+ spin_lock_bh(&moxa_lock);
MoxaPortWriteData(ch, &c, 1);
- spin_unlock_irqrestore(&moxa_lock, flags);
+ spin_unlock_bh(&moxa_lock);
/************************************************
if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) )
*************************************************/
@@ -1359,58 +1356,111 @@ static void moxa_hangup(struct tty_struct *tty)
wake_up_interruptible(&ch->open_wait);
}
-static void moxa_poll(unsigned long ignored)
+static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
{
- struct moxa_port *ch;
- struct tty_struct *tty;
- unsigned int card;
- int i;
+ dcd = !!dcd;
- del_timer(&moxaTimer);
+ if ((dcd != p->DCDState) && p->tty && C_CLOCAL(p->tty)) {
+ if (!dcd) {
+ tty_hangup(p->tty);
+ p->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
+ }
+ wake_up_interruptible(&p->open_wait);
+ }
+ p->DCDState = dcd;
+}
- if (MoxaDriverPoll() < 0) {
- mod_timer(&moxaTimer, jiffies + HZ / 50);
- return;
+static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
+ u16 __iomem *ip)
+{
+ struct tty_struct *tty = p->tty;
+ void __iomem *ofsAddr;
+ u16 intr;
+
+ if (tty) {
+ if ((p->statusflags & EMPTYWAIT) &&
+ MoxaPortTxQueue(p) == 0) {
+ p->statusflags &= ~EMPTYWAIT;
+ tty_wakeup(tty);
+ }
+ if ((p->statusflags & LOWWAIT) && !tty->stopped &&
+ MoxaPortTxQueue(p) <= WAKEUP_CHARS) {
+ p->statusflags &= ~LOWWAIT;
+ tty_wakeup(tty);
+ }
+ } else
+ p->statusflags &= ~EMPTYWAIT;
+
+ if (!handle) /* nothing to do */
+ return 0;
+
+ intr = readw(ip); /* port irq status */
+ if (intr == 0)
+ return 0;
+
+ writew(0, ip); /* ACK port */
+ ofsAddr = p->tableAddr;
+ if (intr & IntrTx) /* disable tx intr */
+ writew(readw(ofsAddr + HostStat) & ~WakeupTx,
+ ofsAddr + HostStat);
+
+ if ((p->asyncflags & ASYNC_INITIALIZED) == 0)
+ return 0;
+
+ if (!tty) { /* discard data, nobody wants them, catch dcd change */
+ MoxaPortFlushData(p, 0);
+ goto end;
+ }
+
+ if (!(p->statusflags & THROTTLE) && MoxaPortRxQueue(p) > 0) { /* RX */
+ MoxaPortReadData(p);
+ tty_schedule_flip(tty);
+ }
+
+ if ((intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */
+ tty_insert_flip_char(tty, 0, TTY_BREAK);
+ tty_schedule_flip(tty);
}
+end:
+ if (intr & IntrLine)
+ moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state);
+ return 0;
+}
+
+static void moxa_poll(unsigned long ignored)
+{
+ struct moxa_board_conf *brd;
+ u16 __iomem *ip;
+ unsigned int card, port;
+
+ spin_lock(&moxa_lock);
for (card = 0; card < MAX_BOARDS; card++) {
- if (!moxa_boards[card].ready)
+ brd = &moxa_boards[card];
+ if (!brd->ready)
continue;
- ch = moxa_boards[card].ports;
- for (i = 0; i < moxa_boards[card].numPorts; i++, ch++) {
- if ((ch->asyncflags & ASYNC_INITIALIZED) == 0)
- continue;
- if (!(ch->statusflags & THROTTLE) &&
- (MoxaPortRxQueue(ch) > 0))
- moxa_receive_data(ch);
- tty = ch->tty;
- if (tty == NULL)
- continue;
- if (ch->statusflags & LOWWAIT) {
- if (MoxaPortTxQueue(ch) <= WAKEUP_CHARS) {
- if (!tty->stopped) {
- ch->statusflags &= ~LOWWAIT;
- tty_wakeup(tty);
- }
- }
- }
- if (!I_IGNBRK(tty) && (MoxaPortResetBrkCnt(ch) > 0)) {
- tty_insert_flip_char(tty, 0, TTY_BREAK);
- tty_schedule_flip(tty);
- }
- if (MoxaPortDCDChange(ch)) {
- if (ch->asyncflags & ASYNC_CHECK_CD) {
- if (MoxaPortDCDON(ch))
- wake_up_interruptible(&ch->open_wait);
- else {
- tty_hangup(tty);
- wake_up_interruptible(&ch->open_wait);
- ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
- }
+
+ ip = NULL;
+ if (readb(brd->intPend) == 0xff)
+ ip = brd->intTable + readb(brd->intNdx);
+
+ for (port = 0; port < brd->numPorts; port++)
+ moxa_poll_port(&brd->ports[port], !!ip, ip + port);
+
+ if (ip)
+ writeb(0, brd->intPend); /* ACK */
+
+ if (moxaLowWaterChk) {
+ struct moxa_port *p = brd->ports;
+ for (port = 0; port < brd->numPorts; port++, p++)
+ if (p->lowChkFlag) {
+ p->lowChkFlag = 0;
+ moxa_low_water_check(p->tableAddr);
}
- }
}
}
+ moxaLowWaterChk = 0;
+ spin_unlock(&moxa_lock);
mod_timer(&moxaTimer, jiffies + HZ / 50);
}
@@ -1425,10 +1475,6 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term
ch = (struct moxa_port *) tty->driver_data;
ts = tty->termios;
- if (ts->c_cflag & CLOCAL)
- ch->asyncflags &= ~ASYNC_CHECK_CD;
- else
- ch->asyncflags |= ASYNC_CHECK_CD;
rts = cts = txflow = rxflow = xany = 0;
if (ts->c_cflag & CRTSCTS)
rts = cts = 1;
@@ -1453,7 +1499,6 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
struct moxa_port *ch)
{
DECLARE_WAITQUEUE(wait,current);
- unsigned long flags;
int retval;
int do_clocal = C_CLOCAL(tty);
@@ -1488,11 +1533,11 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
add_wait_queue(&ch->open_wait, &wait);
pr_debug("block_til_ready before block: ttys%d, count = %d\n",
tty->index, ch->count);
- spin_lock_irqsave(&moxa_lock, flags);
+ spin_lock_bh(&moxa_lock);
if (!tty_hung_up_p(filp))
ch->count--;
ch->blocked_open++;
- spin_unlock_irqrestore(&moxa_lock, flags);
+ spin_unlock_bh(&moxa_lock);
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
@@ -1509,7 +1554,7 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
break;
}
if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal ||
- MoxaPortDCDON(ch)))
+ ch->DCDState))
break;
if (signal_pending(current)) {
@@ -1521,11 +1566,11 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
set_current_state(TASK_RUNNING);
remove_wait_queue(&ch->open_wait, &wait);
- spin_lock_irqsave(&moxa_lock, flags);
+ spin_lock_bh(&moxa_lock);
if (!tty_hung_up_p(filp))
ch->count++;
ch->blocked_open--;
- spin_unlock_irqrestore(&moxa_lock, flags);
+ spin_unlock_bh(&moxa_lock);
pr_debug("block_til_ready after blocking: ttys%d, count = %d\n",
tty->index, ch->count);
if (retval)
@@ -1538,28 +1583,10 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
static void moxa_setup_empty_event(struct tty_struct *tty)
{
struct moxa_port *ch = tty->driver_data;
- unsigned long flags;
- spin_lock_irqsave(&moxa_lock, flags);
+ spin_lock_bh(&moxa_lock);
ch->statusflags |= EMPTYWAIT;
- mod_timer(&ch->emptyTimer, jiffies + HZ);
- spin_unlock_irqrestore(&moxa_lock, flags);
-}
-
-static void moxa_check_xmit_empty(unsigned long data)
-{
- struct moxa_port *ch;
-
- ch = (struct moxa_port *) data;
- if (ch->tty && (ch->statusflags & EMPTYWAIT)) {
- if (MoxaPortTxQueue(ch) == 0) {
- ch->statusflags &= ~EMPTYWAIT;
- tty_wakeup(ch->tty);
- return;
- }
- mod_timer(&ch->emptyTimer, round_jiffies(jiffies + HZ));
- } else
- ch->statusflags &= ~EMPTYWAIT;
+ spin_unlock_bh(&moxa_lock);
}
static void moxa_shut_down(struct moxa_port *ch)
@@ -1582,43 +1609,8 @@ static void moxa_shut_down(struct moxa_port *ch)
ch->asyncflags &= ~ASYNC_INITIALIZED;
}
-static void moxa_receive_data(struct moxa_port *ch)
-{
- struct tty_struct *tp;
- struct ktermios *ts;
- unsigned long flags;
-
- ts = NULL;
- tp = ch->tty;
- if (tp)
- ts = tp->termios;
- /**************************************************
- if ( !tp || !ts || !(ts->c_cflag & CREAD) ) {
- *****************************************************/
- if (!tp || !ts) {
- MoxaPortFlushData(ch, 0);
- return;
- }
- spin_lock_irqsave(&moxa_lock, flags);
- MoxaPortReadData(ch, tp);
- spin_unlock_irqrestore(&moxa_lock, flags);
- tty_schedule_flip(tp);
-}
-
-/*
- * Query
- */
-
-#define DCD_changed 0x01
-#define DCD_oldstate 0x80
-
-static int moxaLowWaterChk;
-
-static void moxa_low_water_check(void __iomem *);
-
/*****************************************************************************
* Driver level functions: *
- * 3. MoxaDriverPoll(void); *
*****************************************************************************/
static void MoxaPortFlushData(struct moxa_port *port, int mode)
@@ -1634,67 +1626,6 @@ static void MoxaPortFlushData(struct moxa_port *port, int mode)
}
}
-static int MoxaDriverPoll(void)
-{
- struct moxa_board_conf *brd;
- struct moxa_port *p;
- void __iomem *ofsAddr;
- void __iomem *ip;
- unsigned int port, ports, card;
- ushort temp;
-
- for (card = 0; card < MAX_BOARDS; card++) {
- brd = &moxa_boards[card];
- if (brd->ready == 0)
- continue;
- if ((ports = brd->numPorts) == 0)
- continue;
- if (readb(brd->intPend) == 0xff) {
- ip = brd->intTable + readb(brd->intNdx);
- p = brd->ports;
- ports <<= 1;
- for (port = 0; port < ports; port += 2, p++) {
- temp = readw(ip + port);
- if (temp == 0)
- continue;
-
- writew(0, ip + port);
- ofsAddr = p->tableAddr;
- if (temp & IntrTx)
- writew(readw(ofsAddr + HostStat) &
- ~WakeupTx, ofsAddr + HostStat);
- if (temp & IntrBreak)
- p->breakCnt++;
-
- if (temp & IntrLine) {
- if (readb(ofsAddr + FlagStat) & DCD_state) {
- if ((p->DCDState & DCD_oldstate) == 0)
- p->DCDState = (DCD_oldstate |
- DCD_changed);
- } else {
- if (p->DCDState & DCD_oldstate)
- p->DCDState = DCD_changed;
- }
- }
- }
- writeb(0, brd->intPend);
- }
- if (moxaLowWaterChk) {
- p = brd->ports;
- for (port = 0; port < ports; port++, p++) {
- if (p->lowChkFlag) {
- p->lowChkFlag = 0;
- ofsAddr = p->tableAddr;
- moxa_low_water_check(ofsAddr);
- }
- }
- }
- }
- moxaLowWaterChk = 0;
-
- return 0;
-}
-
/*****************************************************************************
* Port level functions: *
* 2. MoxaPortEnable(int port); *
@@ -1706,8 +1637,6 @@ static int MoxaDriverPoll(void)
* 10. MoxaPortLineCtrl(int port, int dtrState, int rtsState); *
* 11. MoxaPortFlowCtrl(int port, int rts, int cts, int rx, int tx,int xany); *
* 12. MoxaPortLineStatus(int port); *
- * 13. MoxaPortDCDChange(int port); *
- * 14. MoxaPortDCDON(int port); *
* 15. MoxaPortFlushData(int port, int mode); *
* 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); *
* 17. MoxaPortReadData(int port, struct tty_struct *tty); *
@@ -1754,14 +1683,6 @@ static int MoxaDriverPoll(void)
* -ENOIOCTLCMD
*
*
- * Function 3: Moxa driver polling process routine.
- * Syntax:
- * int MoxaDriverPoll(void);
- *
- * return: 0 ; polling O.K.
- * -1 : no any Moxa card.
- *
- *
* Function 6: Enable this port to start Tx/Rx data.
* Syntax:
* void MoxaPortEnable(int port);
@@ -1852,25 +1773,6 @@ static int MoxaDriverPoll(void)
* Bit 2 - DCD state (0: off, 1: on)
*
*
- * Function 17: Check the DCD state has changed since the last read
- * of this function.
- * Syntax:
- * int MoxaPortDCDChange(int port);
- * int port : port number (0 - 127)
- *
- * return: 0 : no changed
- * 1 : DCD has changed
- *
- *
- * Function 18: Check ths current DCD state is ON or not.
- * Syntax:
- * int MoxaPortDCDON(int port);
- * int port : port number (0 - 127)
- *
- * return: 0 : DCD off
- * 1 : DCD on
- *
- *
* Function 19: Flush the Rx/Tx buffer data of this port.
* Syntax:
* void MoxaPortFlushData(int port, int mode);
@@ -1953,7 +1855,6 @@ static void MoxaPortEnable(struct moxa_port *port)
ofsAddr = port->tableAddr;
writew(lowwater, ofsAddr + Low_water);
- port->breakCnt = 0;
if (port->board->boardType == MOXA_BOARD_C320_ISA ||
port->board->boardType == MOXA_BOARD_C320_PCI) {
moxafunc(ofsAddr, FC_SetBreakIrq, 0);
@@ -2122,37 +2023,11 @@ static int MoxaPortLineStatus(struct moxa_port *port)
val = readw(ofsAddr + FlagStat) >> 4;
}
val &= 0x0B;
- if (val & 8) {
+ if (val & 8)
val |= 4;
- if ((port->DCDState & DCD_oldstate) == 0)
- port->DCDState = (DCD_oldstate | DCD_changed);
- } else {
- if (port->DCDState & DCD_oldstate)
- port->DCDState = DCD_changed;
- }
+ moxa_new_dcdstate(port, val & 8);
val &= 7;
- return (val);
-}
-
-static int MoxaPortDCDChange(struct moxa_port *port)
-{
- int n;
-
- n = port->DCDState;
- port->DCDState &= ~DCD_changed;
- n &= DCD_changed;
- return (n);
-}
-
-static int MoxaPortDCDON(struct moxa_port *port)
-{
- int n;
-
- if (port->DCDState & DCD_oldstate)
- n = 1;
- else
- n = 0;
- return (n);
+ return val;
}
static int MoxaPortWriteData(struct moxa_port *port, unsigned char *buffer,
@@ -2220,8 +2095,9 @@ static int MoxaPortWriteData(struct moxa_port *port, unsigned char *buffer,
return (total);
}
-static int MoxaPortReadData(struct moxa_port *port, struct tty_struct *tty)
+static int MoxaPortReadData(struct moxa_port *port)
{
+ struct tty_struct *tty = port->tty;
register ushort head, pageofs;
int i, count, cnt, len, total, remain;
ushort tail, rx_mask, spage, epage;
@@ -2242,7 +2118,7 @@ static int MoxaPortReadData(struct moxa_port *port, struct tty_struct *tty)
total = count;
remain = count - total;
- moxaLog.rxcnt[port->tty->index] += total;
+ moxaLog.rxcnt[tty->index] += total;
count = total;
if (spage == epage) {
bufhead = readw(ofsAddr + Ofs_rxb);
@@ -2340,15 +2216,6 @@ static void MoxaPortTxEnable(struct moxa_port *port)
moxafunc(port->tableAddr, FC_SetXonState, Magic_code);
}
-
-static int MoxaPortResetBrkCnt(struct moxa_port *port)
-{
- ushort cnt;
- cnt = port->breakCnt;
- port->breakCnt = 0;
- return (cnt);
-}
-
static int moxa_get_serial_info(struct moxa_port *info,
struct serial_struct __user *retinfo)
{
@@ -2412,21 +2279,6 @@ static int moxa_set_serial_info(struct moxa_port *info,
* Static local functions: *
*****************************************************************************/
-static void moxa_low_water_check(void __iomem *ofsAddr)
-{
- int len;
- ushort rptr, wptr, mask;
-
- if (readb(ofsAddr + FlagStat) & Xoff_state) {
- rptr = readw(ofsAddr + RXrptr);
- wptr = readw(ofsAddr + RXwptr);
- mask = readw(ofsAddr + RX_mask);
- len = (wptr - rptr) & mask;
- if (len <= Low_water)
- moxafunc(ofsAddr, FC_SendXon, 0);
- }
-}
-
static void MoxaSetFifo(struct moxa_port *port, int enable)
{
void __iomem *ofsAddr = port->tableAddr;
diff --git a/drivers/char/moxa.h b/drivers/char/moxa.h
index 49e926d..0b16506 100644
--- a/drivers/char/moxa.h
+++ b/drivers/char/moxa.h
@@ -165,11 +165,11 @@
#define HostStat 0x08 /* IRQ flag and general flag */
#define FlagStat 0x0A
#define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */
- /* x x x x | | | | */
- /* | | | + CTS flow */
- /* | | +--- RTS flow */
- /* | +------ TX Xon/Xoff */
- /* +--------- RX Xon/Xoff */
+ /* x x x x | | | | */
+ /* | | | + CTS flow */
+ /* | | +--- RTS flow */
+ /* | +------ TX Xon/Xoff */
+ /* +--------- RX Xon/Xoff */
#define Break_cnt 0x0E /* received break count */
#define CD180TXirq 0x10 /* if non-0: enable TX irq */
#define RX_mask 0x12
--
1.5.3.8
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFT 2/9] Char: moxa, cleanup rx/tx
2008-02-07 19:11 [RFT 1/9] Char: moxa, merge 2 poll functions Jiri Slaby
@ 2008-02-07 19:11 ` Jiri Slaby
2008-02-07 19:11 ` [RFT 3/9] Char: moxa, serialise timer Jiri Slaby
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Jiri Slaby @ 2008-02-07 19:11 UTC (permalink / raw)
To: Oyvind Aabling; +Cc: linux-kernel, Jiri Slaby
- cleanup types
- use tty_prepare_flip_string and io memcpys
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
drivers/char/moxa.c | 124 ++++++++++++++++++++------------------------------
drivers/char/moxa.h | 2 +-
2 files changed, 51 insertions(+), 75 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index bdd5fd9..f45405f 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -224,7 +224,7 @@ static void MoxaPortLineCtrl(struct moxa_port *, int, int);
static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int);
static int MoxaPortLineStatus(struct moxa_port *);
static void MoxaPortFlushData(struct moxa_port *, int);
-static int MoxaPortWriteData(struct moxa_port *, unsigned char *, int);
+static int MoxaPortWriteData(struct moxa_port *, const unsigned char *, int);
static int MoxaPortReadData(struct moxa_port *);
static int MoxaPortTxQueue(struct moxa_port *);
static int MoxaPortRxQueue(struct moxa_port *);
@@ -1164,7 +1164,7 @@ static int moxa_write(struct tty_struct *tty,
return 0;
spin_lock_bh(&moxa_lock);
- len = MoxaPortWriteData(ch, (unsigned char *) buf, count);
+ len = MoxaPortWriteData(ch, buf, count);
spin_unlock_bh(&moxa_lock);
/*********************************************
@@ -2030,15 +2030,13 @@ static int MoxaPortLineStatus(struct moxa_port *port)
return val;
}
-static int MoxaPortWriteData(struct moxa_port *port, unsigned char *buffer,
- int len)
+static int MoxaPortWriteData(struct moxa_port *port,
+ const unsigned char *buffer, int len)
{
- int c, total, i;
- ushort tail;
- int cnt;
- ushort head, tx_mask, spage, epage;
- ushort pageno, pageofs, bufhead;
void __iomem *baseAddr, *ofsAddr, *ofs;
+ unsigned int c, total;
+ u16 head, tail, tx_mask, spage, epage;
+ u16 pageno, pageofs, bufhead;
ofsAddr = port->tableAddr;
baseAddr = port->board->basemem;
@@ -2047,8 +2045,7 @@ static int MoxaPortWriteData(struct moxa_port *port, unsigned char *buffer,
epage = readw(ofsAddr + EndPage_txb);
tail = readw(ofsAddr + TXwptr);
head = readw(ofsAddr + TXrptr);
- c = (head > tail) ? (head - tail - 1)
- : (head - tail + tx_mask);
+ c = (head > tail) ? (head - tail - 1) : (head - tail + tx_mask);
if (c > len)
c = len;
moxaLog.txcnt[port->tty->index] += c;
@@ -2063,46 +2060,42 @@ static int MoxaPortWriteData(struct moxa_port *port, unsigned char *buffer,
len = tx_mask + 1 - tail;
len = (c > len) ? len : c;
ofs = baseAddr + DynPage_addr + bufhead + tail;
- for (i = 0; i < len; i++)
- writeb(*buffer++, ofs + i);
+ memcpy_toio(ofs, buffer, len);
+ buffer += len;
tail = (tail + len) & tx_mask;
c -= len;
}
- writew(tail, ofsAddr + TXwptr);
} else {
- len = c;
pageno = spage + (tail >> 13);
pageofs = tail & Page_mask;
- do {
- cnt = Page_size - pageofs;
- if (cnt > c)
- cnt = c;
- c -= cnt;
+ while (c > 0) {
+ len = Page_size - pageofs;
+ if (len > c)
+ len = c;
writeb(pageno, baseAddr + Control_reg);
ofs = baseAddr + DynPage_addr + pageofs;
- for (i = 0; i < cnt; i++)
- writeb(*buffer++, ofs + i);
- if (c == 0) {
- writew((tail + len) & tx_mask, ofsAddr + TXwptr);
- break;
- }
+ memcpy_toio(ofs, buffer, len);
+ buffer += len;
if (++pageno == epage)
pageno = spage;
pageofs = 0;
- } while (1);
+ c -= len;
+ }
+ tail = (tail + total) & tx_mask;
}
+ writew(tail, ofsAddr + TXwptr);
writeb(1, ofsAddr + CD180TXirq); /* start to send */
- return (total);
+ return total;
}
static int MoxaPortReadData(struct moxa_port *port)
{
struct tty_struct *tty = port->tty;
- register ushort head, pageofs;
- int i, count, cnt, len, total, remain;
- ushort tail, rx_mask, spage, epage;
- ushort pageno, bufhead;
+ unsigned char *dst;
void __iomem *baseAddr, *ofsAddr, *ofs;
+ unsigned int count, len, total;
+ u16 tail, rx_mask, spage, epage;
+ u16 pageno, pageofs, bufhead, head;
ofsAddr = port->tableAddr;
baseAddr = port->board->basemem;
@@ -2111,101 +2104,84 @@ static int MoxaPortReadData(struct moxa_port *port)
rx_mask = readw(ofsAddr + RX_mask);
spage = readw(ofsAddr + Page_rxb);
epage = readw(ofsAddr + EndPage_rxb);
- count = (tail >= head) ? (tail - head)
- : (tail - head + rx_mask + 1);
+ count = (tail >= head) ? (tail - head) : (tail - head + rx_mask + 1);
if (count == 0)
return 0;
total = count;
- remain = count - total;
moxaLog.rxcnt[tty->index] += total;
- count = total;
if (spage == epage) {
bufhead = readw(ofsAddr + Ofs_rxb);
writew(spage, baseAddr + Control_reg);
while (count > 0) {
- if (tail >= head)
- len = tail - head;
- else
- len = rx_mask + 1 - head;
- len = (count > len) ? len : count;
ofs = baseAddr + DynPage_addr + bufhead + head;
- for (i = 0; i < len; i++)
- tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL);
+ len = (tail >= head) ? (tail - head) :
+ (rx_mask + 1 - head);
+ len = tty_prepare_flip_string(tty, &dst,
+ min(len, count));
+ memcpy_fromio(dst, ofs, len);
head = (head + len) & rx_mask;
count -= len;
}
- writew(head, ofsAddr + RXrptr);
} else {
- len = count;
pageno = spage + (head >> 13);
pageofs = head & Page_mask;
- do {
- cnt = Page_size - pageofs;
- if (cnt > count)
- cnt = count;
- count -= cnt;
+ while (count > 0) {
writew(pageno, baseAddr + Control_reg);
ofs = baseAddr + DynPage_addr + pageofs;
- for (i = 0; i < cnt; i++)
- tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL);
- if (count == 0) {
- writew((head + len) & rx_mask, ofsAddr + RXrptr);
- break;
- }
- if (++pageno == epage)
+ len = tty_prepare_flip_string(tty, &dst,
+ min(Page_size - pageofs, count));
+ memcpy_fromio(dst, ofs, len);
+
+ count -= len;
+ pageofs = (pageofs + len) & Page_mask;
+ if (pageofs == 0 && ++pageno == epage)
pageno = spage;
- pageofs = 0;
- } while (1);
+ }
+ head = (head + total) & rx_mask;
}
- if ((readb(ofsAddr + FlagStat) & Xoff_state) && (remain < LowWater)) {
+ writew(head, ofsAddr + RXrptr);
+ if (readb(ofsAddr + FlagStat) & Xoff_state) {
moxaLowWaterChk = 1;
port->lowChkFlag = 1;
}
- return (total);
+ return total;
}
static int MoxaPortTxQueue(struct moxa_port *port)
{
void __iomem *ofsAddr = port->tableAddr;
- ushort rptr, wptr, mask;
- int len;
+ u16 rptr, wptr, mask;
rptr = readw(ofsAddr + TXrptr);
wptr = readw(ofsAddr + TXwptr);
mask = readw(ofsAddr + TX_mask);
- len = (wptr - rptr) & mask;
- return (len);
+ return (wptr - rptr) & mask;
}
static int MoxaPortTxFree(struct moxa_port *port)
{
void __iomem *ofsAddr = port->tableAddr;
- ushort rptr, wptr, mask;
- int len;
+ u16 rptr, wptr, mask;
rptr = readw(ofsAddr + TXrptr);
wptr = readw(ofsAddr + TXwptr);
mask = readw(ofsAddr + TX_mask);
- len = mask - ((wptr - rptr) & mask);
- return (len);
+ return mask - ((wptr - rptr) & mask);
}
static int MoxaPortRxQueue(struct moxa_port *port)
{
void __iomem *ofsAddr = port->tableAddr;
- ushort rptr, wptr, mask;
- int len;
+ u16 rptr, wptr, mask;
rptr = readw(ofsAddr + RXrptr);
wptr = readw(ofsAddr + RXwptr);
mask = readw(ofsAddr + RX_mask);
- len = (wptr - rptr) & mask;
- return (len);
+ return (wptr - rptr) & mask;
}
-
static void MoxaPortTxDisable(struct moxa_port *port)
{
moxafunc(port->tableAddr, FC_SetXoffState, Magic_code);
diff --git a/drivers/char/moxa.h b/drivers/char/moxa.h
index 0b16506..87d16ce 100644
--- a/drivers/char/moxa.h
+++ b/drivers/char/moxa.h
@@ -217,7 +217,7 @@
#define C320p32rx_mask (C320p32rx_size - 1)
#define C320p32tx_mask (C320p32tx_size - 1)
-#define Page_size 0x2000
+#define Page_size 0x2000U
#define Page_mask (Page_size - 1)
#define C218rx_spage 3
#define C218tx_spage 4
--
1.5.3.8
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFT 3/9] Char: moxa, serialise timer
2008-02-07 19:11 [RFT 1/9] Char: moxa, merge 2 poll functions Jiri Slaby
2008-02-07 19:11 ` [RFT 2/9] Char: moxa, cleanup rx/tx Jiri Slaby
@ 2008-02-07 19:11 ` Jiri Slaby
2008-02-07 19:11 ` [RFT 4/9] Char: moxa, rework open/close Jiri Slaby
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Jiri Slaby @ 2008-02-07 19:11 UTC (permalink / raw)
To: Oyvind Aabling; +Cc: linux-kernel, Jiri Slaby
- del timer after we are sure it won't be fired again
- make timer scheduling atomic
- don't reschedule timer when all cards have gone
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
drivers/char/moxa.c | 26 +++++++++++++++-----------
1 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index f45405f..eabb2e0 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -846,10 +846,11 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
if (ret)
goto err_free;
+ spin_lock_bh(&moxa_lock);
brd->ready = 1;
-
if (!timer_pending(&moxaTimer))
mod_timer(&moxaTimer, jiffies + HZ / 50);
+ spin_unlock_bh(&moxa_lock);
return 0;
err_free:
@@ -1040,13 +1041,6 @@ static void __exit moxa_exit(void)
{
int i;
- del_timer_sync(&moxaTimer);
-
- if (tty_unregister_driver(moxaDriver))
- printk(KERN_ERR "Couldn't unregister MOXA Intellio family "
- "serial driver\n");
- put_tty_driver(moxaDriver);
-
#ifdef CONFIG_PCI
pci_unregister_driver(&moxa_pci_driver);
#endif
@@ -1054,6 +1048,13 @@ static void __exit moxa_exit(void)
for (i = 0; i < MAX_BOARDS; i++) /* ISA boards */
if (moxa_boards[i].ready)
moxa_board_deinit(&moxa_boards[i]);
+
+ del_timer_sync(&moxaTimer);
+
+ if (tty_unregister_driver(moxaDriver))
+ printk(KERN_ERR "Couldn't unregister MOXA Intellio family "
+ "serial driver\n");
+ put_tty_driver(moxaDriver);
}
module_init(moxa_init);
@@ -1432,7 +1433,7 @@ static void moxa_poll(unsigned long ignored)
{
struct moxa_board_conf *brd;
u16 __iomem *ip;
- unsigned int card, port;
+ unsigned int card, port, served = 0;
spin_lock(&moxa_lock);
for (card = 0; card < MAX_BOARDS; card++) {
@@ -1440,6 +1441,8 @@ static void moxa_poll(unsigned long ignored)
if (!brd->ready)
continue;
+ served++;
+
ip = NULL;
if (readb(brd->intPend) == 0xff)
ip = brd->intTable + readb(brd->intNdx);
@@ -1460,9 +1463,10 @@ static void moxa_poll(unsigned long ignored)
}
}
moxaLowWaterChk = 0;
- spin_unlock(&moxa_lock);
- mod_timer(&moxaTimer, jiffies + HZ / 50);
+ if (served)
+ mod_timer(&moxaTimer, jiffies + HZ / 50);
+ spin_unlock(&moxa_lock);
}
/******************************************************************************/
--
1.5.3.8
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFT 4/9] Char: moxa, rework open/close
2008-02-07 19:11 [RFT 1/9] Char: moxa, merge 2 poll functions Jiri Slaby
2008-02-07 19:11 ` [RFT 2/9] Char: moxa, cleanup rx/tx Jiri Slaby
2008-02-07 19:11 ` [RFT 3/9] Char: moxa, serialise timer Jiri Slaby
@ 2008-02-07 19:11 ` Jiri Slaby
2008-02-07 19:11 ` [RFT 5/9] Char: moxa, little cleanup Jiri Slaby
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Jiri Slaby @ 2008-02-07 19:11 UTC (permalink / raw)
To: Oyvind Aabling; +Cc: linux-kernel, Jiri Slaby
- add locking to open/close/hangup
- add pci hot-un-plug support (hangup on board remove, wait for openers)
- cleanup block_till_ready
- move close code common to close/hangup into separate function to be
able to call it from open when hangup occurs while block_till_ready
- let ldisc flush on tty layer, it will do it after we return
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
drivers/char/moxa.c | 239 +++++++++++++++++++++------------------------------
1 files changed, 97 insertions(+), 142 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index eabb2e0..5a55b8c 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -42,7 +42,6 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/bitops.h>
-#include <linux/completion.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -134,13 +133,11 @@ struct moxa_port {
int type;
int close_delay;
- int count;
- int blocked_open;
+ unsigned int count;
int asyncflags;
int cflag;
unsigned long statusflags;
wait_queue_head_t open_wait;
- struct completion close_wait;
u8 DCDState;
u8 lineCtrl;
@@ -167,6 +164,7 @@ static int ttymajor = MOXAMAJOR;
static struct mon_str moxaLog;
static unsigned int moxaFuncTout = HZ / 2;
static unsigned int moxaLowWaterChk;
+static DEFINE_MUTEX(moxa_openlock);
/* Variables for insmod */
#ifdef MODULE
static unsigned long baseaddr[MAX_BOARDS];
@@ -209,8 +207,6 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
static void moxa_poll(unsigned long);
static void moxa_set_tty_param(struct tty_struct *, struct ktermios *);
-static int moxa_block_till_ready(struct tty_struct *, struct file *,
- struct moxa_port *);
static void moxa_setup_empty_event(struct tty_struct *);
static void moxa_shut_down(struct moxa_port *);
/*
@@ -817,7 +813,6 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
p->close_delay = 5 * HZ / 10;
p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
init_waitqueue_head(&p->open_wait);
- init_completion(&p->close_wait);
}
switch (brd->boardType) {
@@ -861,9 +856,30 @@ err:
static void moxa_board_deinit(struct moxa_board_conf *brd)
{
+ unsigned int a, opened;
+
+ mutex_lock(&moxa_openlock);
spin_lock_bh(&moxa_lock);
brd->ready = 0;
spin_unlock_bh(&moxa_lock);
+
+ /* pci hot-un-plug support */
+ for (a = 0; a < brd->numPorts; a++)
+ if (brd->ports[a].asyncflags & ASYNC_NORMAL_ACTIVE)
+ tty_hangup(brd->ports[a].tty);
+ while (1) {
+ opened = 0;
+ for (a = 0; a < brd->numPorts; a++)
+ if (brd->ports[a].asyncflags & ASYNC_NORMAL_ACTIVE)
+ opened++;
+ mutex_unlock(&moxa_openlock);
+ if (!opened)
+ break;
+ set_task_state(current, TASK_UNINTERRUPTIBLE);
+ schedule_timeout(msecs_to_jiffies(50));
+ mutex_lock(&moxa_openlock);
+ }
+
iounmap(brd->basemem);
brd->basemem = NULL;
kfree(brd->ports);
@@ -1060,6 +1076,44 @@ static void __exit moxa_exit(void)
module_init(moxa_init);
module_exit(moxa_exit);
+static void moxa_close_port(struct moxa_port *ch)
+{
+ moxa_shut_down(ch);
+ MoxaPortFlushData(ch, 2);
+ ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
+ ch->tty = NULL;
+}
+
+static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
+ struct moxa_port *ch)
+{
+ DEFINE_WAIT(wait);
+ int retval = 0;
+
+ while (1) {
+ prepare_to_wait(&ch->open_wait, &wait, TASK_INTERRUPTIBLE);
+ if (tty_hung_up_p(filp)) {
+#ifdef SERIAL_DO_RESTART
+ retval = -ERESTARTSYS;
+#else
+ retval = -EAGAIN;
+#endif
+ break;
+ }
+ if (ch->DCDState)
+ break;
+
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ break;
+ }
+ schedule();
+ }
+ finish_wait(&ch->open_wait, &wait);
+
+ return retval;
+}
+
static int moxa_open(struct tty_struct *tty, struct file *filp)
{
struct moxa_board_conf *brd;
@@ -1071,9 +1125,13 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
if (port == MAX_PORTS) {
return capable(CAP_SYS_ADMIN) ? 0 : -EPERM;
}
+ if (mutex_lock_interruptible(&moxa_openlock))
+ return -ERESTARTSYS;
brd = &moxa_boards[port / MAX_PORTS_PER_BOARD];
- if (!brd->ready)
+ if (!brd->ready) {
+ mutex_unlock(&moxa_openlock);
return -ENODEV;
+ }
ch = &brd->ports[port % MAX_PORTS_PER_BOARD];
ch->count++;
@@ -1084,39 +1142,37 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
moxa_set_tty_param(tty, tty->termios);
MoxaPortLineCtrl(ch, 1, 1);
MoxaPortEnable(ch);
+ MoxaSetFifo(ch, ch->type == PORT_16550A);
ch->asyncflags |= ASYNC_INITIALIZED;
}
- retval = moxa_block_till_ready(tty, filp, ch);
-
- moxa_unthrottle(tty);
+ mutex_unlock(&moxa_openlock);
- if (ch->type == PORT_16550A) {
- MoxaSetFifo(ch, 1);
- } else {
- MoxaSetFifo(ch, 0);
- }
+ retval = 0;
+ if (!(filp->f_flags & O_NONBLOCK) && !C_CLOCAL(tty))
+ retval = moxa_block_till_ready(tty, filp, ch);
+ mutex_lock(&moxa_openlock);
+ if (retval) {
+ if (ch->count) /* 0 means already hung up... */
+ if (--ch->count == 0)
+ moxa_close_port(ch);
+ } else
+ ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
+ mutex_unlock(&moxa_openlock);
- return (retval);
+ return retval;
}
static void moxa_close(struct tty_struct *tty, struct file *filp)
{
- struct moxa_port *ch;
+ struct moxa_port *ch = tty->driver_data;
int port;
port = tty->index;
- if (port == MAX_PORTS) {
- return;
- }
- if (tty->driver_data == NULL) {
+ if (port == MAX_PORTS || ch == NULL || tty_hung_up_p(filp))
return;
- }
- if (tty_hung_up_p(filp)) {
- return;
- }
- ch = (struct moxa_port *) tty->driver_data;
- if ((tty->count == 1) && (ch->count != 1)) {
+ mutex_lock(&moxa_openlock);
+ if (tty->count == 1 && ch->count != 1) {
printk(KERN_WARNING "moxa_close: bad serial port count; "
"tty->count is 1, ch->count is %d\n", ch->count);
ch->count = 1;
@@ -1127,32 +1183,18 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
ch->count = 0;
}
if (ch->count) {
+ mutex_unlock(&moxa_openlock);
return;
}
- ch->asyncflags |= ASYNC_CLOSING;
ch->cflag = tty->termios->c_cflag;
if (ch->asyncflags & ASYNC_INITIALIZED) {
moxa_setup_empty_event(tty);
tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
}
- moxa_shut_down(ch);
- MoxaPortFlushData(ch, 2);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
- tty_ldisc_flush(tty);
-
- tty->closing = 0;
- ch->tty = NULL;
- if (ch->blocked_open) {
- if (ch->close_delay) {
- msleep_interruptible(jiffies_to_msecs(ch->close_delay));
- }
- wake_up_interruptible(&ch->open_wait);
- }
- ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
- complete_all(&ch->close_wait);
+ moxa_close_port(ch);
+ mutex_unlock(&moxa_openlock);
}
static int moxa_write(struct tty_struct *tty,
@@ -1347,13 +1389,13 @@ static void moxa_start(struct tty_struct *tty)
static void moxa_hangup(struct tty_struct *tty)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
+ struct moxa_port *ch = tty->driver_data;
- moxa_flush_buffer(tty);
- moxa_shut_down(ch);
+ mutex_lock(&moxa_openlock);
ch->count = 0;
- ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
- ch->tty = NULL;
+ moxa_close_port(ch);
+ mutex_unlock(&moxa_openlock);
+
wake_up_interruptible(&ch->open_wait);
}
@@ -1362,10 +1404,8 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
dcd = !!dcd;
if ((dcd != p->DCDState) && p->tty && C_CLOCAL(p->tty)) {
- if (!dcd) {
+ if (!dcd)
tty_hangup(p->tty);
- p->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
- }
wake_up_interruptible(&p->open_wait);
}
p->DCDState = dcd;
@@ -1499,91 +1539,6 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term
tty_encode_baud_rate(tty, baud, baud);
}
-static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
- struct moxa_port *ch)
-{
- DECLARE_WAITQUEUE(wait,current);
- int retval;
- int do_clocal = C_CLOCAL(tty);
-
- /*
- * If the device is in the middle of being closed, then block
- * until it's done, and then try again.
- */
- if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) {
- if (ch->asyncflags & ASYNC_CLOSING)
- wait_for_completion_interruptible(&ch->close_wait);
-#ifdef SERIAL_DO_RESTART
- if (ch->asyncflags & ASYNC_HUP_NOTIFY)
- return (-EAGAIN);
- else
- return (-ERESTARTSYS);
-#else
- return (-EAGAIN);
-#endif
- }
- /*
- * If non-blocking mode is set, then make the check up front
- * and then exit.
- */
- if (filp->f_flags & O_NONBLOCK) {
- ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
- return (0);
- }
- /*
- * Block waiting for the carrier detect and the line to become free
- */
- retval = 0;
- add_wait_queue(&ch->open_wait, &wait);
- pr_debug("block_til_ready before block: ttys%d, count = %d\n",
- tty->index, ch->count);
- spin_lock_bh(&moxa_lock);
- if (!tty_hung_up_p(filp))
- ch->count--;
- ch->blocked_open++;
- spin_unlock_bh(&moxa_lock);
-
- while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) ||
- !(ch->asyncflags & ASYNC_INITIALIZED)) {
-#ifdef SERIAL_DO_RESTART
- if (ch->asyncflags & ASYNC_HUP_NOTIFY)
- retval = -EAGAIN;
- else
- retval = -ERESTARTSYS;
-#else
- retval = -EAGAIN;
-#endif
- break;
- }
- if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal ||
- ch->DCDState))
- break;
-
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
- schedule();
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&ch->open_wait, &wait);
-
- spin_lock_bh(&moxa_lock);
- if (!tty_hung_up_p(filp))
- ch->count++;
- ch->blocked_open--;
- spin_unlock_bh(&moxa_lock);
- pr_debug("block_til_ready after blocking: ttys%d, count = %d\n",
- tty->index, ch->count);
- if (retval)
- return (retval);
- /* FIXME: review to see if we need to use set_bit on these */
- ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
- return 0;
-}
-
static void moxa_setup_empty_event(struct tty_struct *tty)
{
struct moxa_port *ch = tty->driver_data;
@@ -1595,22 +1550,22 @@ static void moxa_setup_empty_event(struct tty_struct *tty)
static void moxa_shut_down(struct moxa_port *ch)
{
- struct tty_struct *tp;
+ struct tty_struct *tp = ch->tty;
if (!(ch->asyncflags & ASYNC_INITIALIZED))
return;
- tp = ch->tty;
-
MoxaPortDisable(ch);
/*
* If we're a modem control device and HUPCL is on, drop RTS & DTR.
*/
- if (tp->termios->c_cflag & HUPCL)
+ if (C_HUPCL(tp))
MoxaPortLineCtrl(ch, 0, 0);
+ spin_lock_bh(&moxa_lock);
ch->asyncflags &= ~ASYNC_INITIALIZED;
+ spin_unlock_bh(&moxa_lock);
}
/*****************************************************************************
--
1.5.3.8
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFT 5/9] Char: moxa, little cleanup
2008-02-07 19:11 [RFT 1/9] Char: moxa, merge 2 poll functions Jiri Slaby
` (2 preceding siblings ...)
2008-02-07 19:11 ` [RFT 4/9] Char: moxa, rework open/close Jiri Slaby
@ 2008-02-07 19:11 ` Jiri Slaby
2008-02-07 19:11 ` [RFT 6/9] Char: moxa, remove useless tty functions Jiri Slaby
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Jiri Slaby @ 2008-02-07 19:11 UTC (permalink / raw)
To: Oyvind Aabling; +Cc: linux-kernel, Jiri Slaby
Cleanup of
- whitespace
- macros
- useless casts
- return (sth); -> return sth;
- types
- superfluous parenthesis and braces
- init tmp directly in moxa_get_serial_info
- commented defunct code
- commented prototypes
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
drivers/char/moxa.c | 158 ++++++++++++++++++---------------------------------
1 files changed, 55 insertions(+), 103 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 5a55b8c..d123827 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -54,7 +54,6 @@
#define MOXA_FW_HDRLEN 32
#define MOXAMAJOR 172
-#define MOXACUMAJOR 173
#define MAX_BOARDS 4 /* Don't change this value */
#define MAX_PORTS_PER_BOARD 32 /* Don't change this value */
@@ -246,7 +245,7 @@ static void moxa_wait_finish(void __iomem *ofsAddr)
printk(KERN_WARNING "moxa function expired\n");
}
-static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg)
+static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg)
{
writew(arg, ofsAddr + FuncArg);
writew(cmd, ofsAddr + FuncCode);
@@ -947,7 +946,7 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, board);
- return (0);
+ return 0;
err_base:
iounmap(board->basemem);
board->basemem = NULL;
@@ -998,10 +997,8 @@ static int __init moxa_init(void)
moxaDriver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(moxaDriver, &moxa_ops);
- pr_debug("Moxa tty devices major number = %d\n", ttymajor);
-
if (tty_register_driver(moxaDriver)) {
- printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n");
+ printk(KERN_ERR "can't register MOXA Smartio tty driver!\n");
put_tty_driver(moxaDriver);
return -1;
}
@@ -1055,7 +1052,7 @@ static int __init moxa_init(void)
static void __exit moxa_exit(void)
{
- int i;
+ unsigned int i;
#ifdef CONFIG_PCI
pci_unregister_driver(&moxa_pci_driver);
@@ -1210,12 +1207,8 @@ static int moxa_write(struct tty_struct *tty,
len = MoxaPortWriteData(ch, buf, count);
spin_unlock_bh(&moxa_lock);
- /*********************************************
- if ( !(ch->statusflags & LOWWAIT) &&
- ((len != count) || (MoxaPortTxFree(port) <= 100)) )
- ************************************************/
ch->statusflags |= LOWWAIT;
- return (len);
+ return len;
}
static int moxa_write_room(struct tty_struct *tty)
@@ -1223,10 +1216,10 @@ static int moxa_write_room(struct tty_struct *tty)
struct moxa_port *ch;
if (tty->stopped)
- return (0);
+ return 0;
ch = tty->driver_data;
if (ch == NULL)
- return (0);
+ return 0;
return MoxaPortTxFree(ch);
}
@@ -1252,7 +1245,7 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
* routine. And since the open() failed, we return 0 here. TDJ
*/
if (ch == NULL)
- return (0);
+ return 0;
chars = MoxaPortTxQueue(ch);
if (chars) {
/*
@@ -1262,7 +1255,7 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
if (!(ch->statusflags & EMPTYWAIT))
moxa_setup_empty_event(tty);
}
- return (chars);
+ return chars;
}
static void moxa_flush_chars(struct tty_struct *tty)
@@ -1282,9 +1275,7 @@ static void moxa_put_char(struct tty_struct *tty, unsigned char c)
spin_lock_bh(&moxa_lock);
MoxaPortWriteData(ch, &c, 1);
spin_unlock_bh(&moxa_lock);
- /************************************************
- if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) )
- *************************************************/
+
ch->statusflags |= LOWWAIT;
}
@@ -1337,34 +1328,33 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
static void moxa_throttle(struct tty_struct *tty)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
+ struct moxa_port *ch = tty->driver_data;
ch->statusflags |= THROTTLE;
}
static void moxa_unthrottle(struct tty_struct *tty)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
+ struct moxa_port *ch = tty->driver_data;
ch->statusflags &= ~THROTTLE;
}
static void moxa_set_termios(struct tty_struct *tty,
- struct ktermios *old_termios)
+ struct ktermios *old_termios)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
+ struct moxa_port *ch = tty->driver_data;
if (ch == NULL)
return;
moxa_set_tty_param(tty, old_termios);
- if (!(old_termios->c_cflag & CLOCAL) &&
- (tty->termios->c_cflag & CLOCAL))
+ if (!(old_termios->c_cflag & CLOCAL) && C_CLOCAL(tty))
wake_up_interruptible(&ch->open_wait);
}
static void moxa_stop(struct tty_struct *tty)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
+ struct moxa_port *ch = tty->driver_data;
if (ch == NULL)
return;
@@ -1375,7 +1365,7 @@ static void moxa_stop(struct tty_struct *tty)
static void moxa_start(struct tty_struct *tty)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
+ struct moxa_port *ch = tty->driver_data;
if (ch == NULL)
return;
@@ -1403,7 +1393,7 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
{
dcd = !!dcd;
- if ((dcd != p->DCDState) && p->tty && C_CLOCAL(p->tty)) {
+ if (dcd != p->DCDState && p->tty && C_CLOCAL(p->tty)) {
if (!dcd)
tty_hangup(p->tty);
wake_up_interruptible(&p->open_wait);
@@ -1513,12 +1503,10 @@ static void moxa_poll(unsigned long ignored)
static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_termios)
{
- register struct ktermios *ts;
- struct moxa_port *ch;
+ register struct ktermios *ts = tty->termios;
+ struct moxa_port *ch = tty->driver_data;
int rts, cts, txflow, rxflow, xany, baud;
- ch = (struct moxa_port *) tty->driver_data;
- ts = tty->termios;
rts = cts = txflow = rxflow = xany = 0;
if (ts->c_cflag & CRTSCTS)
rts = cts = 1;
@@ -1575,7 +1563,7 @@ static void moxa_shut_down(struct moxa_port *ch)
static void MoxaPortFlushData(struct moxa_port *port, int mode)
{
void __iomem *ofsAddr;
- if ((mode < 0) || (mode > 2))
+ if (mode < 0 || mode > 2)
return;
ofsAddr = port->tableAddr;
moxafunc(ofsAddr, FC_FlushQueue, mode);
@@ -1585,27 +1573,6 @@ static void MoxaPortFlushData(struct moxa_port *port, int mode)
}
}
-/*****************************************************************************
- * Port level functions: *
- * 2. MoxaPortEnable(int port); *
- * 3. MoxaPortDisable(int port); *
- * 4. MoxaPortGetMaxBaud(int port); *
- * 6. MoxaPortSetBaud(int port, long baud); *
- * 8. MoxaPortSetTermio(int port, unsigned char *termio); *
- * 9. MoxaPortGetLineOut(int port, int *dtrState, int *rtsState); *
- * 10. MoxaPortLineCtrl(int port, int dtrState, int rtsState); *
- * 11. MoxaPortFlowCtrl(int port, int rts, int cts, int rx, int tx,int xany); *
- * 12. MoxaPortLineStatus(int port); *
- * 15. MoxaPortFlushData(int port, int mode); *
- * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); *
- * 17. MoxaPortReadData(int port, struct tty_struct *tty); *
- * 20. MoxaPortTxQueue(int port); *
- * 21. MoxaPortTxFree(int port); *
- * 22. MoxaPortRxQueue(int port); *
- * 24. MoxaPortTxDisable(int port); *
- * 25. MoxaPortTxEnable(int port); *
- * 27. MoxaPortResetBrkCnt(int port); *
- *****************************************************************************/
/*
* Moxa Port Number Description:
*
@@ -1810,16 +1777,16 @@ static void MoxaPortFlushData(struct moxa_port *port, int mode)
static void MoxaPortEnable(struct moxa_port *port)
{
void __iomem *ofsAddr;
- short lowwater = 512;
+ u16 lowwater = 512;
ofsAddr = port->tableAddr;
writew(lowwater, ofsAddr + Low_water);
if (port->board->boardType == MOXA_BOARD_C320_ISA ||
- port->board->boardType == MOXA_BOARD_C320_PCI) {
+ port->board->boardType == MOXA_BOARD_C320_PCI)
moxafunc(ofsAddr, FC_SetBreakIrq, 0);
- } else {
- writew(readw(ofsAddr + HostStat) | WakeupBreak, ofsAddr + HostStat);
- }
+ else
+ writew(readw(ofsAddr + HostStat) | WakeupBreak,
+ ofsAddr + HostStat);
moxafunc(ofsAddr, FC_SetLineIrq, Magic_code);
moxafunc(ofsAddr, FC_FlushQueue, 2);
@@ -1842,9 +1809,9 @@ static long MoxaPortGetMaxBaud(struct moxa_port *port)
{
if (port->board->boardType == MOXA_BOARD_C320_ISA ||
port->board->boardType == MOXA_BOARD_C320_PCI)
- return (460800L);
+ return 460800L;
else
- return (921600L);
+ return 921600L;
}
@@ -1854,8 +1821,8 @@ static long MoxaPortSetBaud(struct moxa_port *port, long baud)
long max, clock;
unsigned int val;
- if ((baud < 50L) || ((max = MoxaPortGetMaxBaud(port)) == 0))
- return (0);
+ if (baud < 50L || (max = MoxaPortGetMaxBaud(port)) == 0)
+ return 0;
ofsAddr = port->tableAddr;
if (baud > max)
baud = max;
@@ -1868,7 +1835,7 @@ static long MoxaPortSetBaud(struct moxa_port *port, long baud)
val = clock / baud;
moxafunc(ofsAddr, FC_SetBaud, val);
baud = clock / val;
- return (baud);
+ return baud;
}
static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
@@ -1907,12 +1874,12 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
} else
mode |= MX_PARNONE;
- moxafunc(ofsAddr, FC_SetDataMode, (ushort) mode);
+ moxafunc(ofsAddr, FC_SetDataMode, (u16)mode);
if (port->board->boardType == MOXA_BOARD_C320_ISA ||
port->board->boardType == MOXA_BOARD_C320_PCI) {
if (baud >= 921600L)
- return (-1);
+ return -1;
}
baud = MoxaPortSetBaud(port, baud);
@@ -1923,24 +1890,23 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
moxa_wait_finish(ofsAddr);
}
- return (baud);
+ return baud;
}
static int MoxaPortGetLineOut(struct moxa_port *port, int *dtrState,
int *rtsState)
{
-
if (dtrState)
*dtrState = !!(port->lineCtrl & DTR_ON);
if (rtsState)
*rtsState = !!(port->lineCtrl & RTS_ON);
- return (0);
+ return 0;
}
static void MoxaPortLineCtrl(struct moxa_port *port, int dtr, int rts)
{
- int mode = 0;
+ u8 mode = 0;
if (dtr)
mode |= DTR_ON;
@@ -2152,60 +2118,46 @@ static void MoxaPortTxEnable(struct moxa_port *port)
}
static int moxa_get_serial_info(struct moxa_port *info,
- struct serial_struct __user *retinfo)
+ struct serial_struct __user *retinfo)
{
- struct serial_struct tmp;
-
- memset(&tmp, 0, sizeof(tmp));
- tmp.type = info->type;
- tmp.line = info->tty->index;
- tmp.port = 0;
- tmp.irq = 0;
- tmp.flags = info->asyncflags;
- tmp.baud_base = 921600;
- tmp.close_delay = info->close_delay;
- tmp.custom_divisor = 0;
- tmp.hub6 = 0;
- if(copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
- return -EFAULT;
- return (0);
+ struct serial_struct tmp = {
+ .type = info->type,
+ .line = info->tty->index,
+ .flags = info->asyncflags,
+ .baud_base = 921600,
+ .close_delay = info->close_delay
+ };
+ return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
}
static int moxa_set_serial_info(struct moxa_port *info,
- struct serial_struct __user *new_info)
+ struct serial_struct __user *new_info)
{
struct serial_struct new_serial;
- if(copy_from_user(&new_serial, new_info, sizeof(new_serial)))
+ if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
return -EFAULT;
- if ((new_serial.irq != 0) ||
- (new_serial.port != 0) ||
-// (new_serial.type != info->type) ||
- (new_serial.custom_divisor != 0) ||
- (new_serial.baud_base != 921600))
- return (-EPERM);
+ if (new_serial.irq != 0 || new_serial.port != 0 ||
+ new_serial.custom_divisor != 0 ||
+ new_serial.baud_base != 921600)
+ return -EPERM;
if (!capable(CAP_SYS_ADMIN)) {
if (((new_serial.flags & ~ASYNC_USR_MASK) !=
(info->asyncflags & ~ASYNC_USR_MASK)))
- return (-EPERM);
- } else {
+ return -EPERM;
+ } else
info->close_delay = new_serial.close_delay * HZ / 100;
- }
new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS);
new_serial.flags |= (info->asyncflags & ASYNC_FLAGS);
- if (new_serial.type == PORT_16550A) {
- MoxaSetFifo(info, 1);
- } else {
- MoxaSetFifo(info, 0);
- }
+ MoxaSetFifo(info, new_serial.type == PORT_16550A);
info->type = new_serial.type;
- return (0);
+ return 0;
}
--
1.5.3.8
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFT 6/9] Char: moxa, remove useless tty functions
2008-02-07 19:11 [RFT 1/9] Char: moxa, merge 2 poll functions Jiri Slaby
` (3 preceding siblings ...)
2008-02-07 19:11 ` [RFT 5/9] Char: moxa, little cleanup Jiri Slaby
@ 2008-02-07 19:11 ` Jiri Slaby
2008-02-07 19:11 ` [RFT 7/9] Char: moxa, introduce MOXA_IS_320 macro Jiri Slaby
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Jiri Slaby @ 2008-02-07 19:11 UTC (permalink / raw)
To: Oyvind Aabling; +Cc: linux-kernel, Jiri Slaby
- moxa_flush_chars -- no code; ldics handle this well
- moxa_put_char -- only wrapper to moxa_write (same code), tty does this
the same way if tty->driver->put_char is NULL
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
drivers/char/moxa.c | 25 -------------------------
1 files changed, 0 insertions(+), 25 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index d123827..5f7fb38 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -193,8 +193,6 @@ static int moxa_write(struct tty_struct *, const unsigned char *, int);
static int moxa_write_room(struct tty_struct *);
static void moxa_flush_buffer(struct tty_struct *);
static int moxa_chars_in_buffer(struct tty_struct *);
-static void moxa_flush_chars(struct tty_struct *);
-static void moxa_put_char(struct tty_struct *, unsigned char);
static void moxa_throttle(struct tty_struct *);
static void moxa_unthrottle(struct tty_struct *);
static void moxa_set_termios(struct tty_struct *, struct ktermios *);
@@ -372,8 +370,6 @@ static const struct tty_operations moxa_ops = {
.write_room = moxa_write_room,
.flush_buffer = moxa_flush_buffer,
.chars_in_buffer = moxa_chars_in_buffer,
- .flush_chars = moxa_flush_chars,
- .put_char = moxa_put_char,
.ioctl = moxa_ioctl,
.throttle = moxa_throttle,
.unthrottle = moxa_unthrottle,
@@ -1258,27 +1254,6 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
return chars;
}
-static void moxa_flush_chars(struct tty_struct *tty)
-{
- /*
- * Don't think I need this, because this is called to empty the TX
- * buffer for the 16450, 16550, etc.
- */
-}
-
-static void moxa_put_char(struct tty_struct *tty, unsigned char c)
-{
- struct moxa_port *ch = tty->driver_data;
-
- if (ch == NULL)
- return;
- spin_lock_bh(&moxa_lock);
- MoxaPortWriteData(ch, &c, 1);
- spin_unlock_bh(&moxa_lock);
-
- ch->statusflags |= LOWWAIT;
-}
-
static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
{
struct moxa_port *ch = tty->driver_data;
--
1.5.3.8
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFT 7/9] Char: moxa, introduce MOXA_IS_320 macro
2008-02-07 19:11 [RFT 1/9] Char: moxa, merge 2 poll functions Jiri Slaby
` (4 preceding siblings ...)
2008-02-07 19:11 ` [RFT 6/9] Char: moxa, remove useless tty functions Jiri Slaby
@ 2008-02-07 19:11 ` Jiri Slaby
2008-02-07 19:11 ` [RFT 8/9] Char: moxa, notify about board readiness Jiri Slaby
2008-02-07 19:11 ` [RFT 9/9] Char: moxa, fix ioctl race Jiri Slaby
7 siblings, 0 replies; 9+ messages in thread
From: Jiri Slaby @ 2008-02-07 19:11 UTC (permalink / raw)
To: Oyvind Aabling; +Cc: linux-kernel, Jiri Slaby
It allows to simplify the code, especially MoxaPortSetBaud.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
drivers/char/moxa.c | 65 +++++++++++++++------------------------------------
1 files changed, 19 insertions(+), 46 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 5f7fb38..3b1760f 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -59,6 +59,9 @@
#define MAX_PORTS_PER_BOARD 32 /* Don't change this value */
#define MAX_PORTS (MAX_BOARDS * MAX_PORTS_PER_BOARD)
+#define MOXA_IS_320(brd) ((brd)->boardType == MOXA_BOARD_C320_ISA || \
+ (brd)->boardType == MOXA_BOARD_C320_PCI)
+
/*
* Define the Moxa PCI vendor and device IDs.
*/
@@ -493,11 +496,9 @@ static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr,
const u16 *uptr = ptr;
size_t wlen, len2, j;
unsigned long key, loadbuf, loadlen, checksum, checksum_ok;
- unsigned int i, retry, c320;
+ unsigned int i, retry;
u16 usum, keycode;
- c320 = brd->boardType == MOXA_BOARD_C320_PCI ||
- brd->boardType == MOXA_BOARD_C320_ISA;
keycode = (brd->boardType == MOXA_BOARD_CP204J) ? CP204J_KeyCode :
C218_KeyCode;
@@ -567,7 +568,7 @@ static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr,
if (readw(baseAddr + Magic_no) != Magic_code)
return -EIO;
- if (c320) {
+ if (MOXA_IS_320(brd)) {
if (brd->busType == MOXA_BUS_TYPE_PCI) { /* ASIC board */
writew(0x3800, baseAddr + TMS320_PORT1);
writew(0x3900, baseAddr + TMS320_PORT2);
@@ -588,7 +589,7 @@ static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr,
if (readw(baseAddr + Magic_no) != Magic_code)
return -EIO;
- if (c320) {
+ if (MOXA_IS_320(brd)) {
j = readw(baseAddr + Module_cnt);
if (j <= 0)
return -EIO;
@@ -1596,18 +1597,9 @@ static void MoxaPortFlushData(struct moxa_port *port, int mode)
* int port : port number (0 - 127)
*
*
- * Function 8: Get the maximun available baud rate of this port.
- * Syntax:
- * long MoxaPortGetMaxBaud(int port);
- * int port : port number (0 - 127)
- *
- * return: 0 : this port is invalid
- * 38400/57600/115200 bps
- *
- *
* Function 10: Setting baud rate of this port.
* Syntax:
- * long MoxaPortSetBaud(int port, long baud);
+ * speed_t MoxaPortSetBaud(int port, speed_t baud);
* int port : port number (0 - 127)
* long baud : baud rate (50 - 115200)
*
@@ -1756,8 +1748,7 @@ static void MoxaPortEnable(struct moxa_port *port)
ofsAddr = port->tableAddr;
writew(lowwater, ofsAddr + Low_water);
- if (port->board->boardType == MOXA_BOARD_C320_ISA ||
- port->board->boardType == MOXA_BOARD_C320_PCI)
+ if (MOXA_IS_320(port->board))
moxafunc(ofsAddr, FC_SetBreakIrq, 0);
else
writew(readw(ofsAddr + HostStat) | WakeupBreak,
@@ -1780,33 +1771,18 @@ static void MoxaPortDisable(struct moxa_port *port)
moxafunc(ofsAddr, FC_DisableCH, Magic_code);
}
-static long MoxaPortGetMaxBaud(struct moxa_port *port)
-{
- if (port->board->boardType == MOXA_BOARD_C320_ISA ||
- port->board->boardType == MOXA_BOARD_C320_PCI)
- return 460800L;
- else
- return 921600L;
-}
-
-
-static long MoxaPortSetBaud(struct moxa_port *port, long baud)
+static speed_t MoxaPortSetBaud(struct moxa_port *port, speed_t baud)
{
- void __iomem *ofsAddr;
- long max, clock;
- unsigned int val;
+ void __iomem *ofsAddr = port->tableAddr;
+ unsigned int clock, val;
+ speed_t max;
- if (baud < 50L || (max = MoxaPortGetMaxBaud(port)) == 0)
+ max = MOXA_IS_320(port->board) ? 460800 : 921600;
+ if (baud < 50)
return 0;
- ofsAddr = port->tableAddr;
if (baud > max)
baud = max;
- if (max == 38400L)
- clock = 614400L; /* for 9.8304 Mhz : max. 38400 bps */
- else if (max == 57600L)
- clock = 691200L; /* for 11.0592 Mhz : max. 57600 bps */
- else
- clock = 921600L; /* for 14.7456 Mhz : max. 115200 bps */
+ clock = 921600;
val = clock / baud;
moxafunc(ofsAddr, FC_SetBaud, val);
baud = clock / val;
@@ -1851,11 +1827,9 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
moxafunc(ofsAddr, FC_SetDataMode, (u16)mode);
- if (port->board->boardType == MOXA_BOARD_C320_ISA ||
- port->board->boardType == MOXA_BOARD_C320_PCI) {
- if (baud >= 921600L)
- return -1;
- }
+ if (MOXA_IS_320(port->board) && baud >= 921600)
+ return -1;
+
baud = MoxaPortSetBaud(port, baud);
if (termio->c_iflag & (IXON | IXOFF | IXANY)) {
@@ -1915,8 +1889,7 @@ static int MoxaPortLineStatus(struct moxa_port *port)
int val;
ofsAddr = port->tableAddr;
- if (port->board->boardType == MOXA_BOARD_C320_ISA ||
- port->board->boardType == MOXA_BOARD_C320_PCI) {
+ if (MOXA_IS_320(port->board)) {
moxafunc(ofsAddr, FC_LineStatus, 0);
val = readw(ofsAddr + FuncArg);
} else {
--
1.5.3.8
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFT 8/9] Char: moxa, notify about board readiness
2008-02-07 19:11 [RFT 1/9] Char: moxa, merge 2 poll functions Jiri Slaby
` (5 preceding siblings ...)
2008-02-07 19:11 ` [RFT 7/9] Char: moxa, introduce MOXA_IS_320 macro Jiri Slaby
@ 2008-02-07 19:11 ` Jiri Slaby
2008-02-07 19:11 ` [RFT 9/9] Char: moxa, fix ioctl race Jiri Slaby
7 siblings, 0 replies; 9+ messages in thread
From: Jiri Slaby @ 2008-02-07 19:11 UTC (permalink / raw)
To: Oyvind Aabling; +Cc: linux-kernel, Jiri Slaby
Drop a message to dmesg about card is being ready.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
drivers/char/moxa.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 3b1760f..fd9c946 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -943,6 +943,8 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, board);
+ dev_info(&pdev->dev, "board ready (firmware loaded)\n");
+
return 0;
err_base:
iounmap(board->basemem);
@@ -1028,6 +1030,10 @@ static int __init moxa_init(void)
continue;
}
+ printk(KERN_INFO "moxa isa board found at 0x%.8lu and "
+ "ready (firmware loaded)\n",
+ baseaddr[i]);
+
brd++;
isabrds++;
}
--
1.5.3.8
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFT 9/9] Char: moxa, fix ioctl race
2008-02-07 19:11 [RFT 1/9] Char: moxa, merge 2 poll functions Jiri Slaby
` (6 preceding siblings ...)
2008-02-07 19:11 ` [RFT 8/9] Char: moxa, notify about board readiness Jiri Slaby
@ 2008-02-07 19:11 ` Jiri Slaby
7 siblings, 0 replies; 9+ messages in thread
From: Jiri Slaby @ 2008-02-07 19:11 UTC (permalink / raw)
To: Oyvind Aabling; +Cc: linux-kernel, Jiri Slaby
The lock fixes window between board->ready test and its port access.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
drivers/char/moxa.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index fd9c946..6e170a4 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -299,6 +299,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
struct moxa_port *p;
unsigned int i, j;
+ mutex_lock(&moxa_openlock);
for (i = 0; i < MAX_BOARDS; i++) {
p = moxa_boards[i].ports;
for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
@@ -307,10 +308,13 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
tmp.inq = MoxaPortRxQueue(p);
tmp.outq = MoxaPortTxQueue(p);
}
- if (copy_to_user(argm, &tmp, sizeof(tmp)))
+ if (copy_to_user(argm, &tmp, sizeof(tmp))) {
+ mutex_unlock(&moxa_openlock);
return -EFAULT;
+ }
}
}
+ mutex_unlock(&moxa_openlock);
return 0;
} case MOXA_GET_OQUEUE:
status = MoxaPortTxQueue(ch);
@@ -324,6 +328,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
struct moxa_port *p;
unsigned int i, j;
+ mutex_lock(&moxa_openlock);
for (i = 0; i < MAX_BOARDS; i++) {
p = moxa_boards[i].ports;
for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
@@ -344,10 +349,13 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
else
tmp.cflag = p->tty->termios->c_cflag;
copy:
- if (copy_to_user(argm, &tmp, sizeof(tmp)))
+ if (copy_to_user(argm, &tmp, sizeof(tmp))) {
+ mutex_unlock(&moxa_openlock);
return -EFAULT;
+ }
}
}
+ mutex_unlock(&moxa_openlock);
return 0;
}
case TIOCGSERIAL:
--
1.5.3.8
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2008-02-07 19:17 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-02-07 19:11 [RFT 1/9] Char: moxa, merge 2 poll functions Jiri Slaby
2008-02-07 19:11 ` [RFT 2/9] Char: moxa, cleanup rx/tx Jiri Slaby
2008-02-07 19:11 ` [RFT 3/9] Char: moxa, serialise timer Jiri Slaby
2008-02-07 19:11 ` [RFT 4/9] Char: moxa, rework open/close Jiri Slaby
2008-02-07 19:11 ` [RFT 5/9] Char: moxa, little cleanup Jiri Slaby
2008-02-07 19:11 ` [RFT 6/9] Char: moxa, remove useless tty functions Jiri Slaby
2008-02-07 19:11 ` [RFT 7/9] Char: moxa, introduce MOXA_IS_320 macro Jiri Slaby
2008-02-07 19:11 ` [RFT 8/9] Char: moxa, notify about board readiness Jiri Slaby
2008-02-07 19:11 ` [RFT 9/9] Char: moxa, fix ioctl race Jiri Slaby
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).