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