From dc50eab76b709d68175a358d6e23a5a3890764d3 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 19:39:57 +0200 Subject: Merging upstream version 6.7.7. Signed-off-by: Daniel Baumann --- drivers/ata/libata-eh.c | 54 +++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 22 deletions(-) (limited to 'drivers/ata/libata-eh.c') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 5686353e44..b0d6e69c4a 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -494,6 +494,18 @@ void ata_eh_release(struct ata_port *ap) mutex_unlock(&ap->host->eh_mutex); } +static void ata_eh_dev_disable(struct ata_device *dev) +{ + ata_acpi_on_disable(dev); + ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET); + dev->class++; + + /* From now till the next successful probe, ering is used to + * track probe failures. Clear accumulated device error info. + */ + ata_ering_clear(&dev->ering); +} + static void ata_eh_unload(struct ata_port *ap) { struct ata_link *link; @@ -517,8 +529,8 @@ static void ata_eh_unload(struct ata_port *ap) */ ata_for_each_link(link, ap, PMP_FIRST) { sata_scr_write(link, SCR_CONTROL, link->saved_scontrol & 0xff0); - ata_for_each_dev(dev, link, ALL) - ata_dev_disable(dev); + ata_for_each_dev(dev, link, ENABLED) + ata_eh_dev_disable(dev); } /* freeze and set UNLOADED */ @@ -1211,14 +1223,8 @@ void ata_dev_disable(struct ata_device *dev) return; ata_dev_warn(dev, "disable device\n"); - ata_acpi_on_disable(dev); - ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET); - dev->class++; - /* From now till the next successful probe, ering is used to - * track probe failures. Clear accumulated device error info. - */ - ata_ering_clear(&dev->ering); + ata_eh_dev_disable(dev); } EXPORT_SYMBOL_GPL(ata_dev_disable); @@ -1240,12 +1246,12 @@ void ata_eh_detach_dev(struct ata_device *dev) /* * If the device is still enabled, transition it to standby power mode - * (i.e. spin down HDDs). + * (i.e. spin down HDDs) and disable it. */ - if (ata_dev_enabled(dev)) + if (ata_dev_enabled(dev)) { ata_dev_power_set_standby(dev); - - ata_dev_disable(dev); + ata_eh_dev_disable(dev); + } spin_lock_irqsave(ap->lock, flags); @@ -2909,6 +2915,8 @@ int ata_eh_reset(struct ata_link *link, int classify, */ if (ata_is_host_link(link)) ata_eh_thaw_port(ap); + ata_link_warn(link, "%s failed\n", + reset == hardreset ? "hardreset" : "softreset"); goto out; } @@ -3043,15 +3051,6 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, if (ehc->i.flags & ATA_EHI_DID_RESET) readid_flags |= ATA_READID_POSTRESET; - /* - * When resuming, before executing any command, make sure to - * transition the device to the active power mode. - */ - if ((action & ATA_EH_SET_ACTIVE) && ata_dev_enabled(dev)) { - ata_dev_power_set_active(dev); - ata_eh_done(link, dev, ATA_EH_SET_ACTIVE); - } - if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) { WARN_ON(dev->class == ATA_DEV_PMP); @@ -3848,6 +3847,17 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, } } + /* + * Make sure to transition devices to the active power mode + * if needed (e.g. if we were scheduled on system resume). + */ + ata_for_each_dev(dev, link, ENABLED) { + if (ehc->i.dev_action[dev->devno] & ATA_EH_SET_ACTIVE) { + ata_dev_power_set_active(dev); + ata_eh_done(link, dev, ATA_EH_SET_ACTIVE); + } + } + /* retry flush if necessary */ ata_for_each_dev(dev, link, ALL) { if (dev->class != ATA_DEV_ATA && -- cgit v1.2.3