SATA PIIX: 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 2510p that uses the ata_piix driver.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>

authored by Rafael J. Wysocki and committed by Jeff Garzik 5f451fe1 e57db7bd

+34
+34
drivers/ata/ata_piix.c
··· 1387 1387 } 1388 1388 } 1389 1389 1390 + static bool piix_broken_system_poweroff(struct pci_dev *pdev) 1391 + { 1392 + static const struct dmi_system_id broken_systems[] = { 1393 + { 1394 + .ident = "HP Compaq 2510p", 1395 + .matches = { 1396 + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 1397 + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 2510p"), 1398 + }, 1399 + /* PCI slot number of the controller */ 1400 + .driver_data = (void *)0x1FUL, 1401 + }, 1402 + 1403 + { } /* terminate list */ 1404 + }; 1405 + const struct dmi_system_id *dmi = dmi_first_match(broken_systems); 1406 + 1407 + if (dmi) { 1408 + unsigned long slot = (unsigned long)dmi->driver_data; 1409 + /* apply the quirk only to on-board controllers */ 1410 + return slot == PCI_SLOT(pdev->devfn); 1411 + } 1412 + 1413 + return false; 1414 + } 1415 + 1390 1416 /** 1391 1417 * piix_init_one - Register PIIX ATA PCI device with kernel services 1392 1418 * @pdev: PCI device to register ··· 1447 1421 /* no hotplugging support (FIXME) */ 1448 1422 if (!in_module_init) 1449 1423 return -ENODEV; 1424 + 1425 + if (piix_broken_system_poweroff(pdev)) { 1426 + piix_port_info[ent->driver_data].flags |= 1427 + ATA_FLAG_NO_POWEROFF_SPINDOWN | 1428 + ATA_FLAG_NO_HIBERNATE_SPINDOWN; 1429 + dev_info(&pdev->dev, "quirky BIOS, skipping spindown " 1430 + "on poweroff and hibernation\n"); 1431 + } 1450 1432 1451 1433 port_info[0] = piix_port_info[ent->driver_data]; 1452 1434 port_info[1] = piix_port_info[ent->driver_data];