USB: allow libusb to talk to unauthenticated WUSB devices
David Vrabel [Wed, 18 Feb 2009 14:43:47 +0000 (14:43 +0000)]
To permit a userspace application to associate with WUSB devices
using numeric association, control transfers to unauthenticated WUSB
devices must be allowed.

This requires that wusbcore correctly sets the device state to
UNAUTHENTICATED, DEFAULT and ADDRESS and that control transfers can be
performed to UNAUTHENTICATED devices.

Signed-off-by: David Vrabel <david.vrabel@csr.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

drivers/usb/core/devio.c
drivers/usb/core/hub.c
drivers/usb/core/urb.c
drivers/usb/wusbcore/devconnect.c
drivers/usb/wusbcore/security.c
include/linux/usb/ch9.h

index 6585f52..8f022af 100644 (file)
@@ -525,7 +525,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,
 {
        int ret = 0;
 
-       if (ps->dev->state != USB_STATE_ADDRESS
+       if (ps->dev->state != USB_STATE_UNAUTHENTICATED
+        && ps->dev->state != USB_STATE_ADDRESS
         && ps->dev->state != USB_STATE_CONFIGURED)
                return -EHOSTUNREACH;
        if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype))
index 7e33d63..f17d9eb 100644 (file)
@@ -1305,6 +1305,7 @@ void usb_set_device_state(struct usb_device *udev,
                recursively_mark_NOTATTACHED(udev);
        spin_unlock_irqrestore(&device_state_lock, flags);
 }
+EXPORT_SYMBOL_GPL(usb_set_device_state);
 
 /*
  * WUSB devices are simple: they have no hubs behind, so the mapping
index 58bc5e3..7025d80 100644 (file)
@@ -295,7 +295,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
        if (!urb || urb->hcpriv || !urb->complete)
                return -EINVAL;
        dev = urb->dev;
-       if ((!dev) || (dev->state < USB_STATE_DEFAULT))
+       if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED))
                return -ENODEV;
 
        /* For now, get the endpoint from the pipe.  Eventually drivers
index 8e18141..f0aac0c 100644 (file)
@@ -889,6 +889,8 @@ static void wusb_dev_add_ncb(struct usb_device *usb_dev)
        if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
                return;         /* skip non wusb and wusb RHs */
 
+       usb_set_device_state(usb_dev, USB_STATE_UNAUTHENTICATED);
+
        wusbhc = wusbhc_get_by_usb_dev(usb_dev);
        if (wusbhc == NULL)
                goto error_nodev;
index f4aa28e..8118db7 100644 (file)
@@ -312,6 +312,7 @@ int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
        result = wusb_set_dev_addr(wusbhc, wusb_dev, 0);
        if (result < 0)
                goto error_addr0;
+       usb_set_device_state(usb_dev, USB_STATE_DEFAULT);
        usb_ep0_reinit(usb_dev);
 
        /* Set new (authenticated) address. */
@@ -327,6 +328,7 @@ int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
        result = wusb_set_dev_addr(wusbhc, wusb_dev, new_address);
        if (result < 0)
                goto error_addr;
+       usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
        usb_ep0_reinit(usb_dev);
        usb_dev->authenticated = 1;
 error_addr:
index fa777db..d9d5480 100644 (file)
@@ -763,8 +763,8 @@ enum usb_device_state {
        /* chapter 9 and authentication (wireless) device states */
        USB_STATE_ATTACHED,
        USB_STATE_POWERED,                      /* wired */
-       USB_STATE_UNAUTHENTICATED,              /* auth */
        USB_STATE_RECONNECTING,                 /* auth */
+       USB_STATE_UNAUTHENTICATED,              /* auth */
        USB_STATE_DEFAULT,                      /* limited function */
        USB_STATE_ADDRESS,
        USB_STATE_CONFIGURED,                   /* most functions */