qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Re: [PATCH v8 07/11] pci: introduce a parser for pci device


From: Michael S. Tsirkin
Subject: [Qemu-devel] Re: [PATCH v8 07/11] pci: introduce a parser for pci device path
Date: Mon, 15 Nov 2010 10:06:13 +0200
User-agent: Mutt/1.5.21 (2010-09-15)

On Mon, Nov 15, 2010 at 04:30:43PM +0900, Isaku Yamahata wrote:
> introduce a function to parse pci device path of
> the format, [Domain:]Slot.Function:Slot.Function....:Slot.Function.
> 
> Signed-off-by: Isaku Yamahata <address@hidden>

Hmm.
How about we use openfirmware path like what Gleb's patch does,
with a fallback to bus:dev.fn for when it's unambiguous?

> ---
>  hw/pci.c |   87 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  hw/pci.h |    1 +
>  2 files changed, 88 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/pci.c b/hw/pci.c
> index fba765b..6a9a5ef 100644
> --- a/hw/pci.c
> +++ b/hw/pci.c
> @@ -433,6 +433,93 @@ static void pci_set_default_subsystem_id(PCIDevice 
> *pci_dev)
>  }
>  
>  /*
> + * Parse format [Domain:]Slot.Function:Slot.Function....:Slot.Function
> + * and get PCIDevice
> + * return 0 on success
> + *       -1 on error: format is invalid or device isn't found.
> + */
> +int pci_parse_dev_path(const char *addr, PCIDevice **pdev)
> +{
> +    unsigned long domain;
> +    unsigned long slot;
> +    unsigned long func;
> +    const char *p;
> +    char *e;
> +    unsigned long val;
> +    PCIBus *bus;
> +    PCIBus *child_bus;
> +    PCIDevice *d;
> +
> +    p = addr;
> +    val = strtoul(p, &e, 0);
> +    if (e == p) {
> +        return -1;
> +    }
> +    if (*e == ':') {
> +        domain = val;
> +        p = e + 1;
> +        val = strtoul(p, &e, 0);
> +        if (e == p) {
> +            return -1;
> +        }
> +    } else if (*e == '.'){
> +        domain = 0;
> +    } else {
> +        return -1;
> +    }
> +    if (domain > 0xffff) {
> +        return -1;
> +    }
> +
> +    bus = pci_find_root_bus(domain);
> +    if (!bus) {
> +        return -1;
> +    }
> +
> +    for (;;) {
> +        slot = val;
> +        if (*e != '.') {
> +            return -1;
> +        }
> +        p = e + 1;
> +        val = strtoul(p, &e, 0);
> +        if (e == p) {
> +            return -1;
> +        }
> +        func = val;
> +        if (slot > 0x1f || func >= PCI_FUNC_MAX) {
> +            return -1;
> +        }
> +        d = bus->devices[PCI_DEVFN(slot, func)];
> +        if (!d) {
> +            return -1;
> +        }
> +        if (*e == '\0') {
> +            break;
> +        }
> +
> +        if (*e != ':') {
> +            return -1;
> +        }
> +        p = e + 1;
> +        val = strtoul(p, &e, 0);
> +        if (e == p) {
> +            return -1;
> +        }
> +        QLIST_FOREACH(child_bus, &bus->child, sibling) {
> +            if (child_bus->parent_dev == d) {
> +                bus = child_bus;
> +                continue;
> +            }
> +        }
> +        return -1;
> +    }
> +
> +    *pdev = d;
> +    return 0;
> +}
> +
> +/*
>   * Parse [[<domain>:]<bus>:]<slot>, return -1 on error if funcp == NULL
>   *       [[<domain>:]<bus>:]<slot>.<func>, return -1 on error
>   */
> diff --git a/hw/pci.h b/hw/pci.h
> index 7100804..8c16f91 100644
> --- a/hw/pci.h
> +++ b/hw/pci.h
> @@ -239,6 +239,7 @@ PCIBus *pci_find_bus(PCIBus *bus, int bus_num);
>  PCIDevice *pci_find_device(PCIBus *bus, int bus_num, int slot, int function);
>  PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr);
>  
> +int pci_parse_dev_path(const char *addr, PCIDevice **pdev);
>  int pci_parse_devaddr(const char *addr, int *domp, int *busp,
>                        unsigned int *slotp, unsigned int *funcp);
>  int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
> -- 
> 1.7.1.1



reply via email to

[Prev in Thread] Current Thread [Next in Thread]