libata: add CONFIG_PM to libata core layer
[powerpc.git] / drivers / ata / libata-core.c
index 3adc2cf..dc362fa 100644 (file)
@@ -59,7 +59,7 @@
 
 #include "libata.h"
 
-#define DRV_VERSION    "2.10"  /* must be exactly four chars */
+#define DRV_VERSION    "2.20"  /* must be exactly four chars */
 
 
 /* debounce timing parameters in msecs { interval, duration, timeout } */
@@ -72,7 +72,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev,
 static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
 static void ata_dev_xfermask(struct ata_device *dev);
 
-static unsigned int ata_unique_id = 1;
+static unsigned int ata_print_id = 1;
 static struct workqueue_struct *ata_wq;
 
 struct workqueue_struct *ata_aux_wq;
@@ -823,6 +823,48 @@ static u64 ata_id_n_sectors(const u16 *id)
        }
 }
 
+/**
+ *     ata_id_to_dma_mode      -       Identify DMA mode from id block
+ *     @dev: device to identify
+ *     @mode: mode to assume if we cannot tell
+ *
+ *     Set up the timing values for the device based upon the identify
+ *     reported values for the DMA mode. This function is used by drivers
+ *     which rely upon firmware configured modes, but wish to report the
+ *     mode correctly when possible.
+ *
+ *     In addition we emit similarly formatted messages to the default
+ *     ata_dev_set_mode handler, in order to provide consistency of
+ *     presentation.
+ */
+
+void ata_id_to_dma_mode(struct ata_device *dev, u8 unknown)
+{
+       unsigned int mask;
+       u8 mode;
+
+       /* Pack the DMA modes */
+       mask = ((dev->id[63] >> 8) << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA;
+       if (dev->id[53] & 0x04)
+               mask |= ((dev->id[88] >> 8) << ATA_SHIFT_UDMA) & ATA_MASK_UDMA;
+
+       /* Select the mode in use */
+       mode = ata_xfer_mask2mode(mask);
+
+       if (mode != 0) {
+               ata_dev_printk(dev, KERN_INFO, "configured for %s\n",
+                      ata_mode_string(mask));
+       } else {
+               /* SWDMA perhaps ? */
+               mode = unknown;
+               ata_dev_printk(dev, KERN_INFO, "configured for DMA\n");
+       }
+
+       /* Configure the device reporting */
+       dev->xfer_mode = mode;
+       dev->xfer_shift = ata_xfer_mode2shift(mode);
+}
+
 /**
  *     ata_noop_dev_select - Select device 0/1 on ATA bus
  *     @ap: ATA channel to manipulate
@@ -891,8 +933,8 @@ void ata_dev_select(struct ata_port *ap, unsigned int device,
                           unsigned int wait, unsigned int can_sleep)
 {
        if (ata_msg_probe(ap))
-               ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, ata%u: "
-                               "device %u, wait %u\n", ap->id, device, wait);
+               ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, "
+                               "device %u, wait %u\n", device, wait);
 
        if (wait)
                ata_wait_idle(ap);
@@ -1392,8 +1434,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
        int rc;
 
        if (ata_msg_ctl(ap))
-               ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n",
-                              __FUNCTION__, ap->id, dev->devno);
+               ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
 
        ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
 
@@ -1430,7 +1471,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
        if (err_mask) {
                if (err_mask & AC_ERR_NODEV_HINT) {
                        DPRINTK("ata%u.%d: NODEV after polling detection\n",
-                               ap->id, dev->devno);
+                               ap->print_id, dev->devno);
                        return -ENOENT;
                }
 
@@ -1558,15 +1599,13 @@ int ata_dev_configure(struct ata_device *dev)
        int rc;
 
        if (!ata_dev_enabled(dev) && ata_msg_info(ap)) {
-               ata_dev_printk(dev, KERN_INFO,
-                              "%s: ENTER/EXIT (host %u, dev %u) -- nodev\n",
-                              __FUNCTION__, ap->id, dev->devno);
+               ata_dev_printk(dev, KERN_INFO, "%s: ENTER/EXIT -- nodev\n",
+                              __FUNCTION__);
                return 0;
        }
 
        if (ata_msg_probe(ap))
-               ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n",
-                              __FUNCTION__, ap->id, dev->devno);
+               ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
 
        /* set _SDD */
        rc = ata_acpi_push_id(ap, dev->devno);
@@ -1610,8 +1649,9 @@ int ata_dev_configure(struct ata_device *dev)
        if (dev->class == ATA_DEV_ATA) {
                if (ata_id_is_cfa(id)) {
                        if (id[162] & 1) /* CPRM may make this media unusable */
-                               ata_dev_printk(dev, KERN_WARNING, "ata%u: device %u  supports DRM functions and may not be fully accessable.\n",
-                                       ap->id, dev->devno);
+                               ata_dev_printk(dev, KERN_WARNING,
+                                              "supports DRM functions and may "
+                                              "not be fully accessable.\n");
                        snprintf(revbuf, 7, "CFA");
                }
                else
@@ -1679,7 +1719,7 @@ int ata_dev_configure(struct ata_device *dev)
                                        "%s: %s, %s, max %s\n",
                                        revbuf, modelbuf, fwrevbuf,
                                        ata_mode_string(xfer_mask));
-                               ata_dev_printk(dev, KERN_INFO, 
+                               ata_dev_printk(dev, KERN_INFO,
                                        "%Lu sectors, multi %u, CHS %u/%u/%u\n",
                                        (unsigned long long)dev->n_sectors,
                                        dev->multi_count, dev->cylinders,
@@ -1810,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])
@@ -1824,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);
@@ -2516,12 +2568,11 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
         * host channels are not permitted to do so.
         */
        if (used_dma && (ap->host->flags & ATA_HOST_SIMPLEX))
