From ab14230854aba9d0c99b3cd0e4bb1ef430973d84 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 31 Oct 2011 00:48:00 -0700 Subject: usb: gadget: renesas_usbhs: check device0 status when alloc 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 Signed-off-by: Felipe Balbi diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 3f1eaf1..e6fd044 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -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"); -- cgit v0.10.2