Skip to contentSkip to conversation

tcm_qla2xxx: Fix residual for underrun commands that fail

PATCH Applied Roland Dreier 2 participants 2 messages Jun 5, 2013 – Jun 14, 2013

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 tcm_qla2xxx: Fix residual for underrun commands that fail

From: Roland Dreier <[email protected]>

Suppose an initiator sends a DATA IN command with an allocation length shorter than the FC transfer length -- we get a target message like

    TARGET_CORE[qla2xxx]: Expected Transfer Length: 256 does not match SCSI CDB Length: 0 for SAM Opcode: 0x12

In that case, the target core adjusts the data_length and sets se_cmd->residual_count for the underrun. But now suppose that command fails and we end up in tcm_qla2xxx_queue_status() -- that function unconditionally overwrites residual_count with the already adjusted data_length, and the initiator will burp with a message like

    qla2xxx [0000:00:06.0]-301d:0: Dropped frame(s) detected (0x100 of 0x100 bytes).

Fix this by adding on to the existing underflow residual count instead.

---
 drivers/scsi/qla2xxx/tcm_qla2xxx.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/scsi/qla2xxx/tcm_qla2xxx.c +5 -1
index 7a3870f..66b0b26 100644
@@ -688,8 +688,12 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
 		 * For FCP_READ with CHECK_CONDITION status, clear cmd->bufflen
 		 * for qla_tgt_xmit_response LLD code
 		 */
+		if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) {
+			se_cmd->se_cmd_flags &= ~SCF_OVERFLOW_BIT;
+			se_cmd->residual_count = 0;
+		}
 		se_cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT;
-		se_cmd->residual_count = se_cmd->data_length;
+		se_cmd->residual_count += se_cmd->data_length;
 
 		cmd->bufflen = 0;
 	}
Signature · 1 line
1.8.1.2
#1 lore raw

Hi Roland,

Quoted 13 lines · Roland Dreier

From: Roland Dreier <[email protected]>

Suppose an initiator sends a DATA IN command with an allocation length shorter than the FC transfer length -- we get a target message like

    TARGET_CORE[qla2xxx]: Expected Transfer Length: 256 does not match SCSI CDB Length: 0 for SAM Opcode: 0x12

In that case, the target core adjusts the data_length and sets se_cmd->residual_count for the underrun. But now suppose that command fails and we end up in tcm_qla2xxx_queue_status() -- that function unconditionally overwrites residual_count with the already adjusted data_length, and the initiator will burp with a message like

Quoted 6 lines
    qla2xxx [0000:00:06.0]-301d:0: Dropped frame(s) detected (0x100 of 0x100 bytes).

Fix this by adding on to the existing underflow residual count instead.

---

Apologies for the delay, finally catching up on the backlog..

Applied to target-pending/master, with a CC' to stable.

Also including QLogic folks on the CC'.

Thanks!

--nab

Quoted 21 lines
 drivers/scsi/qla2xxx/tcm_qla2xxx.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/scsi/qla2xxx/tcm_qla2xxx.c +5 -1
index 7a3870f..66b0b26 100644
@@ -688,8 +688,12 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
 		 * For FCP_READ with CHECK_CONDITION status, clear cmd->bufflen
 		 * for qla_tgt_xmit_response LLD code
 		 */
+		if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) {
+			se_cmd->se_cmd_flags &= ~SCF_OVERFLOW_BIT;
+			se_cmd->residual_count = 0;
+		}
 		se_cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT;
-		se_cmd->residual_count = se_cmd->data_length;
+		se_cmd->residual_count += se_cmd->data_length;
 
 		cmd->bufflen = 0;
 	}