Browse Source

[usb] Allow additional settling time for out-of-spec hubs

Some hubs (e.g. the Avocent Corp. Virtual Hub on a Lenovo x3550
Integrated Management Module) have been observed to require more than
the standard 200ms for ports to stabilise, with the result that
devices appear to disconnect and immediately reconnect during the
initial bus enumeration.

Work around this problem by allowing specific hubs an extra 500ms of
settling time.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
53ba5936b5
2 changed files with 19 additions and 0 deletions
  1. 11
    0
      src/drivers/usb/usbhub.c
  2. 8
    0
      src/drivers/usb/usbhub.h

+ 11
- 0
src/drivers/usb/usbhub.c View File

155
 	/* Refill interrupt ring */
155
 	/* Refill interrupt ring */
156
 	hub_refill ( hubdev );
156
 	hub_refill ( hubdev );
157
 
157
 
158
+	/* Delay to allow ports to stabilise on out-of-spec hubs */
159
+	if ( hubdev->flags & USB_HUB_SLOW_START )
160
+		mdelay ( USB_HUB_SLOW_START_DELAY_MS );
161
+
158
 	return 0;
162
 	return 0;
159
 
163
 
160
 	usb_endpoint_close ( &hubdev->intr );
164
 	usb_endpoint_close ( &hubdev->intr );
410
 	hubdev->usb = usb;
414
 	hubdev->usb = usb;
411
 	hubdev->features =
415
 	hubdev->features =
412
 		( enhanced ? USB_HUB_FEATURES_ENHANCED : USB_HUB_FEATURES );
416
 		( enhanced ? USB_HUB_FEATURES_ENHANCED : USB_HUB_FEATURES );
417
+	hubdev->flags = func->id->driver_data;
413
 	usb_endpoint_init ( &hubdev->intr, usb, &usb_hub_intr_operations );
418
 	usb_endpoint_init ( &hubdev->intr, usb, &usb_hub_intr_operations );
414
 	usb_refill_init ( &hubdev->intr, 0, USB_HUB_INTR_FILL );
419
 	usb_refill_init ( &hubdev->intr, 0, USB_HUB_INTR_FILL );
415
 	process_init_stopped ( &hubdev->refill, &hub_refill_desc, NULL );
420
 	process_init_stopped ( &hubdev->refill, &hub_refill_desc, NULL );
517
 
522
 
518
 /** USB hub device IDs */
523
 /** USB hub device IDs */
519
 static struct usb_device_id hub_ids[] = {
524
 static struct usb_device_id hub_ids[] = {
525
+	{
526
+		.name = "avocent-hub",
527
+		.vendor = 0x0624,
528
+		.product = 0x0248,
529
+		.driver_data = USB_HUB_SLOW_START,
530
+	},
520
 	{
531
 	{
521
 		.name = "hub",
532
 		.name = "hub",
522
 		.vendor = USB_ANY_ID,
533
 		.vendor = USB_ANY_ID,

+ 8
- 0
src/drivers/usb/usbhub.h View File

257
 	struct usb_hub *hub;
257
 	struct usb_hub *hub;
258
 	/** Features */
258
 	/** Features */
259
 	unsigned int features;
259
 	unsigned int features;
260
+	/** Flags */
261
+	unsigned int flags;
260
 
262
 
261
 	/** Interrupt endpoint */
263
 	/** Interrupt endpoint */
262
 	struct usb_endpoint intr;
264
 	struct usb_endpoint intr;
264
 	struct process refill;
266
 	struct process refill;
265
 };
267
 };
266
 
268
 
269
+/** Hub requires additional settling delay */
270
+#define USB_HUB_SLOW_START 0x0001
271
+
272
+/** Additional setting delay for out-of-spec hubs */
273
+#define USB_HUB_SLOW_START_DELAY_MS 500
274
+
267
 /** Interrupt ring fill level
275
 /** Interrupt ring fill level
268
  *
276
  *
269
  * This is a policy decision.
277
  * This is a policy decision.

Loading…
Cancel
Save