[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 06/96] pci: Convert core to realize
From: |
Michael S. Tsirkin |
Subject: |
[Qemu-devel] [PULL 06/96] pci: Convert core to realize |
Date: |
Wed, 18 Feb 2015 22:44:34 +0100 |
From: Markus Armbruster <address@hidden>
Implement DeviceClass methods realize() and unrealize() instead of
init() and exit(). The core's initialization errors now get
propagated properly, and QMP sends them instead of an unspecific
"Device initialization failed" error. Unrealize can't fail, so no
change there.
PCIDeviceClass is unchanged: it still provides init() and exit().
Therefore, device models' errors are still not propagated.
Signed-off-by: Markus Armbruster <address@hidden>
Reviewed-by: Michael S. Tsirkin <address@hidden>
Signed-off-by: Michael S. Tsirkin <address@hidden>
Reviewed-by: Gonglei <address@hidden>
---
hw/pci/pci.c | 93 ++++++++++++++++++++++++++++++++----------------------------
1 file changed, 49 insertions(+), 44 deletions(-)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index d508930..aaf480d 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -115,7 +115,7 @@ static const TypeInfo pcie_bus_info = {
static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
static void pci_update_mappings(PCIDevice *d);
static void pci_irq_handler(void *opaque, int irq_num, int level);
-static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom);
+static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, Error **);
static void pci_del_option_rom(PCIDevice *pdev);
static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
@@ -726,7 +726,7 @@ static void pci_init_mask_bridge(PCIDevice *d)
PCI_PREF_RANGE_TYPE_MASK);
}
-static int pci_init_multifunction(PCIBus *bus, PCIDevice *dev)
+static void pci_init_multifunction(PCIBus *bus, PCIDevice *dev, Error **errp)
{
uint8_t slot = PCI_SLOT(dev->devfn);
uint8_t func;
@@ -752,26 +752,25 @@ static int pci_init_multifunction(PCIBus *bus, PCIDevice
*dev)
PCIDevice *f0 = bus->devices[PCI_DEVFN(slot, 0)];
if (f0 && !(f0->cap_present & QEMU_PCI_CAP_MULTIFUNCTION)) {
/* function 0 should set multifunction bit */
- error_report("PCI: single function device can't be populated "
- "in function %x.%x", slot, PCI_FUNC(dev->devfn));
- return -1;
+ error_setg(errp, "PCI: single function device can't be populated "
+ "in function %x.%x", slot, PCI_FUNC(dev->devfn));
+ return;
}
- return 0;
+ return;
}
if (dev->cap_present & QEMU_PCI_CAP_MULTIFUNCTION) {
- return 0;
+ return;
}
/* function 0 indicates single function, so function > 0 must be NULL */
for (func = 1; func < PCI_FUNC_MAX; ++func) {
if (bus->devices[PCI_DEVFN(slot, func)]) {
- error_report("PCI: %x.0 indicates single function, "
- "but %x.%x is already populated.",
- slot, slot, func);
- return -1;
+ error_setg(errp, "PCI: %x.0 indicates single function, "
+ "but %x.%x is already populated.",
+ slot, slot, func);
+ return;
}
}
- return 0;
}
static void pci_config_alloc(PCIDevice *pci_dev)
@@ -804,11 +803,13 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
/* -1 for devfn means auto assign */
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
- const char *name, int devfn)
+ const char *name, int devfn,
+ Error **errp)
{
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
PCIConfigReadFunc *config_read = pc->config_read;
PCIConfigWriteFunc *config_write = pc->config_write;
+ Error *local_err = NULL;
AddressSpace *dma_as;
if (devfn < 0) {
@@ -817,12 +818,15 @@ static PCIDevice *do_pci_register_device(PCIDevice
*pci_dev, PCIBus *bus,
if (!bus->devices[devfn])
goto found;
}
- error_report("PCI: no slot/function available for %s, all in use",
name);
+ error_setg(errp, "PCI: no slot/function available for %s, all in use",
+ name);
return NULL;
found: ;
} else if (bus->devices[devfn]) {
- error_report("PCI: slot %d function %d not available for %s, in use by
%s",
- PCI_SLOT(devfn), PCI_FUNC(devfn), name,
bus->devices[devfn]->name);
+ error_setg(errp, "PCI: slot %d function %d not available for %s,"
+ " in use by %s",
+ PCI_SLOT(devfn), PCI_FUNC(devfn), name,
+ bus->devices[devfn]->name);
return NULL;
}
@@ -866,7 +870,9 @@ static PCIDevice *do_pci_register_device(PCIDevice
*pci_dev, PCIBus *bus,
if (pc->is_bridge) {
pci_init_mask_bridge(pci_dev);
}
- if (pci_init_multifunction(bus, pci_dev)) {
+ pci_init_multifunction(bus, pci_dev, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
do_pci_unregister_device(pci_dev);
return NULL;
}
@@ -897,7 +903,7 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
pci_unregister_vga(pci_dev);
}
-static int pci_unregister_device(DeviceState *dev)
+static void pci_qdev_unrealize(DeviceState *dev, Error **errp)
{
PCIDevice *pci_dev = PCI_DEVICE(dev);
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
@@ -910,7 +916,6 @@ static int pci_unregister_device(DeviceState *dev)
}
do_pci_unregister_device(pci_dev);
- return 0;
}
void pci_register_bar(PCIDevice *pci_dev, int region_num,
@@ -1751,10 +1756,11 @@ PCIDevice *pci_find_device(PCIBus *bus, int bus_num,
uint8_t devfn)
return bus->devices[devfn];
}
-static int pci_qdev_init(DeviceState *qdev)
+static void pci_qdev_realize(DeviceState *qdev, Error **errp)
{
PCIDevice *pci_dev = (PCIDevice *)qdev;
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
+ Error *local_err = NULL;
PCIBus *bus;
int rc;
bool is_default_rom;
@@ -1767,15 +1773,16 @@ static int pci_qdev_init(DeviceState *qdev)
bus = PCI_BUS(qdev_get_parent_bus(qdev));
pci_dev = do_pci_register_device(pci_dev, bus,
object_get_typename(OBJECT(qdev)),
- pci_dev->devfn);
+ pci_dev->devfn, errp);
if (pci_dev == NULL)
- return -1;
+ return;
if (pc->init) {
rc = pc->init(pci_dev);
if (rc != 0) {
do_pci_unregister_device(pci_dev);
- return rc;
+ error_setg(errp, "Device initialization failed");
+ return;
}
}
@@ -1786,13 +1793,12 @@ static int pci_qdev_init(DeviceState *qdev)
is_default_rom = true;
}
- rc = pci_add_option_rom(pci_dev, is_default_rom);
- if (rc != 0) {
- pci_unregister_device(DEVICE(pci_dev));
- return rc;
+ pci_add_option_rom(pci_dev, is_default_rom, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ pci_qdev_unrealize(DEVICE(pci_dev), NULL);
+ return;
}
-
- return 0;
}
PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
@@ -1932,7 +1938,8 @@ static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr,
int size)
}
/* Add an option rom for the device */
-static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
+static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom,
+ Error **errp)
{
int size;
char *path;
@@ -1941,9 +1948,9 @@ static int pci_add_option_rom(PCIDevice *pdev, bool
is_default_rom)
const VMStateDescription *vmsd;
if (!pdev->romfile)
- return 0;
+ return;
if (strlen(pdev->romfile) == 0)
- return 0;
+ return;
if (!pdev->rom_bar) {
/*
@@ -1957,7 +1964,9 @@ static int pci_add_option_rom(PCIDevice *pdev, bool
is_default_rom)
* if the rom bar is disabled.
*/
if (DEVICE(pdev)->hotplugged) {
- return -1;
+ error_setg(errp, "Hot-plugged device without ROM bar"
+ " can't have an option ROM");
+ return;
}
if (class == 0x0300) {
@@ -1965,7 +1974,7 @@ static int pci_add_option_rom(PCIDevice *pdev, bool
is_default_rom)
} else {
rom_add_option(pdev->romfile, -1);
}
- return 0;
+ return;
}
path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile);
@@ -1975,15 +1984,13 @@ static int pci_add_option_rom(PCIDevice *pdev, bool
is_default_rom)
size = get_image_size(path);
if (size < 0) {
- error_report("%s: failed to find romfile \"%s\"",
- __func__, pdev->romfile);
+ error_setg(errp, "failed to find romfile \"%s\"", pdev->romfile);
g_free(path);
- return -1;
+ return;
} else if (size == 0) {
- error_report("%s: ignoring empty romfile \"%s\"",
- __func__, pdev->romfile);
+ error_setg(errp, "romfile \"%s\" is empty", pdev->romfile);
g_free(path);
- return -1;
+ return;
}
if (size & (size - 1)) {
size = 1 << qemu_fls(size);
@@ -2009,8 +2016,6 @@ static int pci_add_option_rom(PCIDevice *pdev, bool
is_default_rom)
}
pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
-
- return 0;
}
static void pci_del_option_rom(PCIDevice *pdev)
@@ -2292,8 +2297,8 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev)
static void pci_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
- k->init = pci_qdev_init;
- k->exit = pci_unregister_device;
+ k->realize = pci_qdev_realize;
+ k->unrealize = pci_qdev_unrealize;
k->bus_type = TYPE_PCI_BUS;
k->props = pci_props;
}
--
MST
- [Qemu-devel] [PULL 00/96] pci, pc, virtio fixes and cleanups, Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 02/96] bios linker: validate pointer within table, Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 01/96] acpi-build: fix memory leak with bridge hp off, Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 03/96] acpi: move generic aml building helpers into dedictated file, Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 04/96] acpi: add build_append_namestring() helper, Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 05/96] acpi: drop min-bytes in build_package(), Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 06/96] pci: Convert core to realize,
Michael S. Tsirkin <=
- [Qemu-devel] [PULL 07/96] pci: Permit incremental conversion of device models to realize, Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 08/96] pci: Trivial device model conversions to realize, Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 09/96] pcnet: pcnet_common_init() always returns 0, change to void, Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 10/96] pcnet: Convert to realize, Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 11/96] serial-pci: Convert to realize, Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 12/96] ide/ich: Convert to realize, Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 13/96] cirrus-vga: Convert to realize, Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 14/96] qxl: Convert to realize, Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 15/96] pci-assign: Convert to realize, Michael S. Tsirkin, 2015/02/18
- [Qemu-devel] [PULL 17/96] acpi, pc: Add hotunplug request cb for pc machine., Michael S. Tsirkin, 2015/02/18