libata: move reset freeze/thaw handling into ata_eh_reset()

Previously reset freeze/thaw handling lived outside of ata_eh_reset()
mainly because the original PMP reset code needed the port frozen
while resetting all the fan-out ports, which is no longer the case.

This patch moves freeze/thaw handling into ata_eh_reset().
@prereset() and @postreset() are now called w/o freezing the port
although @prereset() an be called frozen if the port is frozen prior
to entering ata_eh_reset().

This makes code simpler and will help removing hotplug event related
races.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
Tejun Heo 2008-05-19 01:15:07 +09:00 committed by Jeff Garzik
parent 932648b007
commit dc98c32cbe
2 changed files with 18 additions and 32 deletions

View File

@ -2170,6 +2170,9 @@ int ata_eh_reset(struct ata_link *link, int classify,
/* /*
* Perform reset * Perform reset
*/ */
if (ata_is_host_link(link))
ata_eh_freeze_port(ap);
deadline = jiffies + ata_eh_reset_timeouts[try++]; deadline = jiffies + ata_eh_reset_timeouts[try++];
if (reset) { if (reset) {
@ -2238,6 +2241,10 @@ int ata_eh_reset(struct ata_link *link, int classify,
if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0) if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0)
link->sata_spd = (sstatus >> 4) & 0xf; link->sata_spd = (sstatus >> 4) & 0xf;
/* thaw the port */
if (ata_is_host_link(link))
ata_eh_thaw_port(ap);
if (postreset) if (postreset)
postreset(link, classes); postreset(link, classes);
@ -2589,7 +2596,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
struct ata_link *link; struct ata_link *link;
struct ata_device *dev; struct ata_device *dev;
int nr_failed_devs, nr_disabled_devs; int nr_failed_devs, nr_disabled_devs;
int reset, rc; int rc;
unsigned long flags; unsigned long flags;
DPRINTK("ENTER\n"); DPRINTK("ENTER\n");
@ -2632,7 +2639,6 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
rc = 0; rc = 0;
nr_failed_devs = 0; nr_failed_devs = 0;
nr_disabled_devs = 0; nr_disabled_devs = 0;
reset = 0;
/* if UNLOADING, finish immediately */ /* if UNLOADING, finish immediately */
if (ap->pflags & ATA_PFLAG_UNLOADING) if (ap->pflags & ATA_PFLAG_UNLOADING)
@ -2646,40 +2652,24 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
if (ata_eh_skip_recovery(link)) if (ata_eh_skip_recovery(link))
ehc->i.action = 0; ehc->i.action = 0;
/* do we need to reset? */
if (ehc->i.action & ATA_EH_RESET)
reset = 1;
ata_link_for_each_dev(dev, link) ata_link_for_each_dev(dev, link)
ehc->classes[dev->devno] = ATA_DEV_UNKNOWN; ehc->classes[dev->devno] = ATA_DEV_UNKNOWN;
} }
/* reset */ /* reset */
if (reset) { ata_port_for_each_link(link, ap) {
/* if PMP is attached, this function only deals with struct ata_eh_context *ehc = &link->eh_context;
* downstream links, port should stay thawed.
*/
if (!sata_pmp_attached(ap))
ata_eh_freeze_port(ap);
ata_port_for_each_link(link, ap) { if (!(ehc->i.action & ATA_EH_RESET))
struct ata_eh_context *ehc = &link->eh_context; continue;
if (!(ehc->i.action & ATA_EH_RESET)) rc = ata_eh_reset(link, ata_link_nr_vacant(link),
continue; prereset, softreset, hardreset, postreset);
if (rc) {
rc = ata_eh_reset(link, ata_link_nr_vacant(link), ata_link_printk(link, KERN_ERR,
prereset, softreset, hardreset, "reset failed, giving up\n");
postreset); goto out;
if (rc) {
ata_link_printk(link, KERN_ERR,
"reset failed, giving up\n");
goto out;
}
} }
if (!sata_pmp_attached(ap))
ata_eh_thaw_port(ap);
} }
/* the rest */ /* the rest */

View File

@ -700,8 +700,6 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
if (ehc->i.action & ATA_EH_RESET) { if (ehc->i.action & ATA_EH_RESET) {
struct ata_link *tlink; struct ata_link *tlink;
ata_eh_freeze_port(ap);
/* reset */ /* reset */
rc = ata_eh_reset(link, 0, prereset, softreset, hardreset, rc = ata_eh_reset(link, 0, prereset, softreset, hardreset,
postreset); postreset);
@ -711,8 +709,6 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
goto fail; goto fail;
} }
ata_eh_thaw_port(ap);
/* PMP is reset, SErrors cannot be trusted, scan all */ /* PMP is reset, SErrors cannot be trusted, scan all */
ata_port_for_each_link(tlink, ap) { ata_port_for_each_link(tlink, ap) {
struct ata_eh_context *ehc = &tlink->eh_context; struct ata_eh_context *ehc = &tlink->eh_context;