[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: Steven Toth <stoth@kernellabs.com> Reported-by: Pengfei Wang <wpengfeinudt@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
parent
9e9e6a7814
commit
6fb05e0dd3
@ -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,
|
|||||||
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,
|
|||||||
|
|
||||||
} 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);
|
||||||
|
Loading…
Reference in New Issue
Block a user