|
@@ -1660,7 +1660,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
|
|
|
struct ata_taskfile tf;
|
|
|
unsigned int err_mask = 0;
|
|
|
const char *reason;
|
|
|
- int tried_spinup = 0;
|
|
|
+ int may_fallback = 1, tried_spinup = 0;
|
|
|
int rc;
|
|
|
|
|
|
if (ata_msg_ctl(ap))
|
|
@@ -1704,11 +1704,31 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
|
|
|
return -ENOENT;
|
|
|
}
|
|
|
|
|
|
+ /* Device or controller might have reported the wrong
|
|
|
+ * device class. Give a shot at the other IDENTIFY if
|
|
|
+ * the current one is aborted by the device.
|
|
|
+ */
|
|
|
+ if (may_fallback &&
|
|
|
+ (err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
|
|
|
+ may_fallback = 0;
|
|
|
+
|
|
|
+ if (class == ATA_DEV_ATA)
|
|
|
+ class = ATA_DEV_ATAPI;
|
|
|
+ else
|
|
|
+ class = ATA_DEV_ATA;
|
|
|
+ goto retry;
|
|
|
+ }
|
|
|
+
|
|
|
rc = -EIO;
|
|
|
reason = "I/O error";
|
|
|
goto err_out;
|
|
|
}
|
|
|
|
|
|
+ /* Falling back doesn't make sense if ID data was read
|
|
|
+ * successfully at least once.
|
|
|
+ */
|
|
|
+ may_fallback = 0;
|
|
|
+
|
|
|
swap_buf_le16(id, ATA_ID_WORDS);
|
|
|
|
|
|
/* sanity check */
|