.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,
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
* 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->sff_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);
}
/**
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;
/* 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;
return 0;
}
+/**
+ * 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...)
*/
int ata_sff_prereset(struct ata_link *link, unsigned long deadline)
{
- struct ata_port *ap = link->ap;
struct ata_eh_context *ehc = &link->eh_context;
int rc;
/* wait for !BSY if we don't know that no device is attached */
if (!ata_link_offline(link)) {
- rc = ata_sff_wait_ready(ap, deadline);
+ 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);
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.
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;
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->sff_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)
{
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->sff_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);
}
/**
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);
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;
}
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;
- }
-
- /* TODO: phy layer with polling, timeouts, etc. */
- if (ata_link_offline(link)) {
- *class = ATA_DEV_NONE;
- DPRINTK("EXIT, link offline\n");
- return 0;
- }
-
- /* wait a while before checking status */
- ata_sff_wait_after_reset(ap, deadline);
-
- /* 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;
- }
-
- 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;
- }
-
- ap->ops->sff_dev_select(ap, 0); /* probably unnecessary */
-
- *class = ata_sff_dev_classify(link->device, 1, NULL);
+ rc = sata_link_hardreset(link, timing, deadline, &online,
+ ata_sff_check_ready);
+ if (online)
+ *class = ata_sff_dev_classify(link->device, 1, NULL);
DPRINTK("EXIT, class=%u\n", *class);
- return 0;
+ return rc;
}
/**
/* 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,
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);