diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index f77a673..5b30776 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2486,6 +2486,11 @@ int ata_eh_reset(struct ata_link *link, int classify, */ while (ata_eh_reset_timeouts[max_tries] != ULONG_MAX) max_tries++; + if (max_tries > 1) + ehc->i.flags &= ~ATA_EHI_LAST_RESET; + else + ehc->i.flags |= ATA_EHI_LAST_RESET; + if (link->flags & ATA_LFLAG_NO_HRST) hardreset = NULL; if (link->flags & ATA_LFLAG_NO_SRST) @@ -2814,6 +2819,7 @@ int ata_eh_reset(struct ata_link *link, int classify, } if (try == max_tries - 1) { + ehc->i.flags |= ATA_EHI_LAST_RESET; sata_down_spd_limit(link, 0); if (slave) sata_down_spd_limit(slave, 0); diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 2116113..5c22f02 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -1583,11 +1583,14 @@ static int nv_hardreset(struct ata_link *link, unsigned int *class, { struct ata_eh_context *ehc = &link->eh_context; - /* Do hardreset iff it's post-boot probing, please read the - * comment above port ops for details. + /* + * Do hardreset iff it's the last reset attempt or post-boot + * probing, please read the comment above port ops for + * details. */ - if (!(link->ap->pflags & ATA_PFLAG_LOADING) && - !ata_dev_enabled(link->device)) + if (ehc->i.flags & ATA_EHI_LAST_RESET || + (!(link->ap->pflags & ATA_PFLAG_LOADING) && + !ata_dev_enabled(link->device))) sata_link_hardreset(link, sata_deb_timing_hotplug, deadline, NULL, NULL); else { diff --git a/include/linux/libata.h b/include/linux/libata.h index b85f3ff..de61cc3 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -341,6 +341,7 @@ enum { ATA_EHI_PRINTINFO = (1 << 18), /* print configuration info */ ATA_EHI_SETMODE = (1 << 19), /* configure transfer mode */ ATA_EHI_POST_SETMODE = (1 << 20), /* revaildating after setmode */ + ATA_EHI_LAST_RESET = (1 << 21), /* last reset attempt hint */ ATA_EHI_DID_RESET = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET,