When a disk is in SLEEP mode it can not respond to any any commands. Several commands are simply a NOOP to a disk that is in standby mode, but when a disk is in SLEEP mode, they frequencly cause the disk to spin up for no reason. To avoid this, complete these commands in libata without waking the disk. These commands are: CHECK POWER MODE FLUSH CACHE SLEEP STANDBY IMMEDIATE IDENTIFY If we know the disk is sleeping, we don't need to wake it up to find out if it is in standby, so just pretend it is in standby. While asleep, there's no dirty pages in the cache, so there's no need to flush it. There's no point in waking a disk from sleep just to put it back to sleep. We also have a cache of the IDENTIFY information so just return that instead of waking the disk. --- drivers/ata/libata-core.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 09ed67772fae..6c5269de4bf2 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5040,6 +5040,26 @@ void ata_qc_issue(struct ata_queued_cmd *qc) /* if device is sleeping, schedule reset and abort the link */ if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { + switch (qc->tf.command) + { + case ATA_CMD_CHK_POWER: + case ATA_CMD_SLEEP: + case ATA_CMD_FLUSH: + case ATA_CMD_FLUSH_EXT: + case ATA_CMD_STANDBYNOW1: + if (qc->tf.command == ATA_CMD_ID_ATA) + { + /* only fake the reply for IDENTIFY if it is from userspace */ + if (ata_tag_internal(qc->tag)) + break; + sg_copy_from_buffer(qc->sg, 1, qc->dev->id, 2 * ATA_ID_WORDS); + } + /* fake reply to avoid waking drive */ + qc->flags |= ATA_QCFLAG_RTF_FILLED; + qc->result_tf.nsect = 0; + ata_qc_complete(qc); + return; + } link->eh_info.action |= ATA_EH_RESET; ata_ehi_push_desc(&link->eh_info, "waking up from sleep"); ata_link_abort(link); -- 2.30.2