From 0165de09747be76b09ef769fcfed3514fe5f6509 Mon Sep 17 00:00:00 2001
From: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
Date: Fri, 25 Aug 2006 19:35:29 -0700
Subject: [PATCH] wusb: hub code recognizes wusb ports

This patch enables the USB stack to recognize WUSB devices (from a
WUSB HCD) and assigns them the proper speed setting
(USB_SPEED_VARIABLE).

1. Introduce usb_hcd->wireless to mark a host controller instance as
   being wireless, and thus having wireless 'fake' ports.

   [discarded previous model of using a reserved bit in the port_stat
   struct to do this; thanks to Alan Stern for indicating the
   proper way to do it].

2. Introduce hub.c:hub_is_wusb() that tests if a hub is a WUSB root
   hub (WUSB doesn't have non-root hubs).

New code being pushed to linuxuwb.org requires this patch to connect WUSB
devices.

Signed-off-by: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/usb/core/hcd.h |  1 +
 drivers/usb/core/hub.c | 16 +++++++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 58c7767bc904d8..fc71a08a1af47e 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -85,6 +85,7 @@ struct usb_hcd {	/* usb_bus.hcpriv points to this */
 	unsigned		uses_new_polling:1;
 	unsigned		poll_rh:1;	/* poll for rh status? */
 	unsigned		poll_pending:1;	/* status has changed? */
+	unsigned		wireless:1;	/* Wireless USB HCD */
 
 	int			irq;		/* irq allocated */
 	void __iomem		*regs;		/* device memory/io */
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index bdf5be09965068..db4a9be1cb8a8c 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1331,6 +1331,18 @@ static int hub_port_status(struct usb_hub *hub, int port1,
 	return ret;
 }
 
+
+/* Returns 1 if @hub is a WUSB root hub, 0 otherwise */
+static unsigned hub_is_wusb(struct usb_hub *hub)
+{
+	struct usb_hcd *hcd;
+	if (hub->hdev->parent != NULL)  /* not a root hub? */
+		return 0;
+	hcd = container_of(hub->hdev->bus, struct usb_hcd, self);
+	return hcd->wireless;
+}
+
+
 #define PORT_RESET_TRIES	5
 #define SET_ADDRESS_TRIES	2
 #define GET_DESCRIPTOR_TRIES	2
@@ -1371,7 +1383,9 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
 		/* if we`ve finished resetting, then break out of the loop */
 		if (!(portstatus & USB_PORT_STAT_RESET) &&
 		    (portstatus & USB_PORT_STAT_ENABLE)) {
-			if (portstatus & USB_PORT_STAT_HIGH_SPEED)
+			if (hub_is_wusb(hub))
+				udev->speed = USB_SPEED_VARIABLE;
+			else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
 				udev->speed = USB_SPEED_HIGH;
 			else if (portstatus & USB_PORT_STAT_LOW_SPEED)
 				udev->speed = USB_SPEED_LOW;
-- 
GitLab