USB: add all configs to the "descriptors" attribute
[safe/jmp/linux-2.6] / drivers / ata / libata-sff.c
index 8544321..3c2d228 100644 (file)
@@ -44,20 +44,25 @@ const struct ata_port_operations ata_sff_port_ops = {
 
        .qc_prep                = ata_sff_qc_prep,
        .qc_issue               = ata_sff_qc_issue,
+       .qc_fill_rtf            = ata_sff_qc_fill_rtf,
 
        .freeze                 = ata_sff_freeze,
        .thaw                   = ata_sff_thaw,
+       .prereset               = ata_sff_prereset,
        .softreset              = ata_sff_softreset,
+       .hardreset              = sata_sff_hardreset,
+       .postreset              = ata_sff_postreset,
        .error_handler          = ata_sff_error_handler,
        .post_internal_cmd      = ata_sff_post_internal_cmd,
 
-       .dev_select             = ata_sff_dev_select,
-       .check_status           = ata_sff_check_status,
-       .tf_load                = ata_sff_tf_load,
-       .tf_read                = ata_sff_tf_read,
-       .exec_command           = ata_sff_exec_command,
-       .data_xfer              = ata_sff_data_xfer,
-       .irq_on                 = ata_sff_irq_on,
+       .sff_dev_select         = ata_sff_dev_select,
+       .sff_check_status       = ata_sff_check_status,
+       .sff_tf_load            = ata_sff_tf_load,
+       .sff_tf_read            = ata_sff_tf_read,
+       .sff_exec_command       = ata_sff_exec_command,
+       .sff_data_xfer          = ata_sff_data_xfer,
+       .sff_irq_on             = ata_sff_irq_on,
+       .sff_irq_clear          = ata_sff_irq_clear,
 
        .port_start             = ata_sff_port_start,
 };
@@ -71,7 +76,6 @@ const struct ata_port_operations ata_bmdma_port_ops = {
        .bmdma_start            = ata_bmdma_start,
        .bmdma_stop             = ata_bmdma_stop,
        .bmdma_status           = ata_bmdma_status,
-       .irq_clear              = ata_sff_irq_clear,
 };
 
 /**
@@ -245,8 +249,8 @@ u8 ata_sff_check_status(struct ata_port *ap)
  */
 u8 ata_sff_altstatus(struct ata_port *ap)
 {
-       if (ap->ops->check_altstatus)
-               return ap->ops->check_altstatus(ap);
+       if (ap->ops->sff_check_altstatus)
+               return ap->ops->sff_check_altstatus(ap);
 
        return ioread8(ap->ioaddr.altstatus_addr);
 }
