* [PATCH 1/3] scsi_debug: add get_data_transfer_info helper function
@ 2008-01-22 16:31 FUJITA Tomonori
2008-01-22 16:32 ` [PATCH 2/3] scsi_debug: add bidi data transfer support FUJITA Tomonori
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: FUJITA Tomonori @ 2008-01-22 16:31 UTC (permalink / raw)
To: James.Bottomley, dougg; +Cc: bharrosh, fujita.tomonori, linux-scsi, Jens.Axboe
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>
---
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 82c06f0..31f7378 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -311,12 +311,47 @@ static void sdebug_max_tgts_luns(void);
static struct device pseudo_primary;
static struct bus_type pseudo_lld_bus;
+static void get_data_transfer_info(unsigned char *cmd,
+ unsigned long long *lba, unsigned int *num)
+{
+ int i;
+
+ switch (*cmd) {
+ case WRITE_16:
+ case READ_16:
+ for (*lba = 0, i = 0; i < 8; ++i) {
+ if (i > 0)
+ *lba <<= 8;
+ *lba += cmd[2 + i];
+ }
+ *num = cmd[13] + (cmd[12] << 8) +
+ (cmd[11] << 16) + (cmd[10] << 24);
+ break;
+ case WRITE_12:
+ case READ_12:
+ *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24);
+ *num = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24);
+ break;
+ case WRITE_10:
+ case READ_10:
+ *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24);
+ *num = cmd[8] + (cmd[7] << 8);
+ break;
+ case WRITE_6:
+ case READ_6:
+ *lba = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16);
+ *num = (0 == cmd[4]) ? 256 : cmd[4];
+ break;
+ default:
+ break;
+ }
+}
static
int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
{
unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
- int len, k, j;
+ int len, k;
unsigned int num;
unsigned long long lba;
int errsts = 0;
@@ -452,28 +487,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
break;
if (scsi_debug_fake_rw)
break;
- if ((*cmd) == READ_16) {
- for (lba = 0, j = 0; j < 8; ++j) {
- if (j > 0)
- lba <<= 8;
- lba += cmd[2 + j];
- }
- num = cmd[13] + (cmd[12] << 8) +
- (cmd[11] << 16) + (cmd[10] << 24);
- } else if ((*cmd) == READ_12) {
- lba = cmd[5] + (cmd[4] << 8) +
- (cmd[3] << 16) + (cmd[2] << 24);
- num = cmd[9] + (cmd[8] << 8) +
- (cmd[7] << 16) + (cmd[6] << 24);
- } else if ((*cmd) == READ_10) {
- lba = cmd[5] + (cmd[4] << 8) +
- (cmd[3] << 16) + (cmd[2] << 24);
- num = cmd[8] + (cmd[7] << 8);
- } else { /* READ (6) */
- lba = cmd[3] + (cmd[2] << 8) +
- ((cmd[1] & 0x1f) << 16);
- num = (0 == cmd[4]) ? 256 : cmd[4];
- }
+ get_data_transfer_info(cmd, &lba, &num);
errsts = resp_read(SCpnt, lba, num, devip);
if (inj_recovered && (0 == errsts)) {
mk_sense_buffer(devip, RECOVERED_ERROR,
@@ -500,28 +514,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
break;
if (scsi_debug_fake_rw)
break;
- if ((*cmd) == WRITE_16) {
- for (lba = 0, j = 0; j < 8; ++j) {
- if (j > 0)
- lba <<= 8;
- lba += cmd[2 + j];
- }
- num = cmd[13] + (cmd[12] << 8) +
- (cmd[11] << 16) + (cmd[10] << 24);
- } else if ((*cmd) == WRITE_12) {
- lba = cmd[5] + (cmd[4] << 8) +
- (cmd[3] << 16) + (cmd[2] << 24);
- num = cmd[9] + (cmd[8] << 8) +
- (cmd[7] << 16) + (cmd[6] << 24);
- } else if ((*cmd) == WRITE_10) {
- lba = cmd[5] + (cmd[4] << 8) +
- (cmd[3] << 16) + (cmd[2] << 24);
- num = cmd[8] + (cmd[7] << 8);
- } else { /* WRITE (6) */
- lba = cmd[3] + (cmd[2] << 8) +
- ((cmd[1] & 0x1f) << 16);
- num = (0 == cmd[4]) ? 256 : cmd[4];
- }
+ get_data_transfer_info(cmd, &lba, &num);
errsts = resp_write(SCpnt, lba, num, devip);
if (inj_recovered && (0 == errsts)) {
mk_sense_buffer(devip, RECOVERED_ERROR,
--
1.5.3.4
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/3] scsi_debug: add bidi data transfer support 2008-01-22 16:31 [PATCH 1/3] scsi_debug: add get_data_transfer_info helper function FUJITA Tomonori @ 2008-01-22 16:32 ` FUJITA Tomonori 2008-01-22 23:11 ` Douglas Gilbert 2008-01-22 16:32 ` [PATCH 3/3] scsi_debug: add XDWRITEREAD_10 support FUJITA Tomonori 2008-01-22 23:10 ` [PATCH 1/3] scsi_debug: add get_data_transfer_info helper function Douglas Gilbert 2 siblings, 1 reply; 6+ messages in thread From: FUJITA Tomonori @ 2008-01-22 16:32 UTC (permalink / raw) To: James.Bottomley, dougg; +Cc: bharrosh, fujita.tomonori, linux-scsi, Jens.Axboe This enables fill_from_dev_buffer and fetch_to_dev_buffer to handle bidi commands. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- drivers/scsi/scsi_debug.c | 21 ++++++++++----------- 1 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 31f7378..d810aa7 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -594,18 +594,18 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, int k, req_len, act_len, len, active; void * kaddr; void * kaddr_off; - struct scatterlist * sg; + struct scatterlist *sg; + struct scsi_data_buffer *sdb = scsi_in(scp); - if (0 == scsi_bufflen(scp)) + if (!sdb->length) return 0; - if (NULL == scsi_sglist(scp)) + if (!sdb->table.sgl) return (DID_ERROR << 16); - if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) || - (scp->sc_data_direction == DMA_FROM_DEVICE))) + if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_FROM_DEVICE)) return (DID_ERROR << 16); active = 1; req_len = act_len = 0; - scsi_for_each_sg(scp, sg, scsi_sg_count(scp), k) { + for_each_sg(sdb->table.sgl, sg, sdb->table.nents, k) { if (active) { kaddr = (unsigned char *) kmap_atomic(sg_page(sg), KM_USER0); @@ -623,10 +623,10 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, } req_len += sg->length; } - if (scsi_get_resid(scp)) - scsi_set_resid(scp, scsi_get_resid(scp) - act_len); + if (sdb->resid) + sdb->resid -= act_len; else - scsi_set_resid(scp, req_len - act_len); + sdb->resid = req_len - act_len; return 0; } @@ -643,8 +643,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, return 0; if (NULL == scsi_sglist(scp)) return -1; - if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) || - (scp->sc_data_direction == DMA_TO_DEVICE))) + if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_TO_DEVICE)) return -1; req_len = fin = 0; scsi_for_each_sg(scp, sg, scsi_sg_count(scp), k) { -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] scsi_debug: add bidi data transfer support 2008-01-22 16:32 ` [PATCH 2/3] scsi_debug: add bidi data transfer support FUJITA Tomonori @ 2008-01-22 23:11 ` Douglas Gilbert 0 siblings, 0 replies; 6+ messages in thread From: Douglas Gilbert @ 2008-01-22 23:11 UTC (permalink / raw) To: FUJITA Tomonori Cc: James.Bottomley, bharrosh, fujita.tomonori, linux-scsi, Jens.Axboe FUJITA Tomonori wrote: > This enables fill_from_dev_buffer and fetch_to_dev_buffer to handle > bidi commands. > > Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> > --- > drivers/scsi/scsi_debug.c | 21 ++++++++++----------- > 1 files changed, 10 insertions(+), 11 deletions(-) > > diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c > index 31f7378..d810aa7 100644 > --- a/drivers/scsi/scsi_debug.c > +++ b/drivers/scsi/scsi_debug.c > @@ -594,18 +594,18 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, > int k, req_len, act_len, len, active; > void * kaddr; > void * kaddr_off; > - struct scatterlist * sg; > + struct scatterlist *sg; > + struct scsi_data_buffer *sdb = scsi_in(scp); > > - if (0 == scsi_bufflen(scp)) > + if (!sdb->length) > return 0; > - if (NULL == scsi_sglist(scp)) > + if (!sdb->table.sgl) > return (DID_ERROR << 16); > - if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) || > - (scp->sc_data_direction == DMA_FROM_DEVICE))) > + if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_FROM_DEVICE)) > return (DID_ERROR << 16); > active = 1; > req_len = act_len = 0; > - scsi_for_each_sg(scp, sg, scsi_sg_count(scp), k) { > + for_each_sg(sdb->table.sgl, sg, sdb->table.nents, k) { > if (active) { > kaddr = (unsigned char *) > kmap_atomic(sg_page(sg), KM_USER0); > @@ -623,10 +623,10 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, > } > req_len += sg->length; > } > - if (scsi_get_resid(scp)) > - scsi_set_resid(scp, scsi_get_resid(scp) - act_len); > + if (sdb->resid) > + sdb->resid -= act_len; > else > - scsi_set_resid(scp, req_len - act_len); > + sdb->resid = req_len - act_len; > return 0; > } > > @@ -643,8 +643,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, > return 0; > if (NULL == scsi_sglist(scp)) > return -1; > - if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) || > - (scp->sc_data_direction == DMA_TO_DEVICE))) > + if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_TO_DEVICE)) > return -1; > req_len = fin = 0; > scsi_for_each_sg(scp, sg, scsi_sg_count(scp), k) { Signed-off-by: Douglas Gilbert <dougg@torque.net> ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/3] scsi_debug: add XDWRITEREAD_10 support 2008-01-22 16:31 [PATCH 1/3] scsi_debug: add get_data_transfer_info helper function FUJITA Tomonori 2008-01-22 16:32 ` [PATCH 2/3] scsi_debug: add bidi data transfer support FUJITA Tomonori @ 2008-01-22 16:32 ` FUJITA Tomonori 2008-01-22 23:11 ` Douglas Gilbert 2008-01-22 23:10 ` [PATCH 1/3] scsi_debug: add get_data_transfer_info helper function Douglas Gilbert 2 siblings, 1 reply; 6+ messages in thread From: FUJITA Tomonori @ 2008-01-22 16:32 UTC (permalink / raw) To: James.Bottomley, dougg; +Cc: bharrosh, fujita.tomonori, linux-scsi, Jens.Axboe Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- drivers/scsi/scsi_debug.c | 70 +++++++++++++++++++++++++++++++++++++++++++++ include/scsi/scsi.h | 1 + 2 files changed, 71 insertions(+), 0 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index d810aa7..1541c17 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, unsigned int num, struct sdebug_dev_info * devip); static int resp_report_luns(struct scsi_cmnd * SCpnt, struct sdebug_dev_info * devip); +static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba, + unsigned int num, struct sdebug_dev_info *devip); static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, int arr_len); 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, break; case WRITE_10: case READ_10: + case XDWRITEREAD_10: *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); *num = cmd[8] + (cmd[7] << 8); break; @@ -542,6 +545,28 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) case WRITE_BUFFER: errsts = check_readiness(SCpnt, 1, devip); break; + case XDWRITEREAD_10: + if (!scsi_bidi_cmnd(SCpnt)) { + mk_sense_buffer(devip, ILLEGAL_REQUEST, + INVALID_FIELD_IN_CDB, 0); + errsts = check_condition_result; + break; + } + + errsts = check_readiness(SCpnt, 0, devip); + if (errsts) + break; + if (scsi_debug_fake_rw) + break; + get_data_transfer_info(cmd, &lba, &num); + errsts = resp_read(SCpnt, lba, num, devip); + if (errsts) + break; + errsts = resp_write(SCpnt, lba, num, devip); + if (errsts) + break; + errsts = resp_xdwriteread(SCpnt, lba, num, devip); + break; default: if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " @@ -1948,6 +1973,50 @@ static int resp_report_luns(struct scsi_cmnd * scp, min((int)alloc_len, SDEBUG_RLUN_ARR_SZ)); } +static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba, + unsigned int num, struct sdebug_dev_info *devip) +{ + int i, j, ret = -1; + unsigned char *kaddr, *buf; + unsigned int offset; + struct scatterlist *sg; + struct scsi_data_buffer *sdb = scsi_in(scp); + + /* better not to use temporary buffer. */ + buf = kmalloc(scsi_bufflen(scp), GFP_ATOMIC); + if (!buf) + return ret; + + offset = 0; + scsi_for_each_sg(scp, sg, scsi_sg_count(scp), i) { + kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0); + if (!kaddr) + goto out; + + memcpy(buf + offset, kaddr + sg->offset, sg->length); + offset += sg->length; + kunmap_atomic(kaddr, KM_USER0); + } + + offset = 0; + for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) { + kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0); + if (!kaddr) + goto out; + + for (j = 0; j < sg->length; j++) + *(kaddr + sg->offset + j) ^= *(buf + offset + j); + + offset += sg->length; + kunmap_atomic(kaddr, KM_USER0); + } + ret = 0; +out: + kfree(buf); + + return ret; +} + /* When timer goes off this function is called. */ static void timer_intr_handler(unsigned long indx) { @@ -1981,6 +2050,7 @@ static int scsi_debug_slave_alloc(struct scsi_device * sdp) if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n", sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); + set_bit(QUEUE_FLAG_BIDI, &sdp->request_queue->queue_flags); return 0; } diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 056c5af..19ca9e9 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -102,6 +102,7 @@ extern const unsigned char scsi_command_size[8]; #define READ_TOC 0x43 #define LOG_SELECT 0x4c #define LOG_SENSE 0x4d +#define XDWRITEREAD_10 0x53 #define MODE_SELECT_10 0x55 #define RESERVE_10 0x56 #define RELEASE_10 0x57 -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 3/3] scsi_debug: add XDWRITEREAD_10 support 2008-01-22 16:32 ` [PATCH 3/3] scsi_debug: add XDWRITEREAD_10 support FUJITA Tomonori @ 2008-01-22 23:11 ` Douglas Gilbert 0 siblings, 0 replies; 6+ messages in thread From: Douglas Gilbert @ 2008-01-22 23:11 UTC (permalink / raw) To: FUJITA Tomonori Cc: James.Bottomley, bharrosh, fujita.tomonori, linux-scsi, Jens.Axboe FUJITA Tomonori wrote: > Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> > --- > drivers/scsi/scsi_debug.c | 70 +++++++++++++++++++++++++++++++++++++++++++++ > include/scsi/scsi.h | 1 + > 2 files changed, 71 insertions(+), 0 deletions(-) > > diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c > index d810aa7..1541c17 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, > unsigned int num, struct sdebug_dev_info * devip); > static int resp_report_luns(struct scsi_cmnd * SCpnt, > struct sdebug_dev_info * devip); > +static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba, > + unsigned int num, struct sdebug_dev_info *devip); > static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, > int arr_len); > 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, > break; > case WRITE_10: > case READ_10: > + case XDWRITEREAD_10: > *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); > *num = cmd[8] + (cmd[7] << 8); > break; > @@ -542,6 +545,28 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) > case WRITE_BUFFER: > errsts = check_readiness(SCpnt, 1, devip); > break; > + case XDWRITEREAD_10: > + if (!scsi_bidi_cmnd(SCpnt)) { > + mk_sense_buffer(devip, ILLEGAL_REQUEST, > + INVALID_FIELD_IN_CDB, 0); > + errsts = check_condition_result; > + break; > + } > + > + errsts = check_readiness(SCpnt, 0, devip); > + if (errsts) > + break; > + if (scsi_debug_fake_rw) > + break; > + get_data_transfer_info(cmd, &lba, &num); > + errsts = resp_read(SCpnt, lba, num, devip); > + if (errsts) > + break; > + errsts = resp_write(SCpnt, lba, num, devip); > + if (errsts) > + break; > + errsts = resp_xdwriteread(SCpnt, lba, num, devip); > + break; > default: > if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) > printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " > @@ -1948,6 +1973,50 @@ static int resp_report_luns(struct scsi_cmnd * scp, > min((int)alloc_len, SDEBUG_RLUN_ARR_SZ)); > } > > +static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba, > + unsigned int num, struct sdebug_dev_info *devip) > +{ > + int i, j, ret = -1; > + unsigned char *kaddr, *buf; > + unsigned int offset; > + struct scatterlist *sg; > + struct scsi_data_buffer *sdb = scsi_in(scp); > + > + /* better not to use temporary buffer. */ > + buf = kmalloc(scsi_bufflen(scp), GFP_ATOMIC); > + if (!buf) > + return ret; > + > + offset = 0; > + scsi_for_each_sg(scp, sg, scsi_sg_count(scp), i) { > + kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0); > + if (!kaddr) > + goto out; > + > + memcpy(buf + offset, kaddr + sg->offset, sg->length); > + offset += sg->length; > + kunmap_atomic(kaddr, KM_USER0); > + } > + > + offset = 0; > + for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) { > + kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0); > + if (!kaddr) > + goto out; > + > + for (j = 0; j < sg->length; j++) > + *(kaddr + sg->offset + j) ^= *(buf + offset + j); > + > + offset += sg->length; > + kunmap_atomic(kaddr, KM_USER0); > + } > + ret = 0; > +out: > + kfree(buf); > + > + return ret; > +} > + > /* When timer goes off this function is called. */ > static void timer_intr_handler(unsigned long indx) > { > @@ -1981,6 +2050,7 @@ static int scsi_debug_slave_alloc(struct scsi_device * sdp) > if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) > printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n", > sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); > + set_bit(QUEUE_FLAG_BIDI, &sdp->request_queue->queue_flags); > return 0; > } > > diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h > index 056c5af..19ca9e9 100644 > --- a/include/scsi/scsi.h > +++ b/include/scsi/scsi.h > @@ -102,6 +102,7 @@ extern const unsigned char scsi_command_size[8]; > #define READ_TOC 0x43 > #define LOG_SELECT 0x4c > #define LOG_SENSE 0x4d > +#define XDWRITEREAD_10 0x53 > #define MODE_SELECT_10 0x55 > #define RESERVE_10 0x56 > #define RELEASE_10 0x57 Signed-off-by: Douglas Gilbert <dougg@torque.net> ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] scsi_debug: add get_data_transfer_info helper function 2008-01-22 16:31 [PATCH 1/3] scsi_debug: add get_data_transfer_info helper function FUJITA Tomonori 2008-01-22 16:32 ` [PATCH 2/3] scsi_debug: add bidi data transfer support FUJITA Tomonori 2008-01-22 16:32 ` [PATCH 3/3] scsi_debug: add XDWRITEREAD_10 support FUJITA Tomonori @ 2008-01-22 23:10 ` Douglas Gilbert 2 siblings, 0 replies; 6+ messages in thread From: Douglas Gilbert @ 2008-01-22 23:10 UTC (permalink / raw) To: FUJITA Tomonori Cc: James.Bottomley, bharrosh, fujita.tomonori, linux-scsi, Jens.Axboe FUJITA Tomonori wrote: > 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> > --- > 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 82c06f0..31f7378 100644 > --- a/drivers/scsi/scsi_debug.c > +++ b/drivers/scsi/scsi_debug.c > @@ -311,12 +311,47 @@ static void sdebug_max_tgts_luns(void); > static struct device pseudo_primary; > static struct bus_type pseudo_lld_bus; > > +static void get_data_transfer_info(unsigned char *cmd, > + unsigned long long *lba, unsigned int *num) > +{ > + int i; > + > + switch (*cmd) { > + case WRITE_16: > + case READ_16: > + for (*lba = 0, i = 0; i < 8; ++i) { > + if (i > 0) > + *lba <<= 8; > + *lba += cmd[2 + i]; > + } > + *num = cmd[13] + (cmd[12] << 8) + > + (cmd[11] << 16) + (cmd[10] << 24); > + break; > + case WRITE_12: > + case READ_12: > + *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); > + *num = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); > + break; > + case WRITE_10: > + case READ_10: > + *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); > + *num = cmd[8] + (cmd[7] << 8); > + break; > + case WRITE_6: > + case READ_6: > + *lba = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16); > + *num = (0 == cmd[4]) ? 256 : cmd[4]; > + break; > + default: > + break; > + } > +} > > static > int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) > { > unsigned char *cmd = (unsigned char *) SCpnt->cmnd; > - int len, k, j; > + int len, k; > unsigned int num; > unsigned long long lba; > int errsts = 0; > @@ -452,28 +487,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) > break; > if (scsi_debug_fake_rw) > break; > - if ((*cmd) == READ_16) { > - for (lba = 0, j = 0; j < 8; ++j) { > - if (j > 0) > - lba <<= 8; > - lba += cmd[2 + j]; > - } > - num = cmd[13] + (cmd[12] << 8) + > - (cmd[11] << 16) + (cmd[10] << 24); > - } else if ((*cmd) == READ_12) { > - lba = cmd[5] + (cmd[4] << 8) + > - (cmd[3] << 16) + (cmd[2] << 24); > - num = cmd[9] + (cmd[8] << 8) + > - (cmd[7] << 16) + (cmd[6] << 24); > - } else if ((*cmd) == READ_10) { > - lba = cmd[5] + (cmd[4] << 8) + > - (cmd[3] << 16) + (cmd[2] << 24); > - num = cmd[8] + (cmd[7] << 8); > - } else { /* READ (6) */ > - lba = cmd[3] + (cmd[2] << 8) + > - ((cmd[1] & 0x1f) << 16); > - num = (0 == cmd[4]) ? 256 : cmd[4]; > - } > + get_data_transfer_info(cmd, &lba, &num); > errsts = resp_read(SCpnt, lba, num, devip); > if (inj_recovered && (0 == errsts)) { > mk_sense_buffer(devip, RECOVERED_ERROR, > @@ -500,28 +514,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) > break; > if (scsi_debug_fake_rw) > break; > - if ((*cmd) == WRITE_16) { > - for (lba = 0, j = 0; j < 8; ++j) { > - if (j > 0) > - lba <<= 8; > - lba += cmd[2 + j]; > - } > - num = cmd[13] + (cmd[12] << 8) + > - (cmd[11] << 16) + (cmd[10] << 24); > - } else if ((*cmd) == WRITE_12) { > - lba = cmd[5] + (cmd[4] << 8) + > - (cmd[3] << 16) + (cmd[2] << 24); > - num = cmd[9] + (cmd[8] << 8) + > - (cmd[7] << 16) + (cmd[6] << 24); > - } else if ((*cmd) == WRITE_10) { > - lba = cmd[5] + (cmd[4] << 8) + > - (cmd[3] << 16) + (cmd[2] << 24); > - num = cmd[8] + (cmd[7] << 8); > - } else { /* WRITE (6) */ > - lba = cmd[3] + (cmd[2] << 8) + > - ((cmd[1] & 0x1f) << 16); > - num = (0 == cmd[4]) ? 256 : cmd[4]; > - } > + get_data_transfer_info(cmd, &lba, &num); > errsts = resp_write(SCpnt, lba, num, devip); > if (inj_recovered && (0 == errsts)) { > mk_sense_buffer(devip, RECOVERED_ERROR, Tomo, Thanks. Signed-off-by: Douglas Gilbert <dougg@torque.net> ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2008-01-22 23:12 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-01-22 16:31 [PATCH 1/3] scsi_debug: add get_data_transfer_info helper function FUJITA Tomonori 2008-01-22 16:32 ` [PATCH 2/3] scsi_debug: add bidi data transfer support FUJITA Tomonori 2008-01-22 23:11 ` Douglas Gilbert 2008-01-22 16:32 ` [PATCH 3/3] scsi_debug: add XDWRITEREAD_10 support FUJITA Tomonori 2008-01-22 23:11 ` Douglas Gilbert 2008-01-22 23:10 ` [PATCH 1/3] scsi_debug: add get_data_transfer_info helper function Douglas Gilbert
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.