usb: bugfix collection.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJVC9F3AAoJEEy22O7T6HE4kJYQAIb5UZgIso2tKJe2QtUdWk+a aliDfUeYjbILgyOuB+wYQ+hGuSQgbArP+RT4G1cpv6wJKKOqNmJI83ahD4GMNvZS ZC7Z9lx7RjNW7lCTA0+H8Zd1YtEJKb4aleFYVCfL6u+8Yx/JK+W0nToMpZcw+H3O xlGclKNkyd4M5sE9XJXn/SPDDfqQ15Clor1yWBAqyHuzWFkyo/WhxwKidXZE6RjZ PSS0sDTwTHLz4wvjUrPt8N4JR1l226g0M32HjyNRRcqQEmCHZb/QM/BNBOOBX7aF 3sAAxpmUro+bA3mljVV34RedTWpv5FQ/d8Ye0t2eWjQfzksDjcJhYU0pfNSUYdvG 2SnBL3e05Ykl+nvsvWbgcobMHiTvZqiBMyV4LXJKvRIwMJRfhWgKKLpQLFM2ZYyX bcfC6OBthluY7eqJWIkDUsIevjxSYkSz0cvbFXVZk/+jCb5Q2/SgW+3No0NxuwpF lx1VYqJ4UCg7om91TOqT30CYIHfFpNPhWyk2j9/kSCnod/pTZQ7Q3J3ePf1Kts+Z K1G/9nh86pHhb/jrGVxqotPt1j+xG7Dd7J10BDkAa0ylIkMbsV1JS8D+1v5d5QZA I6odLJJunhtxbMzFP2yE/gZLaMQoUA5PgNRBqwGfam4o5MxdmXWojnahWXwbqecl nbK4Tmae1cFoWytDZikP =T+GC -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-20150320-1' into staging usb: bugfix collection. # gpg: Signature made Fri Mar 20 07:51:19 2015 GMT using RSA key ID D3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" * remotes/kraxel/tags/pull-usb-20150320-1: ehci: fix segfault when hot-unplugging ehci controller ohci: fix resource cleanup leak uhci: fix segfault when hot-unplugging uhci controller hw/usb: Include USB files only if necessary usb/dev-storage: Avoid qerror_report_err() outside QMP handlers usb/dev-storage: Fix QMP device_add missing encryption key failure monitor usb: Inline monitor_read_bdrv_key_start()'s first part monitor: Plug memory leak in monitor_read_bdrv_key_start() monitor: Drop dead QMP check from monitor_read_password() uhci: Convert to realize ohci: Complete conversion to realize usb: Improve companion configuration error messages usb: Propagate errors through usb_register_companion() Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
e7e9b49f8e
|
@ -32,6 +32,7 @@ CONFIG_DS1338=y
|
||||||
CONFIG_PFLASH_CFI01=y
|
CONFIG_PFLASH_CFI01=y
|
||||||
CONFIG_PFLASH_CFI02=y
|
CONFIG_PFLASH_CFI02=y
|
||||||
CONFIG_MICRODRIVE=y
|
CONFIG_MICRODRIVE=y
|
||||||
|
CONFIG_USB=y
|
||||||
CONFIG_USB_MUSB=y
|
CONFIG_USB_MUSB=y
|
||||||
CONFIG_USB_EHCI_SYSBUS=y
|
CONFIG_USB_EHCI_SYSBUS=y
|
||||||
CONFIG_PLATFORM_BUS=y
|
CONFIG_PLATFORM_BUS=y
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
CONFIG_USB=y
|
||||||
CONFIG_USB_TABLET_WACOM=y
|
CONFIG_USB_TABLET_WACOM=y
|
||||||
CONFIG_USB_STORAGE_BOT=y
|
CONFIG_USB_STORAGE_BOT=y
|
||||||
CONFIG_USB_STORAGE_UAS=y
|
CONFIG_USB_STORAGE_UAS=y
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# usb subsystem core
|
# usb subsystem core
|
||||||
common-obj-y += core.o combined-packet.o bus.o desc.o desc-msos.o
|
common-obj-y += core.o combined-packet.o bus.o libhw.o
|
||||||
common-obj-y += libhw.o
|
common-obj-$(CONFIG_USB) += desc.o desc-msos.o
|
||||||
|
|
||||||
# usb host adapters
|
# usb host adapters
|
||||||
common-obj-$(CONFIG_USB_UHCI) += hcd-uhci.o
|
common-obj-$(CONFIG_USB_UHCI) += hcd-uhci.o
|
||||||
|
@ -11,8 +11,8 @@ common-obj-$(CONFIG_USB_XHCI) += hcd-xhci.o
|
||||||
common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o
|
common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o
|
||||||
|
|
||||||
# emulated usb devices
|
# emulated usb devices
|
||||||
common-obj-y += dev-hub.o
|
common-obj-$(CONFIG_USB) += dev-hub.o
|
||||||
common-obj-y += dev-hid.o
|
common-obj-$(CONFIG_USB) += dev-hid.o
|
||||||
common-obj-$(CONFIG_USB_TABLET_WACOM) += dev-wacom.o
|
common-obj-$(CONFIG_USB_TABLET_WACOM) += dev-wacom.o
|
||||||
common-obj-$(CONFIG_USB_STORAGE_BOT) += dev-storage.o
|
common-obj-$(CONFIG_USB_STORAGE_BOT) += dev-storage.o
|
||||||
common-obj-$(CONFIG_USB_STORAGE_UAS) += dev-uas.o
|
common-obj-$(CONFIG_USB_STORAGE_UAS) += dev-uas.o
|
||||||
|
|
27
hw/usb/bus.c
27
hw/usb/bus.c
|
@ -360,9 +360,10 @@ void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
|
||||||
bus->nfree++;
|
bus->nfree++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usb_register_companion(const char *masterbus, USBPort *ports[],
|
void usb_register_companion(const char *masterbus, USBPort *ports[],
|
||||||
uint32_t portcount, uint32_t firstport,
|
uint32_t portcount, uint32_t firstport,
|
||||||
void *opaque, USBPortOps *ops, int speedmask)
|
void *opaque, USBPortOps *ops, int speedmask,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
USBBus *bus;
|
USBBus *bus;
|
||||||
int i;
|
int i;
|
||||||
|
@ -373,22 +374,22 @@ int usb_register_companion(const char *masterbus, USBPort *ports[],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bus || !bus->ops->register_companion) {
|
if (!bus) {
|
||||||
qerror_report(QERR_INVALID_PARAMETER_VALUE, "masterbus",
|
error_setg(errp, "USB bus '%s' not found", masterbus);
|
||||||
"an USB masterbus");
|
return;
|
||||||
if (bus) {
|
}
|
||||||
error_printf_unless_qmp(
|
if (!bus->ops->register_companion) {
|
||||||
"USB bus '%s' does not allow companion controllers\n",
|
error_setg(errp, "Can't use USB bus '%s' as masterbus,"
|
||||||
masterbus);
|
" it doesn't support companion controllers",
|
||||||
}
|
masterbus);
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < portcount; i++) {
|
for (i = 0; i < portcount; i++) {
|
||||||
usb_fill_port(ports[i], opaque, i, ops, speedmask);
|
usb_fill_port(ports[i], opaque, i, ops, speedmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bus->ops->register_companion(bus, ports, portcount, firstport);
|
bus->ops->register_companion(bus, ports, portcount, firstport, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr)
|
void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr)
|
||||||
|
|
|
@ -559,8 +559,7 @@ static void usb_msd_password_cb(void *opaque, int err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
qerror_report_err(local_err);
|
error_report_err(local_err);
|
||||||
error_free(local_err);
|
|
||||||
qdev_unplug(&s->dev.qdev, NULL);
|
qdev_unplug(&s->dev.qdev, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -610,6 +609,23 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bdrv_add_key(blk_bs(blk), NULL, &err);
|
||||||
|
if (err) {
|
||||||
|
if (monitor_cur_is_qmp()) {
|
||||||
|
error_propagate(errp, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
error_free(err);
|
||||||
|
err = NULL;
|
||||||
|
if (cur_mon) {
|
||||||
|
monitor_read_bdrv_key_start(cur_mon, blk_bs(blk),
|
||||||
|
usb_msd_password_cb, s);
|
||||||
|
s->dev.auto_attach = 0;
|
||||||
|
} else {
|
||||||
|
autostart = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
blkconf_serial(&s->conf, &dev->serial);
|
blkconf_serial(&s->conf, &dev->serial);
|
||||||
blkconf_blocksizes(&s->conf);
|
blkconf_blocksizes(&s->conf);
|
||||||
|
|
||||||
|
@ -638,16 +654,6 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
|
||||||
}
|
}
|
||||||
usb_msd_handle_reset(dev);
|
usb_msd_handle_reset(dev);
|
||||||
s->scsi_dev = scsi_dev;
|
s->scsi_dev = scsi_dev;
|
||||||
|
|
||||||
if (bdrv_key_required(blk_bs(blk))) {
|
|
||||||
if (cur_mon) {
|
|
||||||
monitor_read_bdrv_key_start(cur_mon, blk_bs(blk),
|
|
||||||
usb_msd_password_cb, s);
|
|
||||||
s->dev.auto_attach = 0;
|
|
||||||
} else {
|
|
||||||
autostart = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usb_msd_realize_bot(USBDevice *dev, Error **errp)
|
static void usb_msd_realize_bot(USBDevice *dev, Error **errp)
|
||||||
|
|
|
@ -101,6 +101,15 @@ static void usb_ehci_pci_exit(PCIDevice *dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void usb_ehci_pci_reset(DeviceState *dev)
|
||||||
|
{
|
||||||
|
PCIDevice *pci_dev = PCI_DEVICE(dev);
|
||||||
|
EHCIPCIState *i = PCI_EHCI(pci_dev);
|
||||||
|
EHCIState *s = &i->ehci;
|
||||||
|
|
||||||
|
ehci_reset(s);
|
||||||
|
}
|
||||||
|
|
||||||
static void usb_ehci_pci_write_config(PCIDevice *dev, uint32_t addr,
|
static void usb_ehci_pci_write_config(PCIDevice *dev, uint32_t addr,
|
||||||
uint32_t val, int l)
|
uint32_t val, int l)
|
||||||
{
|
{
|
||||||
|
@ -143,6 +152,7 @@ static void ehci_class_init(ObjectClass *klass, void *data)
|
||||||
k->config_write = usb_ehci_pci_write_config;
|
k->config_write = usb_ehci_pci_write_config;
|
||||||
dc->vmsd = &vmstate_ehci_pci;
|
dc->vmsd = &vmstate_ehci_pci;
|
||||||
dc->props = ehci_pci_properties;
|
dc->props = ehci_pci_properties;
|
||||||
|
dc->reset = usb_ehci_pci_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo ehci_pci_type_info = {
|
static const TypeInfo ehci_pci_type_info = {
|
||||||
|
|
|
@ -42,6 +42,15 @@ static void usb_ehci_sysbus_realize(DeviceState *dev, Error **errp)
|
||||||
sysbus_init_irq(d, &s->irq);
|
sysbus_init_irq(d, &s->irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void usb_ehci_sysbus_reset(DeviceState *dev)
|
||||||
|
{
|
||||||
|
SysBusDevice *d = SYS_BUS_DEVICE(dev);
|
||||||
|
EHCISysBusState *i = SYS_BUS_EHCI(d);
|
||||||
|
EHCIState *s = &i->ehci;
|
||||||
|
|
||||||
|
ehci_reset(s);
|
||||||
|
}
|
||||||
|
|
||||||
static void ehci_sysbus_init(Object *obj)
|
static void ehci_sysbus_init(Object *obj)
|
||||||
{
|
{
|
||||||
SysBusDevice *d = SYS_BUS_DEVICE(obj);
|
SysBusDevice *d = SYS_BUS_DEVICE(obj);
|
||||||
|
@ -70,6 +79,7 @@ static void ehci_sysbus_class_init(ObjectClass *klass, void *data)
|
||||||
dc->realize = usb_ehci_sysbus_realize;
|
dc->realize = usb_ehci_sysbus_realize;
|
||||||
dc->vmsd = &vmstate_ehci_sysbus;
|
dc->vmsd = &vmstate_ehci_sysbus;
|
||||||
dc->props = ehci_sysbus_properties;
|
dc->props = ehci_sysbus_properties;
|
||||||
|
dc->reset = usb_ehci_sysbus_reset;
|
||||||
set_bit(DEVICE_CATEGORY_USB, dc->categories);
|
set_bit(DEVICE_CATEGORY_USB, dc->categories);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -769,30 +769,26 @@ static void ehci_wakeup(USBPort *port)
|
||||||
qemu_bh_schedule(s->async_bh);
|
qemu_bh_schedule(s->async_bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ehci_register_companion(USBBus *bus, USBPort *ports[],
|
static void ehci_register_companion(USBBus *bus, USBPort *ports[],
|
||||||
uint32_t portcount, uint32_t firstport)
|
uint32_t portcount, uint32_t firstport,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
EHCIState *s = container_of(bus, EHCIState, bus);
|
EHCIState *s = container_of(bus, EHCIState, bus);
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
if (firstport + portcount > NB_PORTS) {
|
if (firstport + portcount > NB_PORTS) {
|
||||||
qerror_report(QERR_INVALID_PARAMETER_VALUE, "firstport",
|
error_setg(errp, "firstport must be between 0 and %u",
|
||||||
"firstport on masterbus");
|
NB_PORTS - portcount);
|
||||||
error_printf_unless_qmp(
|
return;
|
||||||
"firstport value of %u makes companion take ports %u - %u, which "
|
|
||||||
"is outside of the valid range of 0 - %u\n", firstport, firstport,
|
|
||||||
firstport + portcount - 1, NB_PORTS - 1);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < portcount; i++) {
|
for (i = 0; i < portcount; i++) {
|
||||||
if (s->companion_ports[firstport + i]) {
|
if (s->companion_ports[firstport + i]) {
|
||||||
qerror_report(QERR_INVALID_PARAMETER_VALUE, "masterbus",
|
error_setg(errp, "firstport %u asks for ports %u-%u,"
|
||||||
"an USB masterbus");
|
" but port %u has a companion assigned already",
|
||||||
error_printf_unless_qmp(
|
firstport, firstport, firstport + portcount - 1,
|
||||||
"port %u on masterbus %s already has a companion assigned\n",
|
firstport + i);
|
||||||
firstport + i, bus->qbus.name);
|
return;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -806,8 +802,6 @@ static int ehci_register_companion(USBBus *bus, USBPort *ports[],
|
||||||
|
|
||||||
s->companion_count++;
|
s->companion_count++;
|
||||||
s->caps[0x05] = (s->companion_count << 4) | portcount;
|
s->caps[0x05] = (s->companion_count << 4) | portcount;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ehci_wakeup_endpoint(USBBus *bus, USBEndpoint *ep,
|
static void ehci_wakeup_endpoint(USBBus *bus, USBEndpoint *ep,
|
||||||
|
@ -845,7 +839,7 @@ static USBDevice *ehci_find_device(EHCIState *ehci, uint8_t addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 4.1 host controller initialization */
|
/* 4.1 host controller initialization */
|
||||||
static void ehci_reset(void *opaque)
|
void ehci_reset(void *opaque)
|
||||||
{
|
{
|
||||||
EHCIState *s = opaque;
|
EHCIState *s = opaque;
|
||||||
int i;
|
int i;
|
||||||
|
@ -2471,7 +2465,6 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp)
|
||||||
s->async_bh = qemu_bh_new(ehci_frame_timer, s);
|
s->async_bh = qemu_bh_new(ehci_frame_timer, s);
|
||||||
s->device = dev;
|
s->device = dev;
|
||||||
|
|
||||||
qemu_register_reset(ehci_reset, s);
|
|
||||||
s->vmstate = qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s);
|
s->vmstate = qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -325,6 +325,7 @@ extern const VMStateDescription vmstate_ehci;
|
||||||
void usb_ehci_init(EHCIState *s, DeviceState *dev);
|
void usb_ehci_init(EHCIState *s, DeviceState *dev);
|
||||||
void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp);
|
void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp);
|
||||||
void usb_ehci_unrealize(EHCIState *s, DeviceState *dev, Error **errp);
|
void usb_ehci_unrealize(EHCIState *s, DeviceState *dev, Error **errp);
|
||||||
|
void ehci_reset(void *opaque);
|
||||||
|
|
||||||
#define TYPE_PCI_EHCI "pci-ehci-usb"
|
#define TYPE_PCI_EHCI "pci-ehci-usb"
|
||||||
#define PCI_EHCI(obj) OBJECT_CHECK(EHCIPCIState, (obj), TYPE_PCI_EHCI)
|
#define PCI_EHCI(obj) OBJECT_CHECK(EHCIPCIState, (obj), TYPE_PCI_EHCI)
|
||||||
|
|
|
@ -1827,11 +1827,12 @@ static USBPortOps ohci_port_ops = {
|
||||||
static USBBusOps ohci_bus_ops = {
|
static USBBusOps ohci_bus_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int usb_ohci_init(OHCIState *ohci, DeviceState *dev,
|
static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
|
||||||
int num_ports, dma_addr_t localmem_base,
|
int num_ports, dma_addr_t localmem_base,
|
||||||
char *masterbus, uint32_t firstport,
|
char *masterbus, uint32_t firstport,
|
||||||
AddressSpace *as)
|
AddressSpace *as, Error **errp)
|
||||||
{
|
{
|
||||||
|
Error *err = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ohci->as = as;
|
ohci->as = as;
|
||||||
|
@ -1857,10 +1858,13 @@ static int usb_ohci_init(OHCIState *ohci, DeviceState *dev,
|
||||||
for(i = 0; i < num_ports; i++) {
|
for(i = 0; i < num_ports; i++) {
|
||||||
ports[i] = &ohci->rhport[i].port;
|
ports[i] = &ohci->rhport[i].port;
|
||||||
}
|
}
|
||||||
if (usb_register_companion(masterbus, ports, num_ports,
|
usb_register_companion(masterbus, ports, num_ports,
|
||||||
firstport, ohci, &ohci_port_ops,
|
firstport, ohci, &ohci_port_ops,
|
||||||
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) {
|
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL,
|
||||||
return -1;
|
&err);
|
||||||
|
if (err) {
|
||||||
|
error_propagate(errp, err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
usb_bus_new(&ohci->bus, sizeof(ohci->bus), &ohci_bus_ops, dev);
|
usb_bus_new(&ohci->bus, sizeof(ohci->bus), &ohci_bus_ops, dev);
|
||||||
|
@ -1879,9 +1883,6 @@ static int usb_ohci_init(OHCIState *ohci, DeviceState *dev,
|
||||||
usb_packet_init(&ohci->usb_packet);
|
usb_packet_init(&ohci->usb_packet);
|
||||||
|
|
||||||
ohci->async_td = 0;
|
ohci->async_td = 0;
|
||||||
qemu_register_reset(ohci_reset, ohci);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TYPE_PCI_OHCI "pci-ohci"
|
#define TYPE_PCI_OHCI "pci-ohci"
|
||||||
|
@ -1914,22 +1915,24 @@ static void ohci_die(OHCIState *ohci)
|
||||||
PCI_STATUS_DETECTED_PARITY);
|
PCI_STATUS_DETECTED_PARITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usb_ohci_initfn_pci(PCIDevice *dev)
|
static void usb_ohci_realize_pci(PCIDevice *dev, Error **errp)
|
||||||
{
|
{
|
||||||
|
Error *err = NULL;
|
||||||
OHCIPCIState *ohci = PCI_OHCI(dev);
|
OHCIPCIState *ohci = PCI_OHCI(dev);
|
||||||
|
|
||||||
dev->config[PCI_CLASS_PROG] = 0x10; /* OHCI */
|
dev->config[PCI_CLASS_PROG] = 0x10; /* OHCI */
|
||||||
dev->config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */
|
dev->config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */
|
||||||
|
|
||||||
if (usb_ohci_init(&ohci->state, DEVICE(dev), ohci->num_ports, 0,
|
usb_ohci_init(&ohci->state, DEVICE(dev), ohci->num_ports, 0,
|
||||||
ohci->masterbus, ohci->firstport,
|
ohci->masterbus, ohci->firstport,
|
||||||
pci_get_address_space(dev)) != 0) {
|
pci_get_address_space(dev), &err);
|
||||||
return -1;
|
if (err) {
|
||||||
|
error_propagate(errp, err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
ohci->state.irq = pci_allocate_irq(dev);
|
|
||||||
|
|
||||||
|
ohci->state.irq = pci_allocate_irq(dev);
|
||||||
pci_register_bar(dev, 0, 0, &ohci->state.mem);
|
pci_register_bar(dev, 0, 0, &ohci->state.mem);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usb_ohci_exit(PCIDevice *dev)
|
static void usb_ohci_exit(PCIDevice *dev)
|
||||||
|
@ -1951,6 +1954,15 @@ static void usb_ohci_exit(PCIDevice *dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void usb_ohci_reset_pci(DeviceState *d)
|
||||||
|
{
|
||||||
|
PCIDevice *dev = PCI_DEVICE(d);
|
||||||
|
OHCIPCIState *ohci = PCI_OHCI(dev);
|
||||||
|
OHCIState *s = &ohci->state;
|
||||||
|
|
||||||
|
ohci_reset(s);
|
||||||
|
}
|
||||||
|
|
||||||
#define TYPE_SYSBUS_OHCI "sysbus-ohci"
|
#define TYPE_SYSBUS_OHCI "sysbus-ohci"
|
||||||
#define SYSBUS_OHCI(obj) OBJECT_CHECK(OHCISysBusState, (obj), TYPE_SYSBUS_OHCI)
|
#define SYSBUS_OHCI(obj) OBJECT_CHECK(OHCISysBusState, (obj), TYPE_SYSBUS_OHCI)
|
||||||
|
|
||||||
|
@ -1971,11 +1983,19 @@ static void ohci_realize_pxa(DeviceState *dev, Error **errp)
|
||||||
|
|
||||||
/* Cannot fail as we pass NULL for masterbus */
|
/* Cannot fail as we pass NULL for masterbus */
|
||||||
usb_ohci_init(&s->ohci, dev, s->num_ports, s->dma_offset, NULL, 0,
|
usb_ohci_init(&s->ohci, dev, s->num_ports, s->dma_offset, NULL, 0,
|
||||||
&address_space_memory);
|
&address_space_memory, &error_abort);
|
||||||
sysbus_init_irq(sbd, &s->ohci.irq);
|
sysbus_init_irq(sbd, &s->ohci.irq);
|
||||||
sysbus_init_mmio(sbd, &s->ohci.mem);
|
sysbus_init_mmio(sbd, &s->ohci.mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void usb_ohci_reset_sysbus(DeviceState *dev)
|
||||||
|
{
|
||||||
|
OHCISysBusState *s = SYSBUS_OHCI(dev);
|
||||||
|
OHCIState *ohci = &s->ohci;
|
||||||
|
|
||||||
|
ohci_reset(ohci);
|
||||||
|
}
|
||||||
|
|
||||||
static Property ohci_pci_properties[] = {
|
static Property ohci_pci_properties[] = {
|
||||||
DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus),
|
DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus),
|
||||||
DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3),
|
DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3),
|
||||||
|
@ -2087,7 +2107,7 @@ static void ohci_pci_class_init(ObjectClass *klass, void *data)
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||||
|
|
||||||
k->init = usb_ohci_initfn_pci;
|
k->realize = usb_ohci_realize_pci;
|
||||||
k->exit = usb_ohci_exit;
|
k->exit = usb_ohci_exit;
|
||||||
k->vendor_id = PCI_VENDOR_ID_APPLE;
|
k->vendor_id = PCI_VENDOR_ID_APPLE;
|
||||||
k->device_id = PCI_DEVICE_ID_APPLE_IPID_USB;
|
k->device_id = PCI_DEVICE_ID_APPLE_IPID_USB;
|
||||||
|
@ -2097,6 +2117,7 @@ static void ohci_pci_class_init(ObjectClass *klass, void *data)
|
||||||
dc->props = ohci_pci_properties;
|
dc->props = ohci_pci_properties;
|
||||||
dc->hotpluggable = false;
|
dc->hotpluggable = false;
|
||||||
dc->vmsd = &vmstate_ohci;
|
dc->vmsd = &vmstate_ohci;
|
||||||
|
dc->reset = usb_ohci_reset_pci;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo ohci_pci_info = {
|
static const TypeInfo ohci_pci_info = {
|
||||||
|
@ -2120,6 +2141,7 @@ static void ohci_sysbus_class_init(ObjectClass *klass, void *data)
|
||||||
set_bit(DEVICE_CATEGORY_USB, dc->categories);
|
set_bit(DEVICE_CATEGORY_USB, dc->categories);
|
||||||
dc->desc = "OHCI USB Controller";
|
dc->desc = "OHCI USB Controller";
|
||||||
dc->props = ohci_sysbus_properties;
|
dc->props = ohci_sysbus_properties;
|
||||||
|
dc->reset = usb_ohci_reset_sysbus;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo ohci_sysbus_info = {
|
static const TypeInfo ohci_sysbus_info = {
|
||||||
|
|
|
@ -66,7 +66,7 @@ struct UHCIInfo {
|
||||||
uint16_t device_id;
|
uint16_t device_id;
|
||||||
uint8_t revision;
|
uint8_t revision;
|
||||||
uint8_t irq_pin;
|
uint8_t irq_pin;
|
||||||
int (*initfn)(PCIDevice *dev);
|
void (*realize)(PCIDevice *dev, Error **errp);
|
||||||
bool unplug;
|
bool unplug;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -348,9 +348,10 @@ static void uhci_update_irq(UHCIState *s)
|
||||||
pci_set_irq(&s->dev, level);
|
pci_set_irq(&s->dev, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uhci_reset(void *opaque)
|
static void uhci_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
UHCIState *s = opaque;
|
PCIDevice *d = PCI_DEVICE(dev);
|
||||||
|
UHCIState *s = DO_UPCAST(UHCIState, dev, d);
|
||||||
uint8_t *pci_conf;
|
uint8_t *pci_conf;
|
||||||
int i;
|
int i;
|
||||||
UHCIPort *port;
|
UHCIPort *port;
|
||||||
|
@ -454,11 +455,11 @@ static void uhci_port_write(void *opaque, hwaddr addr,
|
||||||
port = &s->ports[i];
|
port = &s->ports[i];
|
||||||
usb_device_reset(port->port.dev);
|
usb_device_reset(port->port.dev);
|
||||||
}
|
}
|
||||||
uhci_reset(s);
|
uhci_reset(DEVICE(s));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (val & UHCI_CMD_HCRESET) {
|
if (val & UHCI_CMD_HCRESET) {
|
||||||
uhci_reset(s);
|
uhci_reset(DEVICE(s));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
s->cmd = val;
|
s->cmd = val;
|
||||||
|
@ -1190,8 +1191,9 @@ static USBPortOps uhci_port_ops = {
|
||||||
static USBBusOps uhci_bus_ops = {
|
static USBBusOps uhci_bus_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int usb_uhci_common_initfn(PCIDevice *dev)
|
static void usb_uhci_common_realize(PCIDevice *dev, Error **errp)
|
||||||
{
|
{
|
||||||
|
Error *err = NULL;
|
||||||
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
|
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
|
||||||
UHCIPCIDeviceClass *u = container_of(pc, UHCIPCIDeviceClass, parent_class);
|
UHCIPCIDeviceClass *u = container_of(pc, UHCIPCIDeviceClass, parent_class);
|
||||||
UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
|
UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
|
||||||
|
@ -1209,10 +1211,13 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
|
||||||
for(i = 0; i < NB_PORTS; i++) {
|
for(i = 0; i < NB_PORTS; i++) {
|
||||||
ports[i] = &s->ports[i].port;
|
ports[i] = &s->ports[i].port;
|
||||||
}
|
}
|
||||||
if (usb_register_companion(s->masterbus, ports, NB_PORTS,
|
usb_register_companion(s->masterbus, ports, NB_PORTS,
|
||||||
s->firstport, s, &uhci_port_ops,
|
s->firstport, s, &uhci_port_ops,
|
||||||
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) {
|
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL,
|
||||||
return -1;
|
&err);
|
||||||
|
if (err) {
|
||||||
|
error_propagate(errp, err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
usb_bus_new(&s->bus, sizeof(s->bus), &uhci_bus_ops, DEVICE(dev));
|
usb_bus_new(&s->bus, sizeof(s->bus), &uhci_bus_ops, DEVICE(dev));
|
||||||
|
@ -1226,19 +1231,15 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
|
||||||
s->num_ports_vmstate = NB_PORTS;
|
s->num_ports_vmstate = NB_PORTS;
|
||||||
QTAILQ_INIT(&s->queues);
|
QTAILQ_INIT(&s->queues);
|
||||||
|
|
||||||
qemu_register_reset(uhci_reset, s);
|
|
||||||
|
|
||||||
memory_region_init_io(&s->io_bar, OBJECT(s), &uhci_ioport_ops, s,
|
memory_region_init_io(&s->io_bar, OBJECT(s), &uhci_ioport_ops, s,
|
||||||
"uhci", 0x20);
|
"uhci", 0x20);
|
||||||
|
|
||||||
/* Use region 4 for consistency with real hardware. BSD guests seem
|
/* Use region 4 for consistency with real hardware. BSD guests seem
|
||||||
to rely on this. */
|
to rely on this. */
|
||||||
pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
|
pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
|
static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
|
||||||
{
|
{
|
||||||
UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
|
UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
|
||||||
uint8_t *pci_conf = s->dev.config;
|
uint8_t *pci_conf = s->dev.config;
|
||||||
|
@ -1250,7 +1251,7 @@ static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
|
||||||
/* USB legacy support */
|
/* USB legacy support */
|
||||||
pci_set_long(pci_conf + 0xc0,0x00002000);
|
pci_set_long(pci_conf + 0xc0,0x00002000);
|
||||||
|
|
||||||
return usb_uhci_common_initfn(dev);
|
usb_uhci_common_realize(dev, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usb_uhci_exit(PCIDevice *dev)
|
static void usb_uhci_exit(PCIDevice *dev)
|
||||||
|
@ -1296,13 +1297,14 @@ static void uhci_class_init(ObjectClass *klass, void *data)
|
||||||
UHCIPCIDeviceClass *u = container_of(k, UHCIPCIDeviceClass, parent_class);
|
UHCIPCIDeviceClass *u = container_of(k, UHCIPCIDeviceClass, parent_class);
|
||||||
UHCIInfo *info = data;
|
UHCIInfo *info = data;
|
||||||
|
|
||||||
k->init = info->initfn ? info->initfn : usb_uhci_common_initfn;
|
k->realize = info->realize ? info->realize : usb_uhci_common_realize;
|
||||||
k->exit = info->unplug ? usb_uhci_exit : NULL;
|
k->exit = info->unplug ? usb_uhci_exit : NULL;
|
||||||
k->vendor_id = info->vendor_id;
|
k->vendor_id = info->vendor_id;
|
||||||
k->device_id = info->device_id;
|
k->device_id = info->device_id;
|
||||||
k->revision = info->revision;
|
k->revision = info->revision;
|
||||||
k->class_id = PCI_CLASS_SERIAL_USB;
|
k->class_id = PCI_CLASS_SERIAL_USB;
|
||||||
dc->vmsd = &vmstate_uhci;
|
dc->vmsd = &vmstate_uhci;
|
||||||
|
dc->reset = uhci_reset;
|
||||||
if (!info->unplug) {
|
if (!info->unplug) {
|
||||||
/* uhci controllers in companion setups can't be hotplugged */
|
/* uhci controllers in companion setups can't be hotplugged */
|
||||||
dc->hotpluggable = false;
|
dc->hotpluggable = false;
|
||||||
|
@ -1335,7 +1337,7 @@ static UHCIInfo uhci_info[] = {
|
||||||
.device_id = PCI_DEVICE_ID_VIA_UHCI,
|
.device_id = PCI_DEVICE_ID_VIA_UHCI,
|
||||||
.revision = 0x01,
|
.revision = 0x01,
|
||||||
.irq_pin = 3,
|
.irq_pin = 3,
|
||||||
.initfn = usb_uhci_vt82c686b_initfn,
|
.realize = usb_uhci_vt82c686b_realize,
|
||||||
.unplug = true,
|
.unplug = true,
|
||||||
},{
|
},{
|
||||||
.name = "ich9-usb-uhci1", /* 00:1d.0 */
|
.name = "ich9-usb-uhci1", /* 00:1d.0 */
|
||||||
|
|
|
@ -526,8 +526,9 @@ struct USBBus {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct USBBusOps {
|
struct USBBusOps {
|
||||||
int (*register_companion)(USBBus *bus, USBPort *ports[],
|
void (*register_companion)(USBBus *bus, USBPort *ports[],
|
||||||
uint32_t portcount, uint32_t firstport);
|
uint32_t portcount, uint32_t firstport,
|
||||||
|
Error **errp);
|
||||||
void (*wakeup_endpoint)(USBBus *bus, USBEndpoint *ep, unsigned int stream);
|
void (*wakeup_endpoint)(USBBus *bus, USBEndpoint *ep, unsigned int stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -543,9 +544,10 @@ USBDevice *usb_create_simple(USBBus *bus, const char *name);
|
||||||
USBDevice *usbdevice_create(const char *cmdline);
|
USBDevice *usbdevice_create(const char *cmdline);
|
||||||
void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
|
void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
|
||||||
USBPortOps *ops, int speedmask);
|
USBPortOps *ops, int speedmask);
|
||||||
int usb_register_companion(const char *masterbus, USBPort *ports[],
|
void usb_register_companion(const char *masterbus, USBPort *ports[],
|
||||||
uint32_t portcount, uint32_t firstport,
|
uint32_t portcount, uint32_t firstport,
|
||||||
void *opaque, USBPortOps *ops, int speedmask);
|
void *opaque, USBPortOps *ops, int speedmask,
|
||||||
|
Error **errp);
|
||||||
void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr);
|
void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr);
|
||||||
void usb_unregister_port(USBBus *bus, USBPort *port);
|
void usb_unregister_port(USBBus *bus, USBPort *port);
|
||||||
void usb_claim_port(USBDevice *dev, Error **errp);
|
void usb_claim_port(USBDevice *dev, Error **errp);
|
||||||
|
|
32
monitor.c
32
monitor.c
|
@ -266,10 +266,7 @@ void monitor_read_command(Monitor *mon, int show_prompt)
|
||||||
int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
|
int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
if (monitor_ctrl_mode(mon)) {
|
if (mon->rs) {
|
||||||
qerror_report(QERR_MISSING_PARAMETER, "password");
|
|
||||||
return -EINVAL;
|
|
||||||
} else if (mon->rs) {
|
|
||||||
readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
|
readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
|
||||||
/* prompt is printed on return from the command handler */
|
/* prompt is printed on return from the command handler */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -5389,23 +5386,8 @@ int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
|
||||||
BlockCompletionFunc *completion_cb,
|
BlockCompletionFunc *completion_cb,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
Error *local_err = NULL;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
bdrv_add_key(bs, NULL, &local_err);
|
|
||||||
if (!local_err) {
|
|
||||||
if (completion_cb)
|
|
||||||
completion_cb(opaque, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Need a key for @bs */
|
|
||||||
|
|
||||||
if (monitor_ctrl_mode(mon)) {
|
|
||||||
qerror_report_err(local_err);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
|
monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
|
||||||
bdrv_get_encrypted_filename(bs));
|
bdrv_get_encrypted_filename(bs));
|
||||||
|
|
||||||
|
@ -5424,6 +5406,7 @@ int monitor_read_block_device_key(Monitor *mon, const char *device,
|
||||||
BlockCompletionFunc *completion_cb,
|
BlockCompletionFunc *completion_cb,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
|
Error *err = NULL;
|
||||||
BlockBackend *blk;
|
BlockBackend *blk;
|
||||||
|
|
||||||
blk = blk_by_name(device);
|
blk = blk_by_name(device);
|
||||||
|
@ -5432,7 +5415,16 @@ int monitor_read_block_device_key(Monitor *mon, const char *device,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return monitor_read_bdrv_key_start(mon, blk_bs(blk), completion_cb, opaque);
|
bdrv_add_key(blk_bs(blk), NULL, &err);
|
||||||
|
if (err) {
|
||||||
|
error_free(err);
|
||||||
|
return monitor_read_bdrv_key_start(mon, blk_bs(blk), completion_cb, opaque);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (completion_cb) {
|
||||||
|
completion_cb(opaque, 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QemuOptsList qemu_mon_opts = {
|
QemuOptsList qemu_mon_opts = {
|
||||||
|
|
Loading…
Reference in a new issue