Commit f39fc866 authored by Jens Axboe's avatar Jens Axboe Committed by Linus Torvalds

[PATCH] generic tag update

The following comes from James Bottemley, as he updated the SCSI layer
to use the generic tagging.

Basically just put blk_queue_tag_request() into ll_rw_blk.c and name it
something more sane, blk_queue_find_tag(). In addition, remove REQ_CMD
requirement in blk_queue_start_tag() -- this is actually IDE specific
(we can only tag read/write requests there...), SCSI actually requires
everything to be tagged once enabled. It's replaced with a safety check
for an already tagged request.
parent 3f1fe673
...@@ -299,6 +299,27 @@ void blk_queue_assign_lock(request_queue_t *q, spinlock_t *lock) ...@@ -299,6 +299,27 @@ void blk_queue_assign_lock(request_queue_t *q, spinlock_t *lock)
q->queue_lock = lock; q->queue_lock = lock;
} }
/**
* blk_queue_find_tag - find a request by its tag and queue
*
* @q: The request queue for the device
* @tag: The tag of the request
*
* Notes:
* Should be used when a device returns a tag and you want to match
* it with a request.
*
* no locks need be held.
**/
struct request *blk_queue_find_tag(request_queue_t *q, int tag)
{
struct blk_queue_tag *bqt = q->queue_tags;
if(unlikely(bqt == NULL || bqt->max_depth < tag))
return NULL;
return bqt->tag_index[tag];
}
/** /**
* blk_queue_free_tags - release tag maintenance info * blk_queue_free_tags - release tag maintenance info
* @q: the request queue for the device * @q: the request queue for the device
...@@ -432,10 +453,12 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq) ...@@ -432,10 +453,12 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq)
* Description: * Description:
* This can either be used as a stand-alone helper, or possibly be * This can either be used as a stand-alone helper, or possibly be
* assigned as the queue &prep_rq_fn (in which case &struct request * assigned as the queue &prep_rq_fn (in which case &struct request
* automagically gets a tag assigned). Note that this function assumes * automagically gets a tag assigned). Note that this function
* that only REQ_CMD requests can be queued! The request will also be * assumes that any type of request can be queued! if this is not
* removed from the request queue, so it's the drivers responsibility to * true for your device, you must check the request type before
* readd it if it should need to be restarted for some reason. * calling this function. The request will also be removed from
* the request queue, so it's the drivers responsibility to readd
* it if it should need to be restarted for some reason.
* *
* Notes: * Notes:
* queue lock must be held. * queue lock must be held.
...@@ -446,8 +469,12 @@ int blk_queue_start_tag(request_queue_t *q, struct request *rq) ...@@ -446,8 +469,12 @@ int blk_queue_start_tag(request_queue_t *q, struct request *rq)
unsigned long *map = bqt->tag_map; unsigned long *map = bqt->tag_map;
int tag = 0; int tag = 0;
if (unlikely(!(rq->flags & REQ_CMD))) if (unlikely((rq->flags & REQ_QUEUED))) {
return 1; printk(KERN_ERR
"request %p for device [02%x:02%x] already tagged %d",
rq, major(rq->rq_dev), minor(rq->rq_dev), rq->tag);
BUG();
}
for (map = bqt->tag_map; *map == -1UL; map++) { for (map = bqt->tag_map; *map == -1UL; map++) {
tag += BLK_TAGS_PER_LONG; tag += BLK_TAGS_PER_LONG;
...@@ -2033,6 +2060,7 @@ EXPORT_SYMBOL(blk_put_request); ...@@ -2033,6 +2060,7 @@ EXPORT_SYMBOL(blk_put_request);
EXPORT_SYMBOL(blk_queue_prep_rq); EXPORT_SYMBOL(blk_queue_prep_rq);
EXPORT_SYMBOL(blk_queue_find_tag);
EXPORT_SYMBOL(blk_queue_init_tags); EXPORT_SYMBOL(blk_queue_init_tags);
EXPORT_SYMBOL(blk_queue_free_tags); EXPORT_SYMBOL(blk_queue_free_tags);
EXPORT_SYMBOL(blk_queue_start_tag); EXPORT_SYMBOL(blk_queue_start_tag);
......
...@@ -291,7 +291,7 @@ static ide_startstop_t service(struct ata_device *drive, struct request *rq) ...@@ -291,7 +291,7 @@ static ide_startstop_t service(struct ata_device *drive, struct request *rq)
TCQ_PRINTK("%s: stat %x, feat %x\n", __FUNCTION__, stat, feat); TCQ_PRINTK("%s: stat %x, feat %x\n", __FUNCTION__, stat, feat);
rq = blk_queue_tag_request(&drive->queue, tag); rq = blk_queue_find_tag(&drive->queue, tag);
if (!rq) { if (!rq) {
printk(KERN_ERR"%s: missing request for tag %d\n", __FUNCTION__, tag); printk(KERN_ERR"%s: missing request for tag %d\n", __FUNCTION__, tag);
return ide_stopped; return ide_stopped;
......
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