aboutsummaryrefslogblamecommitdiffstats
path: root/include/scsi/scsi_tcq.h
blob: b27977e8aaed9b12bf6497fbdf01879a47b26cbc (plain) (tree)
1
2
3
4
5
6
7
8





                             
                           
 


                                                            
                   
                                                                         
                                                                
 

                                                       
 


                                                                             


                                                             


                                                  
                                                    





                                                                                


                                 
                                                 
                                                                 
 
                                                                   






                                                                     
 




                                                               
                                                                              
 
          





                                                                    




                                                                        

                                                        




                                       

 


                                                       
                                                    









                                                                           
                                            
                                                            





                                                                     
                         
                             
#ifndef _SCSI_SCSI_TCQ_H
#define _SCSI_SCSI_TCQ_H

#include <linux/blkdev.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>

#define SCSI_NO_TAG	(-1)    /* identify no tag in use */


#ifdef CONFIG_BLOCK
static inline struct scsi_cmnd *scsi_mq_find_tag(struct Scsi_Host *shost,
						 int unique_tag)
{
	u16 hwq = blk_mq_unique_tag_to_hwq(unique_tag);
	struct request *req = NULL;

	if (hwq < shost->tag_set.nr_hw_queues)
		req = blk_mq_tag_to_rq(shost->tag_set.tags[hwq],
				       blk_mq_unique_tag_to_tag(unique_tag));
	return req ? (struct scsi_cmnd *)req->special : NULL;
}

/**
 * scsi_find_tag - find a tagged command by device
 * @SDpnt:	pointer to the ScSI device
 * @tag:	tag generated by blk_mq_unique_tag()
 *
 * Notes:
 *	Only works with tags allocated by the generic blk layer.
 **/
static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag)
{
        struct request *req;

        if (tag != SCSI_NO_TAG) {
		if (shost_use_blk_mq(sdev->host))
			return scsi_mq_find_tag(sdev->host, tag);

		req = blk_queue_find_tag(sdev->request_queue, tag);
	        return req ? (struct scsi_cmnd *)req->special : NULL;
	}

	/* single command, look in space */
	return sdev->current_cmnd;
}


/**
 * scsi_init_shared_tag_map - create a shared tag map
 * @shost:	the host to share the tag map among all devices
 * @depth:	the total depth of the map
 */
static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth)
{
	/*
	 * We always have a shared tag map around when using blk-mq.
	 */
	if (shost_use_blk_mq(shost))
		return 0;

	/*
	 * If the shared tag map isn't already initialized, do it now.
	 * This saves callers from having to check ->bqt when setting up
	 * devices on the shared host (for libata)
	 */
	if (!shost->bqt) {
		shost->bqt = blk_init_tags(depth,
			shost->hostt->tag_alloc_policy);
		if (!shost->bqt)
			return -ENOMEM;
	}

	return 0;
}

/**
 * scsi_host_find_tag - find the tagged command by host
 * @shost:	pointer to scsi_host
 * @tag:	tag generated by blk_mq_unique_tag()
 *
 * Notes:
 *	Only works with tags allocated by the generic blk layer.
 **/
static inline struct scsi_cmnd *scsi_host_find_tag(struct Scsi_Host *shost,
						int tag)
{
	struct request *req;

	if (tag != SCSI_NO_TAG) {
		if (shost_use_blk_mq(shost))
			return scsi_mq_find_tag(shost, tag);
		req = blk_map_queue_find_tag(shost->bqt, tag);
		return req ? (struct scsi_cmnd *)req->special : NULL;
	}
	return NULL;
}

#endif /* CONFIG_BLOCK */
#endif /* _SCSI_SCSI_TCQ_H */