summaryrefslogtreecommitdiff
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
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.
-rw-r--r--hw/usb/hid-logitech-dj.c45
-rw-r--r--hw/usb/hid-logitech-dj.h9
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;