aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_debug.c')
-rw-r--r--drivers/scsi/scsi_debug.c174
1 files changed, 118 insertions, 56 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 82c06f0a9d02..1541c174937a 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -280,6 +280,8 @@ static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba,
280 unsigned int num, struct sdebug_dev_info * devip); 280 unsigned int num, struct sdebug_dev_info * devip);
281static int resp_report_luns(struct scsi_cmnd * SCpnt, 281static int resp_report_luns(struct scsi_cmnd * SCpnt,
282 struct sdebug_dev_info * devip); 282 struct sdebug_dev_info * devip);
283static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba,
284 unsigned int num, struct sdebug_dev_info *devip);
283static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, 285static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
284 int arr_len); 286 int arr_len);
285static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, 287static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
@@ -311,12 +313,48 @@ static void sdebug_max_tgts_luns(void);
311static struct device pseudo_primary; 313static struct device pseudo_primary;
312static struct bus_type pseudo_lld_bus; 314static struct bus_type pseudo_lld_bus;
313 315
316static void get_data_transfer_info(unsigned char *cmd,
317 unsigned long long *lba, unsigned int *num)
318{
319 int i;
320
321 switch (*cmd) {
322 case WRITE_16:
323 case READ_16:
324 for (*lba = 0, i = 0; i < 8; ++i) {
325 if (i > 0)
326 *lba <<= 8;
327 *lba += cmd[2 + i];
328 }
329 *num = cmd[13] + (cmd[12] << 8) +
330 (cmd[11] << 16) + (cmd[10] << 24);
331 break;
332 case WRITE_12:
333 case READ_12:
334 *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24);
335 *num = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24);
336 break;
337 case WRITE_10:
338 case READ_10:
339 case XDWRITEREAD_10:
340 *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24);
341 *num = cmd[8] + (cmd[7] << 8);
342 break;
343 case WRITE_6:
344 case READ_6:
345 *lba = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16);
346 *num = (0 == cmd[4]) ? 256 : cmd[4];
347 break;
348 default:
349 break;
350 }
351}
314 352
315static 353static
316int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) 354int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
317{ 355{
318 unsigned char *cmd = (unsigned char *) SCpnt->cmnd; 356 unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
319 int len, k, j; 357 int len, k;
320 unsigned int num; 358 unsigned int num;
321 unsigned long long lba; 359 unsigned long long lba;
322 int errsts = 0; 360 int errsts = 0;
@@ -452,28 +490,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
452 break; 490 break;
453 if (scsi_debug_fake_rw) 491 if (scsi_debug_fake_rw)
454 break; 492 break;
455 if ((*cmd) == READ_16) { 493 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); 494 errsts = resp_read(SCpnt, lba, num, devip);
478 if (inj_recovered && (0 == errsts)) { 495 if (inj_recovered && (0 == errsts)) {
479 mk_sense_buffer(devip, RECOVERED_ERROR, 496 mk_sense_buffer(devip, RECOVERED_ERROR,
@@ -500,28 +517,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
500 break; 517 break;
501 if (scsi_debug_fake_rw) 518 if (scsi_debug_fake_rw)
502 break; 519 break;
503 if ((*cmd) == WRITE_16) { 520 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); 521 errsts = resp_write(SCpnt, lba, num, devip);
526 if (inj_recovered && (0 == errsts)) { 522 if (inj_recovered && (0 == errsts)) {
527 mk_sense_buffer(devip, RECOVERED_ERROR, 523 mk_sense_buffer(devip, RECOVERED_ERROR,
@@ -549,6 +545,28 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
549 case WRITE_BUFFER: 545 case WRITE_BUFFER:
550 errsts = check_readiness(SCpnt, 1, devip); 546 errsts = check_readiness(SCpnt, 1, devip);
551 break; 547 break;
548 case XDWRITEREAD_10:
549 if (!scsi_bidi_cmnd(SCpnt)) {
550 mk_sense_buffer(devip, ILLEGAL_REQUEST,
551 INVALID_FIELD_IN_CDB, 0);
552 errsts = check_condition_result;
553 break;
554 }
555
556 errsts = check_readiness(SCpnt, 0, devip);
557 if (errsts)
558 break;
559 if (scsi_debug_fake_rw)
560 break;
561 get_data_transfer_info(cmd, &lba, &num);
562 errsts = resp_read(SCpnt, lba, num, devip);
563 if (errsts)
564 break;
565 errsts = resp_write(SCpnt, lba, num, devip);
566 if (errsts)
567 break;
568 errsts = resp_xdwriteread(SCpnt, lba, num, devip);
569 break;
552 default: 570 default:
553 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 571 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
554 printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " 572 printk(KERN_INFO "scsi_debug: Opcode: 0x%x not "
@@ -601,18 +619,18 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
601 int k, req_len, act_len, len, active; 619 int k, req_len, act_len, len, active;
602 void * kaddr; 620 void * kaddr;
603 void * kaddr_off; 621 void * kaddr_off;
604 struct scatterlist * sg; 622 struct scatterlist *sg;
623 struct scsi_data_buffer *sdb = scsi_in(scp);
605 624
606 if (0 == scsi_bufflen(scp)) 625 if (!sdb->length)
607 return 0; 626 return 0;
608 if (NULL == scsi_sglist(scp)) 627 if (!sdb->table.sgl)
609 return (DID_ERROR << 16); 628 return (DID_ERROR << 16);
610 if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) || 629 if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_FROM_DEVICE))
611 (scp->sc_data_direction == DMA_FROM_DEVICE)))
612 return (DID_ERROR << 16); 630 return (DID_ERROR << 16);
613 active = 1; 631 active = 1;
614 req_len = act_len = 0; 632 req_len = act_len = 0;
615 scsi_for_each_sg(scp, sg, scsi_sg_count(scp), k) { 633 for_each_sg(sdb->table.sgl, sg, sdb->table.nents, k) {
616 if (active) { 634 if (active) {
617 kaddr = (unsigned char *) 635 kaddr = (unsigned char *)
618 kmap_atomic(sg_page(sg), KM_USER0); 636 kmap_atomic(sg_page(sg), KM_USER0);
@@ -630,10 +648,10 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
630 } 648 }
631 req_len += sg->length; 649 req_len += sg->length;
632 } 650 }
633 if (scsi_get_resid(scp)) 651 if (sdb->resid)
634 scsi_set_resid(scp, scsi_get_resid(scp) - act_len); 652 sdb->resid -= act_len;
635 else 653 else
636 scsi_set_resid(scp, req_len - act_len); 654 sdb->resid = req_len - act_len;
637 return 0; 655 return 0;
638} 656}
639 657
@@ -650,8 +668,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
650 return 0; 668 return 0;
651 if (NULL == scsi_sglist(scp)) 669 if (NULL == scsi_sglist(scp))
652 return -1; 670 return -1;
653 if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) || 671 if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_TO_DEVICE))
654 (scp->sc_data_direction == DMA_TO_DEVICE)))
655 return -1; 672 return -1;
656 req_len = fin = 0; 673 req_len = fin = 0;
657 scsi_for_each_sg(scp, sg, scsi_sg_count(scp), k) { 674 scsi_for_each_sg(scp, sg, scsi_sg_count(scp), k) {
@@ -1956,6 +1973,50 @@ static int resp_report_luns(struct scsi_cmnd * scp,
1956 min((int)alloc_len, SDEBUG_RLUN_ARR_SZ)); 1973 min((int)alloc_len, SDEBUG_RLUN_ARR_SZ));
1957} 1974}
1958 1975
1976static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba,
1977 unsigned int num, struct sdebug_dev_info *devip)
1978{
1979 int i, j, ret = -1;
1980 unsigned char *kaddr, *buf;
1981 unsigned int offset;
1982 struct scatterlist *sg;
1983 struct scsi_data_buffer *sdb = scsi_in(scp);
1984
1985 /* better not to use temporary buffer. */
1986 buf = kmalloc(scsi_bufflen(scp), GFP_ATOMIC);
1987 if (!buf)
1988 return ret;
1989
1990 offset = 0;
1991 scsi_for_each_sg(scp, sg, scsi_sg_count(scp), i) {
1992 kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
1993 if (!kaddr)
1994 goto out;
1995
1996 memcpy(buf + offset, kaddr + sg->offset, sg->length);
1997 offset += sg->length;
1998 kunmap_atomic(kaddr, KM_USER0);
1999 }
2000
2001 offset = 0;
2002 for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) {
2003 kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
2004 if (!kaddr)
2005 goto out;
2006
2007 for (j = 0; j < sg->length; j++)
2008 *(kaddr + sg->offset + j) ^= *(buf + offset + j);
2009
2010 offset += sg->length;
2011 kunmap_atomic(kaddr, KM_USER0);
2012 }
2013 ret = 0;
2014out:
2015 kfree(buf);
2016
2017 return ret;
2018}
2019
1959/* When timer goes off this function is called. */ 2020/* When timer goes off this function is called. */
1960static void timer_intr_handler(unsigned long indx) 2021static void timer_intr_handler(unsigned long indx)
1961{ 2022{
@@ -1989,6 +2050,7 @@ static int scsi_debug_slave_alloc(struct scsi_device * sdp)
1989 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 2050 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
1990 printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n", 2051 printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n",
1991 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); 2052 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
2053 set_bit(QUEUE_FLAG_BIDI, &sdp->request_queue->queue_flags);
1992 return 0; 2054 return 0;
1993} 2055}
1994 2056