]> 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 fef87dd70d1774e8b70ef397b21098b7b98b0233..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 } */
@@ -895,6 +895,7 @@ static u64 ata_read_native_max_address(struct ata_device *dev)
 /**
  *     ata_set_native_max_address_ext  -       LBA48 native max set
  *     @dev: Device to query
+ *     @new_sectors: new max sectors value to set for the device
  *
  *     Perform an LBA48 size set max upon the device in question. Return the
  *     actual LBA48 size or zero if the command fails.
@@ -932,6 +933,7 @@ static u64 ata_set_native_max_address_ext(struct ata_device *dev, u64 new_sector
 /**
  *     ata_set_native_max_address      -       LBA28 native max set
  *     @dev: Device to query
+ *     @new_sectors: new max sectors value to set for the device
  *
  *     Perform an LBA28 size set max upon the device in question. Return the
  *     actual LBA28 size or zero if the command fails.
@@ -975,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
@@ -1586,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
@@ -1609,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 */
@@ -1652,7 +1654,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
        struct ata_taskfile tf;
        unsigned int err_mask = 0;
        const char *reason;
-       int tried_spinup = 0;
+       int may_fallback = 1, tried_spinup = 0;
        int rc;
 
        if (ata_msg_ctl(ap))
@@ -1696,11 +1698,31 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
                        return -ENOENT;
                }
 
+               /* Device or controller might have reported the wrong
+                * device class.  Give a shot at the other IDENTIFY if
+                * the current one is aborted by the device.
+                */
+               if (may_fallback &&
+                   (err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
+                       may_fallback = 0;
+
+                       if (class == ATA_DEV_ATA)
+                               class = ATA_DEV_ATAPI;
+                       else
+                               class = ATA_DEV_ATA;
+                       goto retry;
+               }
+
                rc = -EIO;
                reason = "I/O error";
                goto err_out;
        }
 
+       /* Falling back doesn't make sense if ID data was read
+        * successfully at least once.
+        */
+       may_fallback = 0;
+
        swap_buf_le16(id, ATA_ID_WORDS);
 
        /* sanity check */
@@ -1841,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);
@@ -1891,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,
@@ -2642,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 */
@@ -2858,7 +2879,7 @@ int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
                dev = &ap->device[i];
 
                /* don't update suspended devices' xfer mode */
-               if (!ata_dev_ready(dev))
+               if (!ata_dev_enabled(dev))
                        continue;
 
                rc = ata_dev_set_mode(dev);
@@ -2872,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;
@@ -3004,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;
@@ -3604,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",
@@ -3616,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 "
@@ -3630,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
@@ -3660,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);
@@ -3731,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 |
@@ -5843,37 +5881,11 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
  */
 int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
 {
-       int i, j, rc;
+       int rc;
 
        rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1);
-       if (rc)
-               goto fail;
-
-       /* EH is quiescent now.  Fail if we have any ready device.
-        * This happens if hotplug occurs between completion of device
-        * suspension and here.
-        */
-       for (i = 0; i < host->n_ports; i++) {
-               struct ata_port *ap = host->ports[i];
-
-               for (j = 0; j < ATA_MAX_DEVICES; j++) {
-                       struct ata_device *dev = &ap->device[j];
-
-                       if (ata_dev_ready(dev)) {
-                               ata_port_printk(ap, KERN_WARNING,
-                                               "suspend failed, device %d "
-                                               "still active\n", dev->devno);
-                               rc = -EBUSY;
-                               goto fail;
-                       }
-               }
-       }
-
-       host->dev->power.power_state = mesg;
-       return 0;
-
- fail:
-       ata_host_resume(host);
+       if (rc == 0)
+               host->dev->power.power_state = mesg;
        return rc;
 }
 
@@ -5982,6 +5994,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
        if (!ap)
                return NULL;
 
+       ap->pflags |= ATA_PFLAG_INITIALIZING;
        ap->lock = &host->lock;
        ap->flags = ATA_FLAG_DISABLED;
        ap->print_id = -1;
@@ -6350,6 +6363,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
                        ehi->action |= ATA_EH_SOFTRESET;
                        ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
 
+                       ap->pflags &= ~ATA_PFLAG_INITIALIZING;
                        ap->pflags |= ATA_PFLAG_LOADING;
                        ata_port_schedule_eh(ap);
 
@@ -6874,6 +6888,7 @@ EXPORT_SYMBOL_GPL(ata_timing_merge);
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL_GPL(pci_test_config_bits);
 EXPORT_SYMBOL_GPL(ata_pci_init_native_host);
+EXPORT_SYMBOL_GPL(ata_pci_init_bmdma);
 EXPORT_SYMBOL_GPL(ata_pci_prepare_native_host);
 EXPORT_SYMBOL_GPL(ata_pci_init_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
@@ -6887,11 +6902,6 @@ EXPORT_SYMBOL_GPL(ata_pci_default_filter);
 EXPORT_SYMBOL_GPL(ata_pci_clear_simplex);
 #endif /* CONFIG_PCI */
 
-#ifdef CONFIG_PM
-EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
-EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
-#endif /* CONFIG_PM */
-
 EXPORT_SYMBOL_GPL(ata_eng_timeout);
 EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
 EXPORT_SYMBOL_GPL(ata_port_abort);