Commit 838ede57 authored by James Bottomley's avatar James Bottomley

Initial support (mid-layer) for generic TCQ

parent 14ca3b78
......@@ -230,6 +230,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j)
retval->select_queue_depths = tpnt->select_queue_depths;
retval->max_sectors = tpnt->max_sectors;
retval->use_blk_tcq = tpnt->use_blk_tcq;
if(!scsi_hostlist)
scsi_hostlist = retval;
......
......@@ -286,6 +286,12 @@ typedef struct SHT
unsigned highmem_io:1;
/*
* True if the driver wishes to use the generic block layer
* tag queueing functions
*/
unsigned use_blk_tcq:1;
/*
* Name of proc directory
*/
......@@ -386,6 +392,7 @@ struct Scsi_Host
unsigned unchecked_isa_dma:1;
unsigned use_clustering:1;
unsigned highmem_io:1;
unsigned use_blk_tcq:1;
/*
* Host has rejected a command because it was busy.
......
......@@ -850,6 +850,64 @@ struct scsi_cmnd {
extern int scsi_reset_provider(Scsi_Device *, int);
/**
* scsi_activate_tcq - turn on tag command queueing
* @SDpnt: device to turn on TCQ for
* @depth: queue depth
*
* Notes:
* Eventually, I hope depth would be the maximum depth
* the device could cope with and the real queue depth
* would be adjustable from 0 to depth.
**/
static inline void scsi_activate_tcq(Scsi_Device *SDpnt, int depth) {
request_queue_t *q = &SDpnt->request_queue;
if(SDpnt->tagged_supported && !blk_queue_tagged(q)) {
blk_queue_init_tags(q, depth);
SDpnt->tagged_queue = 1;
}
}
/**
* scsi_deactivate_tcq - turn off tag command queueing
* @SDpnt: device to turn off TCQ for
**/
static inline void scsi_deactivate_tcq(Scsi_Device *SDpnt) {
blk_queue_free_tags(&SDpnt->request_queue);
SDpnt->tagged_queue = 0;
}
#define MSG_SIMPLE_TAG 0x20
#define MSG_HEAD_TAG 0x21
#define MSG_ORDERED_TAG 0x22
/**
* scsi_populate_tag_msg - place a tag message in a buffer
* @SCpnt: pointer to the Scsi_Cmnd for the tag
* @msg: pointer to the area to place the tag
*
* Notes:
* designed to create the correct type of tag message for the
* particular request. Returns the size of the tag message.
* May return 0 if TCQ is disabled for this device.
**/
static inline int scsi_populate_tag_msg(Scsi_Cmnd *SCpnt, char *msg) {
struct request *req = SCpnt->request;
if(!blk_rq_tagged(req))
return 0;
if(req->flags & REQ_BARRIER)
*msg++ = MSG_ORDERED_TAG;
else
*msg++ = MSG_SIMPLE_TAG;
*msg++ = SCpnt->request->tag;
return 2;
}
#endif
/*
......
......@@ -378,6 +378,9 @@ static Scsi_Cmnd *__scsi_end_request(Scsi_Cmnd * SCpnt,
add_blkdev_randomness(major(req->rq_dev));
if(blk_rq_tagged(req))
blk_queue_end_tag(q, req);
end_that_request_last(req);
spin_unlock_irqrestore(q->queue_lock, flags);
......@@ -924,7 +927,10 @@ void scsi_request_fn(request_queue_t * q)
* reason to search the list, because all of the commands
* in this queue are for the same device.
*/
blkdev_dequeue_request(req);
if(blk_queue_tagged(q))
blk_queue_start_tag(q, req);
else
blkdev_dequeue_request(req);
SCpnt->request = req;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment