sata_mv fix SOC flags, enable NCQ on SOC
[safe/jmp/linux-2.6] / drivers / ata / libata-pmp.c
index 7f1a87f..ff1822a 100644 (file)
 #include <linux/libata.h>
 #include "libata.h"
 
+const struct ata_port_operations sata_pmp_port_ops = {
+       .inherits               = &sata_port_ops,
+       .pmp_prereset           = ata_std_prereset,
+       .pmp_hardreset          = sata_std_hardreset,
+       .pmp_postreset          = ata_std_postreset,
+       .error_handler          = sata_pmp_error_handler,
+};
+
 /**
  *     sata_pmp_read - read PMP register
  *     @link: link to read PMP register for
@@ -176,132 +184,6 @@ int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val)
 }
 
 /**
- *     sata_pmp_std_prereset - prepare PMP link for reset
- *     @link: link to be reset
- *     @deadline: deadline jiffies for the operation
- *
- *     @link is about to be reset.  Initialize it.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep)
- *
- *     RETURNS:
- *     0 on success, -errno otherwise.
- */
-int sata_pmp_std_prereset(struct ata_link *link, unsigned long deadline)
-{
-       struct ata_eh_context *ehc = &link->eh_context;
-       const unsigned long *timing = sata_ehc_deb_timing(ehc);
-       int rc;
-
-       /* if we're about to do hardreset, nothing more to do */
-       if (ehc->i.action & ATA_EH_HARDRESET)
-               return 0;
-
-       /* resume link */
-       rc = sata_link_resume(link, timing, deadline);
-       if (rc) {
-               /* phy resume failed */
-               ata_link_printk(link, KERN_WARNING, "failed to resume link "
-                               "for reset (errno=%d)\n", rc);
-               return rc;
-       }
-
-       /* clear SError bits including .X which blocks the port when set */
-       rc = sata_scr_write(link, SCR_ERROR, 0xffffffff);
-       if (rc) {
-               ata_link_printk(link, KERN_ERR,
-                               "failed to clear SError (errno=%d)\n", rc);
-               return rc;
-       }
-
-       return 0;
-}
-
-/**
- *     sata_pmp_std_hardreset - standard hardreset method for PMP link
- *     @link: link to be reset
- *     @class: resulting class of attached device
- *     @deadline: deadline jiffies for the operation
- *
- *     Hardreset PMP port @link.  Note that this function doesn't
- *     wait for BSY clearance.  There simply isn't a generic way to
- *     wait the event.  Instead, this function return -EAGAIN thus
- *     telling libata-EH to followup with softreset.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep)
- *
- *     RETURNS:
- *     0 on success, -errno otherwise.
- */
-int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class,
-                          unsigned long deadline)
-{
-       const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
-       bool online;
-       u32 tmp;
-       int rc;
-
-       DPRINTK("ENTER\n");
-
-       /* do hardreset */
-       rc = sata_link_hardreset(link, timing, deadline, &online, NULL);
-       if (rc) {
-               ata_link_printk(link, KERN_ERR,
-                               "COMRESET failed (errno=%d)\n", rc);
-               goto out;
-       }
-
-       /* clear SError bits including .X which blocks the port when set */
-       rc = sata_scr_write(link, SCR_ERROR, 0xffffffff);
-       if (rc) {
-               ata_link_printk(link, KERN_ERR, "failed to clear SError "
-                               "during hardreset (errno=%d)\n", rc);
-               goto out;
-       }
-
-       /* if device is present, follow up with srst to wait for !BSY */
-       if (online)
-               rc = -EAGAIN;
- out:
-       /* if SCR isn't accessible, we need to reset the PMP */
-       if (rc && rc != -EAGAIN && sata_scr_read(link, SCR_STATUS, &tmp))
-               rc = -ERESTART;
-
-       DPRINTK("EXIT, rc=%d\n", rc);
-       return rc;
-}
-
-/**
- *     ata_std_postreset - standard postreset method for PMP link
- *     @link: the target ata_link
- *     @classes: classes of attached devices
- *
- *     This function is invoked after a successful reset.  Note that
- *     the device might have been reset more than once using
- *     different reset methods before postreset is invoked.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep)
- */
-void sata_pmp_std_postreset(struct ata_link *link, unsigned int *class)
-{
-       u32 serror;
-
-       DPRINTK("ENTER\n");
-
-       /* clear SError */
-       if (sata_scr_read(link, SCR_ERROR, &serror) == 0)
-               sata_scr_write(link, SCR_ERROR, serror);
-
-       /* print link status */
-       sata_print_link_status(link);
-
-       DPRINTK("EXIT\n");
-}
-
-/**
  *     sata_pmp_read_gscr - read GSCR block of SATA PMP
  *     @dev: PMP device
  *     @gscr: buffer to read GSCR block into
@@ -529,7 +411,7 @@ int sata_pmp_attach(struct ata_device *dev)
        int rc;
 
        /* is it hanging off the right place? */
-       if (!(ap->flags & ATA_FLAG_PMP)) {
+       if (!sata_pmp_supported(ap)) {
                ata_dev_printk(dev, KERN_ERR,
                               "host does not support Port Multiplier\n");
                return -EINVAL;
@@ -994,7 +876,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
 
  retry:
        /* PMP attached? */
-       if (!ap->nr_pmp_links) {
+       if (!sata_pmp_attached(ap)) {
                rc = ata_eh_recover(ap, ops->prereset, ops->softreset,
                                    ops->hardreset, ops->postreset, NULL);
                if (rc) {
@@ -1101,7 +983,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
        if (ap->pflags & ATA_PFLAG_UNLOADING)
                return rc;
 
-       if (!ap->nr_pmp_links)
+       if (!sata_pmp_attached(ap))
                goto retry;
 
        if (--pmp_tries) {
@@ -1138,3 +1020,7 @@ void sata_pmp_error_handler(struct ata_port *ap)
        sata_pmp_eh_recover(ap);
        ata_eh_finish(ap);
 }
+
+EXPORT_SYMBOL_GPL(sata_pmp_port_ops);
+EXPORT_SYMBOL_GPL(sata_pmp_qc_defer_cmd_switch);
+EXPORT_SYMBOL_GPL(sata_pmp_error_handler);