summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/usb/dev-unifying.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/hw/usb/dev-unifying.c b/hw/usb/dev-unifying.c
index f31d0040dd..9e3a487e68 100644
--- a/hw/usb/dev-unifying.c
+++ b/hw/usb/dev-unifying.c
@@ -339,10 +339,27 @@ static const USBDesc desc_ltunify = {
.str = desc_strings,
};
+/* temporary helper to find a paired device matching this HID device */
+static LHidDevice *find_lhid_device(USBLtunifyState *s, HIDState *hs)
+{
+ int i;
+ LHidDevice *hd;
+
+ for (i = 0; i < MAX_DEVICES; i++) {
+ hd = &s->devices[i];
+ if (hd->hid == hs) {
+ return hd;
+ }
+ }
+
+ return NULL;
+}
+
/* Called when the host mouse or keyboard generates an event */
static void usb_ltunify_hid_event(HIDState *hs)
{
USBLtunifyState *s;
+ LHidDevice *hd;
uint8_t ifnum;
if (hs->kind == HID_KEYBOARD) {
@@ -354,11 +371,11 @@ static void usb_ltunify_hid_event(HIDState *hs)
}
s = container_of(hs, USBLtunifyState, hid[ifnum]);
- /* TODO: devices can get unpaired. Move HIDState to LHidDevice! */
- if (s->devices[ifnum].mode == LTUNIFY_MODE_HID) {
+ hd = find_lhid_device(s, hs);
+ if (hd == NULL || hd->mode == LTUNIFY_MODE_HID) {
usb_wakeup(s->intr[ifnum], 0);
} else {
- assert(s->devices[ifnum].mode == LTUNIFY_MODE_DJ);
+ assert(hd->mode == LTUNIFY_MODE_DJ);
usb_wakeup(s->intr[IFACE_HIDPP], 0);
}
}
@@ -537,8 +554,15 @@ static void usb_ltunify_handle_datain_hid(USBDevice *dev, USBPacket *p)
uint8_t ifnum = p->ep->nr == 1 ? IFACE_KBD : IFACE_MSE;
HIDState *hs = &s->hid[ifnum];
uint8_t buf[p->iov.size];
+ LHidDevice *hd = find_lhid_device(s, hs);
int len;
+ if (hd != NULL && hd->mode == LTUNIFY_MODE_DJ) {
+ /* do not speak HID when in HID++ mode */
+ p->status = USB_RET_NAK;
+ return;
+ }
+
len = usb_ltunify_poll_hid(hs, buf, sizeof(buf));
if (len <= 0) {
p->status = USB_RET_NAK;