Merge branch 'master' into upstream
[pandora-kernel.git] / drivers / scsi / libata-core.c
index a42877e..df483ad 100644 (file)
@@ -981,8 +981,10 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc)
  *
  *     LOCKING:
  *     None.  Should be called with kernel context, might sleep.
+ *
+ *     RETURNS:
+ *     Zero on success, AC_ERR_* mask on failure
  */
-
 unsigned ata_exec_internal(struct ata_device *dev,
                           struct ata_taskfile *tf, const u8 *cdb,
                           int dma_dir, void *buf, unsigned int buflen)
@@ -1479,31 +1481,21 @@ static int ata_bus_probe(struct ata_port *ap)
        down_xfermask = 0;
 
        /* reset and determine device classes */
-       for (i = 0; i < ATA_MAX_DEVICES; i++)
-               classes[i] = ATA_DEV_UNKNOWN;
+       ap->ops->phy_reset(ap);
 
-       if (ap->ops->probe_reset) {
-               rc = ap->ops->probe_reset(ap, classes);
-               if (rc) {
-                       ata_port_printk(ap, KERN_ERR,
-                                       "reset failed (errno=%d)\n", rc);
-                       return rc;
-               }
-       } else {
-               ap->ops->phy_reset(ap);
+       for (i = 0; i < ATA_MAX_DEVICES; i++) {
+               dev = &ap->device[i];
 
-               for (i = 0; i < ATA_MAX_DEVICES; i++) {
-                       if (!(ap->flags & ATA_FLAG_DISABLED))
-                               classes[i] = ap->device[i].class;
-                       ap->device[i].class = ATA_DEV_UNKNOWN;
-               }
+               if (!(ap->flags & ATA_FLAG_DISABLED) &&
+                   dev->class != ATA_DEV_UNKNOWN)
+                       classes[dev->devno] = dev->class;
+               else
+                       classes[dev->devno] = ATA_DEV_NONE;
 
-               ata_port_probe(ap);
+               dev->class = ATA_DEV_UNKNOWN;
        }
 
-       for (i = 0; i < ATA_MAX_DEVICES; i++)
-               if (classes[i] == ATA_DEV_UNKNOWN)
-                       classes[i] = ATA_DEV_NONE;
+       ata_port_probe(ap);
 
        /* after the reset the device state is PIO 0 and the controller
           state is undefined. Record the mode */
@@ -2609,38 +2601,12 @@ int ata_std_prereset(struct ata_port *ap)
        return 0;
 }
 
-/**
- *     ata_std_probeinit - initialize probing
- *     @ap: port to be probed
- *
- *     @ap is about to be probed.  Initialize it.  This function is
- *     to be used as standard callback for ata_drive_probe_reset().
- *
- *     NOTE!!! Do not use this function as probeinit if a low level
- *     driver implements only hardreset.  Just pass NULL as probeinit
- *     in that case.  Using this function is probably okay but doing
- *     so makes reset sequence different from the original
- *     ->phy_reset implementation and Jeff nervous.  :-P
- */
-void ata_std_probeinit(struct ata_port *ap)
-{
-       static const unsigned long deb_timing[] = { 5, 100, 5000 };
-
-       /* resume link */
-       sata_phy_resume(ap, deb_timing);
-
-       /* wait for device */
-       if (ata_port_online(ap))
-               ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
-}
-
 /**
  *     ata_std_softreset - reset host port via ATA SRST
  *     @ap: port to reset
  *     @classes: resulting classes of attached devices
  *
- *     Reset host port using ATA SRST.  This function is to be used
- *     as standard callback for ata_drive_*_reset() functions.
+ *     Reset host port using ATA SRST.
  *
  *     LOCKING:
  *     Kernel thread context (may sleep)
@@ -2695,8 +2661,6 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
  *     @class: resulting class of attached device
  *
  *     SATA phy-reset host port using DET bits of SControl register.
- *     This function is to be used as standard callback for
- *     ata_drive_*_reset().
  *
  *     LOCKING:
  *     Kernel thread context (may sleep)
@@ -2775,9 +2739,6 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
  *     the device might have been reset more than once using
  *     different reset methods before postreset is invoked.
  *
- *     This function is to be used as standard callback for
- *     ata_drive_*_reset().
- *
  *     LOCKING:
  *     Kernel thread context (may sleep)
  */
