diff options
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_sbc.c | 13 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 20 |
2 files changed, 25 insertions, 8 deletions
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 8a462773d0c8..be5234abb76c 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -280,13 +280,13 @@ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o | |||
280 | return 0; | 280 | return 0; |
281 | } | 281 | } |
282 | 282 | ||
283 | static void xdreadwrite_callback(struct se_cmd *cmd) | 283 | static sense_reason_t xdreadwrite_callback(struct se_cmd *cmd) |
284 | { | 284 | { |
285 | unsigned char *buf, *addr; | 285 | unsigned char *buf, *addr; |
286 | struct scatterlist *sg; | 286 | struct scatterlist *sg; |
287 | unsigned int offset; | 287 | unsigned int offset; |
288 | int i; | 288 | sense_reason_t ret = TCM_NO_SENSE; |
289 | int count; | 289 | int i, count; |
290 | /* | 290 | /* |
291 | * From sbc3r22.pdf section 5.48 XDWRITEREAD (10) command | 291 | * From sbc3r22.pdf section 5.48 XDWRITEREAD (10) command |
292 | * | 292 | * |
@@ -301,7 +301,7 @@ static void xdreadwrite_callback(struct se_cmd *cmd) | |||
301 | buf = kmalloc(cmd->data_length, GFP_KERNEL); | 301 | buf = kmalloc(cmd->data_length, GFP_KERNEL); |
302 | if (!buf) { | 302 | if (!buf) { |
303 | pr_err("Unable to allocate xor_callback buf\n"); | 303 | pr_err("Unable to allocate xor_callback buf\n"); |
304 | return; | 304 | return TCM_OUT_OF_RESOURCES; |
305 | } | 305 | } |
306 | /* | 306 | /* |
307 | * Copy the scatterlist WRITE buffer located at cmd->t_data_sg | 307 | * Copy the scatterlist WRITE buffer located at cmd->t_data_sg |
@@ -320,8 +320,10 @@ static void xdreadwrite_callback(struct se_cmd *cmd) | |||
320 | offset = 0; | 320 | offset = 0; |
321 | for_each_sg(cmd->t_bidi_data_sg, sg, cmd->t_bidi_data_nents, count) { | 321 | for_each_sg(cmd->t_bidi_data_sg, sg, cmd->t_bidi_data_nents, count) { |
322 | addr = kmap_atomic(sg_page(sg)); | 322 | addr = kmap_atomic(sg_page(sg)); |
323 | if (!addr) | 323 | if (!addr) { |
324 | ret = TCM_OUT_OF_RESOURCES; | ||
324 | goto out; | 325 | goto out; |
326 | } | ||
325 | 327 | ||
326 | for (i = 0; i < sg->length; i++) | 328 | for (i = 0; i < sg->length; i++) |
327 | *(addr + sg->offset + i) ^= *(buf + offset + i); | 329 | *(addr + sg->offset + i) ^= *(buf + offset + i); |
@@ -332,6 +334,7 @@ static void xdreadwrite_callback(struct se_cmd *cmd) | |||
332 | 334 | ||
333 | out: | 335 | out: |
334 | kfree(buf); | 336 | kfree(buf); |
337 | return ret; | ||
335 | } | 338 | } |
336 | 339 | ||
337 | sense_reason_t | 340 | sense_reason_t |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 98ec7110873b..53d1d756f7f5 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -1904,10 +1904,24 @@ static void target_complete_ok_work(struct work_struct *work) | |||
1904 | } | 1904 | } |
1905 | /* | 1905 | /* |
1906 | * Check for a callback, used by amongst other things | 1906 | * Check for a callback, used by amongst other things |
1907 | * XDWRITE_READ_10 emulation. | 1907 | * XDWRITE_READ_10 and COMPARE_AND_WRITE emulation. |
1908 | */ | 1908 | */ |
1909 | if (cmd->transport_complete_callback) | 1909 | if (cmd->transport_complete_callback) { |
1910 | cmd->transport_complete_callback(cmd); | 1910 | sense_reason_t rc; |
1911 | |||
1912 | rc = cmd->transport_complete_callback(cmd); | ||
1913 | if (!rc) | ||
1914 | return; | ||
1915 | |||
1916 | ret = transport_send_check_condition_and_sense(cmd, | ||
1917 | rc, 0); | ||
1918 | if (ret == -EAGAIN || ret == -ENOMEM) | ||
1919 | goto queue_full; | ||
1920 | |||
1921 | transport_lun_remove_cmd(cmd); | ||
1922 | transport_cmd_check_stop_to_fabric(cmd); | ||
1923 | return; | ||
1924 | } | ||
1911 | 1925 | ||
1912 | switch (cmd->data_direction) { | 1926 | switch (cmd->data_direction) { |
1913 | case DMA_FROM_DEVICE: | 1927 | case DMA_FROM_DEVICE: |