aboutsummaryrefslogtreecommitdiffstats
path: root/xen/drivers/pci/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'xen/drivers/pci/pci.c')
-rw-r--r--xen/drivers/pci/pci.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/xen/drivers/pci/pci.c b/xen/drivers/pci/pci.c
index b6e388a4f1..25dc5f1486 100644
--- a/xen/drivers/pci/pci.c
+++ b/xen/drivers/pci/pci.c
@@ -4,6 +4,7 @@
* Architecture-independent PCI access functions.
*/
+#include <xen/init.h>
#include <xen/pci.h>
#include <xen/pci_regs.h>
@@ -102,3 +103,44 @@ int pci_find_ext_capability(int seg, int bus, int devfn, int cap)
}
return 0;
}
+
+const char *__init parse_pci(const char *s, unsigned int *seg_p,
+ unsigned int *bus_p, unsigned int *dev_p,
+ unsigned int *func_p)
+{
+ unsigned long seg = simple_strtoul(s, &s, 16), bus, dev, func;
+
+ if ( *s != ':' )
+ return NULL;
+ bus = simple_strtoul(s + 1, &s, 16);
+ if ( *s == ':' )
+ dev = simple_strtoul(s + 1, &s, 16);
+ else
+ {
+ dev = bus;
+ bus = seg;
+ seg = 0;
+ }
+ if ( func_p )
+ {
+ if ( *s != '.' )
+ return NULL;
+ func = simple_strtoul(s + 1, &s, 0);
+ }
+ else
+ func = 0;
+ if ( seg != (seg_p ? (u16)seg : 0) ||
+ bus != PCI_BUS(PCI_BDF2(bus, 0)) ||
+ dev != PCI_SLOT(PCI_DEVFN(dev, 0)) ||
+ func != PCI_FUNC(PCI_DEVFN(0, func)) )
+ return NULL;
+
+ if ( seg_p )
+ *seg_p = seg;
+ *bus_p = bus;
+ *dev_p = dev;
+ if ( func_p )
+ *func_p = func;
+
+ return s;
+}