@@ -2824,151 +2785,6 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
        DPRINTK("EXIT\n");
 }
 
-/**
- *     ata_std_probe_reset - standard probe reset method
- *     @ap: prot to perform probe-reset
- *     @classes: resulting classes of attached devices
- *
- *     The stock off-the-shelf ->probe_reset method.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep)
- *
- *     RETURNS:
- *     0 on success, -errno otherwise.
- */
-int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes)
-{
-       ata_reset_fn_t hardreset;
-
-       hardreset = NULL;
-       if (sata_scr_valid(ap))
-               hardreset = sata_std_hardreset;
-
-       return ata_drive_probe_reset(ap, ata_std_probeinit,
-                                    ata_std_softreset, hardreset,
-                                    ata_std_postreset, classes);
-}
-
-int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
-                unsigned int *classes)
-{
-       int i, rc;
-
-       for (i = 0; i < ATA_MAX_DEVICES; i++)
-               classes[i] = ATA_DEV_UNKNOWN;
-
-       rc = reset(ap, classes);
-       if (rc)
-               return rc;
-
-       /* If any class isn't ATA_DEV_UNKNOWN, consider classification
-        * is complete and convert all ATA_DEV_UNKNOWN to
-        * ATA_DEV_NONE.
-        */
-       for (i = 0; i < ATA_MAX_DEVICES; i++)
-               if (classes[i] != ATA_DEV_UNKNOWN)
-                       break;
-
-       if (i < ATA_MAX_DEVICES)
-               for (i = 0; i < ATA_MAX_DEVICES; i++)
-                       if (classes[i] == ATA_DEV_UNKNOWN)
-                               classes[i] = ATA_DEV_NONE;
-
-       return 0;
-}
-
-/**
- *     ata_drive_probe_reset - Perform probe reset with given methods
- *     @ap: port to reset
- *     @probeinit: probeinit method (can be NULL)
- *     @softreset: softreset method (can be NULL)
- *     @hardreset: hardreset method (can be NULL)
- *     @postreset: postreset method (can be NULL)
- *     @classes: resulting classes of attached devices
- *
- *     Reset the specified port and classify attached devices using
- *     given methods.  This function prefers softreset but tries all
- *     possible reset sequences to reset and classify devices.  This
- *     function is intended to be used for constructing ->probe_reset
- *     callback by low level drivers.
- *
- *     Reset methods should follow the following rules.
- *
- *     - Return 0 on sucess, -errno on failure.
- *     - If classification is supported, fill classes[] with
- *       recognized class codes.
- *     - If classification is not supported, leave classes[] alone.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep)
- *
- *     RETURNS:
- *     0 on success, -EINVAL if no reset method is avaliable, -ENODEV
- *     if classification fails, and any error code from reset
- *     methods.
- */
-int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit,
-                         ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
-                         ata_postreset_fn_t postreset, unsigned int *classes)
-{
-       int rc = -EINVAL;
-
-       ata_eh_freeze_port(ap);
-
-       if (probeinit)
-               probeinit(ap);
-
-       if (softreset && !sata_set_spd_needed(ap)) {
-               rc = ata_do_reset(ap, softreset, classes);
-               if (rc == 0 && classes[0] != ATA_DEV_UNKNOWN)
-                       goto done;
-               ata_port_printk(ap, KERN_INFO, "softreset failed, "
-                               "will try hardreset in 5 secs\n");
-               ssleep(5);
-       }
-
-       if (!hardreset)
-               goto done;
-
-       while (1) {
-               rc = ata_do_reset(ap, hardreset, classes);
-               if (rc == 0) {
-                       if (classes[0] != ATA_DEV_UNKNOWN)
-                               goto done;
-                       break;
-               }
-
-               if (sata_down_spd_limit(ap))
-                       goto done;
-
-               ata_port_printk(ap, KERN_INFO, "hardreset failed, "
-                               "will retry in 5 secs\n");
-               ssleep(5);
-       }
-
-       if (softreset) {
-               ata_port_printk(ap, KERN_INFO,
-                               "hardreset succeeded without classification, "
-                               "will retry softreset in 5 secs\n");
-               ssleep(5);
-
-               rc = ata_do_reset(ap, softreset, classes);
-       }
-
- done:
-       if (rc == 0) {
-               if (postreset)
-                       postreset(ap, classes);
-
-               ata_eh_thaw_port(ap);
-
-               if (classes[0] == ATA_DEV_UNKNOWN)
-                       rc = -ENODEV;
-       }
-       return rc;
-}
-
 /**
  *     ata_dev_same_device - Determine whether new ID matches configured device
  *     @dev: device to compare against
@@ -3473,6 +3289,7 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
        qc->n_elem = 1;
        qc->orig_n_elem = 1;
        qc->buf_virt = buf;
+       qc->nbytes = buflen;
 
        sg = qc->__sg;
        sg_init_one(sg, buf, buflen);
@@ -3679,7 +3496,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
 
 /**
  *     ata_mmio_data_xfer - Transfer data by MMIO
- *     @dev: device for this I/O
+ *     @adev: device for this I/O
  *     @buf: data buffer
  *     @buflen: buffer length
  *     @write_data: read/write
@@ -5173,6 +4990,7 @@ int ata_device_resume(struct ata_device *dev)
        if (ap->flags & ATA_FLAG_SUSPENDED) {
                struct ata_device *failed_dev;
 
+               ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
                ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 200000);
 
                ap->flags &= ~ATA_FLAG_SUSPENDED;
@@ -5367,10 +5185,19 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
        ap->hw_sata_spd_limit = UINT_MAX;
        ap->active_tag = ATA_TAG_POISON;
        ap->last_ctl = 0xFF;
-       ap->msg_enable = ATA_MSG_DRV;
+
+#if defined(ATA_VERBOSE_DEBUG)
+       /* turn on all debugging levels */
+       ap->msg_enable = 0x00FF;
+#elif defined(ATA_DEBUG)
+       ap->msg_enable = ATA_MSG_DRV | ATA_MSG_INFO | ATA_MSG_CTL | ATA_MSG_WARN | ATA_MSG_ERR;
+#else 
+       ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR;
+#endif
 
        INIT_WORK(&ap->port_task, NULL, NULL);
        INIT_WORK(&ap->hotplug_task, ata_scsi_hotplug, ap);
