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 /drivers | |
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/target/target_core_sbc.c | 2 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 16 |
2 files changed, 18 insertions, 0 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: |