Commit cd9aa33e authored by Laszlo Ersek's avatar Laszlo Ersek Committed by Luiz Capitulino
Browse files

pci: add Error-propagating pci_add_capability2()



... and rebase pci_add_capability() to it.

Signed-off-by: default avatarLaszlo Ersek <lersek@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Signed-off-by: default avatarLuiz Capitulino <lcapitulino@redhat.com>
parent 665f119f
Loading
Loading
Loading
Loading
+26 −6
Original line number Diff line number Diff line
@@ -2012,6 +2012,25 @@ static void pci_del_option_rom(PCIDevice *pdev)
 * in pci config space */
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;
@@ -2019,6 +2038,7 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
    if (!offset) {
        offset = pci_find_space(pdev, size);
        if (!offset) {
            error_setg(errp, "out of PCI config space");
            return -ENOSPC;
        }
    } else {
@@ -2029,9 +2049,9 @@ 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 "
                error_setg(errp, "%s:%02x:%02x.%x "
                           "Attempt to add PCI capability %x at offset "
                        "%x overlaps existing capability %x at offset %x\n",
                           "%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);
+4 −0
Original line number Diff line number Diff line
@@ -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);