[RFT 8/9] Char: moxa, notify about board readiness

Previous thread: [PATCH] Use global TLB flushes in MTRR code by Andi Kleen on Thursday, February 7, 2008 - 12:02 pm. (10 messages)

Next thread: [PATCH] input: driver for USB VoIP phones with CM109 chipset by Alfred E. Heggestad on Thursday, February 7, 2008 - 11:38 am. (10 messages)
From: Jiri Slaby
Date: Thursday, February 7, 2008 - 12:11 pm

- 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 ...
From: Jiri Slaby
Date: Thursday, February 7, 2008 - 12:11 pm

- 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 = ...
From: Jiri Slaby
Date: Thursday, February 7, 2008 - 12:11 pm

- 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 ...
From: Jiri Slaby
Date: Thursday, February 7, 2008 - 12:11 pm

- 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 / ...
From: Jiri Slaby
Date: Thursday, February 7, 2008 - 12:11 pm

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 ...
From: Jiri Slaby
Date: Thursday, February 7, 2008 - 12:11 pm

- 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 ...
From: Jiri Slaby
Date: Thursday, February 7, 2008 - 12:11 pm

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 ...
From: Jiri Slaby
Date: Thursday, February 7, 2008 - 12:11 pm

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

--

From: Jiri Slaby
Date: Thursday, February 7, 2008 - 12:11 pm

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

--

Previous thread: [PATCH] Use global TLB flushes in MTRR code by Andi Kleen on Thursday, February 7, 2008 - 12:02 pm. (10 messages)

Next thread: [PATCH] input: driver for USB VoIP phones with CM109 chipset by Alfred E. Heggestad on Thursday, February 7, 2008 - 11:38 am. (10 messages)