summaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
authorDamien Le Moal <dlemoal@kernel.org>2023-08-29 03:18:34 +0200
committerDamien Le Moal <dlemoal@kernel.org>2023-10-03 02:39:49 +0200
commit8c1f08170694f50216f0e336ccfc589d3430a339 (patch)
tree5d98441cc3d415ed861d495300093ef8e917a686 /drivers/ata/libata-scsi.c
parentscsi: Remove scsi device no_start_on_resume flag (diff)
downloadlinux-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-scsi.c')
-rw-r--r--drivers/ata/libata-scsi.c53
1 files changed, 9 insertions, 44 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index a371b497035e..63b4c09e15df 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1202,7 +1202,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
{
struct scsi_cmnd *scmd = qc->scsicmd;
- struct ata_taskfile *tf = &qc->tf;
const u8 *cdb = scmd->cmnd;
u16 fp;
u8 bp = 0xff;
@@ -1212,54 +1211,24 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
goto invalid_fld;
}
- tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
- tf->protocol = ATA_PROT_NODATA;
- if (cdb[1] & 0x1) {
- ; /* ignore IMMED bit, violates sat-r05 */
- }
+ /* LOEJ bit set not supported */
if (cdb[4] & 0x2) {
fp = 4;
bp = 1;
- goto invalid_fld; /* LOEJ bit set not supported */
+ goto invalid_fld;
}
+
+ /* Power conditions not supported */
if (((cdb[4] >> 4) & 0xf) != 0) {
fp = 4;
bp = 3;
- goto invalid_fld; /* power conditions not supported */
+ goto invalid_fld;
}
- if (cdb[4] & 0x1) {
- tf->nsect = 1; /* 1 sector, lba=0 */
-
- if (qc->dev->flags & ATA_DFLAG_LBA) {
- tf->flags |= ATA_TFLAG_LBA;
-
- tf->lbah = 0x0;
- tf->lbam = 0x0;
- tf->lbal = 0x0;
- tf->device |= ATA_LBA;
- } else {
- /* CHS */
- tf->lbal = 0x1; /* sect */
- tf->lbam = 0x0; /* cyl low */
- tf->lbah = 0x0; /* cyl high */
- }
-
- tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
- } else {
- /* Some odd clown BIOSen issue spindown on power off (ACPI S4
- * or S5) causing some drives to spin up and down again.
- */
- if ((qc->ap->flags & ATA_FLAG_NO_POWEROFF_SPINDOWN) &&
- system_state == SYSTEM_POWER_OFF)
- goto skip;
-
- if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) &&
- system_entering_hibernation())
- goto skip;
-
- /* Issue ATA STANDBY IMMEDIATE command */
- tf->command = ATA_CMD_STANDBYNOW1;
+ /* Ignore IMMED bit (cdb[1] & 0x1), violates sat-r05 */
+ if (!ata_dev_power_init_tf(qc->dev, &qc->tf, cdb[4] & 0x1)) {
+ ata_scsi_set_sense(qc->dev, scmd, ABORTED_COMMAND, 0, 0);
+ return 1;
}
/*
@@ -1274,12 +1243,8 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
invalid_fld:
ata_scsi_set_invalid_field(qc->dev, scmd, fp, bp);
return 1;
- skip:
- scmd->result = SAM_STAT_GOOD;
- return 1;
}
-
/**
* ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command
* @qc: Storage for translated ATA taskfile