-               ap->host->simplex_claimed = 1;
+               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;
@@ -2650,7 +2701,7 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
 {
        struct ata_ioports *ioaddr = &ap->ioaddr;
 
-       DPRINTK("ata%u: bus reset via SRST\n", ap->id);
+       DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);
 
        /* software reset.  causes dev0 to be selected */
        iowrite8(ap->ctl, ioaddr->ctl_addr);
@@ -2710,7 +2761,7 @@ void ata_bus_reset(struct ata_port *ap)
        u8 err;
        unsigned int dev0, dev1 = 0, devmask = 0;
 
-       DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no);
+       DPRINTK("ENTER, host %u, port %u\n", ap->print_id, ap->port_no);
 
        /* determine if device 0/1 are present */
        if (ap->flags & ATA_FLAG_SATA_RESET)
@@ -3306,6 +3357,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        /* Devices where NCQ should be avoided */
        /* NCQ is slow */
         { "WDC WD740ADFD-00",   NULL,          ATA_HORKAGE_NONCQ },
+       /* http://thread.gmane.org/gmane.linux.ide/14907 */
+       { "FUJITSU MHT2060BH",  NULL,           ATA_HORKAGE_NONCQ },
 
        /* Devices with NCQ limits */
 
@@ -3402,7 +3455,7 @@ static void ata_dev_xfermask(struct ata_device *dev)
                               "device is on DMA blacklist, disabling DMA\n");
        }
 
-       if ((host->flags & ATA_HOST_SIMPLEX) && host->simplex_claimed) {
+       if ((host->flags & ATA_HOST_SIMPLEX) && host->simplex_claimed != ap) {
                xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
                ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by "
                               "other device, disabling DMA\n");
@@ -3779,7 +3832,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
        struct scatterlist *lsg = &sg[qc->n_elem - 1];
        int n_elem, pre_n_elem, dir, trim_sg = 0;
 
-       VPRINTK("ENTER, ata%u\n", ap->id);
+       VPRINTK("ENTER, ata%u\n", ap->print_id);
        WARN_ON(!(qc->flags & ATA_QCFLAG_SG));
 
        /* we must lengthen transfers to end on a 32-bit boundary */
@@ -4180,7 +4233,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
        if (do_write != i_write)
                goto err_out;
 
-       VPRINTK("ata%u: xfering %d bytes\n", ap->id, bytes);
+       VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes);
 
        __atapi_pio_bytes(qc, bytes);
 
