summaryrefslogtreecommitdiff
path: root/hw/usb/hid-logitech-dj.c
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-03-19 15:14:33 +0100
committerPeter Wu <peter@lekensteyn.nl>2014-03-19 15:14:33 +0100
commit4e6cc45456993307d605dfe50b5e370ba93fac9d (patch)
tree49fff599fbac53ff9874f933cddc828f3445b3b3 /hw/usb/hid-logitech-dj.c
parent3a5922cc11f73269bfcd762997efc2c029a3b585 (diff)
downloadqemu-4e6cc45456993307d605dfe50b5e370ba93fac9d.tar.gz
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.
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;
}
}