forked from Minki/linux
libata-link: separate out ata_eh_handle_dev_fail()
Separate out ata_eh_handle_dev_fail() from ata_eh_recover(). This is in preparation of ata_link and PMP support. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
790956e7bb
commit
fee7ca72d3
@ -1897,6 +1897,57 @@ static int ata_eh_skip_recovery(struct ata_port *ap)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void ata_eh_handle_dev_fail(struct ata_device *dev, int err)
|
||||
{
|
||||
struct ata_port *ap = dev->ap;
|
||||
struct ata_eh_context *ehc = &ap->eh_context;
|
||||
|
||||
ehc->tries[dev->devno]--;
|
||||
|
||||
switch (err) {
|
||||
case -ENODEV:
|
||||
/* device missing or wrong IDENTIFY data, schedule probing */
|
||||
ehc->i.probe_mask |= (1 << dev->devno);
|
||||
case -EINVAL:
|
||||
/* give it just one more chance */
|
||||
ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
|
||||
case -EIO:
|
||||
if (ehc->tries[dev->devno] == 1) {
|
||||
/* This is the last chance, better to slow
|
||||
* down than lose it.
|
||||
*/
|
||||
sata_down_spd_limit(ap);
|
||||
ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
|
||||
}
|
||||
}
|
||||
|
||||
if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) {
|
||||
/* disable device if it has used up all its chances */
|
||||
ata_dev_disable(dev);
|
||||
|
||||
/* detach if offline */
|
||||
if (ata_port_offline(ap))
|
||||
ata_eh_detach_dev(dev);
|
||||
|
||||
/* probe if requested */
|
||||
if ((ehc->i.probe_mask & (1 << dev->devno)) &&
|
||||
!(ehc->did_probe_mask & (1 << dev->devno))) {
|
||||
ata_eh_detach_dev(dev);
|
||||
ata_dev_init(dev);
|
||||
|
||||
ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
|
||||
ehc->did_probe_mask |= (1 << dev->devno);
|
||||
ehc->i.action |= ATA_EH_SOFTRESET;
|
||||
}
|
||||
} else {
|
||||
/* soft didn't work? be haaaaard */
|
||||
if (ehc->i.flags & ATA_EHI_DID_RESET)
|
||||
ehc->i.action |= ATA_EH_HARDRESET;
|
||||
else
|
||||
ehc->i.action |= ATA_EH_SOFTRESET;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_eh_recover - recover host port after error
|
||||
* @ap: host port to recover
|
||||
@ -1997,50 +2048,7 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
|
||||
goto out;
|
||||
|
||||
dev_fail:
|
||||
ehc->tries[dev->devno]--;
|
||||
|
||||
switch (rc) {
|
||||
case -ENODEV:
|
||||
/* device missing or wrong IDENTIFY data, schedule probing */
|
||||
ehc->i.probe_mask |= (1 << dev->devno);
|
||||
case -EINVAL:
|
||||
/* give it just one more chance */
|
||||
ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
|
||||
case -EIO:
|
||||
if (ehc->tries[dev->devno] == 1) {
|
||||
/* This is the last chance, better to slow
|
||||
* down than lose it.
|
||||
*/
|
||||
sata_down_spd_limit(ap);
|
||||
ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
|
||||
}
|
||||
}
|
||||
|
||||
if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) {
|
||||
/* disable device if it has used up all its chances */
|
||||
ata_dev_disable(dev);
|
||||
|
||||
/* detach if offline */
|
||||
if (ata_port_offline(ap))
|
||||
ata_eh_detach_dev(dev);
|
||||
|
||||
/* probe if requested */
|
||||
if ((ehc->i.probe_mask & (1 << dev->devno)) &&
|
||||
!(ehc->did_probe_mask & (1 << dev->devno))) {
|
||||
ata_eh_detach_dev(dev);
|
||||
ata_dev_init(dev);
|
||||
|
||||
ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
|
||||
ehc->did_probe_mask |= (1 << dev->devno);
|
||||
ehc->i.action |= ATA_EH_SOFTRESET;
|
||||
}
|
||||
} else {
|
||||
/* soft didn't work? be haaaaard */
|
||||
if (ehc->i.flags & ATA_EHI_DID_RESET)
|
||||
ehc->i.action |= ATA_EH_HARDRESET;
|
||||
else
|
||||
ehc->i.action |= ATA_EH_SOFTRESET;
|
||||
}
|
||||
ata_eh_handle_dev_fail(dev, rc);
|
||||
|
||||
if (ata_port_nr_enabled(ap)) {
|
||||
ata_port_printk(ap, KERN_WARNING, "failed to recover some "
|
||||
|
Loading…
Reference in New Issue
Block a user