Commit db4742dd8f0aa9125b74f9b2516336a75f3d9106
Committed by
James Bottomley
1 parent
64a87b244b
Exists in
master
and in
7 other branches
[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>
Showing 7 changed files with 47 additions and 35 deletions Side-by-side Diff
block/scsi_ioctl.c
... | ... | @@ -33,13 +33,12 @@ |
33 | 33 | #include <scsi/scsi_cmnd.h> |
34 | 34 | |
35 | 35 | /* Command group 3 is reserved and should never be used. */ |
36 | -const unsigned char scsi_command_size[8] = | |
36 | +const unsigned char scsi_command_size_tbl[8] = | |
37 | 37 | { |
38 | 38 | 6, 10, 10, 12, |
39 | 39 | 16, 12, 10, 10 |
40 | 40 | }; |
41 | - | |
42 | -EXPORT_SYMBOL(scsi_command_size); | |
41 | +EXPORT_SYMBOL(scsi_command_size_tbl); | |
43 | 42 | |
44 | 43 | #include <scsi/sg.h> |
45 | 44 |
drivers/scsi/constants.c
... | ... | @@ -28,7 +28,6 @@ |
28 | 28 | #define SERVICE_ACTION_OUT_12 0xa9 |
29 | 29 | #define SERVICE_ACTION_IN_16 0x9e |
30 | 30 | #define SERVICE_ACTION_OUT_16 0x9f |
31 | -#define VARIABLE_LENGTH_CMD 0x7f | |
32 | 31 | |
33 | 32 | |
34 | 33 | |
... | ... | @@ -210,7 +209,7 @@ |
210 | 209 | cdb0 = cdbp[0]; |
211 | 210 | switch(cdb0) { |
212 | 211 | case VARIABLE_LENGTH_CMD: |
213 | - len = cdbp[7] + 8; | |
212 | + len = scsi_varlen_cdb_length(cdbp); | |
214 | 213 | if (len < 10) { |
215 | 214 | printk("short variable length command, " |
216 | 215 | "len=%d ext_len=%d", len, cdb_len); |
... | ... | @@ -300,7 +299,7 @@ |
300 | 299 | cdb0 = cdbp[0]; |
301 | 300 | switch(cdb0) { |
302 | 301 | case VARIABLE_LENGTH_CMD: |
303 | - len = cdbp[7] + 8; | |
302 | + len = scsi_varlen_cdb_length(cdbp); | |
304 | 303 | if (len < 10) { |
305 | 304 | printk("short opcode=0x%x command, len=%d " |
306 | 305 | "ext_len=%d", cdb0, len, cdb_len); |
... | ... | @@ -335,10 +334,7 @@ |
335 | 334 | int k, len; |
336 | 335 | |
337 | 336 | print_opcode_name(cdb, 0); |
338 | - if (VARIABLE_LENGTH_CMD == cdb[0]) | |
339 | - len = cdb[7] + 8; | |
340 | - else | |
341 | - len = COMMAND_SIZE(cdb[0]); | |
337 | + len = scsi_command_size(cdb); | |
342 | 338 | /* print out all bytes in cdb */ |
343 | 339 | for (k = 0; k < len; ++k) |
344 | 340 | printk(" %02x", cdb[k]); |
drivers/scsi/scsi.c
... | ... | @@ -79,15 +79,6 @@ |
79 | 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 | 82 | * Note - the initial logging level can be set here to log events at boot time. |
92 | 83 | * After the system is up, you may enable logging via the /proc interface. |
93 | 84 | */ |
94 | 85 | |
... | ... | @@ -709,9 +700,11 @@ |
709 | 700 | * Before we queue this command, check if the command |
710 | 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 | 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 | 708 | cmd->result = (DID_ABORT << 16); |
716 | 709 | |
717 | 710 | scsi_done(cmd); |
drivers/scsi/scsi_lib.c
... | ... | @@ -445,7 +445,7 @@ |
445 | 445 | scsi_set_resid(cmd, 0); |
446 | 446 | memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); |
447 | 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 | |
451 | 451 | void scsi_device_unbusy(struct scsi_device *sdev) |
include/scsi/scsi.h
... | ... | @@ -30,13 +30,6 @@ |
30 | 30 | #endif |
31 | 31 | |
32 | 32 | /* |
33 | - * SCSI command lengths | |
34 | - */ | |
35 | - | |
36 | -extern const unsigned char scsi_command_size[8]; | |
37 | -#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7] | |
38 | - | |
39 | -/* | |
40 | 33 | * Special value for scanning to specify scanning or rescanning of all |
41 | 34 | * possible channels, (target) ids, or luns on a given shost. |
42 | 35 | */ |
... | ... | @@ -109,6 +102,7 @@ |
109 | 102 | #define MODE_SENSE_10 0x5a |
110 | 103 | #define PERSISTENT_RESERVE_IN 0x5e |
111 | 104 | #define PERSISTENT_RESERVE_OUT 0x5f |
105 | +#define VARIABLE_LENGTH_CMD 0x7f | |
112 | 106 | #define REPORT_LUNS 0xa0 |
113 | 107 | #define MAINTENANCE_IN 0xa3 |
114 | 108 | #define MOVE_MEDIUM 0xa5 |
... | ... | @@ -134,6 +128,38 @@ |
134 | 128 | /* Values for T10/04-262r7 */ |
135 | 129 | #define ATA_16 0x85 /* 16-byte pass-thru */ |
136 | 130 | #define ATA_12 0xa1 /* 12-byte pass-thru */ |
131 | + | |
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) */ | |
139 | +struct 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 | + | |
148 | +static inline unsigned | |
149 | +scsi_varlen_cdb_length(const void *hdr) | |
150 | +{ | |
151 | + return ((struct scsi_varlen_cdb_hdr *)hdr)->additional_cdb_length + 8; | |
152 | +} | |
153 | + | |
154 | +extern const unsigned char scsi_command_size_tbl[8]; | |
155 | +#define COMMAND_SIZE(opcode) scsi_command_size_tbl[((opcode) >> 5) & 7] | |
156 | + | |
157 | +static inline unsigned | |
158 | +scsi_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 | +} | |
137 | 163 | |
138 | 164 | /* |
139 | 165 | * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft |
include/scsi/scsi_cmnd.h
include/scsi/scsi_host.h
... | ... | @@ -573,13 +573,11 @@ |
573 | 573 | /* |
574 | 574 | * The maximum length of SCSI commands that this host can accept. |
575 | 575 | * Probably 12 for most host adapters, but could be 16 for others. |
576 | + * or 260 if the driver supports variable length cdbs. | |
576 | 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 | - * 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?). | |
578 | + * assumed. | |
581 | 579 | */ |
582 | - unsigned char max_cmd_len; | |
580 | + unsigned short max_cmd_len; | |
583 | 581 | |
584 | 582 | int this_id; |
585 | 583 | int can_queue; |