libata: always do follow-up SRST if hardreset returned -EAGAIN

As an optimization, follow-up SRST used to be skipped if
classification wasn't requested even when hardreset requested it via
-EAGAIN. However, some hardresets can't wait for device readiness and
skipping SRST can cause timeout or other failures during revalidation.
Always perform follow-up SRST if hardreset returns -EAGAIN. This
makes reset paths more predictable and thus less error-prone.

While at it, move hardreset error checking such that it's done right
after hardreset is finished. This simplifies followup SRST condition
check a bit and makes the reset path easier to modify.

Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>

authored by

Tejun Heo and committed by
Jeff Garzik
5dbfc9cb a674050e

+6 -14
+6 -14
drivers/ata/libata-eh.c
··· 2171 } 2172 2173 static int ata_eh_followup_srst_needed(struct ata_link *link, 2174 - int rc, int classify, 2175 - const unsigned int *classes) 2176 { 2177 if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link)) 2178 return 0; 2179 - if (rc == -EAGAIN) { 2180 - if (classify) 2181 - return 1; 2182 - rc = 0; 2183 - } 2184 - if (rc != 0) 2185 - return 0; 2186 if (sata_pmp_supported(link->ap) && ata_is_host_link(link)) 2187 return 1; 2188 return 0; ··· 2303 ehc->i.flags |= ATA_EHI_DID_SOFTRESET; 2304 2305 rc = ata_do_reset(link, reset, classes, deadline); 2306 2307 if (reset == hardreset && 2308 - ata_eh_followup_srst_needed(link, rc, classify, classes)) { 2309 /* okay, let's do follow-up softreset */ 2310 reset = softreset; 2311 ··· 2322 ata_eh_about_to_do(link, NULL, ATA_EH_RESET); 2323 rc = ata_do_reset(link, reset, classes, deadline); 2324 } 2325 - 2326 - /* -EAGAIN can happen if we skipped followup SRST */ 2327 - if (rc && rc != -EAGAIN) 2328 - goto fail; 2329 } else { 2330 if (verbose) 2331 ata_link_printk(link, KERN_INFO, "no reset method "
··· 2171 } 2172 2173 static int ata_eh_followup_srst_needed(struct ata_link *link, 2174 + int rc, const unsigned int *classes) 2175 { 2176 if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link)) 2177 return 0; 2178 + if (rc == -EAGAIN) 2179 + return 1; 2180 if (sata_pmp_supported(link->ap) && ata_is_host_link(link)) 2181 return 1; 2182 return 0; ··· 2309 ehc->i.flags |= ATA_EHI_DID_SOFTRESET; 2310 2311 rc = ata_do_reset(link, reset, classes, deadline); 2312 + if (rc && rc != -EAGAIN) 2313 + goto fail; 2314 2315 if (reset == hardreset && 2316 + ata_eh_followup_srst_needed(link, rc, classes)) { 2317 /* okay, let's do follow-up softreset */ 2318 reset = softreset; 2319 ··· 2326 ata_eh_about_to_do(link, NULL, ATA_EH_RESET); 2327 rc = ata_do_reset(link, reset, classes, deadline); 2328 } 2329 } else { 2330 if (verbose) 2331 ata_link_printk(link, KERN_INFO, "no reset method "