@@ -290,7 +294,7 @@ int ata_sff_busy_sleep(struct ata_port *ap,
        while (status != 0xff && (status & ATA_BUSY) &&
               time_before(jiffies, timeout)) {
                msleep(50);
-               status = ap->ops->check_status(ap);
+               status = ap->ops->sff_check_status(ap);
        }
 
        if (status == 0xff)
@@ -306,9 +310,16 @@ int ata_sff_busy_sleep(struct ata_port *ap,
        return 0;
 }
 
+static int ata_sff_check_ready(struct ata_link *link)
+{
+       u8 status = link->ap->ops->sff_check_status(link->ap);
+
+       return ata_check_ready(status);
+}
+
 /**
  *     ata_sff_wait_ready - sleep until BSY clears, or timeout
- *     @ap: port containing status register to be polled
+ *     @link: SFF link to wait ready status for
  *     @deadline: deadline jiffies for the operation
  *
  *     Sleep until ATA Status register bit BSY clears, or timeout
@@ -320,32 +331,9 @@ int ata_sff_busy_sleep(struct ata_port *ap,
  *     RETURNS:
  *     0 on success, -errno otherwise.
  */
-int ata_sff_wait_ready(struct ata_port *ap, unsigned long deadline)
+int ata_sff_wait_ready(struct ata_link *link, unsigned long deadline)
 {
-       unsigned long start = jiffies;
-       int warned = 0;
-
-       while (1) {
-               u8 status = ap->ops->check_status(ap);
-               unsigned long now = jiffies;
-
-               if (!(status & ATA_BUSY))
-                       return 0;
-               if (!ata_link_online(&ap->link) && status == 0xff)
-                       return -ENODEV;
-               if (time_after(now, deadline))
-                       return -EBUSY;
-
-               if (!warned && time_after(now, start + 5 * HZ) &&
-                   (deadline - now > 3 * HZ)) {
-                       ata_port_printk(ap, KERN_WARNING,
-                               "port is slow to respond, please be patient "
-                               "(Status 0x%x)\n", status);
-                       warned = 1;
-               }
-
-               msleep(50);
-       }
+       return ata_wait_ready(link, deadline, ata_sff_check_ready);
 }
 
 /**
@@ -403,7 +391,7 @@ void ata_dev_select(struct ata_port *ap, unsigned int device,
        if (wait)
                ata_wait_idle(ap);
 
-       ap->ops->dev_select(ap, device);
+       ap->ops->sff_dev_select(ap, device);
 
        if (wait) {
                if (can_sleep && ap->link.device[device].class == ATA_DEV_ATAPI)
@@ -434,7 +422,7 @@ u8 ata_sff_irq_on(struct ata_port *ap)
                iowrite8(ap->ctl, ioaddr->ctl_addr);
        tmp = ata_wait_idle(ap);
 
-       ap->ops->irq_clear(ap);
+       ap->ops->sff_irq_clear(ap);
 
        return tmp;
 }
@@ -593,8 +581,8 @@ void ata_sff_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
 static inline void ata_tf_to_host(struct ata_port *ap,
                                  const struct ata_taskfile *tf)
 {
-       ap->ops->tf_load(ap, tf);
-       ap->ops->exec_command(ap, tf);
+       ap->ops->sff_tf_load(ap, tf);
+       ap->ops->sff_exec_command(ap, tf);
 }
 
 /**
@@ -709,13 +697,15 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
                buf = kmap_atomic(page, KM_IRQ0);
 
                /* do the actual data transfer */
-               ap->ops->data_xfer(qc->dev, buf + offset, qc->sect_size, do_write);
+               ap->ops->sff_data_xfer(qc->dev, buf + offset, qc->sect_size,
+                                      do_write);
 
                kunmap_atomic(buf, KM_IRQ0);
                local_irq_restore(flags);
        } else {
                buf = page_address(page);
-               ap->ops->data_xfer(qc->dev, buf + offset, qc->sect_size, do_write);
+               ap->ops->sff_data_xfer(qc->dev, buf + offset, qc->sect_size,
+                                      do_write);
        }
 
        qc->curbytes += qc->sect_size;
@@ -772,7 +762,7 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
        DPRINTK("send cdb\n");
        WARN_ON(qc->dev->cdb_len < 12);
 
-       ap->ops->data_xfer(qc->dev, qc->cdb, qc->dev->cdb_len, 1);
+       ap->ops->sff_data_xfer(qc->dev, qc->cdb, qc->dev->cdb_len, 1);
        ata_sff_altstatus(ap); /* flush */
 
        switch (qc->tf.protocol) {
@@ -844,13 +834,13 @@ next_sg:
                buf = kmap_atomic(page, KM_IRQ0);
 
                /* do the actual data transfer */
-               consumed = ap->ops->data_xfer(dev,  buf + offset, count, rw);
+               consumed = ap->ops->sff_data_xfer(dev,  buf + offset, count, rw);
 
                kunmap_atomic(buf, KM_IRQ0);
                local_irq_restore(flags);
        } else {
                buf = page_address(page);
-               consumed = ap->ops->data_xfer(dev,  buf + offset, count, rw);
+               consumed = ap->ops->sff_data_xfer(dev,  buf + offset, count, rw);
        }
 
        bytes -= min(bytes, consumed);
@@ -893,7 +883,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
         * error, qc->result_tf is later overwritten by ata_qc_complete().
         * So, the correctness of qc->result_tf is not affected.
         */
-       ap->ops->tf_read(ap, &qc->result_tf);
+       ap->ops->sff_tf_read(ap, &qc->result_tf);
        ireason = qc->result_tf.nsect;
        bc_lo = qc->result_tf.lbam;
        bc_hi = qc->result_tf.lbah;
