aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/target_core_sbc.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2012-09-07 11:30:40 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2012-09-17 20:13:38 -0400
commita50da144d048f9dbebed2b1441ed779d6bbbcd03 (patch)
tree25290267964578f79c10590a6511d10b85e7de96 /drivers/target/target_core_sbc.c
parent7a3f369ce31694017996524a1cdb08208a839077 (diff)
target: support zero allocation length in SBC commands
READ CAPACITY must be subject to the same treatment as INQUIRY, REQUEST SENSE, and MODE SENSE, but there are no pre-existing bugs to fix here. Just use an on-stack buffer, and copy to it after checking the return value of transport_kmap_data_sg. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/target_core_sbc.c')
-rw-r--r--drivers/target/target_core_sbc.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index a9dd9469e3bd..868f8aa04f13 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -40,8 +40,9 @@
40static int sbc_emulate_readcapacity(struct se_cmd *cmd) 40static int sbc_emulate_readcapacity(struct se_cmd *cmd)
41{ 41{
42 struct se_device *dev = cmd->se_dev; 42 struct se_device *dev = cmd->se_dev;
43 unsigned char *buf;
44 unsigned long long blocks_long = dev->transport->get_blocks(dev); 43 unsigned long long blocks_long = dev->transport->get_blocks(dev);
44 unsigned char *rbuf;
45 unsigned char buf[8];
45 u32 blocks; 46 u32 blocks;
46 47
47 if (blocks_long >= 0x00000000ffffffff) 48 if (blocks_long >= 0x00000000ffffffff)
@@ -49,8 +50,6 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd)
49 else 50 else
50 blocks = (u32)blocks_long; 51 blocks = (u32)blocks_long;
51 52
52 buf = transport_kmap_data_sg(cmd);
53
54 buf[0] = (blocks >> 24) & 0xff; 53 buf[0] = (blocks >> 24) & 0xff;
55 buf[1] = (blocks >> 16) & 0xff; 54 buf[1] = (blocks >> 16) & 0xff;
56 buf[2] = (blocks >> 8) & 0xff; 55 buf[2] = (blocks >> 8) & 0xff;
@@ -60,7 +59,11 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd)
60 buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff; 59 buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff;
61 buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff; 60 buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff;
62 61
63 transport_kunmap_data_sg(cmd); 62 rbuf = transport_kmap_data_sg(cmd);
63 if (rbuf) {
64 memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
65 transport_kunmap_data_sg(cmd);
66 }
64 67
65 target_complete_cmd(cmd, GOOD); 68 target_complete_cmd(cmd, GOOD);
66 return 0; 69 return 0;
@@ -69,11 +72,11 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd)
69static int sbc_emulate_readcapacity_16(struct se_cmd *cmd) 72static int sbc_emulate_readcapacity_16(struct se_cmd *cmd)
70{ 73{
71 struct se_device *dev = cmd->se_dev; 74 struct se_device *dev = cmd->se_dev;
72 unsigned char *buf; 75 unsigned char *rbuf;
76 unsigned char buf[32];
73 unsigned long long blocks = dev->transport->get_blocks(dev); 77 unsigned long long blocks = dev->transport->get_blocks(dev);
74 78
75 buf = transport_kmap_data_sg(cmd); 79 memset(buf, 0, sizeof(buf));
76
77 buf[0] = (blocks >> 56) & 0xff; 80 buf[0] = (blocks >> 56) & 0xff;
78 buf[1] = (blocks >> 48) & 0xff; 81 buf[1] = (blocks >> 48) & 0xff;
79 buf[2] = (blocks >> 40) & 0xff; 82 buf[2] = (blocks >> 40) & 0xff;
@@ -93,7 +96,11 @@ static int sbc_emulate_readcapacity_16(struct se_cmd *cmd)
93 if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) 96 if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
94 buf[14] = 0x80; 97 buf[14] = 0x80;
95 98
96 transport_kunmap_data_sg(cmd); 99 rbuf = transport_kmap_data_sg(cmd);
100 if (rbuf) {
101 memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
102 transport_kunmap_data_sg(cmd);
103 }
97 104
98 target_complete_cmd(cmd, GOOD); 105 target_complete_cmd(cmd, GOOD);
99 return 0; 106 return 0;