mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-17 04:36:22 +00:00
Slightly modified patch from Bart Van Assche <bvanassche@acm.org> cleaning VERIFY commands processing
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4131 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -767,9 +767,6 @@ Bits of scst_cdb_flags can be:
|
||||
|
||||
<item> <bf/SCST_INFO_VALID/ - bits of op_flags are valid
|
||||
|
||||
<item> <bf/SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED/ - mismatch of data_direction with
|
||||
the value supplied by target driver is allowed
|
||||
|
||||
<item> <bf/SCST_IMPLICIT_HQ/ - this command is an implicit HEAD OF QUEUE command
|
||||
|
||||
<item> <bf/SCST_SKIP_UA/ - Unit Attentions shouldn't be delivered for this command
|
||||
|
||||
@@ -182,7 +182,6 @@ enum scst_cdb_flags {
|
||||
SCST_LONG_TIMEOUT = 0x0004,
|
||||
SCST_UNKNOWN_LENGTH = 0x0008,
|
||||
SCST_INFO_VALID = 0x0010, /* must be single bit */
|
||||
SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED = 0x0020,
|
||||
SCST_IMPLICIT_HQ = 0x0040,
|
||||
SCST_SKIP_UA = 0x0080,
|
||||
SCST_WRITE_MEDIUM = 0x0100,
|
||||
|
||||
@@ -1151,20 +1151,29 @@ static bool vdisk_parse_offset(struct vdisk_cmd_params *p, struct scst_cmd *cmd)
|
||||
case READ_12:
|
||||
case WRITE_10:
|
||||
case WRITE_12:
|
||||
case VERIFY:
|
||||
case WRITE_VERIFY:
|
||||
case WRITE_VERIFY_12:
|
||||
case VERIFY_12:
|
||||
lba_start = get_unaligned_be32(&cdb[2]);
|
||||
data_len = cmd->bufflen;
|
||||
break;
|
||||
case READ_16:
|
||||
case WRITE_16:
|
||||
case WRITE_VERIFY_16:
|
||||
case VERIFY_16:
|
||||
lba_start = get_unaligned_be64(&cdb[2]);
|
||||
data_len = cmd->bufflen;
|
||||
break;
|
||||
case VERIFY:
|
||||
lba_start = get_unaligned_be32(&cdb[2]);
|
||||
data_len = get_unaligned_be16(&cdb[7]) << virt_dev->block_shift;
|
||||
break;
|
||||
case VERIFY_12:
|
||||
lba_start = get_unaligned_be32(&cdb[2]);
|
||||
data_len = get_unaligned_be32(&cdb[6]) << virt_dev->block_shift;
|
||||
break;
|
||||
case VERIFY_16:
|
||||
lba_start = get_unaligned_be64(&cdb[2]);
|
||||
data_len = get_unaligned_be32(&cdb[10]) << virt_dev->block_shift;
|
||||
break;
|
||||
case SYNCHRONIZE_CACHE:
|
||||
lba_start = get_unaligned_be32(&cdb[2]);
|
||||
data_len = get_unaligned_be16(&cdb[7]) << virt_dev->block_shift;
|
||||
@@ -3364,6 +3373,10 @@ static enum compl_status_e fileio_exec_verify(struct vdisk_cmd_params *p)
|
||||
* from the file/disk yet.
|
||||
*/
|
||||
|
||||
compare = scst_cmd_get_data_direction(cmd) == SCST_DATA_WRITE;
|
||||
TRACE_DBG("VERIFY with BYTCHK=%d at offset %lld and with len = %lld\n",
|
||||
compare, loff, p->data_len);
|
||||
|
||||
/* SEEK */
|
||||
old_fs = get_fs();
|
||||
set_fs(get_ds());
|
||||
@@ -3392,13 +3405,12 @@ static enum compl_status_e fileio_exec_verify(struct vdisk_cmd_params *p)
|
||||
goto out_set_fs;
|
||||
}
|
||||
|
||||
length = scst_get_buf_first(cmd, &address);
|
||||
address_sav = address;
|
||||
if (!length && cmd->data_len) {
|
||||
length = cmd->data_len;
|
||||
compare = 0;
|
||||
} else
|
||||
compare = 1;
|
||||
if (compare) {
|
||||
length = scst_get_buf_first(cmd, &address);
|
||||
address_sav = address;
|
||||
} else {
|
||||
length = p->data_len;
|
||||
}
|
||||
|
||||
while (length > 0) {
|
||||
len_mem = (length > LEN_MEM) ? LEN_MEM : length;
|
||||
@@ -3430,7 +3442,8 @@ static enum compl_status_e fileio_exec_verify(struct vdisk_cmd_params *p)
|
||||
goto out_set_fs;
|
||||
}
|
||||
length -= len_mem;
|
||||
address += len_mem;
|
||||
if (compare)
|
||||
address += len_mem;
|
||||
if (compare && length <= 0) {
|
||||
scst_put_buf(cmd, address_sav);
|
||||
length = scst_get_buf_next(cmd, &address);
|
||||
|
||||
+69
-22
@@ -76,6 +76,10 @@ static int get_trans_len_4(struct scst_cmd *cmd, uint8_t off);
|
||||
|
||||
static int get_bidi_trans_len_2(struct scst_cmd *cmd, uint8_t off);
|
||||
|
||||
static int get_verify_trans_len_2(struct scst_cmd *cmd, uint8_t off);
|
||||
static int get_verify_trans_len_3(struct scst_cmd *cmd, uint8_t off);
|
||||
static int get_verify_trans_len_4(struct scst_cmd *cmd, uint8_t off);
|
||||
|
||||
/* for special commands */
|
||||
static int get_trans_len_block_limit(struct scst_cmd *cmd, uint8_t off);
|
||||
static int get_trans_len_read_capacity(struct scst_cmd *cmd, uint8_t off);
|
||||
@@ -262,10 +266,9 @@ static const struct scst_sdbops scst_scsi_op_table[] = {
|
||||
SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
|
||||
3, get_trans_len_2},
|
||||
{0x13, "VOVVVV ", "VERIFY(6)",
|
||||
SCST_DATA_NONE, SCST_TRANSFER_LEN_TYPE_FIXED|
|
||||
SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED|
|
||||
SCST_WRITE_EXCL_ALLOWED,
|
||||
2, get_trans_len_3},
|
||||
SCST_DATA_UNKNOWN, SCST_TRANSFER_LEN_TYPE_FIXED|
|
||||
SCST_WRITE_EXCL_ALLOWED,
|
||||
2, get_verify_trans_len_3},
|
||||
{0x14, "VOOVVV ", "RECOVER BUFFERED DATA",
|
||||
SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED|
|
||||
SCST_WRITE_EXCL_ALLOWED,
|
||||
@@ -358,10 +361,9 @@ static const struct scst_sdbops scst_scsi_op_table[] = {
|
||||
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
|
||||
7, get_trans_len_2},
|
||||
{0x2F, "O OO O ", "VERIFY(10)",
|
||||
SCST_DATA_NONE, SCST_TRANSFER_LEN_TYPE_FIXED|
|
||||
SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED|
|
||||
SCST_WRITE_EXCL_ALLOWED,
|
||||
7, get_trans_len_2},
|
||||
SCST_DATA_UNKNOWN, SCST_TRANSFER_LEN_TYPE_FIXED|
|
||||
SCST_WRITE_EXCL_ALLOWED,
|
||||
7, get_verify_trans_len_2},
|
||||
{0x33, "O OO O ", "SET LIMITS(10)",
|
||||
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
|
||||
{0x34, " O ", "READ POSITION",
|
||||
@@ -537,10 +539,9 @@ static const struct scst_sdbops scst_scsi_op_table[] = {
|
||||
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
|
||||
10, get_trans_len_4},
|
||||
{0x8F, "O OO O ", "VERIFY(16)",
|
||||
SCST_DATA_NONE, SCST_TRANSFER_LEN_TYPE_FIXED|
|
||||
SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED|
|
||||
SCST_WRITE_EXCL_ALLOWED,
|
||||
10, get_trans_len_4},
|
||||
SCST_DATA_UNKNOWN, SCST_TRANSFER_LEN_TYPE_FIXED|
|
||||
SCST_WRITE_EXCL_ALLOWED,
|
||||
10, get_verify_trans_len_4},
|
||||
{0x90, "O OO O ", "PRE-FETCH(16)",
|
||||
SCST_DATA_NONE, SCST_WRITE_EXCL_ALLOWED,
|
||||
0, get_trans_len_none},
|
||||
@@ -624,10 +625,9 @@ static const struct scst_sdbops scst_scsi_op_table[] = {
|
||||
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
|
||||
6, get_trans_len_4},
|
||||
{0xAF, "O OO O ", "VERIFY(12)",
|
||||
SCST_DATA_NONE, SCST_TRANSFER_LEN_TYPE_FIXED|
|
||||
SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED|
|
||||
SCST_WRITE_EXCL_ALLOWED,
|
||||
6, get_trans_len_4},
|
||||
SCST_DATA_UNKNOWN, SCST_TRANSFER_LEN_TYPE_FIXED|
|
||||
SCST_WRITE_EXCL_ALLOWED,
|
||||
6, get_verify_trans_len_4},
|
||||
#if 0 /* No need to support at all */
|
||||
{0xB0, " OO O ", "SEARCH DATA HIGH(12)",
|
||||
SCST_DATA_WRITE, FLAG_NONE, 9, get_trans_len_1},
|
||||
@@ -5116,6 +5116,59 @@ static int get_trans_len_3_read_elem_stat(struct scst_cmd *cmd, uint8_t off)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_bidi_trans_len_2(struct scst_cmd *cmd, uint8_t off)
|
||||
{
|
||||
cmd->bufflen = get_unaligned_be16(cmd->cdb + off);
|
||||
cmd->out_bufflen = cmd->bufflen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_verify_trans_len_2() - Compute transport len and dir for SCSI VERIFY.
|
||||
*
|
||||
* Whether a data-out buffer is associated with a SCSI VERIFY command depends on
|
||||
* the BYTCHK bit in that command. Check that bit and compute the data out
|
||||
* buffer length and the data transfer direction.
|
||||
*/
|
||||
static int get_verify_trans_len_2(struct scst_cmd *cmd, uint8_t off)
|
||||
{
|
||||
if (cmd->cdb[1] & BYTCHK) {
|
||||
cmd->bufflen = get_unaligned_be16(cmd->cdb + off);
|
||||
cmd->data_direction = SCST_DATA_WRITE;
|
||||
} else {
|
||||
cmd->bufflen = 0;
|
||||
cmd->data_direction = SCST_DATA_NONE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_verify_trans_len_3(struct scst_cmd *cmd, uint8_t off)
|
||||
{
|
||||
if (cmd->cdb[1] & BYTCHK) {
|
||||
cmd->bufflen = get_unaligned_be24(cmd->cdb + off);
|
||||
cmd->data_direction = SCST_DATA_WRITE;
|
||||
} else {
|
||||
cmd->bufflen = 0;
|
||||
cmd->data_direction = SCST_DATA_NONE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_verify_trans_len_4(struct scst_cmd *cmd, uint8_t off)
|
||||
{
|
||||
if (cmd->cdb[1] & BYTCHK) {
|
||||
cmd->bufflen = get_unaligned_be32(cmd->cdb + off);
|
||||
cmd->data_direction = SCST_DATA_WRITE;
|
||||
} else {
|
||||
cmd->bufflen = 0;
|
||||
cmd->data_direction = SCST_DATA_NONE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_trans_len_1(struct scst_cmd *cmd, uint8_t off)
|
||||
{
|
||||
cmd->bufflen = (u32)cmd->cdb[off];
|
||||
@@ -5164,12 +5217,6 @@ static int get_trans_len_none(struct scst_cmd *cmd, uint8_t off)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_bidi_trans_len_2(struct scst_cmd *cmd, uint8_t off)
|
||||
{
|
||||
cmd->bufflen = get_unaligned_be16(cmd->cdb + off);
|
||||
cmd->out_bufflen = cmd->bufflen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* scst_get_cdb_info() - fill various info about the command's CDB
|
||||
|
||||
@@ -532,13 +532,6 @@ static bool scst_is_allowed_to_mismatch_cmd(struct scst_cmd *cmd)
|
||||
{
|
||||
bool res = false;
|
||||
|
||||
/* VERIFY commands with BYTCHK unset shouldn't fail here */
|
||||
if ((cmd->op_flags & SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED) &&
|
||||
(cmd->cdb[1] & BYTCHK) == 0) {
|
||||
res = true;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (cmd->cdb[0]) {
|
||||
case TEST_UNIT_READY:
|
||||
/* Crazy VMware people sometimes do TUR with READ direction */
|
||||
@@ -548,7 +541,6 @@ static bool scst_is_allowed_to_mismatch_cmd(struct scst_cmd *cmd)
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user