On Wed, 18 Apr 2012 19:30:40 +1000 Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx> wrote: > > Signed-off-by: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx> > --- > usr/bs_rdwr.c | 24 ++++++++++++++++++++++++ > usr/sbc.c | 17 ++++++++++++++++- > usr/scsi.c | 2 ++ > 3 files changed, 42 insertions(+), 1 deletions(-) What happens if bs_aio.c is used? It would be great if both support this. At least, bs_aio.c can return a proper error if it gets WRITE_SAME*? > diff --git a/usr/bs_rdwr.c b/usr/bs_rdwr.c > index fbc9a2c..e4456fc 100644 > --- a/usr/bs_rdwr.c > +++ b/usr/bs_rdwr.c > @@ -65,6 +65,7 @@ static void bs_rdwr_request(struct scsi_cmd *cmd) > uint8_t key; > uint16_t asc; > char *tmpbuf; > + size_t blocksize; > > ret = length = 0; > key = asc = 0; > @@ -109,6 +110,29 @@ static void bs_rdwr_request(struct scsi_cmd *cmd) > POSIX_FADV_NOREUSE); > > break; > + case WRITE_SAME: > + while (cmd->tl > 0) { > + blocksize = 1 << cmd->dev->blk_shift; > + tmpbuf = scsi_get_out_buffer(cmd); > + > + switch(cmd->scb[1] & 0x06) { > + case 0x02: /* PBDATA==0 LBDATA==1 */ > + put_unaligned_be32(cmd->offset, tmpbuf); > + break; > + case 0x04: /* PBDATA==1 LBDATA==0 */ > + /* physical sector format */ > + put_unaligned_be64(cmd->offset, tmpbuf); > + break; > + } > + > + ret = pwrite64(fd, tmpbuf, blocksize, cmd->offset); > + if (ret != blocksize) > + set_medium_error(&result, &key, &asc); > + > + cmd->offset += blocksize; > + cmd->tl -= blocksize; Can we avoid changing the above? I can't recall the core code reuse them after submitting a command to backing store but I think that backing store code shouldn't touch them. > + } > + break; > case READ_6: > case READ_10: > case READ_12: > diff --git a/usr/sbc.c b/usr/sbc.c > index 55145cf..cf72e65 100644 > --- a/usr/sbc.c > +++ b/usr/sbc.c > @@ -228,6 +228,20 @@ static int sbc_rw(int host_no, struct scsi_cmd *cmd) > goto sense; > } > break; > + case WRITE_SAME: > + /* We only support protection information type 0 */ > + if (cmd->scb[1] & 0xe0) { > + key = ILLEGAL_REQUEST; > + asc = ASC_INVALID_FIELD_IN_CDB; > + goto sense; > + } > + /* LBDATA and PBDATA can not both be set */ > + if ((cmd->scb[1] & 0x06) == 0x06) { > + key = ILLEGAL_REQUEST; > + asc = ASC_INVALID_FIELD_IN_CDB; > + goto sense; > + } > + break; > } > > if (lu->attrs.readonly) { > @@ -236,6 +250,7 @@ static int sbc_rw(int host_no, struct scsi_cmd *cmd) > case WRITE_10: > case WRITE_12: > case WRITE_16: > + case WRITE_SAME: > case PRE_FETCH_10: > case PRE_FETCH_16: > key = DATA_PROTECT; > @@ -607,7 +622,7 @@ static struct device_type_template sbc_template = { > > /* 0x40 */ > {spc_illegal_op,}, > - {spc_illegal_op,}, > + {sbc_rw,}, /* WRITE_SAME10 */ > {sbc_unmap,}, > {spc_illegal_op,}, > {spc_illegal_op,}, > diff --git a/usr/scsi.c b/usr/scsi.c > index 7802ba1..c46753e 100644 > --- a/usr/scsi.c > +++ b/usr/scsi.c > @@ -119,6 +119,7 @@ uint64_t scsi_rw_offset(uint8_t *scb) > case WRITE_10: > case VERIFY_10: > case WRITE_VERIFY: > + case WRITE_SAME: > case SYNCHRONIZE_CACHE: > case READ_12: > case WRITE_12: > @@ -162,6 +163,7 @@ uint32_t scsi_rw_count(uint8_t *scb) > case WRITE_10: > case VERIFY_10: > case WRITE_VERIFY: > + case WRITE_SAME: > case SYNCHRONIZE_CACHE: > cnt = (uint16_t)scb[7] << 8 | (uint16_t)scb[8]; > break; > -- > 1.7.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe stgt" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- To unsubscribe from this list: send the line "unsubscribe stgt" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html