aboutsummaryrefslogtreecommitdiffstats
path: root/xen/drivers
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2013-08-28 10:12:36 +0200
committerJan Beulich <jbeulich@suse.com>2013-08-28 10:12:36 +0200
commitaa4b2aea4fa300341668971e50fbfd16b1ed925d (patch)
tree58cc54354404464bc163272fbc696ce858c06b36 /xen/drivers
parentdcbff3aeac6020cdf1f5bd0f0eb0d329fc55d939 (diff)
downloadxen-aa4b2aea4fa300341668971e50fbfd16b1ed925d.tar.gz
xen-aa4b2aea4fa300341668971e50fbfd16b1ed925d.tar.bz2
xen-aa4b2aea4fa300341668971e50fbfd16b1ed925d.zip
PCI: centralize parsing of device coordinates in command line options
With yet another case to come in a subsequent patch, it seems time to do this in a single place rather than hand crafting it in various scattered around locations. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/drivers')
-rw-r--r--xen/drivers/char/ehci-dbgp.c24
-rw-r--r--xen/drivers/char/ns16550.c22
-rw-r--r--xen/drivers/passthrough/pci.c21
-rw-r--r--xen/drivers/pci/pci.c42
4 files changed, 64 insertions, 45 deletions
diff --git a/xen/drivers/char/ehci-dbgp.c b/xen/drivers/char/ehci-dbgp.c
index 6b7066081d..bead374bc8 100644
--- a/xen/drivers/char/ehci-dbgp.c
+++ b/xen/drivers/char/ehci-dbgp.c
@@ -1482,31 +1482,25 @@ void __init ehci_dbgp_init(void)
}
else if ( strncmp(opt_dbgp + 4, "@pci", 4) == 0 )
{
- unsigned long val = simple_strtoul(opt_dbgp + 8, &e, 16);
+ unsigned int bus, slot, func;
- dbgp->bus = val;
- if ( dbgp->bus != val || *e != ':' )
+ e = parse_pci(opt_dbgp + 8, NULL, &bus, &slot, &func);
+ if ( !e || *e )
return;
- val = simple_strtoul(e + 1, &e, 16);
- if ( PCI_SLOT(PCI_DEVFN(val, 0)) != val || *e != '.' )
- return;
- dbgp->slot = val;
-
- val = simple_strtoul(e + 1, &e, 16);
- if ( PCI_FUNC(PCI_DEVFN(0, val)) != val || *e )
- return;
- dbgp->func = val;
+ dbgp->bus = bus;
+ dbgp->slot = slot;
+ dbgp->func = func;
- if ( !pci_device_detect(0, dbgp->bus, dbgp->slot, dbgp->func) )
+ if ( !pci_device_detect(0, bus, slot, func) )
return;
- dbgp->cap = __find_dbgp(dbgp->bus, dbgp->slot, dbgp->func);
+ dbgp->cap = __find_dbgp(bus, slot, func);
if ( !dbgp->cap )
return;
dbgp_printk("Using EHCI debug port on %02x:%02x.%u\n",
- dbgp->bus, dbgp->slot, dbgp->func);
+ bus, slot, func);
}
else
return;
diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 6082c85434..7cbe5fd50c 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -403,19 +403,6 @@ static int __init parse_parity_char(int c)
return 0;
}
-static void __init parse_pci_bdf(const char **conf, unsigned int bdf[3])
-{
- bdf[0] = simple_strtoul(*conf, conf, 16);
- if ( **conf != ':' )
- return;
- (*conf)++;
- bdf[1] = simple_strtoul(*conf, conf, 16);
- if ( **conf != '.' )
- return;
- (*conf)++;
- bdf[2] = simple_strtoul(*conf, conf, 16);
-}
-
static int __init check_existence(struct ns16550 *uart)
{
unsigned char status, scratch, scratch2, scratch3;
@@ -593,14 +580,19 @@ static void __init ns16550_parse_port_config(
if ( *conf == ',' && *++conf != ',' )
{
+ conf = parse_pci(conf, NULL, &uart->ps_bdf[0],
+ &uart->ps_bdf[1], &uart->ps_bdf[2]);
+ if ( !conf )
+ PARSE_ERR("Bad port PCI coordinates");
uart->ps_bdf_enable = 1;
- parse_pci_bdf(&conf, &uart->ps_bdf[0]);
}
if ( *conf == ',' && *++conf != ',' )
{
+ if ( !parse_pci(conf, NULL, &uart->pb_bdf[0],
+ &uart->pb_bdf[1], &uart->pb_bdf[2]) )
+ PARSE_ERR("Bad bridge PCI coordinates");
uart->pb_bdf_enable = 1;
- parse_pci_bdf(&conf, &uart->pb_bdf[0]);
}
config_parsed:
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index b488e2ae18..e9f2a56dbc 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -127,29 +127,20 @@ static unsigned int nr_phantom_devs;
static void __init parse_phantom_dev(char *str) {
const char *s = str;
+ unsigned int seg, bus, slot;
struct phantom_dev phantom;
if ( !s || !*s || nr_phantom_devs >= ARRAY_SIZE(phantom_devs) )
return;
- phantom.seg = simple_strtol(s, &s, 16);
- if ( *s != ':' )
+ s = parse_pci(s, &seg, &bus, &slot, NULL);
+ if ( !s || *s != ',' )
return;
- phantom.bus = simple_strtol(s + 1, &s, 16);
- if ( *s == ',' )
- {
- phantom.slot = phantom.bus;
- phantom.bus = phantom.seg;
- phantom.seg = 0;
- }
- else if ( *s == ':' )
- phantom.slot = simple_strtol(s + 1, &s, 16);
- else
- return;
+ phantom.seg = seg;
+ phantom.bus = bus;
+ phantom.slot = slot;
- if ( *s != ',' )
- return;
switch ( phantom.stride = simple_strtol(s + 1, &s, 0) )
{
case 1: case 2: case 4:
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;
+}