USB: composite: Hold spinlock before calling usb_func_wakeup_int() API
There is a chance that composite_resume might race with android_disable if composition switch happens and at the same time, reset interrupt is triggered. In this case, it could lead to accessing invalid address as composite_resume() not calling usb_func_wakeup_int() without holding spinlock. Hence modfiy usb_func_wakeup_int() such that caller of this function should call it with spinlock holding to fix the issue. CRs-Fixed: 799332 Change-Id: I97ef374923504977ac8fc32954dd7de834a01041 Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org> Signed-off-by: Azhar Shaikh <azhars@codeaurora.org>
This commit is contained in:
parent
7010bdba62
commit
15d49a1051
1 changed files with 7 additions and 7 deletions
|
@ -367,9 +367,7 @@ EXPORT_SYMBOL_GPL(usb_interface_id);
|
|||
static int usb_func_wakeup_int(struct usb_function *func)
|
||||
{
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
struct usb_gadget *gadget;
|
||||
struct usb_composite_dev *cdev;
|
||||
|
||||
pr_debug("%s - %s function wakeup\n",
|
||||
__func__, func->name ? func->name : "");
|
||||
|
@ -388,11 +386,7 @@ static int usb_func_wakeup_int(struct usb_function *func)
|
|||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
cdev = get_gadget_data(gadget);
|
||||
|
||||
spin_lock_irqsave(&cdev->lock, flags);
|
||||
ret = usb_gadget_func_wakeup(gadget, func->intf_id);
|
||||
spin_unlock_irqrestore(&cdev->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -400,10 +394,12 @@ static int usb_func_wakeup_int(struct usb_function *func)
|
|||
int usb_func_wakeup(struct usb_function *func)
|
||||
{
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
pr_debug("%s function wakeup\n",
|
||||
func->name ? func->name : "");
|
||||
|
||||
spin_lock_irqsave(&func->config->cdev->lock, flags);
|
||||
ret = usb_func_wakeup_int(func);
|
||||
if (ret == -EAGAIN) {
|
||||
DBG(func->config->cdev,
|
||||
|
@ -416,6 +412,7 @@ int usb_func_wakeup(struct usb_function *func)
|
|||
func->name ? func->name : "", ret);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&func->config->cdev->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_func_wakeup);
|
||||
|
@ -2250,7 +2247,8 @@ void composite_resume(struct usb_gadget *gadget)
|
|||
struct usb_composite_dev *cdev = get_gadget_data(gadget);
|
||||
struct usb_function *f;
|
||||
u16 maxpower;
|
||||
int ret;
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
/* REVISIT: should we have config level
|
||||
* suspend/resume callbacks?
|
||||
|
@ -2259,6 +2257,7 @@ void composite_resume(struct usb_gadget *gadget)
|
|||
if (cdev->driver->resume)
|
||||
cdev->driver->resume(cdev);
|
||||
|
||||
spin_lock_irqsave(&cdev->lock, flags);
|
||||
if (cdev->config) {
|
||||
list_for_each_entry(f, &cdev->config->functions, list) {
|
||||
ret = usb_func_wakeup_int(f);
|
||||
|
@ -2286,6 +2285,7 @@ void composite_resume(struct usb_gadget *gadget)
|
|||
maxpower : CONFIG_USB_GADGET_VBUS_DRAW);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&cdev->lock, flags);
|
||||
cdev->suspended = 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue