Skip to content

Commit 9cec467

Browse files
damien-lemoalfloatious
authored andcommitted
ata: libata-core: Do not call ata_dev_power_set_standby() twice
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. Fixes: 2da4c5e ("ata: libata-core: Improve ata_dev_power_set_active()") Cc: [email protected] Signed-off-by: Damien Le Moal <[email protected]> Signed-off-by: Niklas Cassel <[email protected]>
1 parent 26c8404 commit 9cec467

File tree

1 file changed

+30
-29
lines changed

1 file changed

+30
-29
lines changed

drivers/ata/libata-core.c

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,6 +2001,33 @@ bool ata_dev_power_init_tf(struct ata_device *dev, struct ata_taskfile *tf,
20012001
return true;
20022002
}
20032003

2004+
static bool ata_dev_power_is_active(struct ata_device *dev)
2005+
{
2006+
struct ata_taskfile tf;
2007+
unsigned int err_mask;
2008+
2009+
ata_tf_init(dev, &tf);
2010+
tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
2011+
tf.protocol = ATA_PROT_NODATA;
2012+
tf.command = ATA_CMD_CHK_POWER;
2013+
2014+
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
2015+
if (err_mask) {
2016+
ata_dev_err(dev, "Check power mode failed (err_mask=0x%x)\n",
2017+
err_mask);
2018+
/*
2019+
* Assume we are in standby mode so that we always force a
2020+
* spinup in ata_dev_power_set_active().
2021+
*/
2022+
return false;
2023+
}
2024+
2025+
ata_dev_dbg(dev, "Power mode: 0x%02x\n", tf.nsect);
2026+
2027+
/* Active or idle */
2028+
return tf.nsect == 0xff;
2029+
}
2030+
20042031
/**
20052032
* ata_dev_power_set_standby - Set a device power mode to standby
20062033
* @dev: target device
@@ -2017,8 +2044,9 @@ void ata_dev_power_set_standby(struct ata_device *dev)
20172044
struct ata_taskfile tf;
20182045
unsigned int err_mask;
20192046

2020-
/* If the device is already sleeping, do nothing. */
2021-
if (dev->flags & ATA_DFLAG_SLEEPING)
2047+
/* If the device is already sleeping or in standby, do nothing. */
2048+
if ((dev->flags & ATA_DFLAG_SLEEPING) ||
2049+
!ata_dev_power_is_active(dev))
20222050
return;
20232051

20242052
/*
@@ -2046,33 +2074,6 @@ void ata_dev_power_set_standby(struct ata_device *dev)
20462074
err_mask);
20472075
}
20482076

2049-
static bool ata_dev_power_is_active(struct ata_device *dev)
2050-
{
2051-
struct ata_taskfile tf;
2052-
unsigned int err_mask;
2053-
2054-
ata_tf_init(dev, &tf);
2055-
tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
2056-
tf.protocol = ATA_PROT_NODATA;
2057-
tf.command = ATA_CMD_CHK_POWER;
2058-
2059-
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
2060-
if (err_mask) {
2061-
ata_dev_err(dev, "Check power mode failed (err_mask=0x%x)\n",
2062-
err_mask);
2063-
/*
2064-
* Assume we are in standby mode so that we always force a
2065-
* spinup in ata_dev_power_set_active().
2066-
*/
2067-
return false;
2068-
}
2069-
2070-
ata_dev_dbg(dev, "Power mode: 0x%02x\n", tf.nsect);
2071-
2072-
/* Active or idle */
2073-
return tf.nsect == 0xff;
2074-
}
2075-
20762077
/**
20772078
* ata_dev_power_set_active - Set a device power mode to active
20782079
* @dev: target device

0 commit comments

Comments
 (0)