From c13df76703ed1fb63c2ddba0a5de51b8a6fce4bf Mon Sep 17 00:00:00 2001 From: "Han, Weidong" Date: Mon, 30 Mar 2009 20:41:47 +0800 Subject: [PATCH] Improve pci host device address parsing pci_parse_devaddr parses [[:][:], it's valid when even enter only slot, whereas it must be bus:slot.func in device assignment command (-pcidevice host=bus:slot.func). So I implemented a dedicated function to parse device bdf in device assignment command, rather than mix two parsing function together. Signed-off-by: Weidong Han Signed-off-by: Avi Kivity --- hw/device-assignment.c | 22 ++++++++-------------- hw/pci.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ hw/pci.h | 3 +++ 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/hw/device-assignment.c b/hw/device-assignment.c index b7f9fa6b90..09e54ae33f 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -1190,8 +1190,7 @@ out: */ AssignedDevInfo *add_assigned_device(const char *arg) { - char *cp, *cp1; - char device[8]; + char device[16]; char dma[6]; int r; AssignedDevInfo *adev; @@ -1202,6 +1201,13 @@ AssignedDevInfo *add_assigned_device(const char *arg) return NULL; } r = get_param_value(device, sizeof(device), "host", arg); + if (!r) + goto bad; + + r = pci_parse_host_devaddr(device, &adev->bus, &adev->dev, &adev->func); + if (r) + goto bad; + r = get_param_value(adev->name, sizeof(adev->name), "name", arg); if (!r) snprintf(adev->name, sizeof(adev->name), "%s", device); @@ -1211,18 +1217,6 @@ AssignedDevInfo *add_assigned_device(const char *arg) if (r && !strncmp(dma, "none", 4)) adev->disable_iommu = 1; #endif - cp = device; - adev->bus = strtoul(cp, &cp1, 16); - if (*cp1 != ':') - goto bad; - cp = cp1 + 1; - - adev->dev = strtoul(cp, &cp1, 16); - if (*cp1 != '.') - goto bad; - cp = cp1 + 1; - - adev->func = strtoul(cp, &cp1, 16); LIST_INSERT_HEAD(&adev_head, adev, next); return adev; diff --git a/hw/pci.c b/hw/pci.c index eca0517ab1..bf97c8cd09 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -163,6 +163,7 @@ static int pci_set_default_subsystem_id(PCIDevice *pci_dev) } /* + * Parse pci address in qemu command * Parse [[:]:], return -1 on error */ static int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp) @@ -211,6 +212,55 @@ static int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned *s return 0; } +/* + * Parse device bdf in device assignment command: + * + * -pcidevice host=bus:dev.func + * + * Parse :. return -1 on error + */ +int pci_parse_host_devaddr(const char *addr, int *busp, + int *slotp, int *funcp) +{ + const char *p; + char *e; + int val; + int bus = 0, slot = 0, func = 0; + + p = addr; + val = strtoul(p, &e, 16); + if (e == p) + return -1; + if (*e == ':') { + bus = val; + p = e + 1; + val = strtoul(p, &e, 16); + if (e == p) + return -1; + if (*e == '.') { + slot = val; + p = e + 1; + val = strtoul(p, &e, 16); + if (e == p) + return -1; + func = val; + } else + return -1; + } else + return -1; + + if (bus > 0xff || slot > 0x1f || func > 0x7) + return -1; + + if (*e) + return -1; + + *busp = bus; + *slotp = slot; + *funcp = func; + return 0; +} + int pci_read_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp) { char devaddr[32]; diff --git a/hw/pci.h b/hw/pci.h index ea0bec8910..890a41b18d 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -234,6 +234,9 @@ PCIDevice *pci_find_device(int bus_num, int slot, int function); int pci_read_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp); int pci_assign_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp); +int pci_parse_host_devaddr(const char *addr, int *busp, + int *slotp, int *funcp); + void pci_info(Monitor *mon); PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did, pci_map_irq_fn map_irq, const char *name); -- 2.11.4.GIT