[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] xl: implement pci attach to explicitly defined virtual PCI slot
# HG changeset patch # User Gianni Tedesco <gianni.tedesco@xxxxxxxxxx> # Date 1280929380 -3600 # Node ID 9c720d64160b5e98f3b44b37a23de630c96c085f # Parent b92dfdc284ddf1c5be14526cb74f5f5571f5eef1 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> Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> --- tools/libxl/libxl.h | 2 tools/libxl/libxl_pci.c | 166 +++++++++++++++++++++++++++++++++++++---------- tools/libxl/xl_cmdimpl.c | 6 - 3 files changed, 138 insertions(+), 36 deletions(-) diff -r b92dfdc284dd -r 9c720d64160b tools/libxl/libxl.h --- a/tools/libxl/libxl.h Wed Aug 04 14:24:43 2010 +0100 +++ b/tools/libxl/libxl.h Wed Aug 04 14:43:00 2010 +0100 @@ -521,7 +521,7 @@ int libxl_device_pci_shutdown(libxl_ctx 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 b92dfdc284dd -r 9c720d64160b tools/libxl/libxl_pci.c --- a/tools/libxl/libxl_pci.c Wed Aug 04 14:24:43 2010 +0100 +++ b/tools/libxl/libxl_pci.c Wed Aug 04 14:43: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) -{ - unsigned dom, bus, dev, func; - char *p, *buf2; - int rc; - - if ( NULL == (buf2 = strdup(str)) ) +static int hex_convert(const char *str, unsigned int *val, unsigned int mask) +{ + unsigned long ret; + char *end; + + 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; - } - } - - rc = pcidev_init(pcidev, dom, bus, dev, func, 0); - - 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: + 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; + } + } + 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 b92dfdc284dd -r 9c720d64160b tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Wed Aug 04 14:24:43 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Wed Aug 04 14:43:00 2010 +0100 @@ -965,7 +965,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++; } } @@ -1997,7 +1997,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); } @@ -2037,7 +2037,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-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |