Commit da52c083 authored by Mark Cave-Ayland's avatar Mark Cave-Ayland
Browse files

adb: create autopoll variables directly within ADBBusState



Rather than each ADB implementation requiring its own functions to manage
autopoll state, timers, and autopoll masks prepare to move this information
directly into ADBBusState.

Add external functions within adb.h to allow each ADB implementation to
manage the new autopoll variables.

Signed-off-by: default avatarMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Tested-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Acked-by: default avatarLaurent Vivier <laurent@vivier.eu>
Message-Id: <20200623204936.24064-8-mark.cave-ayland@ilande.co.uk>
parent 0606b288
Loading
Loading
Loading
Loading
+77 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "adb-internal.h"

/* error codes */
@@ -89,19 +90,92 @@ int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
    return olen;
}

void adb_set_autopoll_enabled(ADBBusState *s, bool enabled)
{
    if (s->autopoll_enabled != enabled) {
        s->autopoll_enabled = enabled;
        if (s->autopoll_enabled) {
            timer_mod(s->autopoll_timer,
                      qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
                      s->autopoll_rate_ms);
        } else {
            timer_del(s->autopoll_timer);
        }
    }
}

void adb_set_autopoll_rate_ms(ADBBusState *s, int rate_ms)
{
    s->autopoll_rate_ms = rate_ms;

    if (s->autopoll_enabled) {
        timer_mod(s->autopoll_timer,
                  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
                  s->autopoll_rate_ms);
    }
}

void adb_set_autopoll_mask(ADBBusState *s, uint16_t mask)
{
    if (s->autopoll_mask != mask) {
        s->autopoll_mask = mask;
        if (s->autopoll_enabled && s->autopoll_mask) {
            timer_mod(s->autopoll_timer,
                      qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
                      s->autopoll_rate_ms);
        } else {
            timer_del(s->autopoll_timer);
        }
    }
}

static void adb_autopoll(void *opaque)
{
    ADBBusState *s = opaque;

    s->autopoll_cb(s->autopoll_cb_opaque);

    timer_mod(s->autopoll_timer,
              qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
              s->autopoll_rate_ms);
}

void adb_register_autopoll_callback(ADBBusState *s, void (*cb)(void *opaque),
                                    void *opaque)
{
    s->autopoll_cb = cb;
    s->autopoll_cb_opaque = opaque;
}

static const VMStateDescription vmstate_adb_bus = {
    .name = "adb_bus",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_TIMER_PTR(autopoll_timer, ADBBusState),
        VMSTATE_BOOL(autopoll_enabled, ADBBusState),
        VMSTATE_UINT8(autopoll_rate_ms, ADBBusState),
        VMSTATE_UINT16(autopoll_mask, ADBBusState),
        VMSTATE_END_OF_LIST()
    }
};

static void adb_bus_reset(BusState *qbus)
{
    ADBBusState *adb_bus = ADB_BUS(qbus);

    adb_bus->autopoll_enabled = false;
    adb_bus->autopoll_mask = 0xffff;
    adb_bus->autopoll_rate_ms = 20;
}

static void adb_bus_realize(BusState *qbus, Error **errp)
{
    ADBBusState *adb_bus = ADB_BUS(qbus);

    adb_bus->autopoll_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, adb_autopoll,
                                           adb_bus);

    vmstate_register(NULL, -1, &vmstate_adb_bus, adb_bus);
}

@@ -109,6 +183,8 @@ static void adb_bus_unrealize(BusState *qbus)
{
    ADBBusState *adb_bus = ADB_BUS(qbus);

    timer_del(adb_bus->autopoll_timer);

    vmstate_unregister(NULL, &vmstate_adb_bus, adb_bus);
}

@@ -118,6 +194,7 @@ static void adb_bus_class_init(ObjectClass *klass, void *data)

    k->realize = adb_bus_realize;
    k->unrealize = adb_bus_unrealize;
    k->reset = adb_bus_reset;
}

static const TypeInfo adb_bus_type_info = {
+13 −0
Original line number Diff line number Diff line
@@ -75,12 +75,25 @@ struct ADBBusState {
    ADBDevice *devices[MAX_ADB_DEVICES];
    int nb_devices;
    int poll_index;

    QEMUTimer *autopoll_timer;
    bool autopoll_enabled;
    uint8_t autopoll_rate_ms;
    uint16_t autopoll_mask;
    void (*autopoll_cb)(void *opaque);
    void *autopoll_cb_opaque;
};

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_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);
void adb_register_autopoll_callback(ADBBusState *s, void (*cb)(void *opaque),
                                    void *opaque);

#define TYPE_ADB_KEYBOARD "adb-keyboard"
#define TYPE_ADB_MOUSE "adb-mouse"