diff options
author | FUJITA Tomonori <tomof@acm.org> | 2008-01-22 11:32:01 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-30 14:14:25 -0500 |
commit | c639d14e2f70d086842d37fb8e4f5ab9bd56af2e (patch) | |
tree | 7f6bd8106b7fc983d54ecb9f3cfd0e746f7fe884 /drivers/scsi/scsi_debug.c | |
parent | 072d0bb3ce3507ac6e101ca8ce0b94c5777c62ed (diff) |
[SCSI] scsi_debug: add XDWRITEREAD_10 support
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 | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index d810aa7aee40..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); |
281 | static int resp_report_luns(struct scsi_cmnd * SCpnt, | 281 | static int resp_report_luns(struct scsi_cmnd * SCpnt, |
282 | struct sdebug_dev_info * devip); | 282 | struct sdebug_dev_info * devip); |
283 | static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba, | ||
284 | unsigned int num, struct sdebug_dev_info *devip); | ||
283 | static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | 285 | static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, |
284 | int arr_len); | 286 | int arr_len); |
285 | static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | 287 | static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, |
@@ -334,6 +336,7 @@ static void get_data_transfer_info(unsigned char *cmd, | |||
334 | break; | 336 | break; |
335 | case WRITE_10: | 337 | case WRITE_10: |
336 | case READ_10: | 338 | case READ_10: |
339 | case XDWRITEREAD_10: | ||
337 | *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); | 340 | *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); |
338 | *num = cmd[8] + (cmd[7] << 8); | 341 | *num = cmd[8] + (cmd[7] << 8); |
339 | break; | 342 | break; |
@@ -542,6 +545,28 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
542 | case WRITE_BUFFER: | 545 | case WRITE_BUFFER: |
543 | errsts = check_readiness(SCpnt, 1, devip); | 546 | errsts = check_readiness(SCpnt, 1, devip); |
544 | 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; | ||
545 | default: | 570 | default: |
546 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 571 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
547 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " | 572 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " |
@@ -1948,6 +1973,50 @@ static int resp_report_luns(struct scsi_cmnd * scp, | |||
1948 | min((int)alloc_len, SDEBUG_RLUN_ARR_SZ)); | 1973 | min((int)alloc_len, SDEBUG_RLUN_ARR_SZ)); |
1949 | } | 1974 | } |
1950 | 1975 | ||
1976 | static 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; | ||
2014 | out: | ||
2015 | kfree(buf); | ||
2016 | |||
2017 | return ret; | ||
2018 | } | ||
2019 | |||
1951 | /* When timer goes off this function is called. */ | 2020 | /* When timer goes off this function is called. */ |
1952 | static void timer_intr_handler(unsigned long indx) | 2021 | static void timer_intr_handler(unsigned long indx) |
1953 | { | 2022 | { |
@@ -1981,6 +2050,7 @@ static int scsi_debug_slave_alloc(struct scsi_device * sdp) | |||
1981 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 2050 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
1982 | 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", |
1983 | 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); | ||
1984 | return 0; | 2054 | return 0; |
1985 | } | 2055 | } |
1986 | 2056 | ||