Commit | Line | Data |
---|---|---|
1da177e4 LT |
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> | |
86e33a29 | 7 | #include <scsi/scsi_host.h> |
1da177e4 | 8 | |
1da177e4 LT |
9 | #define MSG_SIMPLE_TAG 0x20 |
10 | #define MSG_HEAD_TAG 0x21 | |
11 | #define MSG_ORDERED_TAG 0x22 | |
e66ecd50 | 12 | #define MSG_ACA_TAG 0x24 /* unsupported */ |
1da177e4 LT |
13 | |
14 | #define SCSI_NO_TAG (-1) /* identify no tag in use */ | |
15 | ||
16 | ||
9361401e | 17 | #ifdef CONFIG_BLOCK |
1da177e4 | 18 | |
a62182f3 CH |
19 | int scsi_change_queue_type(struct scsi_device *sdev, int tag_type); |
20 | ||
1da177e4 LT |
21 | /** |
22 | * scsi_get_tag_type - get the type of tag the device supports | |
23 | * @sdev: the scsi device | |
1da177e4 LT |
24 | */ |
25 | static inline int scsi_get_tag_type(struct scsi_device *sdev) | |
26 | { | |
27 | if (!sdev->tagged_supported) | |
28 | return 0; | |
1da177e4 LT |
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: | |
1da177e4 LT |
38 | case MSG_SIMPLE_TAG: |
39 | sdev->simple_tags = 1; | |
40 | break; | |
41 | case 0: | |
42 | /* fall through */ | |
43 | default: | |
1da177e4 LT |
44 | sdev->simple_tags = 0; |
45 | break; | |
46 | } | |
47 | } | |
1da177e4 | 48 | |
d285203c | 49 | static inline struct scsi_cmnd *scsi_mq_find_tag(struct Scsi_Host *shost, |
1ee8e889 | 50 | int unique_tag) |
d285203c | 51 | { |
1ee8e889 BVA |
52 | u16 hwq = blk_mq_unique_tag_to_hwq(unique_tag); |
53 | struct request *req = NULL; | |
d285203c | 54 | |
1ee8e889 BVA |
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)); | |
d285203c CH |
58 | return req ? (struct scsi_cmnd *)req->special : NULL; |
59 | } | |
60 | ||
1da177e4 LT |
61 | /** |
62 | * scsi_find_tag - find a tagged command by device | |
63 | * @SDpnt: pointer to the ScSI device | |
1ee8e889 | 64 | * @tag: tag generated by blk_mq_unique_tag() |
1da177e4 LT |
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 | { | |
1da177e4 LT |
71 | struct request *req; |
72 | ||
73 | if (tag != SCSI_NO_TAG) { | |
d285203c | 74 | if (shost_use_blk_mq(sdev->host)) |
1ee8e889 | 75 | return scsi_mq_find_tag(sdev->host, tag); |
d285203c | 76 | |
1ee8e889 | 77 | req = blk_queue_find_tag(sdev->request_queue, tag); |
1da177e4 LT |
78 | return req ? (struct scsi_cmnd *)req->special : NULL; |
79 | } | |
80 | ||
81 | /* single command, look in space */ | |
82 | return sdev->current_cmnd; | |
83 | } | |
84 | ||
d285203c | 85 | |
86e33a29 JB |
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 | */ | |
deb81d80 | 91 | static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth) |
86e33a29 | 92 | { |
d285203c CH |
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 | ||
3070f69b JA |
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; | |
86e33a29 JB |
111 | } |
112 | ||
f583f492 DS |
113 | /** |
114 | * scsi_host_find_tag - find the tagged command by host | |
115 | * @shost: pointer to scsi_host | |
1ee8e889 | 116 | * @tag: tag generated by blk_mq_unique_tag() |
f583f492 DS |
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) { | |
d285203c | 127 | if (shost_use_blk_mq(shost)) |
1ee8e889 | 128 | return scsi_mq_find_tag(shost, tag); |
f583f492 DS |
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 | ||
9361401e | 135 | #endif /* CONFIG_BLOCK */ |
1da177e4 | 136 | #endif /* _SCSI_SCSI_TCQ_H */ |