diff options
author | Laszlo Ersek <lersek@redhat.com> | 2014-04-10 10:24:36 +0200 |
---|---|---|
committer | Luiz Capitulino <lcapitulino@redhat.com> | 2014-05-08 14:19:59 -0400 |
commit | cd9aa33e2cab11fb89071dc2f48550431406e524 (patch) | |
tree | f4082c171e3084a6a6f03850d381da95567f6d95 | |
parent | 665f119fbad97c05c2603673ac6b2dcbf0d0e9e1 (diff) |
pci: add Error-propagating pci_add_capability2()
... and rebase pci_add_capability() to it.
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
-rw-r--r-- | hw/pci/pci.c | 32 | ||||
-rw-r--r-- | include/hw/pci/pci.h | 4 |
2 files changed, 30 insertions, 6 deletions
diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 517ff2a21b..22fe5eec36 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -2013,12 +2013,32 @@ static void pci_del_option_rom(PCIDevice *pdev) int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t offset, uint8_t size) { + int ret; + Error *local_err = NULL; + + ret = pci_add_capability2(pdev, cap_id, offset, size, &local_err); + if (local_err) { + assert(ret < 0); + error_report("%s", error_get_pretty(local_err)); + error_free(local_err); + } else { + /* success implies a positive offset in config space */ + assert(ret > 0); + } + return ret; +} + +int pci_add_capability2(PCIDevice *pdev, uint8_t cap_id, + uint8_t offset, uint8_t size, + Error **errp) +{ uint8_t *config; int i, overlapping_cap; if (!offset) { offset = pci_find_space(pdev, size); if (!offset) { + error_setg(errp, "out of PCI config space"); return -ENOSPC; } } else { @@ -2029,12 +2049,12 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, for (i = offset; i < offset + size; i++) { overlapping_cap = pci_find_capability_at_offset(pdev, i); if (overlapping_cap) { - fprintf(stderr, "ERROR: %s:%02x:%02x.%x " - "Attempt to add PCI capability %x at offset " - "%x overlaps existing capability %x at offset %x\n", - pci_root_bus_path(pdev), pci_bus_num(pdev->bus), - PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), - cap_id, offset, overlapping_cap, i); + error_setg(errp, "%s:%02x:%02x.%x " + "Attempt to add PCI capability %x at offset " + "%x overlaps existing capability %x at offset %x", + pci_root_bus_path(pdev), pci_bus_num(pdev->bus), + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), + cap_id, offset, overlapping_cap, i); return -EINVAL; } } diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 693dd6b658..8c25ae5d1d 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -6,6 +6,7 @@ #include "hw/qdev.h" #include "exec/memory.h" #include "sysemu/dma.h" +#include "qapi/error.h" /* PCI includes legacy ISA access. */ #include "hw/isa/isa.h" @@ -308,6 +309,9 @@ pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num); int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t offset, uint8_t size); +int pci_add_capability2(PCIDevice *pdev, uint8_t cap_id, + uint8_t offset, uint8_t size, + Error **errp); void pci_del_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size); |