History

target: Fix error checking for UNMAP commands

SBC-3 (revision 35) says: The PARAMETER LIST LENGTH field specifies the length in bytes of the UNMAP parameter list that is available to be transferred from the Data-Out Buffer. If the parameter list length is greater than zero and less than 0008h (i.e., eight), then the device server shall terminate the command with CHECK CONDITION status with the sense key set to ILLEGAL REQUEST and the additional sense code set to PARAMETER LIST LENGTH ERROR. A PARAMETER LIST LENGTH set to zero specifies that no data shall be sent. so our sense code for too-short descriptors was wrong, and we were incorrectly failing commands that didn't transfer any descriptors. While we're at it, also handle the UNMAP check: If the ANCHOR bit is set to one, and the ANC_SUP bit in the Logical Block Provisioning VPD page (see 6.6.4) is set to zero, then the device server shall terminate the command with CHECK CONDITION status with the sense key set to ILLEGAL REQUEST and the additional sense code set to INVALID FIELD IN CDB. (chris boot: Fix wrong cut+paste comment in transport_send_check_condition_and_sense)

Roland Dreier committed 13 years ago

Commit bb992e71 parent 33633673 files · +21 −1Browse files

Unified · Split

3 files
  1. drivers/target/target_core_iblock.c +10 −1
  2. drivers/target/target_core_transport.c +10 −0
  3. include/target/target_core_base.h +1 −0
drivers/target/target_core_iblock.c+10−1
@@ -391,10 +391,19 @@ iblock_execute_unmap(struct se_cmd *cmd) · 390 unmodified lines
391391 sense_reason_t ret = 0;
392392 int dl, bd_dl, err;
393393
394+ /* We never set ANC_SUP */
395+ if (cmd->t_task_cdb[1])
396+ return TCM_INVALID_CDB_FIELD;
397+
398+ if (cmd->data_length == 0) {
399+ target_complete_cmd(cmd, SAM_STAT_GOOD);
400+ return 0;
401+ }
402+
394403 if (cmd->data_length < 8) {
395404 pr_warn("UNMAP parameter list length %u too small\n",
396405 cmd->data_length);
397− return TCM_INVALID_PARAMETER_LIST;
406+ return TCM_PARAMETER_LIST_LENGTH_ERROR;
398407 }
399408
400409 buf = transport_kmap_data_sg(cmd);
drivers/target/target_core_transport.c+10−0
@@ -1517,6 +1517,7 @@ void transport_generic_request_failure(struct se_cmd *cmd, · 1516 unmodified lines
15171517 case TCM_UNSUPPORTED_SCSI_OPCODE:
15181518 case TCM_INVALID_CDB_FIELD:
15191519 case TCM_INVALID_PARAMETER_LIST:
1520+ case TCM_PARAMETER_LIST_LENGTH_ERROR:
15201521 case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE:
15211522 case TCM_UNKNOWN_MODE_PAGE:
15221523 case TCM_WRITE_PROTECTED:
@@ -2677,6 +2678,15 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd, · 1154 unmodified lines
26772678 /* INVALID FIELD IN PARAMETER LIST */
26782679 buffer[SPC_ASC_KEY_OFFSET] = 0x26;
26792680 break;
2681+ case TCM_PARAMETER_LIST_LENGTH_ERROR:
2682+ /* CURRENT ERROR */
2683+ buffer[0] = 0x70;
2684+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
2685+ /* ILLEGAL REQUEST */
2686+ buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
2687+ /* PARAMETER LIST LENGTH ERROR */
2688+ buffer[SPC_ASC_KEY_OFFSET] = 0x1a;
2689+ break;
26802690 case TCM_UNEXPECTED_UNSOLICITED_DATA:
26812691 /* CURRENT ERROR */
26822692 buffer[0] = 0x70;
include/target/target_core_base.h+1−0
@@ -195,6 +195,7 @@ enum tcm_sense_reason_table { · 194 unmodified lines
195195 TCM_RESERVATION_CONFLICT = R(0x10),
196196 TCM_ADDRESS_OUT_OF_RANGE = R(0x11),
197197 TCM_OUT_OF_RESOURCES = R(0x12),
198+ TCM_PARAMETER_LIST_LENGTH_ERROR = R(0x13),
198199 #undef R
199200 };
200201

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t