aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPete Zaitcev <zaitcev@redhat.com>2010-01-08 15:39:22 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-15 08:50:08 -0700
commit0f43110993a731cb24ab39befc7cb1c265a4bf20 (patch)
tree5814e73ceba33cf539e79a08369ab0922b7ada7e
parent7de0f5637dd3df19f9914055b79fbdea872f4289 (diff)
USB: fix crash in uhci_scan_schedule
commit d23356da714595b888686d22cd19061323c09190 upstream. When hardware is removed on a Stratus, the system may crash like this: ACPI: PCI interrupt for device 0000:7c:00.1 disabled Trying to free nonexistent resource <00000000a8000000-00000000afffffff> Trying to free nonexistent resource <00000000a4800000-00000000a480ffff> uhci_hcd 0000:7e:1d.0: remove, state 1 usb usb2: USB disconnect, address 1 usb 2-1: USB disconnect, address 2 Unable to handle kernel paging request at 0000000000100100 RIP: [<ffffffff88021950>] :uhci_hcd:uhci_scan_schedule+0xa2/0x89c #4 [ffff81011de17e50] uhci_scan_schedule at ffffffff88021918 #5 [ffff81011de17ed0] uhci_irq at ffffffff88023cb8 #6 [ffff81011de17f10] usb_hcd_irq at ffffffff801f1c1f #7 [ffff81011de17f20] handle_IRQ_event at ffffffff8001123b #8 [ffff81011de17f50] __do_IRQ at ffffffff800ba749 This occurs because an interrupt scans uhci->skelqh, which is being freed. We do the right thing: disable the interrupts in the device, and do not do any processing if the interrupt is shared with other source, but it's possible that another CPU gets delayed somewhere (e.g. loops) until we started freeing. The agreed-upon solution is to wait for interrupts to play out before proceeding. No other bareers are neceesary. A backport of this patch was tested on a 2.6.18 based kernel. Testing of 2.6.32-based kernels is under way, but it takes us forever (months) to turn this around. So I think it's a good patch and we should keep it. Tracked in RH bz#516851 Signed-Off-By: Pete Zaitcev <zaitcev@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/host/uhci-hcd.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 99cd00fd3514..09197067fe6b 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -735,6 +735,7 @@ static void uhci_stop(struct usb_hcd *hcd)
uhci_hc_died(uhci);
uhci_scan_schedule(uhci);
spin_unlock_irq(&uhci->lock);
+ synchronize_irq(hcd->irq);
del_timer_sync(&uhci->fsbr_timer);
release_uhci(uhci);