@@ -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()
}
};
@@ -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);
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> --- hw/input/adb.c | 21 +++++++++++++++++++++ include/hw/input/adb.h | 4 ++++ 2 files changed, 25 insertions(+)