+       INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan, ap);
        INIT_LIST_HEAD(&ap->eh_done_q);
        init_waitqueue_head(&ap->eh_wait_q);
 
@@ -5419,7 +5246,7 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent,
 
        DPRINTK("ENTER\n");
 
-       if (!ent->port_ops->probe_reset && !ent->port_ops->error_handler &&
+       if (!ent->port_ops->error_handler &&
            !(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) {
                printk(KERN_ERR "ata%u: no reset mechanism available\n",
                       port_no);
@@ -5470,6 +5297,7 @@ int ata_device_add(const struct ata_probe_ent *ent)
        unsigned int count = 0, i;
        struct device *dev = ent->dev;
        struct ata_host_set *host_set;
+       int rc;
 
        DPRINTK("ENTER\n");
        /* alloc a container for our list of ATA ports (buses) */
@@ -5521,9 +5349,13 @@ int ata_device_add(const struct ata_probe_ent *ent)
                goto err_free_ret;
 
        /* obtain irq, that is shared between channels */
-       if (request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
-                       DRV_NAME, host_set))
+       rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
+                        DRV_NAME, host_set);
+       if (rc) {
+               dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
+                          ent->irq, rc);
                goto err_out;
+       }
 
        /* perform each probe synchronously */
        DPRINTK("probe begin\n");
@@ -5551,7 +5383,7 @@ int ata_device_add(const struct ata_probe_ent *ent)
                         */
                }
 
