aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/renesas_usbhs/mod_host.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-10-31 03:48:00 -0400
committerFelipe Balbi <balbi@ti.com>2011-12-12 04:45:07 -0500
commitab14230854aba9d0c99b3cd0e4bb1ef430973d84 (patch)
treef4c598256c6b61404883bfeda2aa5c66ff76866b /drivers/usb/renesas_usbhs/mod_host.c
parentc5b963f809f378d4fedd6f2f09b36f50c5a37bd5 (diff)
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 <kuninori.morimoto.gx@renesas.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/renesas_usbhs/mod_host.c')
-rw-r--r--drivers/usb/renesas_usbhs/mod_host.c36
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 3f1eaf15e0ba..e6fd044adfa3 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";
153#define usbhsh_usbv_to_udev(d) dev_get_drvdata(&(d)->dev) 153#define usbhsh_usbv_to_udev(d) dev_get_drvdata(&(d)->dev)
154 154
155#define usbhsh_udev_to_usbv(h) ((h)->usbv) 155#define usbhsh_udev_to_usbv(h) ((h)->usbv)
156#define usbhsh_udev_is_used(h) usbhsh_udev_to_usbv(h)
156 157
157#define usbhsh_pipe_info(p) ((p)->mod_private) 158#define usbhsh_pipe_info(p) ((p)->mod_private)
158 159
@@ -231,27 +232,34 @@ static struct usbhsh_device *usbhsh_device_alloc(struct usbhsh_hpriv *hpriv,
231 int i; 232 int i;
232 233
233 /* 234 /*
234 * device 0 235 * find device
235 */ 236 */
236 if (0 == usb_pipedevice(urb->pipe)) { 237 if (0 == usb_pipedevice(urb->pipe)) {
238 /*
239 * device0 is special case
240 */
237 udev = usbhsh_device0(hpriv); 241 udev = usbhsh_device0(hpriv);
238 goto usbhsh_device_find; 242 if (usbhsh_udev_is_used(udev))
239 } 243 udev = NULL;
244 } else {
245 struct usbhsh_device *pos;
240 246
241 /* 247 /*
242 * find unused device 248 * find unused device
243 */ 249 */
244 usbhsh_for_each_udev(udev, hpriv, i) { 250 usbhsh_for_each_udev(pos, hpriv, i) {
245 if (usbhsh_udev_to_usbv(udev)) 251 if (usbhsh_udev_is_used(pos))
246 continue; 252 continue;
247 goto usbhsh_device_find; 253 udev = pos;
254 break;
255 }
248 } 256 }
249 257
250 dev_err(dev, "no free usbhsh_device\n"); 258 if (!udev) {
251 259 dev_err(dev, "no free usbhsh_device\n");
252 return NULL; 260 return NULL;
261 }
253 262
254usbhsh_device_find:
255 if (usbhsh_device_has_endpoint(udev)) 263 if (usbhsh_device_has_endpoint(udev))
256 dev_warn(dev, "udev have old endpoint\n"); 264 dev_warn(dev, "udev have old endpoint\n");
257 265