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 <lyz@rock-chips.com>
This commit is contained in:
lyz
2015-01-19 18:55:56 +08:00
parent f38ab909f0
commit b1e25b6bf2

View File

@@ -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;
}
}
/**