Hi Greg, David
This patch does a bunch of small modifications to the USB core so that WUSB
devices are accepted in the system. I finally got a well-behaved one that
allowed me to test these changes.
1. [this is not really needed] change usb_get_configuration() so that
it is more tolerant to devices with bad configuration descriptors
(it'll make it ignore configurations that fail to load).
2. Introduce USB_PORT_STAT_WIRELESS; we take one of the reserved bits
in the USB port status (bit 5) to report that we are a wireless
(fake port).
Yes, bad bad, it is taken by the spec. The rationale for doing it
like this is that we avoid having to use side channels to convey
the information. If any future spec uses it we'd have to move it.
Another option would be to set a bit somewhere in the hub struct
and test against that. I want to give that a shot, however, I don't
know when will I be able.
3. If the port is wireless (as mentioned by USB_PORT_STAT_WIRELESS),
enable the new speed rules (USB_SPEED_VARIABLE) and set ep0's
maxpacketsize to 512 (even though the device descriptor reports
it as 0xff).
4. Clean up the message for a new usb device and make it report wusb
devices.
New code being pushed to linuxuwb.org requires this patch to connect WUSB
devices.
Signed-off-by: Inaky Perez-Gonzalez <[EMAIL PROTECTED]>
--
config.c | 4 +++-
hub.c | 41 ++++++++++++++++++++++++++++-------------
hub.h | 3 ++-
3 files changed, 33 insertions(+), 15 deletions(-)
diff -r dcc321d1340a drivers/usb/core/config.c
--- a/drivers/usb/core/config.c Sun Aug 06 19:00:05 2006 +0000
+++ b/drivers/usb/core/config.c Tue Aug 22 15:43:32 2006 -0700
@@ -475,7 +475,9 @@ int usb_get_configuration(struct usb_dev
if (result < 0) {
dev_err(ddev, "unable to read config index %d "
"descriptor/%s\n", cfgno, "start");
- goto err;
+ dev_err(ddev, "chopping to %d config(s)\n", cfgno);
+ dev->descriptor.bNumConfigurations = cfgno;
+ break;
} else if (result < 4) {
dev_err(ddev, "config index %d descriptor too short "
"(expected %i, got %i)\n", cfgno,
diff -r dcc321d1340a drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c Sun Aug 06 19:00:05 2006 +0000
+++ b/drivers/usb/core/hub.c Tue Aug 22 15:46:50 2006 -0700
@@ -1512,7 +1512,9 @@ static int hub_port_wait_reset(struct us
/* 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 (portstatus & USB_PORT_STAT_WIRELESS)
+ 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;
@@ -2214,6 +2216,7 @@ hub_port_init (struct usb_hub *hub, stru
int i, j, retval;
unsigned delay = HUB_SHORT_RESET_TIME;
enum usb_device_speed oldspeed = udev->speed;
+ char *speed, *type;
/* root hub ports have a slightly longer reset period
* (from USB 2.0 spec, section 7.1.7.5)
@@ -2246,8 +2249,13 @@ hub_port_init (struct usb_hub *hub, stru
/* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
* it's fixed size except for full speed devices.
+ * For Wireless USB devices, ep0 max packet is always 512 (tho
+ * reported as 0xff in the device descriptor). WUSB1.0[4.8.1].
*/
switch (udev->speed) {
+ case USB_SPEED_VARIABLE: /* fixed at 512 */
+ udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(512);
+ break;
case USB_SPEED_HIGH: /* fixed at 64 */
udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
break;
@@ -2265,17 +2273,21 @@ hub_port_init (struct usb_hub *hub, stru
goto fail;
}
+ type = "";
+ switch (udev->speed) {
+ case USB_SPEED_LOW: speed = "low"; break;
+ case USB_SPEED_FULL: speed = "full"; break;
+ case USB_SPEED_HIGH: speed = "high"; break;
+ case USB_SPEED_VARIABLE:
+ speed = "variable";
+ type = "Wireless ";
+ break;
+ default: speed = "?"; break;
+ }
dev_info (&udev->dev,
- "%s %s speed USB device using %s and address %d\n",
- (udev->config) ? "reset" : "new",
- ({ char *speed; switch (udev->speed) {
- case USB_SPEED_LOW: speed = "low"; break;
- case USB_SPEED_FULL: speed = "full"; break;
- case USB_SPEED_HIGH: speed = "high"; break;
- default: speed = "?"; break;
- }; speed;}),
- udev->bus->controller->driver->name,
- udev->devnum);
+ "%s %s speed %sUSB device using %s and address %d\n",
+ (udev->config) ? "reset" : "new", speed, type,
+ udev->bus->controller->driver->name, udev->devnum);
/* Set up TT records, if needed */
if (hdev->tt) {
@@ -2317,6 +2329,8 @@ hub_port_init (struct usb_hub *hub, stru
* down tremendously by NAKing the unexpectedly
* early status stage. Also, retry on all errors;
* some devices are flakey.
+ * 255 is for WUSB devices, we actually need to use 512.
+ * WUSB1.0[4.8.1].
*/
for (j = 0; j < 3; ++j) {
buf->bMaxPacketSize0 = 0;
@@ -2326,7 +2340,7 @@ hub_port_init (struct usb_hub *hub, stru
buf, GET_DESCRIPTOR_BUFSIZE,
(i ? USB_CTRL_GET_TIMEOUT : 1000));
switch (buf->bMaxPacketSize0) {
- case 8: case 16: case 32: case 64:
+ case 8: case 16: case 32: case 64: case 255:
if (buf->bDescriptorType ==
USB_DT_DEVICE) {
r = 0;
@@ -2400,7 +2414,8 @@ hub_port_init (struct usb_hub *hub, stru
if (retval)
goto fail;
- i = udev->descriptor.bMaxPacketSize0;
+ i = udev->descriptor.bMaxPacketSize0 == 0xff?
+ 512 : udev->descriptor.bMaxPacketSize0;
if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) {
if (udev->speed != USB_SPEED_FULL ||
!(i == 8 || i == 16 || i == 32 || i == 64)) {
diff -r dcc321d1340a drivers/usb/core/hub.h
--- a/drivers/usb/core/hub.h Sun Aug 06 19:00:05 2006 +0000
+++ b/drivers/usb/core/hub.h Tue Aug 22 15:43:32 2006 -0700
@@ -73,7 +73,8 @@ struct usb_port_status {
#define USB_PORT_STAT_SUSPEND 0x0004
#define USB_PORT_STAT_OVERCURRENT 0x0008
#define USB_PORT_STAT_RESET 0x0010
-/* bits 5 to 7 are reserved */
+/* bits 5 to 7 are reserved, 5 is taken by Linux to mark WUSB port */
+#define USB_PORT_STAT_WIRELESS 0x0020
#define USB_PORT_STAT_POWER 0x0100
#define USB_PORT_STAT_LOW_SPEED 0x0200
#define USB_PORT_STAT_HIGH_SPEED 0x0400
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel