aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2007-03-02 17:47:28 -0500
committerJeff Garzik <jeff@garzik.org>2007-03-02 17:47:28 -0500
commitf31f0cc2f0b7527072d94d02da332d9bb8d7d94c (patch)
tree0b35e182a2e094d4cf4ad786d27db79c04ec3267 /drivers/ata
parent032af1ce16d496b825adde0fa03948785ee16830 (diff)
downloadkernel_samsung_smdk4412-f31f0cc2f0b7527072d94d02da332d9bb8d7d94c.zip
kernel_samsung_smdk4412-f31f0cc2f0b7527072d94d02da332d9bb8d7d94c.tar.gz
kernel_samsung_smdk4412-f31f0cc2f0b7527072d94d02da332d9bb8d7d94c.tar.bz2
[libata] change master/slave IDENTIFY order
2.6.21-rc has horrible problems with libata and PATA cable types (and thus speeds). This occurs because Tejun fixed a pile of other bugs and we now do cable detect enforcement for drive side detection properly. Unfortunately we don't do the process around cable detection right. Tejun identified the problem and pointed to the right Annex in the spec, this patch implements the needed changes. The basic requirement is that we have to identify the slave before the master. The patch switches the identify order so that we can do the drive side detection correctly. [NOTE: patch and description extracted from a larger work written and signed-off-by Alan Cox] Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-core.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index eb59f16..606145e 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1850,8 +1850,11 @@ int ata_bus_probe(struct ata_port *ap)
for (i = 0; i < ATA_MAX_DEVICES; i++)
ap->device[i].pio_mode = XFER_PIO_0;
- /* read IDENTIFY page and configure devices */
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ /* read IDENTIFY page and configure devices. We have to do the identify
+ specific sequence bass-ackwards so that PDIAG- is released by
+ the slave device */
+
+ for (i = ATA_MAX_DEVICES - 1; i >= 0; i--) {
dev = &ap->device[i];
if (tries[i])
@@ -1864,6 +1867,15 @@ int ata_bus_probe(struct ata_port *ap)
dev->id);
if (rc)
goto fail;
+ }
+
+ /* After the identify sequence we can now set up the devices. We do
+ this in the normal order so that the user doesn't get confused */
+
+ for(i = 0; i < ATA_MAX_DEVICES; i++) {
+ dev = &ap->device[i];
+ if (!ata_dev_enabled(dev))
+ continue;
ap->eh_context.i.flags |= ATA_EHI_PRINTINFO;
rc = ata_dev_configure(dev);