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

[Xen-devel] [PATCH RFC 1/2] 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@xxxxxxxx>

--- 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;
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -403,19 +403,6 @@ static int __init parse_parity_char(int 
     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_co
 
     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:
--- 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:
--- 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
     }
     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;
+}
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -139,6 +139,8 @@ int pci_mmcfg_write(unsigned int seg, un
 int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap);
 int pci_find_next_cap(u16 seg, u8 bus, unsigned int devfn, u8 pos, int cap);
 int pci_find_ext_capability(int seg, int bus, int devfn, int cap);
+const char *parse_pci(const char *, unsigned int *seg, unsigned int *bus,
+                      unsigned int *dev, unsigned int *func);
 
 struct pirq;
 int msixtbl_pt_register(struct domain *, struct pirq *, uint64_t gtable);


Attachment: PCI-parse.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.