diff options
-rw-r--r-- | drivers/target/target_core_sbc.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 42f18fc1067b..77e6531fb0a1 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -1079,25 +1079,31 @@ sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read, | |||
1079 | left = sectors * dev->prot_length; | 1079 | left = sectors * dev->prot_length; |
1080 | 1080 | ||
1081 | for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) { | 1081 | for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) { |
1082 | 1082 | unsigned int psg_len, copied = 0; | |
1083 | len = min(psg->length, left); | ||
1084 | if (offset >= sg->length) { | ||
1085 | sg = sg_next(sg); | ||
1086 | offset = 0; | ||
1087 | } | ||
1088 | 1083 | ||
1089 | paddr = kmap_atomic(sg_page(psg)) + psg->offset; | 1084 | paddr = kmap_atomic(sg_page(psg)) + psg->offset; |
1090 | addr = kmap_atomic(sg_page(sg)) + sg->offset + offset; | 1085 | psg_len = min(left, psg->length); |
1091 | 1086 | while (psg_len) { | |
1092 | if (read) | 1087 | len = min(psg_len, sg->length - offset); |
1093 | memcpy(paddr, addr, len); | 1088 | addr = kmap_atomic(sg_page(sg)) + sg->offset + offset; |
1094 | else | 1089 | |
1095 | memcpy(addr, paddr, len); | 1090 | if (read) |
1096 | 1091 | memcpy(paddr + copied, addr, len); | |
1097 | left -= len; | 1092 | else |
1098 | offset += len; | 1093 | memcpy(addr, paddr + copied, len); |
1094 | |||
1095 | left -= len; | ||
1096 | offset += len; | ||
1097 | copied += len; | ||
1098 | psg_len -= len; | ||
1099 | |||
1100 | if (offset >= sg->length) { | ||
1101 | sg = sg_next(sg); | ||
1102 | offset = 0; | ||
1103 | } | ||
1104 | kunmap_atomic(addr); | ||
1105 | } | ||
1099 | kunmap_atomic(paddr); | 1106 | kunmap_atomic(paddr); |
1100 | kunmap_atomic(addr); | ||
1101 | } | 1107 | } |
1102 | } | 1108 | } |
1103 | 1109 | ||