From 1fd684346d41f6be2487c161f60d03a7feb68911 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 19 Jan 2009 20:57:36 +0100 Subject: SATA AHCI: Blacklist system that spins off disks during ACPI power off Some notebooks from HP have the problem that their BIOSes attempt to spin down hard drives before entering ACPI system states S4 and S5. This leads to a yo-yo effect during system power-off shutdown and the last phase of hibernation when the disk is first spun down by the kernel and then almost immediately turned on and off by the BIOS. This, in turn, may result in shortening the disk's life times. To prevent this from happening we can blacklist the affected systems using DMI information. Blacklist HP nx6310 that uses the AHCI driver. Signed-off-by: Rafael J. Wysocki Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers/ata/ahci.c') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 96039671e3b..77bba4c083c 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -2548,6 +2548,32 @@ static void ahci_p5wdh_workaround(struct ata_host *host) } } +static bool ahci_broken_system_poweroff(struct pci_dev *pdev) +{ + static const struct dmi_system_id broken_systems[] = { + { + .ident = "HP Compaq nx6310", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6310"), + }, + /* PCI slot number of the controller */ + .driver_data = (void *)0x1FUL, + }, + + { } /* terminate list */ + }; + const struct dmi_system_id *dmi = dmi_first_match(broken_systems); + + if (dmi) { + unsigned long slot = (unsigned long)dmi->driver_data; + /* apply the quirk only to on-board controllers */ + return slot == PCI_SLOT(pdev->devfn); + } + + return false; +} + static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; @@ -2647,6 +2673,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } } + if (ahci_broken_system_poweroff(pdev)) { + pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN; + dev_info(&pdev->dev, + "quirky BIOS, skipping spindown on poweroff\n"); + } + /* CAP.NP sometimes indicate the index of the last enabled * port, at other times, that of the last possible port, so * determining the maximum port number requires looking at -- cgit v1.2.3 From f3d7f23f87723a0947164ec88fc40e08254a64d6 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 26 Jan 2009 02:05:44 -0800 Subject: ahci: add a module parameter to ignore the SSS flags for async scanning The SSS flag, which directs the OS to spin up one disk at a time to not have the PSU blow out, sometimes gets set even when not needed. The effect of this is a longer-than-needed boot time. This patch adds a module parameter that makes the driver ignore SSS at least as far as the parallel scan during boot is concerned... Signed-off-by: Arjan van de Ven Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/ata/ahci.c') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 77bba4c083c..a603bbf9b1b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -61,9 +61,14 @@ #define EM_MSG_LED_VALUE_ON 0x00010000 static int ahci_skip_host_reset; +static int ahci_ignore_sss; + 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)"); +module_param_named(ignore_sss, ahci_ignore_sss, int, 0444); +MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)"); + static int ahci_enable_alpm(struct ata_port *ap, enum link_pm policy); static void ahci_disable_alpm(struct ata_port *ap); @@ -2692,8 +2697,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) host->iomap = pcim_iomap_table(pdev); host->private_data = hpriv; - if (!(hpriv->cap & HOST_CAP_SSS)) + if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) host->flags |= ATA_HOST_PARALLEL_SCAN; + else + printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n"); if (pi.flags & ATA_FLAG_EM) ahci_reset_em(host); -- cgit v1.2.3 From 7adbe46b9289794f8fe629cd78c876169741177f Mon Sep 17 00:00:00 2001 From: peerchen Date: Fri, 27 Feb 2009 16:58:41 +0800 Subject: ahci: Add the Device IDs for MCP89 and remove IDs of MCP7B to/from ahci.c Added the Device IDs for MCP89 AHCI controller. Removed the IDs of MCP7B because this chipset had been cancelled. Signed-off-by: Peer Chen Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/ata/ahci.c') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index a603bbf9b1b..66e012cd327 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -582,18 +582,18 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(NVIDIA, 0x0abd), board_ahci }, /* MCP79 */ { PCI_VDEVICE(NVIDIA, 0x0abe), board_ahci }, /* MCP79 */ { PCI_VDEVICE(NVIDIA, 0x0abf), board_ahci }, /* MCP79 */ - { PCI_VDEVICE(NVIDIA, 0x0bc8), board_ahci }, /* MCP7B */ - { PCI_VDEVICE(NVIDIA, 0x0bc9), board_ahci }, /* MCP7B */ - { PCI_VDEVICE(NVIDIA, 0x0bca), board_ahci }, /* MCP7B */ - { PCI_VDEVICE(NVIDIA, 0x0bcb), board_ahci }, /* MCP7B */ - { PCI_VDEVICE(NVIDIA, 0x0bcc), board_ahci }, /* MCP7B */ - { PCI_VDEVICE(NVIDIA, 0x0bcd), board_ahci }, /* MCP7B */ - { PCI_VDEVICE(NVIDIA, 0x0bce), board_ahci }, /* MCP7B */ - { PCI_VDEVICE(NVIDIA, 0x0bcf), board_ahci }, /* MCP7B */ - { PCI_VDEVICE(NVIDIA, 0x0bc4), board_ahci }, /* MCP7B */ - { PCI_VDEVICE(NVIDIA, 0x0bc5), board_ahci }, /* MCP7B */ - { PCI_VDEVICE(NVIDIA, 0x0bc6), board_ahci }, /* MCP7B */ - { PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci }, /* MCP7B */ + { PCI_VDEVICE(NVIDIA, 0x0d84), board_ahci }, /* MCP89 */ + { PCI_VDEVICE(NVIDIA, 0x0d85), board_ahci }, /* MCP89 */ + { PCI_VDEVICE(NVIDIA, 0x0d86), board_ahci }, /* MCP89 */ + { PCI_VDEVICE(NVIDIA, 0x0d87), board_ahci }, /* MCP89 */ + { PCI_VDEVICE(NVIDIA, 0x0d88), board_ahci }, /* MCP89 */ + { PCI_VDEVICE(NVIDIA, 0x0d89), board_ahci }, /* MCP89 */ + { PCI_VDEVICE(NVIDIA, 0x0d8a), board_ahci }, /* MCP89 */ + { PCI_VDEVICE(NVIDIA, 0x0d8b), board_ahci }, /* MCP89 */ + { PCI_VDEVICE(NVIDIA, 0x0d8c), board_ahci }, /* MCP89 */ + { PCI_VDEVICE(NVIDIA, 0x0d8d), board_ahci }, /* MCP89 */ + { PCI_VDEVICE(NVIDIA, 0x0d8e), board_ahci }, /* MCP89 */ + { PCI_VDEVICE(NVIDIA, 0x0d8f), board_ahci }, /* MCP89 */ /* SiS */ { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ -- cgit v1.2.3 From a5bfc4714b3f01365aef89a92673f2ceb1ccf246 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 23 Jan 2009 11:31:39 +0900 Subject: ahci: drop intx manipulation on msi enable There's no need to turn off intx explicitly on msi enable. This is automatically handled by pci. Drop it. This might be needed on machines if the BIOS turns intx off during boot. However, there's no evidence of such behavior for ahci and the only such case seems to be ICH5 PATA according to ata_piix. Also, given the way ahci operates, it's highly unlikely BIOS ever disables IRQ for the controller. However, as this change has slight possibility of introducing failure, please schedule it for #upstream. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/ata/ahci.c') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 66e012cd327..98d7a9fbb7e 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -2647,8 +2647,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; - if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) - pci_intx(pdev, 1); + if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) + pci_enable_msi(pdev); /* save initial config */ ahci_save_initial_config(pdev, hpriv); -- cgit v1.2.3 From d2f9c0614e664708978c53eca4a5963e92830e88 Mon Sep 17 00:00:00 2001 From: Maciej Rutecki Date: Fri, 20 Mar 2009 00:06:46 +0100 Subject: ahci: Blacklist HP Compaq 6720s that spins off disks during ACPI power off Blacklist HP Compaq 6720s so that it doesn't play a "spin down, spin up, spin down" ping-pong with the hard disk during system power off. Signed-off-by: Maciej Rutecki Signed-off-by: Rafael J. Wysocki Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/ata/ahci.c') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 98d7a9fbb7e..699789bc9ea 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -2565,6 +2565,15 @@ static bool ahci_broken_system_poweroff(struct pci_dev *pdev) /* PCI slot number of the controller */ .driver_data = (void *)0x1FUL, }, + { + .ident = "HP Compaq 6720s", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6720s"), + }, + /* PCI slot number of the controller */ + .driver_data = (void *)0x1FUL, + }, { } /* terminate list */ }; -- cgit v1.2.3 From 14bdef982caeda19afe34010482867c18217c641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Inge=20Bols=C3=B8?= Date: Sat, 14 Mar 2009 21:38:24 +0100 Subject: [libata] convert drivers to use ata.h mode mask defines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No functional changes in this patch. Signed-off-by: Erik Inge Bolsø Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/ata/ahci.c') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 699789bc9ea..ec2922ad2dc 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -404,7 +404,7 @@ static const struct ata_port_info ahci_port_info[] = { /* board_ahci */ { .flags = AHCI_FLAG_COMMON, - .pio_mask = 0x1f, /* pio0-4 */ + .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, @@ -412,7 +412,7 @@ static const struct ata_port_info ahci_port_info[] = { { AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP), .flags = AHCI_FLAG_COMMON, - .pio_mask = 0x1f, /* pio0-4 */ + .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_vt8251_ops, }, @@ -420,7 +420,7 @@ static const struct ata_port_info ahci_port_info[] = { { AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), .flags = AHCI_FLAG_COMMON, - .pio_mask = 0x1f, /* pio0-4 */ + .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, @@ -430,7 +430,7 @@ static const struct ata_port_info ahci_port_info[] = { AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255), .flags = AHCI_FLAG_COMMON, - .pio_mask = 0x1f, /* pio0-4 */ + .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_sb600_ops, }, @@ -440,7 +440,7 @@ static const struct ata_port_info ahci_port_info[] = { AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP), .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, - .pio_mask = 0x1f, /* pio0-4 */ + .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, @@ -448,7 +448,7 @@ static const struct ata_port_info ahci_port_info[] = { { AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL), .flags = AHCI_FLAG_COMMON, - .pio_mask = 0x1f, /* pio0-4 */ + .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_sb600_ops, }, @@ -456,7 +456,7 @@ static const struct ata_port_info ahci_port_info[] = { { AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), .flags = AHCI_FLAG_COMMON, - .pio_mask = 0x1f, /* pio0-4 */ + .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, @@ -464,7 +464,7 @@ static const struct ata_port_info ahci_port_info[] = { { AHCI_HFLAGS (AHCI_HFLAG_NO_PMP), .flags = AHCI_FLAG_COMMON, - .pio_mask = 0x1f, /* pio0-4 */ + .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, -- cgit v1.2.3 From 208f2a886a2f6cf329c9fcbf8d29a0dd245cc763 Mon Sep 17 00:00:00 2001 From: David Milburn Date: Fri, 20 Mar 2009 14:14:23 -0500 Subject: [libata] ahci: correct enclosure LED state save ahci_transmit_led_message saves off the led_state with a value that includes the port number OR'd in, this incorrect value maybe reported back in ahci_led_store. For instance, if you turn off all the leds for port 1 and cat the value back it will report 1 instead of 0. # echo 0 > /sys/class/scsi_host/host1/em_message # cat /sys/class/scsi_host/host1/em_message 1 Signed-off-by: David Milburn Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata/ahci.c') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index ec2922ad2dc..788bba2b1e1 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1348,7 +1348,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, writel(message[1], mmio + hpriv->em_loc+4); /* save off new led state for port/slot */ - emp->led_state = message[1]; + emp->led_state = state; /* * tell hardware to transmit the message -- cgit v1.2.3