aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_sbc.c4
-rw-r--r--drivers/target/target_core_spc.c9
-rw-r--r--drivers/target/target_core_transport.c17
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}
1280EXPORT_SYMBOL(spc_emulate_report_luns); 1283EXPORT_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}
704EXPORT_SYMBOL(target_complete_cmd); 704EXPORT_SYMBOL(target_complete_cmd);
705 705
706void 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}
721EXPORT_SYMBOL(target_complete_cmd_with_length);
722
706static void target_add_to_state_list(struct se_cmd *cmd) 723static 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;