xref: /linux/include/scsi/scsi_tcq.h (revision 957e3facd147510f2cf8780e38606f1d707f0e33)
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 MSG_SIMPLE_TAG	0x20
10 #define MSG_HEAD_TAG	0x21
11 #define MSG_ORDERED_TAG	0x22
12 #define MSG_ACA_TAG	0x24	/* unsupported */
13 
14 #define SCSI_NO_TAG	(-1)    /* identify no tag in use */
15 
16 
17 #ifdef CONFIG_BLOCK
18 
19 int scsi_change_queue_type(struct scsi_device *sdev, int tag_type);
20 
21 /**
22  * scsi_get_tag_type - get the type of tag the device supports
23  * @sdev:	the scsi device
24  */
25 static inline int scsi_get_tag_type(struct scsi_device *sdev)
26 {
27 	if (!sdev->tagged_supported)
28 		return 0;
29 	if (sdev->simple_tags)
30 		return MSG_SIMPLE_TAG;
31 	return 0;
32 }
33 
34 static inline void scsi_set_tag_type(struct scsi_device *sdev, int tag)
35 {
36 	switch (tag) {
37 	case MSG_ORDERED_TAG:
38 	case MSG_SIMPLE_TAG:
39 		sdev->simple_tags = 1;
40 		break;
41 	case 0:
42 		/* fall through */
43 	default:
44 		sdev->simple_tags = 0;
45 		break;
46 	}
47 }
48 
49 static inline struct scsi_cmnd *scsi_mq_find_tag(struct Scsi_Host *shost,
50 						 int unique_tag)
51 {
52 	u16 hwq = blk_mq_unique_tag_to_hwq(unique_tag);
53 	struct request *req = NULL;
54 
55 	if (hwq < shost->tag_set.nr_hw_queues)
56 		req = blk_mq_tag_to_rq(shost->tag_set.tags[hwq],
57 				       blk_mq_unique_tag_to_tag(unique_tag));
58 	return req ? (struct scsi_cmnd *)req->special : NULL;
59 }
60 
61 /**
62  * scsi_find_tag - find a tagged command by device
63  * @SDpnt:	pointer to the ScSI device
64  * @tag:	tag generated by blk_mq_unique_tag()
65  *
66  * Notes:
67  *	Only works with tags allocated by the generic blk layer.
68  **/
69 static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag)
70 {
71         struct request *req;
72 
73         if (tag != SCSI_NO_TAG) {
74 		if (shost_use_blk_mq(sdev->host))
75 			return scsi_mq_find_tag(sdev->host, tag);
76 
77 		req = blk_queue_find_tag(sdev->request_queue, tag);
78 	        return req ? (struct scsi_cmnd *)req->special : NULL;
79 	}
80 
81 	/* single command, look in space */
82 	return sdev->current_cmnd;
83 }
84 
85 
86 /**
87  * scsi_init_shared_tag_map - create a shared tag map
88  * @shost:	the host to share the tag map among all devices
89  * @depth:	the total depth of the map
90  */
91 static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth)
92 {
93 	/*
94 	 * We always have a shared tag map around when using blk-mq.
95 	 */
96 	if (shost_use_blk_mq(shost))
97 		return 0;
98 
99 	/*
100 	 * If the shared tag map isn't already initialized, do it now.
101 	 * This saves callers from having to check ->bqt when setting up
102 	 * devices on the shared host (for libata)
103 	 */
104 	if (!shost->bqt) {
105 		shost->bqt = blk_init_tags(depth);
106 		if (!shost->bqt)
107 			return -ENOMEM;
108 	}
109 
110 	return 0;
111 }
112 
113 /**
114  * scsi_host_find_tag - find the tagged command by host
115  * @shost:	pointer to scsi_host
116  * @tag:	tag generated by blk_mq_unique_tag()
117  *
118  * Notes:
119  *	Only works with tags allocated by the generic blk layer.
120  **/
121 static inline struct scsi_cmnd *scsi_host_find_tag(struct Scsi_Host *shost,
122 						int tag)
123 {
124 	struct request *req;
125 
126 	if (tag != SCSI_NO_TAG) {
127 		if (shost_use_blk_mq(shost))
128 			return scsi_mq_find_tag(shost, tag);
129 		req = blk_map_queue_find_tag(shost->bqt, tag);
130 		return req ? (struct scsi_cmnd *)req->special : NULL;
131 	}
132 	return NULL;
133 }
134 
135 #endif /* CONFIG_BLOCK */
136 #endif /* _SCSI_SCSI_TCQ_H */
137