[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH V3 6/6] refactor codes to unify pvusb and qemu emulated usb
Now we have pvusb implementation. To merge with future qemu emulated usb work, refactor codes: - define 'protocol' (type) to indicate pvusb or qemu, add 'protocol' to usb controller and usb device structures, add 'type' to xl interface usb-attach|detach. - extract common codes for both qemu and pvusb from libxl_pvusb.c to libxl_usb.c, and adjust libxl_pvusb.c codes accordingly. Signed-off-by: Chunyan Liu <cyliu@xxxxxxxx> --- tools/libxl/Makefile | 2 +- tools/libxl/libxl_internal.h | 4 + tools/libxl/libxl_pvusb.c | 169 +------------------------------- tools/libxl/libxl_types.idl | 11 +++ tools/libxl/libxl_usb.c | 224 +++++++++++++++++++++++++++++++++++++++++++ tools/libxl/xl_cmdimpl.c | 54 +++++++++-- tools/libxl/xl_cmdtable.c | 4 +- 7 files changed, 293 insertions(+), 175 deletions(-) create mode 100644 tools/libxl/libxl_usb.c diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile index d52281f..f786fcf 100644 --- a/tools/libxl/Makefile +++ b/tools/libxl/Makefile @@ -95,7 +95,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \ libxl_internal.o libxl_utils.o libxl_uuid.o \ libxl_json.o libxl_aoutils.o libxl_numa.o libxl_vnuma.o \ libxl_save_callout.o _libxl_save_msgs_callout.o \ - libxl_qmp.o libxl_event.o libxl_fork.o libxl_pvusb.o $(LIBXL_OBJS-y) + libxl_qmp.o libxl_event.o libxl_fork.o libxl_pvusb.o libxl_usb.o $(LIBXL_OBJS-y) LIBXL_OBJS += libxl_genid.o LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index f426ed8..2ee058b 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -2428,6 +2428,10 @@ _hidden int libxl__device_usbctrl_add(libxl__gc *gc, uint32_t domid, _hidden int libxl__device_usb_add(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb); _hidden int libxl__device_usb_destroy_all(libxl__gc *gc, uint32_t domid); +_hidden bool pv_is_usb_assigned(libxl__gc *gc, libxl_device_usb *usb); +_hidden int pv_usb_add(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb); +_hidden int pv_usb_remove(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb); +_hidden int pv_usb_destroy_all(libxl__gc *gc, uint32_t domid); /* Internal function to connect a vkb device */ _hidden int libxl__device_vkb_add(libxl__gc *gc, uint32_t domid, diff --git a/tools/libxl/libxl_pvusb.c b/tools/libxl/libxl_pvusb.c index 4e4975a..3dfd2bd 100644 --- a/tools/libxl/libxl_pvusb.c +++ b/tools/libxl/libxl_pvusb.c @@ -16,8 +16,6 @@ #define USBBACK_INFO_PATH "/libxl/usbback" -#define USBHUB_CLASS_CODE 0x09 - static int libxl__device_usbctrl_setdefault(libxl__gc *gc, uint32_t domid, libxl_device_usbctrl *usbctrl) { @@ -338,6 +336,7 @@ int libxl_device_usbctrl_getinfo(libxl_ctx *ctx, uint32_t domid, usbctrlinfo->devid = usbctrl->devid; usbctrlinfo->ports = usbctrl->ports; usbctrlinfo->version = usbctrl->version; + usbctrlinfo->protocol = usbctrl->protocol; dompath = libxl__xs_get_dompath(gc, domid); usbctrlpath = GCSPRINTF("%s/device/vusb/%d", dompath, usbctrlinfo->devid); @@ -451,7 +450,7 @@ static bool is_usb_in_array(libxl_device_usb *usbs, int num, } /* check if USB device is already assigned to a domain */ -static bool is_usb_assigned(libxl__gc *gc, libxl_device_usb *usb) +bool pv_is_usb_assigned(libxl__gc *gc, libxl_device_usb *usb) { libxl_device_usb *usbs; int rc, num; @@ -468,27 +467,6 @@ static bool is_usb_assigned(libxl__gc *gc, libxl_device_usb *usb) return false; } -/* check if USB device type is assignable */ -static bool is_usb_assignable(libxl__gc *gc, libxl_device_usb *usb) -{ - libxl_ctx *ctx = libxl__gc_owner(gc); - int classcode; - char *filename; - void *buf; - - assert(usb->busid); - - filename = GCSPRINTF(SYSFS_USB_DEV"/%s/bDeviceClass", usb->busid); - if (libxl_read_file_contents(ctx, filename, &buf, NULL) < 0) - return false; - - sscanf(buf, "%x", &classcode); - if (classcode == USBHUB_CLASS_CODE) - return false; - - return true; -} - /* get usb devices under certain usb controller */ static int libxl__device_usb_list(libxl__gc *gc, uint32_t domid, int usbctrl, libxl_device_usb **usbs, int *num) @@ -573,47 +551,6 @@ libxl_device_usb *libxl_device_usb_list(libxl_ctx *ctx, uint32_t domid, return usbs; } -/* set default value */ -static char *usb_busaddr_to_busid(libxl__gc *gc, int bus, int addr) -{ - libxl_ctx *ctx = libxl__gc_owner(gc); - struct dirent *de; - DIR *dir; - char *busid = NULL; - - if (bus < 1 || addr < 1) - return NULL; - - if (!(dir = opendir(SYSFS_USB_DEV))) - return NULL; - - while((de = readdir(dir))) { - char *filename; - void *buf; - int busnum = -1; - int devnum = -1; - - if (!de->d_name) - continue; - - filename = GCSPRINTF(SYSFS_USB_DEV"/%s/devnum", de->d_name); - if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) - sscanf(buf, "%x", &devnum); - - filename = GCSPRINTF(SYSFS_USB_DEV"/%s/busnum", de->d_name); - if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) - sscanf(buf, "%x", &busnum); - - if (bus == busnum && addr == devnum) { - busid = strdup(de->d_name); - break; - } - } - - closedir(dir); - return busid; -} - /* find first unused controller:port and give that to usb device */ static int libxl__device_usb_set_default_usbctrl(libxl__gc *gc, uint32_t domid, @@ -1012,29 +949,10 @@ out: return rc; } -int libxl__device_usb_add(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb) +int pv_usb_add(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb) { int rc; - usb->busid = usb_busaddr_to_busid(gc, usb->hostbus, usb->hostaddr); - if (!usb->busid) { - LOG(ERROR, "USB device doesn't exist in sysfs"); - return ERROR_INVAL; - } - - if (!is_usb_assignable(gc, usb)) { - LOG(ERROR, "USB device is not assignable."); - rc = ERROR_FAIL; - goto out; - } - - /* check usb device is already assigned by pvusb */ - if (is_usb_assigned(gc, usb)) { - LOG(ERROR, "USB device is already attached to a domain."); - rc = ERROR_FAIL; - goto out; - } - rc = libxl__device_usb_setdefault(gc, domid, usb); if (rc) goto out; @@ -1044,18 +962,6 @@ out: return rc; } -int libxl_device_usb_add(libxl_ctx *ctx, uint32_t domid, - libxl_device_usb *usb, - const libxl_asyncop_how *ao_how) -{ - AO_CREATE(ctx, domid, ao_how); - int rc; - - rc = libxl__device_usb_add(gc, domid, usb); - libxl__ao_complete(egc, ao, rc); - return AO_INPROGRESS; -} - static int do_usb_remove(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb) { @@ -1067,19 +973,12 @@ static int do_usb_remove(libxl__gc *gc, uint32_t domid, return 0; } -static int libxl__device_usb_remove(libxl__gc *gc, uint32_t domid, - libxl_device_usb *usb) +int pv_usb_remove(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb) { libxl_device_usb *usbs = NULL; libxl_device_usb *usb_find = NULL; int i, num, rc; - usb->busid = usb_busaddr_to_busid(gc, usb->hostbus, usb->hostaddr); - if (!usb->busid) { - LOG(ERROR, "USB device doesn't exist in sysfs"); - return ERROR_INVAL; - } - usbs = libxl_device_usb_list_all(gc, domid, &num); if (!usbs) { LOG(ERROR, "No USB device attached to this domain"); @@ -1108,21 +1007,7 @@ out: return rc; } -int libxl_device_usb_remove(libxl_ctx *ctx, uint32_t domid, - libxl_device_usb *usb, - const libxl_asyncop_how *ao_how) - -{ - AO_CREATE(ctx, domid, ao_how); - int rc; - - rc = libxl__device_usb_remove(gc, domid, usb); - - libxl__ao_complete(egc, ao, rc); - return AO_INPROGRESS; -} - -int libxl__device_usb_destroy_all(libxl__gc *gc, uint32_t domid) +int pv_usb_destroy_all(libxl__gc *gc, uint32_t domid) { libxl_ctx *ctx = CTX; libxl_device_usbctrl *usbctrls = NULL; @@ -1148,50 +1033,6 @@ out: free(usbctrls); return rc; } - -int libxl_device_usb_getinfo(libxl_ctx *ctx, char *busid, libxl_usbinfo *usbinfo) -{ - GC_INIT(ctx); - char *filename; - void *buf; - - assert(busid); - - filename = GCSPRINTF(SYSFS_USB_DEV"/%s/devnum", busid); - if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) - sscanf(buf, "%x", &usbinfo->devnum); - - filename = GCSPRINTF(SYSFS_USB_DEV"/%s/busnum", busid); - if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) - sscanf(buf, "%x", &usbinfo->busnum); - - filename = GCSPRINTF(SYSFS_USB_DEV"/%s/idVendor", busid); - if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) - sscanf(buf, "%x", &usbinfo->idVendor); - - filename = GCSPRINTF(SYSFS_USB_DEV"/%s/idProduct", busid); - if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) - sscanf(buf, "%x", &usbinfo->idProduct); - - filename = GCSPRINTF(SYSFS_USB_DEV"/%s/manufacturer", busid); - if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) { - /* replace \n to \0 */ - usbinfo->manuf = strdup(buf); - if (strlen(usbinfo->manuf) > 0) - usbinfo->manuf[strlen(usbinfo->manuf) - 1] = '\0'; - } - - filename = GCSPRINTF(SYSFS_USB_DEV"/%s/product", busid); - if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) { - /* replace \n to \0 */ - usbinfo->prod = strdup(buf); - if (strlen(usbinfo->manuf) > 0) - usbinfo->manuf[strlen(usbinfo->manuf) - 1] = '\0'; - } - - GC_FREE; - return 0; -} /* * Local variables: * mode: C diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index a6db614..df56303 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -533,7 +533,15 @@ libxl_device_pci = Struct("device_pci", [ ("seize", bool), ]) +libxl_usb_protocol = Enumeration("usb_protocol", [ + (0, "AUTO"), + (1, "PV"), + (2, "DEVICEMODEL"), + ], init_val = "LIBXL_USB_PROTOCOL_PV") + + libxl_device_usbctrl = Struct("device_usbctrl", [ + ("protocol", libxl_usb_protocol), ("devid", libxl_devid), ("version", integer), ("ports", integer), @@ -542,6 +550,7 @@ libxl_device_usbctrl = Struct("device_usbctrl", [ ]) libxl_device_usb = Struct("device_usb", [ + ("protocol", libxl_usb_protocol), ("ctrl", libxl_devid), ("port", integer), ("busid", string), @@ -626,6 +635,7 @@ libxl_vtpminfo = Struct("vtpminfo", [ ], dir=DIR_OUT) libxl_usbctrlinfo = Struct("usbctrlinfo", [ + ("protocol", libxl_usb_protocol), ("devid", libxl_devid), ("version", integer), ("ports", integer), @@ -640,6 +650,7 @@ libxl_usbctrlinfo = Struct("usbctrlinfo", [ ], dir=DIR_OUT) libxl_usbinfo = Struct("usbinfo", [ + ("protocol", libxl_usb_protocol), ("busnum", integer), ("devnum", integer), ("idVendor", integer), diff --git a/tools/libxl/libxl_usb.c b/tools/libxl/libxl_usb.c new file mode 100644 index 0000000..ad96d15 --- /dev/null +++ b/tools/libxl/libxl_usb.c @@ -0,0 +1,224 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +#include "libxl_osdeps.h" /* must come before any other headers */ + +#include "libxl_internal.h" + +#define USBHUB_CLASS_CODE 0x09 + +static char *usb_busaddr_to_busid(libxl__gc *gc, int bus, int addr) +{ + libxl_ctx *ctx = libxl__gc_owner(gc); + struct dirent *de; + DIR *dir; + char *busid = NULL; + + if (bus < 1 || addr < 1) + return NULL; + + if (!(dir = opendir(SYSFS_USB_DEV))) + return NULL; + + while((de = readdir(dir))) { + char *filename; + void *buf; + int busnum = -1; + int devnum = -1; + + if (!de->d_name) + continue; + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/devnum", de->d_name); + if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) + sscanf(buf, "%x", &devnum); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/busnum", de->d_name); + if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) + sscanf(buf, "%x", &busnum); + + if (bus == busnum && addr == devnum) { + busid = strdup(de->d_name); + break; + } + } + + closedir(dir); + return busid; +} + +static bool is_usb_assignable(libxl__gc *gc, libxl_device_usb *usb) +{ + libxl_ctx *ctx = libxl__gc_owner(gc); + int classcode; + char *filename; + void *buf; + + assert(usb->busid); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/bDeviceClass", usb->busid); + if (libxl_read_file_contents(ctx, filename, &buf, NULL) < 0) + return false; + + sscanf(buf, "%x", &classcode); + if (classcode == USBHUB_CLASS_CODE) + return false; + + return true; +} + +int libxl__device_usb_add(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb) +{ + int rc; + + usb->busid = usb_busaddr_to_busid(gc, usb->hostbus, usb->hostaddr); + if (!usb->busid) { + LOG(ERROR, "USB device doesn't exist in sysfs"); + return ERROR_INVAL; + } + + if (!is_usb_assignable(gc, usb)) { + LOG(ERROR, "USB device is not assignable."); + rc = ERROR_FAIL; + goto out; + } + + /* check usb device is already assigned by pvusb */ + if (pv_is_usb_assigned(gc, usb)) { + LOG(ERROR, "USB device is already attached to a domain."); + rc = ERROR_FAIL; + goto out; + } + + /* TODO check usb device is already assigned by qemu */ + + switch (usb->protocol) { + case LIBXL_USB_PROTOCOL_PV: + rc = pv_usb_add(gc, domid, usb); + break; + default: + /* not supported */ + rc = ERROR_FAIL; + break; + } + +out: + return rc; +} + +int libxl_device_usb_add(libxl_ctx *ctx, uint32_t domid, + libxl_device_usb *usb, + const libxl_asyncop_how *ao_how) +{ + AO_CREATE(ctx, domid, ao_how); + int rc; + + rc = libxl__device_usb_add(gc, domid, usb); + libxl__ao_complete(egc, ao, rc); + return AO_INPROGRESS; +} + +static int libxl__device_usb_remove(libxl__gc *gc, uint32_t domid, + libxl_device_usb *usb) +{ + int rc; + + switch (usb->protocol) { + case LIBXL_USB_PROTOCOL_PV: + usb->busid = usb_busaddr_to_busid(gc, usb->hostbus, usb->hostaddr); + if (!usb->busid) { + LOG(ERROR, "USB device doesn't exist in sysfs"); + return ERROR_INVAL; + } + + rc = pv_usb_remove(gc, domid, usb); + break; + default: + /* not supported */ + rc = ERROR_FAIL; + break; + } + + return rc; +} + +int libxl_device_usb_remove(libxl_ctx *ctx, uint32_t domid, + libxl_device_usb *usb, + const libxl_asyncop_how *ao_how) + +{ + AO_CREATE(ctx, domid, ao_how); + int rc; + + rc = libxl__device_usb_remove(gc, domid, usb); + + libxl__ao_complete(egc, ao, rc); + return AO_INPROGRESS; +} + +int libxl__device_usb_destroy_all(libxl__gc *gc, uint32_t domid) +{ + int rc; + + /* destroy all usb devices handled by pvusb */ + rc = pv_usb_destroy_all(gc, domid); + if (rc) goto out; + + /* TODO destroy all usb devices handled by qemu */ + +out: + return rc; +} + +int libxl_device_usb_getinfo(libxl_ctx *ctx, char *busid, libxl_usbinfo *usbinfo) +{ + GC_INIT(ctx); + char *filename; + void *buf; + + assert(busid); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/devnum", busid); + if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) + sscanf(buf, "%x", &usbinfo->devnum); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/busnum", busid); + if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) + sscanf(buf, "%x", &usbinfo->busnum); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/idVendor", busid); + if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) + sscanf(buf, "%x", &usbinfo->idVendor); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/idProduct", busid); + if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) + sscanf(buf, "%x", &usbinfo->idProduct); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/manufacturer", busid); + if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) { + /* replace \n to \0 */ + usbinfo->manuf = strdup(buf); + if (strlen(usbinfo->manuf) > 0) + usbinfo->manuf[strlen(usbinfo->manuf) - 1] = '\0'; + } + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/product", busid); + if (!libxl_read_file_contents(ctx, filename, &buf, NULL)) { + /* replace \n to \0 */ + usbinfo->prod = strdup(buf); + if (strlen(usbinfo->manuf) > 0) + usbinfo->manuf[strlen(usbinfo->manuf) - 1] = '\0'; + } + + GC_FREE; + return 0; +} diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index 750377f..f41ac6c 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -3400,7 +3400,16 @@ int main_usbattach(int argc, char **argv) } while (argc > optind) { - if (MATCH_OPTION("controller", argv[optind], oparg)) { + if (MATCH_OPTION("type", argv[optind], oparg)) { + if (!strcmp(oparg, "pv")) { + usb.protocol = LIBXL_USB_PROTOCOL_PV; + } else if (!strcmp(oparg, "qemu")) { + usb.protocol = LIBXL_USB_PROTOCOL_DEVICEMODEL; + } else { + fprintf(stderr, "unrecognized type `%s'\n", oparg); + exit(-1); + } + } else if (MATCH_OPTION("controller", argv[optind], oparg)) { usb.ctrl = atoi(oparg); } else if (MATCH_OPTION("port", argv[optind], oparg)) { usb.port = atoi(oparg); @@ -3435,7 +3444,7 @@ int main_usbattach(int argc, char **argv) int main_usbdetach(int argc, char **argv) { uint32_t domid; - char *devname, *p; + char *devname, *p, *oparg; int opt; libxl_device_usb usb; @@ -3448,9 +3457,21 @@ int main_usbdetach(int argc, char **argv) domid = find_domain(argv[optind++]); devname = argv[optind++]; - if (argc > optind) { - fprintf(stderr, "Invalid arguments.\n"); - exit(-1); + while (argc > optind) { + if (MATCH_OPTION("type", argv[optind], oparg)) { + if (!strcmp(oparg, "pv")) { + usb.protocol = LIBXL_USB_PROTOCOL_PV; + } else if (!strcmp(oparg, "qemu")) { + usb.protocol = LIBXL_USB_PROTOCOL_DEVICEMODEL; + } else { + fprintf(stderr, "unrecognized type `%s'\n", oparg); + exit(-1); + } + } else { + fprintf(stderr, "unrecognized argument `%s'\n", argv[optind]); + exit(-1); + } + optind++; } p = strchr(devname, '.'); @@ -3472,6 +3493,18 @@ int main_usbdetach(int argc, char **argv) return 0; } +static const char *get_usb_protocol_string(libxl_usb_protocol type) +{ + switch (type) { + case LIBXL_USB_PROTOCOL_PV: + return "pv"; + case LIBXL_USB_PROTOCOL_DEVICEMODEL: + return "qemu"; + default: + return "invalid"; + } +} + int main_usblist(int argc, char **argv) { uint32_t domid; @@ -3491,19 +3524,21 @@ int main_usblist(int argc, char **argv) exit(-1); } + /* list pvusb info */ usbctrls = libxl_device_usbctrl_list(ctx, domid, &numctrl); if (!usbctrls) { return 0; } for (i = 0; i < numctrl; ++i) { - printf("%-6s %-3s %-5s %-7s %-5s %-30s\n", - "Devid", "BE", "state", "usb-ver", "ports", "BE-path"); + printf("%-6s %-6s %-3s %-5s %-7s %-5s %-30s\n", + "Devid", "Type", "BE", "state", "usb-ver", "ports", "BE-path"); if (!libxl_device_usbctrl_getinfo(ctx, domid, &usbctrls[i], &usbctrlinfo)) { - printf("%-6d %-3d %-5d %-7d %-5d %-30s\n", + printf("%-6d %-6s %-3d %-5d %-7d %-5d %-30s\n", usbctrlinfo.devid, + get_usb_protocol_string(usbctrlinfo.protocol), usbctrlinfo.backend_id, usbctrlinfo.state, usbctrlinfo.version, usbctrlinfo.ports, usbctrlinfo.backend); @@ -3517,6 +3552,9 @@ int main_usblist(int argc, char **argv) } free(usbctrls); + + /* TODO list qemu usb device info*/ + return 0; } diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c index da30ae0..4054911 100644 --- a/tools/libxl/xl_cmdtable.c +++ b/tools/libxl/xl_cmdtable.c @@ -557,12 +557,12 @@ struct cmd_spec cmd_table[] = { { "usb-attach", &main_usbattach, 1, 2, "Attach a USB device to a domain", - "<Domain> <bus.addr> [controller=<DevId> [port=<port>]]", + "<Domain> <bus.addr> [type=pv|qemu] [controller=<DevId> [port=<port>]]", }, { "usb-detach", &main_usbdetach, 0, 1, "Detach a USB device from a domain", - "<Domain> <bus.addr>", + "<Domain> <bus.addr> [type=pv|qemu]", }, { "usb-list", &main_usblist, 0, 0, -- 1.8.5.2 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |