target: Set additional sense length field in sense data

The target code was not setting the additional sense length field in the
sense data it returned, which meant that at least the Linux stack
ignored the ASC/ASCQ fields.  For example, without this patch, on a
tcm_loop device:

    # sg_raw -v /dev/sda 2 0 0 0 0 0

gives

        cdb to send: 02 00 00 00 00 00
    SCSI Status: Check Condition

    Sense Information:
     Fixed format, current;  Sense key: Illegal Request
      Raw sense data (in hex):
            70 00 05 00 00 00 00 00

while after the patch we correctly get the following (which matches what
a regular disk returns):

        cdb to send: 02 00 00 00 00 00
    SCSI Status: Check Condition

    Sense Information:
     Fixed format, current;  Sense key: Illegal Request
     Additional sense: Invalid command operation code
     Raw sense data (in hex):
            70 00 05 00 00 00 00 0a  00 00 00 00 20 00 00 00
            00 00

Signed-off-by: Roland Dreier <roland@purestorage.com>
Cc: stable@kernel.org
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
Roland Dreier 2011-12-13 14:55:33 -08:00 коммит произвёл Nicholas Bellinger
Родитель 6d5b597560
Коммит 895f302252
2 изменённых файлов: 15 добавлений и 0 удалений

Просмотреть файл

