diff options
author | Damien Le Moal <dlemoal@kernel.org> | 2023-08-29 03:18:34 +0200 |
---|---|---|
committer | Damien Le Moal <dlemoal@kernel.org> | 2023-10-03 02:39:49 +0200 |
commit | 8c1f08170694f50216f0e336ccfc589d3430a339 (patch) | |
tree | 5d98441cc3d415ed861d495300093ef8e917a686 /drivers/ata/libata-core.c | |
parent | scsi: Remove scsi device no_start_on_resume flag (diff) | |
download | linux-8c1f08170694f50216f0e336ccfc589d3430a339.tar.xz linux-8c1f08170694f50216f0e336ccfc589d3430a339.zip |
ata: libata-scsi: Cleanup ata_scsi_start_stop_xlat()
Now that libata does its own internal device power mode management
through libata EH, the scsi disk driver will not issue START STOP UNIT
commands anymore. We can receive this command only from user passthrough
operations. So there is no need to consider the system state and ATA
port flags for suspend to translate the command.
Since setting up the taskfile for the verify and standby
immediate commands is the same as done in ata_dev_power_set_active()
and ata_dev_power_set_standby(), factor out this code into the helper
function ata_dev_power_init_tf() to simplify ata_scsi_start_stop_xlat()
as well as ata_dev_power_set_active() and ata_dev_power_set_standby().
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 0f63f805c78c..5afd30d76f0b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1972,6 +1972,35 @@ retry: return rc; } +bool ata_dev_power_init_tf(struct ata_device *dev, struct ata_taskfile *tf, + bool set_active) +{ + /* Only applies to ATA and ZAC devices */ + if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC) + return false; + + ata_tf_init(dev, tf); + tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; + tf->protocol = ATA_PROT_NODATA; + + if (set_active) { + /* VERIFY for 1 sector at lba=0 */ + tf->command = ATA_CMD_VERIFY; + tf->nsect = 1; + if (dev->flags & ATA_DFLAG_LBA) { + tf->flags |= ATA_TFLAG_LBA; + tf->device |= ATA_LBA; + } else { + /* CHS */ + tf->lbal = 0x1; /* sect */ + } + } else { + tf->command = ATA_CMD_STANDBYNOW1; + } + + return true; +} + /** * ata_dev_power_set_standby - Set a device power mode to standby * @dev: target device @@ -1988,10 +2017,6 @@ void ata_dev_power_set_standby(struct ata_device *dev) struct ata_taskfile tf; unsigned int err_mask; - /* Issue STANDBY IMMEDIATE command only if supported by the device */ - if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC) - return; - /* * Some odd clown BIOSes issue spindown on power off (ACPI S4 or S5) * causing some drives to spin up and down again. For these, do nothing @@ -2005,10 +2030,9 @@ void ata_dev_power_set_standby(struct ata_device *dev) system_entering_hibernation()) return; - ata_tf_init(dev, &tf); - tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; - tf.protocol = ATA_PROT_NODATA; - tf.command = ATA_CMD_STANDBYNOW1; + /* Issue STANDBY IMMEDIATE command only if supported by the device */ + if (!ata_dev_power_init_tf(dev, &tf, false)) + return; ata_dev_notice(dev, "Entering standby power mode\n"); @@ -2038,22 +2062,9 @@ void ata_dev_power_set_active(struct ata_device *dev) * Issue READ VERIFY SECTORS command for 1 sector at lba=0 only * if supported by the device. */ - if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC) + if (!ata_dev_power_init_tf(dev, &tf, true)) return; - ata_tf_init(dev, &tf); - tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; - tf.protocol = ATA_PROT_NODATA; - tf.command = ATA_CMD_VERIFY; - tf.nsect = 1; - if (dev->flags & ATA_DFLAG_LBA) { - tf.flags |= ATA_TFLAG_LBA; - tf.device |= ATA_LBA; - } else { - /* CHS */ - tf.lbal = 0x1; /* sect */ - } - ata_dev_notice(dev, "Entering active power mode\n"); err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); |