Commit 1ffc151f authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik

libata: assume no device is attached if both IDENTIFYs are aborted

This is to fix bugzilla #10254.  QSI cdrom attached to pata_sis as
secondary master appears as phantom device for the slave.
Interestingly, instead of not setting DRQ after IDENTIFY which
triggers NODEV_HINT, it aborts both IDENTIFY and IDENTIFY PACKET which
makes EH retry.

Modify EH such that it assumes no device is attached if both flavors
of IDENTIFY are aborted by the device.  There really isn't much point
in retrying when the device actively aborts the commands.

While at it, convert NODEV detection message to ata_dev_printk() to
help debugging obscure detection problems.

This problem was reported by Jan Bücken.
Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
Cc: Jan Bücken <jb.faq@gmx.de>
Acked-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent b63b1331
...@@ -2092,17 +2092,18 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, ...@@ -2092,17 +2092,18 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
id, sizeof(id[0]) * ATA_ID_WORDS, 0); id, sizeof(id[0]) * ATA_ID_WORDS, 0);
if (err_mask) { if (err_mask) {
if (err_mask & AC_ERR_NODEV_HINT) { if (err_mask & AC_ERR_NODEV_HINT) {
DPRINTK("ata%u.%d: NODEV after polling detection\n", ata_dev_printk(dev, KERN_DEBUG,
ap->print_id, dev->devno); "NODEV after polling detection\n");
return -ENOENT; return -ENOENT;
} }
/* Device or controller might have reported the wrong if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
* device class. Give a shot at the other IDENTIFY if /* Device or controller might have reported
* the current one is aborted by the device. * the wrong device class. Give a shot at the
* other IDENTIFY if the current one is
* aborted by the device.
*/ */
if (may_fallback && if (may_fallback) {
(err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
may_fallback = 0; may_fallback = 0;
if (class == ATA_DEV_ATA) if (class == ATA_DEV_ATA)
...@@ -2112,6 +2113,15 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, ...@@ -2112,6 +2113,15 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
goto retry; goto retry;
} }
/* Control reaches here iff the device aborted
* both flavors of IDENTIFYs which happens
* sometimes with phantom devices.
*/
ata_dev_printk(dev, KERN_DEBUG,
"both IDENTIFYs aborted, assuming NODEV\n");
return -ENOENT;
}
rc = -EIO; rc = -EIO;
reason = "I/O error"; reason = "I/O error";
goto err_out; goto err_out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment