usb: gadget: renesas_usbhs: check device0 status when alloc
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Mon, 31 Oct 2011 07:48:00 +0000 (00:48 -0700)
committerFelipe Balbi <balbi@ti.com>
Mon, 12 Dec 2011 09:45:07 +0000 (11:45 +0200)
device0 was treated without checking in usbhsh_device_alloc().
but "udev->usbv" and "dev_set_drvdata()" will be overwritten
if device0  was multi-allocated.
This patch fixes this issue.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/renesas_usbhs/mod_host.c

index 3f1eaf15e0ba1523a39b993be47b867ad5ffaa78..e6fd044adfa32a802af7622701cf01b2ba224d51 100644 (file)
@@ -153,6 +153,7 @@ static const char usbhsh_hcd_name[] = "renesas_usbhs host";
 #define usbhsh_usbv_to_udev(d) dev_get_drvdata(&(d)->dev)
 
 #define usbhsh_udev_to_usbv(h) ((h)->usbv)
+#define usbhsh_udev_is_used(h) usbhsh_udev_to_usbv(h)
 
 #define usbhsh_pipe_info(p)    ((p)->mod_private)
 
@@ -231,27 +232,34 @@ static struct usbhsh_device *usbhsh_device_alloc(struct usbhsh_hpriv *hpriv,
        int i;
 
        /*
-        * device 0
+        * find device
         */
        if (0 == usb_pipedevice(urb->pipe)) {
+               /*
+                * device0 is special case
+                */
                udev = usbhsh_device0(hpriv);
-               goto usbhsh_device_find;
-       }
+               if (usbhsh_udev_is_used(udev))
+                       udev = NULL;
+       } else {
+               struct usbhsh_device *pos;
 
-       /*
-        * find unused device
-        */
-       usbhsh_for_each_udev(udev, hpriv, i) {
-               if (usbhsh_udev_to_usbv(udev))
-                       continue;
-               goto usbhsh_device_find;
+               /*
+                * find unused device
+                */
+               usbhsh_for_each_udev(pos, hpriv, i) {
+                       if (usbhsh_udev_is_used(pos))
+                               continue;
+                       udev = pos;
+                       break;
+               }
        }
 
-       dev_err(dev, "no free usbhsh_device\n");
-
-       return NULL;
+       if (!udev) {
+               dev_err(dev, "no free usbhsh_device\n");
+               return NULL;
+       }
 
-usbhsh_device_find:
        if (usbhsh_device_has_endpoint(udev))
                dev_warn(dev, "udev have old endpoint\n");