usb: tag standalone ehci as hotpluggable

Add a flag to EHCIPCIInfo saying whenever the controller supports
companions or not.  Make sure we only allow registering companions for
ehci versions supporting that.  Enable pci hotplug for the ehci
variants not supporting companions.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Gerd Hoffmann 2014-08-29 14:40:08 +02:00
parent 638ca939d8
commit ec56214f6f
3 changed files with 18 additions and 3 deletions

View File

@ -23,6 +23,7 @@ typedef struct EHCIPCIInfo {
uint16_t vendor_id; uint16_t vendor_id;
uint16_t device_id; uint16_t device_id;
uint8_t revision; uint8_t revision;
bool companion;
} EHCIPCIInfo; } EHCIPCIInfo;
static int usb_ehci_pci_initfn(PCIDevice *dev) static int usb_ehci_pci_initfn(PCIDevice *dev)
@ -71,6 +72,7 @@ static int usb_ehci_pci_initfn(PCIDevice *dev)
static void usb_ehci_pci_init(Object *obj) static void usb_ehci_pci_init(Object *obj)
{ {
DeviceClass *dc = OBJECT_GET_CLASS(DeviceClass, obj, TYPE_DEVICE);
EHCIPCIState *i = PCI_EHCI(obj); EHCIPCIState *i = PCI_EHCI(obj);
EHCIState *s = &i->ehci; EHCIState *s = &i->ehci;
@ -81,6 +83,10 @@ static void usb_ehci_pci_init(Object *obj)
s->portscbase = 0x44; s->portscbase = 0x44;
s->portnr = NB_PORTS; s->portnr = NB_PORTS;
if (!dc->hotpluggable) {
s->companion_enable = true;
}
usb_ehci_init(s, DEVICE(obj)); usb_ehci_init(s, DEVICE(obj));
} }
@ -137,7 +143,6 @@ static void ehci_class_init(ObjectClass *klass, void *data)
k->exit = usb_ehci_pci_exit; k->exit = usb_ehci_pci_exit;
k->class_id = PCI_CLASS_SERIAL_USB; k->class_id = PCI_CLASS_SERIAL_USB;
k->config_write = usb_ehci_pci_write_config; k->config_write = usb_ehci_pci_write_config;
dc->hotpluggable = false;
dc->vmsd = &vmstate_ehci_pci; dc->vmsd = &vmstate_ehci_pci;
dc->props = ehci_pci_properties; dc->props = ehci_pci_properties;
} }
@ -161,6 +166,9 @@ static void ehci_data_class_init(ObjectClass *klass, void *data)
k->device_id = i->device_id; k->device_id = i->device_id;
k->revision = i->revision; k->revision = i->revision;
set_bit(DEVICE_CATEGORY_USB, dc->categories); set_bit(DEVICE_CATEGORY_USB, dc->categories);
if (i->companion) {
dc->hotpluggable = false;
}
} }
static struct EHCIPCIInfo ehci_pci_info[] = { static struct EHCIPCIInfo ehci_pci_info[] = {
@ -174,11 +182,13 @@ static struct EHCIPCIInfo ehci_pci_info[] = {
.vendor_id = PCI_VENDOR_ID_INTEL, .vendor_id = PCI_VENDOR_ID_INTEL,
.device_id = PCI_DEVICE_ID_INTEL_82801I_EHCI1, .device_id = PCI_DEVICE_ID_INTEL_82801I_EHCI1,
.revision = 0x03, .revision = 0x03,
.companion = true,
},{ },{
.name = "ich9-usb-ehci2", /* 00:1a.7 */ .name = "ich9-usb-ehci2", /* 00:1a.7 */
.vendor_id = PCI_VENDOR_ID_INTEL, .vendor_id = PCI_VENDOR_ID_INTEL,
.device_id = PCI_DEVICE_ID_INTEL_82801I_EHCI2, .device_id = PCI_DEVICE_ID_INTEL_82801I_EHCI2,
.revision = 0x03, .revision = 0x03,
.companion = true,
} }
}; };

View File

@ -2347,10 +2347,13 @@ static USBPortOps ehci_port_ops = {
.complete = ehci_async_complete_packet, .complete = ehci_async_complete_packet,
}; };
static USBBusOps ehci_bus_ops = { static USBBusOps ehci_bus_ops_companion = {
.register_companion = ehci_register_companion, .register_companion = ehci_register_companion,
.wakeup_endpoint = ehci_wakeup_endpoint, .wakeup_endpoint = ehci_wakeup_endpoint,
}; };
static USBBusOps ehci_bus_ops_standalone = {
.wakeup_endpoint = ehci_wakeup_endpoint,
};
static void usb_ehci_pre_save(void *opaque) static void usb_ehci_pre_save(void *opaque)
{ {
@ -2456,7 +2459,8 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp)
return; return;
} }
usb_bus_new(&s->bus, sizeof(s->bus), &ehci_bus_ops, dev); usb_bus_new(&s->bus, sizeof(s->bus), s->companion_enable ?
&ehci_bus_ops_companion : &ehci_bus_ops_standalone, dev);
for (i = 0; i < s->portnr; i++) { for (i = 0; i < s->portnr; i++) {
usb_register_port(&s->bus, &s->ports[i], s, i, &ehci_port_ops, usb_register_port(&s->bus, &s->ports[i], s, i, &ehci_port_ops,
USB_SPEED_MASK_HIGH); USB_SPEED_MASK_HIGH);

View File

@ -262,6 +262,7 @@ struct EHCIState {
MemoryRegion mem_opreg; MemoryRegion mem_opreg;
MemoryRegion mem_ports; MemoryRegion mem_ports;
int companion_count; int companion_count;
bool companion_enable;
uint16_t capsbase; uint16_t capsbase;
uint16_t opregbase; uint16_t opregbase;
uint16_t portscbase; uint16_t portscbase;