Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 12436c30 authored by Tejun Heo's avatar Tejun Heo
Browse files

Merge branch 'irq-pio'

Conflicts:

	drivers/scsi/libata-core.c
	include/linux/libata.h
parents 88ce7550 7894eaf2
Loading
Loading
Loading
Loading
+495 −308
Original line number Diff line number Diff line
@@ -1345,11 +1345,19 @@ static int ata_dev_configure(struct ata_device *dev, int print_info)
					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)) {
			ata_dev_printk(dev, KERN_WARNING,
@@ -1359,10 +1367,16 @@ static int ata_dev_configure(struct ata_device *dev, int print_info)
		}
		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)
			ata_dev_printk(dev, KERN_INFO, "ATAPI, max %s\n",
				       ata_mode_string(xfer_mask));
			ata_dev_printk(dev, KERN_INFO, "ATAPI, max %s%s\n",
				       ata_mode_string(xfer_mask),
				       cdb_intr_string);
	}

	ap->host->max_cmd_len = 0;
@@ -3211,6 +3225,15 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc)
	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;
}
/**
@@ -3458,7 +3481,6 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc)
		qc = ata_qc_from_tag(ap, qc->tag);
		if (qc) {
			if (!(qc->err_mask & AC_ERR_HSM)) {
				ap->flags &= ~ATA_FLAG_NOINTR;
				ata_irq_on(ap);
				ata_qc_complete(qc);
			} else
@@ -3466,7 +3488,6 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc)
		}
	} else {
		/* old EH */
		ap->flags &= ~ATA_FLAG_NOINTR;
		ata_irq_on(ap);
		ata_qc_complete(qc);
	}
@@ -3474,105 +3495,6 @@ void ata_poll_qc_complete(struct ata_queued_cmd *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
@@ -3741,7 +3663,23 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
	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++;
@@ -3750,14 +3688,68 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
		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.
 */

	/* do the actual data transfer */
	do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
	ata_data_xfer(ap, buf, ATA_SECT_SIZE, do_write);
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.
 */

	kunmap(page);
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);

	ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
	ata_altstatus(ap); /* flush */

	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;
	}
}

/**
@@ -3823,7 +3815,23 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
	/* 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;
@@ -3834,13 +3842,6 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
		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;
}
@@ -3877,6 +3878,8 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
	if (do_write != i_write)
		goto err_out;

	VPRINTK("ata%u: xfering %d bytes\n", ap->id, bytes);

	__atapi_pio_bytes(qc, bytes);

	return;
@@ -3888,186 +3891,294 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
}

/**
 *	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;

		if (is_atapi_taskfile(&qc->tf) &&
		    !(qc->dev->flags & ATA_DFLAG_CDB_INTR))
			return 1;
	}

	return 0;
}

	/* check error */
	if (status & (ATA_ERR | ATA_DF)) {
/**
 *	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;
			goto fsm_start;
		}

		/* 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;
		return;
			goto fsm_start;
		}

	/* transfer data if any */
	if (is_atapi_taskfile(&qc->tf)) {
		/* DRQ=0 means no more data to transfer */
		/* 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.protocol == ATA_PROT_PIO) {
			/* PIO data out protocol.
			 * send first data block.
			 */

			/* 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;

	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;
			return;
				goto fsm_start;
			}

			/* 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;
			}

			atapi_pio_bytes(qc);

			if (unlikely(ap->hsm_task_state == HSM_ST_ERR))
				/* bad ireason reported by device */
				goto fsm_start;

		} else {
			/* ATA PIO protocol */
			if (unlikely((status & ATA_DRQ) == 0)) {
				/* handle BSY=0, DRQ=0 as error */
		if ((status & ATA_DRQ) == 0) {
				qc->err_mask |= AC_ERR_HSM;
				ap->hsm_task_state = HSM_ST_ERR;
			return;
				goto fsm_start;
			}

		ata_pio_sector(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;
			}

static void ata_pio_error(struct ata_queued_cmd *qc)
{
	struct ata_port *ap = qc->ap;
			ata_pio_sectors(qc);

	if (qc->tf.command != ATA_CMD_PACKET)
		ata_dev_printk(qc->dev, KERN_WARNING, "PIO error\n");
			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;
			}
		}

	/* make sure qc->err_mask is available to
	 * know what's wrong and recover
	 */
	WARN_ON(qc->err_mask == 0);
		ata_altstatus(ap); /* flush */
		poll_next = 1;
		break;

	case HSM_ST_LAST:
		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);

		ap->hsm_task_state = HSM_ST_IDLE;

		/* complete taskfile transaction */
		if (in_wq)
			ata_poll_qc_complete(qc);
}
		else
			ata_qc_complete(qc);

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;
		poll_next = 0;
		break;

