]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ata/libata-core.c
libata: don't consider 0xff as port empty if SStatus is available
[linux-2.6-omap-h63xx.git] / drivers / ata / libata-core.c
index 335ac8fb5251113ad2ec7d927af83eceb3ee9c1b..5788a9dd0445ca3f414ac7c5bd6d029fd65a33c7 100644 (file)
@@ -59,7 +59,7 @@
 
 #include "libata.h"
 
-#define DRV_VERSION    "2.20"  /* must be exactly four chars */
+#define DRV_VERSION    "2.21"  /* must be exactly four chars */
 
 
 /* debounce timing parameters in msecs { interval, duration, timeout } */
@@ -101,12 +101,6 @@ int libata_noacpi = 1;
 module_param_named(noacpi, libata_noacpi, int, 0444);
 MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set");
 
-int ata_spindown_compat = 1;
-module_param_named(spindown_compat, ata_spindown_compat, int, 0644);
-MODULE_PARM_DESC(spindown_compat, "Enable backward compatible spindown "
-                "behavior.  Will be removed.  More info can be found in "
-                "Documentation/feature-removal-schedule.txt\n");
-
 MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("Library module for ATA devices");
 MODULE_LICENSE("GPL");
@@ -983,7 +977,7 @@ static u64 ata_hpa_resize(struct ata_device *dev)
 {
        u64 sectors = dev->n_sectors;
        u64 hpa_sectors;
-       
+
        if (ata_id_has_lba48(dev->id))
                hpa_sectors = ata_read_native_max_address_ext(dev);
        else
@@ -1594,7 +1588,7 @@ unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd)
  *     Check if the current speed of the device requires IORDY. Used
  *     by various controllers for chip configuration.
  */
+
 unsigned int ata_pio_need_iordy(const struct ata_device *adev)
 {
        /* Controller doesn't support  IORDY. Probably a pointless check
@@ -1617,7 +1611,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
  *     Compute the highest mode possible if we are not using iordy. Return
  *     -1 if no iordy mode is available.
  */
+
 static u32 ata_pio_mask_no_iordy(const struct ata_device *adev)
 {
        /* If we have no drive specific rule, then PIO 2 is non IORDY */
@@ -1869,7 +1863,7 @@ int ata_dev_configure(struct ata_device *dev)
                ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
 
        /* set _SDD */
-       rc = ata_acpi_push_id(ap, dev->devno);
+       rc = ata_acpi_push_id(dev);
        if (rc) {
                ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n",
                        rc);
@@ -1919,7 +1913,6 @@ int ata_dev_configure(struct ata_device *dev)
                        snprintf(revbuf, 7, "ATA-%d",  ata_id_major_version(id));
 
                dev->n_sectors = ata_id_n_sectors(id);
-               dev->n_sectors_boot = dev->n_sectors;
 
                /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
                ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
@@ -2670,7 +2663,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
                t->active += (t->cycle - (t->active + t->recover)) / 2;
                t->recover = t->cycle - t->active;
        }
-       
+
        /* In a few cases quantisation may produce enough errors to
           leave t->cycle too low for the sum of active and recovery
           if so we must correct this */
@@ -2900,9 +2893,6 @@ int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
        if (used_dma && (ap->host->flags & ATA_HOST_SIMPLEX))
                ap->host->simplex_claimed = ap;
 
-       /* step5: chip specific finalisation */
-       if (ap->ops->post_set_mode)
-               ap->ops->post_set_mode(ap);
  out:
        if (rc)
                *r_failed_dev = dev;
@@ -3032,7 +3022,7 @@ int ata_wait_ready(struct ata_port *ap, unsigned long deadline)
 
                if (!(status & ATA_BUSY))
                        return 0;
-               if (status == 0xff)
+               if (!ata_port_online(ap) && status == 0xff)
                        return -ENODEV;
                if (time_after(now, deadline))
                        return -EBUSY;
@@ -3632,7 +3622,6 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
        const u16 *old_id = dev->id;
        unsigned char model[2][ATA_ID_PROD_LEN + 1];
        unsigned char serial[2][ATA_ID_SERNO_LEN + 1];
-       u64 new_n_sectors;
 
        if (dev->class != new_class) {
                ata_dev_printk(dev, KERN_INFO, "class mismatch %d != %d\n",
@@ -3644,7 +3633,6 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
        ata_id_c_string(new_id, model[1], ATA_ID_PROD, sizeof(model[1]));
        ata_id_c_string(old_id, serial[0], ATA_ID_SERNO, sizeof(serial[0]));
        ata_id_c_string(new_id, serial[1], ATA_ID_SERNO, sizeof(serial[1]));
-       new_n_sectors = ata_id_n_sectors(new_id);
 
        if (strcmp(model[0], model[1])) {
                ata_dev_printk(dev, KERN_INFO, "model number mismatch "
@@ -3658,25 +3646,12 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
                return 0;
        }
 
-       if (dev->class == ATA_DEV_ATA && dev->n_sectors != new_n_sectors) {
-               ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch "
-                              "%llu != %llu\n",
-                              (unsigned long long)dev->n_sectors,
-                              (unsigned long long)new_n_sectors);
-               /* Are we the boot time size - if so we appear to be the
-                  same disk at this point and our HPA got reapplied */
-               if (ata_ignore_hpa && dev->n_sectors_boot == new_n_sectors 
-                   && ata_id_hpa_enabled(new_id))
-                       return 1;
-               return 0;
-       }
-
        return 1;
 }
 
 /**
- *     ata_dev_revalidate - Revalidate ATA device
- *     @dev: device to revalidate
+ *     ata_dev_reread_id - Re-read IDENTIFY data
+ *     @adev: target ATA device
  *     @readid_flags: read ID flags
  *
  *     Re-read IDENTIFY page and make sure @dev is still attached to
@@ -3688,34 +3663,68 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
  *     RETURNS:
  *     0 on success, negative errno otherwise
  */
-int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags)
+int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags)
 {
        unsigned int class = dev->class;
        u16 *id = (void *)dev->ap->sector_buf;
        int rc;
 
-       if (!ata_dev_enabled(dev)) {
-               rc = -ENODEV;
-               goto fail;
-       }
-
        /* read ID data */
        rc = ata_dev_read_id(dev, &class, readid_flags, id);
        if (rc)
-               goto fail;
+               return rc;
 
        /* is the device still there? */
-       if (!ata_dev_same_device(dev, class, id)) {
-               rc = -ENODEV;
-               goto fail;
-       }
+       if (!ata_dev_same_device(dev, class, id))
+               return -ENODEV;
 
        memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS);
