Skip to content

Commit b118906

Browse files
committed
ata: libata-scsi: Fix system suspend for a security locked drive
Commit cf3fc03 ("ata: libata-scsi: Fix ata_to_sense_error() status handling") fixed ata_to_sense_error() to properly generate sense key ABORTED COMMAND (without any additional sense code), instead of the previous bogus sense key ILLEGAL REQUEST with the additional sense code UNALIGNED WRITE COMMAND, for a failed command. However, this broke suspend for Security locked drives (drives that have Security enabled, and have not been Security unlocked by boot firmware). The reason for this is that the SCSI disk driver, for the Synchronize Cache command only, treats any sense data with sense key ILLEGAL REQUEST as a successful command (regardless of ASC / ASCQ). After commit cf3fc03 ("ata: libata-scsi: Fix ata_to_sense_error() status handling") the code that treats any sense data with sense key ILLEGAL REQUEST as a successful command is no longer applicable, so the command fails, which causes the system suspend to be aborted: sd 1:0:0:0: PM: dpm_run_callback(): scsi_bus_suspend returns -5 sd 1:0:0:0: PM: failed to suspend async: error -5 PM: Some devices failed to suspend, or early wake event detected To make suspend work once again, for a Security locked device only, return sense data LOGICAL UNIT ACCESS NOT AUTHORIZED, the actual sense data which a real SCSI device would have returned if locked. The SCSI disk driver treats this sense data as a successful command. Cc: [email protected] Reported-by: Ilia Baryshnikov <[email protected]> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220704 Fixes: cf3fc03 ("ata: libata-scsi: Fix ata_to_sense_error() status handling") Reviewed-by: Hannes Reinecke <[email protected]> Reviewed-by: Martin K. Petersen <[email protected]> Reviewed-by: Damien Le Moal <[email protected]> Signed-off-by: Niklas Cassel <[email protected]>
1 parent b32cc17 commit b118906

File tree

2 files changed

+8
-0
lines changed

2 files changed

+8
-0
lines changed

drivers/ata/libata-scsi.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,13 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
992992
return;
993993
}
994994

995+
if (ata_id_is_locked(dev->id)) {
996+
/* Security locked */
997+
/* LOGICAL UNIT ACCESS NOT AUTHORIZED */
998+
ata_scsi_set_sense(dev, cmd, DATA_PROTECT, 0x74, 0x71);
999+
return;
1000+
}
1001+
9951002
if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) {
9961003
ata_dev_dbg(dev,
9971004
"Missing result TF: reporting aborted command\n");

include/linux/ata.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,7 @@ struct ata_bmdma_prd {
566566
#define ata_id_has_ncq(id) ((id)[ATA_ID_SATA_CAPABILITY] & (1 << 8))
567567
#define ata_id_queue_depth(id) (((id)[ATA_ID_QUEUE_DEPTH] & 0x1f) + 1)
568568
#define ata_id_removable(id) ((id)[ATA_ID_CONFIG] & (1 << 7))
569+
#define ata_id_is_locked(id) (((id)[ATA_ID_DLF] & 0x7) == 0x7)
569570
#define ata_id_has_atapi_AN(id) \
570571
((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
571572
((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \

0 commit comments

Comments
 (0)