[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


 


Rackspace

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