+       return 0;
+}
+
+/**
+ *     ata_dev_revalidate - Revalidate ATA device
+ *     @dev: device to revalidate
+ *     @readid_flags: read ID flags
+ *
+ *     Re-read IDENTIFY page, make sure @dev is still attached to the
+ *     port and reconfigure it according to the new IDENTIFY page.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ *
+ *     RETURNS:
+ *     0 on success, negative errno otherwise
+ */
+int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags)
+{
+       u64 n_sectors = dev->n_sectors;
+       int rc;
+
+       if (!ata_dev_enabled(dev))
+               return -ENODEV;
+
+       /* re-read ID */
+       rc = ata_dev_reread_id(dev, readid_flags);
+       if (rc)
+               goto fail;
 
        /* configure device according to the new ID */
        rc = ata_dev_configure(dev);
-       if (rc == 0)
-               return 0;
+       if (rc)
+               goto fail;
+
+       /* verify n_sectors hasn't changed */
+       if (dev->class == ATA_DEV_ATA && dev->n_sectors != n_sectors) {
+               ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch "
+                              "%llu != %llu\n",
+                              (unsigned long long)n_sectors,
+                              (unsigned long long)dev->n_sectors);
+               rc = -ENODEV;
+               goto fail;
+       }
+
+       return 0;
 
  fail:
        ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc);
@@ -3759,6 +3768,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,ATA_HORKAGE_NODMA },
        { "_NEC DV5800A",       NULL,           ATA_HORKAGE_NODMA },
        { "SAMSUNG CD-ROM SN-124","N001",       ATA_HORKAGE_NODMA },
+       { "Seagate STT20000A", NULL,            ATA_HORKAGE_NODMA },
 
        /* Weird ATAPI devices */
        { "TORiSAN DVD-ROM DRD-N216", NULL,     ATA_HORKAGE_MAX_SEC_128 |