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).