WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 4 of 6] xl: implement pci attach to explicitly define

To: Xen Devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 4 of 6] xl: implement pci attach to explicitly defined virtual PCI slot
From: Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
Date: Mon, 2 Aug 2010 15:58:46 +0100
Cc: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>, Stefano Stabellini <Stefano.Stabellini@xxxxxxxxxxxxx>
Delivery-date: Mon, 02 Aug 2010 08:05:59 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1280761122@xxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1280761122@xxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.4.3
 tools/libxl/libxl.h      |    2 +-
 tools/libxl/libxl_pci.c  |  156 ++++++++++++++++++++++++++++++++++++++--------
 tools/libxl/xl_cmdimpl.c |    6 +-
 3 files changed, 133 insertions(+), 31 deletions(-)


# HG changeset patch
# User Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
# Date 1280760240 -3600
# Branch pci-patches-v3
# Node ID 4aea113e2ce2a46c908e62cace4bf9a710ae7c51
# Parent  a993021324d0c7d23a16290b7a722c2878506c2e
xl: implement pci attach to explicitly defined virtual PCI slot

Move to state-machine parser for PCI BDF's now that the number of possible
sscanf expressions is sufficiently large to make it worth it. Also implement
parsing of virtual PCI slot numbers.

Signed-off-by: Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>

diff -r a993021324d0 -r 4aea113e2ce2 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Mon Aug 02 15:41:41 2010 +0100
+++ b/tools/libxl/libxl.h       Mon Aug 02 15:44:00 2010 +0100
@@ -521,7 +521,7 @@ int libxl_device_pci_remove(libxl_ctx *c
 int libxl_device_pci_shutdown(libxl_ctx *ctx, uint32_t domid);
 int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, 
uint32_t domid, int *num);
 int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, 
