Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi_debug: change SCSI command parser to table driven

The existing 'big switch' parser in queuecommand() is changed to
a table driven parser. The old and new queuecommand() were moved
in the source so diff would not shuffle them. Apart from the new
tables most other changes are refactoring existing response code
to be more easily called out of the table parser. The 'strict'
parameter is added so that cdb_s can be checked for non-zero
values in parts of the cdb that are reserved. Some other changes
include: tweak request sense response when D_SENSE differs; support
NDOB in Write Same(16); and fix crash in Get LBA Status when LBP
was inactive.

Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>

authored by

Douglas Gilbert and committed by
Christoph Hellwig
c2248fc9 0d01c5df

+834 -559
+834 -559
drivers/scsi/scsi_debug.c
··· 71 71 /* Additional Sense Code (ASC) */ 72 72 #define NO_ADDITIONAL_SENSE 0x0 73 73 #define LOGICAL_UNIT_NOT_READY 0x4 74 + #define LOGICAL_UNIT_COMMUNICATION_FAILURE 0x8 74 75 #define UNRECOVERED_READ_ERR 0x11 75 76 #define PARAMETER_LIST_LENGTH_ERR 0x1a 76 77 #define INVALID_OPCODE 0x20 77 - #define INVALID_COMMAND_OPCODE 0x20 78 78 #define LBA_OUT_OF_RANGE 0x21 79 79 #define INVALID_FIELD_IN_CDB 0x24 80 80 #define INVALID_FIELD_IN_PARAM_LIST 0x26 ··· 136 136 #define DEF_VIRTUAL_GB 0 137 137 #define DEF_VPD_USE_HOSTNO 1 138 138 #define DEF_WRITESAME_LENGTH 0xFFFF 139 + #define DEF_STRICT 0 139 140 #define DELAY_OVERRIDDEN -9999 140 141 141 142 /* bit mask values for scsi_debug_opts */ ··· 184 183 #define SDEBUG_NUM_UAS 4 185 184 186 185 /* for check_readiness() */ 187 - #define UAS_ONLY 1 188 - #define UAS_TUR 0 186 + #define UAS_ONLY 1 /* check for UAs only */ 187 + #define UAS_TUR 0 /* if no UAs then check if media access possible */ 189 188 190 189 /* when 1==SCSI_DEBUG_OPT_MEDIUM_ERR, a medium error is simulated at this 191 190 * sector on read commands: */ ··· 210 209 #if DEF_CMD_PER_LUN > SCSI_DEBUG_CANQUEUE 211 210 #warning "Expect DEF_CMD_PER_LUN <= SCSI_DEBUG_CANQUEUE" 212 211 #endif 212 + 213 + /* SCSI opcodes (first byte of cdb) mapped onto these indexes */ 214 + enum sdeb_opcode_index { 215 + SDEB_I_INVALID_OPCODE = 0, 216 + SDEB_I_INQUIRY = 1, 217 + SDEB_I_REPORT_LUNS = 2, 218 + SDEB_I_REQUEST_SENSE = 3, 219 + SDEB_I_TEST_UNIT_READY = 4, 220 + SDEB_I_MODE_SENSE = 5, /* 6, 10 */ 221 + SDEB_I_MODE_SELECT = 6, /* 6, 10 */ 222 + SDEB_I_LOG_SENSE = 7, 223 + SDEB_I_READ_CAPACITY = 8, /* 10; 16 is in SA_IN(16) */ 224 + SDEB_I_READ = 9, /* 6, 10, 12, 16 */ 225 + SDEB_I_WRITE = 10, /* 6, 10, 12, 16 */ 226 + SDEB_I_START_STOP = 11, 227 + SDEB_I_SERV_ACT_IN = 12, /* 12, 16 */ 228 + SDEB_I_SERV_ACT_OUT = 13, /* 12, 16 */ 229 + SDEB_I_MAINT_IN = 14, 230 + SDEB_I_MAINT_OUT = 15, 231 + SDEB_I_VERIFY = 16, /* 10 only */ 232 + SDEB_I_VARIABLE_LEN = 17, 233 + SDEB_I_RESERVE = 18, /* 6, 10 */ 234 + SDEB_I_RELEASE = 19, /* 6, 10 */ 235 + SDEB_I_ALLOW_REMOVAL = 20, /* PREVENT ALLOW MEDIUM REMOVAL */ 236 + SDEB_I_REZERO_UNIT = 21, /* REWIND in SSC */ 237 + SDEB_I_ATA_PT = 22, /* 12, 16 */ 238 + SDEB_I_SEND_DIAG = 23, 239 + SDEB_I_UNMAP = 24, 240 + SDEB_I_XDWRITEREAD = 25, /* 10 only */ 241 + SDEB_I_WRITE_BUFFER = 26, 242 + SDEB_I_WRITE_SAME = 27, /* 10, 16 */ 243 + SDEB_I_SYNC_CACHE = 28, /* 10 only */ 244 + SDEB_I_COMP_WRITE = 29, 245 + SDEB_I_LAST_ELEMENT = 30, /* keep this last */ 246 + }; 247 + 248 + static const unsigned char opcode_ind_arr[256] = { 249 + /* 0x0; 0x0->0x1f: 6 byte cdbs */ 250 + SDEB_I_TEST_UNIT_READY, SDEB_I_REZERO_UNIT, 0, SDEB_I_REQUEST_SENSE, 251 + 0, 0, 0, 0, 252 + SDEB_I_READ, 0, SDEB_I_WRITE, 0, 0, 0, 0, 0, 253 + 0, 0, SDEB_I_INQUIRY, 0, 0, SDEB_I_MODE_SELECT, SDEB_I_RESERVE, 254 + SDEB_I_RELEASE, 255 + 0, 0, SDEB_I_MODE_SENSE, SDEB_I_START_STOP, 0, SDEB_I_SEND_DIAG, 256 + SDEB_I_ALLOW_REMOVAL, 0, 257 + /* 0x20; 0x20->0x3f: 10 byte cdbs */ 258 + 0, 0, 0, 0, 0, SDEB_I_READ_CAPACITY, 0, 0, 259 + SDEB_I_READ, 0, SDEB_I_WRITE, 0, 0, 0, 0, SDEB_I_VERIFY, 260 + 0, 0, 0, 0, 0, SDEB_I_SYNC_CACHE, 0, 0, 261 + 0, 0, 0, SDEB_I_WRITE_BUFFER, 0, 0, 0, 0, 262 + /* 0x40; 0x40->0x5f: 10 byte cdbs */ 263 + 0, SDEB_I_WRITE_SAME, SDEB_I_UNMAP, 0, 0, 0, 0, 0, 264 + 0, 0, 0, 0, 0, SDEB_I_LOG_SENSE, 0, 0, 265 + 0, 0, 0, SDEB_I_XDWRITEREAD, 0, SDEB_I_MODE_SELECT, SDEB_I_RESERVE, 266 + SDEB_I_RELEASE, 267 + 0, 0, SDEB_I_MODE_SENSE, 0, 0, 0, 0, 0, 268 + /* 0x60; 0x60->0x7d are reserved */ 269 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 270 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271 + 0, SDEB_I_VARIABLE_LEN, 272 + /* 0x80; 0x80->0x9f: 16 byte cdbs */ 273 + 0, 0, 0, 0, 0, SDEB_I_ATA_PT, 0, 0, 274 + SDEB_I_READ, SDEB_I_COMP_WRITE, SDEB_I_WRITE, 0, 0, 0, 0, 0, 275 + 0, 0, 0, SDEB_I_WRITE_SAME, 0, 0, 0, 0, 276 + 0, 0, 0, 0, 0, 0, SDEB_I_SERV_ACT_IN, SDEB_I_SERV_ACT_OUT, 277 + /* 0xa0; 0xa0->0xbf: 12 byte cdbs */ 278 + SDEB_I_REPORT_LUNS, SDEB_I_ATA_PT, 0, SDEB_I_MAINT_IN, 279 + SDEB_I_MAINT_OUT, 0, 0, 0, 280 + SDEB_I_READ, SDEB_I_SERV_ACT_OUT, SDEB_I_WRITE, SDEB_I_SERV_ACT_IN, 281 + 0, 0, 0, 0, 282 + 0, 0, 0, 0, 0, 0, 0, 0, 283 + 0, 0, 0, 0, 0, 0, 0, 0, 284 + /* 0xc0; 0xc0->0xff: vendor specific */ 285 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 286 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 287 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 288 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 289 + }; 290 + 291 + #define F_D_IN 1 292 + #define F_D_OUT 2 293 + #define F_D_OUT_MAYBE 4 /* WRITE SAME, NDOB bit */ 294 + #define F_D_UNKN 8 295 + #define F_RL_WLUN_OK 0x10 296 + #define F_SKIP_UA 0x20 297 + #define F_DELAY_OVERR 0x40 298 + #define F_SA_LOW 0x80 /* cdb byte 1, bits 4 to 0 */ 299 + #define F_SA_HIGH 0x100 /* as used by variable length cdbs */ 300 + #define F_INV_OP 0x200 301 + #define F_FAKE_RW 0x400 302 + #define F_M_ACCESS 0x800 /* media access */ 303 + 304 + #define FF_RESPOND (F_RL_WLUN_OK | F_SKIP_UA | F_DELAY_OVERR) 305 + #define FF_DIRECT_IO (F_M_ACCESS | F_FAKE_RW) 306 + #define FF_SA (F_SA_HIGH | F_SA_LOW) 307 + 308 + struct sdebug_dev_info; 309 + static int scsi_debug_queuecommand(struct scsi_cmnd *scp); 310 + static int resp_inquiry(struct scsi_cmnd *, struct sdebug_dev_info *); 311 + static int resp_report_luns(struct scsi_cmnd *, struct sdebug_dev_info *); 312 + static int resp_requests(struct scsi_cmnd *, struct sdebug_dev_info *); 313 + static int resp_mode_sense(struct scsi_cmnd *, struct sdebug_dev_info *); 314 + static int resp_mode_select(struct scsi_cmnd *, struct sdebug_dev_info *); 315 + static int resp_log_sense(struct scsi_cmnd *, struct sdebug_dev_info *); 316 + static int resp_readcap(struct scsi_cmnd *, struct sdebug_dev_info *); 317 + static int resp_read_dt0(struct scsi_cmnd *, struct sdebug_dev_info *); 318 + static int resp_write_dt0(struct scsi_cmnd *, struct sdebug_dev_info *); 319 + static int resp_start_stop(struct scsi_cmnd *, struct sdebug_dev_info *); 320 + static int resp_readcap16(struct scsi_cmnd *, struct sdebug_dev_info *); 321 + static int resp_get_lba_status(struct scsi_cmnd *, struct sdebug_dev_info *); 322 + static int resp_report_tgtpgs(struct scsi_cmnd *, struct sdebug_dev_info *); 323 + static int resp_unmap(struct scsi_cmnd *, struct sdebug_dev_info *); 324 + static int resp_write_same_10(struct scsi_cmnd *, struct sdebug_dev_info *); 325 + static int resp_write_same_16(struct scsi_cmnd *, struct sdebug_dev_info *); 326 + static int resp_xdwriteread_10(struct scsi_cmnd *, struct sdebug_dev_info *); 327 + 328 + struct opcode_info_t { 329 + u8 num_attached; /* 0 if this is it (i.e. a leaf); use 0xff 330 + * for terminating element */ 331 + u8 opcode; /* if num_attached > 0, preferred */ 332 + u16 sa; /* service action */ 333 + u32 flags; /* OR-ed set of SDEB_F_* */ 334 + int (*pfp)(struct scsi_cmnd *, struct sdebug_dev_info *); 335 + const struct opcode_info_t *arrp; /* num_attached elements or NULL */ 336 + u8 len_mask[16]; /* len=len_mask[0], then mask for cdb[1]... */ 337 + /* ignore cdb bytes after position 15 */ 338 + }; 339 + 340 + static const struct opcode_info_t msense_iarr[1] = { 341 + {0, 0x1a, 0, F_D_IN, NULL, NULL, 342 + {6, 0xe8, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 343 + }; 344 + 345 + static const struct opcode_info_t mselect_iarr[1] = { 346 + {0, 0x15, 0, F_D_OUT, NULL, NULL, 347 + {6, 0xf1, 0, 0, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 348 + }; 349 + 350 + static const struct opcode_info_t read_iarr[3] = { 351 + {0, 0x28, 0, F_D_IN | FF_DIRECT_IO, resp_read_dt0, NULL,/* READ(10) */ 352 + {10, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xc7, 0, 0, 353 + 0, 0, 0, 0} }, 354 + {0, 0x8, 0, F_D_IN | FF_DIRECT_IO, resp_read_dt0, NULL, /* READ(6) */ 355 + {6, 0xff, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 356 + {0, 0xa8, 0, F_D_IN | FF_DIRECT_IO, resp_read_dt0, NULL,/* READ(12) */ 357 + {12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 358 + 0xc7, 0, 0, 0, 0} }, 359 + }; 360 + 361 + static const struct opcode_info_t write_iarr[3] = { 362 + {0, 0x2a, 0, F_D_OUT | FF_DIRECT_IO, resp_write_dt0, NULL, /* 10 */ 363 + {10, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xc7, 0, 0, 364 + 0, 0, 0, 0} }, 365 + {0, 0xa, 0, F_D_OUT | FF_DIRECT_IO, resp_write_dt0, NULL, /* 6 */ 366 + {6, 0xff, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 367 + {0, 0xaa, 0, F_D_OUT | FF_DIRECT_IO, resp_write_dt0, NULL, /* 12 */ 368 + {12, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 369 + 0xc7, 0, 0, 0, 0} }, 370 + }; 371 + 372 + static const struct opcode_info_t sa_in_iarr[1] = { 373 + {0, 0x9e, 0x12, F_SA_LOW | F_D_IN, resp_get_lba_status, NULL, 374 + {16, 0x12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 375 + 0xff, 0xff, 0xff, 0, 0xc7} }, 376 + }; 377 + 378 + static const struct opcode_info_t vl_iarr[1] = { /* VARIABLE LENGTH */ 379 + {0, 0x7f, 0xb, F_SA_HIGH | F_D_OUT | FF_DIRECT_IO, resp_write_dt0, 380 + NULL, {32, 0xc7, 0, 0, 0, 0, 0x1f, 0x18, 0x0, 0xb, 0xfa, 381 + 0, 0xff, 0xff, 0xff, 0xff} }, /* WRITE(32) */ 382 + }; 383 + 384 + static const struct opcode_info_t maint_in_iarr[2] = { 385 + {0, 0xa3, 0xc, F_SA_LOW | F_D_IN, NULL, NULL, 386 + {12, 0xc, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 387 + 0xc7, 0, 0, 0, 0} }, 388 + {0, 0xa3, 0xd, F_SA_LOW | F_D_IN, NULL, NULL, 389 + {12, 0xd, 0x80, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0xc7, 0, 0, 390 + 0, 0} }, 391 + }; 392 + 393 + static const struct opcode_info_t write_same_iarr[1] = { 394 + {0, 0x93, 0, F_D_OUT_MAYBE | FF_DIRECT_IO, resp_write_same_16, NULL, 395 + {16, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 396 + 0xff, 0xff, 0xff, 0x1f, 0xc7} }, 397 + }; 398 + 399 + static const struct opcode_info_t reserve_iarr[1] = { 400 + {0, 0x16, 0, F_D_OUT, NULL, NULL, /* RESERVE(6) */ 401 + {6, 0x1f, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 402 + }; 403 + 404 + static const struct opcode_info_t release_iarr[1] = { 405 + {0, 0x17, 0, F_D_OUT, NULL, NULL, /* RELEASE(6) */ 406 + {6, 0x1f, 0xff, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 407 + }; 408 + 409 + 410 + /* This array is accessed via SDEB_I_* values. Make sure all are mapped, 411 + * plus the terminating elements for logic that scans this table such as 412 + * REPORT SUPPORTED OPERATION CODES. */ 413 + static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = { 414 + /* 0 */ 415 + {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, 416 + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 417 + {0, 0x12, 0, FF_RESPOND | F_D_IN, resp_inquiry, NULL, 418 + {6, 0xe3, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 419 + {0, 0xa0, 0, FF_RESPOND | F_D_IN, resp_report_luns, NULL, 420 + {12, 0xe3, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0xc7, 0, 0, 421 + 0, 0} }, 422 + {0, 0x3, 0, FF_RESPOND | F_D_IN, resp_requests, NULL, 423 + {6, 0xe1, 0, 0, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 424 + {0, 0x0, 0, F_M_ACCESS | F_RL_WLUN_OK, NULL, NULL,/* TEST UNIT READY */ 425 + {6, 0, 0, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 426 + {1, 0x5a, 0, F_D_IN, resp_mode_sense, msense_iarr, 427 + {10, 0xf8, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 428 + 0} }, 429 + {1, 0x55, 0, F_D_OUT, resp_mode_select, mselect_iarr, 430 + {10, 0xf1, 0, 0, 0, 0, 0, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0} }, 431 + {0, 0x4d, 0, F_D_IN, resp_log_sense, NULL, 432 + {10, 0xe3, 0xff, 0xff, 0, 0xff, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 433 + 0, 0, 0} }, 434 + {0, 0x25, 0, F_D_IN, resp_readcap, NULL, 435 + {10, 0xe1, 0xff, 0xff, 0xff, 0xff, 0, 0, 0x1, 0xc7, 0, 0, 0, 0, 436 + 0, 0} }, 437 + {3, 0x88, 0, F_D_IN | FF_DIRECT_IO, resp_read_dt0, read_iarr, 438 + {16, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 439 + 0xff, 0xff, 0xff, 0x9f, 0xc7} }, /* READ(16) */ 440 + /* 10 */ 441 + {3, 0x8a, 0, F_D_OUT | FF_DIRECT_IO, resp_write_dt0, write_iarr, 442 + {16, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 443 + 0xff, 0xff, 0xff, 0x9f, 0xc7} }, /* WRITE(16) */ 444 + {0, 0x1b, 0, 0, resp_start_stop, NULL, /* START STOP UNIT */ 445 + {6, 0x1, 0, 0xf, 0xf7, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 446 + {1, 0x9e, 0x10, F_SA_LOW | F_D_IN, resp_readcap16, sa_in_iarr, 447 + {16, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 448 + 0xff, 0xff, 0xff, 0x1, 0xc7} }, /* READ CAPACITY(16) */ 449 + {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* SA OUT */ 450 + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 451 + {2, 0xa3, 0xa, F_SA_LOW | F_D_IN, resp_report_tgtpgs, maint_in_iarr, 452 + {12, 0xea, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0xc7, 0, 0, 0, 453 + 0} }, 454 + {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* MAINT OUT */ 455 + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 456 + {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* VERIFY */ 457 + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 458 + {1, 0x7f, 0x9, F_SA_HIGH | F_D_IN | FF_DIRECT_IO, resp_read_dt0, 459 + vl_iarr, {32, 0xc7, 0, 0, 0, 0, 0x1f, 0x18, 0x0, 0x9, 0xfe, 0, 460 + 0xff, 0xff, 0xff, 0xff} },/* VARIABLE LENGTH, READ(32) */ 461 + {1, 0x56, 0, F_D_OUT, NULL, reserve_iarr, /* RESERVE(10) */ 462 + {10, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 463 + 0} }, 464 + {1, 0x57, 0, F_D_OUT, NULL, release_iarr, /* RELEASE(10) */ 465 + {10, 0x13, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 466 + 0} }, 467 + /* 20 */ 468 + {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* ALLOW REMOVAL */ 469 + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 470 + {0, 0x1, 0, 0, resp_start_stop, NULL, /* REWIND ?? */ 471 + {6, 0x1, 0, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 472 + {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* ATA_PT */ 473 + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 474 + {0, 0x1d, F_D_OUT, 0, NULL, NULL, /* SEND DIAGNOSTIC */ 475 + {6, 0xf7, 0, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 476 + {0, 0x42, 0, F_D_OUT | FF_DIRECT_IO, resp_unmap, NULL, /* UNMAP */ 477 + {10, 0x1, 0, 0, 0, 0, 0x1f, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0} }, 478 + {0, 0x53, 0, F_D_IN | F_D_OUT | FF_DIRECT_IO, resp_xdwriteread_10, 479 + NULL, {10, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xc7, 480 + 0, 0, 0, 0, 0, 0} }, 481 + {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* WRITE_BUFFER */ 482 + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 483 + {1, 0x41, 0, F_D_OUT_MAYBE | FF_DIRECT_IO, resp_write_same_10, 484 + write_same_iarr, {10, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 485 + 0xff, 0xc7, 0, 0, 0, 0, 0, 0} }, 486 + {0, 0x35, 0, F_DELAY_OVERR | FF_DIRECT_IO, NULL, NULL, /* SYNC_CACHE */ 487 + {10, 0x7, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xc7, 0, 0, 488 + 0, 0, 0, 0} }, 489 + {0, 0x89, 0, F_D_OUT | FF_DIRECT_IO, NULL, NULL, 490 + {16, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 491 + 0, 0xff, 0x1f, 0xc7} }, /* COMPARE AND WRITE */ 492 + 493 + /* 30 */ 494 + {0xff, 0, 0, 0, NULL, NULL, /* terminating element */ 495 + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 496 + }; 213 497 214 498 struct sdebug_scmd_extra_t { 215 499 bool inj_recovered; ··· 543 257 static bool scsi_debug_removable = DEF_REMOVABLE; 544 258 static bool scsi_debug_clustering; 545 259 static bool scsi_debug_host_lock = DEF_HOST_LOCK; 260 + static bool scsi_debug_strict = DEF_STRICT; 546 261 static bool sdebug_any_injecting_opt; 547 262 548 263 static atomic_t sdebug_cmnd_count; ··· 577 290 unsigned int target; 578 291 u64 lun; 579 292 struct sdebug_host_info *sdbg_host; 580 - u64 wlun; 581 293 unsigned long uas_bm[1]; 582 294 atomic_t num_in_q; 583 - char stopped; 584 - char used; 295 + char stopped; /* TODO: should be atomic */ 296 + bool used; 585 297 }; 586 298 587 299 struct sdebug_host_info { ··· 761 475 mk_sense_invalid_opcode(struct scsi_cmnd *scp) 762 476 { 763 477 mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_OPCODE, 0); 764 - } 765 - 766 - static void get_data_transfer_info(unsigned char *cmd, 767 - unsigned long long *lba, unsigned int *num, 768 - u32 *ei_lba) 769 - { 770 - *ei_lba = 0; 771 - 772 - switch (*cmd) { 773 - case VARIABLE_LENGTH_CMD: 774 - *lba = (u64)cmd[19] | (u64)cmd[18] << 8 | 775 - (u64)cmd[17] << 16 | (u64)cmd[16] << 24 | 776 - (u64)cmd[15] << 32 | (u64)cmd[14] << 40 | 777 - (u64)cmd[13] << 48 | (u64)cmd[12] << 56; 778 - 779 - *ei_lba = (u32)cmd[23] | (u32)cmd[22] << 8 | 780 - (u32)cmd[21] << 16 | (u32)cmd[20] << 24; 781 - 782 - *num = (u32)cmd[31] | (u32)cmd[30] << 8 | (u32)cmd[29] << 16 | 783 - (u32)cmd[28] << 24; 784 - break; 785 - 786 - case WRITE_SAME_16: 787 - case WRITE_16: 788 - case READ_16: 789 - *lba = (u64)cmd[9] | (u64)cmd[8] << 8 | 790 - (u64)cmd[7] << 16 | (u64)cmd[6] << 24 | 791 - (u64)cmd[5] << 32 | (u64)cmd[4] << 40 | 792 - (u64)cmd[3] << 48 | (u64)cmd[2] << 56; 793 - 794 - *num = (u32)cmd[13] | (u32)cmd[12] << 8 | (u32)cmd[11] << 16 | 795 - (u32)cmd[10] << 24; 796 - break; 797 - case WRITE_12: 798 - case READ_12: 799 - *lba = (u32)cmd[5] | (u32)cmd[4] << 8 | (u32)cmd[3] << 16 | 800 - (u32)cmd[2] << 24; 801 - 802 - *num = (u32)cmd[9] | (u32)cmd[8] << 8 | (u32)cmd[7] << 16 | 803 - (u32)cmd[6] << 24; 804 - break; 805 - case WRITE_SAME: 806 - case WRITE_10: 807 - case READ_10: 808 - case XDWRITEREAD_10: 809 - *lba = (u32)cmd[5] | (u32)cmd[4] << 8 | (u32)cmd[3] << 16 | 810 - (u32)cmd[2] << 24; 811 - 812 - *num = (u32)cmd[8] | (u32)cmd[7] << 8; 813 - break; 814 - case WRITE_6: 815 - case READ_6: 816 - *lba = (u32)cmd[3] | (u32)cmd[2] << 8 | 817 - (u32)(cmd[1] & 0x1f) << 16; 818 - *num = (0 == cmd[4]) ? 256 : cmd[4]; 819 - break; 820 - default: 821 - break; 822 - } 823 478 } 824 479 825 480 static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) ··· 1219 992 #define SDEBUG_LONG_INQ_SZ 96 1220 993 #define SDEBUG_MAX_INQ_ARR_SZ 584 1221 994 1222 - static int resp_inquiry(struct scsi_cmnd *scp, int target, 1223 - struct sdebug_dev_info * devip) 995 + static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) 1224 996 { 1225 997 unsigned char pq_pdt; 1226 998 unsigned char * arr; 1227 999 unsigned char *cmd = scp->cmnd; 1228 1000 int alloc_len, n, ret; 1001 + bool have_wlun; 1229 1002 1230 1003 alloc_len = (cmd[3] << 8) + cmd[4]; 1231 1004 arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_ATOMIC); 1232 1005 if (! arr) 1233 1006 return DID_REQUEUE << 16; 1234 - if (devip->wlun) 1007 + have_wlun = (scp->device->lun == SAM2_WLUN_REPORT_LUNS); 1008 + if (have_wlun) 1235 1009 pq_pdt = 0x1e; /* present, wlun */ 1236 1010 else if (scsi_debug_no_lun_0 && (0 == devip->lun)) 1237 1011 pq_pdt = 0x7f; /* not present, no device type */ ··· 1252 1024 (devip->channel & 0x7f); 1253 1025 if (0 == scsi_debug_vpd_use_hostno) 1254 1026 host_no = 0; 1255 - lu_id_num = devip->wlun ? -1 : (((host_no + 1) * 2000) + 1027 + lu_id_num = have_wlun ? -1 : (((host_no + 1) * 2000) + 1256 1028 (devip->target * 1000) + devip->lun); 1257 1029 target_dev_id = ((host_no + 1) * 2000) + 1258 1030 (devip->target * 1000) - 3; ··· 1370 1142 unsigned char * sbuff; 1371 1143 unsigned char *cmd = scp->cmnd; 1372 1144 unsigned char arr[SCSI_SENSE_BUFFERSIZE]; 1373 - int want_dsense; 1145 + bool dsense, want_dsense; 1374 1146 int len = 18; 1375 1147 1376 1148 memset(arr, 0, sizeof(arr)); 1377 - want_dsense = !!(cmd[1] & 1) || scsi_debug_dsense; 1149 + dsense = !!(cmd[1] & 1); 1150 + want_dsense = dsense || scsi_debug_dsense; 1378 1151 sbuff = scp->sense_buffer; 1379 1152 if ((iec_m_pg[2] & 0x4) && (6 == (iec_m_pg[3] & 0xf))) { 1380 - if (want_dsense) { 1153 + if (dsense) { 1381 1154 arr[0] = 0x72; 1382 1155 arr[1] = 0x0; /* NO_SENSE in sense_key */ 1383 1156 arr[2] = THRESHOLD_EXCEEDED; 1384 1157 arr[3] = 0xff; /* TEST set and MRIE==6 */ 1158 + len = 8; 1385 1159 } else { 1386 1160 arr[0] = 0x70; 1387 1161 arr[2] = 0x0; /* NO_SENSE in sense_key */ ··· 1393 1163 } 1394 1164 } else { 1395 1165 memcpy(arr, sbuff, SCSI_SENSE_BUFFERSIZE); 1396 - if ((cmd[1] & 1) && (! scsi_debug_dsense)) { 1397 - /* DESC bit set and sense_buff in fixed format */ 1398 - memset(arr, 0, sizeof(arr)); 1166 + if (arr[0] >= 0x70 && dsense == scsi_debug_dsense) 1167 + ; /* have sense and formats match */ 1168 + else if (arr[0] <= 0x70) { 1169 + if (dsense) { 1170 + memset(arr, 0, 8); 1171 + arr[0] = 0x72; 1172 + len = 8; 1173 + } else { 1174 + memset(arr, 0, 18); 1175 + arr[0] = 0x70; 1176 + arr[7] = 0xa; 1177 + } 1178 + } else if (dsense) { 1179 + memset(arr, 0, 8); 1399 1180 arr[0] = 0x72; 1400 1181 arr[1] = sbuff[2]; /* sense key */ 1401 1182 arr[2] = sbuff[12]; /* asc */ 1402 1183 arr[3] = sbuff[13]; /* ascq */ 1403 1184 len = 8; 1185 + } else { 1186 + memset(arr, 0, 18); 1187 + arr[0] = 0x70; 1188 + arr[2] = sbuff[1]; 1189 + arr[7] = 0xa; 1190 + arr[12] = sbuff[1]; 1191 + arr[13] = sbuff[3]; 1404 1192 } 1193 + 1405 1194 } 1406 1195 mk_sense_buffer(scp, 0, NO_ADDITIONAL_SENSE, 0); 1407 1196 return fill_from_dev_buffer(scp, arr, len); ··· 1430 1181 struct sdebug_dev_info * devip) 1431 1182 { 1432 1183 unsigned char *cmd = scp->cmnd; 1433 - int power_cond, errsts, start; 1184 + int power_cond, start; 1434 1185 1435 - errsts = check_readiness(scp, UAS_ONLY, devip); 1436 - if (errsts) 1437 - return errsts; 1438 1186 power_cond = (cmd[4] & 0xf0) >> 4; 1439 1187 if (power_cond) { 1440 1188 mk_sense_invalid_fld(scp, SDEB_IN_CDB, 4, 7); ··· 1458 1212 { 1459 1213 unsigned char arr[SDEBUG_READCAP_ARR_SZ]; 1460 1214 unsigned int capac; 1461 - int errsts; 1462 1215 1463 - errsts = check_readiness(scp, UAS_ONLY, devip); 1464 - if (errsts) 1465 - return errsts; 1466 1216 /* following just in case virtual_gb changed */ 1467 1217 sdebug_capacity = get_sdebug_capacity(); 1468 1218 memset(arr, 0, SDEBUG_READCAP_ARR_SZ); ··· 1486 1244 unsigned char *cmd = scp->cmnd; 1487 1245 unsigned char arr[SDEBUG_READCAP16_ARR_SZ]; 1488 1246 unsigned long long capac; 1489 - int errsts, k, alloc_len; 1247 + int k, alloc_len; 1490 1248 1491 - errsts = check_readiness(scp, UAS_ONLY, devip); 1492 - if (errsts) 1493 - return errsts; 1494 1249 alloc_len = ((cmd[10] << 24) + (cmd[11] << 16) + (cmd[12] << 8) 1495 1250 + cmd[13]); 1496 1251 /* following just in case virtual_gb changed */ ··· 1762 1523 1763 1524 #define SDEBUG_MAX_MSENSE_SZ 256 1764 1525 1765 - static int resp_mode_sense(struct scsi_cmnd * scp, int target, 1766 - struct sdebug_dev_info * devip) 1526 + static int 1527 + resp_mode_sense(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) 1767 1528 { 1768 1529 unsigned char dbd, llbaa; 1769 1530 int pcontrol, pcode, subpcode, bd_len; 1770 1531 unsigned char dev_spec; 1771 - int k, alloc_len, msense_6, offset, len, errsts, target_dev_id; 1532 + int k, alloc_len, msense_6, offset, len, target_dev_id; 1533 + int target = scp->device->id; 1772 1534 unsigned char * ap; 1773 1535 unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; 1774 1536 unsigned char *cmd = scp->cmnd; 1775 1537 1776 - errsts = check_readiness(scp, UAS_ONLY, devip); 1777 - if (errsts) 1778 - return errsts; 1779 1538 dbd = !!(cmd[1] & 0x8); 1780 1539 pcontrol = (cmd[2] & 0xc0) >> 6; 1781 1540 pcode = cmd[2] & 0x3f; ··· 1921 1684 1922 1685 #define SDEBUG_MAX_MSELECT_SZ 512 1923 1686 1924 - static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, 1925 - struct sdebug_dev_info * devip) 1687 + static int 1688 + resp_mode_select(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) 1926 1689 { 1927 1690 int pf, sp, ps, md_len, bd_len, off, spf, pg_len; 1928 - int param_len, res, errsts, mpage; 1691 + int param_len, res, mpage; 1929 1692 unsigned char arr[SDEBUG_MAX_MSELECT_SZ]; 1930 1693 unsigned char *cmd = scp->cmnd; 1694 + int mselect6 = (MODE_SELECT == cmd[0]); 1931 1695 1932 - errsts = check_readiness(scp, UAS_ONLY, devip); 1933 - if (errsts) 1934 - return errsts; 1935 1696 memset(arr, 0, sizeof(arr)); 1936 1697 pf = cmd[1] & 0x10; 1937 1698 sp = cmd[1] & 0x1; ··· 2028 1793 static int resp_log_sense(struct scsi_cmnd * scp, 2029 1794 struct sdebug_dev_info * devip) 2030 1795 { 2031 - int ppc, sp, pcontrol, pcode, subpcode, alloc_len, errsts, len, n; 1796 + int ppc, sp, pcontrol, pcode, subpcode, alloc_len, len, n; 2032 1797 unsigned char arr[SDEBUG_MAX_LSENSE_SZ]; 2033 1798 unsigned char *cmd = scp->cmnd; 2034 1799 2035 - errsts = check_readiness(scp, UAS_ONLY, devip); 2036 - if (errsts) 2037 - return errsts; 2038 1800 memset(arr, 0, sizeof(arr)); 2039 1801 ppc = cmd[1] & 0x2; 2040 1802 sp = cmd[1] & 0x1; ··· 2121 1889 } 2122 1890 2123 1891 /* Returns number of bytes copied or -1 if error. */ 2124 - static int do_device_access(struct scsi_cmnd *scmd, 2125 - unsigned long long lba, unsigned int num, int write) 1892 + static int 1893 + do_device_access(struct scsi_cmnd *scmd, u64 lba, u32 num, bool do_write) 2126 1894 { 2127 1895 int ret; 2128 - unsigned long long block, rest = 0; 1896 + u64 block, rest = 0; 2129 1897 struct scsi_data_buffer *sdb; 2130 1898 enum dma_data_direction dir; 2131 1899 size_t (*func)(struct scatterlist *, unsigned int, void *, size_t, 2132 1900 off_t); 2133 1901 2134 - if (write) { 1902 + if (do_write) { 2135 1903 sdb = scsi_out(scmd); 2136 1904 dir = DMA_TO_DEVICE; 2137 1905 func = sg_pcopy_to_buffer; ··· 2277 2045 return 0; 2278 2046 } 2279 2047 2280 - static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba, 2281 - unsigned int num, u32 ei_lba) 2048 + static int 2049 + resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) 2282 2050 { 2051 + u8 *cmd = scp->cmnd; 2052 + u64 lba; 2053 + u32 num; 2054 + u32 ei_lba; 2283 2055 unsigned long iflags; 2284 2056 int ret; 2057 + bool check_prot; 2285 2058 2286 - ret = check_device_access_params(SCpnt, lba, num); 2287 - if (ret) 2288 - return ret; 2059 + switch (cmd[0]) { 2060 + case READ_16: 2061 + ei_lba = 0; 2062 + lba = get_unaligned_be64(cmd + 2); 2063 + num = get_unaligned_be32(cmd + 10); 2064 + check_prot = true; 2065 + break; 2066 + case READ_10: 2067 + ei_lba = 0; 2068 + lba = get_unaligned_be32(cmd + 2); 2069 + num = get_unaligned_be16(cmd + 7); 2070 + check_prot = true; 2071 + break; 2072 + case READ_6: 2073 + ei_lba = 0; 2074 + lba = (u32)cmd[3] | (u32)cmd[2] << 8 | 2075 + (u32)(cmd[1] & 0x1f) << 16; 2076 + num = (0 == cmd[4]) ? 256 : cmd[4]; 2077 + check_prot = true; 2078 + break; 2079 + case READ_12: 2080 + ei_lba = 0; 2081 + lba = get_unaligned_be32(cmd + 2); 2082 + num = get_unaligned_be32(cmd + 6); 2083 + check_prot = true; 2084 + break; 2085 + case XDWRITEREAD_10: 2086 + ei_lba = 0; 2087 + lba = get_unaligned_be32(cmd + 2); 2088 + num = get_unaligned_be16(cmd + 7); 2089 + check_prot = false; 2090 + break; 2091 + default: /* assume READ(32) */ 2092 + lba = get_unaligned_be64(cmd + 12); 2093 + ei_lba = get_unaligned_be32(cmd + 20); 2094 + num = get_unaligned_be32(cmd + 28); 2095 + check_prot = false; 2096 + break; 2097 + } 2098 + if (check_prot) { 2099 + if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && 2100 + (cmd[1] & 0xe0)) { 2101 + mk_sense_invalid_opcode(scp); 2102 + return check_condition_result; 2103 + } 2104 + if ((scsi_debug_dif == SD_DIF_TYPE1_PROTECTION || 2105 + scsi_debug_dif == SD_DIF_TYPE3_PROTECTION) && 2106 + (cmd[1] & 0xe0) == 0) 2107 + sdev_printk(KERN_ERR, scp->device, "Unprotected RD " 2108 + "to DIF device\n"); 2109 + } 2110 + if (sdebug_any_injecting_opt) { 2111 + struct sdebug_scmd_extra_t *ep = scsi_cmd_priv(scp); 2112 + 2113 + if (ep->inj_short) 2114 + num /= 2; 2115 + } 2116 + 2117 + /* inline check_device_access_params() */ 2118 + if (lba + num > sdebug_capacity) { 2119 + mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0); 2120 + return check_condition_result; 2121 + } 2122 + /* transfer length excessive (tie in to block limits VPD page) */ 2123 + if (num > sdebug_store_sectors) { 2124 + /* needs work to find which cdb byte 'num' comes from */ 2125 + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); 2126 + return check_condition_result; 2127 + } 2289 2128 2290 2129 if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && 2291 2130 (lba <= (OPT_MEDIUM_ERR_ADDR + OPT_MEDIUM_ERR_NUM - 1)) && 2292 2131 ((lba + num) > OPT_MEDIUM_ERR_ADDR)) { 2293 2132 /* claim unrecoverable read error */ 2294 - mk_sense_buffer(SCpnt, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0); 2133 + mk_sense_buffer(scp, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0); 2295 2134 /* set info field and valid bit for fixed descriptor */ 2296 - if (0x70 == (SCpnt->sense_buffer[0] & 0x7f)) { 2297 - SCpnt->sense_buffer[0] |= 0x80; /* Valid bit */ 2135 + if (0x70 == (scp->sense_buffer[0] & 0x7f)) { 2136 + scp->sense_buffer[0] |= 0x80; /* Valid bit */ 2298 2137 ret = (lba < OPT_MEDIUM_ERR_ADDR) 2299 2138 ? OPT_MEDIUM_ERR_ADDR : (int)lba; 2300 - SCpnt->sense_buffer[3] = (ret >> 24) & 0xff; 2301 - SCpnt->sense_buffer[4] = (ret >> 16) & 0xff; 2302 - SCpnt->sense_buffer[5] = (ret >> 8) & 0xff; 2303 - SCpnt->sense_buffer[6] = ret & 0xff; 2139 + put_unaligned_be32(ret, scp->sense_buffer + 3); 2304 2140 } 2305 - scsi_set_resid(SCpnt, scsi_bufflen(SCpnt)); 2141 + scsi_set_resid(scp, scsi_bufflen(scp)); 2306 2142 return check_condition_result; 2307 2143 } 2308 2144 2309 2145 read_lock_irqsave(&atomic_rw, iflags); 2310 2146 2311 2147 /* DIX + T10 DIF */ 2312 - if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) { 2313 - int prot_ret = prot_verify_read(SCpnt, lba, num, ei_lba); 2148 + if (scsi_debug_dix && scsi_prot_sg_count(scp)) { 2149 + int prot_ret = prot_verify_read(scp, lba, num, ei_lba); 2314 2150 2315 2151 if (prot_ret) { 2316 2152 read_unlock_irqrestore(&atomic_rw, iflags); 2317 - mk_sense_buffer(SCpnt, ABORTED_COMMAND, 0x10, prot_ret); 2153 + mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, prot_ret); 2318 2154 return illegal_condition_result; 2319 2155 } 2320 2156 } 2321 2157 2322 - ret = do_device_access(SCpnt, lba, num, 0); 2158 + ret = do_device_access(scp, lba, num, false); 2323 2159 read_unlock_irqrestore(&atomic_rw, iflags); 2324 2160 if (ret == -1) 2325 2161 return DID_ERROR << 16; 2326 2162 2327 - scsi_in(SCpnt)->resid = scsi_bufflen(SCpnt) - ret; 2163 + scsi_in(scp)->resid = scsi_bufflen(scp) - ret; 2328 2164 2165 + if (sdebug_any_injecting_opt) { 2166 + struct sdebug_scmd_extra_t *ep = scsi_cmd_priv(scp); 2167 + 2168 + if (ep->inj_recovered) { 2169 + mk_sense_buffer(scp, RECOVERED_ERROR, 2170 + THRESHOLD_EXCEEDED, 0); 2171 + return check_condition_result; 2172 + } else if (ep->inj_transport) { 2173 + mk_sense_buffer(scp, ABORTED_COMMAND, 2174 + TRANSPORT_PROBLEM, ACK_NAK_TO); 2175 + return check_condition_result; 2176 + } else if (ep->inj_dif) { 2177 + /* Logical block guard check failed */ 2178 + mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, 1); 2179 + return illegal_condition_result; 2180 + } else if (ep->inj_dix) { 2181 + mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, 1); 2182 + return illegal_condition_result; 2183 + } 2184 + } 2329 2185 return 0; 2330 2186 } 2331 2187 ··· 2596 2276 } 2597 2277 } 2598 2278 2599 - static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba, 2600 - unsigned int num, u32 ei_lba) 2279 + static int 2280 + resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) 2601 2281 { 2282 + u8 *cmd = scp->cmnd; 2283 + u64 lba; 2284 + u32 num; 2285 + u32 ei_lba; 2602 2286 unsigned long iflags; 2603 2287 int ret; 2288 + bool check_prot; 2604 2289 2605 - ret = check_device_access_params(SCpnt, lba, num); 2606 - if (ret) 2607 - return ret; 2290 + switch (cmd[0]) { 2291 + case WRITE_16: 2292 + ei_lba = 0; 2293 + lba = get_unaligned_be64(cmd + 2); 2294 + num = get_unaligned_be32(cmd + 10); 2295 + check_prot = true; 2296 + break; 2297 + case WRITE_10: 2298 + ei_lba = 0; 2299 + lba = get_unaligned_be32(cmd + 2); 2300 + num = get_unaligned_be16(cmd + 7); 2301 + check_prot = true; 2302 + break; 2303 + case WRITE_6: 2304 + ei_lba = 0; 2305 + lba = (u32)cmd[3] | (u32)cmd[2] << 8 | 2306 + (u32)(cmd[1] & 0x1f) << 16; 2307 + num = (0 == cmd[4]) ? 256 : cmd[4]; 2308 + check_prot = true; 2309 + break; 2310 + case WRITE_12: 2311 + ei_lba = 0; 2312 + lba = get_unaligned_be32(cmd + 2); 2313 + num = get_unaligned_be32(cmd + 6); 2314 + check_prot = true; 2315 + break; 2316 + case 0x53: /* XDWRITEREAD(10) */ 2317 + ei_lba = 0; 2318 + lba = get_unaligned_be32(cmd + 2); 2319 + num = get_unaligned_be16(cmd + 7); 2320 + check_prot = false; 2321 + break; 2322 + default: /* assume WRITE(32) */ 2323 + lba = get_unaligned_be64(cmd + 12); 2324 + ei_lba = get_unaligned_be32(cmd + 20); 2325 + num = get_unaligned_be32(cmd + 28); 2326 + check_prot = false; 2327 + break; 2328 + } 2329 + if (check_prot) { 2330 + if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && 2331 + (cmd[1] & 0xe0)) { 2332 + mk_sense_invalid_opcode(scp); 2333 + return check_condition_result; 2334 + } 2335 + if ((scsi_debug_dif == SD_DIF_TYPE1_PROTECTION || 2336 + scsi_debug_dif == SD_DIF_TYPE3_PROTECTION) && 2337 + (cmd[1] & 0xe0) == 0) 2338 + sdev_printk(KERN_ERR, scp->device, "Unprotected WR " 2339 + "to DIF device\n"); 2340 + } 2341 + 2342 + /* inline check_device_access_params() */ 2343 + if (lba + num > sdebug_capacity) { 2344 + mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0); 2345 + return check_condition_result; 2346 + } 2347 + /* transfer length excessive (tie in to block limits VPD page) */ 2348 + if (num > sdebug_store_sectors) { 2349 + /* needs work to find which cdb byte 'num' comes from */ 2350 + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); 2351 + return check_condition_result; 2352 + } 2608 2353 2609 2354 write_lock_irqsave(&atomic_rw, iflags); 2610 2355 2611 2356 /* DIX + T10 DIF */ 2612 - if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) { 2613 - int prot_ret = prot_verify_write(SCpnt, lba, num, ei_lba); 2357 + if (scsi_debug_dix && scsi_prot_sg_count(scp)) { 2358 + int prot_ret = prot_verify_write(scp, lba, num, ei_lba); 2614 2359 2615 2360 if (prot_ret) { 2616 2361 write_unlock_irqrestore(&atomic_rw, iflags); 2617 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 0x10, 2618 - prot_ret); 2362 + mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, prot_ret); 2619 2363 return illegal_condition_result; 2620 2364 } 2621 2365 } 2622 2366 2623 - ret = do_device_access(SCpnt, lba, num, 1); 2367 + ret = do_device_access(scp, lba, num, true); 2624 2368 if (scsi_debug_lbp()) 2625 2369 map_region(lba, num); 2626 2370 write_unlock_irqrestore(&atomic_rw, iflags); ··· 2692 2308 return (DID_ERROR << 16); 2693 2309 else if ((ret < (num * scsi_debug_sector_size)) && 2694 2310 (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) 2695 - sdev_printk(KERN_INFO, SCpnt->device, 2311 + sdev_printk(KERN_INFO, scp->device, 2696 2312 "%s: write: cdb indicated=%u, IO sent=%d bytes\n", 2697 2313 my_name, num * scsi_debug_sector_size, ret); 2698 2314 2315 + if (sdebug_any_injecting_opt) { 2316 + struct sdebug_scmd_extra_t *ep = scsi_cmd_priv(scp); 2317 + 2318 + if (ep->inj_recovered) { 2319 + mk_sense_buffer(scp, RECOVERED_ERROR, 2320 + THRESHOLD_EXCEEDED, 0); 2321 + return check_condition_result; 2322 + } else if (ep->inj_dif) { 2323 + /* Logical block guard check failed */ 2324 + mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, 1); 2325 + return illegal_condition_result; 2326 + } else if (ep->inj_dix) { 2327 + mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, 1); 2328 + return illegal_condition_result; 2329 + } 2330 + } 2699 2331 return 0; 2700 2332 } 2701 2333 2702 - static int resp_write_same(struct scsi_cmnd *scmd, unsigned long long lba, 2703 - unsigned int num, u32 ei_lba, unsigned int unmap) 2334 + static int 2335 + resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num, u32 ei_lba, 2336 + bool unmap, bool ndob) 2704 2337 { 2705 2338 unsigned long iflags; 2706 2339 unsigned long long i; 2707 2340 int ret; 2708 2341 2709 - ret = check_device_access_params(scmd, lba, num); 2342 + ret = check_device_access_params(scp, lba, num); 2710 2343 if (ret) 2711 2344 return ret; 2712 - 2713 - if (num > scsi_debug_write_same_length) { 2714 - mk_sense_buffer(scmd, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 2715 - 0); 2716 - return check_condition_result; 2717 - } 2718 2345 2719 2346 write_lock_irqsave(&atomic_rw, iflags); 2720 2347 ··· 2734 2339 goto out; 2735 2340 } 2736 2341 2737 - /* Else fetch one logical block */ 2738 - ret = fetch_to_dev_buffer(scmd, 2739 - fake_storep + (lba * scsi_debug_sector_size), 2740 - scsi_debug_sector_size); 2342 + /* if ndob then zero 1 logical block, else fetch 1 logical block */ 2343 + if (ndob) { 2344 + memset(fake_storep + (lba * scsi_debug_sector_size), 0, 2345 + scsi_debug_sector_size); 2346 + ret = 0; 2347 + } else 2348 + ret = fetch_to_dev_buffer(scp, fake_storep + 2349 + (lba * scsi_debug_sector_size), 2350 + scsi_debug_sector_size); 2741 2351 2742 2352 if (-1 == ret) { 2743 2353 write_unlock_irqrestore(&atomic_rw, iflags); 2744 2354 return (DID_ERROR << 16); 2745 2355 } else if ((ret < (num * scsi_debug_sector_size)) && 2746 2356 (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) 2747 - sdev_printk(KERN_INFO, scmd->device, 2357 + sdev_printk(KERN_INFO, scp->device, 2748 2358 "%s: %s: cdb indicated=%u, IO sent=%d bytes\n", 2749 2359 my_name, "write same", 2750 2360 num * scsi_debug_sector_size, ret); ··· 2768 2368 return 0; 2769 2369 } 2770 2370 2371 + static int 2372 + resp_write_same_10(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) 2373 + { 2374 + u8 *cmd = scp->cmnd; 2375 + u32 lba; 2376 + u16 num; 2377 + u32 ei_lba = 0; 2378 + bool unmap = false; 2379 + 2380 + if (cmd[1] & 0x8) { 2381 + if (scsi_debug_lbpws10 == 0) { 2382 + mk_sense_invalid_fld(scp, SDEB_IN_CDB, 1, 3); 2383 + return check_condition_result; 2384 + } else 2385 + unmap = true; 2386 + } 2387 + lba = get_unaligned_be32(cmd + 2); 2388 + num = get_unaligned_be16(cmd + 7); 2389 + if (num > scsi_debug_write_same_length) { 2390 + mk_sense_invalid_fld(scp, SDEB_IN_CDB, 7, -1); 2391 + return check_condition_result; 2392 + } 2393 + return resp_write_same(scp, lba, num, ei_lba, unmap, false); 2394 + } 2395 + 2396 + static int 2397 + resp_write_same_16(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) 2398 + { 2399 + u8 *cmd = scp->cmnd; 2400 + u64 lba; 2401 + u32 num; 2402 + u32 ei_lba = 0; 2403 + bool unmap = false; 2404 + bool ndob = false; 2405 + 2406 + if (cmd[1] & 0x8) { /* UNMAP */ 2407 + if (scsi_debug_lbpws == 0) { 2408 + mk_sense_invalid_fld(scp, SDEB_IN_CDB, 1, 3); 2409 + return check_condition_result; 2410 + } else 2411 + unmap = true; 2412 + } 2413 + if (cmd[1] & 0x1) /* NDOB (no data-out buffer, assumes zeroes) */ 2414 + ndob = true; 2415 + lba = get_unaligned_be64(cmd + 2); 2416 + num = get_unaligned_be32(cmd + 10); 2417 + if (num > scsi_debug_write_same_length) { 2418 + mk_sense_invalid_fld(scp, SDEB_IN_CDB, 10, -1); 2419 + return check_condition_result; 2420 + } 2421 + return resp_write_same(scp, lba, num, ei_lba, unmap, ndob); 2422 + } 2423 + 2771 2424 struct unmap_block_desc { 2772 2425 __be64 lba; 2773 2426 __be32 blocks; 2774 2427 __be32 __reserved; 2775 2428 }; 2776 2429 2777 - static int resp_unmap(struct scsi_cmnd * scmd, struct sdebug_dev_info * devip) 2430 + static int 2431 + resp_unmap(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) 2778 2432 { 2779 2433 unsigned char *buf; 2780 2434 struct unmap_block_desc *desc; ··· 2836 2382 int ret; 2837 2383 unsigned long iflags; 2838 2384 2839 - ret = check_readiness(scmd, UAS_ONLY, devip); 2840 - if (ret) 2841 - return ret; 2842 2385 2843 - payload_len = get_unaligned_be16(&scmd->cmnd[7]); 2844 - BUG_ON(scsi_bufflen(scmd) != payload_len); 2386 + if (!scsi_debug_lbp()) 2387 + return 0; /* fib and say its done */ 2388 + payload_len = get_unaligned_be16(scp->cmnd + 7); 2389 + BUG_ON(scsi_bufflen(scp) != payload_len); 2845 2390 2846 2391 descriptors = (payload_len - 8) / 16; 2847 - 2848 - buf = kmalloc(scsi_bufflen(scmd), GFP_ATOMIC); 2849 - if (!buf) 2392 + if (descriptors > scsi_debug_unmap_max_desc) { 2393 + mk_sense_invalid_fld(scp, SDEB_IN_CDB, 7, -1); 2850 2394 return check_condition_result; 2395 + } 2851 2396 2852 - scsi_sg_copy_to_buffer(scmd, buf, scsi_bufflen(scmd)); 2397 + buf = kmalloc(scsi_bufflen(scp), GFP_ATOMIC); 2398 + if (!buf) { 2399 + mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, 2400 + INSUFF_RES_ASCQ); 2401 + return check_condition_result; 2402 + } 2403 + 2404 + scsi_sg_copy_to_buffer(scp, buf, scsi_bufflen(scp)); 2853 2405 2854 2406 BUG_ON(get_unaligned_be16(&buf[0]) != payload_len - 2); 2855 2407 BUG_ON(get_unaligned_be16(&buf[2]) != descriptors * 16); ··· 2868 2408 unsigned long long lba = get_unaligned_be64(&desc[i].lba); 2869 2409 unsigned int num = get_unaligned_be32(&desc[i].blocks); 2870 2410 2871 - ret = check_device_access_params(scmd, lba, num); 2411 + ret = check_device_access_params(scp, lba, num); 2872 2412 if (ret) 2873 2413 goto out; 2874 2414 ··· 2886 2426 2887 2427 #define SDEBUG_GET_LBA_STATUS_LEN 32 2888 2428 2889 - static int resp_get_lba_status(struct scsi_cmnd * scmd, 2890 - struct sdebug_dev_info * devip) 2429 + static int 2430 + resp_get_lba_status(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) 2891 2431 { 2892 - unsigned long long lba; 2893 - unsigned int alloc_len, mapped, num; 2894 - unsigned char arr[SDEBUG_GET_LBA_STATUS_LEN]; 2432 + u8 *cmd = scp->cmnd; 2433 + u64 lba; 2434 + u32 alloc_len, mapped, num; 2435 + u8 arr[SDEBUG_GET_LBA_STATUS_LEN]; 2895 2436 int ret; 2896 2437 2897 - ret = check_readiness(scmd, UAS_ONLY, devip); 2898 - if (ret) 2899 - return ret; 2900 - 2901 - lba = get_unaligned_be64(&scmd->cmnd[2]); 2902 - alloc_len = get_unaligned_be32(&scmd->cmnd[10]); 2438 + lba = get_unaligned_be64(cmd + 2); 2439 + alloc_len = get_unaligned_be32(cmd + 10); 2903 2440 2904 2441 if (alloc_len < 24) 2905 2442 return 0; 2906 2443 2907 - ret = check_device_access_params(scmd, lba, 1); 2444 + ret = check_device_access_params(scp, lba, 1); 2908 2445 if (ret) 2909 2446 return ret; 2910 2447 2911 - mapped = map_state(lba, &num); 2448 + if (scsi_debug_lbp()) 2449 + mapped = map_state(lba, &num); 2450 + else { 2451 + mapped = 1; 2452 + /* following just in case virtual_gb changed */ 2453 + sdebug_capacity = get_sdebug_capacity(); 2454 + if (sdebug_capacity - lba <= 0xffffffff) 2455 + num = sdebug_capacity - lba; 2456 + else 2457 + num = 0xffffffff; 2458 + } 2912 2459 2913 2460 memset(arr, 0, SDEBUG_GET_LBA_STATUS_LEN); 2914 - put_unaligned_be32(20, &arr[0]); /* Parameter Data Length */ 2915 - put_unaligned_be64(lba, &arr[8]); /* LBA */ 2916 - put_unaligned_be32(num, &arr[16]); /* Number of blocks */ 2917 - arr[20] = !mapped; /* mapped = 0, unmapped = 1 */ 2461 + put_unaligned_be32(20, arr); /* Parameter Data Length */ 2462 + put_unaligned_be64(lba, arr + 8); /* LBA */ 2463 + put_unaligned_be32(num, arr + 16); /* Number of blocks */ 2464 + arr[20] = !mapped; /* prov_stat=0: mapped; 1: dealloc */ 2918 2465 2919 - return fill_from_dev_buffer(scmd, arr, SDEBUG_GET_LBA_STATUS_LEN); 2466 + return fill_from_dev_buffer(scp, arr, SDEBUG_GET_LBA_STATUS_LEN); 2920 2467 } 2921 2468 2922 2469 #define SDEBUG_RLUN_ARR_SZ 256 ··· 3018 2551 kfree(buf); 3019 2552 3020 2553 return 0; 2554 + } 2555 + 2556 + static int 2557 + resp_xdwriteread_10(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) 2558 + { 2559 + u8 *cmd = scp->cmnd; 2560 + u64 lba; 2561 + u32 num; 2562 + int errsts; 2563 + 2564 + if (!scsi_bidi_cmnd(scp)) { 2565 + mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, 2566 + INSUFF_RES_ASCQ); 2567 + return check_condition_result; 2568 + } 2569 + errsts = resp_read_dt0(scp, devip); 2570 + if (errsts) 2571 + return errsts; 2572 + if (!(cmd[1] & 0x4)) { /* DISABLE_WRITE is not set */ 2573 + errsts = resp_write_dt0(scp, devip); 2574 + if (errsts) 2575 + return errsts; 2576 + } 2577 + lba = get_unaligned_be32(cmd + 2); 2578 + num = get_unaligned_be16(cmd + 7); 2579 + return resp_xdwriteread(scp, lba, num, devip); 3021 2580 } 3022 2581 3023 2582 /* When timer or tasklet goes off this function is called. */ ··· 3218 2725 open_devip->sdbg_host = sdbg_host; 3219 2726 atomic_set(&open_devip->num_in_q, 0); 3220 2727 set_bit(SDEBUG_UA_POR, open_devip->uas_bm); 3221 - open_devip->used = 1; 3222 - if (sdev->lun == SAM2_WLUN_REPORT_LUNS) 3223 - open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff; 3224 - 2728 + open_devip->used = true; 3225 2729 return open_devip; 3226 2730 } 3227 2731 ··· 3260 2770 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); 3261 2771 if (devip) { 3262 2772 /* make this slot available for re-use */ 3263 - devip->used = 0; 2773 + devip->used = false; 3264 2774 sdp->hostdata = NULL; 3265 2775 } 3266 2776 } ··· 3705 3215 module_param_named(removable, scsi_debug_removable, bool, S_IRUGO | S_IWUSR); 3706 3216 module_param_named(scsi_level, scsi_debug_scsi_level, int, S_IRUGO); 3707 3217 module_param_named(sector_size, scsi_debug_sector_size, int, S_IRUGO); 3218 + module_param_named(strict, scsi_debug_strict, bool, S_IRUGO | S_IWUSR); 3708 3219 module_param_named(unmap_alignment, scsi_debug_unmap_alignment, int, S_IRUGO); 3709 3220 module_param_named(unmap_granularity, scsi_debug_unmap_granularity, int, S_IRUGO); 3710 3221 module_param_named(unmap_max_blocks, scsi_debug_unmap_max_blocks, int, S_IRUGO); ··· 3725 3234 MODULE_PARM_DESC(ato, "application tag ownership: 0=disk 1=host (def=1)"); 3726 3235 MODULE_PARM_DESC(clustering, "when set enables larger transfers (def=0)"); 3727 3236 MODULE_PARM_DESC(delay, "response delay (def=1 jiffy); 0:imm, -1,-2:tiny"); 3728 - MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs(def=8)"); 3237 + MODULE_PARM_DESC(dev_size_mb, "size in MiB of ram shared by devs(def=8)"); 3729 3238 MODULE_PARM_DESC(dif, "data integrity field type: 0-3 (def=0)"); 3730 3239 MODULE_PARM_DESC(dix, "data integrity extensions mask (def=0)"); 3731 3240 MODULE_PARM_DESC(dsense, "use descriptor sense format(def=0 -> fixed)"); ··· 3752 3261 MODULE_PARM_DESC(removable, "claim to have removable media (def=0)"); 3753 3262 MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=6[SPC-4])"); 3754 3263 MODULE_PARM_DESC(sector_size, "logical block size in bytes (def=512)"); 3264 + MODULE_PARM_DESC(strict, "stricter checks: reserved field in cdb (def=0)"); 3755 3265 MODULE_PARM_DESC(unmap_alignment, "lowest aligned thin provisioning lba (def=0)"); 3756 3266 MODULE_PARM_DESC(unmap_granularity, "thin provisioning granularity in blocks (def=1)"); 3757 3267 MODULE_PARM_DESC(unmap_max_blocks, "max # of blocks can be unmapped in one cmd (def=0xffffffff)"); 3758 3268 MODULE_PARM_DESC(unmap_max_desc, "max # of ranges that can be unmapped in one cmd (def=256)"); 3759 - MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)"); 3269 + MODULE_PARM_DESC(virtual_gb, "virtual gigabyte (GiB) size (def=0 -> use dev_size_mb)"); 3760 3270 MODULE_PARM_DESC(vpd_use_hostno, "0 -> dev ids ignore hostno (def=1 -> unique dev ids)"); 3761 3271 MODULE_PARM_DESC(write_same_length, "Maximum blocks per WRITE SAME cmd (def=0xffff)"); 3762 3272 ··· 4136 3644 { 4137 3645 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_virtual_gb); 4138 3646 } 4139 - 4140 3647 static ssize_t virtual_gb_store(struct device_driver *ddp, const char *buf, 4141 3648 size_t count) 4142 3649 { 4143 - int n; 3650 + int n; 4144 3651 bool changed; 4145 3652 4146 3653 if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { ··· 4304 3813 } 4305 3814 static DRIVER_ATTR_RW(host_lock); 4306 3815 3816 + static ssize_t strict_show(struct device_driver *ddp, char *buf) 3817 + { 3818 + return scnprintf(buf, PAGE_SIZE, "%d\n", !!scsi_debug_strict); 3819 + } 3820 + static ssize_t strict_store(struct device_driver *ddp, const char *buf, 3821 + size_t count) 3822 + { 3823 + int n; 3824 + 3825 + if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { 3826 + scsi_debug_strict = (n > 0); 3827 + return count; 3828 + } 3829 + return -EINVAL; 3830 + } 3831 + static DRIVER_ATTR_RW(strict); 3832 + 4307 3833 4308 3834 /* Note: The following array creates attribute files in the 4309 3835 /sys/bus/pseudo/drivers/scsi_debug directory. The advantage of these ··· 4356 3848 &driver_attr_removable.attr, 4357 3849 &driver_attr_host_lock.attr, 4358 3850 &driver_attr_ndelay.attr, 3851 + &driver_attr_strict.attr, 4359 3852 NULL, 4360 3853 }; 4361 3854 ATTRIBUTE_GROUPS(sdebug_drv); ··· 4669 4160 } 4670 4161 4671 4162 static int 4672 - scsi_debug_queuecommand(struct scsi_cmnd *SCpnt) 4673 - { 4674 - unsigned char *cmd = SCpnt->cmnd; 4675 - int len, k; 4676 - unsigned int num; 4677 - unsigned long long lba; 4678 - u32 ei_lba; 4679 - int errsts = 0; 4680 - int target = SCpnt->device->id; 4681 - struct sdebug_dev_info *devip = NULL; 4682 - int inj_recovered = 0; 4683 - int inj_transport = 0; 4684 - int inj_dif = 0; 4685 - int inj_dix = 0; 4686 - int inj_short = 0; 4687 - int delay_override = 0; 4688 - int unmap = 0; 4689 - 4690 - scsi_set_resid(SCpnt, 0); 4691 - if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && 4692 - !(SCSI_DEBUG_OPT_NO_CDB_NOISE & scsi_debug_opts)) { 4693 - char b[120]; 4694 - int n; 4695 - 4696 - len = SCpnt->cmd_len; 4697 - if (len > 32) 4698 - strcpy(b, "too long, over 32 bytes"); 4699 - else { 4700 - for (k = 0, n = 0; k < len; ++k) 4701 - n += scnprintf(b + n, sizeof(b) - n, "%02x ", 4702 - (unsigned int)cmd[k]); 4703 - } 4704 - sdev_printk(KERN_INFO, SCpnt->device, "%s: cmd %s\n", my_name, 4705 - b); 4706 - } 4707 - 4708 - if ((SCpnt->device->lun >= scsi_debug_max_luns) && 4709 - (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS)) 4710 - return schedule_resp(SCpnt, NULL, DID_NO_CONNECT << 16, 0); 4711 - devip = devInfoReg(SCpnt->device); 4712 - if (NULL == devip) 4713 - return schedule_resp(SCpnt, NULL, DID_NO_CONNECT << 16, 0); 4714 - 4715 - if ((scsi_debug_every_nth != 0) && 4716 - (atomic_inc_return(&sdebug_cmnd_count) >= 4717 - abs(scsi_debug_every_nth))) { 4718 - atomic_set(&sdebug_cmnd_count, 0); 4719 - if (scsi_debug_every_nth < -1) 4720 - scsi_debug_every_nth = -1; 4721 - if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts) 4722 - return 0; /* ignore command causing timeout */ 4723 - else if (SCSI_DEBUG_OPT_MAC_TIMEOUT & scsi_debug_opts && 4724 - scsi_medium_access_command(SCpnt)) 4725 - return 0; /* time out reads and writes */ 4726 - else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts) 4727 - inj_recovered = 1; /* to reads and writes below */ 4728 - else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts) 4729 - inj_transport = 1; /* to reads and writes below */ 4730 - else if (SCSI_DEBUG_OPT_DIF_ERR & scsi_debug_opts) 4731 - inj_dif = 1; /* to reads and writes below */ 4732 - else if (SCSI_DEBUG_OPT_DIX_ERR & scsi_debug_opts) 4733 - inj_dix = 1; /* to reads and writes below */ 4734 - else if (SCSI_DEBUG_OPT_SHORT_TRANSFER & scsi_debug_opts) 4735 - inj_short = 1; 4736 - } 4737 - 4738 - if (devip->wlun) { 4739 - switch (*cmd) { 4740 - case INQUIRY: 4741 - case REQUEST_SENSE: 4742 - case TEST_UNIT_READY: 4743 - case REPORT_LUNS: 4744 - break; /* only allowable wlun commands */ 4745 - default: 4746 - if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 4747 - printk(KERN_INFO "scsi_debug: Opcode: 0x%x " 4748 - "not supported for wlun\n", *cmd); 4749 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 4750 - INVALID_OPCODE, 0); 4751 - errsts = check_condition_result; 4752 - return schedule_resp(SCpnt, devip, errsts, 0); 4753 - } 4754 - } 4755 - 4756 - switch (*cmd) { 4757 - case INQUIRY: /* mandatory, ignore unit attention */ 4758 - delay_override = 1; 4759 - errsts = resp_inquiry(SCpnt, target, devip); 4760 - break; 4761 - case REQUEST_SENSE: /* mandatory, ignore unit attention */ 4762 - delay_override = 1; 4763 - errsts = resp_requests(SCpnt, devip); 4764 - break; 4765 - case REZERO_UNIT: /* actually this is REWIND for SSC */ 4766 - case START_STOP: 4767 - errsts = resp_start_stop(SCpnt, devip); 4768 - break; 4769 - case ALLOW_MEDIUM_REMOVAL: 4770 - errsts = check_readiness(SCpnt, UAS_ONLY, devip); 4771 - if (errsts) 4772 - break; 4773 - if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 4774 - printk(KERN_INFO "scsi_debug: Medium removal %s\n", 4775 - cmd[4] ? "inhibited" : "enabled"); 4776 - break; 4777 - case SEND_DIAGNOSTIC: /* mandatory */ 4778 - errsts = check_readiness(SCpnt, UAS_ONLY, devip); 4779 - break; 4780 - case TEST_UNIT_READY: /* mandatory */ 4781 - /* delay_override = 1; */ 4782 - errsts = check_readiness(SCpnt, UAS_TUR, devip); 4783 - break; 4784 - case RESERVE: 4785 - errsts = check_readiness(SCpnt, UAS_ONLY, devip); 4786 - break; 4787 - case RESERVE_10: 4788 - errsts = check_readiness(SCpnt, UAS_ONLY, devip); 4789 - break; 4790 - case RELEASE: 4791 - errsts = check_readiness(SCpnt, UAS_ONLY, devip); 4792 - break; 4793 - case RELEASE_10: 4794 - errsts = check_readiness(SCpnt, UAS_ONLY, devip); 4795 - break; 4796 - case READ_CAPACITY: 4797 - errsts = resp_readcap(SCpnt, devip); 4798 - break; 4799 - case SERVICE_ACTION_IN: 4800 - if (cmd[1] == SAI_READ_CAPACITY_16) 4801 - errsts = resp_readcap16(SCpnt, devip); 4802 - else if (cmd[1] == SAI_GET_LBA_STATUS) { 4803 - 4804 - if (scsi_debug_lbp() == 0) { 4805 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 4806 - INVALID_COMMAND_OPCODE, 0); 4807 - errsts = check_condition_result; 4808 - } else 4809 - errsts = resp_get_lba_status(SCpnt, devip); 4810 - } else { 4811 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 4812 - INVALID_OPCODE, 0); 4813 - errsts = check_condition_result; 4814 - } 4815 - break; 4816 - case MAINTENANCE_IN: 4817 - if (MI_REPORT_TARGET_PGS != cmd[1]) { 4818 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 4819 - INVALID_OPCODE, 0); 4820 - errsts = check_condition_result; 4821 - break; 4822 - } 4823 - errsts = resp_report_tgtpgs(SCpnt, devip); 4824 - break; 4825 - case READ_16: 4826 - case READ_12: 4827 - case READ_10: 4828 - /* READ{10,12,16} and DIF Type 2 are natural enemies */ 4829 - if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && 4830 - cmd[1] & 0xe0) { 4831 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 4832 - INVALID_COMMAND_OPCODE, 0); 4833 - errsts = check_condition_result; 4834 - break; 4835 - } 4836 - 4837 - if ((scsi_debug_dif == SD_DIF_TYPE1_PROTECTION || 4838 - scsi_debug_dif == SD_DIF_TYPE3_PROTECTION) && 4839 - (cmd[1] & 0xe0) == 0) 4840 - printk(KERN_ERR "Unprotected RD/WR to DIF device\n"); 4841 - 4842 - /* fall through */ 4843 - case READ_6: 4844 - read: 4845 - errsts = check_readiness(SCpnt, UAS_TUR, devip); 4846 - if (errsts) 4847 - break; 4848 - if (scsi_debug_fake_rw) 4849 - break; 4850 - get_data_transfer_info(cmd, &lba, &num, &ei_lba); 4851 - 4852 - if (inj_short) 4853 - num /= 2; 4854 - 4855 - errsts = resp_read(SCpnt, lba, num, ei_lba); 4856 - if (inj_recovered && (0 == errsts)) { 4857 - mk_sense_buffer(SCpnt, RECOVERED_ERROR, 4858 - THRESHOLD_EXCEEDED, 0); 4859 - errsts = check_condition_result; 4860 - } else if (inj_transport && (0 == errsts)) { 4861 - mk_sense_buffer(SCpnt, ABORTED_COMMAND, 4862 - TRANSPORT_PROBLEM, ACK_NAK_TO); 4863 - errsts = check_condition_result; 4864 - } else if (inj_dif && (0 == errsts)) { 4865 - /* Logical block guard check failed */ 4866 - mk_sense_buffer(SCpnt, ABORTED_COMMAND, 0x10, 1); 4867 - errsts = illegal_condition_result; 4868 - } else if (inj_dix && (0 == errsts)) { 4869 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 0x10, 1); 4870 - errsts = illegal_condition_result; 4871 - } 4872 - break; 4873 - case REPORT_LUNS: /* mandatory, ignore unit attention */ 4874 - delay_override = 1; 4875 - errsts = resp_report_luns(SCpnt, devip); 4876 - break; 4877 - case VERIFY: /* 10 byte SBC-2 command */ 4878 - errsts = check_readiness(SCpnt, UAS_TUR, devip); 4879 - break; 4880 - case WRITE_16: 4881 - case WRITE_12: 4882 - case WRITE_10: 4883 - /* WRITE{10,12,16} and DIF Type 2 are natural enemies */ 4884 - if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && 4885 - cmd[1] & 0xe0) { 4886 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 4887 - INVALID_COMMAND_OPCODE, 0); 4888 - errsts = check_condition_result; 4889 - break; 4890 - } 4891 - 4892 - if ((scsi_debug_dif == SD_DIF_TYPE1_PROTECTION || 4893 - scsi_debug_dif == SD_DIF_TYPE3_PROTECTION) && 4894 - (cmd[1] & 0xe0) == 0) 4895 - printk(KERN_ERR "Unprotected RD/WR to DIF device\n"); 4896 - 4897 - /* fall through */ 4898 - case WRITE_6: 4899 - write: 4900 - errsts = check_readiness(SCpnt, UAS_TUR, devip); 4901 - if (errsts) 4902 - break; 4903 - if (scsi_debug_fake_rw) 4904 - break; 4905 - get_data_transfer_info(cmd, &lba, &num, &ei_lba); 4906 - errsts = resp_write(SCpnt, lba, num, ei_lba); 4907 - if (inj_recovered && (0 == errsts)) { 4908 - mk_sense_buffer(SCpnt, RECOVERED_ERROR, 4909 - THRESHOLD_EXCEEDED, 0); 4910 - errsts = check_condition_result; 4911 - } else if (inj_dif && (0 == errsts)) { 4912 - mk_sense_buffer(SCpnt, ABORTED_COMMAND, 0x10, 1); 4913 - errsts = illegal_condition_result; 4914 - } else if (inj_dix && (0 == errsts)) { 4915 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 0x10, 1); 4916 - errsts = illegal_condition_result; 4917 - } 4918 - break; 4919 - case WRITE_SAME_16: 4920 - case WRITE_SAME: 4921 - if (cmd[1] & 0x8) { 4922 - if ((*cmd == WRITE_SAME_16 && scsi_debug_lbpws == 0) || 4923 - (*cmd == WRITE_SAME && scsi_debug_lbpws10 == 0)) { 4924 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 4925 - INVALID_FIELD_IN_CDB, 0); 4926 - errsts = check_condition_result; 4927 - } else 4928 - unmap = 1; 4929 - } 4930 - if (errsts) 4931 - break; 4932 - errsts = check_readiness(SCpnt, UAS_TUR, devip); 4933 - if (errsts) 4934 - break; 4935 - if (scsi_debug_fake_rw) 4936 - break; 4937 - get_data_transfer_info(cmd, &lba, &num, &ei_lba); 4938 - errsts = resp_write_same(SCpnt, lba, num, ei_lba, unmap); 4939 - break; 4940 - case UNMAP: 4941 - errsts = check_readiness(SCpnt, UAS_TUR, devip); 4942 - if (errsts) 4943 - break; 4944 - if (scsi_debug_fake_rw) 4945 - break; 4946 - 4947 - if (scsi_debug_unmap_max_desc == 0 || scsi_debug_lbpu == 0) { 4948 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 4949 - INVALID_COMMAND_OPCODE, 0); 4950 - errsts = check_condition_result; 4951 - } else 4952 - errsts = resp_unmap(SCpnt, devip); 4953 - break; 4954 - case MODE_SENSE: 4955 - case MODE_SENSE_10: 4956 - errsts = resp_mode_sense(SCpnt, target, devip); 4957 - break; 4958 - case MODE_SELECT: 4959 - errsts = resp_mode_select(SCpnt, 1, devip); 4960 - break; 4961 - case MODE_SELECT_10: 4962 - errsts = resp_mode_select(SCpnt, 0, devip); 4963 - break; 4964 - case LOG_SENSE: 4965 - errsts = resp_log_sense(SCpnt, devip); 4966 - break; 4967 - case SYNCHRONIZE_CACHE: 4968 - delay_override = 1; 4969 - errsts = check_readiness(SCpnt, UAS_TUR, devip); 4970 - break; 4971 - case WRITE_BUFFER: 4972 - errsts = check_readiness(SCpnt, UAS_ONLY, devip); 4973 - break; 4974 - case XDWRITEREAD_10: 4975 - if (!scsi_bidi_cmnd(SCpnt)) { 4976 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 4977 - INVALID_FIELD_IN_CDB, 0); 4978 - errsts = check_condition_result; 4979 - break; 4980 - } 4981 - 4982 - errsts = check_readiness(SCpnt, UAS_TUR, devip); 4983 - if (errsts) 4984 - break; 4985 - if (scsi_debug_fake_rw) 4986 - break; 4987 - get_data_transfer_info(cmd, &lba, &num, &ei_lba); 4988 - errsts = resp_read(SCpnt, lba, num, ei_lba); 4989 - if (errsts) 4990 - break; 4991 - errsts = resp_write(SCpnt, lba, num, ei_lba); 4992 - if (errsts) 4993 - break; 4994 - errsts = resp_xdwriteread(SCpnt, lba, num, devip); 4995 - break; 4996 - case VARIABLE_LENGTH_CMD: 4997 - if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION) { 4998 - 4999 - if ((cmd[10] & 0xe0) == 0) 5000 - printk(KERN_ERR 5001 - "Unprotected RD/WR to DIF device\n"); 5002 - 5003 - if (cmd[9] == READ_32) { 5004 - BUG_ON(SCpnt->cmd_len < 32); 5005 - goto read; 5006 - } 5007 - 5008 - if (cmd[9] == WRITE_32) { 5009 - BUG_ON(SCpnt->cmd_len < 32); 5010 - goto write; 5011 - } 5012 - } 5013 - 5014 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 5015 - INVALID_FIELD_IN_CDB, 0); 5016 - errsts = check_condition_result; 5017 - break; 5018 - case 0x85: 5019 - if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 5020 - sdev_printk(KERN_INFO, SCpnt->device, 5021 - "%s: ATA PASS-THROUGH(16) not supported\n", my_name); 5022 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 5023 - INVALID_OPCODE, 0); 5024 - errsts = check_condition_result; 5025 - break; 5026 - default: 5027 - if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 5028 - sdev_printk(KERN_INFO, SCpnt->device, 5029 - "%s: Opcode: 0x%x not supported\n", 5030 - my_name, *cmd); 5031 - errsts = check_readiness(SCpnt, UAS_ONLY, devip); 5032 - if (errsts) 5033 - break; /* Unit attention takes precedence */ 5034 - mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, INVALID_OPCODE, 0); 5035 - errsts = check_condition_result; 5036 - break; 5037 - } 5038 - return schedule_resp(SCpnt, devip, errsts, 5039 - (delay_override ? 0 : scsi_debug_delay)); 5040 - } 5041 - 5042 - static int 5043 4163 sdebug_queuecommand_lock_or_not(struct Scsi_Host *shost, struct scsi_cmnd *cmd) 5044 4164 { 5045 4165 if (scsi_debug_host_lock) { ··· 4773 4635 } 4774 4636 } 4775 4637 return 0; 4638 + } 4639 + 4640 + static int 4641 + scsi_debug_queuecommand(struct scsi_cmnd *scp) 4642 + { 4643 + u8 sdeb_i; 4644 + struct scsi_device *sdp = scp->device; 4645 + const struct opcode_info_t *oip; 4646 + const struct opcode_info_t *r_oip; 4647 + struct sdebug_dev_info *devip; 4648 + u8 *cmd = scp->cmnd; 4649 + int (*r_pfp)(struct scsi_cmnd *, struct sdebug_dev_info *); 4650 + int k, na; 4651 + int errsts = 0; 4652 + int errsts_no_connect = DID_NO_CONNECT << 16; 4653 + u32 flags; 4654 + u16 sa; 4655 + u8 opcode = cmd[0]; 4656 + bool has_wlun_rl; 4657 + bool debug = !!(SCSI_DEBUG_OPT_NOISE & scsi_debug_opts); 4658 + 4659 + scsi_set_resid(scp, 0); 4660 + if (debug && !(SCSI_DEBUG_OPT_NO_CDB_NOISE & scsi_debug_opts)) { 4661 + char b[120]; 4662 + int n, len, sb; 4663 + 4664 + len = scp->cmd_len; 4665 + sb = (int)sizeof(b); 4666 + if (len > 32) 4667 + strcpy(b, "too long, over 32 bytes"); 4668 + else { 4669 + for (k = 0, n = 0; k < len && n < sb; ++k) 4670 + n += scnprintf(b + n, sb - n, "%02x ", 4671 + (u32)cmd[k]); 4672 + } 4673 + sdev_printk(KERN_INFO, sdp, "%s: cmd %s\n", my_name, b); 4674 + } 4675 + has_wlun_rl = (sdp->lun == SAM2_WLUN_REPORT_LUNS); 4676 + if ((sdp->lun >= scsi_debug_max_luns) && !has_wlun_rl) 4677 + return schedule_resp(scp, NULL, errsts_no_connect, 0); 4678 + 4679 + sdeb_i = opcode_ind_arr[opcode]; /* fully mapped */ 4680 + oip = &opcode_info_arr[sdeb_i]; /* safe if table consistent */ 4681 + devip = (struct sdebug_dev_info *)sdp->hostdata; 4682 + if (!devip) { 4683 + devip = devInfoReg(sdp); 4684 + if (NULL == devip) 4685 + return schedule_resp(scp, NULL, errsts_no_connect, 0); 4686 + } 4687 + na = oip->num_attached; 4688 + r_pfp = oip->pfp; 4689 + if (na) { /* multiple commands with this opcode */ 4690 + r_oip = oip; 4691 + if (FF_SA & r_oip->flags) { 4692 + if (F_SA_LOW & oip->flags) 4693 + sa = 0x1f & cmd[1]; 4694 + else 4695 + sa = get_unaligned_be16(cmd + 8); 4696 + for (k = 0; k <= na; oip = r_oip->arrp + k++) { 4697 + if (opcode == oip->opcode && sa == oip->sa) 4698 + break; 4699 + } 4700 + } else { /* since no service action only check opcode */ 4701 + for (k = 0; k <= na; oip = r_oip->arrp + k++) { 4702 + if (opcode == oip->opcode) 4703 + break; 4704 + } 4705 + } 4706 + if (k > na) { 4707 + if (F_SA_LOW & r_oip->flags) 4708 + mk_sense_invalid_fld(scp, SDEB_IN_CDB, 1, 4); 4709 + else if (F_SA_HIGH & r_oip->flags) 4710 + mk_sense_invalid_fld(scp, SDEB_IN_CDB, 8, 7); 4711 + else 4712 + mk_sense_invalid_opcode(scp); 4713 + goto check_cond; 4714 + } 4715 + } /* else (when na==0) we assume the oip is a match */ 4716 + flags = oip->flags; 4717 + if (F_INV_OP & flags) { 4718 + mk_sense_invalid_opcode(scp); 4719 + goto check_cond; 4720 + } 4721 + if (has_wlun_rl && !(F_RL_WLUN_OK & flags)) { 4722 + if (debug) 4723 + sdev_printk(KERN_INFO, sdp, "scsi_debug: Opcode: " 4724 + "0x%x not supported for wlun\n", opcode); 4725 + mk_sense_invalid_opcode(scp); 4726 + goto check_cond; 4727 + } 4728 + if (scsi_debug_strict) { /* check cdb against mask */ 4729 + u8 rem; 4730 + int j; 4731 + 4732 + for (k = 1; k < oip->len_mask[0] && k < 16; ++k) { 4733 + rem = ~oip->len_mask[k] & cmd[k]; 4734 + if (rem) { 4735 + for (j = 7; j >= 0; --j, rem <<= 1) { 4736 + if (0x80 & rem) 4737 + break; 4738 + } 4739 + mk_sense_invalid_fld(scp, SDEB_IN_CDB, k, j); 4740 + goto check_cond; 4741 + } 4742 + } 4743 + } 4744 + if (!(F_SKIP_UA & flags) && 4745 + SDEBUG_NUM_UAS != find_first_bit(devip->uas_bm, SDEBUG_NUM_UAS)) { 4746 + errsts = check_readiness(scp, UAS_ONLY, devip); 4747 + if (errsts) 4748 + goto check_cond; 4749 + } 4750 + if ((F_M_ACCESS & flags) && devip->stopped) { 4751 + mk_sense_buffer(scp, NOT_READY, LOGICAL_UNIT_NOT_READY, 0x2); 4752 + if (debug) 4753 + sdev_printk(KERN_INFO, sdp, "%s reports: Not ready: " 4754 + "%s\n", my_name, "initializing command " 4755 + "required"); 4756 + errsts = check_condition_result; 4757 + goto fini; 4758 + } 4759 + if (scsi_debug_fake_rw && (F_FAKE_RW & flags)) 4760 + goto fini; 4761 + if (scsi_debug_every_nth) { 4762 + if (check_inject(scp)) 4763 + return 0; /* ignore command: make trouble */ 4764 + } 4765 + if (oip->pfp) /* if this command has a resp_* function, call it */ 4766 + errsts = oip->pfp(scp, devip); 4767 + else if (r_pfp) /* if leaf function ptr NULL, try the root's */ 4768 + errsts = r_pfp(scp, devip); 4769 + 4770 + fini: 4771 + return schedule_resp(scp, devip, errsts, 4772 + ((F_DELAY_OVERR & flags) ? 0 : scsi_debug_delay)); 4773 + check_cond: 4774 + return schedule_resp(scp, devip, check_condition_result, 0); 4776 4775 } 4777 4776 4778 4777 static struct scsi_host_template sdebug_driver_template = {