diff options
| author | Sagi Grimberg <sagig@mellanox.com> | 2014-01-23 12:29:38 -0500 |
|---|---|---|
| committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-01-25 01:58:53 -0500 |
| commit | 76736db3e291246fbce9db856706af3454b0b078 (patch) | |
| tree | 0dddd05312db6510a42de37659ccf4203466c9fa | |
| parent | 676687c69697d2081d25afd14ee90937d1fb0c8e (diff) | |
target: Report bad sector in sense data for DIF errors
SPC-4 states that data-integrity errors shall also report
the failed sector in CHECK_CONDITION response sense data
information field.
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
| -rw-r--r-- | drivers/target/target_core_sbc.c | 2 | ||||
| -rw-r--r-- | drivers/target/target_core_transport.c | 16 | ||||
| -rw-r--r-- | include/target/target_core_base.h | 5 |
3 files changed, 22 insertions, 1 deletions
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 75364c7f6219..fa3cae393e13 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
| @@ -1131,6 +1131,7 @@ sbc_dif_verify_write(struct se_cmd *cmd, sector_t start, unsigned int sectors, | |||
| 1131 | if (rc) { | 1131 | if (rc) { |
| 1132 | kunmap_atomic(paddr); | 1132 | kunmap_atomic(paddr); |
| 1133 | kunmap_atomic(daddr); | 1133 | kunmap_atomic(daddr); |
| 1134 | cmd->bad_sector = sector; | ||
| 1134 | return rc; | 1135 | return rc; |
| 1135 | } | 1136 | } |
| 1136 | 1137 | ||
| @@ -1191,6 +1192,7 @@ sbc_dif_verify_read(struct se_cmd *cmd, sector_t start, unsigned int sectors, | |||
| 1191 | if (rc) { | 1192 | if (rc) { |
| 1192 | kunmap_atomic(paddr); | 1193 | kunmap_atomic(paddr); |
| 1193 | kunmap_atomic(daddr); | 1194 | kunmap_atomic(daddr); |
| 1195 | cmd->bad_sector = sector; | ||
| 1194 | return rc; | 1196 | return rc; |
| 1195 | } | 1197 | } |
| 1196 | 1198 | ||
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index aebe0bb3f23b..51a9736be726 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
| @@ -2493,6 +2493,19 @@ static int transport_get_sense_codes( | |||
| 2493 | return 0; | 2493 | return 0; |
| 2494 | } | 2494 | } |
| 2495 | 2495 | ||
| 2496 | static | ||
| 2497 | void transport_err_sector_info(unsigned char *buffer, sector_t bad_sector) | ||
| 2498 | { | ||
| 2499 | /* Place failed LBA in sense data information descriptor 0. */ | ||
| 2500 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 0xc; | ||
| 2501 | buffer[SPC_DESC_TYPE_OFFSET] = 0; /* Information */ | ||
| 2502 | buffer[SPC_ADDITIONAL_DESC_LEN_OFFSET] = 0xa; | ||
| 2503 | buffer[SPC_VALIDITY_OFFSET] = 0x80; | ||
| 2504 | |||
| 2505 | /* Descriptor Information: failing sector */ | ||
| 2506 | put_unaligned_be64(bad_sector, &buffer[12]); | ||
| 2507 | } | ||
| 2508 | |||
| 2496 | int | 2509 | int |
| 2497 | transport_send_check_condition_and_sense(struct se_cmd *cmd, | 2510 | transport_send_check_condition_and_sense(struct se_cmd *cmd, |
| 2498 | sense_reason_t reason, int from_transport) | 2511 | sense_reason_t reason, int from_transport) |
| @@ -2695,6 +2708,7 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd, | |||
| 2695 | /* LOGICAL BLOCK GUARD CHECK FAILED */ | 2708 | /* LOGICAL BLOCK GUARD CHECK FAILED */ |
| 2696 | buffer[SPC_ASC_KEY_OFFSET] = 0x10; | 2709 | buffer[SPC_ASC_KEY_OFFSET] = 0x10; |
| 2697 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x01; | 2710 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x01; |
| 2711 | transport_err_sector_info(buffer, cmd->bad_sector); | ||
| 2698 | break; | 2712 | break; |
| 2699 | case TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED: | 2713 | case TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED: |
| 2700 | /* CURRENT ERROR */ | 2714 | /* CURRENT ERROR */ |
| @@ -2705,6 +2719,7 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd, | |||
| 2705 | /* LOGICAL BLOCK APPLICATION TAG CHECK FAILED */ | 2719 | /* LOGICAL BLOCK APPLICATION TAG CHECK FAILED */ |
| 2706 | buffer[SPC_ASC_KEY_OFFSET] = 0x10; | 2720 | buffer[SPC_ASC_KEY_OFFSET] = 0x10; |
| 2707 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x02; | 2721 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x02; |
| 2722 | transport_err_sector_info(buffer, cmd->bad_sector); | ||
| 2708 | break; | 2723 | break; |
| 2709 | case TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED: | 2724 | case TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED: |
| 2710 | /* CURRENT ERROR */ | 2725 | /* CURRENT ERROR */ |
| @@ -2715,6 +2730,7 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd, | |||
| 2715 | /* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */ | 2730 | /* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */ |
| 2716 | buffer[SPC_ASC_KEY_OFFSET] = 0x10; | 2731 | buffer[SPC_ASC_KEY_OFFSET] = 0x10; |
| 2717 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x03; | 2732 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x03; |
| 2733 | transport_err_sector_info(buffer, cmd->bad_sector); | ||
| 2718 | break; | 2734 | break; |
| 2719 | case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE: | 2735 | case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE: |
| 2720 | default: | 2736 | default: |
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 0336d70d0d9f..d28418645b00 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
| @@ -37,6 +37,9 @@ | |||
| 37 | /* Used by transport_send_check_condition_and_sense() */ | 37 | /* Used by transport_send_check_condition_and_sense() */ |
| 38 | #define SPC_SENSE_KEY_OFFSET 2 | 38 | #define SPC_SENSE_KEY_OFFSET 2 |
| 39 | #define SPC_ADD_SENSE_LEN_OFFSET 7 | 39 | #define SPC_ADD_SENSE_LEN_OFFSET 7 |
| 40 | #define SPC_DESC_TYPE_OFFSET 8 | ||
| 41 | #define SPC_ADDITIONAL_DESC_LEN_OFFSET 9 | ||
| 42 | #define SPC_VALIDITY_OFFSET 10 | ||
| 40 | #define SPC_ASC_KEY_OFFSET 12 | 43 | #define SPC_ASC_KEY_OFFSET 12 |
| 41 | #define SPC_ASCQ_KEY_OFFSET 13 | 44 | #define SPC_ASCQ_KEY_OFFSET 13 |
| 42 | #define TRANSPORT_IQN_LEN 224 | 45 | #define TRANSPORT_IQN_LEN 224 |
| @@ -560,7 +563,7 @@ struct se_cmd { | |||
| 560 | unsigned int t_prot_nents; | 563 | unsigned int t_prot_nents; |
| 561 | enum target_prot_ho prot_handover; | 564 | enum target_prot_ho prot_handover; |
| 562 | sense_reason_t pi_err; | 565 | sense_reason_t pi_err; |
| 563 | u32 block_num; | 566 | sector_t bad_sector; |
| 564 | }; | 567 | }; |
| 565 | 568 | ||
| 566 | struct se_ua { | 569 | struct se_ua { |
