Parse full PCI device addresses (Markus Armbruster)

This code parses full PCI device addresses.  It then rejects domains
other than zero, because these are not supported in QEMU.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6609 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
aliguori 2009-02-11 15:21:48 +00:00
parent ca2c72be18
commit 880345c484
2 changed files with 80 additions and 0 deletions

View File

@ -26,6 +26,7 @@
#include "console.h" #include "console.h"
#include "net.h" #include "net.h"
#include "virtio-net.h" #include "virtio-net.h"
#include "sysemu.h"
//#define DEBUG_PCI //#define DEBUG_PCI
@ -158,6 +159,82 @@ static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
return 0; return 0;
} }
/*
* Parse [[<domain>:]<bus>:]<slot>, return -1 on error
*/
static int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
{
const char *p;
char *e;
unsigned long val;
unsigned long dom = 0, bus = 0;
unsigned slot = 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 == ':') {
dom = bus;
bus = val;
p = e + 1;
val = strtoul(p, &e, 16);
if (e == p)
return -1;
}
}
if (dom > 0xffff || bus > 0xff || val > 0x1f)
return -1;
slot = val;
if (*e)
return -1;
/* Note: QEMU doesn't implement domains other than 0 */
if (dom != 0 || pci_find_bus(bus) == NULL)
return -1;
*domp = dom;
*busp = bus;
*slotp = slot;
return 0;
}
int pci_read_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
{
char devaddr[32];
if (!get_param_value(devaddr, sizeof(devaddr), "pci_addr", addr))
return -1;
return pci_parse_devaddr(devaddr, domp, busp, slotp);
}
int pci_assign_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
{
char devaddr[32];
if (!get_param_value(devaddr, sizeof(devaddr), "pci_addr", addr))
return -1;
if (!strcmp(devaddr, "auto")) {
*domp = *busp = 0;
*slotp = -1;
/* want to support dom/bus auto-assign at some point */
return 0;
}
return pci_parse_devaddr(devaddr, domp, busp, slotp);
}
/* -1 for devfn means auto assign */ /* -1 for devfn means auto assign */
PCIDevice *pci_register_device(PCIBus *bus, const char *name, PCIDevice *pci_register_device(PCIBus *bus, const char *name,
int instance_size, int devfn, int instance_size, int devfn,

View File

@ -232,6 +232,9 @@ void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
PCIBus *pci_find_bus(int bus_num); PCIBus *pci_find_bus(int bus_num);
PCIDevice *pci_find_device(int bus_num, int slot, int function); 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);
void pci_info(void); void pci_info(void);
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did, PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
pci_map_irq_fn map_irq, const char *name); pci_map_irq_fn map_irq, const char *name);