From 4e6cc45456993307d605dfe50b5e370ba93fac9d Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Wed, 19 Mar 2014 15:14:33 +0100 Subject: unifying: rename input queue, fix error queue Fix error queue name, rename input queue for clarity. Split input and output queue for further work and NAK when there is no interrupt data available. --- hw/usb/hid-logitech-dj.c | 45 +++++++++++++++++++++++++++++++++------------ hw/usb/hid-logitech-dj.h | 9 +++++++-- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/hw/usb/hid-logitech-dj.c b/hw/usb/hid-logitech-dj.c index ab7db1be8a..6b49e816c0 100644 --- a/hw/usb/hid-logitech-dj.c +++ b/hw/usb/hid-logitech-dj.c @@ -54,9 +54,10 @@ static void hidpp_queue_error(USBLtunifyState *s, HidppMsg *msg, uint8_t err) unsigned slot; if (s->error_queue.n < LQUEUE_SIZE(s->error_queue)) { - slot = LQUEUE_WRAP(s->error_queue, s->queue.head + s->queue.n); + slot = LQUEUE_WRAP(s->error_queue, s->error_queue.head + s->error_queue.n); s->error_queue.n++; report = &s->error_queue.reports[slot]; + report->report_id = HIDPP_SHORT; report->device_index = msg->device_index; report->sub_id = msg->hidpp_s.sub_id; report->address = msg->hidpp_s.address; @@ -65,6 +66,19 @@ static void hidpp_queue_error(USBLtunifyState *s, HidppMsg *msg, uint8_t err) } } +static void hidpp_queue_output_report(USBLtunifyState *s, HidppMsg *msg) +{ + unsigned slot; + + assert(msg_report_length(msg) != 0); + + if (s->output_queue.n < LQUEUE_SIZE(s->output_queue)) { + slot = LQUEUE_WRAP(s->output_queue, s->output_queue.head + s->output_queue.n); + s->output_queue.n++; + s->output_queue.reports[slot] = *msg; + } +} + /* process a received report */ static void hidpp_set_report(USBDevice *dev, USBPacket *p, uint8_t *data, size_t len) { @@ -78,10 +92,10 @@ static void hidpp_set_report(USBDevice *dev, USBPacket *p, uint8_t *data, size_t report_len = msg_report_length(msg); if (report_len > 0 && len >= report_len) { - if (s->queue.n < LQUEUE_SIZE(s->queue)) { - unsigned slot = LQUEUE_WRAP(s->queue, s->queue.head + s->queue.n); - s->queue.n++; - memcpy((uint8_t *) &s->queue.reports[slot], data, report_len); + if (s->input_queue.n < LQUEUE_SIZE(s->input_queue)) { + unsigned slot = LQUEUE_WRAP(s->input_queue, s->input_queue.head + s->input_queue.n); + s->input_queue.n++; + memcpy((uint8_t *) &s->input_queue.reports[slot], data, report_len); } else { /* queue full, cannot accept this report */ hidpp_queue_error(s, msg, HIDPP_ERR_BUSY); @@ -117,22 +131,27 @@ void usb_ltunify_handle_datain_hidpp(USBDevice *dev, USBPacket *p) int len = 0; HidppMsg *msg = NULL; - assert(p->pid == USB_TOKEN_IN); assert(p->ep->nr == 3); + /* process input reports */ + if (s->input_queue.n > 0 && 0) { + slot = s->input_queue.head; + LQUEUE_INCR(s->input_queue, s->input_queue.head); + s->input_queue.n--; + } + /* try to send a reply to a previously sent request if possible. */ if (s->error_queue.n > 0) { slot = s->error_queue.head; LQUEUE_INCR(s->error_queue, s->error_queue.head); s->error_queue.n--; msg = (HidppMsg *) &s->error_queue.reports[slot]; - } else if (s->queue.n > 0) { - slot = s->queue.head; - LQUEUE_INCR(s->queue, s->queue.head); - s->queue.n--; - msg = &s->queue.reports[slot]; - /* TODO: really process message instead of sending it back... */ + } else if (s->output_queue.n > 0) { + slot = s->output_queue.head; + LQUEUE_INCR(s->output_queue, s->output_queue.head); + s->output_queue.n--; + msg = &s->output_queue.reports[slot]; } if (msg != NULL) { @@ -141,5 +160,7 @@ void usb_ltunify_handle_datain_hidpp(USBDevice *dev, USBPacket *p) usb_dump_complete_data(s->usb_dump_state, p, (uint8_t *) msg, len); usb_packet_copy(p, (uint8_t *) msg, len); usb_dump_submit(s->usb_dump_state, p); + } else { + p->status = USB_RET_NAK; } } diff --git a/hw/usb/hid-logitech-dj.h b/hw/usb/hid-logitech-dj.h index 36b2c31e2e..bc4a044382 100644 --- a/hw/usb/hid-logitech-dj.h +++ b/hw/usb/hid-logitech-dj.h @@ -196,7 +196,12 @@ typedef struct USBLtunifyState { HidppMsg reports[16]; unsigned head; unsigned n; - } queue; + } input_queue; + struct { + HidppMsg reports[16]; + unsigned head; + unsigned n; + } output_queue; /* receiver error queue (to be send): drop if full */ struct { HidppMsgShort reports[2]; @@ -204,7 +209,7 @@ typedef struct USBLtunifyState { unsigned n; } error_queue; LHidReceiver receiver; - LHidDevice devices[MAX_DEVICES]; + LHidDevice devices[MAX_DEVICES]; /* paired devices */ } USBLtunifyState; -- cgit v1.2.1