@@ -979,7 +969,7 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
                        qc = ata_qc_from_tag(ap, qc->tag);
                        if (qc) {
                                if (likely(!(qc->err_mask & AC_ERR_HSM))) {
-                                       ap->ops->irq_on(ap);
+                                       ap->ops->sff_irq_on(ap);
                                        ata_qc_complete(qc);
                                } else
                                        ata_port_freeze(ap);
@@ -995,7 +985,7 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
        } else {
                if (in_wq) {
                        spin_lock_irqsave(ap->lock, flags);
-                       ap->ops->irq_on(ap);
+                       ap->ops->sff_irq_on(ap);
                        ata_qc_complete(qc);
                        spin_unlock_irqrestore(ap->lock, flags);
                } else
@@ -1214,7 +1204,7 @@ fsm_start:
                DPRINTK("ata%u: dev %u command complete, drv_stat 0x%x\n",
                        ap->print_id, qc->dev->devno, status);
 
-               WARN_ON(qc->err_mask);
+               WARN_ON(qc->err_mask & (AC_ERR_DEV | AC_ERR_HSM));
 
                ap->hsm_task_state = HSM_ST_IDLE;
 
@@ -1228,7 +1218,7 @@ fsm_start:
                /* make sure qc->err_mask is available to
                 * know what's wrong and recover
                 */
-               WARN_ON(qc->err_mask == 0);
+               WARN_ON(!(qc->err_mask & (AC_ERR_DEV | AC_ERR_HSM)));
 
                ap->hsm_task_state = HSM_ST_IDLE;
 
@@ -1345,7 +1335,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
        case ATA_PROT_DMA:
                WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
 
-               ap->ops->tf_load(ap, &qc->tf);   /* load tf registers */
+               ap->ops->sff_tf_load(ap, &qc->tf);  /* load tf registers */
                ap->ops->bmdma_setup(qc);           /* set up bmdma */
                ap->ops->bmdma_start(qc);           /* initiate bmdma */
                ap->hsm_task_state = HSM_ST_LAST;
@@ -1397,7 +1387,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
        case ATAPI_PROT_DMA:
                WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
 
-               ap->ops->tf_load(ap, &qc->tf);   /* load tf registers */
+               ap->ops->sff_tf_load(ap, &qc->tf);  /* load tf registers */
                ap->ops->bmdma_setup(qc);           /* set up bmdma */
                ap->hsm_task_state = HSM_ST_FIRST;
 
@@ -1415,6 +1405,25 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
 }
 
 /**
+ *     ata_sff_qc_fill_rtf - fill result TF using ->sff_tf_read
+ *     @qc: qc to fill result TF for
+ *
+ *     @qc is finished and result TF needs to be filled.  Fill it
+ *     using ->sff_tf_read.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host lock)
+ *
+ *     RETURNS:
+ *     true indicating that result TF is successfully filled.
+ */
+bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc)
+{
+       qc->ap->ops->sff_tf_read(qc->ap, &qc->result_tf);
+       return true;
+}
+
+/**
  *     ata_sff_host_intr - Handle host interrupt for given (port, task)
  *     @ap: Port on which interrupt arrived (possibly...)
  *     @qc: Taskfile currently active in engine
@@ -1486,12 +1495,12 @@ inline unsigned int ata_sff_host_intr(struct ata_port *ap,
                goto idle_irq;
 
        /* check main status, clearing INTRQ */
-       status = ap->ops->check_status(ap);
+       status = ap->ops->sff_check_status(ap);
        if (unlikely(status & ATA_BUSY))
                goto idle_irq;
 
        /* ack bmdma irq events */
-       ap->ops->irq_clear(ap);
+       ap->ops->sff_irq_clear(ap);
 
        ata_sff_hsm_move(ap, qc, status, 0);
 
@@ -1506,8 +1515,8 @@ idle_irq:
 
 #ifdef ATA_IRQ_TRAP
        if ((ap->stats.idle_irq % 1000) == 0) {
-               ap->ops->check_status(ap);
-               ap->ops->irq_clear(ap);
+               ap->ops->sff_check_status(ap);
+               ap->ops->sff_irq_clear(ap);
                ata_port_printk(ap, KERN_WARNING, "irq trap\n");
                return 1;
        }
