Adds a new request queueing strategy that is more appropriate for some hardware
and considerably cleans up queueing of others, too. This patch was inspired
by a conversation with Arjan van de Ven at the  kernel summit.

The typical queueing loop in a driver looks like this:

static void request_fn(request_queue_t *q)
{
	controller *c = q->queuedata;

	while ((rq = elv_next_request(q))) {
		struct hw_cmd *hw_cmd = get_hw_cmd(c);
		if (!hw_cmd)
			break;

		/* various hw_cmd init stuff */

		/* map rq to sg dma table */
		entries = blk_rq_map_sg(q, rq, hw_cmd->sg_list);

		/* remove request from block queue */
		blkdev_dequeue_request(rq);

		/* map the pages in the request for dma */
		entries = pci_map_sg(c->pdev, hw_cmd->sg_list, entries, XX);

		/* add command to controller pending list */
		add_hw_cmd(c, hw_cmd);
	}

	/* start io */
	if (requests queued)
		start_io_on_queued_requests(c);

	/* if we couldn't get a hardware command because they are all in flight,
	   mark the queue as full */
	if (no_hardware_commands)
		blk_stop_queue(q);
}

Here the driver has to define its  own queueing loop, and handle details such
as removing block requests from the queue and stopping the queue hardware
full conditions.

The revised model is composed of two queueing functions: one for queueing a
request, and one for comitting the queued requests. If we rewrite the queueing
loop above for the new model, it looks like this:

/* requests have been added to controller pending list, just send them off */
static void commit_fn(request_queue_t *q)
{
	controller *c = q->queuedata;

	start_io_on_queued_requests(c);
}

/* queue one request. return 0 if queued, 1 if not */
static int queue_request_fn(request_queue_t *q, struct request *rq)
{
	controller *c = q->queuedata;
	struct hw_cmd *hw_cmd;

	hw_cmd = get_hw_cmd(c);
	if (!hw_cmd)
		return 1;

	/* map rq to sg dma table */
	entries = blk_rq_map_sg(q, rq, hw_cmd->sg_list);

	/* map the pages in the request for dma */
	entries = pci_map_sg(c->pdev, hw_cmd->sg_list, entries, XX);

	/* add command to controller pending list */
	add_hw_cmd(c, hw_cmd);
	return 0;
}

And that's it. Block layer internals take care of the boring details like
stopping/starting the queue (it will be restarted on the next released
request).

Patch converts cpqarray/cciss to use this model, both of those should work
fine I believe (not actually tested). Also attempted to fit SCSI into this
model, not much care was taken there though. I'd be surprised if it boots.

Jens (08/08/2003)