| From cebbert@redhat.com Thu Oct 16 15:47:05 2008 |
| From: Tejun Heo <tj@kernel.org> |
| Date: Mon, 13 Oct 2008 19:21:28 -0400 |
| Subject: libata: always do follow-up SRST if hardreset returned -EAGAIN |
| To: stable@kernel.org |
| Cc: Tejun Heo <tj@kernel.org> |
| Message-ID: <20081013192128.5a797eac@redhat.com> |
| |
| |
| From: Tejun Heo <tj@kernel.org> |
| |
| commit 5dbfc9cb59d4ad75199949d7dd8a8c6d7bc518df upstream |
| |
| 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> |
| Cc: Chuck Ebbert <cebbert@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/ata/libata-eh.c | 20 ++++++-------------- |
| 1 file changed, 6 insertions(+), 14 deletions(-) |
| |
| --- a/drivers/ata/libata-eh.c |
| +++ b/drivers/ata/libata-eh.c |
| @@ -2050,18 +2050,12 @@ static int ata_do_reset(struct ata_link |
| } |
| |
| static int ata_eh_followup_srst_needed(struct ata_link *link, |
| - int rc, int classify, |
| - const unsigned int *classes) |
| + int rc, const unsigned int *classes) |
| { |
| if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link)) |
| return 0; |
| - if (rc == -EAGAIN) { |
| - if (classify) |
| - return 1; |
| - rc = 0; |
| - } |
| - if (rc != 0) |
| - return 0; |
| + if (rc == -EAGAIN) |
| + return 1; |
| if (sata_pmp_supported(link->ap) && ata_is_host_link(link)) |
| return 1; |
| return 0; |
| @@ -2174,9 +2168,11 @@ int ata_eh_reset(struct ata_link *link, |
| ehc->i.flags |= ATA_EHI_DID_SOFTRESET; |
| |
| rc = ata_do_reset(link, reset, classes, deadline); |
| + if (rc && rc != -EAGAIN) |
| + goto fail; |
| |
| if (reset == hardreset && |
| - ata_eh_followup_srst_needed(link, rc, classify, classes)) { |
| + ata_eh_followup_srst_needed(link, rc, classes)) { |
| /* okay, let's do follow-up softreset */ |
| reset = softreset; |
| |
| @@ -2191,10 +2187,6 @@ int ata_eh_reset(struct ata_link *link, |
| ata_eh_about_to_do(link, NULL, ATA_EH_RESET); |
| rc = ata_do_reset(link, reset, classes, deadline); |
| } |
| - |
| - /* -EAGAIN can happen if we skipped followup SRST */ |
| - if (rc && rc != -EAGAIN) |
| - goto fail; |
| } else { |
| if (verbose) |
| ata_link_printk(link, KERN_INFO, "no reset method " |