diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2007-07-16 02:52:16 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2007-07-16 02:52:47 -0400 |
commit | 15d10b611fa94b52f004a08a1d4cf7b39de3cba3 (patch) | |
tree | 39b1e114689b71d37677e9733428b355d52d4e44 /block/bsg.c | |
parent | 2c9ecdf40af0554ee9a2b1cbbbbdbc77f90a40e1 (diff) |
bsg: add SCSI transport-level request support
This enables bsg to handle SCSI transport-level request like SAS
management protocol (SMP).
- add BSG_SUB_PROTOCOL_{SCSI_CMD, SCSI_TMF, SCSI_TRANSPORT} definitions.
- SCSI transport-level requests skip blk_verify_command().
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block/bsg.c')
-rw-r--r-- | block/bsg.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/block/bsg.c b/block/bsg.c index 13ecc951a4c0..461c9f56f3ee 100644 --- a/block/bsg.c +++ b/block/bsg.c | |||
@@ -208,7 +208,11 @@ static int blk_fill_sgv4_hdr_rq(request_queue_t *q, struct request *rq, | |||
208 | if (copy_from_user(rq->cmd, (void *)(unsigned long)hdr->request, | 208 | if (copy_from_user(rq->cmd, (void *)(unsigned long)hdr->request, |
209 | hdr->request_len)) | 209 | hdr->request_len)) |
210 | return -EFAULT; | 210 | return -EFAULT; |
211 | if (blk_verify_command(rq->cmd, has_write_perm)) | 211 | |
212 | if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { | ||
213 | if (blk_verify_command(rq->cmd, has_write_perm)) | ||
214 | return -EPERM; | ||
215 | } else if (!capable(CAP_SYS_RAWIO)) | ||
212 | return -EPERM; | 216 | return -EPERM; |
213 | 217 | ||
214 | /* | 218 | /* |
@@ -232,6 +236,8 @@ static int blk_fill_sgv4_hdr_rq(request_queue_t *q, struct request *rq, | |||
232 | static int | 236 | static int |
233 | bsg_validate_sgv4_hdr(request_queue_t *q, struct sg_io_v4 *hdr, int *rw) | 237 | bsg_validate_sgv4_hdr(request_queue_t *q, struct sg_io_v4 *hdr, int *rw) |
234 | { | 238 | { |
239 | int ret = 0; | ||
240 | |||
235 | if (hdr->guard != 'Q') | 241 | if (hdr->guard != 'Q') |
236 | return -EINVAL; | 242 | return -EINVAL; |
237 | if (hdr->request_len > BLK_MAX_CDB) | 243 | if (hdr->request_len > BLK_MAX_CDB) |
@@ -240,13 +246,22 @@ bsg_validate_sgv4_hdr(request_queue_t *q, struct sg_io_v4 *hdr, int *rw) | |||
240 | hdr->din_xfer_len > (q->max_sectors << 9)) | 246 | hdr->din_xfer_len > (q->max_sectors << 9)) |
241 | return -EIO; | 247 | return -EIO; |
242 | 248 | ||
243 | /* not supported currently */ | 249 | switch (hdr->protocol) { |
244 | if (hdr->protocol || hdr->subprotocol) | 250 | case BSG_PROTOCOL_SCSI: |
245 | return -EINVAL; | 251 | switch (hdr->subprotocol) { |
252 | case BSG_SUB_PROTOCOL_SCSI_CMD: | ||
253 | case BSG_SUB_PROTOCOL_SCSI_TRANSPORT: | ||
254 | break; | ||
255 | default: | ||
256 | ret = -EINVAL; | ||
257 | } | ||
258 | break; | ||
259 | default: | ||
260 | ret = -EINVAL; | ||
261 | } | ||
246 | 262 | ||
247 | *rw = hdr->dout_xfer_len ? WRITE : READ; | 263 | *rw = hdr->dout_xfer_len ? WRITE : READ; |
248 | 264 | return ret; | |
249 | return 0; | ||
250 | } | 265 | } |
251 | 266 | ||
252 | /* | 267 | /* |