Okay, got feedback from everybody and rehashed it to current gregkh's queue. 

wusb: basic device infrastructure modifications [take 3]

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_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].

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

5. If the port's hub is wireless (as asserted by hub.c:hub_is_wusb()),
   enable the new speed rules (USB_SPEED_VARIABLE) and set ep0's
   maxpacketsize to 512 (even though the device descriptor reports it
   as 0xff).

6. 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]>

---
 drivers/usb/core/config.c |    4 ++-
 drivers/usb/core/hcd.h    |    1 
 drivers/usb/core/hub.c    |   55 +++++++++++++++++++++++++++++++++++-----------
 3 files changed, 46 insertions(+), 14 deletions(-)

Index: drivers/usb/core/config.c
===================================================================
--- drivers/usb/core/config.c.orig      2006-08-24 13:41:30.000000000 -0700
+++ drivers/usb/core/config.c   2006-08-24 13:41:44.000000000 -0700
@@ -475,7 +475,9 @@
                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,
Index: drivers/usb/core/hub.c
===================================================================
--- drivers/usb/core/hub.c.orig 2006-08-24 13:41:30.000000000 -0700
+++ drivers/usb/core/hub.c      2006-08-24 13:41:44.000000000 -0700
@@ -1366,6 +1366,20 @@
        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)  // no a root hub?
+               return 0;
+       // FIXME: change to bus_to_hcd() as it is in the tree
+       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
@@ -1406,7 +1420,9 @@
                /* 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;
@@ -2043,6 +2059,7 @@
        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)
@@ -2075,8 +2092,13 @@
   
        /* 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;
@@ -2094,17 +2116,21 @@
                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) {
@@ -2146,6 +2172,8 @@
                         * 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;
@@ -2155,7 +2183,7 @@
                                        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;
@@ -2229,7 +2257,8 @@
        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)) {
Index: drivers/usb/core/hcd.h
===================================================================
--- drivers/usb/core/hcd.h.orig 2006-08-24 13:41:30.000000000 -0700
+++ drivers/usb/core/hcd.h      2006-08-24 13:41:44.000000000 -0700
@@ -85,6 +85,7 @@
        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 */

-------------------------------------------------------------------------
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
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to