diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2013-07-30 15:18:15 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-09-17 11:38:51 -0400 |
commit | 5f5610f69be3a925b1f79af27150bb7377bc9ad6 (patch) | |
tree | 8c1f09ec3d2928798a096fb8df9bb5cd3cd1683c /drivers/usb | |
parent | 2389df458b9e8222ef54fbb6e7023ead84b87a5c (diff) |
usb: gadget: fix a bug and a WARN_ON in dummy-hcd
This patch fixes a NULL pointer dereference and a WARN_ON in
dummy-hcd. These things were the result of moving to the UDC core
framework, and possibly of changes to that framework.
Now unloading a gadget driver causes the UDC to be stopped after the
gadget driver is unbound, not before. Therefore the "driver" argument
to dummy_udc_stop() can be NULL, so we must not try to print the
driver's name without checking first.
Also, the UDC framework automatically unregisters the gadget when the
UDC is deleted. Therefore a sysfs attribute file attached to the
gadget must be removed before the UDC is deleted, not after.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: <stable@vger.kernel.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/dummy_hcd.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 06ecd08fd57a..b8a2376971a4 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -923,8 +923,9 @@ static int dummy_udc_stop(struct usb_gadget *g, | |||
923 | struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); | 923 | struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); |
924 | struct dummy *dum = dum_hcd->dum; | 924 | struct dummy *dum = dum_hcd->dum; |
925 | 925 | ||
926 | dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", | 926 | if (driver) |
927 | driver->driver.name); | 927 | dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", |
928 | driver->driver.name); | ||
928 | 929 | ||
929 | dum->driver = NULL; | 930 | dum->driver = NULL; |
930 | 931 | ||
@@ -1000,8 +1001,8 @@ static int dummy_udc_remove(struct platform_device *pdev) | |||
1000 | { | 1001 | { |
1001 | struct dummy *dum = platform_get_drvdata(pdev); | 1002 | struct dummy *dum = platform_get_drvdata(pdev); |
1002 | 1003 | ||
1003 | usb_del_gadget_udc(&dum->gadget); | ||
1004 | device_remove_file(&dum->gadget.dev, &dev_attr_function); | 1004 | device_remove_file(&dum->gadget.dev, &dev_attr_function); |
1005 | usb_del_gadget_udc(&dum->gadget); | ||
1005 | return 0; | 1006 | return 0; |
1006 | } | 1007 | } |
1007 | 1008 | ||