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@xxxxxxxxxxx> --- drivers/usb/renesas_usbhs/mod_host.c | 36 ++++++++++++++++++++------------- 1 files changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 491b8d8..330fca3 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"); -- 1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html