@@ -1582,9 +1591,9 @@ void ata_sff_freeze(struct ata_port *ap)
         * ATA_NIEN manipulation.  Also, many controllers fail to mask
         * previously pending IRQ on ATA_NIEN assertion.  Clear it.
         */
-       ap->ops->check_status(ap);
+       ap->ops->sff_check_status(ap);
 
-       ap->ops->irq_clear(ap);
+       ap->ops->sff_irq_clear(ap);
 }
 
 /**
@@ -1599,9 +1608,50 @@ void ata_sff_freeze(struct ata_port *ap)
 void ata_sff_thaw(struct ata_port *ap)
 {
        /* clear & re-enable interrupts */
-       ap->ops->check_status(ap);
-       ap->ops->irq_clear(ap);
-       ap->ops->irq_on(ap);
+       ap->ops->sff_check_status(ap);
+       ap->ops->sff_irq_clear(ap);
+       ap->ops->sff_irq_on(ap);
+}
+
+/**
+ *     ata_sff_prereset - prepare SFF link for reset
+ *     @link: SFF link to be reset
+ *     @deadline: deadline jiffies for the operation
+ *
+ *     SFF link @link is about to be reset.  Initialize it.  It first
+ *     calls ata_std_prereset() and wait for !BSY if the port is
+ *     being softreset.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
+ */
+int ata_sff_prereset(struct ata_link *link, unsigned long deadline)
+{
+       struct ata_eh_context *ehc = &link->eh_context;
+       int rc;
+
+       rc = ata_std_prereset(link, deadline);
+       if (rc)
+               return rc;
+
+       /* if we're about to do hardreset, nothing more to do */
+       if (ehc->i.action & ATA_EH_HARDRESET)
+               return 0;
+
+       /* wait for !BSY if we don't know that no device is attached */
+       if (!ata_link_offline(link)) {
+               rc = ata_sff_wait_ready(link, deadline);
+               if (rc && rc != -ENODEV) {
+                       ata_link_printk(link, KERN_WARNING, "device not ready "
+                                       "(errno=%d), forcing hardreset\n", rc);
+                       ehc->i.action |= ATA_EH_HARDRESET;
+               }
+       }
+
+       return 0;
 }
 
 /**
@@ -1626,7 +1676,7 @@ static unsigned int ata_devchk(struct ata_port *ap, unsigned int device)
        struct ata_ioports *ioaddr = &ap->ioaddr;
        u8 nsect, lbal;
 
-       ap->ops->dev_select(ap, device);
+       ap->ops->sff_dev_select(ap, device);
 
        iowrite8(0x55, ioaddr->nsect_addr);
        iowrite8(0xaa, ioaddr->lbal_addr);
@@ -1675,11 +1725,11 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present,
        unsigned int class;
        u8 err;
 
-       ap->ops->dev_select(ap, dev->devno);
+       ap->ops->sff_dev_select(ap, dev->devno);
 
        memset(&tf, 0, sizeof(tf));
 
-       ap->ops->tf_read(ap, &tf);
+       ap->ops->sff_tf_read(ap, &tf);
        err = tf.feature;
        if (r_err)
                *r_err = err;
@@ -1709,31 +1759,48 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present,
                        class = ATA_DEV_ATA;
                else
                        class = ATA_DEV_NONE;
-       } else if ((class == ATA_DEV_ATA) && (ap->ops->check_status(ap) == 0))
+       } else if ((class == ATA_DEV_ATA) &&
+                  (ap->ops->sff_check_status(ap) == 0))
                class = ATA_DEV_NONE;
 
        return class;
 }
 
-static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
-                             unsigned long deadline)
+/**
+ *     ata_sff_wait_after_reset - wait for devices to become ready after reset
+ *     @link: SFF link which is just reset
+ *     @devmask: mask of present devices
+ *     @deadline: deadline jiffies for the operation
+ *
+ *     Wait devices attached to SFF @link to become ready after
+ *     reset.  It contains preceding 150ms wait to avoid accessing TF
+ *     status register too early.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep).
+ *
+ *     RETURNS:
+ *     0 on success, -ENODEV if some or all of devices in @devmask
+ *     don't seem to exist.  -errno on other errors.
+ */
+int ata_sff_wait_after_reset(struct ata_link *link, unsigned int devmask,
+                            unsigned long deadline)
 {
+       struct ata_port *ap = link->ap;
        struct ata_ioports *ioaddr = &ap->ioaddr;
        unsigned int dev0 = devmask & (1 << 0);
        unsigned int dev1 = devmask & (1 << 1);
        int rc, ret = 0;
 
-       /* if device 0 was found in ata_devchk, wait for its
-        * BSY bit to clear
+       msleep(ATA_WAIT_AFTER_RESET_MSECS);
+
+       /* always check readiness of the master device */
+       rc = ata_sff_wait_ready(link, deadline);
+       /* -ENODEV means the odd clown forgot the D7 pulldown resistor
+        * and TF status is 0xff, bail out on it too.
         */
-       if (dev0) {
-               rc = ata_sff_wait_ready(ap, deadline);
-               if (rc) {
-                       if (rc != -ENODEV)
-                               return rc;
-                       ret = rc;
-               }
-       }
+       if (rc)
+               return rc;
 
        /* if device 1 was found in ata_devchk, wait for register
         * access briefly, then wait for BSY to clear.
@@ -1741,7 +1808,7 @@ static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
        if (dev1) {
                int i;
 
-               ap->ops->dev_select(ap, 1);
+               ap->ops->sff_dev_select(ap, 1);
 
                /* Wait for register access.  Some ATAPI devices fail
                 * to set nsect/lbal after reset, so don't waste too
@@ -1757,7 +1824,7 @@ static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
                        msleep(50);     /* give drive a breather */
                }
 
