usb: dwc3: take lock while modifying flags
authorPaul Zimmerman <Paul.Zimmerman@synopsys.com>
Sat, 25 Feb 2012 01:32:16 +0000 (17:32 -0800)
committerFelipe Balbi <balbi@ti.com>
Fri, 2 Mar 2012 10:12:10 +0000 (12:12 +0200)
dwc3_gadget_ep_set_wedge() and dwc3_gadget_set_selfpowered() were
modifying dwc->flags/dwc->is_selfpowered without taking the lock.
Since those modifications are non-atomic, that could cause other
flags to be corrupted. Fix them both to take the lock.

Signed-off-by: Paul Zimmerman <paulz@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/dwc3/gadget.c

index e2633dd03f8c22c7935128c2e0da0ecaad669e37..bfdfd4f151f8e46814af119a7ce7bb205ac4dd37 100644 (file)
@@ -1196,8 +1196,12 @@ out:
 static int dwc3_gadget_ep_set_wedge(struct usb_ep *ep)
 {
        struct dwc3_ep                  *dep = to_dwc3_ep(ep);
+       struct dwc3                     *dwc = dep->dwc;
+       unsigned long                   flags;
 
+       spin_lock_irqsave(&dwc->lock, flags);
        dep->flags |= DWC3_EP_WEDGE;
+       spin_unlock_irqrestore(&dwc->lock, flags);
 
        return dwc3_gadget_ep_set_halt(ep, 1);
 }
@@ -1323,8 +1327,11 @@ static int dwc3_gadget_set_selfpowered(struct usb_gadget *g,
                int is_selfpowered)
 {
        struct dwc3             *dwc = gadget_to_dwc(g);
+       unsigned long           flags;
 
+       spin_lock_irqsave(&dwc->lock, flags);
        dwc->is_selfpowered = !!is_selfpowered;
+       spin_unlock_irqrestore(&dwc->lock, flags);
 
        return 0;
 }