aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-eh.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-11-10 04:08:10 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-01 22:45:55 -0500
commit55a8e2c83ce50548dfef74bb19dfe2b809cb3099 (patch)
tree1d5ed12c49a254364f9009e9cdbf4609b92f3afb /drivers/ata/libata-eh.c
parentbff0464769f2a1bd348265de704471747378e247 (diff)
[PATCH] libata: implement presence detection via polling IDENTIFY
On some controllers (ICHs in piix mode), there is *NO* reliable way to determine device presence other than issuing IDENTIFY and see how the transaction proceeds by watching the TF status register. libata acted this way before irq-pio and phantom devices caused very little problem but now that IDENTIFY is performed using IRQ drive PIO, such phantom devices now result in multiple 30sec timeouts during boot. This patch implements ATA_FLAG_DETECT_POLLING. If a LLD sets this flag, libata core issues the initial IDENTIFY in polling mode and if the initial data transfer fails w/ HSM violation, the port is considered to be empty thus replicating the old libata and IDE behavior. Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r--drivers/ata/libata-eh.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 755fc68b5374..e69f3df2ea39 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1667,12 +1667,23 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
1667 ata_class_enabled(ehc->classes[dev->devno])) { 1667 ata_class_enabled(ehc->classes[dev->devno])) {
1668 dev->class = ehc->classes[dev->devno]; 1668 dev->class = ehc->classes[dev->devno];
1669 1669
1670 if (ap->flags & ATA_FLAG_DETECT_POLLING)
1671 readid_flags |= ATA_READID_DETECT;
1672
1670 rc = ata_dev_read_id(dev, &dev->class, readid_flags, 1673 rc = ata_dev_read_id(dev, &dev->class, readid_flags,
1671 dev->id); 1674 dev->id);
1672 if (rc == 0) { 1675 if (rc == 0) {
1673 ehc->i.flags |= ATA_EHI_PRINTINFO; 1676 ehc->i.flags |= ATA_EHI_PRINTINFO;
1674 rc = ata_dev_configure(dev); 1677 rc = ata_dev_configure(dev);
1675 ehc->i.flags &= ~ATA_EHI_PRINTINFO; 1678 ehc->i.flags &= ~ATA_EHI_PRINTINFO;
1679 } else if (rc == -ENOENT) {
1680 /* IDENTIFY was issued to non-existent
1681 * device. No need to reset. Just
1682 * thaw and kill the device.
1683 */
1684 ata_eh_thaw_port(ap);
1685 dev->class = ATA_DEV_UNKNOWN;
1686 rc = 0;
1676 } 1687 }
1677 1688
1678 if (rc) { 1689 if (rc) {
@@ -1680,12 +1691,14 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
1680 break; 1691 break;
1681 } 1692 }
1682 1693
1683 spin_lock_irqsave(ap->lock, flags); 1694 if (ata_dev_enabled(dev)) {
1684 ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG; 1695 spin_lock_irqsave(ap->lock, flags);
1685 spin_unlock_irqrestore(ap->lock, flags); 1696 ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
1697 spin_unlock_irqrestore(ap->lock, flags);
1686 1698
1687 /* new device discovered, configure transfer mode */ 1699 /* new device discovered, configure xfermode */
1688 ehc->i.flags |= ATA_EHI_SETMODE; 1700 ehc->i.flags |= ATA_EHI_SETMODE;
1701 }
1689 } 1702 }
1690 } 1703 }
1691 1704