@ -4398,6 +4398,7 @@ int transport_send_check_condition_and_sense(
case TCM_NON_EXISTENT_LUN: case TCM_NON_EXISTENT_LUN:
/* CURRENT ERROR */ /* CURRENT ERROR */
buffer[offset] = 0x70; buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */ /* ILLEGAL REQUEST */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* LOGICAL UNIT NOT SUPPORTED */ /* LOGICAL UNIT NOT SUPPORTED */
@ -4407,6 +4408,7 @@ int transport_send_check_condition_and_sense(
case TCM_SECTOR_COUNT_TOO_MANY: case TCM_SECTOR_COUNT_TOO_MANY:
/* CURRENT ERROR */ /* CURRENT ERROR */
buffer[offset] = 0x70; buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */ /* ILLEGAL REQUEST */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* INVALID COMMAND OPERATION CODE */ /* INVALID COMMAND OPERATION CODE */
@ -4415,6 +4417,7 @@ int transport_send_check_condition_and_sense(
case TCM_UNKNOWN_MODE_PAGE: case TCM_UNKNOWN_MODE_PAGE:
/* CURRENT ERROR */ /* CURRENT ERROR */
buffer[offset] = 0x70; buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */ /* ILLEGAL REQUEST */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* INVALID FIELD IN CDB */ /* INVALID FIELD IN CDB */
@ -4423,6 +4426,7 @@ int transport_send_check_condition_and_sense(
case TCM_CHECK_CONDITION_ABORT_CMD: case TCM_CHECK_CONDITION_ABORT_CMD:
/* CURRENT ERROR */ /* CURRENT ERROR */
buffer[offset] = 0x70; buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */ /* ABORTED COMMAND */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* BUS DEVICE RESET FUNCTION OCCURRED */ /* BUS DEVICE RESET FUNCTION OCCURRED */
@ -4432,6 +4436,7 @@ int transport_send_check_condition_and_sense(
case TCM_INCORRECT_AMOUNT_OF_DATA: case TCM_INCORRECT_AMOUNT_OF_DATA:
/* CURRENT ERROR */ /* CURRENT ERROR */
buffer[offset] = 0x70; buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */ /* ABORTED COMMAND */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* WRITE ERROR */ /* WRITE ERROR */
@ -4442,6 +4447,7 @@ int transport_send_check_condition_and_sense(
case TCM_INVALID_CDB_FIELD: case TCM_INVALID_CDB_FIELD:
/* CURRENT ERROR */ /* CURRENT ERROR */
buffer[offset] = 0x70; buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */ /* ABORTED COMMAND */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* INVALID FIELD IN CDB */ /* INVALID FIELD IN CDB */
@ -4450,6 +4456,7 @@ int transport_send_check_condition_and_sense(
case TCM_INVALID_PARAMETER_LIST: case TCM_INVALID_PARAMETER_LIST:
/* CURRENT ERROR */ /* CURRENT ERROR */
buffer[offset] = 0x70; buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */ /* ABORTED COMMAND */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* INVALID FIELD IN PARAMETER LIST */ /* INVALID FIELD IN PARAMETER LIST */
@ -4458,6 +4465,7 @@ int transport_send_check_condition_and_sense(
case TCM_UNEXPECTED_UNSOLICITED_DATA: case TCM_UNEXPECTED_UNSOLICITED_DATA:
/* CURRENT ERROR */ /* CURRENT ERROR */
buffer[offset] = 0x70; buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */ /* ABORTED COMMAND */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* WRITE ERROR */ /* WRITE ERROR */
@ -4468,6 +4476,7 @@ int transport_send_check_condition_and_sense(
case TCM_SERVICE_CRC_ERROR: case TCM_SERVICE_CRC_ERROR:
/* CURRENT ERROR */ /* CURRENT ERROR */
buffer[offset] = 0x70; buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */ /* ABORTED COMMAND */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* PROTOCOL SERVICE CRC ERROR */ /* PROTOCOL SERVICE CRC ERROR */
@ -4478,6 +4487,7 @@ int transport_send_check_condition_and_sense(
case TCM_SNACK_REJECTED: case TCM_SNACK_REJECTED:
/* CURRENT ERROR */ /* CURRENT ERROR */
buffer[offset] = 0x70; buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */ /* ABORTED COMMAND */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* READ ERROR */ /* READ ERROR */
@ -4488,6 +4498,7 @@ int transport_send_check_condition_and_sense(
case TCM_WRITE_PROTECTED: case TCM_WRITE_PROTECTED:
/* CURRENT ERROR */ /* CURRENT ERROR */
buffer[offset] = 0x70; buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* DATA PROTECT */ /* DATA PROTECT */
buffer[offset+SPC_SENSE_KEY_OFFSET] = DATA_PROTECT; buffer[offset+SPC_SENSE_KEY_OFFSET] = DATA_PROTECT;
/* WRITE PROTECTED */ /* WRITE PROTECTED */
@ -4496,6 +4507,7 @@ int transport_send_check_condition_and_sense(
case TCM_CHECK_CONDITION_UNIT_ATTENTION: case TCM_CHECK_CONDITION_UNIT_ATTENTION:
/* CURRENT ERROR */ /* CURRENT ERROR */
buffer[offset] = 0x70; buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* UNIT ATTENTION */ /* UNIT ATTENTION */
buffer[offset+SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; buffer[offset+SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
core_scsi3_ua_for_check_condition(cmd, &asc, &ascq); core_scsi3_ua_for_check_condition(cmd, &asc, &ascq);
@ -4505,6 +4517,7 @@ int transport_send_check_condition_and_sense(
case TCM_CHECK_CONDITION_NOT_READY: case TCM_CHECK_CONDITION_NOT_READY:
/* CURRENT ERROR */ /* CURRENT ERROR */
buffer[offset] = 0x70; buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* Not Ready */ /* Not Ready */
buffer[offset+SPC_SENSE_KEY_OFFSET] = NOT_READY; buffer[offset+SPC_SENSE_KEY_OFFSET] = NOT_READY;
transport_get_sense_codes(cmd, &asc, &ascq); transport_get_sense_codes(cmd, &asc, &ascq);
@ -4515,6 +4528,7 @@ int transport_send_check_condition_and_sense(
default: default:
/* CURRENT ERROR */ /* CURRENT ERROR */
buffer[offset] = 0x70; buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */ /* ILLEGAL REQUEST */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* LOGICAL UNIT COMMUNICATION FAILURE */ /* LOGICAL UNIT COMMUNICATION FAILURE */

Просмотреть файл

@ -35,6 +35,7 @@
#define TRANSPORT_SENSE_BUFFER SCSI_SENSE_BUFFERSIZE #define TRANSPORT_SENSE_BUFFER SCSI_SENSE_BUFFERSIZE
/* Used by transport_send_check_condition_and_sense() */ /* Used by transport_send_check_condition_and_sense() */
#define SPC_SENSE_KEY_OFFSET 2 #define SPC_SENSE_KEY_OFFSET 2
#define SPC_ADD_SENSE_LEN_OFFSET 7
#define SPC_ASC_KEY_OFFSET 12 #define SPC_ASC_KEY_OFFSET 12
#define SPC_ASCQ_KEY_OFFSET 13 #define SPC_ASCQ_KEY_OFFSET 13
#define TRANSPORT_IQN_LEN 224 #define TRANSPORT_IQN_LEN 224