aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2008-04-30 04:27:26 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-05-02 12:33:25 -0400
commitdb4742dd8f0aa9125b74f9b2516336a75f3d9106 (patch)
tree6820b74e8fbfb13c4eee4c8ef8b59a9132320799
parent64a87b244b9297667ca80264aab849a36f494884 (diff)
[SCSI] add support for variable length extended commands
Add support for variable-length, extended, and vendor specific CDBs to scsi-ml. It is now possible for initiators and ULD's to issue these types of commands. LLDs need not change much. All they need is to raise the .max_cmd_len to the longest command they support (see iscsi patch). - clean-up some code paths that did not expect commands to be larger than 16, and change cmd_len members' type to short as char is not enough. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--block/scsi_ioctl.c5
-rw-r--r--drivers/scsi/constants.c10
-rw-r--r--drivers/scsi/scsi.c15
-rw-r--r--drivers/scsi/scsi_lib.c2
-rw-r--r--include/scsi/scsi.h40
-rw-r--r--include/scsi/scsi_cmnd.h2
-rw-r--r--include/scsi/scsi_host.h8
7 files changed, 47 insertions, 35 deletions
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index a2c3a936ebf9..aaf07e413ffd 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -33,13 +33,12 @@
33#include <scsi/scsi_cmnd.h> 33#include <scsi/scsi_cmnd.h>
34 34
35/* Command group 3 is reserved and should never be used. */ 35/* Command group 3 is reserved and should never be used. */
36const unsigned char scsi_command_size[8] = 36const unsigned char scsi_command_size_tbl[8] =
37{ 37{
38 6, 10, 10, 12, 38 6, 10, 10, 12,
39 16, 12, 10, 10 39 16, 12, 10, 10
40}; 40};
41 41EXPORT_SYMBOL(scsi_command_size_tbl);
42EXPORT_SYMBOL(scsi_command_size);
43 42
44#include <scsi/sg.h> 43#include <scsi/sg.h>
45 44
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index 403a7f2d8f9b..9785d7384199 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -28,7 +28,6 @@
28#define SERVICE_ACTION_OUT_12 0xa9 28#define SERVICE_ACTION_OUT_12 0xa9
29#define SERVICE_ACTION_IN_16 0x9e 29#define SERVICE_ACTION_IN_16 0x9e
30#define SERVICE_ACTION_OUT_16 0x9f 30#define SERVICE_ACTION_OUT_16 0x9f
31#define VARIABLE_LENGTH_CMD 0x7f
32 31
33 32
34 33
@@ -210,7 +209,7 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
210 cdb0 = cdbp[0]; 209 cdb0 = cdbp[0];
211 switch(cdb0) { 210 switch(cdb0) {
212 case VARIABLE_LENGTH_CMD: 211 case VARIABLE_LENGTH_CMD:
213 len = cdbp[7] + 8; 212 len = scsi_varlen_cdb_length(cdbp);
214 if (len < 10) { 213 if (len < 10) {
215 printk("short variable length command, " 214 printk("short variable length command, "
216 "len=%d ext_len=%d", len, cdb_len); 215 "len=%d ext_len=%d", len, cdb_len);
@@ -300,7 +299,7 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
300 cdb0 = cdbp[0]; 299 cdb0 = cdbp[0];
301 switch(cdb0) { 300 switch(cdb0) {
302 case VARIABLE_LENGTH_CMD: 301 case VARIABLE_LENGTH_CMD:
303 len = cdbp[7] + 8; 302 len = scsi_varlen_cdb_length(cdbp);
304 if (len < 10) { 303 if (len < 10) {
305 printk("short opcode=0x%x command, len=%d " 304 printk("short opcode=0x%x command, len=%d "
306 "ext_len=%d", cdb0, len, cdb_len); 305 "ext_len=%d", cdb0, len, cdb_len);
@@ -335,10 +334,7 @@ void __scsi_print_command(unsigned char *cdb)
335 int k, len; 334 int k, len;
336 335
337 print_opcode_name(cdb, 0); 336 print_opcode_name(cdb, 0);
338 if (VARIABLE_LENGTH_CMD == cdb[0]) 337 len = scsi_command_size(cdb);
339 len = cdb[7] + 8;
340 else
341 len = COMMAND_SIZE(cdb[0]);
342 /* print out all bytes in cdb */ 338 /* print out all bytes in cdb */
343 for (k = 0; k < len; ++k) 339 for (k = 0; k < len; ++k)
344 printk(" %02x", cdb[k]); 340 printk(" %02x", cdb[k]);
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 749c9c7fc2e1..110e776d1a07 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -79,15 +79,6 @@ static void scsi_done(struct scsi_cmnd *cmd);
79#define MIN_RESET_PERIOD (15*HZ) 79#define MIN_RESET_PERIOD (15*HZ)
80 80
81/* 81/*
82 * Macro to determine the size of SCSI command. This macro takes vendor
83 * unique commands into account. SCSI commands in groups 6 and 7 are
84 * vendor unique and we will depend upon the command length being
85 * supplied correctly in cmd_len.
86 */
87#define CDB_SIZE(cmd) (((((cmd)->cmnd[0] >> 5) & 7) < 6) ? \
88 COMMAND_SIZE((cmd)->cmnd[0]) : (cmd)->cmd_len)
89
90/*
91 * Note - the initial logging level can be set here to log events at boot time. 82 * Note - the initial logging level can be set here to log events at boot time.
92 * After the system is up, you may enable logging via the /proc interface. 83 * After the system is up, you may enable logging via the /proc interface.
93 */ 84 */
@@ -709,9 +700,11 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
709 * Before we queue this command, check if the command 700 * Before we queue this command, check if the command
710 * length exceeds what the host adapter can handle. 701 * length exceeds what the host adapter can handle.
711 */ 702 */
712 if (CDB_SIZE(cmd) > cmd->device->host->max_cmd_len) { 703 if (cmd->cmd_len > cmd->device->host->max_cmd_len) {
713 SCSI_LOG_MLQUEUE(3, 704 SCSI_LOG_MLQUEUE(3,
714 printk("queuecommand : command too long.\n")); 705 printk("queuecommand : command too long. "
706 "cdb_size=%d host->max_cmd_len=%d\n",
707 cmd->cmd_len, cmd->device->host->max_cmd_len));
715 cmd->result = (DID_ABORT << 16); 708 cmd->result = (DID_ABORT << 16);
716 709
717 scsi_done(cmd); 710 scsi_done(cmd);
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 325270b520e1..ba7e8ad76d04 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -445,7 +445,7 @@ static void scsi_init_cmd_errh(struct scsi_cmnd *cmd)
445 scsi_set_resid(cmd, 0); 445 scsi_set_resid(cmd, 0);
446 memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); 446 memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
447 if (cmd->cmd_len == 0) 447 if (cmd->cmd_len == 0)
448 cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); 448 cmd->cmd_len = scsi_command_size(cmd->cmnd);
449} 449}
450 450
451void scsi_device_unbusy(struct scsi_device *sdev) 451void scsi_device_unbusy(struct scsi_device *sdev)
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 1f74bcd603fe..32742c4563de 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -30,13 +30,6 @@
30#endif 30#endif
31 31
32/* 32/*
33 * SCSI command lengths
34 */
35
36extern const unsigned char scsi_command_size[8];
37#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7]
38
39/*
40 * Special value for scanning to specify scanning or rescanning of all 33 * Special value for scanning to specify scanning or rescanning of all
41 * possible channels, (target) ids, or luns on a given shost. 34 * possible channels, (target) ids, or luns on a given shost.
42 */ 35 */
@@ -109,6 +102,7 @@ extern const unsigned char scsi_command_size[8];
109#define MODE_SENSE_10 0x5a 102#define MODE_SENSE_10 0x5a
110#define PERSISTENT_RESERVE_IN 0x5e 103#define PERSISTENT_RESERVE_IN 0x5e
111#define PERSISTENT_RESERVE_OUT 0x5f 104#define PERSISTENT_RESERVE_OUT 0x5f
105#define VARIABLE_LENGTH_CMD 0x7f
112#define REPORT_LUNS 0xa0 106#define REPORT_LUNS 0xa0
113#define MAINTENANCE_IN 0xa3 107#define MAINTENANCE_IN 0xa3
114#define MOVE_MEDIUM 0xa5 108#define MOVE_MEDIUM 0xa5
@@ -136,6 +130,38 @@ extern const unsigned char scsi_command_size[8];
136#define ATA_12 0xa1 /* 12-byte pass-thru */ 130#define ATA_12 0xa1 /* 12-byte pass-thru */
137 131
138/* 132/*
133 * SCSI command lengths
134 */
135
136#define SCSI_MAX_VARLEN_CDB_SIZE 260
137
138/* defined in T10 SCSI Primary Commands-2 (SPC2) */
139struct scsi_varlen_cdb_hdr {
140 u8 opcode; /* opcode always == VARIABLE_LENGTH_CMD */
141 u8 control;
142 u8 misc[5];
143 u8 additional_cdb_length; /* total cdb length - 8 */
144 __be16 service_action;
145 /* service specific data follows */
146};
147
148static inline unsigned
149scsi_varlen_cdb_length(const void *hdr)
150{
151 return ((struct scsi_varlen_cdb_hdr *)hdr)->additional_cdb_length + 8;
152}
153
154extern const unsigned char scsi_command_size_tbl[8];
155#define COMMAND_SIZE(opcode) scsi_command_size_tbl[((opcode) >> 5) & 7]
156
157static inline unsigned
158scsi_command_size(const unsigned char *cmnd)
159{
160 return (cmnd[0] == VARIABLE_LENGTH_CMD) ?
161 scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]);
162}
163
164/*
139 * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft 165 * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
140 * T10/1561-D Revision 4 Draft dated 7th November 2002. 166 * T10/1561-D Revision 4 Draft dated 7th November 2002.
141 */ 167 */
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 7ed883c8e48a..3e46dfae8194 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -78,7 +78,7 @@ struct scsi_cmnd {
78 int allowed; 78 int allowed;
79 int timeout_per_command; 79 int timeout_per_command;
80 80
81 unsigned char cmd_len; 81 unsigned short cmd_len;
82 enum dma_data_direction sc_data_direction; 82 enum dma_data_direction sc_data_direction;
83 83
84 /* These elements define the operation we are about to perform */ 84 /* These elements define the operation we are about to perform */
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index d967d6dc7a28..1834fdfe82a7 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -573,13 +573,11 @@ struct Scsi_Host {
573 /* 573 /*
574 * The maximum length of SCSI commands that this host can accept. 574 * The maximum length of SCSI commands that this host can accept.
575 * Probably 12 for most host adapters, but could be 16 for others. 575 * Probably 12 for most host adapters, but could be 16 for others.
576 * or 260 if the driver supports variable length cdbs.
576 * For drivers that don't set this field, a value of 12 is 577 * For drivers that don't set this field, a value of 12 is
577 * assumed. I am leaving this as a number rather than a bit 578 * assumed.
578 * because you never know what subsequent SCSI standards might do
579 * (i.e. could there be a 20 byte or a 24-byte command a few years
580 * down the road?).
581 */ 579 */
582 unsigned char max_cmd_len; 580 unsigned short max_cmd_len;
583 581
584 int this_id; 582 int this_id;
585 int can_queue; 583 int can_queue;