summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-03-10 10:25:25 +0900
committerJeff Garzik <jeff@garzik.org>2008-03-17 08:26:50 -0400
commita22e64443f0aa4aa4e3c56a49e5c060e90752c07 (patch)
treecc9db844ba0099aced1ad1faf3859da84ab75a09 /drivers/ata
parentdea55137634226fd74d5187a15dee1244ec252cb (diff)
downloadlinux-a22e64443f0aa4aa4e3c56a49e5c060e90752c07.tar.gz
linux-a22e64443f0aa4aa4e3c56a49e5c060e90752c07.tar.bz2
linux-a22e64443f0aa4aa4e3c56a49e5c060e90752c07.zip
ahci: implement skip_host_reset parameter
Under certain circumstances (SSP turned off by the BIOS) and for debugging purposes, skipping global controller reset is helpful. Add a kernel parameter for it. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/ahci.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 53f5afd9420c..bbfccdbba3ab 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -49,6 +49,10 @@
#define DRV_NAME "ahci"
#define DRV_VERSION "3.0"
+static int ahci_skip_host_reset;
+module_param_named(skip_host_reset, ahci_skip_host_reset, int, 0444);
+MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)");
+
static int ahci_enable_alpm(struct ata_port *ap,
enum link_pm policy);
static void ahci_disable_alpm(struct ata_port *ap);
@@ -1088,29 +1092,35 @@ static int ahci_reset_controller(struct ata_host *host)
ahci_enable_ahci(mmio);
/* global controller reset */
- tmp = readl(mmio + HOST_CTL);
- if ((tmp & HOST_RESET) == 0) {
- writel(tmp | HOST_RESET, mmio + HOST_CTL);
- readl(mmio + HOST_CTL); /* flush */
- }
+ if (!ahci_skip_host_reset) {
+ tmp = readl(mmio + HOST_CTL);
+ if ((tmp & HOST_RESET) == 0) {
+ writel(tmp | HOST_RESET, mmio + HOST_CTL);
+ readl(mmio + HOST_CTL); /* flush */
+ }
- /* reset must complete within 1 second, or
- * the hardware should be considered fried.
- */
- ssleep(1);
+ /* reset must complete within 1 second, or
+ * the hardware should be considered fried.
+ */
+ ssleep(1);
- tmp = readl(mmio + HOST_CTL);
- if (tmp & HOST_RESET) {
- dev_printk(KERN_ERR, host->dev,
- "controller reset failed (0x%x)\n", tmp);
- return -EIO;
- }
+ tmp = readl(mmio + HOST_CTL);
+ if (tmp & HOST_RESET) {
+ dev_printk(KERN_ERR, host->dev,
+ "controller reset failed (0x%x)\n", tmp);
+ return -EIO;
+ }
- /* turn on AHCI mode */
- ahci_enable_ahci(mmio);
+ /* turn on AHCI mode */
+ ahci_enable_ahci(mmio);
- /* some registers might be cleared on reset. restore initial values */
- ahci_restore_initial_config(host);
+ /* Some registers might be cleared on reset. Restore
+ * initial values.
+ */
+ ahci_restore_initial_config(host);
+ } else
+ dev_printk(KERN_INFO, host->dev,
+ "skipping global host reset\n");
if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
u16 tmp16;