[stgt] [PATCH 11/13] sbc: fix data-in buffer generation for READ_CAPACITY(16)
nezhinsky at gmail.com
nezhinsky at gmail.com
Wed Jan 16 10:01:51 CET 2013
From: Alexander Nezhinsky <nezhinsky at gmail.com>
READ_CAPACITY(16) is an SBC command behaving in SPC-like manner.
Generate data-in in a separate buffer and safe-copy it to the command buffer
taking into account the allocation length.
Set the actual transfer len correctly.
Signed-off-by: Alexander Nezhinsky <nezhinsky at gmail.com>
---
usr/sbc.c | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/usr/sbc.c b/usr/sbc.c
index c059c37..b2a03e2 100644
--- a/usr/sbc.c
+++ b/usr/sbc.c
@@ -477,13 +477,14 @@ sense:
static int sbc_readcapacity16(int host_no, struct scsi_cmd *cmd)
{
- uint32_t *data;
+ uint32_t alloc_len, avail_len, actual_len;
+ uint8_t *data;
+ uint8_t buf[32];
unsigned int bshift;
uint64_t size;
- int len = 32;
- int val;
+ uint32_t val;
+ uint16_t asc = ASC_INVALID_FIELD_IN_CDB;
unsigned char key = ILLEGAL_REQUEST;
- uint16_t asc = ASC_INVALID_OP_CODE;
if (cmd->dev->attrs.removable && !cmd->dev->attrs.online) {
key = NOT_READY;
@@ -491,27 +492,29 @@ static int sbc_readcapacity16(int host_no, struct scsi_cmd *cmd)
goto sense;
}
- if (scsi_get_in_length(cmd) < 12)
- goto overflow;
-
- len = min_t(int, len, scsi_get_in_length(cmd));
+ alloc_len = get_unaligned_be32(&cmd->scb[10]);
+ if (scsi_get_in_length(cmd) < alloc_len)
+ goto sense;
- data = scsi_get_in_buffer(cmd);
- memset(data, 0, len);
+ data = buf;
+ memset(data, 0, 32);
+ avail_len = 32;
bshift = cmd->dev->blk_shift;
size = cmd->dev->size >> bshift;
- *((uint64_t *)(data)) = __cpu_to_be64(size - 1);
- data[2] = __cpu_to_be32(1UL << bshift);
+ put_unaligned_be64(size - 1, &data[0]);
+ put_unaligned_be32(1UL << bshift, &data[8]);
val = (cmd->dev->attrs.lbppbe << 16) | cmd->dev->attrs.la_lba;
if (cmd->dev->attrs.thinprovisioning)
val |= (3 << 14); /* set LBPME and LBPRZ */
- data[3] = __cpu_to_be32(val);
+ put_unaligned_be32(val, &data[12]);
+
+ actual_len = mem_copy_n32(scsi_get_in_buffer(cmd), data, avail_len,
+ NULL, &alloc_len);
+ scsi_set_in_resid_by_actual(cmd, actual_len);
-overflow:
- scsi_set_in_resid_by_actual(cmd, len);
return SAM_STAT_GOOD;
sense:
--
1.7.9.6
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the stgt
mailing list