int *num);
-int libxl_device_pci_parse_bdf(libxl_device_pci *pcidev, const char *str);
+int libxl_device_pci_parse_bdf(libxl_ctx *ctx, libxl_device_pci *pcidev, const 
char *str);
 
 /*
  * Functions for allowing users of libxl to store private data
diff -r a993021324d0 -r 4aea113e2ce2 tools/libxl/libxl_pci.c
--- a/tools/libxl/libxl_pci.c   Mon Aug 02 15:41:41 2010 +0100
+++ b/tools/libxl/libxl_pci.c   Mon Aug 02 15:44:00 2010 +0100
@@ -52,41 +52,143 @@ static int pcidev_init(libxl_device_pci 
     return 0;
 }
 
-int libxl_device_pci_parse_bdf(libxl_device_pci *pcidev, const char *str)
+static int hex_convert(const char *str, unsigned int *val, unsigned int mask)
 {
-    unsigned dom, bus, dev, func;
-    char *p, *buf2;
-    int rc;
+    unsigned long ret;
+    char *end;
 
-    if ( NULL == (buf2 = strdup(str)) )
+    ret = strtoul(str, &end, 16);
+    if ( end == str || *end != '\0' )
+        return -1;
+    if ( ret & ~mask )
+        return -1;
+    *val = (unsigned int)ret & mask;
+    return 0;
+}
+
+#define STATE_DOMAIN    0
+#define STATE_BUS       1
+#define STATE_DEV       2
+#define STATE_FUNC      3
+#define STATE_VSLOT     4
+#define STATE_OPTIONS_K 6
+#define STATE_OPTIONS_V 7
+#define STATE_TERMINAL  8
+int libxl_device_pci_parse_bdf(libxl_ctx *ctx, libxl_device_pci *pcidev, const 
char *str)
+{
+    unsigned state = STATE_DOMAIN;
+    unsigned dom, bus, dev, func, vslot = 0;
+    char *buf2, *tok, *ptr, *end, *optkey = NULL;
+
+    if ( NULL == (buf2 = ptr = strdup(str)) )
         return ERROR_NOMEM;
 
-    p = strtok(buf2, ",");
-
-    if ( sscanf(str, PCI_BDF, &dom, &bus, &dev, &func) != 4 ) {
-        dom = 0;
-        if ( sscanf(str, PCI_BDF_SHORT, &bus, &dev, &func) != 3 ) {
-            rc = ERROR_FAIL;
-            goto out;
+    for(tok = ptr, end = ptr + strlen(ptr) + 1; ptr < end; ptr++) {
+        switch(state) {
+        case STATE_DOMAIN:
+            if ( *ptr == ':' ) {
+                state = STATE_BUS;
+                *ptr = '\0';
+                if ( hex_convert(tok, &dom, 0xffff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_BUS:
+            if ( *ptr == ':' ) {
+                state = STATE_DEV;
+                *ptr = '\0';
+                if ( hex_convert(tok, &bus, 0xff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }else if ( *ptr == '.' ) {
+                state = STATE_FUNC;
+                *ptr = '\0';
+                if ( dom & ~0xff )
+                    goto parse_error;
+                bus = dom;
+                dom = 0;
+                if ( hex_convert(tok, &dev, 0xff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_DEV:
+            if ( *ptr == '.' ) {
+                state = STATE_FUNC;
+                *ptr = '\0';
+                if ( hex_convert(tok, &dev, 0xff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_FUNC:
+            if ( *ptr == '\0' || *ptr == '@' || *ptr == ',' ) {
+                switch( *ptr ) {
+                case '\0':
+                    state = STATE_TERMINAL;
+                    break;
+                case '@':
+                    state = STATE_VSLOT;
+                    break;
+                case ',':
+                    state = STATE_OPTIONS_K;
+                    break;
+                }
+                *ptr = '\0';
+                if ( hex_convert(tok, &func, 0x7) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_VSLOT:
+            if ( *ptr == '\0' || *ptr == ',' ) {
+                state = ( *ptr == ',' ) ? STATE_OPTIONS_K : STATE_TERMINAL;
+                *ptr = '\0';
+                if ( hex_convert(tok, &vslot, 0xff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_OPTIONS_K:
+            if ( *ptr == '=' ) {
+                state = STATE_OPTIONS_V;
+                *ptr = '\0';
+                optkey = tok;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_OPTIONS_V:
+            if ( *ptr == ',' || *ptr == '\0' ) {
+                state = (*ptr == ',') ? STATE_OPTIONS_K : STATE_TERMINAL;
+                *ptr = '\0';
+                if ( !strcmp(optkey, "msitranslate") ) {
+                    pcidev->msitranslate = atoi(tok);
+                }else if ( !strcmp(optkey, "power_mgmt") ) {
+                    pcidev->power_mgmt = atoi(tok);
+                }else{
+                    XL_LOG(ctx, XL_LOG_WARNING,
+                           "Unknown PCI BDF option: %s", optkey);
+                }
+                tok = ptr + 1;
+            }
+        default:
+            break;
         }
     }
 
-    rc = pcidev_init(pcidev, dom, bus, dev, func, 0);
+    free(buf2);
 
-    while ((p = strtok(NULL, ",=")) != NULL) {
-        while (*p == ' ')
-            p++;
-        if (!strcmp(p, "msitranslate")) {
-            p = strtok(NULL, ",=");
-            pcidev->msitranslate = atoi(p);
-        } else if (!strcmp(p, "power_mgmt")) {
-            p = strtok(NULL, ",=");
-            pcidev->power_mgmt = atoi(p);
-        }
-    }
-out:
-    free(buf2);
-    return rc;
+    if ( tok != ptr || state != STATE_TERMINAL )
+        goto parse_error;
+
+    pcidev_init(pcidev, dom, bus, dev, func, vslot << 3);
+
+    return 0;
+
+parse_error:
+    printf("parse error: %s\n", str);
+    return ERROR_INVAL;
 }
 
 static int libxl_create_pci_backend(libxl_ctx *ctx, uint32_t domid, 
libxl_device_pci *pcidev, int num)
diff -r a993021324d0 -r 4aea113e2ce2 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c  Mon Aug 02 15:41:41 2010 +0100
+++ b/tools/libxl/xl_cmdimpl.c  Mon Aug 02 15:44:00 2010 +0100
@@ -955,7 +955,7 @@ skip_vfb:
 
             pcidev->msitranslate = pci_msitranslate;
             pcidev->power_mgmt = pci_power_mgmt;
-            if (!libxl_device_pci_parse_bdf(pcidev, buf))
+            if (!libxl_device_pci_parse_bdf(&ctx, pcidev, buf))
                 d_config->num_pcidevs++;
         }
     }
@@ -1979,7 +1979,7 @@ void pcidetach(char *dom, char *bdf)
     find_domain(dom);
 
     memset(&pcidev, 0x00, sizeof(pcidev));
-    if (libxl_device_pci_parse_bdf(&pcidev, bdf)) {
+    if (libxl_device_pci_parse_bdf(&ctx, &pcidev, bdf)) {
         fprintf(stderr, "pci-detach: malformed BDF specification \"%s\"\n", 
bdf);
         exit(2);
     }
@@ -2019,7 +2019,7 @@ void pciattach(char *dom, char *bdf, cha
     find_domain(dom);
 
     memset(&pcidev, 0x00, sizeof(pcidev));
-    if (libxl_device_pci_parse_bdf(&pcidev, bdf)) {
+    if (libxl_device_pci_parse_bdf(&ctx, &pcidev, bdf)) {
         fprintf(stderr, "pci-attach: malformed BDF specification \"%s\"\n", 
bdf);
         exit(2);
     }

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel