In an error handling case the lock is not unlocked. The return is
converted to a goto, to share the unlock at the end of the function.
A simplified version of the semantic patch that finds this problem is as
follows: (http://coccinelle.lip6.fr/)
// <smpl>
@r exists@
expression E1;
identifier f;
@@
f (...) { <+...
* spin_lock_irqsave (E1,...);
... when != E1
* return ...;
...+> }
// </smpl>
Signed-off-by: Julia Lawall <julia@diku.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
u32 epctrl;
u32 mps;
int dir_in;
u32 epctrl;
u32 mps;
int dir_in;
dev_dbg(hsotg->dev,
"%s: ep %s: a 0x%02x, attr 0x%02x, mps 0x%04x, intr %d\n",
dev_dbg(hsotg->dev,
"%s: ep %s: a 0x%02x, attr 0x%02x, mps 0x%04x, intr %d\n",
switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
case USB_ENDPOINT_XFER_ISOC:
dev_err(hsotg->dev, "no current ISOC support\n");
switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
case USB_ENDPOINT_XFER_ISOC:
dev_err(hsotg->dev, "no current ISOC support\n");
+ ret = -EINVAL;
+ goto out;
case USB_ENDPOINT_XFER_BULK:
epctrl |= S3C_DxEPCTL_EPType_Bulk;
case USB_ENDPOINT_XFER_BULK:
epctrl |= S3C_DxEPCTL_EPType_Bulk;
/* enable the endpoint interrupt */
s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1);
/* enable the endpoint interrupt */
s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1);
spin_unlock_irqrestore(&hs_ep->lock, flags);
spin_unlock_irqrestore(&hs_ep->lock, flags);
}
static int s3c_hsotg_ep_disable(struct usb_ep *ep)
}
static int s3c_hsotg_ep_disable(struct usb_ep *ep)