dev->cylinders, dev->heads, dev->sectors);
}
+ if (dev->id[59] & 0x100) {
+ dev->multi_count = dev->id[59] & 0xff;
+ DPRINTK("ata%u: dev %u multi count %u\n",
+ ap->id, dev->devno, dev->multi_count);
+ }
+
dev->cdb_len = 16;
}
/* ATAPI-specific feature tests */
else if (dev->class == ATA_DEV_ATAPI) {
+ char *cdb_intr_string = "";
+
rc = atapi_cdb_len(id);
if ((rc < 12) || (rc > ATAPI_CDB_LEN)) {
printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id);
}
dev->cdb_len = (unsigned int) rc;
+ if (ata_id_cdb_intr(dev->id)) {
+ dev->flags |= ATA_DFLAG_CDB_INTR;
+ cdb_intr_string = ", CDB intr";
+ }
+
/* print device info to dmesg */
if (print_info)
- printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n",
- ap->id, dev->devno, ata_mode_string(xfer_mask));
+ printk(KERN_INFO "ata%u: dev %u ATAPI, max %s%s\n",
+ ap->id, dev->devno, ata_mode_string(xfer_mask),
+ cdb_intr_string);
}
ap->host->max_cmd_len = 0;
/* read IDENTIFY page and configure devices */
for (i = 0; i < ATA_MAX_DEVICES; i++) {
dev = &ap->device[i];
- dev->class = classes[i];
- if (!tries[i]) {
- ata_down_xfermask_limit(ap, dev, 1);
- ata_dev_disable(ap, dev);
- }
+ if (tries[i])
+ dev->class = classes[i];
if (!ata_dev_enabled(dev))
continue;
break;
}
rc = 0;
- } else {
+ } else
rc = ata_set_mode(ap, &dev);
- if (rc) {
- down_xfermask = 1;
- goto fail;
- }
+
+ if (rc) {
+ down_xfermask = 1;
+ goto fail;
}
for (i = 0; i < ATA_MAX_DEVICES; i++)
tries[dev->devno] = 0;
}
+ if (!tries[dev->devno]) {
+ ata_down_xfermask_limit(ap, dev, 1);
+ ata_dev_disable(ap, dev);
+ }
+
goto retry;
}
* 0 if spd doesn't need to be changed, 1 if spd has been
* changed. -EOPNOTSUPP if SCR registers are inaccessible.
*/
- static int ata_set_sata_spd(struct ata_port *ap)
+ int ata_set_sata_spd(struct ata_port *ap)
{
u32 scontrol;
* the bus shows 0xFF because the odd clown forgets the D7
* pulldown resistor.
*/
- if (ata_check_status(ap) == 0xFF)
+ if (ata_check_status(ap) == 0xFF) {
+ printk(KERN_ERR "ata%u: SRST failed (status 0xFF)\n", ap->id);
return AC_ERR_OTHER;
+ }
ata_bus_post_reset(ap, devmask);
if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) {
u32 spd;
+ /* set cable type and resume link */
+ ap->cbl = ATA_CBL_SATA;
sata_phy_resume(ap);
+ /* init sata_spd_limit to the current value */
spd = (scr_read(ap, SCR_CONTROL) & 0xf0) >> 4;
if (spd)
ap->sata_spd_limit &= (1 << spd) - 1;
+ /* wait for device */
if (sata_dev_present(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
- * @verbose: fail verbosely
* @classes: resulting classes of attached devices
*
* Reset host port using ATA SRST. This function is to be used
* RETURNS:
* 0 on success, -errno otherwise.
*/
- int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes)
+ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
{
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
unsigned int devmask = 0, err_mask;
DPRINTK("about to softreset, devmask=%x\n", devmask);
err_mask = ata_bus_softreset(ap, devmask);
if (err_mask) {
- if (verbose)
- printk(KERN_ERR "ata%u: SRST failed (err_mask=0x%x)\n",
- ap->id, err_mask);
- else
- DPRINTK("EXIT, softreset failed (err_mask=0x%x)\n",
- err_mask);
+ printk(KERN_ERR "ata%u: SRST failed (err_mask=0x%x)\n",
+ ap->id, err_mask);
return -EIO;
}
/**
* sata_std_hardreset - reset host port via SATA phy reset
* @ap: port to reset
- * @verbose: fail verbosely
* @class: resulting class of attached device
*
* SATA phy-reset host port using DET bits of SControl register.
* RETURNS:
* 0 on success, -errno otherwise.
*/
- int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
+ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
{
u32 scontrol;
}
if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
- if (verbose)
- printk(KERN_ERR "ata%u: COMRESET failed "
- "(device not ready)\n", ap->id);
- else
- DPRINTK("EXIT, device not ready\n");
+ printk(KERN_ERR
+ "ata%u: COMRESET failed (device not ready)\n", ap->id);
return -EIO;
}
{
DPRINTK("ENTER\n");
- /* set cable type if it isn't already set */
- if (ap->cbl == ATA_CBL_NONE && ap->flags & ATA_FLAG_SATA)
- ap->cbl = ATA_CBL_SATA;
-
/* print link status */
if (ap->cbl == ATA_CBL_SATA)
sata_print_link_status(ap);
ata_reset_fn_t hardreset;
hardreset = NULL;
- if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read)
+ if (ap->cbl == ATA_CBL_SATA && ap->ops->scr_read)
hardreset = sata_std_hardreset;
return ata_drive_probe_reset(ap, ata_std_probeinit,
ata_std_postreset, classes);
}
- int ata_do_reset(struct ata_port *ap,
- ata_reset_fn_t reset, ata_postreset_fn_t postreset,
- int verbose, unsigned int *classes)
+ int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
+ ata_postreset_fn_t postreset, unsigned int *classes)
{
int i, rc;
for (i = 0; i < ATA_MAX_DEVICES; i++)
classes[i] = ATA_DEV_UNKNOWN;
- rc = reset(ap, verbose, classes);
+ rc = reset(ap, classes);
if (rc)
return rc;
* - If classification is supported, fill classes[] with
* recognized class codes.
* - If classification is not supported, leave classes[] alone.
- * - If verbose is non-zero, print error message on failure;
- * otherwise, shut up.
*
* LOCKING:
* Kernel thread context (may sleep)
probeinit(ap);
if (softreset && !ata_set_sata_spd_needed(ap)) {
- rc = ata_do_reset(ap, softreset, postreset, 0, classes);
+ rc = ata_do_reset(ap, softreset, postreset, classes);
if (rc == 0 && classes[0] != ATA_DEV_UNKNOWN)
goto done;
printk(KERN_INFO "ata%u: softreset failed, will try "
goto done;
while (1) {
- rc = ata_do_reset(ap, hardreset, postreset, 0, classes);
+ rc = ata_do_reset(ap, hardreset, postreset, classes);
if (rc == 0) {
if (classes[0] != ATA_DEV_UNKNOWN)
goto done;
ap->id);
ssleep(5);
- rc = ata_do_reset(ap, softreset, postreset, 0, classes);
+ rc = ata_do_reset(ap, softreset, postreset, classes);
}
done:
if (ap->ops->check_atapi_dma)
rc = ap->ops->check_atapi_dma(qc);
+ /* We don't support polling DMA.
+ * Use PIO if the LLDD handles only interrupts in
+ * the HSM_ST_LAST state and the ATAPI device
+ * generates CDB interrupts.
+ */
+ if ((ap->flags & ATA_FLAG_PIO_POLLING) &&
+ (qc->dev->flags & ATA_DFLAG_CDB_INTR))
+ rc = 1;
+
return rc;
}
/**
unsigned long flags;
spin_lock_irqsave(&ap->host_set->lock, flags);
- ap->flags &= ~ATA_FLAG_NOINTR;
ata_irq_on(ap);
ata_qc_complete(qc);
spin_unlock_irqrestore(&ap->host_set->lock, flags);
}
-/**
- * ata_pio_poll - poll using PIO, depending on current state
- * @qc: qc in progress
- *
- * LOCKING:
- * None. (executing in kernel thread context)
- *
- * RETURNS:
- * timeout value to use
- */
-static unsigned long ata_pio_poll(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- u8 status;
- unsigned int poll_state = HSM_ST_UNKNOWN;
- unsigned int reg_state = HSM_ST_UNKNOWN;
-
- switch (ap->hsm_task_state) {
- case HSM_ST:
- case HSM_ST_POLL:
- poll_state = HSM_ST_POLL;
- reg_state = HSM_ST;
- break;
- case HSM_ST_LAST:
- case HSM_ST_LAST_POLL:
- poll_state = HSM_ST_LAST_POLL;
- reg_state = HSM_ST_LAST;
- break;
- default:
- BUG();
- break;
- }
-
- status = ata_chk_status(ap);
- if (status & ATA_BUSY) {
- if (time_after(jiffies, ap->pio_task_timeout)) {
- qc->err_mask |= AC_ERR_TIMEOUT;
- ap->hsm_task_state = HSM_ST_TMOUT;
- return 0;
- }
- ap->hsm_task_state = poll_state;
- return ATA_SHORT_PAUSE;
- }
-
- ap->hsm_task_state = reg_state;
- return 0;
-}
-
-/**
- * ata_pio_complete - check if drive is busy or idle
- * @qc: qc to complete
- *
- * LOCKING:
- * None. (executing in kernel thread context)
- *
- * RETURNS:
- * Non-zero if qc completed, zero otherwise.
- */
-static int ata_pio_complete(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- u8 drv_stat;
-
- /*
- * This is purely heuristic. This is a fast path. Sometimes when
- * we enter, BSY will be cleared in a chk-status or two. If not,
- * the drive is probably seeking or something. Snooze for a couple
- * msecs, then chk-status again. If still busy, fall back to
- * HSM_ST_POLL state.
- */
- drv_stat = ata_busy_wait(ap, ATA_BUSY, 10);
- if (drv_stat & ATA_BUSY) {
- msleep(2);
- drv_stat = ata_busy_wait(ap, ATA_BUSY, 10);
- if (drv_stat & ATA_BUSY) {
- ap->hsm_task_state = HSM_ST_LAST_POLL;
- ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
- return 0;
- }
- }
-
- drv_stat = ata_wait_idle(ap);
- if (!ata_ok(drv_stat)) {
- qc->err_mask |= __ac_err_mask(drv_stat);
- ap->hsm_task_state = HSM_ST_ERR;
- return 0;
- }
-
- ap->hsm_task_state = HSM_ST_IDLE;
-
- WARN_ON(qc->err_mask);
- ata_poll_qc_complete(qc);
-
- /* another command may start at this point */
-
- return 1;
-}
-
-
/**
* swap_buf_le16 - swap halves of 16-bit words in place
* @buf: Buffer to swap
page = nth_page(page, (offset >> PAGE_SHIFT));
offset %= PAGE_SIZE;
- buf = kmap(page) + offset;
+ DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
+
+ if (PageHighMem(page)) {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ buf = kmap_atomic(page, KM_IRQ0);
+
+ /* do the actual data transfer */
+ ata_data_xfer(ap, buf + offset, ATA_SECT_SIZE, do_write);
+
+ kunmap_atomic(buf, KM_IRQ0);
+ local_irq_restore(flags);
+ } else {
+ buf = page_address(page);
+ ata_data_xfer(ap, buf + offset, ATA_SECT_SIZE, do_write);
+ }
qc->cursect++;
qc->cursg_ofs++;
qc->cursg++;
qc->cursg_ofs = 0;
}
+}
- DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
+/**
+ * ata_pio_sectors - Transfer one or many 512-byte sectors.
+ * @qc: Command on going
+ *
+ * Transfer one or many ATA_SECT_SIZE of data from/to the
+ * ATA device for the DRQ request.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+
+static void ata_pio_sectors(struct ata_queued_cmd *qc)
+{
+ if (is_multi_taskfile(&qc->tf)) {
+ /* READ/WRITE MULTIPLE */
+ unsigned int nsect;
+
+ WARN_ON(qc->dev->multi_count == 0);
+
+ nsect = min(qc->nsect - qc->cursect, qc->dev->multi_count);
+ while (nsect--)
+ ata_pio_sector(qc);
+ } else
+ ata_pio_sector(qc);
+}
+
+/**
+ * atapi_send_cdb - Write CDB bytes to hardware
+ * @ap: Port to which ATAPI device is attached.
+ * @qc: Taskfile currently active
+ *
+ * When device has indicated its readiness to accept
+ * a CDB, this function is called. Send the CDB.
+ *
+ * LOCKING:
+ * caller.
+ */
+
+static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
+{
+ /* send SCSI cdb */
+ DPRINTK("send cdb\n");
+ WARN_ON(qc->dev->cdb_len < 12);
- /* do the actual data transfer */
- do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
- ata_data_xfer(ap, buf, ATA_SECT_SIZE, do_write);
+ ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
+ ata_altstatus(ap); /* flush */
- kunmap(page);
+ switch (qc->tf.protocol) {
+ case ATA_PROT_ATAPI:
+ ap->hsm_task_state = HSM_ST;
+ break;
+ case ATA_PROT_ATAPI_NODATA:
+ ap->hsm_task_state = HSM_ST_LAST;
+ break;
+ case ATA_PROT_ATAPI_DMA:
+ ap->hsm_task_state = HSM_ST_LAST;
+ /* initiate bmdma */
+ ap->ops->bmdma_start(qc);
+ break;
+ }
}
/**
/* don't cross page boundaries */
count = min(count, (unsigned int)PAGE_SIZE - offset);
- buf = kmap(page) + offset;
+ DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
+
+ if (PageHighMem(page)) {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ buf = kmap_atomic(page, KM_IRQ0);
+
+ /* do the actual data transfer */
+ ata_data_xfer(ap, buf + offset, count, do_write);
+
+ kunmap_atomic(buf, KM_IRQ0);
+ local_irq_restore(flags);
+ } else {
+ buf = page_address(page);
+ ata_data_xfer(ap, buf + offset, count, do_write);
+ }
bytes -= count;
qc->curbytes += count;
qc->cursg_ofs = 0;
}
- DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
-
- /* do the actual data transfer */
- ata_data_xfer(ap, buf, count, do_write);
-
- kunmap(page);
-
if (bytes)
goto next_sg;
}
if (do_write != i_write)
goto err_out;
+ VPRINTK("ata%u: xfering %d bytes\n", ap->id, bytes);
+
__atapi_pio_bytes(qc, bytes);
return;
}
/**
- * ata_pio_block - start PIO on a block
- * @qc: qc to transfer block for
+ * ata_hsm_ok_in_wq - Check if the qc can be handled in the workqueue.
+ * @ap: the target ata_port
+ * @qc: qc on going
*
- * LOCKING:
- * None. (executing in kernel thread context)
+ * RETURNS:
+ * 1 if ok in workqueue, 0 otherwise.
*/
-static void ata_pio_block(struct ata_queued_cmd *qc)
+
+static inline int ata_hsm_ok_in_wq(struct ata_port *ap, struct ata_queued_cmd *qc)
{
- struct ata_port *ap = qc->ap;
- u8 status;
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ return 1;
- /*
- * This is purely heuristic. This is a fast path.
- * Sometimes when we enter, BSY will be cleared in
- * a chk-status or two. If not, the drive is probably seeking
- * or something. Snooze for a couple msecs, then
- * chk-status again. If still busy, fall back to
- * HSM_ST_POLL state.
- */
- status = ata_busy_wait(ap, ATA_BUSY, 5);
- if (status & ATA_BUSY) {
- msleep(2);
- status = ata_busy_wait(ap, ATA_BUSY, 10);
- if (status & ATA_BUSY) {
- ap->hsm_task_state = HSM_ST_POLL;
- ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
- return;
- }
- }
+ if (ap->hsm_task_state == HSM_ST_FIRST) {
+ if (qc->tf.protocol == ATA_PROT_PIO &&
+ (qc->tf.flags & ATA_TFLAG_WRITE))
+ return 1;
- /* check error */
- if (status & (ATA_ERR | ATA_DF)) {
- qc->err_mask |= AC_ERR_DEV;
- ap->hsm_task_state = HSM_ST_ERR;
- return;
+ if (is_atapi_taskfile(&qc->tf) &&
+ !(qc->dev->flags & ATA_DFLAG_CDB_INTR))
+ return 1;
}
- /* transfer data if any */
- if (is_atapi_taskfile(&qc->tf)) {
- /* DRQ=0 means no more data to transfer */
- if ((status & ATA_DRQ) == 0) {
- ap->hsm_task_state = HSM_ST_LAST;
- return;
- }
+ return 0;
+}
- atapi_pio_bytes(qc);
- } else {
- /* handle BSY=0, DRQ=0 as error */
- if ((status & ATA_DRQ) == 0) {
+/**
+ * ata_hsm_move - move the HSM to the next state.
+ * @ap: the target ata_port
+ * @qc: qc on going
+ * @status: current device status
+ * @in_wq: 1 if called from workqueue, 0 otherwise
+ *
+ * RETURNS:
+ * 1 when poll next status needed, 0 otherwise.
+ */
+
+static int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
+ u8 status, int in_wq)
+{
+ unsigned long flags = 0;
+ int poll_next;
+
+ WARN_ON((qc->flags & ATA_QCFLAG_ACTIVE) == 0);
+
+ /* Make sure ata_qc_issue_prot() does not throw things
+ * like DMA polling into the workqueue. Notice that
+ * in_wq is not equivalent to (qc->tf.flags & ATA_TFLAG_POLLING).
+ */
+ WARN_ON(in_wq != ata_hsm_ok_in_wq(ap, 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);
+
+ switch (ap->hsm_task_state) {
+ case HSM_ST_FIRST:
+ /* Send first data block or PACKET CDB */
+
+ /* If polling, we will stay in the work queue after
+ * sending the data. Otherwise, interrupt handler
+ * takes over after sending the data.
+ */
+ poll_next = (qc->tf.flags & ATA_TFLAG_POLLING);
+
+ /* check device status */
+ if (unlikely((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)) {
+ /* Wrong status. Let EH handle this */
qc->err_mask |= AC_ERR_HSM;
ap->hsm_task_state = HSM_ST_ERR;
- return;
+ goto fsm_start;
}
- ata_pio_sector(qc);
- }
-}
+ /* Device should not ask for data transfer (DRQ=1)
+ * when it finds something wrong.
+ * We ignore DRQ here and stop the HSM by
+ * changing hsm_task_state to HSM_ST_ERR and
+ * 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);
+ qc->err_mask |= AC_ERR_DEV;
+ ap->hsm_task_state = HSM_ST_ERR;
+ goto fsm_start;
+ }
-static void ata_pio_error(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
+ /* Send the CDB (atapi) or the first data block (ata pio out).
+ * During the state transition, interrupt handler shouldn't
+ * be invoked before the data transfer is complete and
+ * hsm_task_state is changed. Hence, the following locking.
+ */
+ if (in_wq)
+ spin_lock_irqsave(&ap->host_set->lock, flags);
- if (qc->tf.command != ATA_CMD_PACKET)
- printk(KERN_WARNING "ata%u: dev %u PIO error\n",
- ap->id, qc->dev->devno);
+ if (qc->tf.protocol == ATA_PROT_PIO) {
+ /* PIO data out protocol.
+ * send first data block.
+ */
- /* make sure qc->err_mask is available to
- * know what's wrong and recover
- */
- WARN_ON(qc->err_mask == 0);
+ /* ata_pio_sectors() might change the state
+ * to HSM_ST_LAST. so, the state is changed here
+ * before ata_pio_sectors().
+ */
+ ap->hsm_task_state = HSM_ST;
+ ata_pio_sectors(qc);
+ ata_altstatus(ap); /* flush */
+ } else
+ /* send CDB */
+ atapi_send_cdb(ap, qc);
+
+ if (in_wq)
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+ /* if polling, ata_pio_task() handles the rest.
+ * otherwise, interrupt handler takes over from here.
+ */
+ break;
- ap->hsm_task_state = HSM_ST_IDLE;
+ case HSM_ST:
+ /* complete command or read/write the data register */
+ if (qc->tf.protocol == ATA_PROT_ATAPI) {
+ /* ATAPI PIO protocol */
+ if ((status & ATA_DRQ) == 0) {
+ /* no more data to transfer */
+ ap->hsm_task_state = HSM_ST_LAST;
+ goto fsm_start;
+ }
- ata_poll_qc_complete(qc);
-}
+ /* Device should not ask for data transfer (DRQ=1)
+ * when it finds something wrong.
+ * We ignore DRQ here and stop the HSM by
+ * changing hsm_task_state to HSM_ST_ERR and
+ * 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);
+ qc->err_mask |= AC_ERR_DEV;
+ ap->hsm_task_state = HSM_ST_ERR;
+ goto fsm_start;
+ }
-static void ata_pio_task(void *_data)
-{
- struct ata_queued_cmd *qc = _data;
- struct ata_port *ap = qc->ap;
- unsigned long timeout;
- int qc_completed;
+ atapi_pio_bytes(qc);
-fsm_start:
- timeout = 0;
- qc_completed = 0;
+ if (unlikely(ap->hsm_task_state == HSM_ST_ERR))
+ /* bad ireason reported by device */
+ goto fsm_start;
- switch (ap->hsm_task_state) {
- case HSM_ST_IDLE:
- return;
+ } else {
+ /* ATA PIO protocol */
+ if (unlikely((status & ATA_DRQ) == 0)) {
+ /* handle BSY=0, DRQ=0 as error */
+ qc->err_mask |= AC_ERR_HSM;
+ ap->hsm_task_state = HSM_ST_ERR;
+ goto fsm_start;
+ }
- case HSM_ST:
- ata_pio_block(qc);
+ /* For PIO reads, some devices may ask for
+ * data transfer (DRQ=1) alone with ERR=1.
+ * We respect DRQ here and transfer one
+ * block of junk data before changing the
+ * hsm_task_state to HSM_ST_ERR.
+ *
+ * For PIO writes, ERR=1 DRQ=1 doesn't make
+ * sense since the data block has been
+ * transferred to the device.
+ */
+ if (unlikely(status & (ATA_ERR | ATA_DF))) {
+ /* data might be corrputed */
+ qc->err_mask |= AC_ERR_DEV;
+
+ if (!(qc->tf.flags & ATA_TFLAG_WRITE)) {
+ ata_pio_sectors(qc);
+ ata_altstatus(ap);
+ status = ata_wait_idle(ap);
+ }
+
+ /* ata_pio_sectors() might change the
+ * state to HSM_ST_LAST. so, the state
+ * is changed after ata_pio_sectors().
+ */
+ ap->hsm_task_state = HSM_ST_ERR;
+ goto fsm_start;
+ }
+
+ ata_pio_sectors(qc);
+
+ if (ap->hsm_task_state == HSM_ST_LAST &&
+ (!(qc->tf.flags & ATA_TFLAG_WRITE))) {
+ /* all data read */
+ ata_altstatus(ap);
+ status = ata_wait_idle(ap);
+ goto fsm_start;
+ }
+ }
+
+ ata_altstatus(ap); /* flush */
+ poll_next = 1;
break;
case HSM_ST_LAST:
- qc_completed = ata_pio_complete(qc);
- break;
+ if (unlikely(!ata_ok(status))) {
+ qc->err_mask |= __ac_err_mask(status);
+ ap->hsm_task_state = HSM_ST_ERR;
+ goto 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);
+
+ WARN_ON(qc->err_mask);
- case HSM_ST_POLL:
- case HSM_ST_LAST_POLL:
- timeout = ata_pio_poll(qc);
+ ap->hsm_task_state = HSM_ST_IDLE;
+
+ /* complete taskfile transaction */
+ if (in_wq)
+ ata_poll_qc_complete(qc);
+ else
+ ata_qc_complete(qc);
+
+ poll_next = 0;
break;
- case HSM_ST_TMOUT:
case HSM_ST_ERR:
- ata_pio_error(qc);
- return;
+ if (qc->tf.command != ATA_CMD_PACKET)
+ printk(KERN_ERR "ata%u: dev %u command error, drv_stat 0x%x\n",
+ ap->id, qc->dev->devno, status);
+
+ /* make sure qc->err_mask is available to
+ * know what's wrong and recover
+ */
+ WARN_ON(qc->err_mask == 0);
+
+ ap->hsm_task_state = HSM_ST_IDLE;
+
+ /* complete taskfile transaction */
+ if (in_wq)
+ ata_poll_qc_complete(qc);
+ else
+ ata_qc_complete(qc);
+
+ poll_next = 0;
+ break;
+ default:
+ poll_next = 0;
+ BUG();
}
- if (timeout)
- ata_port_queue_task(ap, ata_pio_task, qc, timeout);
- else if (!qc_completed)
- goto fsm_start;
+ return poll_next;
}
-/**
- * atapi_packet_task - Write CDB bytes to hardware
- * @_data: qc in progress
- *
- * When device has indicated its readiness to accept
- * a CDB, this function is called. Send the CDB.
- * If DMA is to be performed, exit immediately.
- * Otherwise, we are in polling mode, so poll
- * status under operation succeeds or fails.
- *
- * LOCKING:
- * Kernel thread context (may sleep)
- */
-static void atapi_packet_task(void *_data)
+static void ata_pio_task(void *_data)
{
struct ata_queued_cmd *qc = _data;
struct ata_port *ap = qc->ap;
u8 status;
+ int poll_next;
- /* sleep-wait for BSY to clear */
- DPRINTK("busy wait\n");
- if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) {
- qc->err_mask |= AC_ERR_TIMEOUT;
- goto err_out;
- }
-
- /* make sure DRQ is set */
- status = ata_chk_status(ap);
- if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) {
- qc->err_mask |= AC_ERR_HSM;
- goto err_out;
- }
-
- /* send SCSI cdb */
- DPRINTK("send cdb\n");
- WARN_ON(qc->dev->cdb_len < 12);
-
- if (qc->tf.protocol == ATA_PROT_ATAPI_DMA ||
- qc->tf.protocol == ATA_PROT_ATAPI_NODATA) {
- unsigned long flags;
-
- /* Once we're done issuing command and kicking bmdma,
- * irq handler takes over. To not lose irq, we need
- * to clear NOINTR flag before sending cdb, but
- * interrupt handler shouldn't be invoked before we're
- * finished. Hence, the following locking.
- */
- spin_lock_irqsave(&ap->host_set->lock, flags);
- ap->flags &= ~ATA_FLAG_NOINTR;
- ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
- if (qc->tf.protocol == ATA_PROT_ATAPI_DMA)
- ap->ops->bmdma_start(qc); /* initiate bmdma */
- spin_unlock_irqrestore(&ap->host_set->lock, flags);
- } else {
- ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
+fsm_start:
+ WARN_ON(ap->hsm_task_state == HSM_ST_IDLE);
- /* PIO commands are handled by polling */
- ap->hsm_task_state = HSM_ST;
- ata_port_queue_task(ap, ata_pio_task, qc, 0);
+ /*
+ * This is purely heuristic. This is a fast path.
+ * Sometimes when we enter, BSY will be cleared in
+ * a chk-status or two. If not, the drive is probably seeking
+ * or something. Snooze for a couple msecs, then
+ * chk-status again. If still busy, queue delayed work.
+ */
+ status = ata_busy_wait(ap, ATA_BUSY, 5);
+ if (status & ATA_BUSY) {
+ msleep(2);
+ status = ata_busy_wait(ap, ATA_BUSY, 10);
+ if (status & ATA_BUSY) {
+ ata_port_queue_task(ap, ata_pio_task, qc, ATA_SHORT_PAUSE);
+ return;
+ }
}
- return;
+ /* move the HSM */
+ poll_next = ata_hsm_move(ap, qc, status, 1);
-err_out:
- ata_poll_qc_complete(qc);
+ /* another command or interrupt handler
+ * may be running at this point.
+ */
+ if (poll_next)
+ goto fsm_start;
}
/**
{
struct ata_port *ap = qc->ap;
+ /* Use polling pio if the LLD doesn't handle
+ * interrupt driven pio and atapi CDB interrupt.
+ */
+ if (ap->flags & ATA_FLAG_PIO_POLLING) {
+ switch (qc->tf.protocol) {
+ case ATA_PROT_PIO:
+ case ATA_PROT_ATAPI:
+ case ATA_PROT_ATAPI_NODATA:
+ qc->tf.flags |= ATA_TFLAG_POLLING;
+ break;
+ case ATA_PROT_ATAPI_DMA:
+ if (qc->dev->flags & ATA_DFLAG_CDB_INTR)
+ /* see ata_check_atapi_dma() */
+ BUG();
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* select the device */
ata_dev_select(ap, qc->dev->devno, 1, 0);
+ /* start the command */
switch (qc->tf.protocol) {
case ATA_PROT_NODATA:
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_qc_set_polling(qc);
+
ata_tf_to_host(ap, &qc->tf);
+ ap->hsm_task_state = HSM_ST_LAST;
+
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_port_queue_task(ap, ata_pio_task, qc, 0);
+
break;
case ATA_PROT_DMA:
+ WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
+
ap->ops->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;
break;
- case ATA_PROT_PIO: /* load tf registers, initiate polling pio */
- ata_qc_set_polling(qc);
- ata_tf_to_host(ap, &qc->tf);
- ap->hsm_task_state = HSM_ST;
- ata_port_queue_task(ap, ata_pio_task, qc, 0);
- break;
+ case ATA_PROT_PIO:
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_qc_set_polling(qc);
- case ATA_PROT_ATAPI:
- ata_qc_set_polling(qc);
ata_tf_to_host(ap, &qc->tf);
- ata_port_queue_task(ap, atapi_packet_task, qc, 0);
+
+ if (qc->tf.flags & ATA_TFLAG_WRITE) {
+ /* PIO data out protocol */
+ ap->hsm_task_state = HSM_ST_FIRST;
+ ata_port_queue_task(ap, ata_pio_task, qc, 0);
+
+ /* always send first data block using
+ * the ata_pio_task() codepath.
+ */
+ } else {
+ /* PIO data in protocol */
+ ap->hsm_task_state = HSM_ST;
+
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_port_queue_task(ap, ata_pio_task, qc, 0);
+
+ /* if polling, ata_pio_task() handles the rest.
+ * otherwise, interrupt handler takes over from here.
+ */
+ }
+
break;
+ case ATA_PROT_ATAPI:
case ATA_PROT_ATAPI_NODATA:
- ap->flags |= ATA_FLAG_NOINTR;
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_qc_set_polling(qc);
+
ata_tf_to_host(ap, &qc->tf);
- ata_port_queue_task(ap, atapi_packet_task, qc, 0);
+
+ ap->hsm_task_state = HSM_ST_FIRST;
+
+ /* send cdb by polling if no cdb interrupt */
+ if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) ||
+ (qc->tf.flags & ATA_TFLAG_POLLING))
+ ata_port_queue_task(ap, ata_pio_task, qc, 0);
break;
case ATA_PROT_ATAPI_DMA:
- ap->flags |= ATA_FLAG_NOINTR;
+ WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
+
ap->ops->tf_load(ap, &qc->tf); /* load tf registers */
ap->ops->bmdma_setup(qc); /* set up bmdma */
- ata_port_queue_task(ap, atapi_packet_task, qc, 0);
+ ap->hsm_task_state = HSM_ST_FIRST;
+
+ /* send cdb by polling if no cdb interrupt */
+ if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
+ ata_port_queue_task(ap, ata_pio_task, qc, 0);
break;
default:
inline unsigned int ata_host_intr (struct ata_port *ap,
struct ata_queued_cmd *qc)
{
- u8 status, host_stat;
-
- switch (qc->tf.protocol) {
+ u8 status, host_stat = 0;
- case ATA_PROT_DMA:
- case ATA_PROT_ATAPI_DMA:
- case ATA_PROT_ATAPI:
- /* check status of DMA engine */
- host_stat = ap->ops->bmdma_status(ap);
- VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat);
-
- /* if it's not our irq... */
- if (!(host_stat & ATA_DMA_INTR))
- goto idle_irq;
-
- /* before we do anything else, clear DMA-Start bit */
- ap->ops->bmdma_stop(qc);
+ VPRINTK("ata%u: protocol %d task_state %d\n",
+ ap->id, qc->tf.protocol, ap->hsm_task_state);
- /* fall through */
-
- case ATA_PROT_ATAPI_NODATA:
- case ATA_PROT_NODATA:
- /* check altstatus */
- status = ata_altstatus(ap);
- if (status & ATA_BUSY)
- goto idle_irq;
+ /* Check whether we are expecting interrupt in this state */
+ switch (ap->hsm_task_state) {
+ case HSM_ST_FIRST:
+ /* Some pre-ATAPI-4 devices assert INTRQ
+ * at this state when ready to receive CDB.
+ */
- /* check main status, clearing INTRQ */
- status = ata_chk_status(ap);
- if (unlikely(status & ATA_BUSY))
+ /* Check the ATA_DFLAG_CDB_INTR flag is enough here.
+ * The flag was turned on only for atapi devices.
+ * No need to check is_atapi_taskfile(&qc->tf) again.
+ */
+ if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
goto idle_irq;
- DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
- ap->id, qc->tf.protocol, status);
-
- /* ack bmdma irq events */
- ap->ops->irq_clear(ap);
-
- /* complete taskfile transaction */
- qc->err_mask |= ac_err_mask(status);
- ata_qc_complete(qc);
break;
-
+ case HSM_ST_LAST:
+ if (qc->tf.protocol == ATA_PROT_DMA ||
+ 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);
+
+ /* if it's not our irq... */
+ if (!(host_stat & ATA_DMA_INTR))
+ goto idle_irq;
+
+ /* before we do anything else, clear DMA-Start bit */
+ ap->ops->bmdma_stop(qc);
+
+ if (unlikely(host_stat & ATA_DMA_ERR)) {
+ /* error when transfering data to/from memory */
+ qc->err_mask |= AC_ERR_HOST_BUS;
+ ap->hsm_task_state = HSM_ST_ERR;
+ }
+ }
+ break;
+ case HSM_ST:
+ break;
default:
goto idle_irq;
}
+ /* check altstatus */
+ status = ata_altstatus(ap);
+ if (status & ATA_BUSY)
+ goto idle_irq;
+
+ /* check main status, clearing INTRQ */
+ status = ata_chk_status(ap);
+ if (unlikely(status & ATA_BUSY))
+ goto idle_irq;
+
+ /* ack bmdma irq events */
+ ap->ops->irq_clear(ap);
+
+ ata_hsm_move(ap, qc, status, 0);
return 1; /* irq handled */
idle_irq:
ap = host_set->ports[i];
if (ap &&
- !(ap->flags & (ATA_FLAG_DISABLED | ATA_FLAG_NOINTR))) {
+ !(ap->flags & ATA_FLAG_DISABLED)) {
struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->active_tag);
- if (qc && (!(qc->tf.ctl & ATA_NIEN)) &&
+ if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) &&
(qc->flags & ATA_QCFLAG_ACTIVE))
handled |= ata_host_intr(ap, qc);
}
host->transportt = &ata_scsi_transport_template;
- ap = (struct ata_port *) &host->hostdata[0];
+ ap = ata_shost_to_port(host);
ata_host_init(ap, host, host_set, ent, port_no);
int ata_scsi_release(struct Scsi_Host *host)
{
- struct ata_port *ap = (struct ata_port *) &host->hostdata[0];
+ struct ata_port *ap = ata_shost_to_port(host);
int i;
DPRINTK("ENTER\n");
return rc;
}
+ /**
+ * ata_wait_register - wait until register value changes
+ * @reg: IO-mapped register
+ * @mask: Mask to apply to read register value
+ * @val: Wait condition
+ * @interval_msec: polling interval in milliseconds
+ * @timeout_msec: timeout in milliseconds
+ *
+ * Waiting for some bits of register to change is a common
+ * operation for ATA controllers. This function reads 32bit LE
+ * IO-mapped register @reg and tests for the following condition.
+ *
+ * (*@reg & mask) != val
+ *
+ * If the condition is met, it returns; otherwise, the process is
+ * repeated after @interval_msec until timeout.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ *
+ * RETURNS:
+ * The final register value.
+ */
+ u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
+ unsigned long interval_msec,
+ unsigned long timeout_msec)
+ {
+ unsigned long timeout;
+ u32 tmp;
+
+ tmp = ioread32(reg);
+
+ /* Calculate timeout _after_ the first read to make sure
+ * preceding writes reach the controller before starting to
+ * eat away the timeout.
+ */
+ timeout = jiffies + (timeout_msec * HZ) / 1000;
+
+ while ((tmp & mask) == val && time_before(jiffies, timeout)) {
+ msleep(interval_msec);
+ tmp = ioread32(reg);
+ }
+
+ return tmp;
+ }
+
/*
* libata is essentially a library of internal helper functions for
* low-level ATA host controller drivers. As such, the API/ABI is
EXPORT_SYMBOL_GPL(ata_bmdma_status);
EXPORT_SYMBOL_GPL(ata_bmdma_stop);
EXPORT_SYMBOL_GPL(ata_port_probe);
+ EXPORT_SYMBOL_GPL(ata_set_sata_spd);
EXPORT_SYMBOL_GPL(sata_phy_reset);
EXPORT_SYMBOL_GPL(__sata_phy_reset);
EXPORT_SYMBOL_GPL(ata_bus_reset);
EXPORT_SYMBOL_GPL(ata_dev_pair);
EXPORT_SYMBOL_GPL(ata_port_disable);
EXPORT_SYMBOL_GPL(ata_ratelimit);
+ EXPORT_SYMBOL_GPL(ata_wait_register);
EXPORT_SYMBOL_GPL(ata_busy_sleep);
EXPORT_SYMBOL_GPL(ata_port_queue_task);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);