diff options
-rw-r--r-- | hw/input/hid.c | 32 | ||||
-rw-r--r-- | hw/input/virtio-input-hid.c | 1 | ||||
-rw-r--r-- | hw/input/virtio-input-host.c | 1 | ||||
-rw-r--r-- | hw/usb/dev-smartcard-reader.c | 21 | ||||
-rw-r--r-- | hw/usb/hcd-xhci.c | 2 | ||||
-rw-r--r-- | hw/usb/host-libusb.c | 3 | ||||
-rw-r--r-- | hw/virtio/virtio-rng.c | 15 | ||||
-rw-r--r-- | include/hw/virtio/virtio-rng.h | 1 | ||||
-rw-r--r-- | include/standard-headers/linux/input.h | 1 | ||||
-rwxr-xr-x | scripts/update-linux-headers.sh | 1 |
10 files changed, 56 insertions, 22 deletions
diff --git a/hw/input/hid.c b/hw/input/hid.c index 6841cb8649..21ebd9e718 100644 --- a/hw/input/hid.c +++ b/hw/input/hid.c @@ -239,7 +239,7 @@ static void hid_keyboard_event(DeviceState *dev, QemuConsole *src, static void hid_keyboard_process_keycode(HIDState *hs) { - uint8_t hid_code, key; + uint8_t hid_code, index, key; int i, keycode, slot; if (hs->n == 0) { @@ -249,7 +249,8 @@ static void hid_keyboard_process_keycode(HIDState *hs) keycode = hs->kbd.keycodes[slot]; key = keycode & 0x7f; - hid_code = hid_usage_keys[key | ((hs->kbd.modifiers >> 1) & (1 << 7))]; + index = key | ((hs->kbd.modifiers & (1 << 8)) >> 1); + hid_code = hid_usage_keys[index]; hs->kbd.modifiers &= ~(1 << 8); switch (hid_code) { @@ -257,18 +258,41 @@ static void hid_keyboard_process_keycode(HIDState *hs) return; case 0xe0: + assert(key == 0x1d); if (hs->kbd.modifiers & (1 << 9)) { - hs->kbd.modifiers ^= 3 << 8; + /* The hid_codes for the 0xe1/0x1d scancode sequence are 0xe9/0xe0. + * Here we're processing the second hid_code. By dropping bit 9 + * and setting bit 8, the scancode after 0x1d will access the + * second half of the table. + */ + hs->kbd.modifiers ^= (1 << 8) | (1 << 9); return; } + /* fall through to process Ctrl_L */ case 0xe1 ... 0xe7: + /* Ctrl_L/Ctrl_R, Shift_L/Shift_R, Alt_L/Alt_R, Win_L/Win_R. + * Handle releases here, or fall through to process presses. + */ if (keycode & (1 << 7)) { hs->kbd.modifiers &= ~(1 << (hid_code & 0x0f)); return; } - case 0xe8 ... 0xef: + /* fall through */ + case 0xe8 ... 0xe9: + /* USB modifiers are just 1 byte long. Bits 8 and 9 of + * hs->kbd.modifiers implement a state machine that detects the + * 0xe0 and 0xe1/0x1d sequences. These bits do not follow the + * usual rules where bit 7 marks released keys; they are cleared + * elsewhere in the function as the state machine dictates. + */ hs->kbd.modifiers |= 1 << (hid_code & 0x0f); return; + + case 0xea ... 0xef: + abort(); + + default: + break; } if (keycode & (1 << 7)) { diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c index 616a815ed4..4d85dad4d1 100644 --- a/hw/input/virtio-input-hid.c +++ b/hw/input/virtio-input-hid.c @@ -308,6 +308,7 @@ static void virtio_input_hid_handle_status(VirtIOInput *vinput, static Property virtio_input_hid_properties[] = { DEFINE_PROP_STRING("display", VirtIOInputHID, display), DEFINE_PROP_UINT32("head", VirtIOInputHID, head, 0), + DEFINE_PROP_END_OF_LIST(), }; static void virtio_input_hid_class_init(ObjectClass *klass, void *data) diff --git a/hw/input/virtio-input-host.c b/hw/input/virtio-input-host.c index f7e3d844e6..8978f16bae 100644 --- a/hw/input/virtio-input-host.c +++ b/hw/input/virtio-input-host.c @@ -11,6 +11,7 @@ #include "hw/virtio/virtio.h" #include "hw/virtio/virtio-input.h" +#include <sys/ioctl.h> #include "standard-headers/linux/input.h" /* ----------------------------------------------------------------- */ diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c index de534bab37..8952efffa4 100644 --- a/hw/usb/dev-smartcard-reader.c +++ b/hw/usb/dev-smartcard-reader.c @@ -283,6 +283,7 @@ typedef struct CCIDBus { typedef struct USBCCIDState { USBDevice dev; USBEndpoint *intr; + USBEndpoint *bulk; CCIDBus bus; CCIDCardState *card; BulkIn bulk_in_pending[BULK_IN_PENDING_NUM]; /* circular */ @@ -769,6 +770,7 @@ static void ccid_write_slot_status(USBCCIDState *s, CCID_Header *recv) h->b.bError = s->bError; h->bClockStatus = CLOCK_STATUS_RUNNING; ccid_reset_error_status(s); + usb_wakeup(s->bulk, 0); } static void ccid_write_parameters(USBCCIDState *s, CCID_Header *recv) @@ -789,6 +791,7 @@ static void ccid_write_parameters(USBCCIDState *s, CCID_Header *recv) h->bProtocolNum = s->bProtocolNum; h->abProtocolDataStructure = s->abProtocolDataStructure; ccid_reset_error_status(s); + usb_wakeup(s->bulk, 0); } static void ccid_write_data_block(USBCCIDState *s, uint8_t slot, uint8_t seq, @@ -810,6 +813,7 @@ static void ccid_write_data_block(USBCCIDState *s, uint8_t slot, uint8_t seq, } memcpy(p->abData, data, len); ccid_reset_error_status(s); + usb_wakeup(s->bulk, 0); } static void ccid_report_error_failed(USBCCIDState *s, uint8_t error) @@ -1184,7 +1188,7 @@ void ccid_card_send_apdu_to_guest(CCIDCardState *card, uint8_t *apdu, uint32_t len) { DeviceState *qdev = DEVICE(card); - USBDevice *dev = USB_DEVICE(qdev); + USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); USBCCIDState *s = USB_CCID_DEV(dev); Answer *answer; @@ -1207,7 +1211,7 @@ void ccid_card_send_apdu_to_guest(CCIDCardState *card, void ccid_card_card_removed(CCIDCardState *card) { DeviceState *qdev = DEVICE(card); - USBDevice *dev = USB_DEVICE(qdev); + USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); USBCCIDState *s = USB_CCID_DEV(dev); ccid_on_slot_change(s, false); @@ -1218,7 +1222,7 @@ void ccid_card_card_removed(CCIDCardState *card) int ccid_card_ccid_attach(CCIDCardState *card) { DeviceState *qdev = DEVICE(card); - USBDevice *dev = USB_DEVICE(qdev); + USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); USBCCIDState *s = USB_CCID_DEV(dev); DPRINTF(s, 1, "CCID Attach\n"); @@ -1231,7 +1235,7 @@ int ccid_card_ccid_attach(CCIDCardState *card) void ccid_card_ccid_detach(CCIDCardState *card) { DeviceState *qdev = DEVICE(card); - USBDevice *dev = USB_DEVICE(qdev); + USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); USBCCIDState *s = USB_CCID_DEV(dev); DPRINTF(s, 1, "CCID Detach\n"); @@ -1244,7 +1248,7 @@ void ccid_card_ccid_detach(CCIDCardState *card) void ccid_card_card_error(CCIDCardState *card, uint64_t error) { DeviceState *qdev = DEVICE(card); - USBDevice *dev = USB_DEVICE(qdev); + USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); USBCCIDState *s = USB_CCID_DEV(dev); s->bmCommandStatus = COMMAND_STATUS_FAILED; @@ -1263,7 +1267,7 @@ void ccid_card_card_error(CCIDCardState *card, uint64_t error) void ccid_card_card_inserted(CCIDCardState *card) { DeviceState *qdev = DEVICE(card); - USBDevice *dev = USB_DEVICE(qdev); + USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); USBCCIDState *s = USB_CCID_DEV(dev); s->bmCommandStatus = COMMAND_STATUS_NO_ERROR; @@ -1275,7 +1279,7 @@ static int ccid_card_exit(DeviceState *qdev) { int ret = 0; CCIDCardState *card = CCID_CARD(qdev); - USBDevice *dev = USB_DEVICE(qdev); + USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); USBCCIDState *s = USB_CCID_DEV(dev); if (ccid_card_inserted(s)) { @@ -1289,7 +1293,7 @@ static int ccid_card_exit(DeviceState *qdev) static int ccid_card_init(DeviceState *qdev) { CCIDCardState *card = CCID_CARD(qdev); - USBDevice *dev = USB_DEVICE(qdev); + USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); USBCCIDState *s = USB_CCID_DEV(dev); int ret = 0; @@ -1319,6 +1323,7 @@ static void ccid_realize(USBDevice *dev, Error **errp) NULL); qbus_set_hotplug_handler(BUS(&s->bus), DEVICE(dev), &error_abort); s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP); + s->bulk = usb_ep_get(dev, USB_TOKEN_IN, CCID_BULK_IN_EP); s->card = NULL; s->migration_state = MIGRATION_NONE; s->migration_target_ip = 0; diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 90a5fbff29..c673bed4c4 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -2222,8 +2222,6 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, if (xfer->running_retry) { DPRINTF("xhci: xfer nacked, stopping schedule\n"); epctx->retry = xfer; - timer_mod(epctx->kick_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - epctx->interval * 125000); break; } } diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index bc2944c6b2..11429f5e73 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -889,6 +889,9 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev) fail: trace_usb_host_open_failure(bus_num, addr); if (s->dh != NULL) { + usb_host_release_interfaces(s); + libusb_reset_device(s->dh); + usb_host_attach_kernel(s); libusb_close(s->dh); s->dh = NULL; s->dev = NULL; diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index 740ed3102b..6e5f022301 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -77,6 +77,12 @@ static void virtio_rng_process(VirtIORNG *vrng) return; } + if (vrng->activate_timer) { + timer_mod(vrng->rate_limit_timer, + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + vrng->conf.period_ms); + vrng->activate_timer = false; + } + if (vrng->quota_remaining < 0) { quota = 0; } else { @@ -138,8 +144,7 @@ static void check_rate_limit(void *opaque) vrng->quota_remaining = vrng->conf.max_bytes; virtio_rng_process(vrng); - timer_mod(vrng->rate_limit_timer, - qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + vrng->conf.period_ms); + vrng->activate_timer = true; } static void virtio_rng_device_realize(DeviceState *dev, Error **errp) @@ -195,13 +200,9 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp) vrng->vq = virtio_add_queue(vdev, 8, handle_input); vrng->quota_remaining = vrng->conf.max_bytes; - vrng->rate_limit_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, check_rate_limit, vrng); - - timer_mod(vrng->rate_limit_timer, - qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + vrng->conf.period_ms); - + vrng->activate_timer = true; register_savevm(dev, "virtio-rng", -1, 1, virtio_rng_save, virtio_rng_load, vrng); } diff --git a/include/hw/virtio/virtio-rng.h b/include/hw/virtio/virtio-rng.h index 0316488733..3f07de70c7 100644 --- a/include/hw/virtio/virtio-rng.h +++ b/include/hw/virtio/virtio-rng.h @@ -44,6 +44,7 @@ typedef struct VirtIORNG { */ QEMUTimer *rate_limit_timer; int64_t quota_remaining; + bool activate_timer; } VirtIORNG; #endif diff --git a/include/standard-headers/linux/input.h b/include/standard-headers/linux/input.h index a459dd25da..b003c67059 100644 --- a/include/standard-headers/linux/input.h +++ b/include/standard-headers/linux/input.h @@ -10,7 +10,6 @@ #include <sys/time.h> -#include <sys/ioctl.h> #include <sys/types.h> #include "standard-headers/linux/types.h" diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index 47378d93d4..f0e830c2d6 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -56,6 +56,7 @@ cp_virtio() { -e 's/__bitwise__//' \ -e 's/__attribute__((packed))/QEMU_PACKED/' \ -e 's/__inline__/inline/' \ + -e '/sys\/ioctl.h/d' \ "$f" > "$to/$header"; done fi |