Exemple #1
0
/**
 * blk_execute_rq - insert a request into queue for execution
 * @q:		queue to insert the request in
 * @bd_disk:	matching gendisk
 * @rq:		request to insert
 * @at_head:    insert request at head or tail of queue
 *
 * Description:
 *    Insert a fully prepared request at the back of the I/O scheduler queue
 *    for execution and wait for completion.
 */
int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
		   struct request *rq, int at_head)
{
	DECLARE_COMPLETION_ONSTACK(wait);
	char sense[SCSI_SENSE_BUFFERSIZE];
	int err = 0;
	unsigned long hang_check;

	/*
	 * we need an extra reference to the request, so we can look at
	 * it after io completion
	 */
	rq->ref_count++;

	if (!rq->sense) {
		memset(sense, 0, sizeof(sense));
		rq->sense = sense;
		rq->sense_len = 0;
	}

	rq->end_io_data = &wait;
	blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq);

	/* Prevent hang_check timer from firing at us during very long I/O */
	hang_check = sysctl_hung_task_timeout_secs;
	if (hang_check)
		while (!wait_for_completion_io_timeout(&wait, hang_check * (HZ/2)));
	else
		wait_for_completion_io(&wait);

	if (rq->errors)
		err = -EIO;

	return err;
}
Exemple #2
0
int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
		   struct request *rq, int at_head)
{
	DECLARE_COMPLETION_ONSTACK(wait);
	char sense[SCSI_SENSE_BUFFERSIZE];
	int err = 0;
	unsigned long hang_check;

	rq->ref_count++;

	if (!rq->sense) {
		memset(sense, 0, sizeof(sense));
		rq->sense = sense;
		rq->sense_len = 0;
	}

	rq->end_io_data = &wait;
	blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq);

	
	hang_check = sysctl_hung_task_timeout_secs;
	if (hang_check)
		while (!wait_for_completion_io_timeout(&wait, hang_check * (HZ/2)));
	else
		wait_for_completion_io(&wait);

	if (rq->errors)
		err = -EIO;

	return err;
}
Exemple #3
0
void wait_for_bio_entry(struct bio_entry *bioe, ulong timeoutMs)
{
	const ulong timeo = msecs_to_jiffies(timeoutMs);
	ulong rtimeo;
	int c = 0;

retry:
	rtimeo = wait_for_completion_io_timeout(&bioe->done, timeo);
	if (rtimeo == 0) {
		LOGn("timeout(%d): bioe %p bio %p pos %" PRIu64 " len %u\n"
			, c, bioe, bioe->bio
			, (u64)bio_entry_pos(bioe), bio_entry_len(bioe));
		c++;
		goto retry;
	}
}
Exemple #4
0
/* common code that starts a transfer */
static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
{
	if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) {
		dev_dbg(rsb->dev, "RSB transfer still in progress\n");
		return -EBUSY;
	}

	reinit_completion(&rsb->complete);

	writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER,
	       rsb->regs + RSB_INTE);
	writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB,
	       rsb->regs + RSB_CTRL);

	if (!wait_for_completion_io_timeout(&rsb->complete,
					    msecs_to_jiffies(100))) {
		dev_dbg(rsb->dev, "RSB timeout\n");

		/* abort the transfer */
		writel(RSB_CTRL_ABORT_TRANS, rsb->regs + RSB_CTRL);

		/* clear any interrupt flags */
		writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS);

		return -ETIMEDOUT;
	}

	if (rsb->status & RSB_INTS_LOAD_BSY) {
		dev_dbg(rsb->dev, "RSB busy\n");
		return -EBUSY;
	}

	if (rsb->status & RSB_INTS_TRANS_ERR) {
		if (rsb->status & RSB_INTS_TRANS_ERR_ACK) {
			dev_dbg(rsb->dev, "RSB slave nack\n");
			return -EINVAL;
		}

		if (rsb->status & RSB_INTS_TRANS_ERR_DATA) {
			dev_dbg(rsb->dev, "RSB transfer data error\n");
			return -EIO;
		}
	}

	return 0;
}