From: lyz Date: Mon, 19 Jan 2015 10:55:56 +0000 (+0800) Subject: usb: dwc_otg: fix issue with race condition of competition X-Git-Tag: firefly_0821_release~4279 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b1e25b6bf255cecf4d022099857d200cbc681661;p=firefly-linux-kernel-4.4.55.git usb: dwc_otg: fix issue with race condition of competition between hcd_reinit() and cil_interrupt handler. hcd_reinit() should get core_if->lock before modify this lock, so that can prevent competition between cil_interrupt handler and hcd_reinit(), hcd_reinit() be scheduled while cil_interrupt handler holding core_if->lock, hcd_reinit() modify the lock then previous core_if->lock will never be unlocked. Signed-off-by: lyz --- diff --git a/drivers/usb/dwc_otg_310/dwc_otg_hcd.c b/drivers/usb/dwc_otg_310/dwc_otg_hcd.c index 451424e84204..7602e4f851f6 100755 --- a/drivers/usb/dwc_otg_310/dwc_otg_hcd.c +++ b/drivers/usb/dwc_otg_310/dwc_otg_hcd.c @@ -966,9 +966,9 @@ static void dwc_otg_hcd_reinit(dwc_otg_hcd_t *hcd) dwc_hc_t *channel; dwc_hc_t *channel_tmp; dwc_irqflags_t flags; + dwc_spinlock_t *temp_lock; hcd->flags.d32 = 0; - hcd->non_periodic_qh_ptr = &hcd->non_periodic_sched_active; hcd->non_periodic_channels = 0; hcd->periodic_channels = 0; @@ -995,7 +995,15 @@ static void dwc_otg_hcd_reinit(dwc_otg_hcd_t *hcd) dwc_otg_core_host_init(hcd->core_if); /* Set core_if's lock pointer to the hcd->lock */ - hcd->core_if->lock = hcd->lock; + /* Should get this lock before modify it */ + if (hcd->core_if->lock) { + DWC_SPINLOCK_IRQSAVE(hcd->core_if->lock, &flags); + temp_lock = hcd->core_if->lock; + hcd->core_if->lock = hcd->lock; + DWC_SPINUNLOCK_IRQRESTORE(temp_lock, flags); + } else { + hcd->core_if->lock = hcd->lock; + } } /**