@@ -41,7 +41,7 @@ static int read_pci_devaddr(Monitor *mon, const char *addrstr,
if (!strncmp(addrstr, "pci_addr=", 9)) {
addrstr += 9;
}
- if (qemu_parse_pci_devaddr(addrstr, addr, 0)) {
+ if (qemu_parse_pci_devaddr(addrstr, addr, PCI_DEVADDR_WITH_DOM_BUS_OPT)) {
monitor_printf(mon, "Invalid pci address\n");
return -1;
}
@@ -517,7 +517,8 @@ PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr)
return pci_find_bus_nr(pci_find_root_bus(0), 0);
}
- if (qemu_parse_pci_devaddr(devaddr, &addr, 0) < 0) {
+ if (qemu_parse_pci_devaddr(devaddr, &addr,
+ PCI_DEVADDR_WITH_DOM_BUS_OPT) < 0) {
return NULL;
}
@@ -817,8 +817,11 @@ PropertyInfo qdev_prop_losttickpolicy = {
/* --- pci address --- */
/*
- * Parse [[<domain>:]<bus>:]<slot>, return -1 on error if !PCI_DEVADDR_WITH_FUNC
- * [[<domain>:]<bus>:]<slot>.<func>, return -1 on error
+ * Parse
+ * [[<domain>:]<bus>:]<slot>... if PCI_DEVADDR_WITH_DOM_BUS_OPT
+ * ...<slot>.<func> if PCI_DEVADDR_WITH_FUNC
+ * ...<slot>[.<func>] if PCI_DEVADDR_WITH_FUNC_OPT
+ * return -1 on error
*/
int qemu_parse_pci_devaddr(const char *addrstr, PCIDeviceAddress *addr,
unsigned int flags)
@@ -836,6 +839,9 @@ int qemu_parse_pci_devaddr(const char *addrstr, PCIDeviceAddress *addr,
return -1;
}
if (*e == ':') {
+ if (!(flags & PCI_DEVADDR_WITH_DOM_BUS_OPT)) {
+ return -1;
+ }
bus = val;
p = e + 1;
val = strtoul(p, &e, 16);
@@ -855,16 +861,19 @@ int qemu_parse_pci_devaddr(const char *addrstr, PCIDeviceAddress *addr,
slot = val;
- if (flags & PCI_DEVADDR_WITH_FUNC) {
+ if (flags & (PCI_DEVADDR_WITH_FUNC | PCI_DEVADDR_WITH_FUNC_OPT)) {
if (*e != '.') {
- return -1;
- }
- p = e + 1;
- val = strtoul(p, &e, 16);
- if (e == p) {
- return -1;
+ if (flags & PCI_DEVADDR_WITH_FUNC) {
+ return -1;
+ }
+ } else {
+ p = e + 1;
+ val = strtoul(p, &e, 16);
+ if (e == p) {
+ return -1;
+ }
+ func = val;
}
- func = val;
}
if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
@@ -890,7 +899,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
- unsigned int slot, fn, n;
+ PCIDeviceAddress addr;
Error *local_err = NULL;
char *str;
@@ -905,21 +914,11 @@ static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
return set_int32(obj, v, opaque, name, errp);
}
- if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
- fn = 0;
- if (sscanf(str, "%x%n", &slot, &n) != 1) {
- goto invalid;
- }
- }
- if (str[n] != '\0' || fn > 7 || slot > 31) {
- goto invalid;
+ if (qemu_parse_pci_devaddr(str, &addr, PCI_DEVADDR_WITH_FUNC_OPT) < 0) {
+ error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+ } else {
+ *ptr = addr.slot << 3 | addr.function;
}
- *ptr = slot << 3 | fn;
- g_free(str);
- return;
-
-invalid:
- error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
g_free(str);
}
@@ -360,7 +360,9 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus);
extern int qdev_hotplug;
+#define PCI_DEVADDR_WITH_DOM_BUS_OPT 1
#define PCI_DEVADDR_WITH_FUNC 2
+#define PCI_DEVADDR_WITH_FUNC_OPT 4
int qemu_parse_pci_devaddr(const char *addrstr, PCIDeviceAddress *addr,
unsigned int flags);
Generalize qemu_parse_pci_devaddr by two flags so that it can be used for parsing pci-devfn properties as well. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> --- hw/pci-hotplug.c | 2 +- hw/pci.c | 3 ++- hw/qdev-properties.c | 49 ++++++++++++++++++++++++------------------------- hw/qdev.h | 2 ++ 4 files changed, 29 insertions(+), 27 deletions(-)