pci: Make errp the last parameter of pci_add_capability()

Add Error argument for pci_add_capability() to leverage the errp
to pass info on errors. This way is helpful for its callers to
make a better error handling when moving to 'realize'.

Cc: pbonzini@redhat.com
Cc: rth@twiddle.net
Cc: ehabkost@redhat.com
Cc: mst@redhat.com
Cc: jasowang@redhat.com
Cc: marcel@redhat.com
Cc: alex.williamson@redhat.com
Cc: armbru@redhat.com
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
master
Mao Zhongyi 2017-06-27 14:16:50 +08:00 committed by Michael S. Tsirkin
parent 9a815774bb
commit 9a7c2a5970
12 changed files with 95 additions and 43 deletions

View File

@ -1158,13 +1158,23 @@ static void amdvi_realize(DeviceState *dev, Error **err)
x86_iommu->type = TYPE_AMD; x86_iommu->type = TYPE_AMD;
qdev_set_parent_bus(DEVICE(&s->pci), &bus->qbus); qdev_set_parent_bus(DEVICE(&s->pci), &bus->qbus);
object_property_set_bool(OBJECT(&s->pci), true, "realized", err); object_property_set_bool(OBJECT(&s->pci), true, "realized", err);
s->capab_offset = pci_add_capability(&s->pci.dev, AMDVI_CAPAB_ID_SEC, 0, ret = pci_add_capability(&s->pci.dev, AMDVI_CAPAB_ID_SEC, 0,
AMDVI_CAPAB_SIZE); AMDVI_CAPAB_SIZE, err);
assert(s->capab_offset > 0); if (ret < 0) {
ret = pci_add_capability(&s->pci.dev, PCI_CAP_ID_MSI, 0, AMDVI_CAPAB_REG_SIZE); return;
assert(ret > 0); }
ret = pci_add_capability(&s->pci.dev, PCI_CAP_ID_HT, 0, AMDVI_CAPAB_REG_SIZE); s->capab_offset = ret;
assert(ret > 0);
ret = pci_add_capability(&s->pci.dev, PCI_CAP_ID_MSI, 0,
AMDVI_CAPAB_REG_SIZE, err);
if (ret < 0) {
return;
}
ret = pci_add_capability(&s->pci.dev, PCI_CAP_ID_HT, 0,
AMDVI_CAPAB_REG_SIZE, err);
if (ret < 0) {
return;
}
/* set up MMIO */ /* set up MMIO */
memory_region_init_io(&s->mmio, OBJECT(s), &mmio_mem_ops, s, "amdvi-mmio", memory_region_init_io(&s->mmio, OBJECT(s), &mmio_mem_ops, s, "amdvi-mmio",

View File

@ -47,6 +47,7 @@
#include "e1000e_core.h" #include "e1000e_core.h"
#include "trace.h" #include "trace.h"
#include "qapi/error.h"
#define TYPE_E1000E "e1000e" #define TYPE_E1000E "e1000e"
#define E1000E(obj) OBJECT_CHECK(E1000EState, (obj), TYPE_E1000E) #define E1000E(obj) OBJECT_CHECK(E1000EState, (obj), TYPE_E1000E)
@ -372,9 +373,15 @@ e1000e_gen_dsn(uint8_t *mac)
static int static int
e1000e_add_pm_capability(PCIDevice *pdev, uint8_t offset, uint16_t pmc) e1000e_add_pm_capability(PCIDevice *pdev, uint8_t offset, uint16_t pmc)
{ {
int ret = pci_add_capability(pdev, PCI_CAP_ID_PM, offset, PCI_PM_SIZEOF); Error *local_err = NULL;
int ret = pci_add_capability(pdev, PCI_CAP_ID_PM, offset,
PCI_PM_SIZEOF, &local_err);
if (local_err) {
error_report_err(local_err);
return ret;
}
if (ret > 0) {
pci_set_word(pdev->config + offset + PCI_PM_PMC, pci_set_word(pdev->config + offset + PCI_PM_PMC,
PCI_PM_CAP_VER_1_1 | PCI_PM_CAP_VER_1_1 |
pmc); pmc);
@ -386,7 +393,6 @@ e1000e_add_pm_capability(PCIDevice *pdev, uint8_t offset, uint16_t pmc)
pci_set_word(pdev->w1cmask + offset + PCI_PM_CTRL, pci_set_word(pdev->w1cmask + offset + PCI_PM_CTRL,
PCI_PM_CTRL_PME_STATUS); PCI_PM_CTRL_PME_STATUS);
}
return ret; return ret;
} }

View File

@ -48,6 +48,7 @@
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "sysemu/dma.h" #include "sysemu/dma.h"
#include "qemu/bitops.h" #include "qemu/bitops.h"
#include "qapi/error.h"
/* QEMU sends frames smaller than 60 bytes to ethernet nics. /* QEMU sends frames smaller than 60 bytes to ethernet nics.
* Such frames are rejected by real nics and their emulations. * Such frames are rejected by real nics and their emulations.
@ -494,7 +495,7 @@ static void eepro100_fcp_interrupt(EEPRO100State * s)
} }
#endif #endif
static void e100_pci_reset(EEPRO100State * s) static void e100_pci_reset(EEPRO100State *s, Error **errp)
{ {
E100PCIDeviceInfo *info = eepro100_get_class(s); E100PCIDeviceInfo *info = eepro100_get_class(s);
uint32_t device = s->device; uint32_t device = s->device;
@ -570,8 +571,12 @@ static void e100_pci_reset(EEPRO100State * s)
/* Power Management Capabilities */ /* Power Management Capabilities */
int cfg_offset = 0xdc; int cfg_offset = 0xdc;
int r = pci_add_capability(&s->dev, PCI_CAP_ID_PM, int r = pci_add_capability(&s->dev, PCI_CAP_ID_PM,
cfg_offset, PCI_PM_SIZEOF); cfg_offset, PCI_PM_SIZEOF,
assert(r > 0); errp);
if (r < 0) {
return;
}
pci_set_word(pci_conf + cfg_offset + PCI_PM_PMC, 0x7e21); pci_set_word(pci_conf + cfg_offset + PCI_PM_PMC, 0x7e21);
#if 0 /* TODO: replace dummy code for power management emulation. */ #if 0 /* TODO: replace dummy code for power management emulation. */
/* TODO: Power Management Control / Status. */ /* TODO: Power Management Control / Status. */
@ -1858,12 +1863,17 @@ static void e100_nic_realize(PCIDevice *pci_dev, Error **errp)
{ {
EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
E100PCIDeviceInfo *info = eepro100_get_class(s); E100PCIDeviceInfo *info = eepro100_get_class(s);
Error *local_err = NULL;
TRACE(OTHER, logout("\n")); TRACE(OTHER, logout("\n"));
s->device = info->device; s->device = info->device;
e100_pci_reset(s); e100_pci_reset(s, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
/* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM, /* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM,
* i82559 and later support 64 or 256 word EEPROM. */ * i82559 and later support 64 or 256 word EEPROM. */

View File

@ -44,6 +44,7 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "hw/pci/pci.h" #include "hw/pci/pci.h"
#include "hw/i386/ich9.h" #include "hw/i386/ich9.h"
#include "qapi/error.h"
/*****************************************************************************/ /*****************************************************************************/

View File

@ -2264,15 +2264,13 @@ static void pci_del_option_rom(PCIDevice *pdev)
* in pci config space * in pci config space
*/ */
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
uint8_t offset, uint8_t size) uint8_t offset, uint8_t size,
Error **errp)
{ {
int ret; int ret;
Error *local_err = NULL;
ret = pci_add_capability2(pdev, cap_id, offset, size, &local_err); ret = pci_add_capability2(pdev, cap_id, offset, size, errp);
if (ret < 0) {
error_report_err(local_err);
}
return ret; return ret;
} }

View File

@ -33,6 +33,7 @@
#include "hw/pci/pci_bridge.h" #include "hw/pci/pci_bridge.h"
#include "hw/pci/pci_bus.h" #include "hw/pci/pci_bus.h"
#include "qemu/range.h" #include "qemu/range.h"
#include "qapi/error.h"
/* PCI bridge subsystem vendor ID helper functions */ /* PCI bridge subsystem vendor ID helper functions */
#define PCI_SSVID_SIZEOF 8 #define PCI_SSVID_SIZEOF 8
@ -43,8 +44,12 @@ int pci_bridge_ssvid_init(PCIDevice *dev, uint8_t offset,
uint16_t svid, uint16_t ssid) uint16_t svid, uint16_t ssid)
{ {
int pos; int pos;
pos = pci_add_capability(dev, PCI_CAP_ID_SSVID, offset, PCI_SSVID_SIZEOF); Error *local_err = NULL;
pos = pci_add_capability(dev, PCI_CAP_ID_SSVID, offset,
PCI_SSVID_SIZEOF, &local_err);
if (pos < 0) { if (pos < 0) {
error_report_err(local_err);
return pos; return pos;
} }

View File

@ -91,11 +91,14 @@ int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port)
/* PCIe cap v2 init */ /* PCIe cap v2 init */
int pos; int pos;
uint8_t *exp_cap; uint8_t *exp_cap;
Error *local_err = NULL;
assert(pci_is_express(dev)); assert(pci_is_express(dev));
pos = pci_add_capability(dev, PCI_CAP_ID_EXP, offset, PCI_EXP_VER2_SIZEOF); pos = pci_add_capability(dev, PCI_CAP_ID_EXP, offset,
PCI_EXP_VER2_SIZEOF, &local_err);
if (pos < 0) { if (pos < 0) {
error_report_err(local_err);
return pos; return pos;
} }
dev->exp.exp_cap = pos; dev->exp.exp_cap = pos;
@ -123,11 +126,14 @@ int pcie_cap_v1_init(PCIDevice *dev, uint8_t offset, uint8_t type,
{ {
/* PCIe cap v1 init */ /* PCIe cap v1 init */
int pos; int pos;
Error *local_err = NULL;
assert(pci_is_express(dev)); assert(pci_is_express(dev));
pos = pci_add_capability(dev, PCI_CAP_ID_EXP, offset, PCI_EXP_VER1_SIZEOF); pos = pci_add_capability(dev, PCI_CAP_ID_EXP, offset,
PCI_EXP_VER1_SIZEOF, &local_err);
if (pos < 0) { if (pos < 0) {
error_report_err(local_err);
return pos; return pos;
} }
dev->exp.exp_cap = pos; dev->exp.exp_cap = pos;

View File

@ -450,9 +450,12 @@ static int shpc_cap_add_config(PCIDevice *d)
{ {
uint8_t *config; uint8_t *config;
int config_offset; int config_offset;
Error *local_err = NULL;
config_offset = pci_add_capability(d, PCI_CAP_ID_SHPC, config_offset = pci_add_capability(d, PCI_CAP_ID_SHPC,
0, SHPC_CAP_LENGTH); 0, SHPC_CAP_LENGTH,
&local_err);
if (config_offset < 0) { if (config_offset < 0) {
error_report_err(local_err);
return config_offset; return config_offset;
} }
config = d->config + config_offset; config = d->config + config_offset;

View File

@ -2,6 +2,7 @@
#include "hw/pci/slotid_cap.h" #include "hw/pci/slotid_cap.h"
#include "hw/pci/pci.h" #include "hw/pci/pci.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "qapi/error.h"
#define SLOTID_CAP_LENGTH 4 #define SLOTID_CAP_LENGTH 4
#define SLOTID_NSLOTS_SHIFT ctz32(PCI_SID_ESR_NSLOTS) #define SLOTID_NSLOTS_SHIFT ctz32(PCI_SID_ESR_NSLOTS)
@ -11,6 +12,8 @@ int slotid_cap_init(PCIDevice *d, int nslots,
unsigned offset) unsigned offset)
{ {
int cap; int cap;
Error *local_err = NULL;
if (!chassis) { if (!chassis) {
error_report("Bridge chassis not specified. Each bridge is required " error_report("Bridge chassis not specified. Each bridge is required "
"to be assigned a unique chassis id > 0."); "to be assigned a unique chassis id > 0.");
@ -21,8 +24,10 @@ int slotid_cap_init(PCIDevice *d, int nslots,
return -EINVAL; return -EINVAL;
} }
cap = pci_add_capability(d, PCI_CAP_ID_SLOTID, offset, SLOTID_CAP_LENGTH); cap = pci_add_capability(d, PCI_CAP_ID_SLOTID, offset,
SLOTID_CAP_LENGTH, &local_err);
if (cap < 0) { if (cap < 0) {
error_report_err(local_err);
return cap; return cap;
} }
/* We make each chassis unique, this way each bridge is First in Chassis */ /* We make each chassis unique, this way each bridge is First in Chassis */

View File

@ -1743,11 +1743,14 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size,
PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS); PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS);
} }
pos = pci_add_capability(&vdev->pdev, PCI_CAP_ID_EXP, pos, size); pos = pci_add_capability(&vdev->pdev, PCI_CAP_ID_EXP, pos, size,
if (pos > 0) { errp);
vdev->pdev.exp.exp_cap = pos; if (pos < 0) {
return pos;
} }
vdev->pdev.exp.exp_cap = pos;
return pos; return pos;
} }

View File

@ -1162,8 +1162,8 @@ static int virtio_pci_add_mem_cap(VirtIOPCIProxy *proxy,
PCIDevice *dev = &proxy->pci_dev; PCIDevice *dev = &proxy->pci_dev;
int offset; int offset;
offset = pci_add_capability(dev, PCI_CAP_ID_VNDR, 0, cap->cap_len); offset = pci_add_capability(dev, PCI_CAP_ID_VNDR, 0,
assert(offset > 0); cap->cap_len, &error_abort);
assert(cap->cap_len >= sizeof *cap); assert(cap->cap_len >= sizeof *cap);
memcpy(dev->config + offset + PCI_CAP_FLAGS, &cap->cap_len, memcpy(dev->config + offset + PCI_CAP_FLAGS, &cap->cap_len,
@ -1810,8 +1810,12 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
pos = pcie_endpoint_cap_init(pci_dev, 0); pos = pcie_endpoint_cap_init(pci_dev, 0);
assert(pos > 0); assert(pos > 0);
pos = pci_add_capability(pci_dev, PCI_CAP_ID_PM, 0, PCI_PM_SIZEOF); pos = pci_add_capability(pci_dev, PCI_CAP_ID_PM, 0,
assert(pos > 0); PCI_PM_SIZEOF, errp);
if (pos < 0) {
return;
}
pci_dev->exp.pm_cap = pos; pci_dev->exp.pm_cap = pos;
/* /*

View File

@ -356,7 +356,8 @@ void pci_unregister_vga(PCIDevice *pci_dev);
pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num); pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
uint8_t offset, uint8_t size); uint8_t offset, uint8_t size,
Error **errp);
int pci_add_capability2(PCIDevice *pdev, uint8_t cap_id, int pci_add_capability2(PCIDevice *pdev, uint8_t cap_id,
uint8_t offset, uint8_t size, uint8_t offset, uint8_t size,
Error **errp); Error **errp);