-               if (!ap->ops->probe_reset) {
+               if (ap->ops->error_handler) {
                        unsigned long flags;
 
                        ata_port_probe(ap);
@@ -5609,6 +5441,63 @@ err_free_ret:
        return 0;
 }
 
+/**
+ *     ata_port_detach - Detach ATA port in prepration of device removal
+ *     @ap: ATA port to be detached
+ *
+ *     Detach all ATA devices and the associated SCSI devices of @ap;
+ *     then, remove the associated SCSI host.  @ap is guaranteed to
+ *     be quiescent on return from this function.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep).
+ */
+void ata_port_detach(struct ata_port *ap)
+{
+       unsigned long flags;
+       int i;
+
+       if (!ap->ops->error_handler)
+               return;
+
+       /* tell EH we're leaving & flush EH */
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       ap->flags |= ATA_FLAG_UNLOADING;
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       ata_port_wait_eh(ap);
+
+       /* EH is now guaranteed to see UNLOADING, so no new device
+        * will be attached.  Disable all existing devices.
+        */
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               ata_dev_disable(&ap->device[i]);
+
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       /* Final freeze & EH.  All in-flight commands are aborted.  EH
+        * will be skipped and retrials will be terminated with bad
+        * target.
+        */
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       ata_port_freeze(ap);    /* won't be thawed */
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       ata_port_wait_eh(ap);
+
+       /* Flush hotplug task.  The sequence is similar to
+        * ata_port_flush_task().
+        */
+       flush_workqueue(ata_aux_wq);
+       cancel_delayed_work(&ap->hotplug_task);
+       flush_workqueue(ata_aux_wq);
+
+       /* remove the associated SCSI host */
+       scsi_remove_host(ap->host);
+}
+
 /**
  *     ata_host_set_remove - PCI layer callback for device removal
  *     @host_set: ATA host set that was removed
@@ -5622,18 +5511,15 @@ err_free_ret:
 
 void ata_host_set_remove(struct ata_host_set *host_set)
 {
-       struct ata_port *ap;
        unsigned int i;
 
-       for (i = 0; i < host_set->n_ports; i++) {
-               ap = host_set->ports[i];
-               scsi_remove_host(ap->host);
-       }
+       for (i = 0; i < host_set->n_ports; i++)
+               ata_port_detach(host_set->ports[i]);
 
        free_irq(host_set->irq, host_set);
 
        for (i = 0; i < host_set->n_ports; i++) {
-               ap = host_set->ports[i];
+               struct ata_port *ap = host_set->ports[i];
 
                ata_scsi_release(ap->host);
 
@@ -5736,8 +5622,12 @@ void ata_pci_remove_one (struct pci_dev *pdev)
 {
        struct device *dev = pci_dev_to_dev(pdev);
        struct ata_host_set *host_set = dev_get_drvdata(dev);
+       struct ata_host_set *host_set2 = host_set->next;
 
        ata_host_set_remove(host_set);
+       if (host_set2)
+               ata_host_set_remove(host_set2);
+
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        dev_set_drvdata(dev, NULL);
@@ -5901,6 +5791,7 @@ EXPORT_SYMBOL_GPL(sata_deb_timing_before_fsrst);
 EXPORT_SYMBOL_GPL(ata_std_bios_param);
 EXPORT_SYMBOL_GPL(ata_std_ports);
 EXPORT_SYMBOL_GPL(ata_device_add);
+EXPORT_SYMBOL_GPL(ata_port_detach);
 EXPORT_SYMBOL_GPL(ata_host_set_remove);
 EXPORT_SYMBOL_GPL(ata_sg_init);
 EXPORT_SYMBOL_GPL(ata_sg_init_one);
@@ -5943,13 +5834,10 @@ EXPORT_SYMBOL_GPL(sata_phy_resume);
 EXPORT_SYMBOL_GPL(sata_phy_reset);
 EXPORT_SYMBOL_GPL(__sata_phy_reset);
 EXPORT_SYMBOL_GPL(ata_bus_reset);
-EXPORT_SYMBOL_GPL(ata_std_probeinit);
 EXPORT_SYMBOL_GPL(ata_std_prereset);
 EXPORT_SYMBOL_GPL(ata_std_softreset);
 EXPORT_SYMBOL_GPL(sata_std_hardreset);
 EXPORT_SYMBOL_GPL(ata_std_postreset);
-EXPORT_SYMBOL_GPL(ata_std_probe_reset);
-EXPORT_SYMBOL_GPL(ata_drive_probe_reset);
 EXPORT_SYMBOL_GPL(ata_dev_revalidate);
 EXPORT_SYMBOL_GPL(ata_dev_classify);
 EXPORT_SYMBOL_GPL(ata_dev_pair);