USB HID does not support Set_Idle
I found that the QEMU USB keyboard support does not work properly with the Set_Idle command. Once a non-zero value is given to Set_Idle, then the keyboard reports an event on every poll - not based on the time issued in the Set_Idle command. I changed the code (see patch below) and it works for me. I'm not that familiar with the qemu internals, so I'm not sure if this is the best way to implement this feature. -Kevin Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
4dca4b639c
commit
68735b6c0c
12
hw/usb-hid.c
12
hw/usb-hid.c
@ -66,6 +66,7 @@ typedef struct USBHIDState {
|
|||||||
int kind;
|
int kind;
|
||||||
int protocol;
|
int protocol;
|
||||||
uint8_t idle;
|
uint8_t idle;
|
||||||
|
int64_t next_idle_clock;
|
||||||
int changed;
|
int changed;
|
||||||
void *datain_opaque;
|
void *datain_opaque;
|
||||||
void (*datain)(void *);
|
void (*datain)(void *);
|
||||||
@ -630,6 +631,11 @@ static void usb_keyboard_handle_reset(USBDevice *dev)
|
|||||||
s->protocol = 1;
|
s->protocol = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void usb_hid_set_next_idle(USBHIDState *s, int64_t curtime)
|
||||||
|
{
|
||||||
|
s->next_idle_clock = curtime + (get_ticks_per_sec() * s->idle * 4) / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
static int usb_hid_handle_control(USBDevice *dev, int request, int value,
|
static int usb_hid_handle_control(USBDevice *dev, int request, int value,
|
||||||
int index, int length, uint8_t *data)
|
int index, int length, uint8_t *data)
|
||||||
{
|
{
|
||||||
@ -795,6 +801,7 @@ static int usb_hid_handle_control(USBDevice *dev, int request, int value,
|
|||||||
break;
|
break;
|
||||||
case SET_IDLE:
|
case SET_IDLE:
|
||||||
s->idle = (uint8_t) (value >> 8);
|
s->idle = (uint8_t) (value >> 8);
|
||||||
|
usb_hid_set_next_idle(s, qemu_get_clock(vm_clock));
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -813,9 +820,10 @@ static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
|
|||||||
switch(p->pid) {
|
switch(p->pid) {
|
||||||
case USB_TOKEN_IN:
|
case USB_TOKEN_IN:
|
||||||
if (p->devep == 1) {
|
if (p->devep == 1) {
|
||||||
/* TODO: Implement finite idle delays. */
|
int64_t curtime = qemu_get_clock(vm_clock);
|
||||||
if (!(s->changed || s->idle))
|
if (!s->changed && (!s->idle || s->next_idle_clock - curtime > 0))
|
||||||
return USB_RET_NAK;
|
return USB_RET_NAK;
|
||||||
|
usb_hid_set_next_idle(s, curtime);
|
||||||
s->changed = 0;
|
s->changed = 0;
|
||||||
if (s->kind == USB_MOUSE)
|
if (s->kind == USB_MOUSE)
|
||||||
ret = usb_mouse_poll(s, p->data, p->len);
|
ret = usb_mouse_poll(s, p->data, p->len);
|
||||||
|
Loading…
Reference in New Issue
Block a user