From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=50008 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PhPJr-0001wk-Rj for qemu-devel@nongnu.org; Mon, 24 Jan 2011 11:31:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PhPJq-0000Ta-HS for qemu-devel@nongnu.org; Mon, 24 Jan 2011 11:31:07 -0500 Received: from mx1.redhat.com ([209.132.183.28]:41232) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PhPJq-0000T7-97 for qemu-devel@nongnu.org; Mon, 24 Jan 2011 11:31:06 -0500 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id p0OGV5RU030590 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 24 Jan 2011 11:31:05 -0500 From: Gerd Hoffmann Date: Mon, 24 Jan 2011 17:30:52 +0100 Message-Id: <1295886655-32312-6-git-send-email-kraxel@redhat.com> In-Reply-To: <1295886655-32312-1-git-send-email-kraxel@redhat.com> References: <1295886655-32312-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH 5/8] usb core: add migration support List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann Yes, seriously. There is no migration support at all for usb devices. They loose state, especially the device address, and stop responding because of that. Oops. Luckily there is so much broken usb hardware out there that the guest usually just kicks the device hard (via port reset and reinitialization), then continues without a hitch. So we got away with that in a surprising high number of cases. The arrival of remote wakeup (which enables autosuspend support) changes that picture though. The usb devices also forget that it they are supposed to wakeup, so they don't do that. The host also doesn't notice the device stopped working in case it suspended the device and thus expects it waking up instead of polling it. Result is that your mouse is dead. Lets start fixing that. Add a vmstate struct for USBDevice. Signed-off-by: Gerd Hoffmann --- hw/hw.h | 10 ++++++++++ hw/usb-bus.c | 16 ++++++++++++++++ hw/usb.h | 10 +++++----- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index dd993de..5e24329 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -587,6 +587,16 @@ extern const VMStateDescription vmstate_i2c_slave; .offset = vmstate_offset_value(_state, _field, i2c_slave), \ } +extern const VMStateDescription vmstate_usb_device; + +#define VMSTATE_USB_DEVICE(_field, _state) { \ + .name = (stringify(_field)), \ + .size = sizeof(USBDevice), \ + .vmsd = &vmstate_usb_device, \ + .flags = VMS_STRUCT, \ + .offset = vmstate_offset_value(_state, _field, USBDevice), \ +} + #define vmstate_offset_macaddr(_state, _field) \ vmstate_offset_array(_state, _field.a, uint8_t, \ sizeof(typeof_field(_state, _field))) diff --git a/hw/usb-bus.c b/hw/usb-bus.c index 6e2e5fd..ac56fbc 100644 --- a/hw/usb-bus.c +++ b/hw/usb-bus.c @@ -23,6 +23,22 @@ static struct BusInfo usb_bus_info = { static int next_usb_bus = 0; static QTAILQ_HEAD(, USBBus) busses = QTAILQ_HEAD_INITIALIZER(busses); +const VMStateDescription vmstate_usb_device = { + .name = "USBDevice", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField []) { + VMSTATE_UINT8(addr, USBDevice), + VMSTATE_INT32(state, USBDevice), + VMSTATE_INT32(remote_wakeup, USBDevice), + VMSTATE_INT32(setup_state, USBDevice), + VMSTATE_INT32(setup_len, USBDevice), + VMSTATE_INT32(setup_index, USBDevice), + VMSTATE_UINT8_ARRAY(setup_buf, USBDevice, 8), + VMSTATE_END_OF_LIST(), + } +}; + void usb_bus_new(USBBus *bus, DeviceState *host) { qbus_create_inplace(&bus->qbus, &usb_bus_info, host, NULL); diff --git a/hw/usb.h b/hw/usb.h index 5c1da3e..d3d755d 100644 --- a/hw/usb.h +++ b/hw/usb.h @@ -165,13 +165,13 @@ struct USBDevice { int auto_attach; int attached; - int state; + int32_t state; uint8_t setup_buf[8]; uint8_t data_buf[1024]; - int remote_wakeup; - int setup_state; - int setup_len; - int setup_index; + int32_t remote_wakeup; + int32_t setup_state; + int32_t setup_len; + int32_t setup_index; QLIST_HEAD(, USBDescString) strings; const USBDescDevice *device; -- 1.7.1