[PATCH 1/3] SBC: Add basic WRITE_SAME(10) support (no UNMAP support yet)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux