aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSagi Grimberg <sagig@mellanox.com>2014-01-23 12:29:38 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2014-01-25 01:58:53 -0500
commit76736db3e291246fbce9db856706af3454b0b078 (patch)
tree0dddd05312db6510a42de37659ccf4203466c9fa
parent676687c69697d2081d25afd14ee90937d1fb0c8e (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.c2
-rw-r--r--drivers/target/target_core_transport.c16
-rw-r--r--include/target/target_core_base.h5
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
2496static
2497void 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
2496int 2509int
2497transport_send_check_condition_and_sense(struct se_cmd *cmd, 2510transport_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
566struct se_ua { 569struct se_ua {