summaryrefslogtreecommitdiff
path: root/hw/usb
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-03-19 16:52:44 +0100
committerPeter Wu <peter@lekensteyn.nl>2014-03-19 16:52:44 +0100
commit6686b53b2ee32157811c8c0d142690f3e3cace7a (patch)
treef3fc7262969e518ce2e17a5ebf2f77677125cd01 /hw/usb
parent3ae4630e287d6b27c4f19180d68831f019dfd7d4 (diff)
downloadqemu-6686b53b2ee32157811c8c0d142690f3e3cace7a.tar.gz
unifying: process receiver reports earlier
The idea of the input queue is probably that wireless devices cannot immediately be queried, but the receiver is able to respond immediately. Signed-off-by: Peter Wu <peter@lekensteyn.nl>
Diffstat (limited to 'hw/usb')
-rw-r--r--hw/usb/hid-logitech-dj.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/hw/usb/hid-logitech-dj.c b/hw/usb/hid-logitech-dj.c
index 62a15ea802..9ff049ff86 100644
--- a/hw/usb/hid-logitech-dj.c
+++ b/hw/usb/hid-logitech-dj.c
@@ -94,14 +94,16 @@ static bool hidpp_device_available(USBLtunifyState *s, uint8_t device_index)
s->devices[device_index - 1].powered_on;
}
-static void hidpp_process_input_report(USBLtunifyState *s, HidppMsg msg)
+static bool hidpp_process_receiver_report(USBLtunifyState *s, HidppMsg msg)
{
LHidDevice *hd;
int i;
uint8_t *parms = msg.dj_s.payload;
- /* reports for receiver */
- if (msg.device_index == 0xFF) {
+ assert(msg.device_index == 0xFF);
+
+ if (msg.report_id == DJ_SHORT) {
+ /* DJ reports */
switch (msg.dj_s.report_type) {
case 0x80: /* Switch and Keep-Alive */
for (i = 0; i < MAX_DEVICES; i++) {
@@ -143,7 +145,23 @@ static void hidpp_process_input_report(USBLtunifyState *s, HidppMsg msg)
default:
hidpp_queue_error(s, &msg, HIDPP_ERR_INVALID_SUBID);
}
- } else if (hidpp_device_available(s, msg.device_index)) {
+ } else if (msg.report_id == HIDPP_SHORT || msg.report_id == HIDPP_LONG) {
+ /* TODO: handle requests */
+ } else {
+ /* DJ_LONG is unhandled */
+ return false;
+ }
+
+ /* report is accepted and possibly processed */
+ return true;
+}
+
+static void hidpp_process_input_report(USBLtunifyState *s, HidppMsg msg)
+{
+ /* receiver reports are processed earlier, elsewhere */
+ assert(msg.device_index != 0xFF);
+
+ if (hidpp_device_available(s, msg.device_index)) {
/* TODO: implement for devices */
hidpp_queue_error(s, &msg, HIDPP_ERR_REQUEST_UNAVAILABLE);
} else {
@@ -164,7 +182,12 @@ 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->input_queue.n < LQUEUE_SIZE(s->input_queue)) {
+ if (msg->device_index == 0xFF) {
+ /* receiver messages can be processed immediately */
+ if (!hidpp_process_receiver_report(s, *msg)) {
+ goto fail;
+ }
+ } else 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);