From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=38729 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PHu5o-0006Cd-Dc for qemu-devel@nongnu.org; Mon, 15 Nov 2010 03:07:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PHu5k-0000lu-4a for qemu-devel@nongnu.org; Mon, 15 Nov 2010 03:07:12 -0500 Received: from mx1.redhat.com ([209.132.183.28]:11851) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PHu5j-0000lq-Q4 for qemu-devel@nongnu.org; Mon, 15 Nov 2010 03:07:08 -0500 Date: Mon, 15 Nov 2010 10:06:13 +0200 From: "Michael S. Tsirkin" Message-ID: <20101115080613.GE22248@redhat.com> References: <3404152716bc65ee54b1c906b2435089a6200092.1289805831.git.yamahata@valinux.co.jp> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <3404152716bc65ee54b1c906b2435089a6200092.1289805831.git.yamahata@valinux.co.jp> Subject: [Qemu-devel] Re: [PATCH v8 07/11] pci: introduce a parser for pci device path List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Isaku Yamahata Cc: skandasa@cisco.com, adnan@khaleel.us, wexu2@cisco.com, gleb@redhat.com, qemu-devel@nongnu.org, etmartin@cisco.com 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 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 [[:]:], return -1 on error if funcp == NULL > * [[:]:]., 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