@@ -4297,7 +4350,7 @@ int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
 
 fsm_start:
        DPRINTK("ata%u: protocol %d task_state %d (dev_stat 0x%X)\n",
-               ap->id, qc->tf.protocol, ap->hsm_task_state, status);
+               ap->print_id, qc->tf.protocol, ap->hsm_task_state, status);
 
        switch (ap->hsm_task_state) {
        case HSM_ST_FIRST:
@@ -4330,8 +4383,8 @@ fsm_start:
                 * let the EH abort the command or reset the device.
                 */
                if (unlikely(status & (ATA_ERR | ATA_DF))) {
-                       printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n",
-                              ap->id, status);
+                       ata_port_printk(ap, KERN_WARNING, "DRQ=1 with device "
+                                       "error, dev_stat 0x%X\n", status);
                        qc->err_mask |= AC_ERR_HSM;
                        ap->hsm_task_state = HSM_ST_ERR;
                        goto fsm_start;
@@ -4388,8 +4441,9 @@ fsm_start:
                         * let the EH abort the command or reset the device.
                         */
                        if (unlikely(status & (ATA_ERR | ATA_DF))) {
-                               printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n",
-                                      ap->id, status);
+                               ata_port_printk(ap, KERN_WARNING, "DRQ=1 with "
+                                               "device error, dev_stat 0x%X\n",
+                                               status);
                                qc->err_mask |= AC_ERR_HSM;
                                ap->hsm_task_state = HSM_ST_ERR;
                                goto fsm_start;
@@ -4475,7 +4529,7 @@ fsm_start:
 
                /* no more data to transfer */
                DPRINTK("ata%u: dev %u command complete, drv_stat 0x%x\n",
-                       ap->id, qc->dev->devno, status);
+                       ap->print_id, qc->dev->devno, status);
 
                WARN_ON(qc->err_mask);
 
@@ -5017,7 +5071,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
        u8 status, host_stat = 0;
 
        VPRINTK("ata%u: protocol %d task_state %d\n",
-               ap->id, qc->tf.protocol, ap->hsm_task_state);
+               ap->print_id, qc->tf.protocol, ap->hsm_task_state);
 
        /* Check whether we are expecting interrupt in this state */
        switch (ap->hsm_task_state) {
@@ -5038,7 +5092,8 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
                    qc->tf.protocol == ATA_PROT_ATAPI_DMA) {
                        /* check status of DMA engine */
                        host_stat = ap->ops->bmdma_status(ap);
-                       VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat);
+                       VPRINTK("ata%u: host_stat 0x%X\n",
+                               ap->print_id, host_stat);
 
                        /* if it's not our irq... */
                        if (!(host_stat & ATA_DMA_INTR))
@@ -5299,6 +5354,7 @@ int ata_flush_cache(struct ata_device *dev)
        return 0;
 }
 
+#ifdef CONFIG_PM
 static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
                               unsigned int action, unsigned int ehi_flags,
                               int wait)
@@ -5414,6 +5470,7 @@ void ata_host_resume(struct ata_host *host)
                            ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
        host->dev->power.power_state = PMSG_ON;
 }
