Skip to contentSkip to conversation

drivers/net/wan/wanxl.c: time_before(timeout, jiffies) -> jiffies, timeout

PATCH In review Roel Kluin 3 participants 8 messages Mar 20, 2008 – Mar 24, 2008

Subsystems (2)
lore
Share & tools
lore

Roel Kluin

author
#0 lore raw

PATCH 1/1 drivers/net/wan/wanxl.c: time_before(timeout, jiffies) -> jiffies, timeout

Not tested, please confirm it's right
---
fix reversal of timeout and jiffies

---

drivers/net/wan/wanxl.c +1 -1
index d4aab8a..f61413b 100644
@@ -650,7 +650,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
 
 	timeout = jiffies + 20 * HZ;
 	while ((stat = readl(card->plx + PLX_MAILBOX_0)) != 0) {
-		if (time_before(timeout, jiffies)) {
+		if (time_before(jiffies, timeout)) {
 			printk(KERN_WARNING "wanXL %s: timeout waiting for"
 			       " PUTS to complete\n", pci_name(pdev));
 			wanxl_pci_remove_one(pdev);
#1 lore raw
Quoted 6 lines · Roel Kluin

fix reversal of timeout and jiffies

drivers/net/wan/wanxl.c +0 -0
index d4aab8a..f61413b 100644

drivers/net/wan/wanxl.c static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, · line 656

Quoted 8 lines
drivers/net/wan/wanxl.c +1 -1
@@ -650,7 +650,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
 
 	timeout = jiffies + 20 * HZ;
 	while ((stat = readl(card->plx + PLX_MAILBOX_0)) != 0) {
-		if (time_before(timeout, jiffies)) {
+		if (time_before(jiffies, timeout)) {
 			printk(KERN_WARNING "wanXL %s: timeout waiting for"
 			       " PUTS to complete\n", pci_name(pdev));
 			wanxl_pci_remove_one(pdev);

Wouldn't it be better to have a schedule() in those while loops too?

Maybe a more generic macro / statement expression
would be more readable?

perhaps something like (compiled/untested):

 drivers/net/wan/wanxl.c |   86 ++++++++++++++++------------------------------
 1 files changed, 30 insertions(+), 56 deletions(-)
drivers/net/wan/wanxl.c +30 -56
index d4aab8a..db1eabe 100644
@@ -51,6 +51,19 @@ static const char* version = "wanXL serial card driver version: 0.48";
 #define MBX2_MEMSZ_MASK 0xFFFF0000 /* PUTS Memory Size Register mask */
 
 
+#define TEST_UNTIL_TIMEOUT(test, hz)			\
+({							\
+	typeof test t;					\
+	unsigned long timeout = jiffies + hz;		\
+	do {						\
+		t = test;				\
+		if (t)					\
+			break;				\
+		schedule();				\
+	} while (time_before(jiffies, timeout));	\
+	t;						\
+})
+
 typedef struct {
 	struct net_device *dev;
 	struct card_t *card;
@@ -396,7 +409,6 @@ static int wanxl_open(struct net_device *dev)
 {
 	port_t *port = dev_to_port(dev);
 	u8 __iomem *dbr = port->card->plx + PLX_DOORBELL_TO_CARD;
-	unsigned long timeout;
 	int i;
 
 	if (get_status(port)->open) {
@@ -412,18 +424,15 @@ static int wanxl_open(struct net_device *dev)
 	/* signal the card */
 	writel(1 << (DOORBELL_TO_CARD_OPEN_0 + port->node), dbr);
 
-	timeout = jiffies + HZ;
-	do
-		if (get_status(port)->open) {
-			netif_start_queue(dev);
-			return 0;
-		}
-	while (time_after(timeout, jiffies));
+	if (!TEST_UNTIL_TIMEOUT((get_status(port)->open), HZ)) {
+		printk(KERN_ERR "%s: unable to open port\n", dev->name);
+		/* ask the card to close the port, should it be still alive */
+		writel(1 << (DOORBELL_TO_CARD_CLOSE_0 + port->node), dbr);
+		return -EFAULT;
+	}
 
-	printk(KERN_ERR "%s: unable to open port\n", dev->name);
-	/* ask the card to close the port, should it be still alive */
-	writel(1 << (DOORBELL_TO_CARD_CLOSE_0 + port->node), dbr);
-	return -EFAULT;
+	netif_start_queue(dev);
+	return 0;
 }
 
 
@@ -431,7 +440,6 @@ static int wanxl_open(struct net_device *dev)
 static int wanxl_close(struct net_device *dev)
 {
 	port_t *port = dev_to_port(dev);
-	unsigned long timeout;
 	int i;
 
 	hdlc_close(dev);
@@ -439,13 +447,7 @@ static int wanxl_close(struct net_device *dev)
 	writel(1 << (DOORBELL_TO_CARD_CLOSE_0 + port->node),
 	       port->card->plx + PLX_DOORBELL_TO_CARD);
 
-	timeout = jiffies + HZ;
-	do
-		if (!get_status(port)->open)
-			break;
-	while (time_after(timeout, jiffies));
-
-	if (get_status(port)->open)
+	if (TEST_UNTIL_TIMEOUT((!get_status(port)->open), HZ))
 		printk(KERN_ERR "%s: unable to close port\n", dev->name);
 
 	netif_stop_queue(dev);
@@ -481,17 +483,11 @@ static struct net_device_stats *wanxl_get_stats(struct net_device *dev)
 
 static int wanxl_puts_command(card_t *card, u32 cmd)
 {
-	unsigned long timeout = jiffies + 5 * HZ;
-
 	writel(cmd, card->plx + PLX_MAILBOX_1);
-	do {
-		if (readl(card->plx + PLX_MAILBOX_1) == 0)
-			return 0;
-
-		schedule();
-	}while (time_after(timeout, jiffies));
+	if (TEST_UNTIL_TIMEOUT((readl(card->plx + PLX_MAILBOX_1)), 5 * HZ))
+		return -1;
 
-	return -1;
+	return 0;
 }
 
 
@@ -649,27 +645,12 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
 #endif
 
 	timeout = jiffies + 20 * HZ;
-	while ((stat = readl(card->plx + PLX_MAILBOX_0)) != 0) {
-		if (time_before(timeout, jiffies)) {
-			printk(KERN_WARNING "wanXL %s: timeout waiting for"
-			       " PUTS to complete\n", pci_name(pdev));
-			wanxl_pci_remove_one(pdev);
-			return -ENODEV;
-		}
-
-		switch(stat & 0xC0) {
-		case 0x00:	/* hmm - PUTS completed with non-zero code? */
-		case 0x80:	/* PUTS still testing the hardware */
-			break;
-
-		default:
-			printk(KERN_WARNING "wanXL %s: PUTS test 0x%X"
+	if (TEST_UNTIL_TIMEOUT(((stat = readl(card->plx + PLX_MAILBOX_0)) != 0),
+			       20 * HZ)) {
+		printk(KERN_WARNING "wanXL %s: PUTS test 0x%X"
 			       " failed\n", pci_name(pdev), stat & 0x30);
 			wanxl_pci_remove_one(pdev);
 			return -ENODEV;
-		}
-
-		schedule();
 	}
 
 	/* get on-board memory size (PUTS detects no more than 4 MB) */
@@ -734,15 +715,8 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
 		return -ENODEV;
 	}
 
-	stat = 0;
-	timeout = jiffies + 5 * HZ;
-	do {
-		if ((stat = readl(card->plx + PLX_MAILBOX_5)) != 0)
-			break;
-		schedule();
-	}while (time_after(timeout, jiffies));
-
-	if (!stat) {
+	if (TEST_UNTIL_TIMEOUT(((stat = readl(card->plx + PLX_MAILBOX_5)) != 0),
+			       5 * HZ)) {
 		printk(KERN_WARNING "wanXL %s: timeout while initializing card "
 		       "firmware\n", pci_name(pdev));
 		wanxl_pci_remove_one(pdev);
author
#2 lore raw
Quoted 8 lines · Joe Perches
Quoted 1 line · Roel Kluin

fix reversal of timeout and jiffies

Wouldn't it be better to have a schedule() in those while loops too?

Maybe a more generic macro / statement expression
would be more readable?

It appears more readable.

Quoted 1 line

perhaps something like (compiled/untested):

A few generic comments (not yet tested)

Quoted 8 lines
 drivers/net/wan/wanxl.c |   86 ++++++++++++++++------------------------------
 1 files changed, 30 insertions(+), 56 deletions(-)
drivers/net/wan/wanxl.c +0 -0
index d4aab8a..db1eabe 100644

drivers/net/wan/wanxl.c static const char* version = "wanXL serial card driver version: 0.48"; · line 56

Quoted 6 lines
drivers/net/wan/wanxl.c +3 -0
@@ -51,6 +51,19 @@ static const char* version = "wanXL serial card driver version: 0.48";
 #define MBX2_MEMSZ_MASK 0xFFFF0000 /* PUTS Memory Size Register mask */
 
 
+#define TEST_UNTIL_TIMEOUT(test, hz)			\
+({							\
+	typeof test t;					\
	typeof(test) t;					\

will this work if test is a function?

drivers/net/wan/wanxl.c static const char* version = "wanXL serial card driver version: 0.48"; · line 57

Quoted 1 line
drivers/net/wan/wanxl.c +1 -0
+	unsigned long timeout = jiffies + hz;		\
	unsigned long timeout = jiffies + (hz);		\

drivers/net/wan/wanxl.c static const char* version = "wanXL serial card driver version: 0.48"; · line 59

Quoted 2 lines
drivers/net/wan/wanxl.c +2 -0
+	do {						\
+		t = test;				\
		t = (test);				\
Quoted 91 lines
drivers/net/wan/wanxl.c +7 -0
+		if (t)					\
+			break;				\
+		schedule();				\
+	} while (time_before(jiffies, timeout));	\
+	t;						\
+})
 
+
 typedef struct {
 	struct net_device *dev;
drivers/net/wan/wanxl.c +12 -29
 	struct card_t *card;
@@ -396,7 +409,6 @@ static int wanxl_open(struct net_device *dev)
 {
 	port_t *port = dev_to_port(dev);
 	u8 __iomem *dbr = port->card->plx + PLX_DOORBELL_TO_CARD;
-	unsigned long timeout;
 	int i;
 
 	if (get_status(port)->open) {
@@ -412,18 +424,15 @@ static int wanxl_open(struct net_device *dev)
 	/* signal the card */
 	writel(1 << (DOORBELL_TO_CARD_OPEN_0 + port->node), dbr);
 
-	timeout = jiffies + HZ;
-	do
-		if (get_status(port)->open) {
-			netif_start_queue(dev);
-			return 0;
-		}
-	while (time_after(timeout, jiffies));
+	if (!TEST_UNTIL_TIMEOUT((get_status(port)->open), HZ)) {
+		printk(KERN_ERR "%s: unable to open port\n", dev->name);
+		/* ask the card to close the port, should it be still alive */
+		writel(1 << (DOORBELL_TO_CARD_CLOSE_0 + port->node), dbr);
+		return -EFAULT;
+	}
 
-	printk(KERN_ERR "%s: unable to open port\n", dev->name);
-	/* ask the card to close the port, should it be still alive */
-	writel(1 << (DOORBELL_TO_CARD_CLOSE_0 + port->node), dbr);
-	return -EFAULT;
+	netif_start_queue(dev);
+	return 0;
 }
 
 
@@ -431,7 +440,6 @@ static int wanxl_open(struct net_device *dev)
 static int wanxl_close(struct net_device *dev)
 {
 	port_t *port = dev_to_port(dev);
-	unsigned long timeout;
 	int i;
 
 	hdlc_close(dev);
@@ -439,13 +447,7 @@ static int wanxl_close(struct net_device *dev)
 	writel(1 << (DOORBELL_TO_CARD_CLOSE_0 + port->node),
 	       port->card->plx + PLX_DOORBELL_TO_CARD);
 
-	timeout = jiffies + HZ;
-	do
-		if (!get_status(port)->open)
-			break;
-	while (time_after(timeout, jiffies));
-
-	if (get_status(port)->open)
+	if (TEST_UNTIL_TIMEOUT((!get_status(port)->open), HZ))
 		printk(KERN_ERR "%s: unable to close port\n", dev->name);
 
 	netif_stop_queue(dev);
@@ -481,17 +483,11 @@ static struct net_device_stats *wanxl_get_stats(struct net_device *dev)
 
 static int wanxl_puts_command(card_t *card, u32 cmd)
 {
-	unsigned long timeout = jiffies + 5 * HZ;
-
 	writel(cmd, card->plx + PLX_MAILBOX_1);
-	do {
-		if (readl(card->plx + PLX_MAILBOX_1) == 0)
-			return 0;
-
-		schedule();
-	}while (time_after(timeout, jiffies));
+	if (TEST_UNTIL_TIMEOUT((readl(card->plx + PLX_MAILBOX_1)), 5 * HZ))
+		return -1;
 
-	return -1;
+	return 0;
 }
 
 

drivers/net/wan/wanxl.c static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, · line 647

Quoted 3 lines
drivers/net/wan/wanxl.c +0 -0
@@ -649,27 +645,12 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
 #endif
 
 	timeout = jiffies + 20 * HZ;

you can remove the line above as well

Quoted 11 lines
drivers/net/wan/wanxl.c +0 -11
-	while ((stat = readl(card->plx + PLX_MAILBOX_0)) != 0) {
-		if (time_before(timeout, jiffies)) {
-			printk(KERN_WARNING "wanXL %s: timeout waiting for"
-			       " PUTS to complete\n", pci_name(pdev));
-			wanxl_pci_remove_one(pdev);
-			return -ENODEV;
-		}
-
-		switch(stat & 0xC0) {
-		case 0x00:	/* hmm - PUTS completed with non-zero code? */
-		case 0x80:	/* PUTS still testing the hardware */

drivers/net/wan/wanxl.c static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, · line 653

Quoted 10 lines
drivers/net/wan/wanxl.c +3 -4
-			break;
-
-		default:
-			printk(KERN_WARNING "wanXL %s: PUTS test 0x%X"
+	if (TEST_UNTIL_TIMEOUT(((stat = readl(card->plx + PLX_MAILBOX_0)) != 0),
+			       20 * HZ)) {
+		printk(KERN_WARNING "wanXL %s: PUTS test 0x%X"
 			       " failed\n", pci_name(pdev), stat & 0x30);
 			wanxl_pci_remove_one(pdev);
 			return -ENODEV;

Doesn't this change behavior for (stat & 0xC0) != 0x00 or 0x80?

Quoted 26 lines
drivers/net/wan/wanxl.c +2 -12
-		}
-
-		schedule();
 	}
 
 	/* get on-board memory size (PUTS detects no more than 4 MB) */
@@ -734,15 +715,8 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
 		return -ENODEV;
 	}
 
-	stat = 0;
-	timeout = jiffies + 5 * HZ;
-	do {
-		if ((stat = readl(card->plx + PLX_MAILBOX_5)) != 0)
-			break;
-		schedule();
-	}while (time_after(timeout, jiffies));
-
-	if (!stat) {
+	if (TEST_UNTIL_TIMEOUT(((stat = readl(card->plx + PLX_MAILBOX_5)) != 0),
+			       5 * HZ)) {
 		printk(KERN_WARNING "wanXL %s: timeout while initializing card "
 		       "firmware\n", pci_name(pdev));
 		wanxl_pci_remove_one(pdev);
#3 lore raw
Quoted 15 lines · Roel Kluin
Quoted 15 lines
drivers/net/wan/wanxl.c +0 -15
-	while ((stat = readl(card->plx + PLX_MAILBOX_0)) != 0) {
-		if (time_before(timeout, jiffies)) {
-			printk(KERN_WARNING "wanXL %s: timeout waiting for"
-			       " PUTS to complete\n", pci_name(pdev));
-			wanxl_pci_remove_one(pdev);
-			return -ENODEV;
-		}
-
-		switch(stat & 0xC0) {
-		case 0x00:	/* hmm - PUTS completed with non-zero code? */
-		case 0x80:	/* PUTS still testing the hardware */
-			break;
-
-		default:
-			printk(KERN_WARNING "wanXL %s: PUTS test 0x%X"
Quoted 8 lines

drivers/net/wan/wanxl.c static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, · line 653

Quoted 6 lines
drivers/net/wan/wanxl.c +3 -0
+	if (TEST_UNTIL_TIMEOUT(((stat = readl(card->plx + PLX_MAILBOX_0)) != 0),
+			       20 * HZ)) {
+		printk(KERN_WARNING "wanXL %s: PUTS test 0x%X"
 			       " failed\n", pci_name(pdev), stat & 0x30);
 			wanxl_pci_remove_one(pdev);
 			return -ENODEV;

Doesn't this change behavior for (stat & 0xC0) != 0x00 or 0x80?

Probably, I didn't look at it too much. Feel free to fix it.

The patch was just to demonstrate the statement expression macro and show the lack of schedules() in some of the loops.

Maybe the statement expression macro should optionally schedule too:

#define TEST_UNTIL_TIMEOUT(test, hz, schedule) \

({							\
	typeof(test) t;					\
	unsigned long timeout = jiffies + (hz);		\
	do {						\
		t = (test);				\
		if (t)					\
			break;				\
		if ((schedule))				\
			schedule();			\
	} while (time_before(jiffies, timeout));	\
	t;						\
})

cheers, Joe

maintainer
#7 lore raw
In reply to Roel Kluin

Hi,

drivers/net/wan/wanxl.c static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, · line 656

Quoted 12 lines · Roel Kluin
drivers/net/wan/wanxl.c +1 -1
@@ -650,7 +650,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
 
 	timeout = jiffies + 20 * HZ;
 	while ((stat = readl(card->plx + PLX_MAILBOX_0)) != 0) {
-		if (time_before(timeout, jiffies)) {
+		if (time_before(jiffies, timeout)) {
 			printk(KERN_WARNING "wanXL %s: timeout waiting for"
 			       " PUTS to complete\n", pci_name(pdev));
 			wanxl_pci_remove_one(pdev);

I can't see a bug here - time_before(timeout, jiffies) means "if timeout is before jiffies", IOW if jiffies passed the timeout.

Perhaps time_after(jiffies, timeout) is a bit better equivalent, I will use that.

Signature · 1 line
Krzysztof Halasa
maintainer
#4 lore raw
In reply to Joe Perches
Quoted 9 lines · Joe Perches

Review

Quoted 6 lines
(quoted diff) +1 -1
 	while ((stat = readl(card->plx + PLX_MAILBOX_0)) != 0) {
-		if (time_before(timeout, jiffies)) {
+		if (time_before(jiffies, timeout)) {
 			printk(KERN_WARNING "wanXL %s: timeout waiting for"
 			       " PUTS to complete\n", pci_name(pdev));
 			wanxl_pci_remove_one(pdev);

Wouldn't it be better to have a schedule() in those while loops too?

There is a schedule() here:

        timeout = jiffies + 20 * HZ;
        while ((stat = readl(card->plx + PLX_MAILBOX_0)) != 0) {
                if (time_before(timeout, jiffies)) {
                        printk(KERN_WARNING "wanXL %s: timeout waiting for"
                               " PUTS to complete\n", pci_name(pdev));
                        wanxl_pci_remove_one(pdev);
                        return -ENODEV;
                }

                switch(stat & 0xC0) {
                case 0x00:      /* hmm - PUTS completed with non-zero code? */
                case 0x80:      /* PUTS still testing the hardware */
                        break;

                default:
                        printk(KERN_WARNING "wanXL %s: PUTS test 0x%X"
                               " failed\n", pci_name(pdev), stat & 0x30);
                        wanxl_pci_remove_one(pdev);
                        return -ENODEV;
                }

                schedule();
        }

The timeout is 20 seconds, busy loop wouldn't make any sense.

Quoted 2 lines

Maybe a more generic macro / statement expression
would be more readable?

I don't think so. BTW the only "long" loop is the POTS one (after hw reset or rmmod + insmod), IIRC it takes about 1 second for every MB of installed DRAM. Officially you can have 1 or 4 MB, and 16 MB module works (IIRC, on my card) as well - thus 20 * HZ timeout.

A couple of reversed time_{after,before}, yes (with reversed arguments, i.e., functionally equivalent but probably harder to parse). Will look at them.

Signature · 1 line
Krzysztof Halasa
#5 lore raw
Quoted 4 lines · Krzysztof Halasa
Quoted 2 lines · Joe Perches

Wouldn't it be better to have a schedule() in those while loops too?

There is a schedule() here:

What's the value of not having schedule() in the
wanxl_open and wanxl_close routines?

maintainer
#6 lore raw
Quoted 2 lines · Joe Perches

What's the value of not having schedule() in the
wanxl_open and wanxl_close routines?

There is no need, it's fast.

Signature · 1 line
Krzysztof Halasa