From 6e5dcf64dfc2415a59987a4096b4ebbf03469bf6 Mon Sep 17 00:00:00 2001 From: Vasily Averin Date: Fri, 11 Nov 2011 13:42:16 +0400 Subject: aacraid: controller hangs if kernel uses non-default ASPM policy commit cf16123c9c8e346ed1dd171295a678d77648d7f8 upstream. Aacraid controller can hang on some nodes if kernel uses non-default (powersave) ASPM policy. Controller hangs shortly after successful load and hardware detection. Scsi error handler detects this hang and tries to restart hardware but it does not help. Initially it was noticed on RHEL6-based openVZ kernel after backporting aacraid driver from mainline (RHEL6 kernel with original driver works well) http://bugzilla.openvz.org/show_bug.cgi?id=2043 This issue happens because default ASPM policy was changed in Red Hat kernels. Therefore guys from Red Hat have noticed this problem long time ago: on Fedora 12 https://bugzilla.redhat.com/show_bug.cgi?id=540478 on Fedora 14 https://bugzilla.redhat.com/show_bug.cgi?id=679385 In RHEL6 kernel this issue was fixed, ASPM was disabled in aacraid driver. In kernel changelog I've found that seems it was done by Matthew Garrett: - [scsi] aacraid: Disable ASPM by default (Matthew Garrett) [599735] However seems this patch was not submitted to mainline. I've reproduced this issue on vanilla 3.1.0 kernel booted with "pcie_aspm.policy=powersave" option, So I believe it makes sense to do it now. Signed-off-by: Vasily Averin [mjg: Checking the Windows drivers indicates that they disable ASPM under all circumstances, so:] Acked-by: Matthew Garrett Acked-by: Achim Leubner Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/aacraid/linit.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 3382475dc22..c7b6fed8873 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -1108,6 +1109,9 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, unique_id++; } + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); + error = pci_enable_device(pdev); if (error) goto out; -- cgit v1.2.3