libata: handle early device PIO modes correctly
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 21 Oct 2005 22:46:32 +0000 (18:46 -0400)
committerJeff Garzik <jgarzik@pobox.com>
Fri, 21 Oct 2005 22:46:32 +0000 (18:46 -0400)
drivers/scsi/libata-core.c
include/linux/ata.h

index 175d4646333d88dd512ac7873bbc8cb4e80f9d0b..09639e7aaa7145559ade55c2ea3aed942c7cd09c 100644 (file)
@@ -1082,6 +1082,31 @@ static inline void ata_dump_id(struct ata_device *dev)
                dev->id[93]);
 }
 
+/*
+ *     Compute the PIO modes available for this device. This is not as
+ *     trivial as it seems if we must consider early devices correctly.
+ *
+ *     FIXME: pre IDE drive timing (do we care ?). 
+ */
+
+static unsigned int ata_pio_modes(struct ata_device *adev)
+{
+       u16 modes;
+
+       /* Usual case. Word 53 indicates word 88 is valid */
+       if (adev->id[ATA_ID_FIELD_VALID] & (1 << 2)) {
+               modes = adev->id[ATA_ID_PIO_MODES] & 0x03;
+               modes <<= 3;
+               modes |= 0x7;
+               return modes;
+       }
+
+       /* If word 88 isn't valid then Word 51 holds the PIO timing number
+          for the maximum. Turn it into a mask and return it */
+       modes = (2 << (adev->id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ;
+       return modes;
+}
+
 /**
  *     ata_dev_identify - obtain IDENTIFY x DEVICE page
  *     @ap: port on which device we wish to probe resides
@@ -1215,10 +1240,8 @@ retry:
        xfer_modes = dev->id[ATA_ID_UDMA_MODES];
        if (!xfer_modes)
                xfer_modes = (dev->id[ATA_ID_MWDMA_MODES]) << ATA_SHIFT_MWDMA;
-       if (!xfer_modes) {
-               xfer_modes = (dev->id[ATA_ID_PIO_MODES]) << (ATA_SHIFT_PIO + 3);
-               xfer_modes |= (0x7 << ATA_SHIFT_PIO);
-       }
+       if (!xfer_modes)
+               xfer_modes = ata_pio_modes(dev);
 
        ata_dump_id(dev);
 
index 630908c9378b45f3ed65bf1118171ff1cbd904dd..33276d1d05d26e0672e9bf89c8b7b3da809abbc1 100644 (file)
@@ -42,13 +42,18 @@ enum {
        ATA_SECT_SIZE           = 512,
 
        ATA_ID_WORDS            = 256,
-       ATA_ID_PROD_OFS         = 27,
-       ATA_ID_FW_REV_OFS       = 23,
        ATA_ID_SERNO_OFS        = 10,
-       ATA_ID_MAJOR_VER        = 80,
-       ATA_ID_PIO_MODES        = 64,
+       ATA_ID_FW_REV_OFS       = 23,
+       ATA_ID_PROD_OFS         = 27,
+       ATA_ID_OLD_PIO_MODES    = 51,
+       ATA_ID_FIELD_VALID      = 53,
        ATA_ID_MWDMA_MODES      = 63,
+       ATA_ID_PIO_MODES        = 64,
+       ATA_ID_EIDE_DMA_MIN     = 65,
+       ATA_ID_EIDE_PIO         = 67,
+       ATA_ID_EIDE_PIO_IORDY   = 68,
        ATA_ID_UDMA_MODES       = 88,
+       ATA_ID_MAJOR_VER        = 80,
        ATA_ID_PIO4             = (1 << 1),
 
        ATA_PCI_CTL_OFS         = 2,