summaryrefslogtreecommitdiff
path: root/hw/usb/hid-logitech-dj.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/usb/hid-logitech-dj.c')
-rw-r--r--hw/usb/hid-logitech-dj.c45
1 files changed, 33 insertions, 12 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;
}
}