aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrking@us.ibm.com <brking@us.ibm.com>2006-01-23 16:03:22 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2006-01-26 15:13:50 -0500
commitbb1d1073a10fdc8547e3eb821ee2488260094b39 (patch)
tree139a30834cea40e0d967506cfdaea603cf56a192
parent15084a4a63bc300c18b28a8a9afac870c552abce (diff)
[SCSI] Prevent scsi_execute_async from guessing cdb length
When the scsi_execute_async interface was added it ended up reducing the flexibility of userspace to send arbitrary scsi commands through sg using SG_IO. The SG_IO interface allows userspace to specify the CDB length. This is now ignored in scsi_execute_async and it is guessed using the COMMAND_SIZE macro, which is not always correct, particularly for vendor specific commands. This patch adds a cmd_len parameter to the scsi_execute_async interface to allow the caller to specify the length of the CDB. Signed-off-by: Brian King <brking@us.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/scsi_error.c2
-rw-r--r--drivers/scsi/scsi_lib.c5
-rw-r--r--drivers/scsi/sg.c2
-rw-r--r--drivers/scsi/st.c2
-rw-r--r--include/scsi/scsi_device.h2
5 files changed, 7 insertions, 6 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index a2333d2c7af..5cc97b72166 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1350,7 +1350,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
1350 cmnd[4] = SCSI_REMOVAL_PREVENT; 1350 cmnd[4] = SCSI_REMOVAL_PREVENT;
1351 cmnd[5] = 0; 1351 cmnd[5] = 0;
1352 1352
1353 scsi_execute_async(sdev, cmnd, DMA_NONE, NULL, 0, 0, 10 * HZ, 1353 scsi_execute_async(sdev, cmnd, 6, DMA_NONE, NULL, 0, 0, 10 * HZ,
1354 5, NULL, NULL, GFP_KERNEL); 1354 5, NULL, NULL, GFP_KERNEL);
1355} 1355}
1356 1356
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 3574ba935af..4a602853a98 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -436,6 +436,7 @@ free_bios:
436 * scsi_execute_async - insert request 436 * scsi_execute_async - insert request
437 * @sdev: scsi device 437 * @sdev: scsi device
438 * @cmd: scsi command 438 * @cmd: scsi command
439 * @cmd_len: length of scsi cdb
439 * @data_direction: data direction 440 * @data_direction: data direction
440 * @buffer: data buffer (this can be a kernel buffer or scatterlist) 441 * @buffer: data buffer (this can be a kernel buffer or scatterlist)
441 * @bufflen: len of buffer 442 * @bufflen: len of buffer
@@ -445,7 +446,7 @@ free_bios:
445 * @flags: or into request flags 446 * @flags: or into request flags
446 **/ 447 **/
447int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, 448int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd,
448 int data_direction, void *buffer, unsigned bufflen, 449 int cmd_len, int data_direction, void *buffer, unsigned bufflen,
449 int use_sg, int timeout, int retries, void *privdata, 450 int use_sg, int timeout, int retries, void *privdata,
450 void (*done)(void *, char *, int, int), gfp_t gfp) 451 void (*done)(void *, char *, int, int), gfp_t gfp)
451{ 452{
@@ -472,7 +473,7 @@ int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd,
472 if (err) 473 if (err)
473 goto free_req; 474 goto free_req;
474 475
475 req->cmd_len = COMMAND_SIZE(cmd[0]); 476 req->cmd_len = cmd_len;
476 memcpy(req->cmd, cmd, req->cmd_len); 477 memcpy(req->cmd, cmd, req->cmd_len);
477 req->sense = sioc->sense; 478 req->sense = sioc->sense;
478 req->sense_len = 0; 479 req->sense_len = 0;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 78aad9582bc..7d0700091f3 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -741,7 +741,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
741 hp->duration = jiffies_to_msecs(jiffies); 741 hp->duration = jiffies_to_msecs(jiffies);
742/* Now send everything of to mid-level. The next time we hear about this 742/* Now send everything of to mid-level. The next time we hear about this
743 packet is when sg_cmd_done() is called (i.e. a callback). */ 743 packet is when sg_cmd_done() is called (i.e. a callback). */
744 if (scsi_execute_async(sdp->device, cmnd, data_dir, srp->data.buffer, 744 if (scsi_execute_async(sdp->device, cmnd, hp->cmd_len, data_dir, srp->data.buffer,
745 hp->dxfer_len, srp->data.k_use_sg, timeout, 745 hp->dxfer_len, srp->data.k_use_sg, timeout,
746 SG_DEFAULT_RETRIES, srp, sg_cmd_done, 746 SG_DEFAULT_RETRIES, srp, sg_cmd_done,
747 GFP_ATOMIC)) { 747 GFP_ATOMIC)) {
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 13b1d3aac26..7f96f33c1bb 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -508,7 +508,7 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd
508 STp->buffer->cmdstat.have_sense = 0; 508 STp->buffer->cmdstat.have_sense = 0;
509 STp->buffer->syscall_result = 0; 509 STp->buffer->syscall_result = 0;
510 510
511 if (scsi_execute_async(STp->device, cmd, direction, 511 if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction,
512 &((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs, 512 &((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs,
513 timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) { 513 timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) {
514 /* could not allocate the buffer or request was too large */ 514 /* could not allocate the buffer or request was too large */
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index e94ca4d3603..290e3b4d2ae 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -275,7 +275,7 @@ extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
275 int data_direction, void *buffer, unsigned bufflen, 275 int data_direction, void *buffer, unsigned bufflen,
276 struct scsi_sense_hdr *, int timeout, int retries); 276 struct scsi_sense_hdr *, int timeout, int retries);
277extern int scsi_execute_async(struct scsi_device *sdev, 277extern int scsi_execute_async(struct scsi_device *sdev,
278 const unsigned char *cmd, int data_direction, 278 const unsigned char *cmd, int cmd_len, int data_direction,
279 void *buffer, unsigned bufflen, int use_sg, 279 void *buffer, unsigned bufflen, int use_sg,
280 int timeout, int retries, void *privdata, 280 int timeout, int retries, void *privdata,
281 void (*done)(void *, char *, int, int), 281 void (*done)(void *, char *, int, int),