Commit 166a2967b45ede2e2e56f3ede3cd32053dc17812

Authored by Aaron Lu
Committed by Jeff Garzik
1 parent b1354cbb5b

libata: tell scsi layer device supports runtime power off

If ATA device supports "Device Attention", then tell scsi layer that
the device supports runtime power off.

Signed-off-by: Aaron Lu <aaron.lu@amd.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>

Showing 2 changed files with 27 additions and 2 deletions Side-by-side Diff

drivers/ata/libata-acpi.c
... ... @@ -1000,7 +1000,10 @@
1000 1000 return;
1001 1001  
1002 1002 status = acpi_bus_get_device(handle, &acpi_dev);
1003   - if (ACPI_SUCCESS(status)) {
  1003 + if (ACPI_FAILURE(status))
  1004 + return;
  1005 +
  1006 + if (dev->sdev->can_power_off) {
1004 1007 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
1005 1008 ata_acpi_wake_dev, dev);
1006 1009 device_set_run_wake(&dev->sdev->sdev_gendev, true);
... ... @@ -1018,7 +1021,10 @@
1018 1021 return;
1019 1022  
1020 1023 status = acpi_bus_get_device(handle, &acpi_dev);
1021   - if (ACPI_SUCCESS(status)) {
  1024 + if (ACPI_FAILURE(status))
  1025 + return;
  1026 +
  1027 + if (dev->sdev->can_power_off) {
1022 1028 device_set_run_wake(&dev->sdev->sdev_gendev, false);
1023 1029 acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
1024 1030 ata_acpi_wake_dev);
... ... @@ -1102,6 +1108,9 @@
1102 1108 acpi_handle *handle)
1103 1109 {
1104 1110 struct ata_device *ata_dev;
  1111 + acpi_status status;
  1112 + struct acpi_device *acpi_dev;
  1113 + struct acpi_device_power_state *states;
1105 1114  
1106 1115 if (ap->flags & ATA_FLAG_ACPI_SATA)
1107 1116 ata_dev = &ap->link.device[sdev->channel];
... ... @@ -1112,6 +1121,21 @@
1112 1121  
1113 1122 if (!*handle)
1114 1123 return -ENODEV;
  1124 +
  1125 + status = acpi_bus_get_device(*handle, &acpi_dev);
  1126 + if (ACPI_FAILURE(status))
  1127 + return 0;
  1128 +
  1129 + /*
  1130 + * If firmware has _PS3 or _PR3 for this device,
  1131 + * and this ata ODD device support device attention,
  1132 + * it means this device can be powered off
  1133 + */
  1134 + states = acpi_dev->power.states;
  1135 + if ((states[ACPI_STATE_D3_HOT].flags.valid ||
  1136 + states[ACPI_STATE_D3_COLD].flags.explicit_set) &&
  1137 + ata_dev->flags & ATA_DFLAG_DA)
  1138 + sdev->can_power_off = 1;
1115 1139  
1116 1140 return 0;
1117 1141 }
include/scsi/scsi_device.h
... ... @@ -153,6 +153,7 @@
153 153 unsigned no_read_capacity_16:1; /* Avoid READ_CAPACITY_16 cmds */
154 154 unsigned try_rc_10_first:1; /* Try READ_CAPACACITY_10 first */
155 155 unsigned is_visible:1; /* is the device visible in sysfs */
  156 + unsigned can_power_off:1; /* Device supports runtime power off */
156 157  
157 158 DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */
158 159 struct list_head event_list; /* asserted events */