mirror of https://gitee.com/openkylin/linux.git
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;
|
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
|
* ata_eh_recover - recover host port after error
|
||||||
* @ap: host port to recover
|
* @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;
|
goto out;
|
||||||
|
|
||||||
dev_fail:
|
dev_fail:
|
||||||
ehc->tries[dev->devno]--;
|
ata_eh_handle_dev_fail(dev, rc);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ata_port_nr_enabled(ap)) {
|
if (ata_port_nr_enabled(ap)) {
|
||||||
ata_port_printk(ap, KERN_WARNING, "failed to recover some "
|
ata_port_printk(ap, KERN_WARNING, "failed to recover some "
|
||||||
|
|
Loading…
Reference in New Issue