-               rc = ata_sff_wait_ready(ap, deadline);
+               rc = ata_sff_wait_ready(link, deadline);
                if (rc) {
                        if (rc != -ENODEV)
                                return rc;
@@ -1766,70 +1833,15 @@ static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
        }
 
        /* is all this really necessary? */
-       ap->ops->dev_select(ap, 0);
+       ap->ops->sff_dev_select(ap, 0);
        if (dev1)
-               ap->ops->dev_select(ap, 1);
+               ap->ops->sff_dev_select(ap, 1);
        if (dev0)
-               ap->ops->dev_select(ap, 0);
+               ap->ops->sff_dev_select(ap, 0);
 
        return ret;
 }
 
-/**
- *     ata_sff_wait_after_reset - wait before checking status after reset
- *     @ap: port containing status register to be polled
- *     @deadline: deadline jiffies for the operation
- *
- *     After reset, we need to pause a while before reading status.
- *     Also, certain combination of controller and device report 0xff
- *     for some duration (e.g. until SATA PHY is up and running)
- *     which is interpreted as empty port in ATA world.  This
- *     function also waits for such devices to get out of 0xff
- *     status.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep).
- */
-void ata_sff_wait_after_reset(struct ata_port *ap, unsigned long deadline)
-{
-       unsigned long until = jiffies + ATA_TMOUT_FF_WAIT;
-
-       if (time_before(until, deadline))
-               deadline = until;
-
-       /* Spec mandates ">= 2ms" before checking status.  We wait
-        * 150ms, because that was the magic delay used for ATAPI
-        * devices in Hale Landis's ATADRVR, for the period of time
-        * between when the ATA command register is written, and then
-        * status is checked.  Because waiting for "a while" before
-        * checking status is fine, post SRST, we perform this magic
-        * delay here as well.
-        *
-        * Old drivers/ide uses the 2mS rule and then waits for ready.
-        */
-       msleep(150);
-
-       /* Wait for 0xff to clear.  Some SATA devices take a long time
-        * to clear 0xff after reset.  For example, HHD424020F7SV00
-        * iVDR needs >= 800ms while.  Quantum GoVault needs even more
-        * than that.
-        *
-        * Note that some PATA controllers (pata_ali) explode if
-        * status register is read more than once when there's no
-        * device attached.
-        */
-       if (ap->flags & ATA_FLAG_SATA) {
-               while (1) {
-                       u8 status = ap->ops->check_status(ap);
-
-                       if (status != 0xff || time_after(jiffies, deadline))
-                               return;
-
-                       msleep(50);
-               }
-       }
-}
-
 static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
                             unsigned long deadline)
 {
@@ -1844,17 +1856,8 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
        udelay(20);     /* FIXME: flush */
        iowrite8(ap->ctl, ioaddr->ctl_addr);
 
-       /* wait a while before checking status */
-       ata_sff_wait_after_reset(ap, deadline);
-
-       /* Before we perform post reset processing we want to see if
-        * the bus shows 0xFF because the odd clown forgets the D7
-        * pulldown resistor.
-        */
-       if (ap->ops->check_status(ap) == 0xFF)
-               return -ENODEV;
-
-       return ata_bus_post_reset(ap, devmask, deadline);
+       /* wait the port to become ready */
+       return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
 }
 
 /**
@@ -1882,11 +1885,6 @@ int ata_sff_softreset(struct ata_link *link, unsigned int *classes,
 
        DPRINTK("ENTER\n");
 
-       if (ata_link_offline(link)) {
-               classes[0] = ATA_DEV_NONE;
-               goto out;
-       }
-
        /* determine if device 0/1 are present */
        if (ata_devchk(ap, 0))
                devmask |= (1 << 0);
