• Damien Le Moal's avatar
    ata,scsi: do not issue START STOP UNIT on resume · 0a858905
    Damien Le Moal authored
    During system resume, ata_port_pm_resume() triggers ata EH to
    1) Resume the controller
    2) Reset and rescan the ports
    3) Revalidate devices
    This EH execution is started asynchronously from ata_port_pm_resume(),
    which means that when sd_resume() is executed, none or only part of the
    above processing may have been executed. However, sd_resume() issues a
    START STOP UNIT to wake up the drive from sleep mode. This command is
    translated to ATA with ata_scsi_start_stop_xlat() and issued to the
    device. However, depending on the state of execution of the EH process
    and revalidation triggerred by ata_port_pm_resume(), two things may
    happen:
    1) The START STOP UNIT fails if it is received before the controller has
       been reenabled at the beginning of the EH execution. This is visible
       with error messages like:
    
    ata10.00: device reported invalid CHS sector 0
    sd 9:0:0:0: [sdc] Start/Stop Unit failed: Result: hostbyte=DID_OK driverbyte=DRIVER_OK
    sd 9:0:0:0: [sdc] Sense Key : Illegal Request [current]
    sd 9:0:0:0: [sdc] Add. Sense: Unaligned write command
    sd 9:0:0:0: PM: dpm_run_callback(): scsi_bus_resume+0x0/0x90 returns -5
    sd 9:0:0:0: PM: failed to resume async: error -5
    
    2) The START STOP UNIT command is received while the EH process is
       on-going, which mean that it is stopped and must wait for its
       completion, at which point the command is rather useless as the drive
       is already fully spun up already. This case results also in a
       significant delay in sd_resume() which is observable by users as
       the entire system resume completion is delayed.
    
    Given that ATA devices will be woken up by libata activity on resume,
    sd_resume() has no need to issue a START STOP UNIT command, which solves
    the above mentioned problems. Do not issue this command by introducing
    the new scsi_device flag no_start_on_resume and setting this flag to 1
    in ata_scsi_dev_config(). sd_resume() is modified to issue a START STOP
    UNIT command only if this flag is not set.
    Reported-by: default avatarPaul Ausbeck <paula@soe.ucsc.edu>
    Closes: https://bugzilla.kernel.org/show_bug.cgi?id=215880
    Fixes: a19a93e4 ("scsi: core: pm: Rely on the device driver core for async power management")
    Signed-off-by: default avatarDamien Le Moal <dlemoal@kernel.org>
    Tested-by: default avatarTanner Watkins <dalzot@gmail.com>
    Tested-by: default avatarPaul Ausbeck <paula@soe.ucsc.edu>
    Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
    Reviewed-by: default avatarBart Van Assche <bvanassche@acm.org>
    0a858905
libata-scsi.c 122 KB