From 35e2bce6a0a27433a92233a4d36df71dec9dd4fe Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 Feb 2012 14:55:37 -0800 Subject: [PATCH] 3.0-stable patches added patches: usb-don-t-fail-usb3-probe-on-missing-legacy-pci-irq.patch usb-storage-fix-freezing-of-the-scanning-thread.patch --- queue-3.0/series | 2 + ...usb3-probe-on-missing-legacy-pci-irq.patch | 86 +++++++ ...-fix-freezing-of-the-scanning-thread.patch | 210 ++++++++++++++++++ 3 files changed, 298 insertions(+) create mode 100644 queue-3.0/usb-don-t-fail-usb3-probe-on-missing-legacy-pci-irq.patch create mode 100644 queue-3.0/usb-storage-fix-freezing-of-the-scanning-thread.patch diff --git a/queue-3.0/series b/queue-3.0/series index e2f45fd712a..3465959c281 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -48,3 +48,5 @@ i387-do-not-preload-fpu-state-at-task-switch-time.patch i387-move-amd-k7-k8-fpu-fxsave-fxrstor-workaround-from-save-to-restore.patch i387-move-ts_usedfpu-flag-from-thread_info-to-task_struct.patch i387-re-introduce-fpu-state-preloading-at-context-switch-time.patch +usb-storage-fix-freezing-of-the-scanning-thread.patch +usb-don-t-fail-usb3-probe-on-missing-legacy-pci-irq.patch diff --git a/queue-3.0/usb-don-t-fail-usb3-probe-on-missing-legacy-pci-irq.patch b/queue-3.0/usb-don-t-fail-usb3-probe-on-missing-legacy-pci-irq.patch new file mode 100644 index 00000000000..b51d3da84eb --- /dev/null +++ b/queue-3.0/usb-don-t-fail-usb3-probe-on-missing-legacy-pci-irq.patch @@ -0,0 +1,86 @@ +From sarah.a.sharp@linux.intel.com Thu Feb 23 14:49:24 2012 +From: Sarah Sharp +Date: Thu, 23 Feb 2012 13:20:13 -0800 +Subject: USB: Don't fail USB3 probe on missing legacy PCI IRQ. +To: stable@vger.kernel.org +Cc: gregkh@linuxfoundation.org, alex.shi@intel.com +Message-ID: <20120223212013.GA22259@xanatos> +Content-Disposition: inline + +From: Sarah Sharp + +commit 68d07f64b8a11a852d48d1b05b724c3e20c0d94b upstream + +Intel has a PCI USB xhci host controller on a new platform. It doesn't +have a line IRQ definition in BIOS. The Linux driver refuses to +initialize this controller, but Windows works well because it only depends +on MSI. + +Actually, Linux also can work for MSI. This patch avoids the line IRQ +checking for USB3 HCDs in usb core PCI probe. It allows the xHCI driver +to try to enable MSI or MSI-X first. It will fail the probe if MSI +enabling failed and there's no legacy PCI IRQ. + +This patch should be backported to kernels as old as 2.6.32. + +[Maintainer note: This patch is a backport of commit +68d07f64b8a11a852d48d1b05b724c3e20c0d94b "USB: Don't fail USB3 probe on +missing legacy PCI IRQ." to the 3.0 kernel. Note, the original patch +description was wrong. We should not back port this to kernels older +than 2.6.36, since that was the first kernel to support MSI and MSI-X +for xHCI hosts. These systems will just not work without MSI support, +so the probe should fail on kernels older than 2.6.36.] + +Signed-off-by: Alex Shi +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hcd-pci.c | 5 ++++- + drivers/usb/core/hcd.c | 6 ++++-- + drivers/usb/host/xhci.c | 5 +++++ + 3 files changed, 13 insertions(+), 3 deletions(-) + +--- a/drivers/usb/core/hcd-pci.c ++++ b/drivers/usb/core/hcd-pci.c +@@ -187,7 +187,10 @@ int usb_hcd_pci_probe(struct pci_dev *de + return -ENODEV; + dev->current_state = PCI_D0; + +- if (!dev->irq) { ++ /* The xHCI driver supports MSI and MSI-X, ++ * so don't fail if the BIOS doesn't provide a legacy IRQ. ++ */ ++ if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) { + dev_err(&dev->dev, + "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", + pci_name(dev)); +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -2435,8 +2435,10 @@ int usb_add_hcd(struct usb_hcd *hcd, + && device_can_wakeup(&hcd->self.root_hub->dev)) + dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); + +- /* enable irqs just before we start the controller */ +- if (usb_hcd_is_primary_hcd(hcd)) { ++ /* enable irqs just before we start the controller, ++ * if the BIOS provides legacy PCI irqs. ++ */ ++ if (usb_hcd_is_primary_hcd(hcd) && irqnum) { + retval = usb_hcd_request_irqs(hcd, irqnum, irqflags); + if (retval) + goto err_request_irq; +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -444,6 +444,11 @@ int xhci_run(struct usb_hcd *hcd) + + if (ret) { + legacy_irq: ++ if (!pdev->irq) { ++ xhci_err(xhci, "No msi-x/msi found and " ++ "no IRQ in BIOS\n"); ++ return -EINVAL; ++ } + /* fall back to legacy interrupt*/ + ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, + hcd->irq_descr, hcd); diff --git a/queue-3.0/usb-storage-fix-freezing-of-the-scanning-thread.patch b/queue-3.0/usb-storage-fix-freezing-of-the-scanning-thread.patch new file mode 100644 index 00000000000..4ffa389ad67 --- /dev/null +++ b/queue-3.0/usb-storage-fix-freezing-of-the-scanning-thread.patch @@ -0,0 +1,210 @@ +From bb94a406682770a35305daaa241ccdb7cab399de Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 21 Feb 2012 13:16:32 -0500 +Subject: usb-storage: fix freezing of the scanning thread + +From: Alan Stern + +commit bb94a406682770a35305daaa241ccdb7cab399de upstream. + +This patch (as1521b) fixes the interaction between usb-storage's +scanning thread and the freezer. The current implementation has a +race: If the device is unplugged shortly after being plugged in and +just as a system sleep begins, the scanning thread may get frozen +before the khubd task. Khubd won't be able to freeze until the +disconnect processing is complete, and the disconnect processing can't +proceed until the scanning thread finishes, so the sleep transition +will fail. + +The implementation in the 3.2 kernel suffers from an additional +problem. There the scanning thread calls set_freezable_with_signal(), +and the signals sent by the freezer will mess up the thread's I/O +delays, which are all interruptible. + +The solution to both problems is the same: Replace the kernel thread +used for scanning with a delayed-work routine on the system freezable +work queue. Freezable work queues have the nice property that you can +cancel a work item even while the work queue is frozen, and no signals +are needed. + +The 3.2 version of this patch solves the problem in Bugzilla #42730. + +Signed-off-by: Alan Stern +Acked-by: Seth Forshee +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/usb.c | 91 ++++++++++++++++------------------------------ + drivers/usb/storage/usb.h | 7 ++- + 2 files changed, 36 insertions(+), 62 deletions(-) + +--- a/drivers/usb/storage/usb.c ++++ b/drivers/usb/storage/usb.c +@@ -788,15 +788,19 @@ static void quiesce_and_remove_host(stru + struct Scsi_Host *host = us_to_host(us); + + /* If the device is really gone, cut short reset delays */ +- if (us->pusb_dev->state == USB_STATE_NOTATTACHED) ++ if (us->pusb_dev->state == USB_STATE_NOTATTACHED) { + set_bit(US_FLIDX_DISCONNECTING, &us->dflags); ++ wake_up(&us->delay_wait); ++ } + +- /* Prevent SCSI-scanning (if it hasn't started yet) +- * and wait for the SCSI-scanning thread to stop. ++ /* Prevent SCSI scanning (if it hasn't started yet) ++ * or wait for the SCSI-scanning routine to stop. + */ +- set_bit(US_FLIDX_DONT_SCAN, &us->dflags); +- wake_up(&us->delay_wait); +- wait_for_completion(&us->scanning_done); ++ cancel_delayed_work_sync(&us->scan_dwork); ++ ++ /* Balance autopm calls if scanning was cancelled */ ++ if (test_bit(US_FLIDX_SCAN_PENDING, &us->dflags)) ++ usb_autopm_put_interface_no_suspend(us->pusb_intf); + + /* Removing the host will perform an orderly shutdown: caches + * synchronized, disks spun down, etc. +@@ -823,52 +827,28 @@ static void release_everything(struct us + scsi_host_put(us_to_host(us)); + } + +-/* Thread to carry out delayed SCSI-device scanning */ +-static int usb_stor_scan_thread(void * __us) ++/* Delayed-work routine to carry out SCSI-device scanning */ ++static void usb_stor_scan_dwork(struct work_struct *work) + { +- struct us_data *us = (struct us_data *)__us; ++ struct us_data *us = container_of(work, struct us_data, ++ scan_dwork.work); + struct device *dev = &us->pusb_intf->dev; + +- dev_dbg(dev, "device found\n"); +- +- set_freezable_with_signal(); +- /* +- * Wait for the timeout to expire or for a disconnect +- * +- * We can't freeze in this thread or we risk causing khubd to +- * fail to freeze, but we can't be non-freezable either. Nor can +- * khubd freeze while waiting for scanning to complete as it may +- * hold the device lock, causing a hang when suspending devices. +- * So we request a fake signal when freezing and use +- * interruptible sleep to kick us out of our wait early when +- * freezing happens. +- */ +- if (delay_use > 0) { +- dev_dbg(dev, "waiting for device to settle " +- "before scanning\n"); +- wait_event_interruptible_timeout(us->delay_wait, +- test_bit(US_FLIDX_DONT_SCAN, &us->dflags), +- delay_use * HZ); +- } +- +- /* If the device is still connected, perform the scanning */ +- if (!test_bit(US_FLIDX_DONT_SCAN, &us->dflags)) { +- +- /* For bulk-only devices, determine the max LUN value */ +- if (us->protocol == USB_PR_BULK && +- !(us->fflags & US_FL_SINGLE_LUN)) { +- mutex_lock(&us->dev_mutex); +- us->max_lun = usb_stor_Bulk_max_lun(us); +- mutex_unlock(&us->dev_mutex); +- } +- scsi_scan_host(us_to_host(us)); +- dev_dbg(dev, "scan complete\n"); ++ dev_dbg(dev, "starting scan\n"); + +- /* Should we unbind if no devices were detected? */ ++ /* For bulk-only devices, determine the max LUN value */ ++ if (us->protocol == USB_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN)) { ++ mutex_lock(&us->dev_mutex); ++ us->max_lun = usb_stor_Bulk_max_lun(us); ++ mutex_unlock(&us->dev_mutex); + } ++ scsi_scan_host(us_to_host(us)); ++ dev_dbg(dev, "scan complete\n"); ++ ++ /* Should we unbind if no devices were detected? */ + + usb_autopm_put_interface(us->pusb_intf); +- complete_and_exit(&us->scanning_done, 0); ++ clear_bit(US_FLIDX_SCAN_PENDING, &us->dflags); + } + + static unsigned int usb_stor_sg_tablesize(struct usb_interface *intf) +@@ -915,7 +895,7 @@ int usb_stor_probe1(struct us_data **pus + init_completion(&us->cmnd_ready); + init_completion(&(us->notify)); + init_waitqueue_head(&us->delay_wait); +- init_completion(&us->scanning_done); ++ INIT_DELAYED_WORK(&us->scan_dwork, usb_stor_scan_dwork); + + /* Associate the us_data structure with the USB device */ + result = associate_dev(us, intf); +@@ -946,7 +926,6 @@ EXPORT_SYMBOL_GPL(usb_stor_probe1); + /* Second part of general USB mass-storage probing */ + int usb_stor_probe2(struct us_data *us) + { +- struct task_struct *th; + int result; + struct device *dev = &us->pusb_intf->dev; + +@@ -987,20 +966,14 @@ int usb_stor_probe2(struct us_data *us) + goto BadDevice; + } + +- /* Start up the thread for delayed SCSI-device scanning */ +- th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan"); +- if (IS_ERR(th)) { +- dev_warn(dev, +- "Unable to start the device-scanning thread\n"); +- complete(&us->scanning_done); +- quiesce_and_remove_host(us); +- result = PTR_ERR(th); +- goto BadDevice; +- } +- ++ /* Submit the delayed_work for SCSI-device scanning */ + usb_autopm_get_interface_no_resume(us->pusb_intf); +- wake_up_process(th); ++ set_bit(US_FLIDX_SCAN_PENDING, &us->dflags); + ++ if (delay_use > 0) ++ dev_dbg(dev, "waiting for device to settle before scanning\n"); ++ queue_delayed_work(system_freezable_wq, &us->scan_dwork, ++ delay_use * HZ); + return 0; + + /* We come here if there are any problems */ +--- a/drivers/usb/storage/usb.h ++++ b/drivers/usb/storage/usb.h +@@ -47,6 +47,7 @@ + #include + #include + #include ++#include + #include + + struct us_data; +@@ -72,7 +73,7 @@ struct us_unusual_dev { + #define US_FLIDX_DISCONNECTING 3 /* disconnect in progress */ + #define US_FLIDX_RESETTING 4 /* device reset in progress */ + #define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */ +-#define US_FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */ ++#define US_FLIDX_SCAN_PENDING 6 /* scanning not yet done */ + #define US_FLIDX_REDO_READ10 7 /* redo READ(10) command */ + #define US_FLIDX_READ10_WORKED 8 /* previous READ(10) succeeded */ + +@@ -147,8 +148,8 @@ struct us_data { + /* mutual exclusion and synchronization structures */ + struct completion cmnd_ready; /* to sleep thread on */ + struct completion notify; /* thread begin/end */ +- wait_queue_head_t delay_wait; /* wait during scan, reset */ +- struct completion scanning_done; /* wait for scan thread */ ++ wait_queue_head_t delay_wait; /* wait during reset */ ++ struct delayed_work scan_dwork; /* for async scanning */ + + /* subdriver information */ + void *extra; /* Any extra data */ -- 2.47.3