1#ifndef _SCSI_SCSI_TCQ_H
2#define _SCSI_SCSI_TCQ_H
3
4#include <linux/blkdev.h>
5#include <scsi/scsi_cmnd.h>
6#include <scsi/scsi_device.h>
7#include <scsi/scsi_host.h>
8
9#define SCSI_NO_TAG	(-1)    /* identify no tag in use */
10
11
12#ifdef CONFIG_BLOCK
13static inline struct scsi_cmnd *scsi_mq_find_tag(struct Scsi_Host *shost,
14						 int unique_tag)
15{
16	u16 hwq = blk_mq_unique_tag_to_hwq(unique_tag);
17	struct request *req = NULL;
18
19	if (hwq < shost->tag_set.nr_hw_queues)
20		req = blk_mq_tag_to_rq(shost->tag_set.tags[hwq],
21				       blk_mq_unique_tag_to_tag(unique_tag));
22	return req ? (struct scsi_cmnd *)req->special : NULL;
23}
24
25/**
26 * scsi_find_tag - find a tagged command by device
27 * @SDpnt:	pointer to the ScSI device
28 * @tag:	tag generated by blk_mq_unique_tag()
29 *
30 * Notes:
31 *	Only works with tags allocated by the generic blk layer.
32 **/
33static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag)
34{
35        struct request *req;
36
37        if (tag != SCSI_NO_TAG) {
38		if (shost_use_blk_mq(sdev->host))
39			return scsi_mq_find_tag(sdev->host, tag);
40
41		req = blk_queue_find_tag(sdev->request_queue, tag);
42	        return req ? (struct scsi_cmnd *)req->special : NULL;
43	}
44
45	/* single command, look in space */
46	return sdev->current_cmnd;
47}
48
49
50/**
51 * scsi_init_shared_tag_map - create a shared tag map
52 * @shost:	the host to share the tag map among all devices
53 * @depth:	the total depth of the map
54 */
55static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth)
56{
57	/*
58	 * We always have a shared tag map around when using blk-mq.
59	 */
60	if (shost_use_blk_mq(shost))
61		return 0;
62
63	/*
64	 * If the shared tag map isn't already initialized, do it now.
65	 * This saves callers from having to check ->bqt when setting up
66	 * devices on the shared host (for libata)
67	 */
68	if (!shost->bqt) {
69		shost->bqt = blk_init_tags(depth,
70			shost->hostt->tag_alloc_policy);
71		if (!shost->bqt)
72			return -ENOMEM;
73	}
74
75	return 0;
76}
77
78/**
79 * scsi_host_find_tag - find the tagged command by host
80 * @shost:	pointer to scsi_host
81 * @tag:	tag generated by blk_mq_unique_tag()
82 *
83 * Notes:
84 *	Only works with tags allocated by the generic blk layer.
85 **/
86static inline struct scsi_cmnd *scsi_host_find_tag(struct Scsi_Host *shost,
87						int tag)
88{
89	struct request *req;
90
91	if (tag != SCSI_NO_TAG) {
92		if (shost_use_blk_mq(shost))
93			return scsi_mq_find_tag(shost, tag);
94		req = blk_map_queue_find_tag(shost->bqt, tag);
95		return req ? (struct scsi_cmnd *)req->special : NULL;
96	}
97	return NULL;
98}
99
100#endif /* CONFIG_BLOCK */
101#endif /* _SCSI_SCSI_TCQ_H */
102