libata: reorganize ata_eh_reset() no reset method path
Reorganize ata_eh_reset() such that @prereset() is called even when no reset method is available and if block is used instead of goto to skip actual reset. This makes no reset case behave better (readiness wait) and future changes easier. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
parent
0cbf0711a1
commit
932648b007
|
@ -2098,7 +2098,9 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
||||||
u32 sstatus;
|
u32 sstatus;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* about to reset */
|
/*
|
||||||
|
* Prepare to reset
|
||||||
|
*/
|
||||||
spin_lock_irqsave(ap->lock, flags);
|
spin_lock_irqsave(ap->lock, flags);
|
||||||
ap->pflags |= ATA_PFLAG_RESETTING;
|
ap->pflags |= ATA_PFLAG_RESETTING;
|
||||||
spin_unlock_irqrestore(ap->lock, flags);
|
spin_unlock_irqrestore(ap->lock, flags);
|
||||||
|
@ -2124,16 +2126,8 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
||||||
ap->ops->set_piomode(ap, dev);
|
ap->ops->set_piomode(ap, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!softreset && !hardreset) {
|
|
||||||
if (verbose)
|
|
||||||
ata_link_printk(link, KERN_INFO, "no reset method "
|
|
||||||
"available, skipping reset\n");
|
|
||||||
if (!(lflags & ATA_LFLAG_ASSUME_CLASS))
|
|
||||||
lflags |= ATA_LFLAG_ASSUME_ATA;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* prefer hardreset */
|
/* prefer hardreset */
|
||||||
|
reset = NULL;
|
||||||
ehc->i.action &= ~ATA_EH_RESET;
|
ehc->i.action &= ~ATA_EH_RESET;
|
||||||
if (hardreset) {
|
if (hardreset) {
|
||||||
reset = hardreset;
|
reset = hardreset;
|
||||||
|
@ -2141,11 +2135,6 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
||||||
} else if (softreset) {
|
} else if (softreset) {
|
||||||
reset = softreset;
|
reset = softreset;
|
||||||
ehc->i.action = ATA_EH_SOFTRESET;
|
ehc->i.action = ATA_EH_SOFTRESET;
|
||||||
} else {
|
|
||||||
ata_link_printk(link, KERN_ERR, "BUG: no reset method, "
|
|
||||||
"please report to linux-ide@vger.kernel.org\n");
|
|
||||||
dump_stack();
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prereset) {
|
if (prereset) {
|
||||||
|
@ -2165,55 +2154,68 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
||||||
"prereset failed (errno=%d)\n", rc);
|
"prereset failed (errno=%d)\n", rc);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* prereset() might have cleared ATA_EH_RESET */
|
/* prereset() might have cleared ATA_EH_RESET. If so,
|
||||||
if (!(ehc->i.action & ATA_EH_RESET)) {
|
* bang classes and return.
|
||||||
/* prereset told us not to reset, bang classes and return */
|
*/
|
||||||
ata_link_for_each_dev(dev, link)
|
if (reset && !(ehc->i.action & ATA_EH_RESET)) {
|
||||||
classes[dev->devno] = ATA_DEV_NONE;
|
ata_link_for_each_dev(dev, link)
|
||||||
rc = 0;
|
classes[dev->devno] = ATA_DEV_NONE;
|
||||||
goto out;
|
rc = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
|
/*
|
||||||
|
* Perform reset
|
||||||
|
*/
|
||||||
deadline = jiffies + ata_eh_reset_timeouts[try++];
|
deadline = jiffies + ata_eh_reset_timeouts[try++];
|
||||||
|
|
||||||
/* shut up during boot probing */
|
if (reset) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
ata_link_printk(link, KERN_INFO, "%s resetting link\n",
|
ata_link_printk(link, KERN_INFO, "%s resetting link\n",
|
||||||
reset == softreset ? "soft" : "hard");
|
reset == softreset ? "soft" : "hard");
|
||||||
|
|
||||||
/* mark that this EH session started with reset */
|
/* mark that this EH session started with reset */
|
||||||
if (reset == hardreset)
|
if (reset == hardreset)
|
||||||
ehc->i.flags |= ATA_EHI_DID_HARDRESET;
|
ehc->i.flags |= ATA_EHI_DID_HARDRESET;
|
||||||
else
|
else
|
||||||
ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
|
ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
|
||||||
|
|
||||||
rc = ata_do_reset(link, reset, classes, deadline);
|
rc = ata_do_reset(link, reset, classes, deadline);
|
||||||
|
|
||||||
if (reset == hardreset &&
|
if (reset == hardreset &&
|
||||||
ata_eh_followup_srst_needed(link, rc, classify, classes)) {
|
ata_eh_followup_srst_needed(link, rc, classify, classes)) {
|
||||||
/* okay, let's do follow-up softreset */
|
/* okay, let's do follow-up softreset */
|
||||||
reset = softreset;
|
reset = softreset;
|
||||||
|
|
||||||
if (!reset) {
|
if (!reset) {
|
||||||
ata_link_printk(link, KERN_ERR,
|
ata_link_printk(link, KERN_ERR,
|
||||||
"follow-up softreset required "
|
"follow-up softreset required "
|
||||||
"but no softreset avaliable\n");
|
"but no softreset avaliable\n");
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
|
||||||
|
rc = ata_do_reset(link, reset, classes, deadline);
|
||||||
}
|
}
|
||||||
|
|
||||||
ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
|
/* -EAGAIN can happen if we skipped followup SRST */
|
||||||
rc = ata_do_reset(link, reset, classes, deadline);
|
if (rc && rc != -EAGAIN)
|
||||||
|
goto fail;
|
||||||
|
} else {
|
||||||
|
if (verbose)
|
||||||
|
ata_link_printk(link, KERN_INFO, "no reset method "
|
||||||
|
"available, skipping reset\n");
|
||||||
|
if (!(lflags & ATA_LFLAG_ASSUME_CLASS))
|
||||||
|
lflags |= ATA_LFLAG_ASSUME_ATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -EAGAIN can happen if we skipped followup SRST */
|
/*
|
||||||
if (rc && rc != -EAGAIN)
|
* Post-reset processing
|
||||||
goto fail;
|
*/
|
||||||
|
|
||||||
done:
|
|
||||||
ata_link_for_each_dev(dev, link) {
|
ata_link_for_each_dev(dev, link) {
|
||||||
/* After the reset, the device state is PIO 0 and the
|
/* After the reset, the device state is PIO 0 and the
|
||||||
* controller state is undefined. Reset also wakes up
|
* controller state is undefined. Reset also wakes up
|
||||||
|
|
Reference in New Issue