diff options
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_sbc.c | 4 | ||||
-rw-r--r-- | drivers/target/target_core_spc.c | 9 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 17 |
3 files changed, 25 insertions, 5 deletions
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 97a33603795d..1d3a626bf24f 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -81,7 +81,7 @@ sbc_emulate_readcapacity(struct se_cmd *cmd) | |||
81 | transport_kunmap_data_sg(cmd); | 81 | transport_kunmap_data_sg(cmd); |
82 | } | 82 | } |
83 | 83 | ||
84 | target_complete_cmd(cmd, GOOD); | 84 | target_complete_cmd_with_length(cmd, GOOD, 8); |
85 | return 0; | 85 | return 0; |
86 | } | 86 | } |
87 | 87 | ||
@@ -137,7 +137,7 @@ sbc_emulate_readcapacity_16(struct se_cmd *cmd) | |||
137 | transport_kunmap_data_sg(cmd); | 137 | transport_kunmap_data_sg(cmd); |
138 | } | 138 | } |
139 | 139 | ||
140 | target_complete_cmd(cmd, GOOD); | 140 | target_complete_cmd_with_length(cmd, GOOD, 32); |
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | 143 | ||
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 17b5b7e099fa..6cd7222738fc 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
@@ -716,6 +716,7 @@ spc_emulate_inquiry(struct se_cmd *cmd) | |||
716 | unsigned char *buf; | 716 | unsigned char *buf; |
717 | sense_reason_t ret; | 717 | sense_reason_t ret; |
718 | int p; | 718 | int p; |
719 | int len = 0; | ||
719 | 720 | ||
720 | buf = kzalloc(SE_INQUIRY_BUF, GFP_KERNEL); | 721 | buf = kzalloc(SE_INQUIRY_BUF, GFP_KERNEL); |
721 | if (!buf) { | 722 | if (!buf) { |
@@ -737,6 +738,7 @@ spc_emulate_inquiry(struct se_cmd *cmd) | |||
737 | } | 738 | } |
738 | 739 | ||
739 | ret = spc_emulate_inquiry_std(cmd, buf); | 740 | ret = spc_emulate_inquiry_std(cmd, buf); |
741 | len = buf[4] + 5; | ||
740 | goto out; | 742 | goto out; |
741 | } | 743 | } |
742 | 744 | ||
@@ -744,6 +746,7 @@ spc_emulate_inquiry(struct se_cmd *cmd) | |||
744 | if (cdb[2] == evpd_handlers[p].page) { | 746 | if (cdb[2] == evpd_handlers[p].page) { |
745 | buf[1] = cdb[2]; | 747 | buf[1] = cdb[2]; |
746 | ret = evpd_handlers[p].emulate(cmd, buf); | 748 | ret = evpd_handlers[p].emulate(cmd, buf); |
749 | len = get_unaligned_be16(&buf[2]) + 4; | ||
747 | goto out; | 750 | goto out; |
748 | } | 751 | } |
749 | } | 752 | } |
@@ -760,7 +763,7 @@ out: | |||
760 | kfree(buf); | 763 | kfree(buf); |
761 | 764 | ||
762 | if (!ret) | 765 | if (!ret) |
763 | target_complete_cmd(cmd, GOOD); | 766 | target_complete_cmd_with_length(cmd, GOOD, len); |
764 | return ret; | 767 | return ret; |
765 | } | 768 | } |
766 | 769 | ||
@@ -1098,7 +1101,7 @@ set_length: | |||
1098 | transport_kunmap_data_sg(cmd); | 1101 | transport_kunmap_data_sg(cmd); |
1099 | } | 1102 | } |
1100 | 1103 | ||
1101 | target_complete_cmd(cmd, GOOD); | 1104 | target_complete_cmd_with_length(cmd, GOOD, length); |
1102 | return 0; | 1105 | return 0; |
1103 | } | 1106 | } |
1104 | 1107 | ||
@@ -1274,7 +1277,7 @@ done: | |||
1274 | buf[3] = (lun_count & 0xff); | 1277 | buf[3] = (lun_count & 0xff); |
1275 | transport_kunmap_data_sg(cmd); | 1278 | transport_kunmap_data_sg(cmd); |
1276 | 1279 | ||
1277 | target_complete_cmd(cmd, GOOD); | 1280 | target_complete_cmd_with_length(cmd, GOOD, 8 + lun_count * 8); |
1278 | return 0; | 1281 | return 0; |
1279 | } | 1282 | } |
1280 | EXPORT_SYMBOL(spc_emulate_report_luns); | 1283 | EXPORT_SYMBOL(spc_emulate_report_luns); |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 15dbf6e97289..c9e8b35a954f 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -703,6 +703,23 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) | |||
703 | } | 703 | } |
704 | EXPORT_SYMBOL(target_complete_cmd); | 704 | EXPORT_SYMBOL(target_complete_cmd); |
705 | 705 | ||
706 | void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int length) | ||
707 | { | ||
708 | if (scsi_status == SAM_STAT_GOOD && length < cmd->data_length) { | ||
709 | if (cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) { | ||
710 | cmd->residual_count += cmd->data_length - length; | ||
711 | } else { | ||
712 | cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; | ||
713 | cmd->residual_count = cmd->data_length - length; | ||
714 | } | ||
715 | |||
716 | cmd->data_length = length; | ||
717 | } | ||
718 | |||
719 | target_complete_cmd(cmd, scsi_status); | ||
720 | } | ||
721 | EXPORT_SYMBOL(target_complete_cmd_with_length); | ||
722 | |||
706 | static void target_add_to_state_list(struct se_cmd *cmd) | 723 | static void target_add_to_state_list(struct se_cmd *cmd) |
707 | { | 724 | { |
708 | struct se_device *dev = cmd->se_dev; | 725 | struct se_device *dev = cmd->se_dev; |