diff options
-rw-r--r-- | drivers/ata/libata-core.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 6ac4f32ddcc2..335ac8fb5251 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -1660,7 +1660,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, | |||
1660 | struct ata_taskfile tf; | 1660 | struct ata_taskfile tf; |
1661 | unsigned int err_mask = 0; | 1661 | unsigned int err_mask = 0; |
1662 | const char *reason; | 1662 | const char *reason; |
1663 | int tried_spinup = 0; | 1663 | int may_fallback = 1, tried_spinup = 0; |
1664 | int rc; | 1664 | int rc; |
1665 | 1665 | ||
1666 | if (ata_msg_ctl(ap)) | 1666 | if (ata_msg_ctl(ap)) |
@@ -1704,11 +1704,31 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, | |||
1704 | return -ENOENT; | 1704 | return -ENOENT; |
1705 | } | 1705 | } |
1706 | 1706 | ||
1707 | /* Device or controller might have reported the wrong | ||
1708 | * device class. Give a shot at the other IDENTIFY if | ||
1709 | * the current one is aborted by the device. | ||
1710 | */ | ||
1711 | if (may_fallback && | ||
1712 | (err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) { | ||
1713 | may_fallback = 0; | ||
1714 | |||
1715 | if (class == ATA_DEV_ATA) | ||
1716 | class = ATA_DEV_ATAPI; | ||
1717 | else | ||
1718 | class = ATA_DEV_ATA; | ||
1719 | goto retry; | ||
1720 | } | ||
1721 | |||
1707 | rc = -EIO; | 1722 | rc = -EIO; |
1708 | reason = "I/O error"; | 1723 | reason = "I/O error"; |
1709 | goto err_out; | 1724 | goto err_out; |
1710 | } | 1725 | } |
1711 | 1726 | ||
1727 | /* Falling back doesn't make sense if ID data was read | ||
1728 | * successfully at least once. | ||
1729 | */ | ||
1730 | may_fallback = 0; | ||
1731 | |||
1712 | swap_buf_le16(id, ATA_ID_WORDS); | 1732 | swap_buf_le16(id, ATA_ID_WORDS); |
1713 | 1733 | ||
1714 | /* sanity check */ | 1734 | /* sanity check */ |