+#endif
 
 /**
  *     ata_port_start - Set port up for dma.
@@ -5497,7 +5554,7 @@ void ata_port_init(struct ata_port *ap, struct ata_host *host,
 
        ap->lock = &host->lock;
        ap->flags = ATA_FLAG_DISABLED;
-       ap->id = ata_unique_id++;
+       ap->print_id = ata_print_id++;
        ap->ctl = ATA_DEVCTL_OBS;
        ap->host = host;
        ap->dev = ent->dev;
@@ -5568,7 +5625,7 @@ static void ata_port_init_shost(struct ata_port *ap, struct Scsi_Host *shost)
 {
        ap->scsi_host = shost;
 
-       shost->unique_id = ap->id;
+       shost->unique_id = ap->print_id;
        shost->max_id = 16;
        shost->max_lun = 1;
        shost->max_channel = 1;
@@ -5638,6 +5695,8 @@ static void ata_host_release(struct device *gendev, void *res)
 
        if (host->ops->host_stop)
                host->ops->host_stop(host);
+
+       dev_set_drvdata(gendev, NULL);
 }
 
 /**
@@ -5832,9 +5891,9 @@ int ata_device_add(const struct ata_probe_ent *ent)
                        /* wait for EH to finish */
                        ata_port_wait_eh(ap);
                } else {
-                       DPRINTK("ata%u: bus probe begin\n", ap->id);
+                       DPRINTK("ata%u: bus probe begin\n", ap->print_id);
                        rc = ata_bus_probe(ap);
-                       DPRINTK("ata%u: bus probe end\n", ap->id);
+                       DPRINTK("ata%u: bus probe end\n", ap->print_id);
 
                        if (rc) {
                                /* FIXME: do something useful here?
@@ -5860,7 +5919,6 @@ int ata_device_add(const struct ata_probe_ent *ent)
 
  err_out:
        devres_release_group(dev, ata_device_add);
-       dev_set_drvdata(dev, NULL);
        VPRINTK("EXIT, returning %d\n", rc);
        return 0;
 }
@@ -6048,6 +6106,7 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
        return (tmp == bits->val) ? 1 : 0;
 }
 
+#ifdef CONFIG_PM
 void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
        pci_save_state(pdev);
@@ -6099,6 +6158,8 @@ int ata_pci_device_resume(struct pci_dev *pdev)
                ata_host_resume(host);
        return rc;
 }
+#endif /* CONFIG_PM */
+
 #endif /* CONFIG_PCI */
 
 
@@ -6276,6 +6337,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_drive_eh);
 EXPORT_SYMBOL_GPL(ata_bmdma_error_handler);
 EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd);
 EXPORT_SYMBOL_GPL(ata_port_probe);
+EXPORT_SYMBOL_GPL(ata_dev_disable);
 EXPORT_SYMBOL_GPL(sata_set_spd);
 EXPORT_SYMBOL_GPL(sata_phy_debounce);
 EXPORT_SYMBOL_GPL(sata_phy_resume);
@@ -6306,10 +6368,13 @@ EXPORT_SYMBOL_GPL(sata_scr_write);
 EXPORT_SYMBOL_GPL(sata_scr_write_flush);
 EXPORT_SYMBOL_GPL(ata_port_online);
 EXPORT_SYMBOL_GPL(ata_port_offline);
+#ifdef CONFIG_PM
 EXPORT_SYMBOL_GPL(ata_host_suspend);
 EXPORT_SYMBOL_GPL(ata_host_resume);
+#endif /* CONFIG_PM */
 EXPORT_SYMBOL_GPL(ata_id_string);
 EXPORT_SYMBOL_GPL(ata_id_c_string);
+EXPORT_SYMBOL_GPL(ata_id_to_dma_mode);
 EXPORT_SYMBOL_GPL(ata_device_blacklisted);
 EXPORT_SYMBOL_GPL(ata_scsi_simulate);
 
@@ -6322,16 +6387,20 @@ EXPORT_SYMBOL_GPL(pci_test_config_bits);
 EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
 EXPORT_SYMBOL_GPL(ata_pci_init_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
+#ifdef CONFIG_PM
 EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend);
 EXPORT_SYMBOL_GPL(ata_pci_device_do_resume);
 EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
 EXPORT_SYMBOL_GPL(ata_pci_device_resume);
+#endif /* CONFIG_PM */
 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);