@@ -1894,7 +1892,7 @@ int ata_sff_softreset(struct ata_link *link, unsigned int *classes,
                devmask |= (1 << 1);
 
        /* select device 0 again */
-       ap->ops->dev_select(ap, 0);
+       ap->ops->sff_dev_select(ap, 0);
 
        /* issue bus reset */
        DPRINTK("about to softreset, devmask=%x\n", devmask);
@@ -1912,7 +1910,6 @@ int ata_sff_softreset(struct ata_link *link, unsigned int *classes,
                classes[1] = ata_sff_dev_classify(&link->device[1],
                                                  devmask & (1 << 1), &err);
 
- out:
        DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
        return 0;
 }
@@ -1935,54 +1932,53 @@ int ata_sff_softreset(struct ata_link *link, unsigned int *classes,
 int sata_sff_hardreset(struct ata_link *link, unsigned int *class,
                       unsigned long deadline)
 {
-       struct ata_port *ap = link->ap;
-       const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
+       struct ata_eh_context *ehc = &link->eh_context;
+       const unsigned long *timing = sata_ehc_deb_timing(ehc);
+       bool online;
        int rc;
 
-       DPRINTK("ENTER\n");
-
-       /* do hardreset */
-       rc = sata_link_hardreset(link, timing, deadline);
-       if (rc) {
-               ata_link_printk(link, KERN_ERR,
-                               "COMRESET failed (errno=%d)\n", rc);
-               return rc;
-       }
+       rc = sata_link_hardreset(link, timing, deadline, &online,
+                                ata_sff_check_ready);
+       if (online)
+               *class = ata_sff_dev_classify(link->device, 1, NULL);
 
-       /* TODO: phy layer with polling, timeouts, etc. */
-       if (ata_link_offline(link)) {
-               *class = ATA_DEV_NONE;
-               DPRINTK("EXIT, link offline\n");
-               return 0;
-       }
+       DPRINTK("EXIT, class=%u\n", *class);
+       return rc;
+}
 
-       /* wait a while before checking status */
-       ata_sff_wait_after_reset(ap, deadline);
+/**
+ *     ata_sff_postreset - SFF postreset callback
+ *     @link: the target SFF ata_link
+ *     @classes: classes of attached devices
+ *
+ *     This function is invoked after a successful reset.  It first
+ *     calls ata_std_postreset() and performs SFF specific postreset
+ *     processing.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ */
+void ata_sff_postreset(struct ata_link *link, unsigned int *classes)
+{
+       struct ata_port *ap = link->ap;
 
-       /* If PMP is supported, we have to do follow-up SRST.  Note
-        * that some PMPs don't send D2H Reg FIS after hardreset at
-        * all if the first port is empty.  Wait for it just for a
-        * second and request follow-up SRST.
-        */
-       if (ap->flags & ATA_FLAG_PMP) {
-               ata_sff_wait_ready(ap, jiffies + HZ);
-               return -EAGAIN;
-       }
+       ata_std_postreset(link, classes);
 
-       rc = ata_sff_wait_ready(ap, deadline);
-       /* link occupied, -ENODEV too is an error */
-       if (rc) {
-               ata_link_printk(link, KERN_ERR,
-                               "COMRESET failed (errno=%d)\n", rc);
-               return rc;
+       /* is double-select really necessary? */
+       if (classes[0] != ATA_DEV_NONE)
+               ap->ops->sff_dev_select(ap, 1);
+       if (classes[1] != ATA_DEV_NONE)
+               ap->ops->sff_dev_select(ap, 0);
+
+       /* bail out if no device is present */
+       if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
+               DPRINTK("EXIT, no device\n");
+               return;
        }
 
-       ap->ops->dev_select(ap, 0);     /* probably unnecessary */
-
-       *class = ata_sff_dev_classify(link->device, 1, NULL);
-
-       DPRINTK("EXIT, class=%u\n", *class);
-       return 0;
+       /* set up device control */
+       if (ap->ioaddr.ctl_addr)
+               iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
 }
 
 /**
@@ -2035,8 +2031,8 @@ void ata_sff_error_handler(struct ata_port *ap)
        }
 
        ata_sff_altstatus(ap);
-       ap->ops->check_status(ap);
-       ap->ops->irq_clear(ap);
+       ap->ops->sff_check_status(ap);
+       ap->ops->sff_irq_clear(ap);
 
        spin_unlock_irqrestore(ap->lock, flags);
 
@@ -2045,14 +2041,12 @@ void ata_sff_error_handler(struct ata_port *ap)
 
        /* PIO and DMA engines have been stopped, perform recovery */
 
-       /* ata_sff_softreset and sata_sff_hardreset are inherited to
-        * all SFF drivers from ata_sff_port_ops.  Ignore softreset if
-        * ctl isn't accessible.  Ignore hardreset if SCR access isn't
-        * available.
+       /* Ignore ata_sff_softreset if ctl isn't accessible and
+        * built-in hardresets if SCR access isn't available.
         */
        if (softreset == ata_sff_softreset && !ap->ioaddr.ctl_addr)
                softreset = NULL;
-       if (hardreset == sata_sff_hardreset && !sata_scr_valid(&ap->link))
+       if (ata_is_builtin_hardreset(hardreset) && !sata_scr_valid(&ap->link))
                hardreset = NULL;
 
        ata_do_eh(ap, ap->ops->prereset, softreset, hardreset,
@@ -2153,7 +2147,7 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc)
        iowrite8(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
 
        /* issue r/w command */
-       ap->ops->exec_command(ap, &qc->tf);
+       ap->ops->sff_exec_command(ap, &qc->tf);
 }
 
 /**
@@ -2277,7 +2271,7 @@ void ata_bus_reset(struct ata_port *ap)
                devmask |= (1 << 1);
 
        /* select device 0 again */
-       ap->ops->dev_select(ap, 0);
+       ap->ops->sff_dev_select(ap, 0);
 
        /* issue bus reset */
        if (ap->flags & ATA_FLAG_SRST) {
@@ -2295,9 +2289,9 @@ void ata_bus_reset(struct ata_port *ap)
 
        /* is double-select really necessary? */
        if (device[1].class != ATA_DEV_NONE)
-               ap->ops->dev_select(ap, 1);
+               ap->ops->sff_dev_select(ap, 1);
        if (device[0].class != ATA_DEV_NONE)
-               ap->ops->dev_select(ap, 0);
+               ap->ops->sff_dev_select(ap, 0);
 
        /* if no devices were detected, disable this port */
        if ((device[0].class == ATA_DEV_NONE) &&
@@ -2740,6 +2734,7 @@ EXPORT_SYMBOL_GPL(ata_sff_irq_on);
 EXPORT_SYMBOL_GPL(ata_sff_irq_clear);
 EXPORT_SYMBOL_GPL(ata_sff_hsm_move);
 EXPORT_SYMBOL_GPL(ata_sff_qc_issue);
+EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf);
 EXPORT_SYMBOL_GPL(ata_sff_host_intr);
 EXPORT_SYMBOL_GPL(ata_sff_interrupt);
 EXPORT_SYMBOL_GPL(ata_sff_freeze);