Commit 6fb05e0d authored by Steven Toth's avatar Steven Toth Committed by Mauro Carvalho Chehab

[media] saa7164: fix double fetch PCIe access condition

Avoid a double fetch by reusing the values from the prior transfer.

Originally reported via https://bugzilla.kernel.org/show_bug.cgi?id=195559

Thanks to Pengfei Wang <wpengfeinudt@gmail.com> for reporting.
Signed-off-by: default avatarSteven Toth <stoth@kernellabs.com>
Reported-by: default avatarPengfei Wang <wpengfeinudt@gmail.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 9e9e6a78
...@@ -389,11 +389,11 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, ...@@ -389,11 +389,11 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
msg_tmp.size = le16_to_cpu((__force __le16)msg_tmp.size); msg_tmp.size = le16_to_cpu((__force __le16)msg_tmp.size);
msg_tmp.command = le32_to_cpu((__force __le32)msg_tmp.command); msg_tmp.command = le32_to_cpu((__force __le32)msg_tmp.command);
msg_tmp.controlselector = le16_to_cpu((__force __le16)msg_tmp.controlselector); msg_tmp.controlselector = le16_to_cpu((__force __le16)msg_tmp.controlselector);
memcpy(msg, &msg_tmp, sizeof(*msg));
/* No need to update the read positions, because this was a peek */ /* No need to update the read positions, because this was a peek */
/* If the caller specifically want to peek, return */ /* If the caller specifically want to peek, return */
if (peekonly) { if (peekonly) {
memcpy(msg, &msg_tmp, sizeof(*msg));
goto peekout; goto peekout;
} }
...@@ -438,21 +438,15 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, ...@@ -438,21 +438,15 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
space_rem = bus->m_dwSizeGetRing - curr_grp; space_rem = bus->m_dwSizeGetRing - curr_grp;
if (space_rem < sizeof(*msg)) { if (space_rem < sizeof(*msg)) {
/* msg wraps around the ring */
memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, space_rem);
memcpy_fromio((u8 *)msg + space_rem, bus->m_pdwGetRing,
sizeof(*msg) - space_rem);
if (buf) if (buf)
memcpy_fromio(buf, bus->m_pdwGetRing + sizeof(*msg) - memcpy_fromio(buf, bus->m_pdwGetRing + sizeof(*msg) -
space_rem, buf_size); space_rem, buf_size);
} else if (space_rem == sizeof(*msg)) { } else if (space_rem == sizeof(*msg)) {
memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
if (buf) if (buf)
memcpy_fromio(buf, bus->m_pdwGetRing, buf_size); memcpy_fromio(buf, bus->m_pdwGetRing, buf_size);
} else { } else {
/* Additional data wraps around the ring */ /* Additional data wraps around the ring */
memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
if (buf) { if (buf) {
memcpy_fromio(buf, bus->m_pdwGetRing + curr_grp + memcpy_fromio(buf, bus->m_pdwGetRing + curr_grp +
sizeof(*msg), space_rem - sizeof(*msg)); sizeof(*msg), space_rem - sizeof(*msg));
...@@ -465,15 +459,10 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, ...@@ -465,15 +459,10 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
} else { } else {
/* No wrapping */ /* No wrapping */
memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
if (buf) if (buf)
memcpy_fromio(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg), memcpy_fromio(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg),
buf_size); buf_size);
} }
/* Convert from little endian to CPU */
msg->size = le16_to_cpu((__force __le16)msg->size);
msg->command = le32_to_cpu((__force __le32)msg->command);
msg->controlselector = le16_to_cpu((__force __le16)msg->controlselector);
/* Update the read positions, adjusting the ring */ /* Update the read positions, adjusting the ring */
saa7164_writel(bus->m_dwGetReadPos, new_grp); saa7164_writel(bus->m_dwGetReadPos, new_grp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment