Blame view

include/scsi/scsi_tcq.h 4.15 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
  #ifndef _SCSI_SCSI_TCQ_H
  #define _SCSI_SCSI_TCQ_H
  
  #include <linux/blkdev.h>
  #include <scsi/scsi_cmnd.h>
  #include <scsi/scsi_device.h>
86e33a296   James Bottomley   [SCSI] add shared...
7
  #include <scsi/scsi_host.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
11
  #define MSG_SIMPLE_TAG	0x20
  #define MSG_HEAD_TAG	0x21
  #define MSG_ORDERED_TAG	0x22
e66ecd505   Nicholas Bellinger   [SCSI] target: Co...
12
  #define MSG_ACA_TAG	0x24	/* unsupported */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
  
  #define SCSI_NO_TAG	(-1)    /* identify no tag in use */
9361401eb   David Howells   [PATCH] BLOCK: Ma...
15
  #ifdef CONFIG_BLOCK
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  
  /**
   * scsi_get_tag_type - get the type of tag the device supports
   * @sdev:	the scsi device
   *
   * Notes:
   *	If the drive only supports simple tags, returns MSG_SIMPLE_TAG
   *	if it supports all tag types, returns MSG_ORDERED_TAG.
   */
  static inline int scsi_get_tag_type(struct scsi_device *sdev)
  {
  	if (!sdev->tagged_supported)
  		return 0;
  	if (sdev->ordered_tags)
  		return MSG_ORDERED_TAG;
  	if (sdev->simple_tags)
  		return MSG_SIMPLE_TAG;
  	return 0;
  }
  
  static inline void scsi_set_tag_type(struct scsi_device *sdev, int tag)
  {
  	switch (tag) {
  	case MSG_ORDERED_TAG:
  		sdev->ordered_tags = 1;
  		/* fall through */
  	case MSG_SIMPLE_TAG:
  		sdev->simple_tags = 1;
  		break;
  	case 0:
  		/* fall through */
  	default:
  		sdev->ordered_tags = 0;
  		sdev->simple_tags = 0;
  		break;
  	}
  }
  /**
   * scsi_activate_tcq - turn on tag command queueing
   * @SDpnt:	device to turn on TCQ for
   * @depth:	queue depth
   *
   * Notes:
   *	Eventually, I hope depth would be the maximum depth
   *	the device could cope with and the real queue depth
   *	would be adjustable from 0 to depth.
   **/
  static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth)
  {
  	if (!sdev->tagged_supported)
  		return;
  
  	if (!blk_queue_tagged(sdev->request_queue))
86e33a296   James Bottomley   [SCSI] add shared...
69
70
  		blk_queue_init_tags(sdev->request_queue, depth,
  				    sdev->host->bqt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  
  	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
  }
  
  /**
   * scsi_deactivate_tcq - turn off tag command queueing
   * @SDpnt:	device to turn off TCQ for
   **/
  static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
  {
  	if (blk_queue_tagged(sdev->request_queue))
  		blk_queue_free_tags(sdev->request_queue);
  	scsi_adjust_queue_depth(sdev, 0, depth);
  }
  
  /**
   * scsi_populate_tag_msg - place a tag message in a buffer
   * @SCpnt:	pointer to the Scsi_Cmnd for the tag
   * @msg:	pointer to the area to place the tag
   *
   * Notes:
   *	designed to create the correct type of tag message for the 
   *	particular request.  Returns the size of the tag message.
   *	May return 0 if TCQ is disabled for this device.
   **/
  static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg)
  {
          struct request *req = cmd->request;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
100
  
          if (blk_rq_tagged(req)) {
9cbbdca44   Tejun Heo   block: remove spu...
101
  		*msg++ = MSG_SIMPLE_TAG;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
          	*msg++ = req->tag;
          	return 2;
  	}
  
  	return 0;
  }
  
  /**
   * scsi_find_tag - find a tagged command by device
   * @SDpnt:	pointer to the ScSI device
   * @tag:	the tag number
   *
   * 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) {
          	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;
  }
86e33a296   James Bottomley   [SCSI] add shared...
130
131
132
133
134
  /**
   * 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
   */
deb81d80b   James Bottomley   [SCSI] add failur...
135
  static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth)
86e33a296   James Bottomley   [SCSI] add shared...
136
  {
3070f69b6   Jens Axboe   scsi: make sure t...
137
138
139
140
141
142
143
144
145
146
147
148
  	/*
  	 * 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);
  		if (!shost->bqt)
  			return -ENOMEM;
  	}
  
  	return 0;
86e33a296   James Bottomley   [SCSI] add shared...
149
  }
f583f4924   David C Somayajulu   [PATCH] helper fu...
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
  /**
   * scsi_host_find_tag - find the tagged command by host
   * @shost:	pointer to scsi_host
   * @tag:	tag of the scsi_cmnd
   *
   * 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) {
  		req = blk_map_queue_find_tag(shost->bqt, tag);
  		return req ? (struct scsi_cmnd *)req->special : NULL;
  	}
  	return NULL;
  }
9361401eb   David Howells   [PATCH] BLOCK: Ma...
169
  #endif /* CONFIG_BLOCK */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
  #endif /* _SCSI_SCSI_TCQ_H */