Whilst autopoll is enabled it is necessary to prevent the ADB buffer contents
from being overwritten until the host has read back the response in its
entirety.
Add adb_autopoll_block() and adb_autopoll_unblock() functions in preparation
for ensuring that the ADB buffer contents are protected for explicit ADB
requests.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Tested-by: Finn Thain <fthain@telegraphics.com.au>
Acked-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <20200623204936.24064-16-mark.cave-ayland@ilande.co.uk>
---
hw/input/adb.c | 21 +++++++++++++++++++++
include/hw/input/adb.h | 4 ++++
2 files changed, 25 insertions(+)
diff --git a/hw/input/adb.c b/hw/input/adb.c
index b3ad7c5fca..70aa1f4570 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -157,6 +157,26 @@ void adb_set_autopoll_mask(ADBBusState *s, uint16_t mask)
}
}
+void adb_autopoll_block(ADBBusState *s)
+{
+ s->autopoll_blocked = true;
+
+ if (s->autopoll_enabled) {
+ timer_del(s->autopoll_timer);
+ }
+}
+
+void adb_autopoll_unblock(ADBBusState *s)
+{
+ s->autopoll_blocked = false;
+
+ if (s->autopoll_enabled) {
+ timer_mod(s->autopoll_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+ s->autopoll_rate_ms);
+ }
+}
+
static void adb_autopoll(void *opaque)
{
ADBBusState *s = opaque;
@@ -184,6 +204,7 @@ static const VMStateDescription vmstate_adb_bus = {
VMSTATE_BOOL(autopoll_enabled, ADBBusState),
VMSTATE_UINT8(autopoll_rate_ms, ADBBusState),
VMSTATE_UINT16(autopoll_mask, ADBBusState),
+ VMSTATE_BOOL(autopoll_blocked, ADBBusState),
VMSTATE_END_OF_LIST()
}
};
diff --git a/include/hw/input/adb.h b/include/hw/input/adb.h
index cff264739c..bb75a7b1e3 100644
--- a/include/hw/input/adb.h
+++ b/include/hw/input/adb.h
@@ -86,6 +86,7 @@ struct ADBBusState {
QEMUTimer *autopoll_timer;
bool autopoll_enabled;
+ bool autopoll_blocked;
uint8_t autopoll_rate_ms;
uint16_t autopoll_mask;
void (*autopoll_cb)(void *opaque);
@@ -96,6 +97,9 @@ int adb_request(ADBBusState *s, uint8_t *buf_out,
const uint8_t *buf, int len);
int adb_poll(ADBBusState *s, uint8_t *buf_out, uint16_t poll_mask);
+void adb_autopoll_block(ADBBusState *s);
+void adb_autopoll_unblock(ADBBusState *s);
+
void adb_set_autopoll_enabled(ADBBusState *s, bool enabled);
void adb_set_autopoll_rate_ms(ADBBusState *s, int rate_ms);
void adb_set_autopoll_mask(ADBBusState *s, uint16_t mask);
--
2.20.1