diff options
author | FUJITA Tomonori <tomof@acm.org> | 2008-01-22 11:31:59 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-30 14:14:24 -0500 |
commit | 3de9f944797177e405dcab05f12560a497c019bb (patch) | |
tree | f3c4f4608cd0889055b9e660aa8960c6fbdb8bdb /drivers/scsi/scsi_debug.c | |
parent | d3f46f39b7092594b498abc12f0c73b0b9913bde (diff) |
[SCSI] scsi_debug: add get_data_transfer_info helper function
This adds get_data_transfer_info helper function that get lha and
sectors for READ_* and WRITE_* commands (and XDWRITEREAD_10 later).
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: Douglas Gilbert <dougg@torque.net>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/scsi_debug.c')
-rw-r--r-- | drivers/scsi/scsi_debug.c | 83 |
1 files changed, 38 insertions, 45 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 82c06f0a9d02..31f7378c5c46 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -311,12 +311,47 @@ static void sdebug_max_tgts_luns(void); | |||
311 | static struct device pseudo_primary; | 311 | static struct device pseudo_primary; |
312 | static struct bus_type pseudo_lld_bus; | 312 | static struct bus_type pseudo_lld_bus; |
313 | 313 | ||
314 | static void get_data_transfer_info(unsigned char *cmd, | ||
315 | unsigned long long *lba, unsigned int *num) | ||
316 | { | ||
317 | int i; | ||
318 | |||
319 | switch (*cmd) { | ||
320 | case WRITE_16: | ||
321 | case READ_16: | ||
322 | for (*lba = 0, i = 0; i < 8; ++i) { | ||
323 | if (i > 0) | ||
324 | *lba <<= 8; | ||
325 | *lba += cmd[2 + i]; | ||
326 | } | ||
327 | *num = cmd[13] + (cmd[12] << 8) + | ||
328 | (cmd[11] << 16) + (cmd[10] << 24); | ||
329 | break; | ||
330 | case WRITE_12: | ||
331 | case READ_12: | ||
332 | *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); | ||
333 | *num = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); | ||
334 | break; | ||
335 | case WRITE_10: | ||
336 | case READ_10: | ||
337 | *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); | ||
338 | *num = cmd[8] + (cmd[7] << 8); | ||
339 | break; | ||
340 | case WRITE_6: | ||
341 | case READ_6: | ||
342 | *lba = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16); | ||
343 | *num = (0 == cmd[4]) ? 256 : cmd[4]; | ||
344 | break; | ||
345 | default: | ||
346 | break; | ||
347 | } | ||
348 | } | ||
314 | 349 | ||
315 | static | 350 | static |
316 | int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | 351 | int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) |
317 | { | 352 | { |
318 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; | 353 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; |
319 | int len, k, j; | 354 | int len, k; |
320 | unsigned int num; | 355 | unsigned int num; |
321 | unsigned long long lba; | 356 | unsigned long long lba; |
322 | int errsts = 0; | 357 | int errsts = 0; |
@@ -452,28 +487,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
452 | break; | 487 | break; |
453 | if (scsi_debug_fake_rw) | 488 | if (scsi_debug_fake_rw) |
454 | break; | 489 | break; |
455 | if ((*cmd) == READ_16) { | 490 | get_data_transfer_info(cmd, &lba, &num); |
456 | for (lba = 0, j = 0; j < 8; ++j) { | ||
457 | if (j > 0) | ||
458 | lba <<= 8; | ||
459 | lba += cmd[2 + j]; | ||
460 | } | ||
461 | num = cmd[13] + (cmd[12] << 8) + | ||
462 | (cmd[11] << 16) + (cmd[10] << 24); | ||
463 | } else if ((*cmd) == READ_12) { | ||
464 | lba = cmd[5] + (cmd[4] << 8) + | ||
465 | (cmd[3] << 16) + (cmd[2] << 24); | ||
466 | num = cmd[9] + (cmd[8] << 8) + | ||
467 | (cmd[7] << 16) + (cmd[6] << 24); | ||
468 | } else if ((*cmd) == READ_10) { | ||
469 | lba = cmd[5] + (cmd[4] << 8) + | ||
470 | (cmd[3] << 16) + (cmd[2] << 24); | ||
471 | num = cmd[8] + (cmd[7] << 8); | ||
472 | } else { /* READ (6) */ | ||
473 | lba = cmd[3] + (cmd[2] << 8) + | ||
474 | ((cmd[1] & 0x1f) << 16); | ||
475 | num = (0 == cmd[4]) ? 256 : cmd[4]; | ||
476 | } | ||
477 | errsts = resp_read(SCpnt, lba, num, devip); | 491 | errsts = resp_read(SCpnt, lba, num, devip); |
478 | if (inj_recovered && (0 == errsts)) { | 492 | if (inj_recovered && (0 == errsts)) { |
479 | mk_sense_buffer(devip, RECOVERED_ERROR, | 493 | mk_sense_buffer(devip, RECOVERED_ERROR, |
@@ -500,28 +514,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
500 | break; | 514 | break; |
501 | if (scsi_debug_fake_rw) | 515 | if (scsi_debug_fake_rw) |
502 | break; | 516 | break; |
503 | if ((*cmd) == WRITE_16) { | 517 | get_data_transfer_info(cmd, &lba, &num); |
504 | for (lba = 0, j = 0; j < 8; ++j) { | ||
505 | if (j > 0) | ||
506 | lba <<= 8; | ||
507 | lba += cmd[2 + j]; | ||
508 | } | ||
509 | num = cmd[13] + (cmd[12] << 8) + | ||
510 | (cmd[11] << 16) + (cmd[10] << 24); | ||
511 | } else if ((*cmd) == WRITE_12) { | ||
512 | lba = cmd[5] + (cmd[4] << 8) + | ||
513 | (cmd[3] << 16) + (cmd[2] << 24); | ||
514 | num = cmd[9] + (cmd[8] << 8) + | ||
515 | (cmd[7] << 16) + (cmd[6] << 24); | ||
516 | } else if ((*cmd) == WRITE_10) { | ||
517 | lba = cmd[5] + (cmd[4] << 8) + | ||
518 | (cmd[3] << 16) + (cmd[2] << 24); | ||
519 | num = cmd[8] + (cmd[7] << 8); | ||
520 | } else { /* WRITE (6) */ | ||
521 | lba = cmd[3] + (cmd[2] << 8) + | ||
522 | ((cmd[1] & 0x1f) << 16); | ||
523 | num = (0 == cmd[4]) ? 256 : cmd[4]; | ||
524 | } | ||
525 | errsts = resp_write(SCpnt, lba, num, devip); | 518 | errsts = resp_write(SCpnt, lba, num, devip); |
526 | if (inj_recovered && (0 == errsts)) { | 519 | if (inj_recovered && (0 == errsts)) { |
527 | mk_sense_buffer(devip, RECOVERED_ERROR, | 520 | mk_sense_buffer(devip, RECOVERED_ERROR, |