fsm_start:
	timeout = 0;
	qc_completed = 0;
	case HSM_ST_ERR:
		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);

	switch (ap->hsm_task_state) {
	case HSM_ST_IDLE:
		return;
		/* make sure qc->err_mask is available to
		 * know what's wrong and recover
		 */
		WARN_ON(qc->err_mask == 0);

	case HSM_ST:
		ata_pio_block(qc);
		break;
		ap->hsm_task_state = HSM_ST_IDLE;

	case HSM_ST_LAST:
		qc_completed = ata_pio_complete(qc);
		break;
		/* complete taskfile transaction */
		if (in_wq)
			ata_poll_qc_complete(qc);
		else
			ata_qc_complete(qc);

	case HSM_ST_POLL:
	case HSM_ST_LAST_POLL:
		timeout = ata_pio_poll(qc);
		poll_next = 0;
		break;

	case HSM_ST_TMOUT:
	case HSM_ST_ERR:
		ata_pio_error(qc);
		return;
	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;
fsm_start:
	WARN_ON(ap->hsm_task_state == HSM_ST_IDLE);

		/* 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.
	/*
	 * 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.
	 */
		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);

		/* PIO commands are handled by polling */
		ap->hsm_task_state = HSM_ST;
		ata_port_queue_task(ap, ata_pio_task, qc, 0);
	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;
}

/**
@@ -4322,43 +4433,105 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
{
	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 */
	case ATA_PROT_PIO:
		if (qc->tf.flags & ATA_TFLAG_POLLING)
			ata_qc_set_polling(qc);

		ata_tf_to_host(ap, &qc->tf);

		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:
		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);
		break;

	case ATA_PROT_ATAPI_NODATA:
		ap->flags |= ATA_FLAG_NOINTR;
		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:
@@ -4388,13 +4561,28 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
inline unsigned int ata_host_intr (struct ata_port *ap,
				   struct ata_queued_cmd *qc)
{
	u8 status, host_stat;
	u8 status, host_stat = 0;

	switch (qc->tf.protocol) {
	VPRINTK("ata%u: protocol %d task_state %d\n",
		ap->id, qc->tf.protocol, ap->hsm_task_state);

	case ATA_PROT_DMA:
	case ATA_PROT_ATAPI_DMA:
	case ATA_PROT_ATAPI:
	/* 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 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;
		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);
@@ -4406,10 +4594,19 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
			/* before we do anything else, clear DMA-Start bit */
			ap->ops->bmdma_stop(qc);

		/* fall through */
			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;
	}

	case ATA_PROT_ATAPI_NODATA:
	case ATA_PROT_NODATA:
	/* check altstatus */
	status = ata_altstatus(ap);
	if (status & ATA_BUSY)
@@ -4419,21 +4616,11 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
	status = ata_chk_status(ap);
	if (unlikely(status & ATA_BUSY))
		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;

	default:
		goto idle_irq;
	}

	ata_hsm_move(ap, qc, status, 0);
	return 1;	/* irq handled */

idle_irq:
@@ -4480,11 +4667,11 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)

		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);
		}
+1 −1
Original line number Diff line number Diff line
@@ -350,7 +350,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
			       qc->tf.command, drv_stat, host_stat);

		/* complete taskfile transaction */
		qc->err_mask |= ac_err_mask(drv_stat);
		qc->err_mask |= AC_ERR_TIMEOUT;
		break;
	}

+4 −4
Original line number Diff line number Diff line
@@ -455,13 +455,13 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
			continue;
		handled = 1;
		adma_enter_reg_mode(ap);
		if (ap->flags & (ATA_FLAG_DISABLED | ATA_FLAG_NOINTR))
		if (ap->flags & ATA_FLAG_DISABLED)
			continue;
		pp = ap->private_data;
		if (!pp || pp->state != adma_state_pkt)
			continue;
		qc = ata_qc_from_tag(ap, ap->active_tag);
		if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
		if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
			if ((status & (aPERR | aPSD | aUIRQ)))
				qc->err_mask |= AC_ERR_OTHER;
			else if (pp->pkt[0] != cDONE)
@@ -480,13 +480,13 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set)
	for (port_no = 0; port_no < host_set->n_ports; ++port_no) {
		struct ata_port *ap;
		ap = host_set->ports[port_no];
		if (ap && (!(ap->flags & (ATA_FLAG_DISABLED | ATA_FLAG_NOINTR)))) {
		if (ap && (!(ap->flags & ATA_FLAG_DISABLED))) {
			struct ata_queued_cmd *qc;
			struct adma_port_priv *pp = ap->private_data;
			if (!pp || pp->state != adma_state_mmio)
				continue;
			qc = ata_qc_from_tag(ap, ap->active_tag);
			if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
			if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {

				/* check main status, clearing INTRQ */
				u8 status = ata_check_status(ap);
+3 −3

File changed.

Preview size limit exceeded, changes collapsed.

+2 −2

File changed.

Preview size limit exceeded, changes collapsed.

Loading