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(-) 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; + } + 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