| 
					
				 | 
			
			
				@@ -13,3 +13,64 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * 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(struct request_queue *q, int tag) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return blk_map_queue_find_tag(q->queue_tags, tag); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+EXPORT_SYMBOL(blk_queue_find_tag); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * __blk_free_tags - release a given set of tag maintenance info 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @bqt:	the tag map to free 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Tries to free the specified @bqt.  Returns true if it was 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * actually freed and false if there are still references using it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static int __blk_free_tags(struct blk_queue_tag *bqt) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int retval; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	retval = atomic_dec_and_test(&bqt->refcnt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (retval) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		BUG_ON(find_first_bit(bqt->tag_map, bqt->max_depth) < 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							bqt->max_depth); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		kfree(bqt->tag_index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		bqt->tag_index = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		kfree(bqt->tag_map); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		bqt->tag_map = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		kfree(bqt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return retval; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * __blk_queue_free_tags - release tag maintenance info 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @q:  the request queue for the device 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  Notes: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *    blk_cleanup_queue() will take care of calling this function, if tagging 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *    has been used. So there's no need to call this directly. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ **/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void __blk_queue_free_tags(struct request_queue *q) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct blk_queue_tag *bqt = q->queue_tags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!bqt) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__blk_free_tags(bqt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	q->queue_tags = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |