ata: libata-core: Do not call ata_dev_power_set_standby() twice
Subsystems (2)
Niklas Cassel
maintainerPATCH v2 1/1 ata: libata-core: Do not call ata_dev_power_set_standby() twice
From: Damien Le Moal <[email protected]>
For regular system shutdown, ata_dev_power_set_standby() will be executed twice: once the scsi device is removed and another when ata_pci_shutdown_one() executes and EH completes unloading the devices.
Make the second call to ata_dev_power_set_standby() do nothing by using ata_dev_power_is_active() and return if the device is already in standby.
---
Changes since V1: Move the function instead of using a forward declaration.
drivers/ata/libata-core.c | 59 ++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 29 deletions(-)
drivers/ata/libata-core.c +30 -29
@@ -2001,6 +2001,33 @@ bool ata_dev_power_init_tf(struct ata_device *dev, struct ata_taskfile *tf,return true; } +static bool ata_dev_power_is_active (struct ata_device *dev) +{ +struct ata_taskfile tf; +unsigned int err_mask; + +ata_tf_init (dev, &tf); + tf.flags |=ATA_TFLAG_DEVICE |ATA_TFLAG_ISADDR ; + tf.protocol =ATA_PROT_NODATA ; + tf.command =ATA_CMD_CHK_POWER ; + + err_mask =ata_exec_internal (dev, &tf,NULL ,DMA_NONE ,NULL ,0 ,0 ); +if (err_mask) { +ata_dev_err (dev,"Check power mode failed (err_mask=0x%x)\n" , + err_mask); +/* +* Assume we are in standby mode so that we always force a +* spinup in ata_dev_power_set_active(). +*/ +return false; + } + +ata_dev_dbg (dev,"Power mode: 0x%02x\n" , tf.nsect); + +/* Active or idle */ +return tf.nsect ==0xff ; +} +/** * ata_dev_power_set_standby - Set a device power mode to standby * @dev: target device
@@ -2017,8 +2044,9 @@ void ata_dev_power_set_standby(struct ata_device *dev)struct ata_taskfile tf;unsigned int err_mask; -/* If the device is already sleeping, do nothing. */ -if (dev->flags &ATA_DFLAG_SLEEPING ) +/* If the device is already sleeping or in standby, do nothing. */ +if ((dev->flags &ATA_DFLAG_SLEEPING ) || + !ata_dev_power_is_active (dev))return ;/*
@@ -2046,33 +2074,6 @@ void ata_dev_power_set_standby(struct ata_device *dev) err_mask); } -static bool ata_dev_power_is_active (struct ata_device *dev) -{ -struct ata_taskfile tf; -unsigned int err_mask; - -ata_tf_init (dev, &tf); - tf.flags |=ATA_TFLAG_DEVICE |ATA_TFLAG_ISADDR ; - tf.protocol =ATA_PROT_NODATA ; - tf.command =ATA_CMD_CHK_POWER ; - - err_mask =ata_exec_internal (dev, &tf,NULL ,DMA_NONE ,NULL ,0 ,0 ); -if (err_mask) { -ata_dev_err (dev,"Check power mode failed (err_mask=0x%x)\n" , - err_mask); -/* -* Assume we are in standby mode so that we always force a -* spinup in ata_dev_power_set_active(). -*/ -return false; - } - -ata_dev_dbg (dev,"Power mode: 0x%02x\n" , tf.nsect); - -/* Active or idle */ -return tf.nsect ==0xff ; -} -/** * ata_dev_power_set_active - Set a device power mode to active * @dev: target device
Signature · 1 line
2.43.2
Quoted 10 lines · Niklas Cassel
From: Damien Le Moal <[email protected]>
For regular system shutdown,
ata_dev_power_set_standby()will be executed twice: once the scsi device is removed and another whenata_pci_shutdown_one()executes and EH completes unloading the devices.Make the second call to
ata_dev_power_set_standby()do nothing by usingata_dev_power_is_active()and return if the device is already in standby.
Quoted 5 lines
Fixes 2da4c5e24e86 ("ata: libata-core: Improve ata_dev_power_set_active()")Signed-off-by Damien Le Moal <[email protected]>Signed-off-by Niklas Cassel <[email protected]>---
Applied:
https://git.kernel.org/pub/scm/linux/kernel/git/libata/linux.git/log/?h=for-6.8-fixes