Re: [patch]ratelimit debounce error messages

Oliver Neukum <[email protected]>
Newsgroups gmane.linux.usb.devel
Organization Novell
Message-ID <[email protected]>
Am Dienstag, 27. Februar 2007 17:03 schrieb Alan Stern:

> Oliver, I've noticed in the past that khubd tries too hard to enumerate a
> new connection.  The new scheme and the old scheme are both tried twice,
> and each try has two attempts to read the device descriptor, where each 
> attempt can loop twice, each loop with up to three calls to 
> usb_control_msg() and a device reset, with timeouts as long as 1 second.
> 
> In really bad cases this can tie things up for close to a minute.  We
> ought to be able to do better.  Some of the loops should be eliminated and
> some of the timeouts decreased.

Something like this?

	Regards
		Oliver

--- a/drivers/usb/core/hub.c	2007-03-01 11:17:53.000000000 +0100
+++ b/drivers/usb/core/hub.c	2007-03-01 12:13:08.000000000 +0100
@@ -70,6 +70,7 @@
 
 	unsigned		has_indicators:1;
 	u8			indicator[USB_MAXCHILDREN];
+	unsigned long		last_failed[USB_MAXCHILDREN];
 	struct delayed_work	leds;
 };
 
@@ -2419,7 +2420,7 @@
 	struct usb_device *hdev = hub->hdev;
 	struct device *hub_dev = hub->intfdev;
 	u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
-	int status, i;
+	int status, i, retries;
  
 	dev_dbg (hub_dev,
 		"port %d, status %04x, change %04x, %s\n",
@@ -2447,7 +2448,7 @@
 			dev_err (hub_dev,
 				"connect-debounce failed, port %d disabled\n",
 				port1);
-			goto done;
+			goto failed;
 		}
 		portstatus = status;
 	}
@@ -2461,7 +2462,7 @@
 			set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
  
 		if (portstatus & USB_PORT_STAT_ENABLE)
-  			goto done;
+  			goto failed;
 		return;
 	}
 
@@ -2478,7 +2479,11 @@
 	}
 #endif
 
-	for (i = 0; i < SET_CONFIG_TRIES; i++) {
+	/* we give short shrift if we had a failure within the last 2 hours */
+	retries = hub->last_failed[port1 - 1] &&
+		time_after(hub->last_failed[port1 - 1] + HZ * 60 * 60 * 2, jiffies) ?
+		1 : SET_CONFIG_TRIES;
+	for (i = 0; i < retries; i++) {
 		struct usb_device *udev;
 
 		/* reallocate for each attempt, since references
@@ -2580,6 +2585,7 @@
 		if (status)
 			dev_dbg(hub_dev, "%dmA power budget left\n", status);
 
+		hub->last_failed[port1 - 1] = 0; /*all former errors forgiven */
 		return;
 
 loop_disable:
@@ -2591,7 +2597,9 @@
 		if (status == -ENOTCONN)
 			break;
 	}
- 
+
+failed:
+	hub->last_failed[port1 - 1] = jiffies;
 done:
 	hub_port_disable(hub, port1, 1);
 }

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.