From 7707beaea780d1ed918fd25a9ce84f055fe17921 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 2 Mar 2021 13:01:52 +0100 Subject: [PATCH 01/13] hw/usb/bus: Remove the "full-path" property This property was only required for the pc-1.0 and earlier machine types. Since these have been removed now, we can delete the property as well. Signed-off-by: Thomas Huth Message-Id: <20210302120152.118042-1-thuth@redhat.com> Signed-off-by: Gerd Hoffmann --- hw/usb/bus.c | 7 +------ include/hw/usb.h | 1 - 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/hw/usb/bus.c b/hw/usb/bus.c index 064f94e9c3..df7411fea8 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -19,8 +19,6 @@ static void usb_qdev_unrealize(DeviceState *qdev); static Property usb_props[] = { DEFINE_PROP_STRING("port", USBDevice, port_path), DEFINE_PROP_STRING("serial", USBDevice, serial), - DEFINE_PROP_BIT("full-path", USBDevice, flags, - USB_DEV_FLAG_FULL_PATH, true), DEFINE_PROP_BIT("msos-desc", USBDevice, flags, USB_DEV_FLAG_MSOS_DESC_ENABLE, true), DEFINE_PROP_STRING("pcap", USBDevice, pcap_filename), @@ -596,11 +594,8 @@ static char *usb_get_dev_path(DeviceState *qdev) { USBDevice *dev = USB_DEVICE(qdev); DeviceState *hcd = qdev->parent_bus->parent; - char *id = NULL; + char *id = qdev_get_dev_path(hcd); - if (dev->flags & (1 << USB_DEV_FLAG_FULL_PATH)) { - id = qdev_get_dev_path(hcd); - } if (id) { char *ret = g_strdup_printf("%s/%s", id, dev->port->path); g_free(id); diff --git a/include/hw/usb.h b/include/hw/usb.h index abfbfc5284..9f42394efa 100644 --- a/include/hw/usb.h +++ b/include/hw/usb.h @@ -216,7 +216,6 @@ struct USBEndpoint { }; enum USBDeviceFlags { - USB_DEV_FLAG_FULL_PATH, USB_DEV_FLAG_IS_HOST, USB_DEV_FLAG_MSOS_DESC_ENABLE, USB_DEV_FLAG_MSOS_DESC_IN_USE, From 405cf80ceb6ba62c7bafba55a85af51262d25b36 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 10 Mar 2021 18:33:20 +0100 Subject: [PATCH 02/13] usb: remove support for -usbdevice parameters No device needs them anymore and in fact they're undocumented. Remove the code. The only change in behavior is that "-usbdevice braille:hello" now reports an error, which is a bugfix. Signed-off-by: Paolo Bonzini Cc: Gerd Hoffmann Signed-off-by: Thomas Huth Message-Id: <20210310173323.1422754-2-thuth@redhat.com> Signed-off-by: Gerd Hoffmann --- hw/usb/bus.c | 32 +++++++------------------------- hw/usb/dev-serial.c | 2 +- include/hw/usb.h | 2 +- 3 files changed, 9 insertions(+), 27 deletions(-) diff --git a/hw/usb/bus.c b/hw/usb/bus.c index df7411fea8..07083349f5 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -310,13 +310,13 @@ typedef struct LegacyUSBFactory { const char *name; const char *usbdevice_name; - USBDevice *(*usbdevice_init)(const char *params); + USBDevice *(*usbdevice_init)(void); } LegacyUSBFactory; static GSList *legacy_usb_factory; void usb_legacy_register(const char *typename, const char *usbdevice_name, - USBDevice *(*usbdevice_init)(const char *params)) + USBDevice *(*usbdevice_init)(void)) { if (usbdevice_name) { LegacyUSBFactory *f = g_malloc0(sizeof(*f)); @@ -658,27 +658,17 @@ void hmp_info_usb(Monitor *mon, const QDict *qdict) } /* handle legacy -usbdevice cmd line option */ -USBDevice *usbdevice_create(const char *cmdline) +USBDevice *usbdevice_create(const char *driver) { USBBus *bus = usb_bus_find(-1 /* any */); LegacyUSBFactory *f = NULL; Error *err = NULL; GSList *i; - char driver[32]; - const char *params; - int len; USBDevice *dev; - params = strchr(cmdline,':'); - if (params) { - params++; - len = params - cmdline; - if (len > sizeof(driver)) - len = sizeof(driver); - pstrcpy(driver, len, cmdline); - } else { - params = ""; - pstrcpy(driver, sizeof(driver), cmdline); + if (strchr(driver, ':')) { + error_report("usbdevice parameters are not supported anymore"); + return NULL; } for (i = legacy_usb_factory; i; i = i->next) { @@ -702,15 +692,7 @@ USBDevice *usbdevice_create(const char *cmdline) return NULL; } - if (f->usbdevice_init) { - dev = f->usbdevice_init(params); - } else { - if (*params) { - error_report("usbdevice %s accepts no params", driver); - return NULL; - } - dev = usb_new(f->name); - } + dev = f->usbdevice_init ? f->usbdevice_init() : usb_new(f->name); if (!dev) { error_report("Failed to create USB device '%s'", f->name); return NULL; diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c index b58c4eb908..63047d79cf 100644 --- a/hw/usb/dev-serial.c +++ b/hw/usb/dev-serial.c @@ -614,7 +614,7 @@ static void usb_serial_realize(USBDevice *dev, Error **errp) s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1); } -static USBDevice *usb_braille_init(const char *unused) +static USBDevice *usb_braille_init(void) { USBDevice *dev; Chardev *cdrv; diff --git a/include/hw/usb.h b/include/hw/usb.h index 9f42394efa..436e07b304 100644 --- a/include/hw/usb.h +++ b/include/hw/usb.h @@ -499,7 +499,7 @@ void usb_bus_new(USBBus *bus, size_t bus_size, void usb_bus_release(USBBus *bus); USBBus *usb_bus_find(int busnr); void usb_legacy_register(const char *typename, const char *usbdevice_name, - USBDevice *(*usbdevice_init)(const char *params)); + USBDevice *(*usbdevice_init)(void)); USBDevice *usb_new(const char *name); bool usb_realize_and_unref(USBDevice *dev, USBBus *bus, Error **errp); USBDevice *usb_create_simple(USBBus *bus, const char *name); From 6523c96c9ce0d4d8c34d447fbdf489ca0affb515 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 10 Mar 2021 18:33:21 +0100 Subject: [PATCH 03/13] usb: remove '-usbdevice u2f-key' It never worked. Signed-off-by: Paolo Bonzini Cc: Gerd Hoffmann Signed-off-by: Thomas Huth Message-Id: <20210310173323.1422754-3-thuth@redhat.com> Signed-off-by: Gerd Hoffmann --- hw/usb/u2f.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/usb/u2f.c b/hw/usb/u2f.c index bc09191f06..56001249a4 100644 --- a/hw/usb/u2f.c +++ b/hw/usb/u2f.c @@ -346,7 +346,6 @@ static const TypeInfo u2f_key_info = { static void u2f_key_register_types(void) { type_register_static(&u2f_key_info); - usb_legacy_register(TYPE_U2F_KEY, "u2f-key", NULL); } type_init(u2f_key_register_types) From 6db34277e3b3071707a3a20afb82176e4f229b8f Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 10 Mar 2021 18:33:22 +0100 Subject: [PATCH 04/13] usb: Un-deprecate -usbdevice (except for -usbdevice audio which gets removed) When trying to remove the -usbdevice option, there were complaints that "-usbdevice braille" is still a very useful shortcut for some people. Thus we never remove this option. Since it's not such a big burden to keep it around, and it's also convenient in the sense that you don't have to worry to enable a host controller explicitly with this option, we should remove it from he deprecation list again. However, there is one exception: "-usbdevice audio" should go away, since audio devices without "audiodev=..." parameter are also on the deprecation list and you cannot use "-usbdevice audio" with "audiodev". Signed-off-by: Thomas Huth Message-Id: <20210310173323.1422754-4-thuth@redhat.com> Signed-off-by: Gerd Hoffmann --- docs/system/deprecated.rst | 9 --------- docs/system/removed-features.rst | 8 ++++++++ hw/usb/dev-audio.c | 1 - softmmu/vl.c | 2 -- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst index 5e3a31c123..62a64a8c41 100644 --- a/docs/system/deprecated.rst +++ b/docs/system/deprecated.rst @@ -21,15 +21,6 @@ deprecated. System emulator command line arguments -------------------------------------- -``-usbdevice`` (since 2.10.0) -''''''''''''''''''''''''''''' - -The ``-usbdevice DEV`` argument is now a synonym for setting -the ``-device usb-DEV`` argument instead. The deprecated syntax -would automatically enable USB support on the machine type. -If using the new syntax, USB support must be explicitly -enabled via the ``-machine usb=on`` argument. - ``-drive file=json:{...{'driver':'file'}}`` (since 3.0) ''''''''''''''''''''''''''''''''''''''''''''''''''''''' diff --git a/docs/system/removed-features.rst b/docs/system/removed-features.rst index 83148dcfda..82e7fcc517 100644 --- a/docs/system/removed-features.rst +++ b/docs/system/removed-features.rst @@ -38,6 +38,14 @@ or ``-display default,show-cursor=on`` instead. QEMU 5.0 introduced an alternative syntax to specify the size of the translation block cache, ``-accel tcg,tb-size=``. +``-usbdevice audio`` (removed in 6.0) +''''''''''''''''''''''''''''''''''''' + +This option lacked the possibility to specify an audio backend device. +Use ``-device usb-audio`` now instead (and specify a corresponding USB +host controller or ``-usb`` if necessary). + + QEMU Machine Protocol (QMP) commands ------------------------------------ diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c index e1486f81e0..f5cb246792 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -1024,7 +1024,6 @@ static const TypeInfo usb_audio_info = { static void usb_audio_register_types(void) { type_register_static(&usb_audio_info); - usb_legacy_register(TYPE_USB_AUDIO, "audio", NULL); } type_init(usb_audio_register_types) diff --git a/softmmu/vl.c b/softmmu/vl.c index b7673b9613..a750dae6b1 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -3180,8 +3180,6 @@ void qemu_init(int argc, char **argv, char **envp) qemu_opts_parse_noisily(olist, "usb=on", false); break; case QEMU_OPTION_usbdevice: - error_report("'-usbdevice' is deprecated, please use " - "'-device usb-...' instead"); olist = qemu_find_opts("machine"); qemu_opts_parse_noisily(olist, "usb=on", false); add_device_config(DEV_USB, optarg); From c2a34ab2a0196e9a97e7206b94a6377cc70fb623 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 10 Mar 2021 18:33:23 +0100 Subject: [PATCH 05/13] usb: Document the missing -usbdevice options There are some more -usbdevice options that have never been mentioned in the documentation. Now that we removed -usbdevice from the list of deprecated features again, we should document them properly. While we're at it, also sort them alphabetically. Signed-off-by: Thomas Huth Message-Id: <20210310173323.1422754-5-thuth@redhat.com> Signed-off-by: Gerd Hoffmann --- qemu-options.hx | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 622d3bfa5a..fe83ea09b2 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1705,7 +1705,7 @@ ERST DEFHEADING() -DEFHEADING(USB options:) +DEFHEADING(USB convenience options:) DEF("usb", 0, QEMU_OPTION_usb, "-usb enable on-board USB host controller (if not enabled by default)\n", @@ -1723,9 +1723,31 @@ DEF("usbdevice", HAS_ARG, QEMU_OPTION_usbdevice, QEMU_ARCH_ALL) SRST ``-usbdevice devname`` - Add the USB device devname. Note that this option is deprecated, - please use ``-device usb-...`` instead. See the chapter about + Add the USB device devname, and enable an on-board USB controller + if possible and necessary (just like it can be done via + ``-machine usb=on``). Note that this option is mainly intended for + the user's convenience only. More fine-grained control can be + achieved by selecting a USB host controller (if necessary) and the + desired USB device via the ``-device`` option instead. For example, + instead of using ``-usbdevice mouse`` it is possible to use + ``-device qemu-xhci -device usb-mouse`` to connect the USB mouse + to a USB 3.0 controller instead (at least on machines that support + PCI and do not have an USB controller enabled by default yet). + For more details, see the chapter about :ref:`Connecting USB devices` in the System Emulation Users Guide. + Possible devices for devname are: + + ``braille`` + Braille device. This will use BrlAPI to display the braille + output on a real or fake device (i.e. it also creates a + corresponding ``braille`` chardev automatically beside the + ``usb-braille`` USB device). + + ``ccid`` + Smartcard reader device + + ``keyboard`` + Standard USB keyboard. Will override the PS/2 keyboard (if present). ``mouse`` Virtual Mouse. This will override the PS/2 mouse emulation when @@ -1737,9 +1759,10 @@ SRST position without having to grab the mouse. Also overrides the PS/2 mouse emulation when activated. - ``braille`` - Braille device. This will use BrlAPI to display the braille - output on a real or fake device. + ``wacom-tablet`` + Wacom PenPartner USB tablet. + + ERST DEFHEADING() From f4c46916dc670f894997409ea261e77867a136fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 9 Mar 2021 20:08:00 +0100 Subject: [PATCH 06/13] hw/southbridge: Add missing Kconfig dependency VT82C686 on USB_UHCI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The VT82C686 south bridge provides a USB UHCI bus via a PCI function. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: BALATON Zoltan Message-Id: <20210309190802.830969-2-f4bug@amsat.org> Signed-off-by: Gerd Hoffmann --- hw/isa/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig index c7f07854f7..2691eae2f0 100644 --- a/hw/isa/Kconfig +++ b/hw/isa/Kconfig @@ -47,6 +47,7 @@ config VT82C686 select ACPI_SMBUS select SERIAL_ISA select FDC + select USB_UHCI config SMC37C669 bool From 9a4e12a64dffa241fc5c06e61c7f90799a67891e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 9 Mar 2021 20:08:01 +0100 Subject: [PATCH 07/13] hw/usb/hcd-uhci: Expose generic prototypes to local header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract generic UHCI prototypes into a new "hcd-uhci.h" local header so we can reuse them in other units. Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210309190802.830969-3-f4bug@amsat.org> Signed-off-by: Gerd Hoffmann --- hw/usb/hcd-uhci.c | 60 ++---------------------------- hw/usb/hcd-uhci.h | 93 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 57 deletions(-) create mode 100644 hw/usb/hcd-uhci.h diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index 5969eb86b3..d6338c33d8 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -40,6 +40,7 @@ #include "qemu/main-loop.h" #include "qemu/module.h" #include "qom/object.h" +#include "hcd-uhci.h" #define FRAME_TIMER_FREQ 1000 @@ -50,8 +51,6 @@ #define MAX_FRAMES_PER_TICK (QH_VALID / 2) -#define NB_PORTS 2 - enum { TD_RESULT_STOP_FRAME = 10, TD_RESULT_COMPLETE, @@ -62,20 +61,8 @@ enum { typedef struct UHCIState UHCIState; typedef struct UHCIAsync UHCIAsync; -typedef struct UHCIQueue UHCIQueue; -typedef struct UHCIInfo UHCIInfo; typedef struct UHCIPCIDeviceClass UHCIPCIDeviceClass; -struct UHCIInfo { - const char *name; - uint16_t vendor_id; - uint16_t device_id; - uint8_t revision; - uint8_t irq_pin; - void (*realize)(PCIDevice *dev, Error **errp); - bool unplug; -}; - struct UHCIPCIDeviceClass { PCIDeviceClass parent_class; UHCIInfo info; @@ -107,43 +94,6 @@ struct UHCIQueue { int8_t valid; }; -typedef struct UHCIPort { - USBPort port; - uint16_t ctrl; -} UHCIPort; - -struct UHCIState { - PCIDevice dev; - MemoryRegion io_bar; - USBBus bus; /* Note unused when we're a companion controller */ - uint16_t cmd; /* cmd register */ - uint16_t status; - uint16_t intr; /* interrupt enable register */ - uint16_t frnum; /* frame number */ - uint32_t fl_base_addr; /* frame list base address */ - uint8_t sof_timing; - uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */ - int64_t expire_time; - QEMUTimer *frame_timer; - QEMUBH *bh; - uint32_t frame_bytes; - uint32_t frame_bandwidth; - bool completions_only; - UHCIPort ports[NB_PORTS]; - - /* Interrupts that should be raised at the end of the current frame. */ - uint32_t pending_int_mask; - - /* Active packets */ - QTAILQ_HEAD(, UHCIQueue) queues; - uint8_t num_ports_vmstate; - - /* Properties */ - char *masterbus; - uint32_t firstport; - uint32_t maxframes; -}; - typedef struct UHCI_TD { uint32_t link; uint32_t ctrl; /* see TD_CTRL_xxx */ @@ -160,10 +110,6 @@ static void uhci_async_cancel(UHCIAsync *async); static void uhci_queue_fill(UHCIQueue *q, UHCI_TD *td); static void uhci_resume(void *opaque); -#define TYPE_UHCI "pci-uhci-usb" -DECLARE_INSTANCE_CHECKER(UHCIState, UHCI, - TYPE_UHCI) - static inline int32_t uhci_queue_token(UHCI_TD *td) { if ((td->token & (0xf << 15)) == 0) { @@ -1213,7 +1159,7 @@ static USBPortOps uhci_port_ops = { static USBBusOps uhci_bus_ops = { }; -static void usb_uhci_common_realize(PCIDevice *dev, Error **errp) +void usb_uhci_common_realize(PCIDevice *dev, Error **errp) { Error *err = NULL; PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); @@ -1335,7 +1281,7 @@ static const TypeInfo uhci_pci_type_info = { }, }; -static void uhci_data_class_init(ObjectClass *klass, void *data) +void uhci_data_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/usb/hcd-uhci.h b/hw/usb/hcd-uhci.h new file mode 100644 index 0000000000..e61d8fcb19 --- /dev/null +++ b/hw/usb/hcd-uhci.h @@ -0,0 +1,93 @@ +/* + * USB UHCI controller emulation + * + * Copyright (c) 2005 Fabrice Bellard + * + * Copyright (c) 2008 Max Krasnyansky + * Magor rewrite of the UHCI data structures parser and frame processor + * Support for fully async operation and multiple outstanding transactions + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef HW_USB_HCD_UHCI_H +#define HW_USB_HCD_UHCI_H + +#include "exec/memory.h" +#include "qemu/timer.h" +#include "hw/pci/pci.h" +#include "hw/usb.h" + +typedef struct UHCIQueue UHCIQueue; + +#define NB_PORTS 2 + +typedef struct UHCIPort { + USBPort port; + uint16_t ctrl; +} UHCIPort; + +typedef struct UHCIState { + PCIDevice dev; + MemoryRegion io_bar; + USBBus bus; /* Note unused when we're a companion controller */ + uint16_t cmd; /* cmd register */ + uint16_t status; + uint16_t intr; /* interrupt enable register */ + uint16_t frnum; /* frame number */ + uint32_t fl_base_addr; /* frame list base address */ + uint8_t sof_timing; + uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */ + int64_t expire_time; + QEMUTimer *frame_timer; + QEMUBH *bh; + uint32_t frame_bytes; + uint32_t frame_bandwidth; + bool completions_only; + UHCIPort ports[NB_PORTS]; + + /* Interrupts that should be raised at the end of the current frame. */ + uint32_t pending_int_mask; + + /* Active packets */ + QTAILQ_HEAD(, UHCIQueue) queues; + uint8_t num_ports_vmstate; + + /* Properties */ + char *masterbus; + uint32_t firstport; + uint32_t maxframes; +} UHCIState; + +#define TYPE_UHCI "pci-uhci-usb" +DECLARE_INSTANCE_CHECKER(UHCIState, UHCI, TYPE_UHCI) + +typedef struct UHCIInfo { + const char *name; + uint16_t vendor_id; + uint16_t device_id; + uint8_t revision; + uint8_t irq_pin; + void (*realize)(PCIDevice *dev, Error **errp); + bool unplug; +} UHCIInfo; + +void uhci_data_class_init(ObjectClass *klass, void *data); +void usb_uhci_common_realize(PCIDevice *dev, Error **errp); + +#endif From 6f2bcd5fc84700b5eabfd58c08cbc61f1d7b5b6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 9 Mar 2021 20:08:02 +0100 Subject: [PATCH 08/13] hw/usb: Extract VT82C686 UHCI PCI function into a new unit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract the VT82C686 PCI UHCI function into a new unit so it is only build when the VT82C686 south bridge is selected. Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210309190802.830969-4-f4bug@amsat.org> Signed-off-by: Gerd Hoffmann --- MAINTAINERS | 1 + hw/usb/hcd-uhci.c | 23 -------------------- hw/usb/meson.build | 1 + hw/usb/vt82c686-uhci-pci.c | 43 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 23 deletions(-) create mode 100644 hw/usb/vt82c686-uhci-pci.c diff --git a/MAINTAINERS b/MAINTAINERS index 5ca3c9f851..b6ab3d25a7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1180,6 +1180,7 @@ S: Odd Fixes F: hw/mips/fuloong2e.c F: hw/isa/vt82c686.c F: hw/pci-host/bonito.c +F: hw/usb/vt82c686-uhci-pci.c F: include/hw/isa/vt82c686.h Loongson-3 virtual platforms diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index d6338c33d8..0cb02a6432 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -1207,21 +1207,6 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp) pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar); } -static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp) -{ - UHCIState *s = UHCI(dev); - uint8_t *pci_conf = s->dev.config; - - /* USB misc control 1/2 */ - pci_set_long(pci_conf + 0x40,0x00001000); - /* PM capability */ - pci_set_long(pci_conf + 0x80,0x00020001); - /* USB legacy support */ - pci_set_long(pci_conf + 0xc0,0x00002000); - - usb_uhci_common_realize(dev, errp); -} - static void usb_uhci_exit(PCIDevice *dev) { UHCIState *s = UHCI(dev); @@ -1318,14 +1303,6 @@ static UHCIInfo uhci_info[] = { .revision = 0x01, .irq_pin = 3, .unplug = true, - },{ - .name = "vt82c686b-usb-uhci", - .vendor_id = PCI_VENDOR_ID_VIA, - .device_id = PCI_DEVICE_ID_VIA_UHCI, - .revision = 0x01, - .irq_pin = 3, - .realize = usb_uhci_vt82c686b_realize, - .unplug = true, },{ .name = "ich9-usb-uhci1", /* 00:1d.0 */ .vendor_id = PCI_VENDOR_ID_INTEL, diff --git a/hw/usb/meson.build b/hw/usb/meson.build index 653192cff6..6e3159798e 100644 --- a/hw/usb/meson.build +++ b/hw/usb/meson.build @@ -32,6 +32,7 @@ softmmu_ss.add(when: 'CONFIG_USB_DWC3', if_true: files('hcd-dwc3.c')) softmmu_ss.add(when: 'CONFIG_TUSB6010', if_true: files('tusb6010.c')) softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('chipidea.c')) softmmu_ss.add(when: 'CONFIG_IMX_USBPHY', if_true: files('imx-usb-phy.c')) +softmmu_ss.add(when: 'CONFIG_VT82C686', if_true: files('vt82c686-uhci-pci.c')) specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-usb2-ctrl-regs.c')) specific_ss.add(when: 'CONFIG_XLNX_USB_SUBSYS', if_true: files('xlnx-usb-subsystem.c')) diff --git a/hw/usb/vt82c686-uhci-pci.c b/hw/usb/vt82c686-uhci-pci.c new file mode 100644 index 0000000000..b109c21603 --- /dev/null +++ b/hw/usb/vt82c686-uhci-pci.c @@ -0,0 +1,43 @@ +#include "qemu/osdep.h" +#include "hcd-uhci.h" + +static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp) +{ + UHCIState *s = UHCI(dev); + uint8_t *pci_conf = s->dev.config; + + /* USB misc control 1/2 */ + pci_set_long(pci_conf + 0x40, 0x00001000); + /* PM capability */ + pci_set_long(pci_conf + 0x80, 0x00020001); + /* USB legacy support */ + pci_set_long(pci_conf + 0xc0, 0x00002000); + + usb_uhci_common_realize(dev, errp); +} + +static UHCIInfo uhci_info[] = { + { + .name = "vt82c686b-usb-uhci", + .vendor_id = PCI_VENDOR_ID_VIA, + .device_id = PCI_DEVICE_ID_VIA_UHCI, + .revision = 0x01, + .irq_pin = 3, + .realize = usb_uhci_vt82c686b_realize, + .unplug = true, + } +}; + +static const TypeInfo vt82c686b_usb_uhci_type_info = { + .parent = TYPE_UHCI, + .name = "vt82c686b-usb-uhci", + .class_init = uhci_data_class_init, + .class_data = uhci_info, +}; + +static void vt82c686b_usb_uhci_register_types(void) +{ + type_register_static(&vt82c686b_usb_uhci_type_info); +} + +type_init(vt82c686b_usb_uhci_register_types) From bbd8323d3196c9979385cba1b8b38859836e63c3 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 12 Mar 2021 10:04:22 +0100 Subject: [PATCH 09/13] usb/storage: move declarations to usb/msd.h header In preparation for splitting the usb-storage.c file move declarations to the new usb/msd.h header file. Signed-off-by: Gerd Hoffmann Message-Id: <20210312090425.772900-2-kraxel@redhat.com> --- hw/usb/dev-storage.c | 48 +++++---------------------------------- include/hw/usb/msd.h | 54 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 42 deletions(-) create mode 100644 include/hw/usb/msd.h diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index a5f76fc001..027e29dda3 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -14,6 +14,7 @@ #include "qemu/option.h" #include "qemu/config-file.h" #include "hw/usb.h" +#include "hw/usb/msd.h" #include "desc.h" #include "hw/qdev-properties.h" #include "hw/scsi/scsi.h" @@ -29,43 +30,6 @@ #define MassStorageReset 0xff #define GetMaxLun 0xfe -enum USBMSDMode { - USB_MSDM_CBW, /* Command Block. */ - USB_MSDM_DATAOUT, /* Transfer data to device. */ - USB_MSDM_DATAIN, /* Transfer data from device. */ - USB_MSDM_CSW /* Command Status. */ -}; - -struct usb_msd_csw { - uint32_t sig; - uint32_t tag; - uint32_t residue; - uint8_t status; -}; - -struct MSDState { - USBDevice dev; - enum USBMSDMode mode; - uint32_t scsi_off; - uint32_t scsi_len; - uint32_t data_len; - struct usb_msd_csw csw; - SCSIRequest *req; - SCSIBus bus; - /* For async completion. */ - USBPacket *packet; - /* usb-storage only */ - BlockConf conf; - bool removable; - bool commandlog; - SCSIDevice *scsi_dev; -}; -typedef struct MSDState MSDState; - -#define TYPE_USB_STORAGE "usb-storage-dev" -DECLARE_INSTANCE_CHECKER(MSDState, USB_STORAGE_DEV, - TYPE_USB_STORAGE) - struct usb_msd_cbw { uint32_t sig; uint32_t tag; @@ -259,7 +223,7 @@ static void usb_msd_packet_complete(MSDState *s) usb_packet_complete(&s->dev, p); } -static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len) +void usb_msd_transfer_data(SCSIRequest *req, uint32_t len) { MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); USBPacket *p = s->packet; @@ -277,7 +241,7 @@ static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len) } } -static void usb_msd_command_complete(SCSIRequest *req, size_t resid) +void usb_msd_command_complete(SCSIRequest *req, size_t resid) { MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); USBPacket *p = s->packet; @@ -320,7 +284,7 @@ static void usb_msd_command_complete(SCSIRequest *req, size_t resid) s->req = NULL; } -static void usb_msd_request_cancelled(SCSIRequest *req) +void usb_msd_request_cancelled(SCSIRequest *req) { MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); @@ -337,7 +301,7 @@ static void usb_msd_request_cancelled(SCSIRequest *req) } } -static void usb_msd_handle_reset(USBDevice *dev) +void usb_msd_handle_reset(USBDevice *dev) { MSDState *s = (MSDState *)dev; @@ -565,7 +529,7 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p) } } -static void *usb_msd_load_request(QEMUFile *f, SCSIRequest *req) +void *usb_msd_load_request(QEMUFile *f, SCSIRequest *req) { MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); diff --git a/include/hw/usb/msd.h b/include/hw/usb/msd.h new file mode 100644 index 0000000000..7538c54569 --- /dev/null +++ b/include/hw/usb/msd.h @@ -0,0 +1,54 @@ +/* + * USB Mass Storage Device emulation + * + * Copyright (c) 2006 CodeSourcery. + * Written by Paul Brook + * + * This code is licensed under the LGPL. + */ + +#include "hw/usb.h" +#include "hw/scsi/scsi.h" + +enum USBMSDMode { + USB_MSDM_CBW, /* Command Block. */ + USB_MSDM_DATAOUT, /* Transfer data to device. */ + USB_MSDM_DATAIN, /* Transfer data from device. */ + USB_MSDM_CSW /* Command Status. */ +}; + +struct usb_msd_csw { + uint32_t sig; + uint32_t tag; + uint32_t residue; + uint8_t status; +}; + +struct MSDState { + USBDevice dev; + enum USBMSDMode mode; + uint32_t scsi_off; + uint32_t scsi_len; + uint32_t data_len; + struct usb_msd_csw csw; + SCSIRequest *req; + SCSIBus bus; + /* For async completion. */ + USBPacket *packet; + /* usb-storage only */ + BlockConf conf; + bool removable; + bool commandlog; + SCSIDevice *scsi_dev; +}; + +typedef struct MSDState MSDState; +#define TYPE_USB_STORAGE "usb-storage-dev" +DECLARE_INSTANCE_CHECKER(MSDState, USB_STORAGE_DEV, + TYPE_USB_STORAGE) + +void usb_msd_transfer_data(SCSIRequest *req, uint32_t len); +void usb_msd_command_complete(SCSIRequest *req, size_t resid); +void usb_msd_request_cancelled(SCSIRequest *req); +void *usb_msd_load_request(QEMUFile *f, SCSIRequest *req); +void usb_msd_handle_reset(USBDevice *dev); From 31b7bed8b600e10c853595fb48f510c54ec86523 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 12 Mar 2021 10:04:23 +0100 Subject: [PATCH 10/13] usb/storage: move usb-bot device to separate source file Pure code motion, no functional change. Signed-off-by: Gerd Hoffmann Message-Id: <20210312090425.772900-3-kraxel@redhat.com> --- hw/usb/dev-storage-bot.c | 63 ++++++++++++++++++++++++++++++++++++++++ hw/usb/dev-storage.c | 42 --------------------------- hw/usb/meson.build | 1 + 3 files changed, 64 insertions(+), 42 deletions(-) create mode 100644 hw/usb/dev-storage-bot.c diff --git a/hw/usb/dev-storage-bot.c b/hw/usb/dev-storage-bot.c new file mode 100644 index 0000000000..6aad026d11 --- /dev/null +++ b/hw/usb/dev-storage-bot.c @@ -0,0 +1,63 @@ +/* + * USB Mass Storage Device emulation + * + * Copyright (c) 2006 CodeSourcery. + * Written by Paul Brook + * + * This code is licensed under the LGPL. + */ + +#include "qemu/osdep.h" +#include "qemu/typedefs.h" +#include "qapi/error.h" +#include "hw/usb.h" +#include "hw/usb/desc.h" +#include "hw/usb/msd.h" + +static const struct SCSIBusInfo usb_msd_scsi_info_bot = { + .tcq = false, + .max_target = 0, + .max_lun = 15, + + .transfer_data = usb_msd_transfer_data, + .complete = usb_msd_command_complete, + .cancel = usb_msd_request_cancelled, + .load_request = usb_msd_load_request, +}; + +static void usb_msd_bot_realize(USBDevice *dev, Error **errp) +{ + MSDState *s = USB_STORAGE_DEV(dev); + DeviceState *d = DEVICE(dev); + + usb_desc_create_serial(dev); + usb_desc_init(dev); + if (d->hotplugged) { + s->dev.auto_attach = 0; + } + + scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev), + &usb_msd_scsi_info_bot, NULL); + usb_msd_handle_reset(dev); +} + +static void usb_msd_class_bot_initfn(ObjectClass *klass, void *data) +{ + USBDeviceClass *uc = USB_DEVICE_CLASS(klass); + + uc->realize = usb_msd_bot_realize; + uc->attached_settable = true; +} + +static const TypeInfo bot_info = { + .name = "usb-bot", + .parent = TYPE_USB_STORAGE, + .class_init = usb_msd_class_bot_initfn, +}; + +static void register_types(void) +{ + type_register_static(&bot_info); +} + +type_init(register_types) diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index 027e29dda3..3e613ecc88 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -551,17 +551,6 @@ static const struct SCSIBusInfo usb_msd_scsi_info_storage = { .load_request = usb_msd_load_request, }; -static const struct SCSIBusInfo usb_msd_scsi_info_bot = { - .tcq = false, - .max_target = 0, - .max_lun = 15, - - .transfer_data = usb_msd_transfer_data, - .complete = usb_msd_command_complete, - .cancel = usb_msd_request_cancelled, - .load_request = usb_msd_load_request, -}; - static void usb_msd_storage_realize(USBDevice *dev, Error **errp) { MSDState *s = USB_STORAGE_DEV(dev); @@ -613,22 +602,6 @@ static void usb_msd_storage_realize(USBDevice *dev, Error **errp) s->scsi_dev = scsi_dev; } -static void usb_msd_bot_realize(USBDevice *dev, Error **errp) -{ - MSDState *s = USB_STORAGE_DEV(dev); - DeviceState *d = DEVICE(dev); - - usb_desc_create_serial(dev); - usb_desc_init(dev); - if (d->hotplugged) { - s->dev.auto_attach = 0; - } - - scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev), - &usb_msd_scsi_info_bot, NULL); - usb_msd_handle_reset(dev); -} - static const VMStateDescription vmstate_usb_msd = { .name = "usb-storage", .version_id = 1, @@ -734,14 +707,6 @@ static void usb_msd_instance_init(Object *obj) object_property_set_int(obj, "bootindex", -1, NULL); } -static void usb_msd_class_bot_initfn(ObjectClass *klass, void *data) -{ - USBDeviceClass *uc = USB_DEVICE_CLASS(klass); - - uc->realize = usb_msd_bot_realize; - uc->attached_settable = true; -} - static const TypeInfo msd_info = { .name = "usb-storage", .parent = TYPE_USB_STORAGE, @@ -749,17 +714,10 @@ static const TypeInfo msd_info = { .instance_init = usb_msd_instance_init, }; -static const TypeInfo bot_info = { - .name = "usb-bot", - .parent = TYPE_USB_STORAGE, - .class_init = usb_msd_class_bot_initfn, -}; - static void usb_msd_register_types(void) { type_register_static(&usb_storage_dev_type_info); type_register_static(&msd_info); - type_register_static(&bot_info); } type_init(usb_msd_register_types) diff --git a/hw/usb/meson.build b/hw/usb/meson.build index 6e3159798e..518cd1fbbb 100644 --- a/hw/usb/meson.build +++ b/hw/usb/meson.build @@ -41,6 +41,7 @@ softmmu_ss.add(when: 'CONFIG_USB', if_true: files('dev-hub.c')) softmmu_ss.add(when: 'CONFIG_USB', if_true: files('dev-hid.c')) softmmu_ss.add(when: 'CONFIG_USB_TABLET_WACOM', if_true: files('dev-wacom.c')) softmmu_ss.add(when: 'CONFIG_USB_STORAGE_BOT', if_true: files('dev-storage.c')) +softmmu_ss.add(when: 'CONFIG_USB_STORAGE_BOT', if_true: files('dev-storage-bot.c')) softmmu_ss.add(when: 'CONFIG_USB_STORAGE_UAS', if_true: files('dev-uas.c')) softmmu_ss.add(when: 'CONFIG_USB_AUDIO', if_true: files('dev-audio.c')) softmmu_ss.add(when: 'CONFIG_USB_SERIAL', if_true: files('dev-serial.c')) From 65561351e32d0cf7f0c1769003529cebec52d579 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 12 Mar 2021 10:04:24 +0100 Subject: [PATCH 11/13] usb/storage move usb-storage device to separate source file Pure code motion, no functional change. Signed-off-by: Gerd Hoffmann Message-Id: <20210312090425.772900-4-kraxel@redhat.com> --- hw/usb/dev-storage-classic.c | 156 +++++++++++++++++++++++++++++++++++ hw/usb/dev-storage.c | 135 ------------------------------ hw/usb/meson.build | 1 + 3 files changed, 157 insertions(+), 135 deletions(-) create mode 100644 hw/usb/dev-storage-classic.c diff --git a/hw/usb/dev-storage-classic.c b/hw/usb/dev-storage-classic.c new file mode 100644 index 0000000000..00cb34b22f --- /dev/null +++ b/hw/usb/dev-storage-classic.c @@ -0,0 +1,156 @@ +/* + * USB Mass Storage Device emulation + * + * Copyright (c) 2006 CodeSourcery. + * Written by Paul Brook + * + * This code is licensed under the LGPL. + */ + +#include "qemu/osdep.h" +#include "qemu/typedefs.h" +#include "qapi/error.h" +#include "qapi/visitor.h" +#include "hw/usb.h" +#include "hw/usb/desc.h" +#include "hw/usb/msd.h" +#include "sysemu/sysemu.h" +#include "sysemu/block-backend.h" + +static const struct SCSIBusInfo usb_msd_scsi_info_storage = { + .tcq = false, + .max_target = 0, + .max_lun = 0, + + .transfer_data = usb_msd_transfer_data, + .complete = usb_msd_command_complete, + .cancel = usb_msd_request_cancelled, + .load_request = usb_msd_load_request, +}; + +static void usb_msd_storage_realize(USBDevice *dev, Error **errp) +{ + MSDState *s = USB_STORAGE_DEV(dev); + BlockBackend *blk = s->conf.blk; + SCSIDevice *scsi_dev; + + if (!blk) { + error_setg(errp, "drive property not set"); + return; + } + + if (!blkconf_blocksizes(&s->conf, errp)) { + return; + } + + if (!blkconf_apply_backend_options(&s->conf, !blk_supports_write_perm(blk), + true, errp)) { + return; + } + + /* + * Hack alert: this pretends to be a block device, but it's really + * a SCSI bus that can serve only a single device, which it + * creates automatically. But first it needs to detach from its + * blockdev, or else scsi_bus_legacy_add_drive() dies when it + * attaches again. We also need to take another reference so that + * blk_detach_dev() doesn't free blk while we still need it. + * + * The hack is probably a bad idea. + */ + blk_ref(blk); + blk_detach_dev(blk, DEVICE(s)); + s->conf.blk = NULL; + + usb_desc_create_serial(dev); + usb_desc_init(dev); + scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev), + &usb_msd_scsi_info_storage, NULL); + scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable, + s->conf.bootindex, s->conf.share_rw, + s->conf.rerror, s->conf.werror, + dev->serial, + errp); + blk_unref(blk); + if (!scsi_dev) { + return; + } + usb_msd_handle_reset(dev); + s->scsi_dev = scsi_dev; +} + +static Property msd_properties[] = { + DEFINE_BLOCK_PROPERTIES(MSDState, conf), + DEFINE_BLOCK_ERROR_PROPERTIES(MSDState, conf), + DEFINE_PROP_BOOL("removable", MSDState, removable, false), + DEFINE_PROP_BOOL("commandlog", MSDState, commandlog, false), + DEFINE_PROP_END_OF_LIST(), +}; + +static void usb_msd_class_storage_initfn(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + USBDeviceClass *uc = USB_DEVICE_CLASS(klass); + + uc->realize = usb_msd_storage_realize; + device_class_set_props(dc, msd_properties); +} + +static void usb_msd_get_bootindex(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + USBDevice *dev = USB_DEVICE(obj); + MSDState *s = USB_STORAGE_DEV(dev); + + visit_type_int32(v, name, &s->conf.bootindex, errp); +} + +static void usb_msd_set_bootindex(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + USBDevice *dev = USB_DEVICE(obj); + MSDState *s = USB_STORAGE_DEV(dev); + int32_t boot_index; + Error *local_err = NULL; + + if (!visit_type_int32(v, name, &boot_index, errp)) { + return; + } + /* check whether bootindex is present in fw_boot_order list */ + check_boot_index(boot_index, &local_err); + if (local_err) { + goto out; + } + /* change bootindex to a new one */ + s->conf.bootindex = boot_index; + + if (s->scsi_dev) { + object_property_set_int(OBJECT(s->scsi_dev), "bootindex", boot_index, + &error_abort); + } + +out: + error_propagate(errp, local_err); +} + +static void usb_msd_instance_init(Object *obj) +{ + object_property_add(obj, "bootindex", "int32", + usb_msd_get_bootindex, + usb_msd_set_bootindex, NULL, NULL); + object_property_set_int(obj, "bootindex", -1, NULL); +} + +static const TypeInfo msd_info = { + .name = "usb-storage", + .parent = TYPE_USB_STORAGE, + .class_init = usb_msd_class_storage_initfn, + .instance_init = usb_msd_instance_init, +}; + +static void register_types(void) +{ + type_register_static(&msd_info); +} + +type_init(register_types) diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index 3e613ecc88..7b587ad051 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -19,9 +19,6 @@ #include "hw/qdev-properties.h" #include "hw/scsi/scsi.h" #include "migration/vmstate.h" -#include "sysemu/sysemu.h" -#include "sysemu/block-backend.h" -#include "qapi/visitor.h" #include "qemu/cutils.h" #include "qom/object.h" #include "trace.h" @@ -540,68 +537,6 @@ void *usb_msd_load_request(QEMUFile *f, SCSIRequest *req) return NULL; } -static const struct SCSIBusInfo usb_msd_scsi_info_storage = { - .tcq = false, - .max_target = 0, - .max_lun = 0, - - .transfer_data = usb_msd_transfer_data, - .complete = usb_msd_command_complete, - .cancel = usb_msd_request_cancelled, - .load_request = usb_msd_load_request, -}; - -static void usb_msd_storage_realize(USBDevice *dev, Error **errp) -{ - MSDState *s = USB_STORAGE_DEV(dev); - BlockBackend *blk = s->conf.blk; - SCSIDevice *scsi_dev; - - if (!blk) { - error_setg(errp, "drive property not set"); - return; - } - - if (!blkconf_blocksizes(&s->conf, errp)) { - return; - } - - if (!blkconf_apply_backend_options(&s->conf, !blk_supports_write_perm(blk), - true, errp)) { - return; - } - - /* - * Hack alert: this pretends to be a block device, but it's really - * a SCSI bus that can serve only a single device, which it - * creates automatically. But first it needs to detach from its - * blockdev, or else scsi_bus_legacy_add_drive() dies when it - * attaches again. We also need to take another reference so that - * blk_detach_dev() doesn't free blk while we still need it. - * - * The hack is probably a bad idea. - */ - blk_ref(blk); - blk_detach_dev(blk, DEVICE(s)); - s->conf.blk = NULL; - - usb_desc_create_serial(dev); - usb_desc_init(dev); - scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev), - &usb_msd_scsi_info_storage, NULL); - scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable, - s->conf.bootindex, s->conf.share_rw, - s->conf.rerror, s->conf.werror, - dev->serial, - errp); - blk_unref(blk); - if (!scsi_dev) { - return; - } - usb_msd_handle_reset(dev); - s->scsi_dev = scsi_dev; -} - static const VMStateDescription vmstate_usb_msd = { .name = "usb-storage", .version_id = 1, @@ -620,14 +555,6 @@ static const VMStateDescription vmstate_usb_msd = { } }; -static Property msd_properties[] = { - DEFINE_BLOCK_PROPERTIES(MSDState, conf), - DEFINE_BLOCK_ERROR_PROPERTIES(MSDState, conf), - DEFINE_PROP_BOOL("removable", MSDState, removable, false), - DEFINE_PROP_BOOL("commandlog", MSDState, commandlog, false), - DEFINE_PROP_END_OF_LIST(), -}; - static void usb_msd_class_initfn_common(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -645,52 +572,6 @@ static void usb_msd_class_initfn_common(ObjectClass *klass, void *data) dc->vmsd = &vmstate_usb_msd; } -static void usb_msd_class_storage_initfn(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - USBDeviceClass *uc = USB_DEVICE_CLASS(klass); - - uc->realize = usb_msd_storage_realize; - device_class_set_props(dc, msd_properties); -} - -static void usb_msd_get_bootindex(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - USBDevice *dev = USB_DEVICE(obj); - MSDState *s = USB_STORAGE_DEV(dev); - - visit_type_int32(v, name, &s->conf.bootindex, errp); -} - -static void usb_msd_set_bootindex(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - USBDevice *dev = USB_DEVICE(obj); - MSDState *s = USB_STORAGE_DEV(dev); - int32_t boot_index; - Error *local_err = NULL; - - if (!visit_type_int32(v, name, &boot_index, errp)) { - return; - } - /* check whether bootindex is present in fw_boot_order list */ - check_boot_index(boot_index, &local_err); - if (local_err) { - goto out; - } - /* change bootindex to a new one */ - s->conf.bootindex = boot_index; - - if (s->scsi_dev) { - object_property_set_int(OBJECT(s->scsi_dev), "bootindex", boot_index, - &error_abort); - } - -out: - error_propagate(errp, local_err); -} - static const TypeInfo usb_storage_dev_type_info = { .name = TYPE_USB_STORAGE, .parent = TYPE_USB_DEVICE, @@ -699,25 +580,9 @@ static const TypeInfo usb_storage_dev_type_info = { .class_init = usb_msd_class_initfn_common, }; -static void usb_msd_instance_init(Object *obj) -{ - object_property_add(obj, "bootindex", "int32", - usb_msd_get_bootindex, - usb_msd_set_bootindex, NULL, NULL); - object_property_set_int(obj, "bootindex", -1, NULL); -} - -static const TypeInfo msd_info = { - .name = "usb-storage", - .parent = TYPE_USB_STORAGE, - .class_init = usb_msd_class_storage_initfn, - .instance_init = usb_msd_instance_init, -}; - static void usb_msd_register_types(void) { type_register_static(&usb_storage_dev_type_info); - type_register_static(&msd_info); } type_init(usb_msd_register_types) diff --git a/hw/usb/meson.build b/hw/usb/meson.build index 518cd1fbbb..9e4da68e3b 100644 --- a/hw/usb/meson.build +++ b/hw/usb/meson.build @@ -42,6 +42,7 @@ softmmu_ss.add(when: 'CONFIG_USB', if_true: files('dev-hid.c')) softmmu_ss.add(when: 'CONFIG_USB_TABLET_WACOM', if_true: files('dev-wacom.c')) softmmu_ss.add(when: 'CONFIG_USB_STORAGE_BOT', if_true: files('dev-storage.c')) softmmu_ss.add(when: 'CONFIG_USB_STORAGE_BOT', if_true: files('dev-storage-bot.c')) +softmmu_ss.add(when: 'CONFIG_USB_STORAGE_BOT', if_true: files('dev-storage-classic.c')) softmmu_ss.add(when: 'CONFIG_USB_STORAGE_UAS', if_true: files('dev-uas.c')) softmmu_ss.add(when: 'CONFIG_USB_AUDIO', if_true: files('dev-audio.c')) softmmu_ss.add(when: 'CONFIG_USB_SERIAL', if_true: files('dev-serial.c')) From f98c9bd45fb4f479ca38f8a2b2abcf27e9c2b9aa Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 12 Mar 2021 10:04:25 +0100 Subject: [PATCH 12/13] usb/storage: add kconfig symbols Add new kconfig symbols so usb-storage and usb-bot can be enabled or disabled individually at build time. Signed-off-by: Gerd Hoffmann Message-Id: <20210312090425.772900-5-kraxel@redhat.com> --- hw/usb/Kconfig | 13 ++++++++++++- hw/usb/meson.build | 4 ++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig index 40093d7ea6..53f8283ffd 100644 --- a/hw/usb/Kconfig +++ b/hw/usb/Kconfig @@ -66,11 +66,22 @@ config USB_TABLET_WACOM default y depends on USB +config USB_STORAGE_CORE + bool + depends on USB + select SCSI + +config USB_STORAGE_CLASSIC + bool + default y + depends on USB + select USB_STORAGE_CORE + config USB_STORAGE_BOT bool default y depends on USB - select SCSI + select USB_STORAGE_CORE config USB_STORAGE_UAS bool diff --git a/hw/usb/meson.build b/hw/usb/meson.build index 9e4da68e3b..fb7a74e73a 100644 --- a/hw/usb/meson.build +++ b/hw/usb/meson.build @@ -40,9 +40,9 @@ specific_ss.add(when: 'CONFIG_XLNX_USB_SUBSYS', if_true: files('xlnx-usb-subsyst softmmu_ss.add(when: 'CONFIG_USB', if_true: files('dev-hub.c')) softmmu_ss.add(when: 'CONFIG_USB', if_true: files('dev-hid.c')) softmmu_ss.add(when: 'CONFIG_USB_TABLET_WACOM', if_true: files('dev-wacom.c')) -softmmu_ss.add(when: 'CONFIG_USB_STORAGE_BOT', if_true: files('dev-storage.c')) +softmmu_ss.add(when: 'CONFIG_USB_STORAGE_CORE', if_true: files('dev-storage.c')) softmmu_ss.add(when: 'CONFIG_USB_STORAGE_BOT', if_true: files('dev-storage-bot.c')) -softmmu_ss.add(when: 'CONFIG_USB_STORAGE_BOT', if_true: files('dev-storage-classic.c')) +softmmu_ss.add(when: 'CONFIG_USB_STORAGE_CLASSIC', if_true: files('dev-storage-classic.c')) softmmu_ss.add(when: 'CONFIG_USB_STORAGE_UAS', if_true: files('dev-uas.c')) softmmu_ss.add(when: 'CONFIG_USB_AUDIO', if_true: files('dev-audio.c')) softmmu_ss.add(when: 'CONFIG_USB_SERIAL', if_true: files('dev-serial.c')) From 39912c14da07a2dbc73854addcfa0a42596340ac Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 12 Mar 2021 10:49:54 +0100 Subject: [PATCH 13/13] usb/storage: clear csw on reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stale data in csw (specifically residue) can confuse the state machine and allows the guest trigger an assert(). So clear csw on reset to avoid this happening in case the guest resets the device in the middle of a request. Buglink: https://bugs.launchpad.net/qemu/+bug/1523811 Signed-off-by: Gerd Hoffmann Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20210312094954.796799-1-kraxel@redhat.com> --- hw/usb/dev-storage.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index 7b587ad051..dca62d544f 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -313,6 +313,7 @@ void usb_msd_handle_reset(USBDevice *dev) usb_msd_packet_complete(s); } + memset(&s->csw, 0, sizeof(s->csw)); s->mode = USB_MSDM_CBW; }