From cc07f3904ea4bda3b93d284a82a4fa8ca29a56ca Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Wed, 7 Mar 2012 19:52:50 +0000 Subject: [PATCH] The FORMAT UNIT has an optional data-out buffer with unspecified length. Make sure that SCST parses this command correctly. Reported-by: Leonid Podolny Signed-off-by: Bart Van Assche git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4158 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_lib.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 3db4de1c8..e6fc2335d 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -76,11 +76,11 @@ 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); +/* for special commands */ +static int get_trans_len_fmt(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); static int get_trans_len_serv_act_in(struct scst_cmd *cmd, uint8_t off); @@ -192,8 +192,8 @@ static const struct scst_sdbops scst_scsi_op_table[] = { SCST_EXCL_ACCESS_ALLOWED, 4, get_trans_len_1}, {0x04, "M O O ", "FORMAT UNIT", - SCST_DATA_WRITE, SCST_LONG_TIMEOUT|SCST_UNKNOWN_LENGTH|SCST_WRITE_MEDIUM, - 0, get_trans_len_none}, + SCST_DATA_NONE, SCST_LONG_TIMEOUT|SCST_WRITE_MEDIUM, + 0, get_trans_len_fmt}, {0x04, " O ", "FORMAT", SCST_DATA_NONE, SCST_WRITE_MEDIUM, 0, get_trans_len_none}, {0x05, "VMVVVV V ", "READ BLOCK LIMITS", @@ -5123,6 +5123,16 @@ static int get_bidi_trans_len_2(struct scst_cmd *cmd, uint8_t off) return 0; } +static int get_trans_len_fmt(struct scst_cmd *cmd, uint8_t off) +{ + if (cmd->cdb[1] & 0x04/*FMTDATA*/) { + cmd->data_direction = SCST_DATA_WRITE; + cmd->op_flags |= SCST_UNKNOWN_LENGTH; + } + + return 0; +} + /* * get_verify_trans_len_2() - Compute transport len and dir for SCSI VERIFY. *