xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v0 RFC 0/2] xl/libxl support for PVUSB
@ 2014-08-10 20:23 Bo Cao
  2014-08-10 20:23 ` [PATCH v0 RFC 1/2] libxl: Introduce functions in libxl to add and remove USB devices for an PV guest Bo Cao
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Bo Cao @ 2014-08-10 20:23 UTC (permalink / raw)
  To: xen-devel; +Cc: George Dunlap, Ian Jackson, Ian Campbell, Lars Kurth

Finally I have a workable version xl/libxl support for PVUSB. Most of
its commands work property now, but there are still some probelm to be solved.
Please take a loot and give me some advices.

== What have been implemented ? ==
I have implemented libxl functions for PVUSB in libxl_usb.c. It mainly consists of two part:
usbctrl_add/remove/list and usb_add/remove/list in which usbctrl denote usb controller in which
usd device can be plugged in. I don't use "ao_dev" in libxl_deivce_usbctrl_add since we don't need to
execute hotplug script for usbctrl and without "ao_dev", adding default usbctrl for usb device
would be easier.

For the cammands to manipulate usb device such as "xl usb-attach" and "xl usb-detach", this patch now only
support to specify usb devices by their interface in sysfs. Using this interface, we can read usb device
information through sysfs and bind/unbind usb device. (The support for mapping the "lsusb" bus:addr to the
sysfs usb interface will come later).

== What needs to do next ? ==
There are two main problems to be solved.

1.  PVUSB Options in VM Guest's Configuration File
    The interface in VM Guest's configuration file to add usb device is: "usb=[interface="1-1"]".
But the problem is now is that after the default usbctrl is added, the state of usbctrl is "2", e,g, "XenbusStateInitWait",
waiting for xen-usbfront to connect. The xen-usbfront in VM Guest isn't loaded. Therefore, "sysfs_intf_write"
will report error. Does anyone have any clue how to solve this?

2. sysfs_intf_write
    In the process of "xl usb-attach domid intf=1-1", after writing "1-1" to Xenstore entry, we need to
bind the controller of this usb device to usbback driver so that it can be used by VM Guest. For exampele,
for usb device "1-1", it's controller interface maybe "1-1:1.0", and we write this value to "/sys/bus/usb/driver/usbback/bind".
But for some devices, they have two controllers, for example "1-1:1.0" and "1-1:1.1". I think this means it has two functions,
such as usbhid and usb-storage. So in this case, we bind the two controller to usbback?

========
There maybe some errors or bugs in the codes. Feel free to tell me.

Cheers,

- Simon

---
CC: George Dunlap <george.dunlap@eu.citrix.com>
CC: Ian Jackson <ian.jackson@citrix.com>
CC: Ian Campbell <ian.campbell@citrix.com>
CC: Pasi Kärkkäinen <pasik@iki.fi>
CC: Lars Kurth <lars.kurth@citrix.com>



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

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v0 RFC 1/2] libxl: Introduce functions in libxl to add and remove USB devices for an PV guest
  2014-08-10 20:23 [PATCH v0 RFC 0/2] xl/libxl support for PVUSB Bo Cao
@ 2014-08-10 20:23 ` Bo Cao
  2014-08-12 16:11   ` Ian Jackson
  2014-08-10 20:23 ` [PATCH v0 RFC 2/2] xl: Add commands for usb hot-plug Bo Cao
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Bo Cao @ 2014-08-10 20:23 UTC (permalink / raw)
  To: xen-devel; +Cc: Lars Kurth, Ian Campbell, George Dunlap, Ian Jackson, Bo Cao

This patch exposes a generic interface which can be expanded in the
future to implement USB for DEVICEMODEL. 

In this patch, I have implemented fucntions in libxl to add and remove USB
devices for an PV guest. Most of the fucntion are implemented in "tools/libxl/libxl_usb.c".

Signed-off-by: Simon Cao <caobosimon@gmail.com>
---
CC: George Dunlap <george.dunlap@eu.citrix.com>
CC: Ian Jackson <ian.jackson@citrix.com>
CC: Ian Campbell <ian.campbell@citrix.com>
CC: Pasi Kärkkäinen <pasik@iki.fi>
CC: Lars Kurth <lars.kurth@citrix.com>
---
 tools/libxl/Makefile                 |    2 +-
 tools/libxl/libxl.c                  |    8 +-
 tools/libxl/libxl.h                  |   69 ++
 tools/libxl/libxl_create.c           |   41 +-
 tools/libxl/libxl_internal.h         |   26 +
 tools/libxl/libxl_types.idl          |   59 +-
 tools/libxl/libxl_types_internal.idl |    1 +
 tools/libxl/libxl_usb.c              | 1277 ++++++++++++++++++++++++++++++++++
 8 files changed, 1474 insertions(+), 9 deletions(-)
 create mode 100644 tools/libxl/libxl_usb.c

diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index 4cfa275..a50e6cf 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -76,7 +76,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_save_callout.o _libxl_save_msgs_callout.o \
-			libxl_qmp.o libxl_event.o libxl_fork.o $(LIBXL_OBJS-y)
+			libxl_qmp.o libxl_event.o libxl_fork.o libxl_usb.o $(LIBXL_OBJS-y)
 LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
 
 LIBXL_TESTS += timedereg
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 9054c3b..ec63831 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -1434,6 +1434,8 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
 
     if (libxl__device_pci_destroy_all(gc, domid) < 0)
         LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "pci shutdown failed for domid %d", domid);
+    if (libxl__device_usb_destroy_all(gc, domid) < 0)
+         LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "usb shutdown failed for domid %d", domid);
     rc = xc_domain_pause(ctx->xch, domid);
     if (rc < 0) {
         LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, "xc_domain_pause failed for %d", domid);
@@ -1734,7 +1736,7 @@ out:
 /******************************************************************************/
 
 /* generic callback for devices that only need to set ao_complete */
-static void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev)
+void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev)
 {
     STATE_AO_GC(aodev->ao);
 
@@ -1757,7 +1759,7 @@ out:
 }
 
 /* common function to get next device id */
-static int libxl__device_nextid(libxl__gc *gc, uint32_t domid, char *device)
+int libxl__device_nextid(libxl__gc *gc, uint32_t domid, char *device)
 {
     char *dompath, **l;
     unsigned int nb;
@@ -1776,7 +1778,7 @@ static int libxl__device_nextid(libxl__gc *gc, uint32_t domid, char *device)
     return nextid;
 }
 
-static int libxl__resolve_domid(libxl__gc *gc, const char *name,
+int libxl__resolve_domid(libxl__gc *gc, const char *name,
                                 uint32_t *domid)
 {
     if (!name)
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 17b8a7b..68f070c 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -91,6 +91,12 @@
 #define LIBXL_HAVE_DOMAIN_NODEAFFINITY 1
 
 /*
+ * LIBXL_HAVE_DEVICE_USB indicates the functions for doing hot-plug of
+ * USB devices.
+ */
+#define LIBXL_HAVE_DEVICE_USB 1
+
+/*
  * LIBXL_HAVE_BUILDINFO_HVM_VENDOR_DEVICE indicates that the
  * libxl_vendor_device field is present in the hvm sections of
  * libxl_domain_build_info. This field tells libxl which
@@ -950,6 +956,64 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk,
                        const libxl_asyncop_how *ao_how)
                        LIBXL_EXTERNAL_CALLERS_ONLY;
 
+/* USB Controllers*/
+int libxl_device_usbctrl_add(libxl_ctx *ctx, uint32_t domid,
+                         libxl_device_usbctrl *usbctrl,
+                         const libxl_asyncop_how *ao_how)
+                         LIBXL_EXTERNAL_CALLERS_ONLY;
+
+int libxl_device_usbctrl_remove(libxl_ctx *ctx, uint32_t domid,
+                         libxl_device_usbctrl *usbctrl,
+                         const libxl_asyncop_how *ao_how)
+                         LIBXL_EXTERNAL_CALLERS_ONLY;
+
+int libxl_device_usbctrl_destroy(libxl_ctx *ctx, uint32_t domid,
+                         libxl_device_usbctrl *usbctrl,
+                         const libxl_asyncop_how *ao_how)
+                         LIBXL_EXTERNAL_CALLERS_ONLY;
+
+libxl_device_usbctrl *libxl_device_usbctrl_list(libxl_ctx *ctx,
+                            uint32_t domid, int *num);
+
+int libxl_devid_to_device_usbctrl(libxl_ctx *ctx, uint32_t domid, 
+                            int devid, libxl_device_usbctrl *usbctrl)
+                            LIBXL_EXTERNAL_CALLERS_ONLY;
+
+int libxl_device_usbctrl_getinfo(libxl_ctx *ctx, uint32_t domid,
+                                libxl_device_usbctrl *usbctrl,
+                                libxl_usbctrlinfo *usbctrlinfo)
+                                LIBXL_EXTERNAL_CALLERS_ONLY;
+
+/* USB Devices */
+int libxl_device_usb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_usb *usb,
+                         const libxl_asyncop_how *ao_how)
+                         LIBXL_EXTERNAL_CALLERS_ONLY;
+
+int libxl_device_usb_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_usb *usb,
+                            const libxl_asyncop_how *ao_how)
+                            LIBXL_EXTERNAL_CALLERS_ONLY;
+
+int libxl_device_usb_destroy(libxl_ctx *ctx, uint32_t domid, libxl_device_usb *usb,
+                            const libxl_asyncop_how *ao_how)
+                            LIBXL_EXTERNAL_CALLERS_ONLY;
+
+libxl_device_usb *libxl_device_usb_list(libxl_ctx *ctx, uint32_t domid,
+                                        int usbctrl, int *num);
+
+int libxl_devid_to_device_usb(libxl_ctx *ctx, uint32_t domid,
+                               int devid, libxl_device_usb *usb)
+                            LIBXL_EXTERNAL_CALLERS_ONLY;
+
+int libxl_hostdev_to_device_usb(libxl_ctx *ctx, uint32_t domid,
+                            int devid, libxl_device_usb *usb)
+                            LIBXL_EXTERNAL_CALLERS_ONLY;
+
+int libxl_intf_to_device_usb(libxl_ctx *ctx, uint32_t domid,
+                            char *intf, libxl_device_usb *usb)
+                            LIBXL_EXTERNAL_CALLERS_ONLY;
+
+int libxl_device_usb_getinfo(libxl_ctx *ctx, char *intf, libxl_usbinfo *usbinfo)
+                             LIBXL_EXTERNAL_CALLERS_ONLY;
 /* Network Interfaces */
 int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic,
                          const libxl_asyncop_how *ao_how)
@@ -1065,6 +1129,11 @@ int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pcidev, in
 int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pcidev, int rebind);
 libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num);
 
+int libxl_device_usb_assignable_add(libxl_ctx *ctx, libxl_device_usb *usb, int rebind);
+int libxl_device_usb_assignable_remove(libxl_ctx *ctx, libxl_device_usb *usb, int rebind);
+libxl_device_usb *libxl_device_usb_assignable_list(libxl_ctx *ctx, int *num);
+libxl_device_usb *libxl_device_usb_assigned_list(libxl_ctx *ctx, int *num);
+
 /* CPUID handling */
 int libxl_cpuid_parse_config(libxl_cpuid_policy_list *cpuid, const char* str);
 int libxl_cpuid_parse_config_xend(libxl_cpuid_policy_list *cpuid,
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index d015cf4..fc51c52 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -685,6 +685,8 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *aodevs,
 
 static void domcreate_attach_vtpms(libxl__egc *egc, libxl__multidev *multidev,
                                    int ret);
+static void domcreate_attach_usbs(libxl__egc *egc, libxl__multidev *multidev,
+                                   int ret);
 static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *aodevs,
                                  int ret);
 
@@ -1239,13 +1241,13 @@ static void domcreate_attach_vtpms(libxl__egc *egc,
    if (d_config->num_vtpms > 0) {
        /* Attach vtpms */
        libxl__multidev_begin(ao, &dcs->multidev);
-       dcs->multidev.callback = domcreate_attach_pci;
+       dcs->multidev.callback = domcreate_attach_usbs;
        libxl__add_vtpms(egc, ao, domid, d_config, &dcs->multidev);
        libxl__multidev_prepared(egc, &dcs->multidev, 0);
        return;
    }
 
-   domcreate_attach_pci(egc, multidev, 0);
+   domcreate_attach_usbs(egc, multidev, 0);
    return;
 
 error_out:
@@ -1253,6 +1255,39 @@ error_out:
    domcreate_complete(egc, dcs, ret);
 }
 
+static void domcreate_attach_usbs(libxl__egc *egc, libxl__multidev *multidev,
+                                int ret)
+{
+    libxl__domain_create_state *dcs = CONTAINER_OF(multidev, *dcs, multidev);
+    STATE_AO_GC(dcs->ao);
+    int i;
+    libxl_ctx *ctx = CTX;
+    int domid = dcs->guest_domid;
+    
+    libxl_domain_config *const d_config = dcs->guest_config;
+    
+    if (ret) {
+        LOG(ERROR, "unable to add vtpm devices");
+        goto error_out;
+    }
+    
+    for (i = 0; i < d_config->num_usbs; i++) {
+        ret = libxl__device_usb_add(gc, domid, &d_config->usbs[i]);
+        if (ret < 0) {
+            LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+                       "libxl__device_usb_add failed: %d", ret);
+            goto error_out;
+        }
+    }
+    
+    domcreate_attach_pci(egc, multidev, 0);
+    return;
+
+error_out:
+   assert(ret);
+   domcreate_complete(egc, dcs, ret);
+}
+
 static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *multidev,
                                  int ret)
 {
@@ -1266,7 +1301,7 @@ static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *multidev,
     libxl_domain_config *const d_config = dcs->guest_config;
 
     if (ret) {
-        LOG(ERROR, "unable to add vtpm devices");
+        LOG(ERROR, "unable to add usb devices");
         goto error_out;
     }
 
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index a0d4f24..629a0c2 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1031,6 +1031,12 @@ _hidden int libxl__wait_for_backend(libxl__gc *gc, const char *be_path,
                                     const char *state);
 _hidden int libxl__nic_type(libxl__gc *gc, libxl__device *dev,
                             libxl_nic_type *nictype);
+_hidden int libxl__device_nextid(libxl__gc *gc, uint32_t domid, char *device);
+_hidden int libxl__resolve_domid(libxl__gc *gc, const char *name, 
+                                 uint32_t *domid); 
+_hidden int libxl__domain_usb_init(libxl__gc *gc, xs_transaction_t t,
+                                   char *libxl_path, struct xs_permissions *perm,
+                                   int perm_size);
 
 /*
  * For each aggregate type which can be used as an input we provide:
@@ -1056,6 +1062,8 @@ _hidden int libxl__device_vtpm_setdefault(libxl__gc *gc, libxl_device_vtpm *vtpm
 _hidden int libxl__device_vfb_setdefault(libxl__gc *gc, libxl_device_vfb *vfb);
 _hidden int libxl__device_vkb_setdefault(libxl__gc *gc, libxl_device_vkb *vkb);
 _hidden int libxl__device_pci_setdefault(libxl__gc *gc, libxl_device_pci *pci);
+_hidden int libxl__device_usbctrl_setdefault(libxl__gc *gc, 
+                                    libxl_device_usbctrl *usbctrl, uint32_t domid);
 
 _hidden const char *libxl__device_nic_devname(libxl__gc *gc,
                                               uint32_t domid,
@@ -2147,6 +2155,8 @@ struct libxl__ao_device {
 
 /* Starts preparing to add/remove a bunch of devices. */
 _hidden void libxl__multidev_begin(libxl__ao *ao, libxl__multidev*);
+/* generic callback for devices that only need to set ao_complete */
+_hidden void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev);
 
 /* Prepares to add/remove one of many devices.  Returns a libxl__ao_device
  * which has had libxl__prepare_ao_device called, and which has also
@@ -2266,6 +2276,18 @@ _hidden void libxl__device_vtpm_add(libxl__egc *egc, uint32_t domid,
                                    libxl_device_vtpm *vtpm,
                                    libxl__ao_device *aodev);
 
+/* from libxl_usb */
+_hidden int libxl__device_usbctrl_add(libxl__gc *gc, uint32_t domid,
+                            libxl_device_usbctrl *usbctrl);
+_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 int libxl__device_usb_assigned_list(libxl__gc *gc, libxl_device_usb **list, int *num);
+_hidden int libxl__device_usb_list(libxl__gc *gc, uint32_t domid, 
+                                libxl_device_usb **usbs, int usbctrl, int *num);
+_hidden libxl_device_usb *libxl_device_usb_list_all(libxl__gc *gc, uint32_t domid, int *num);
+_hidden int libxl__device_usb_setdefault(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb);
+
 /* Internal function to connect a vkb device */
 _hidden int libxl__device_vkb_add(libxl__gc *gc, uint32_t domid,
                                   libxl_device_vkb *vkb);
@@ -2707,6 +2729,10 @@ _hidden void libxl__add_vtpms(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
                              libxl_domain_config *d_config,
                              libxl__multidev *multidev);
 
+_hidden void libxl__add_usbs(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
+                             libxl_domain_config *d_config,
+                             libxl__multidev *multidev);
+
 /*----- device model creation -----*/
 
 /* First layer; wraps libxl__spawn_spawn. */
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index f0f6e34..9057862 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -85,6 +85,16 @@ libxl_nic_type = Enumeration("nic_type", [
     (2, "VIF"),
     ])
 
+libxl_usbctrl_type = Enumeration("usbctrl_type",[
+    (0, "AUTO"),
+    (1, "PV"),
+    (2, "DEVICEMODEL"),
+    ])
+
+libxl_usb_type = Enumeration("device_usb_type", [
+    (1, "HOSTDEV"),
+    ])
+
 libxl_action_on_shutdown = Enumeration("action_on_shutdown", [
     (1, "DESTROY"),
 
@@ -330,7 +340,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
     ("ioports",          Array(libxl_ioport_range, "num_ioports")),
     ("irqs",             Array(uint32, "num_irqs")),
     ("iomem",            Array(libxl_iomem_range, "num_iomem")),
-    ("claim_mode",	     libxl_defbool),
+    ("claim_mode",       libxl_defbool),
     ("event_channels",   uint32),
     ("u", KeyedUnion(None, libxl_domain_type, "type",
                 [("hvm", Struct(None, [("firmware",         string),
@@ -448,6 +458,27 @@ libxl_device_pci = Struct("device_pci", [
     ("seize", bool),
     ])
 
+libxl_device_usbctrl = Struct("device_usbctrl", [
+    ("name", string),
+    ("type", libxl_usbctrl_type),
+    ("backend_domid", libxl_domid),
+    ("backend_domname", string),
+    ("devid", libxl_devid),
+    ("usb_version", uint8),
+    ("num_ports", uint8),
+    ])
+
+libxl_device_usb = Struct("device_usb", [
+    ("ctrl", integer),
+    ("port", integer),
+    ("intf", string),
+    ("u", KeyedUnion(None, libxl_usb_type, "type",
+        [("hostdev", Struct(None, [
+            ("hostbus",   integer),
+            ("hostaddr",  integer) ]))
+        ]))
+    ]) 
+     
 libxl_device_vtpm = Struct("device_vtpm", [
     ("backend_domid",    libxl_domid),
     ("backend_domname",  string),
@@ -462,10 +493,10 @@ libxl_domain_config = Struct("domain_config", [
     ("disks", Array(libxl_device_disk, "num_disks")),
     ("nics", Array(libxl_device_nic, "num_nics")),
     ("pcidevs", Array(libxl_device_pci, "num_pcidevs")),
+    ("usbs", Array(libxl_device_usb, "num_usbs")),
     ("vfbs", Array(libxl_device_vfb, "num_vfbs")),
     ("vkbs", Array(libxl_device_vkb, "num_vkbs")),
     ("vtpms", Array(libxl_device_vtpm, "num_vtpms")),
-
     ("on_poweroff", libxl_action_on_shutdown),
     ("on_reboot", libxl_action_on_shutdown),
     ("on_watchdog", libxl_action_on_shutdown),
@@ -507,6 +538,30 @@ libxl_vtpminfo = Struct("vtpminfo", [
     ("uuid", libxl_uuid),
     ], dir=DIR_OUT)
 
+libxl_usbctrlinfo = Struct("usbctrlinfo", [
+    ("backend", string),
+    ("backend_id", uint32),
+    ("frontend", string),
+    ("frontend_id", uint32),
+    ("devid", libxl_devid),
+    ("state", integer),
+    ("evtch", integer),
+    ("version", integer),
+    ("type", string),
+    ("ref_urb", integer),
+    ("ref_conn", integer),
+    ("num_ports", integer),
+    ], dir=DIR_OUT)
+
+libxl_usbinfo = Struct("usbinfo", [
+    ("bus", integer),
+    ("devnum", integer),
+    ("idVendor", integer),
+    ("idProduct", integer),
+    ("prod", string),
+    ("manuf", string),
+    ], dir=DIR_OUT)
+
 libxl_vcpuinfo = Struct("vcpuinfo", [
     ("vcpuid", uint32),
     ("cpu", uint32),
diff --git a/tools/libxl/libxl_types_internal.idl b/tools/libxl/libxl_types_internal.idl
index a964851..c5c17e7 100644
--- a/tools/libxl/libxl_types_internal.idl
+++ b/tools/libxl/libxl_types_internal.idl
@@ -20,6 +20,7 @@ libxl__device_kind = Enumeration("device_kind", [
     (6, "VKBD"),
     (7, "CONSOLE"),
     (8, "VTPM"),
+    (9, "VUSB"),
     ])
 
 libxl__console_backend = Enumeration("console_backend", [
diff --git a/tools/libxl/libxl_usb.c b/tools/libxl/libxl_usb.c
new file mode 100644
index 0000000..7a03489
--- /dev/null
+++ b/tools/libxl/libxl_usb.c
@@ -0,0 +1,1277 @@
+/*
+ * 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 the usb sys path
+#define SYSFS_USB_DEVS_PATH "/sys/bus/usb/devices"
+#define SYSFS_USBBACK_DRIVER "/sys/bus/usb/drivers/usbback"
+#define USBHUB_CLASS_CODE 9
+
+int libxl__device_usbctrl_setdefault(libxl__gc *gc, 
+                 libxl_device_usbctrl *usbctrl, uint32_t domid)
+{
+    int rc;
+    
+    if (!usbctrl->usb_version)
+        usbctrl->usb_version = 2;
+    if (!usbctrl->num_ports)
+        usbctrl->num_ports = 8;
+
+    if(!usbctrl->backend_domid)
+        usbctrl->backend_domid = 0;
+    
+    rc = libxl__resolve_domid(gc, usbctrl->backend_domname, &usbctrl->backend_domid);
+    if (rc < 0) return rc;
+
+    switch (libxl__domain_type(gc, domid)) {
+    case LIBXL_DOMAIN_TYPE_HVM:
+        if (!usbctrl->type)
+            usbctrl->type = LIBXL_USBCTRL_TYPE_DEVICEMODEL;
+        break;
+    case LIBXL_DOMAIN_TYPE_PV:
+        if (usbctrl->type == LIBXL_USBCTRL_TYPE_DEVICEMODEL) {
+            LOG(ERROR, "trying to create PV guest with an emulated interface");
+            return ERROR_INVAL;
+        }
+        usbctrl->type = LIBXL_USBCTRL_TYPE_PV;
+        break;
+    case LIBXL_DOMAIN_TYPE_INVALID:
+        return ERROR_FAIL;
+    default:
+        abort();
+    }
+    return rc;
+}
+
+static int libxl__device_from_usbctrl(libxl__gc *gc, uint32_t domid,
+                                   libxl_device_usbctrl *usbctrl,
+                                   libxl__device *device)
+{
+    device->backend_devid   = usbctrl->devid;
+    device->backend_domid   = usbctrl->backend_domid;
+    device->backend_kind    = LIBXL__DEVICE_KIND_VUSB;
+    device->devid           = usbctrl->devid;
+    device->domid           = domid;
+    device->kind            = LIBXL__DEVICE_KIND_VUSB;
+
+   return 0;    
+}
+
+static int do_pvusbctrl_add(libxl__gc *gc, uint32_t domid,
+                        libxl_device_usbctrl *usbctrl) 
+{
+    flexarray_t *front;
+    flexarray_t *back;
+    libxl__device *device;
+    unsigned int rc = 0;
+
+    rc = libxl__device_usbctrl_setdefault(gc, usbctrl, domid);
+    if(rc) goto out;
+    
+    front = flexarray_make(gc, 4, 1);
+    back = flexarray_make(gc, 12, 1);
+
+    if (usbctrl->devid == -1) {
+        if ((usbctrl->devid = libxl__device_nextid(gc, domid, "vusb")) < 0) {
+            rc = ERROR_FAIL;
+            goto out;
+        }
+    }
+    
+    GCNEW(device);
+    rc = libxl__device_from_usbctrl(gc, domid, usbctrl, device);
+    if ( rc != 0 ) goto out;
+
+    flexarray_append(back, "frontend-id");
+    flexarray_append(back, libxl__sprintf(gc, "%d", domid));
+    flexarray_append(back, "online");
+    flexarray_append(back, "1");
+    flexarray_append(back, "state");
+    flexarray_append(back, libxl__sprintf(gc, "%d", 1));
+    flexarray_append(back, "usb-ver");
+    flexarray_append(back, libxl__sprintf(gc, "%d", usbctrl->usb_version));
+    flexarray_append(back, "num-ports");
+    flexarray_append(back, libxl__sprintf(gc, "%d", usbctrl->num_ports));
+    flexarray_append(back, "type");
+    switch(usbctrl->type) {
+    case LIBXL_USBCTRL_TYPE_PV:{
+        flexarray_append(back, "PVUSB");
+        break;
+    }
+    case LIBXL_USBCTRL_TYPE_DEVICEMODEL: {
+        flexarray_append(back, "IOEMU");
+        break;
+    }
+    default:
+        abort();
+    }
+    flexarray_append(front, "backend-id");
+    flexarray_append(front, libxl__sprintf(gc, "%d", usbctrl->backend_domid));
+    flexarray_append(front, "state");
+    flexarray_append(front, libxl__sprintf(gc, "%d", 1));
+    libxl__device_generic_add(gc, XBT_NULL, device,
+                              libxl__xs_kvs_of_flexarray(gc, back, back->count),
+                              libxl__xs_kvs_of_flexarray(gc, front, front->count),
+                              NULL);
+    /*If we add usbctrl from usb-add, enable the funciton below will report errors.
+     *This is because the state of usbctrl change too fast for the device_addrm_complete to catch,
+     *from 2 to 4. Since we won't need hot-plug script in this usbctrl_add, it's okay to take if off.
+    aodev->dev = device;
+    aodev->action = LIBXL__DEVICE_ACTION_ADD;
+    //libxl__wait_device_connection(egc, aodev);
+    //ao->complete = 1;
+
+    rc = 0;
+out:
+    aodev->rc = rc;
+    if (rc) aodev->callback(egc, aodev);
+    return 0;
+    */
+out:
+    return rc;
+}
+
+static int libxl_port_add_xenstore(libxl__gc *gc, uint32_t domid,
+                                    libxl_device_usbctrl *usbctrl) {
+    libxl_ctx *ctx = CTX;
+    char *path;
+
+    path = libxl__sprintf(gc, "%s/backend/vusb/%d/%d/port", 
+                        libxl__xs_get_dompath(gc, 0), domid, usbctrl->devid);
+    if (libxl__xs_mkdir(gc, XBT_NULL, path, NULL, 0) ) {
+        return 1;
+    }
+    
+    int i, num_ports = usbctrl->num_ports;
+    for ( i = 1; i <= num_ports; ++i) {
+        if (libxl__xs_write(gc, XBT_NULL, 
+                      libxl__sprintf(gc,"%s/%d", path, i),"%s", "") ) {
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_WARNING,
+                        "Create port %d to %s failed.", i, path);
+            return 1;
+        }
+    }
+    return 0;
+}
+                              
+int libxl__device_usbctrl_add(libxl__gc *gc, uint32_t domid,
+                           libxl_device_usbctrl *usbctrl) 
+{
+    switch (libxl__domain_type(gc, domid)) {
+    case LIBXL_DOMAIN_TYPE_HVM:
+         /* TO_DO */
+        break;
+    case LIBXL_DOMAIN_TYPE_PV:
+        if (do_pvusbctrl_add(gc, domid, usbctrl) ) {
+            return ERROR_FAIL;
+        }
+
+        /* Add sub-port to Xenstore */
+        if (libxl_port_add_xenstore(gc, domid, usbctrl) ) {
+            return ERROR_FAIL;
+        }
+        break;
+    case LIBXL_DOMAIN_TYPE_INVALID:
+            return ERROR_FAIL;
+    }
+
+    return 0;
+}
+
+int libxl_device_usbctrl_add(libxl_ctx *ctx, uint32_t domid, 
+                                libxl_device_usbctrl *usbctrl, const libxl_asyncop_how *ao_how)
+{
+    AO_CREATE(ctx, domid, ao_how);
+    int rc; 
+    
+    rc = libxl__device_usbctrl_add(gc, domid, usbctrl);
+    libxl__ao_complete(egc, ao, rc);
+    return AO_INPROGRESS; 
+}
+
+libxl_device_usbctrl *libxl_device_usbctrl_list(libxl_ctx *ctx, uint32_t domid, int *num)
+{
+    GC_INIT(ctx);
+
+    libxl_device_usbctrl *usbctrls = NULL;
+    char *fe_path = NULL, *result = NULL;
+    char **dir = NULL;
+    unsigned int ndirs = 0;
+    
+    *num = 0;
+    
+    fe_path = libxl__sprintf(gc, "%s/device/vusb", libxl__xs_get_dompath(gc, domid));
+    dir = libxl__xs_directory(gc, XBT_NULL, fe_path, &ndirs);
+
+    if (dir && ndirs) {
+        usbctrls = malloc(sizeof(*usbctrls) * ndirs);
+        libxl_device_usbctrl* usbctrl;
+        libxl_device_usbctrl* end = usbctrls + ndirs;
+        for(usbctrl = usbctrls; usbctrl < end; ++usbctrl, ++dir, (*num)++) {
+            const char *be_path = libxl__xs_read(gc, XBT_NULL,
+                                    GCSPRINTF("%s/%s/backend", fe_path, *dir));
+
+            libxl_device_usbctrl_init(usbctrl);
+
+            usbctrl->devid = atoi(*dir);
+
+            result = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/%s/backend-id",
+                                                   fe_path, *dir));
+            if( result == NULL)
+                goto outerr;
+            usbctrl->backend_domid = atoi(result);
+
+            result = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/usb-ver", be_path));
+            usbctrl->usb_version =  atoi(result);
+
+            result = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/num-ports", be_path));
+            usbctrl->num_ports = atoi(result);
+       }
+    }
+    *num = ndirs;
+    
+    return usbctrls;
+outerr:
+    LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to list USB Controllers");
+    while (*num) {
+        (*num)--;
+        libxl_device_usbctrl_dispose(&usbctrls[*num]);
+    }
+    free(usbctrls);
+    return NULL;
+}
+
+static int libxl__device_usb_remove_common(libxl__gc *gc, uint32_t domid,
+                                libxl_device_usb *usb, int force);
+
+static int libxl__device_usbctrl_remove_common(libxl_ctx *ctx, uint32_t domid,
+                            libxl_device_usbctrl *usbctrl,
+                            const libxl_asyncop_how *ao_how, int force)
+{
+    AO_CREATE(ctx, domid, ao_how);
+    libxl__device *device;
+    libxl__ao_device *aodev;
+    int hvm = 0, rc;
+    libxl_device_usb *usbs;
+    int i, numusb = 0;
+    
+    GCNEW(device); 
+    rc = libxl__device_from_usbctrl(gc, domid, usbctrl, device);
+    if(rc) goto out;
+
+    switch (libxl__domain_type(gc, domid)) {
+    case LIBXL_DOMAIN_TYPE_HVM:
+        hvm = 1;
+        /* TO_DO */
+        break;
+    case LIBXL_DOMAIN_TYPE_PV:
+        /* Remove usb devives first */
+        rc  = libxl__device_usb_list(gc, domid, &usbs, usbctrl->devid, &numusb);
+        if (rc) goto out;
+        for (i = 0; i < numusb; i++) {
+            if (libxl__device_usb_remove_common(gc, domid, &usbs[i], 0)) {
+                fprintf(stderr, "libxl_device_usb_remove failed.\n");
+                return 1;
+            }
+        }
+        /* remove usbctrl */
+        GCNEW(aodev);
+        libxl__prepare_ao_device(ao, aodev);
+        aodev->action = LIBXL__DEVICE_ACTION_REMOVE; 
+        aodev->dev = device;
+        aodev->callback = device_addrm_aocomplete;
+        aodev->force = force;
+        libxl__initiate_device_remove(egc, aodev);
+        break;
+    default:
+        abort();
+    }
+    
+out:
+    if(rc) return AO_ABORT(rc);
+    return AO_INPROGRESS;
+}
+
+int libxl_device_usbctrl_remove(libxl_ctx *ctx, uint32_t domid,
+                            libxl_device_usbctrl *usbctrl,
+                            const libxl_asyncop_how *ao_how)
+{
+    return libxl__device_usbctrl_remove_common(ctx, domid, usbctrl, ao_how, 0);
+}
+
+int libxl_device_usbctrl_destroy(libxl_ctx *ctx, uint32_t domid,
+                            libxl_device_usbctrl *usbctrl,
+                            const libxl_asyncop_how *ao_how)
+{
+    return libxl__device_usbctrl_remove_common(ctx, domid, usbctrl, ao_how, 1);
+}
+
+
+int libxl_device_usbctrl_getinfo(libxl_ctx *ctx, uint32_t domid,
+                                libxl_device_usbctrl *usbctrl,
+                                libxl_usbctrlinfo *usbctrlinfo)
+{
+    GC_INIT(ctx);
+    char *dompath, *usbctrlpath;
+    char *val;
+
+    dompath = libxl__xs_get_dompath(gc, domid);
+    usbctrlinfo->devid = usbctrl->devid;
+    usbctrlinfo->num_ports = usbctrl->num_ports;
+    usbctrlinfo->version = usbctrl->usb_version;
+
+    usbctrlpath = libxl__sprintf(gc, "%s/device/vusb/%d", dompath, usbctrlinfo->devid);
+    usbctrlinfo->backend = xs_read(ctx->xsh, XBT_NULL,
+                                libxl__sprintf(gc, "%s/backend", usbctrlpath), NULL);
+    if (!usbctrlinfo->backend) {
+        GC_FREE;
+        return ERROR_FAIL;
+    }
+    
+    val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/backend-id", usbctrlpath));
+    usbctrlinfo->backend_id = val ? strtoul(val, NULL, 10) : -1;
+    val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/state", usbctrlpath));
+    usbctrlinfo->state = val ? strtoul(val, NULL, 10) : -1;
+    val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/event-channel", usbctrlpath));
+    usbctrlinfo->evtch = val ? strtoul(val, NULL, 10) : -1;
+    val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/urb-ring-ref", usbctrlpath));
+    usbctrlinfo->ref_urb = val ? strtoul(val, NULL, 10) : -1;
+    val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/conn-ring-ref", usbctrlpath));
+    usbctrlinfo->ref_conn= val ? strtoul(val, NULL, 10) : -1;
+    usbctrlinfo->type = xs_read(ctx->xsh, XBT_NULL,
+                                libxl__sprintf(gc, "%s/type", usbctrlinfo->backend), NULL);
+    usbctrlinfo->frontend = xs_read(ctx->xsh, XBT_NULL,
+                                 libxl__sprintf(gc, "%s/frontend", usbctrlinfo->backend), NULL);
+    val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/frontend-id", usbctrlinfo->backend));
+    usbctrlinfo->frontend_id = val ? strtoul(val, NULL, 10) : -1;
+
+    GC_FREE;
+    return 0;
+}
+
+int libxl_devid_to_device_usbctrl(libxl_ctx *ctx, uint32_t domid,
+                               int devid, libxl_device_usbctrl *usbctrl)
+{
+    GC_INIT(ctx);
+    char* fe_path = NULL, *be_path = NULL, *tmp; 
+
+    fe_path = libxl__sprintf(gc, "%s/device/vusb", libxl__xs_get_dompath(gc, domid));
+    be_path = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/%d/backend", fe_path, devid));
+    
+    libxl_device_usbctrl_init(usbctrl);
+    usbctrl->devid = devid;
+    tmp = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/%d/backend-id",
+                                                   fe_path, devid));
+    if( tmp == NULL)
+        return ERROR_FAIL;
+    usbctrl->backend_domid = atoi(tmp);
+
+    tmp = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/usb-ver", be_path));
+    usbctrl->usb_version =  atoi(tmp);
+
+    tmp = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/num-ports", be_path));
+    usbctrl->num_ports = atoi(tmp);
+
+    GC_FREE;
+    return 0;
+}
+
+static int libxl__device_usb_add_xenstore(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb)
+{
+    libxl_ctx *ctx = CTX; 
+    char *be_path;
+    
+    be_path = libxl__sprintf(gc, "%s/backend/vusb/%d/%d", 
+                        libxl__xs_get_dompath(gc, 0), domid, usb->ctrl);
+    libxl_domain_type domtype = libxl__domain_type(gc, domid);
+    if (domtype == LIBXL_DOMAIN_TYPE_INVALID)
+        return ERROR_FAIL;
+
+    if (domtype == LIBXL_DOMAIN_TYPE_PV) {
+        if (libxl__wait_for_backend(gc, be_path, "4") < 0)
+            return ERROR_FAIL;
+    }
+
+    be_path = libxl__sprintf(gc, "%s/port/%d", be_path, usb->port);
+    LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Adding new usb device to xenstore"); 
+    if (libxl__xs_write(gc, XBT_NULL, be_path, "%s", usb->intf) )
+        return 1;
+    
+    return 0;
+}
+
+static int libxl__device_usb_remove_xenstore(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb)
+{
+    libxl_ctx *ctx = CTX;
+    char *be_path;
+
+    be_path = libxl__sprintf(gc, "%s/backend/vusb/%d/%d",
+                        libxl__xs_get_dompath(gc, 0), domid, usb->ctrl);
+    libxl_domain_type domtype = libxl__domain_type(gc, domid);
+    if (domtype == LIBXL_DOMAIN_TYPE_INVALID)
+        return ERROR_FAIL;
+
+    if (domtype == LIBXL_DOMAIN_TYPE_PV) {
+        if (libxl__wait_for_backend(gc, be_path, "4") < 0)
+            return ERROR_FAIL;
+    }
+
+    be_path = libxl__sprintf(gc, "%s/port/%d", be_path, usb->port);
+    LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Removing USB device from xenstore");
+
+    if (libxl__xs_write(gc,XBT_NULL, be_path, "") )
+        return 1;
+
+    return 0;
+}
+
+int libxl__device_usb_assigned_list(libxl__gc *gc, libxl_device_usb **list, int *num)
+{
+    char **domlist;
+    unsigned int nd = 0, i, j;
+    char *be_path;
+    libxl_device_usb *usb;
+
+    *list = NULL;
+    *num = 0;
+
+    domlist = libxl__xs_directory(gc, XBT_NULL, "/local/domain", &nd);
+    be_path = libxl__sprintf(gc,"/local/domain/0/backend/vusb");
+    for (i = 0; i < nd; i++) {
+        char *path, *num_ports, **ctrl_list;
+        unsigned int nc = 0;
+        
+        path = libxl__sprintf(gc, "%s/%s", be_path, domlist[i]);
+        ctrl_list = libxl__xs_directory(gc, XBT_NULL, path , &nc);
+
+        for (j = 0; j < nc; j++) {
+            path = libxl__sprintf(gc, "%s/%s/%s/num-ports", be_path, domlist[i], ctrl_list[j]);
+            num_ports = libxl__xs_read(gc, XBT_NULL, path);
+            if ( num_ports ) {
+                int nport = atoi(num_ports), k;
+                char *devpath, *intf;
+
+                for (k = 1; k <= nport; k++) {
+                    devpath = libxl__sprintf(gc, "%s/%s/%s/port/%u", be_path, domlist[i], ctrl_list[j], k);
+                    intf = libxl__xs_read(gc, XBT_NULL, devpath);
+                    /* If there are USB device attached, add it to list */
+                    if (intf && strcmp(intf, "") ) {
+                        *list = realloc(*list, sizeof(libxl_device_usb) * ((*num) + 1));
+                        if (*list == NULL)
+                            return ERROR_NOMEM;
+                        usb = *list + *num;
+                        usb->ctrl = atoi(ctrl_list[j]);
+                        usb->port = k;
+                        usb->intf = strdup(intf);
+                        (*num)++;
+                    }
+                }
+            }
+        }
+    }
+    libxl__ptr_add(gc, *list);
+
+    return 0;
+}
+
+libxl_device_usb *libxl_device_usb_assigned_list(libxl_ctx *ctx, int *num)
+{
+    GC_INIT(ctx);
+    libxl_device_usb *usbs;
+    int rc;
+
+    rc = libxl__device_usb_assigned_list(gc, &usbs, num);
+
+    GC_FREE;
+    return usbs;
+}
+    
+static int is_usb_in_array(libxl_device_usb *assigned, int num_assigned, char *intf)
+{
+    int i;
+    
+    for (i = 0; i < num_assigned; i++) {
+        if (!strcmp(assigned[i].intf, intf) )
+            return 1;
+    }
+
+    return 0;
+}
+
+static int sysfs_write_intf(libxl__gc *gc, const char * sysfs_path,
+                       libxl_device_usb *usb)
+{
+    libxl_ctx *ctx = CTX;
+    char *buf;
+    int rc, fd;
+    
+    fd = open(sysfs_path, O_WRONLY);
+    if (fd < 0) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Couldn't open %s",
+                         sysfs_path);
+        return ERROR_FAIL;
+    }
+
+    /* bind the usb device to usbback */
+    buf = libxl__sprintf(gc,"%s:1.0", usb->intf);
+    rc = write(fd, buf, strlen(buf));
+    // Annoying to have two if's, but we need the errno 
+    if (rc < 0)
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+                         "write to %s returned %d", sysfs_path, rc);
+    close(fd);
+
+    if (rc < 0)
+        return ERROR_FAIL;
+    return 0;
+}
+
+static int get_usb_bDeviceClass(libxl__gc *gc, char *intf, char *buf)
+{
+    char *path;
+    FILE *fd;
+    int rc;
+
+    path = libxl__sprintf(gc, SYSFS_USB_DEVS_PATH"/%s/bDeviceClass", intf);
+    
+    /* Check if this path exist, if not return 1 */
+    if (access(path, R_OK) )
+        return 1;
+    
+    path = libxl__sprintf(gc, "cat %s", path);
+    fd = popen(path, "r");
+    rc = fscanf(fd, "%s", buf);
+    pclose(fd);
+
+    if (rc)
+        return 0;
+    return 1;
+}
+
+static int is_usb_assignable(libxl__gc *gc, char *intf)
+{
+    int usb_classcode;
+    char buf[5];
+
+    if (!get_usb_bDeviceClass(gc, intf, buf) ){
+        usb_classcode = atoi(buf);
+        if (usb_classcode != USBHUB_CLASS_CODE)
+            return 0;
+    }
+    
+    return 1;
+}
+
+libxl_device_usb *libxl_device_usb_assignable_list(libxl_ctx *ctx, int *num)
+{
+    GC_INIT(ctx);
+    libxl_device_usb *usbs = NULL, *new, *assigned;
+    struct dirent *de;
+    DIR *dir;
+    int rc, num_assigned;
+
+    *num = 0;
+
+    rc = libxl__device_usb_assigned_list(gc, &assigned, &num_assigned);
+    if ( rc )
+        goto out;
+
+    dir = opendir(SYSFS_USB_DEVS_PATH);
+    if ( NULL == dir ) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Couldn't open %s", SYSFS_USB_DEVS_PATH);
+        goto out_closedir;
+    }   
+    
+    while( (de = readdir(dir)) ) {
+        if (!de->d_name)
+            continue;
+
+        if ( is_usb_in_array(assigned, num_assigned, de->d_name) )
+            continue;
+
+        if( is_usb_assignable(gc, de->d_name) )
+            continue;
+        new = realloc(usbs, ((*num) + 1) * sizeof(*new));
+        if ( NULL == new )
+            continue;
+
+        usbs = new;
+        new = usbs + *num;
+
+        memset(new, 0, sizeof(*new));
+        new->intf = strdup(de->d_name);
+
+        (*num)++;
+    }
+
+out_closedir:
+    closedir(dir);
+out:
+    GC_FREE;
+    return usbs;
+}
+
+static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_usb *usb, 
+                                        char **driver_path)
+{
+    libxl_ctx *ctx = CTX;
+    char * spath, *dp = NULL;
+    struct stat st;
+
+    spath = libxl__sprintf(gc, SYSFS_USB_DEVS_PATH"/%s:1.0/driver",
+                          usb->intf);
+    if ( !lstat(spath, &st) ) {
+        /* Find the canousbctrlal path to the driver. */
+        dp = libxl__zalloc(gc, PATH_MAX);
+        dp = realpath(spath, dp);
+        if ( !dp ) {
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "realpath() failed");
+            return -1;
+        }
+
+        LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Driver re-plug path: %s",
+                   dp);
+
+        /* Unbind from the old driver */
+        spath = libxl__sprintf(gc, "%s/unbind", dp);
+        if ( sysfs_write_intf(gc, spath, usb) < 0 ) {
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Couldn't unbind device");
+            return -1;
+        }
+    }
+
+    if ( driver_path )
+        *driver_path = dp;
+
+    return 0;
+}
+
+static int usbback_dev_assign(libxl__gc *gc, libxl_device_usb *usb)
+{
+    libxl_ctx *ctx = CTX;
+
+    if ( sysfs_write_intf(gc, SYSFS_USBBACK_DRIVER"/bind", usb) < 0 ) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+                         "Couldn't bind device to usbback!");
+        return ERROR_FAIL;
+    }
+    return 0;
+}
+
+static int usbback_dev_unassign(libxl__gc *gc, libxl_device_usb *usb)
+{
+    libxl_ctx *ctx = CTX;
+
+    /* Remove from usbback */
+    if ( sysfs_dev_unbind(gc, usb, NULL) < 0 ) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Couldn't unbind device!");
+        return ERROR_FAIL;
+    }
+    
+    return 0;
+}
+
+#define USBBACK_INFO_PATH "/libxl/usbback"
+
+/*cann't write '.' into Xenstore. So, change all '.' to '_' */
+static void usb_interface_encode(char *interface)
+{
+    int i, len = strlen(interface);
+    for (i = 0; i < len; i++) {
+        if (interface[i] == '.')
+            interface[i] = '_';
+    }
+}
+
+static void usb_assignable_driver_path_write(libxl__gc *gc, libxl_device_usb *usb,
+                                            char *driver_path)
+{
+    libxl_ctx *ctx = CTX;
+    char *path, *intf;
+
+    intf = libxl__strdup(gc, usb->intf);
+    usb_interface_encode(intf);
+
+    path = libxl__sprintf(gc, USBBACK_INFO_PATH"/%s/driver_path", intf);
+    if ( libxl__xs_write(gc, XBT_NULL, path, "%s", driver_path) < 0 ) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_WARNING,
+                         "Write of %s to node %s failed.",
+                         driver_path, path);
+    }
+}
+
+static char * usb_assignable_driver_path_read(libxl__gc *gc, libxl_device_usb *usb)
+{
+    char *intf;
+    intf = libxl__strdup(gc, usb->intf);
+    usb_interface_encode(intf);
+
+    return libxl__xs_read(gc, XBT_NULL,libxl__sprintf(gc, 
+                    USBBACK_INFO_PATH"/%s/driver_path", intf));
+}
+
+static void usb_assignable_driver_path_remove(libxl__gc *gc, libxl_device_usb *usb)
+{
+    libxl_ctx *ctx = CTX;
+    char *intf;
+    intf = libxl__strdup(gc, usb->intf);
+    usb_interface_encode(intf);
+
+    /*Remove the xenstore entry */
+    xs_rm(ctx->xsh, XBT_NULL,
+            libxl__sprintf(gc,USBBACK_INFO_PATH"/%s/driver_path", intf));
+}
+
+#undef USBBACK_INFO_PATH
+
+static int do_usb_add (libxl__gc *gc, uint32_t domid, libxl_device_usb *usb)
+{
+    int rc = 0;
+
+    switch (libxl__domain_type(gc, domid)) {
+    case LIBXL_DOMAIN_TYPE_HVM:
+        /* TO-DO */
+        break;
+    case LIBXL_DOMAIN_TYPE_PV:
+        rc = libxl__device_usb_add_xenstore(gc, domid, usb);
+        if(rc) goto out;       
+        /*  Only after usbback automatically add 
+            inft:domid:controllerId:portId to "/sys/bus/usb/drivers/usbback/port_ids
+            can we bind the usb device to usbback. So we need to wait for this to be completed.        
+        */
+        sleep(1);
+
+        rc = usbback_dev_assign(gc, usb);
+        if(rc) {
+            libxl__device_usb_remove_xenstore(gc, domid, usb);
+            goto out;
+        }
+        break;
+    case LIBXL_DOMAIN_TYPE_INVALID:
+        return ERROR_FAIL;
+    }
+    
+out:
+    return rc;
+}
+
+static int libxl__device_set_default_usbctrl(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb)
+{
+    libxl_ctx *ctx = CTX;
+    libxl_device_usbctrl *usbctrls;
+    libxl_device_usb *usbs = NULL;
+    int numctrl, numusb, i, j, rc;
+    char *be_path, *tmp;
+
+    usbctrls = libxl_device_usbctrl_list(ctx, domid, &numctrl);
+    if ( !numctrl)
+        goto out;
+
+    for (i = 0; i < numctrl; i++) {
+        rc = libxl__device_usb_list(gc, domid, &usbs, usbctrls[i].devid, &numusb);
+        if (rc) goto out;
+        if ( !usbctrls[i].num_ports || numusb == usbctrls[i].num_ports )
+            continue;
+        for (j = 1; i <= numusb; j++) {
+            be_path = libxl__sprintf(gc, "%s/backend/vusb/%d/%d/port/%d",
+                             libxl__xs_get_dompath(gc, 0), domid, usbctrls[i].devid, j);
+            tmp = libxl__xs_read(gc, XBT_NULL, be_path);
+            if ( tmp && !strcmp( tmp, "") ) {
+                usb->ctrl = usbctrls[i].devid;
+                usb->port = j;
+                return 0;
+            }
+        }
+        free(usbs);
+    }
+
+out:
+    free(usbctrls);
+    free(usbs);
+    return 1;
+} 
+
+int libxl__device_usb_setdefault(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb)
+{
+    int rc;
+
+    switch (libxl__domain_type(gc, domid)) {
+    case LIBXL_DOMAIN_TYPE_HVM:
+        break;
+    case LIBXL_DOMAIN_TYPE_PV:
+        if (usb->ctrl == -1) {
+            if (usb->port != -1 ) {
+                LOG(ERROR, "USB controller must be specified if you specify port ID");
+                return ERROR_INVAL;
+            }   
+              
+            rc = libxl__device_set_default_usbctrl(gc, domid, usb);
+            /* If no existing ctrl to host this usb device, setup a new one */
+            if (rc) {
+                libxl_device_usbctrl usbctrl;
+                libxl_device_usbctrl_init(&usbctrl);
+                libxl__device_usbctrl_add(gc, domid, &usbctrl);
+                usb->ctrl = usbctrl.devid;
+                usb->port = 1;
+                libxl_device_usbctrl_dispose(&usbctrl);
+            } 
+        }
+
+        if (usb->port == -1) {
+            char *be_path = libxl__sprintf(gc, "%s/backend/vusb/%d/path/%d",
+                        libxl__xs_get_dompath(gc, 0), usb->ctrl, usb->port);
+            char *tmp = libxl__xs_read(gc, XBT_NULL, be_path);
+            if ( !tmp || strcmp(tmp, "") ){
+                LOG(ERROR, "The controller port doesn't exist or it has been assigned to another device");
+                return ERROR_INVAL;
+            }
+        }
+        break;
+    case LIBXL_DOMAIN_TYPE_INVALID:
+        return ERROR_FAIL;
+    default:
+        abort();
+    }
+
+    return 0;
+}
+
+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;
+}
+
+int libxl__device_usb_add(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb)
+{
+    libxl_ctx *ctx = CTX;
+    libxl_device_usb *assigned;
+    int rc, num_assigned;
+    char *driver_path;
+
+    rc = libxl__device_usb_setdefault(gc, domid, usb);
+    if (rc) goto out;
+    
+    rc = libxl__device_usb_assigned_list(gc, &assigned, &num_assigned);
+    if ( rc ) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, 
+             "cannot determine if USB device is assigned, refusing to continue");
+        goto out;
+    }
+
+    if ( is_usb_in_array(assigned, num_assigned, usb->intf) ) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "USB device already attached to a domain");
+        rc = ERROR_FAIL;
+        goto out;
+    }
+    
+    /* Check to see if there's already a driver that we need to unbind from */
+    if ( sysfs_dev_unbind(gc, usb, &driver_path ) ) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+                   "Couldn't unbind %s from driver", usb->intf);
+        return ERROR_FAIL;
+    }
+
+    /* Store driver_path for rebinding to dom0 */
+    if ( driver_path ) {
+        usb_assignable_driver_path_write(gc, usb, driver_path);
+    } else {
+        LIBXL__LOG(ctx, LIBXL__LOG_WARNING,
+                   "%s not bound to a driver, will not be rebound.", usb->intf);
+    }
+    
+    if (do_usb_add(gc, domid, usb) ) 
+       return ERROR_FAIL;
+ 
+out:
+    return rc;
+}
+
+static int do_usb_remove(libxl__gc *gc, uint32_t domid,
+                        libxl_device_usb *usb, int force)
+{
+
+    libxl_ctx *ctx = CTX;
+    libxl_device_usb *assigned;
+    int rc, num;
+
+    assigned = libxl_device_usb_list_all(gc, domid, &num);
+    if ( assigned == NULL ) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "There is no USB device attached to this domain");
+        return ERROR_FAIL;
+    }
+
+    rc = ERROR_INVAL;
+    if ( !is_usb_in_array(assigned, num, usb->intf) ) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "USB device not attached to this domain");
+        goto out_fail;
+    }
+
+    rc = ERROR_FAIL;
+    switch (libxl__domain_type(gc, domid)) {
+    case LIBXL_DOMAIN_TYPE_HVM:
+        //TO-DO
+        break;
+    case LIBXL_DOMAIN_TYPE_PV:
+        //unbind USB device from usbback TO-DO
+        rc = usbback_dev_unassign(gc, usb);
+
+        if (rc) return rc;
+        rc = libxl__device_usb_remove_xenstore(gc, domid, usb);
+        if(rc) 
+            return rc;
+        break;
+    default:
+        abort();
+    }
+out_fail:
+    return 0;
+}
+
+static int libxl__device_usb_remove_common(libxl__gc *gc, uint32_t domid,
+                                libxl_device_usb *usb, int force)
+{
+    libxl_ctx *ctx = CTX;
+    int rc;
+    char *driver_path;
+
+    rc = do_usb_remove(gc, domid, usb, force);
+
+    if (rc)
+        return ERROR_INVAL;
+    
+    /* Rebind if necessary */
+    driver_path = usb_assignable_driver_path_read(gc, usb);
+
+    if ( driver_path ) {
+        LIBXL__LOG(ctx, LIBXL__LOG_INFO, "Rebinding USB device %s to driver at %s",
+                                        usb->intf, driver_path);
+
+        if ( sysfs_write_intf(gc, libxl__sprintf(gc, "%s/bind", driver_path),
+                                 usb) < 0 ) {
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+                             "Couldn't bind device to %s", driver_path);
+            return -1;
+        }
+    }
+
+    usb_assignable_driver_path_remove(gc, usb);
+
+    return 0;
+}
+
+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_common(gc, domid, usb, 0);
+
+    libxl__ao_complete(egc, ao, rc);
+    return AO_INPROGRESS;
+}
+            
+int libxl_device_usb_destroy(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_common(gc, domid, usb, 1);
+
+    libxl__ao_complete(egc, ao, rc);
+    return AO_INPROGRESS;
+}
+
+
+int libxl__device_usb_list(libxl__gc *gc, uint32_t domid, libxl_device_usb **usbs, int usbctrl, int *num)
+{
+    char *be_path, *num_devs;
+    int n, i;
+    libxl_device_usb *usb;
+    
+    *usbs = NULL;
+    *num = 0;
+
+    be_path = libxl__sprintf(gc, "%s/backend/vusb/%d/%d", libxl__xs_get_dompath(gc, 0), domid, usbctrl);
+    num_devs = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/num-ports", be_path));
+    if (!num_devs)
+        goto out;
+
+    n = atoi(num_devs);
+    *usbs = calloc(n, sizeof(libxl_device_usb));
+
+    char *intf;
+    for (i = 0; i < n; i++) {
+        intf = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc,"%s/port/%d", be_path, i + 1));
+        if ( intf && strcmp(intf, "") ) {
+            usb = *usbs + *num;
+            usb->intf = strdup(intf);
+            usb->port = i + 1;
+            usb->ctrl = usbctrl;
+            (*num)++;
+        }
+    }
+out:
+    return 0;
+}
+
+libxl_device_usb *libxl_device_usb_list(libxl_ctx *ctx, uint32_t domid, int usbctrl, int *num)
+{
+    GC_INIT(ctx);
+    libxl_device_usb *usbs;
+    int rc;
+
+    rc = libxl__device_usb_list(gc, domid, &usbs, usbctrl, num);
+
+    if (rc)
+        free(usbs);
+    GC_FREE;
+    return usbs;
+}
+
+libxl_device_usb *libxl_device_usb_list_all(libxl__gc *gc, uint32_t domid, int *num)
+{
+    char **usblist;
+    unsigned int nd, i, j;
+    char *be_path;
+    int rc;
+    libxl_device_usb *usbs = NULL;
+
+    *num = 0;
+
+    be_path = libxl__sprintf(gc,"/local/domain/0/backend/vusb/%d", domid);
+    usblist = libxl__xs_directory(gc, XBT_NULL, be_path, &nd);
+
+    for (i = 0; i < nd; i++) { 
+        int nc = 0;
+        libxl_device_usb *tmp;
+        rc = libxl__device_usb_list(gc, domid, &tmp, atoi(usblist[i]), &nc);
+        if (!nc) 
+            continue;
+        usbs = realloc(usbs, sizeof(libxl_device_usb)*((*num) + nc));
+        /* TO-DO
+        if (usbs == NULL)
+            return ERROR_NOMEM;
+        */
+        for(j = 0; j < nc; j++) {
+            usbs[*num].ctrl = tmp[j].ctrl;
+            usbs[*num].port = tmp[j].port;
+            usbs[*num].intf = strdup(tmp[j].intf);
+            (*num)++;
+        }
+        free(tmp);
+    }
+    return usbs;
+}
+
+int libxl__device_usb_destroy_all(libxl__gc *gc, uint32_t domid)
+{
+    libxl_ctx *ctx = CTX;
+    libxl_device_usbctrl *usbctrls;
+    int num, i, rc = 0;
+
+    usbctrls = libxl_device_usbctrl_list(ctx, domid, &num);
+    if ( usbctrls == NULL )
+        return 0;
+
+    for (i = 0; i < num; i++) {
+        /* Force remove on shutdown since, on HVM, qemu will not always
+         * respond to SCI interrupt because the guest kernel has shut down the
+         * devices by the time we even get here!
+         */
+        if (libxl__device_usbctrl_remove_common(ctx, domid, usbctrls + i, 0, 1) < 0)
+            rc = ERROR_FAIL;
+    }
+
+    free(usbctrls);
+    return 0;
+}
+
+/* TO-DO: map the "lsusb" bus:addr to the sysfs usb address
+static int libxl_hostdev_to_intf(libxl__gc *gc, libxl_device_usb *usb)
+{
+    return 0;
+}
+*/
+
+#define BUF_SIZE 20
+/*use system call popen to get usb device information */
+static int get_usb_devnum (libxl__gc *gc, const char *intf, char *buf)
+{
+    char *path;
+    int rc;
+    FILE *fd;
+
+    path = libxl__sprintf(gc, "cat "SYSFS_USB_DEVS_PATH"/%s/devnum", intf);
+    fd = popen(path, "r");
+    rc = fscanf(fd, "%s", buf);
+    pclose(fd);
+
+    if (rc) return 0;
+    return 1;
+}
+
+static int get_usb_busnum(libxl__gc *gc, const char *intf, char *buf)
+{
+    char *path;
+    int rc;
+    FILE *fd;
+
+    path = libxl__sprintf(gc, "cat "SYSFS_USB_DEVS_PATH"/%s/busnum", intf);
+    fd = popen(path, "r");
+    rc = fscanf(fd, "%s", buf);
+    pclose(fd);
+
+    if (rc) return 0;
+    return 1;
+}
+
+static int get_usb_idVendor(libxl__gc *gc, const char *intf, char *buf)
+{
+    char *path;
+    int rc;
+    FILE *fd;
+
+    path = libxl__sprintf(gc, "cat "SYSFS_USB_DEVS_PATH"/%s/idVendor", intf);
+    fd = popen(path, "r");
+    rc = fscanf(fd, "%s", buf);
+    pclose(fd);
+
+    if (rc) return 0;
+    return 1;
+}
+
+static int get_usb_idProduct(libxl__gc *gc, const char *intf, char *buf)
+{
+    char *path;
+    int rc;
+    FILE *fd;
+
+    path = libxl__sprintf(gc, "cat "SYSFS_USB_DEVS_PATH"/%s/idProduct", intf);
+    fd = popen(path, "r");
+    rc = fscanf(fd, "%s", buf);
+    pclose(fd);
+
+    if (rc) return 0;
+    return 1;
+}
+
+static int get_usb_manufacturer(libxl__gc *gc, const char *intf, char *buf)
+{
+    char *path;
+    int rc;
+    FILE *fd;
+
+    path = libxl__sprintf(gc, "cat "SYSFS_USB_DEVS_PATH"/%s/manufacturer", intf);
+    fd = popen(path, "r");
+    rc = fscanf(fd, "%s", buf);
+    pclose(fd);
+
+    if (rc) return 0;
+    return 1;
+}
+
+static int get_usb_product(libxl__gc *gc, const char *intf, char *buf)
+{
+    char *path;
+    int rc;
+    FILE *fd;
+
+    path = libxl__sprintf(gc, "cat "SYSFS_USB_DEVS_PATH"/%s/product", intf);
+    fd = popen(path, "r");
+    rc = fscanf(fd, "%s", buf);
+    pclose(fd);
+
+    if (rc) return 0;
+    return 1;
+}
+
+int libxl_device_usb_getinfo(libxl_ctx *ctx, char *intf, libxl_usbinfo *usbinfo)
+{
+    GC_INIT(ctx);
+    char buf[20];
+
+    //change usb, why!!!!????
+    // maybe some better method to get this parameter
+
+    if (!get_usb_devnum(gc, intf, buf) ) 
+        usbinfo->devnum = atoi(buf);
+
+    if ( !get_usb_busnum(gc, intf, buf))
+        usbinfo->bus = atoi(buf);
+
+    if (!get_usb_idVendor(gc, intf, buf) )
+         usbinfo->idVendor = atoi(buf);
+
+    if (!get_usb_idProduct(gc, intf, buf) )
+        usbinfo->idProduct  = atoi(buf);
+
+    if (!get_usb_manufacturer(gc, intf, buf) )
+        usbinfo->manuf = strdup(buf);        
+    
+    if (!get_usb_product(gc, intf, buf) )
+        usbinfo->prod = strdup(buf);
+    
+    GC_FREE;
+    return 0; 
+}
+
+int libxl_hostdev_to_device_usb(libxl_ctx *ctx, uint32_t domid,
+                               int devid, libxl_device_usb *usb)
+{
+    return 0;
+}
+
+//If specified by user, no need to convert; otherwise, search for it
+int libxl_intf_to_device_usb(libxl_ctx *ctx, uint32_t domid,
+                               char *intf, libxl_device_usb *usb)
+{
+    GC_INIT(ctx);
+    libxl_device_usb *usbs;
+
+    int rc, num, i;
+
+    rc = libxl__device_usb_assigned_list(gc, &usbs, &num);
+    if(rc) goto out; 
+    
+    for (i = 0; i < num; i++) {
+        if (!strcmp(intf, usbs[i].intf) ) {
+            usb->ctrl = usbs[i].ctrl;
+            usb->port = usbs[i].port;
+            usb->intf = strdup(usbs[i].intf);
+            free(usbs);
+            return 0;
+        }
+    }
+out:
+    GC_FREE;
+    free(usbs);
+    return 1;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
1.7.10.4


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

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v0 RFC 2/2] xl: Add commands for usb hot-plug
  2014-08-10 20:23 [PATCH v0 RFC 0/2] xl/libxl support for PVUSB Bo Cao
  2014-08-10 20:23 ` [PATCH v0 RFC 1/2] libxl: Introduce functions in libxl to add and remove USB devices for an PV guest Bo Cao
@ 2014-08-10 20:23 ` Bo Cao
  2014-08-14 15:04 ` [PATCH v0 RFC 0/2] xl/libxl support for PVUSB George Dunlap
  2014-11-10  8:37 ` Chun Yan Liu
  3 siblings, 0 replies; 12+ messages in thread
From: Bo Cao @ 2014-08-10 20:23 UTC (permalink / raw)
  To: xen-devel; +Cc: Lars Kurth, Ian Campbell, George Dunlap, Ian Jackson, Bo Cao

Add xl commands for USB hot-plug.

Signed-off-by: Simon Cao <caobosimon@gmail.com>
---
CC: George Dunlap <george.dunlap@eu.citrix.com>
CC: Ian Jackson <ian.jackson@citrix.com>
CC: Ian Campbell <ian.campbell@citrix.com>
CC: Pasi Kärkkäinen <pasik@iki.fi>
CC: Lars Kurth <lars.kurth@citrix.com>
---
 tools/libxl/xl.h          |    7 +
 tools/libxl/xl_cmdimpl.c  |  320 ++++++++++++++++++++++++++++++++++++++++++++-
 tools/libxl/xl_cmdtable.c |   33 +++++
 3 files changed, 359 insertions(+), 1 deletion(-)

diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h
index 10a2e66..6cde0fb 100644
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -84,6 +84,13 @@ int main_blockdetach(int argc, char **argv);
 int main_vtpmattach(int argc, char **argv);
 int main_vtpmlist(int argc, char **argv);
 int main_vtpmdetach(int argc, char **argv);
+int main_usbassignable_list(int argc, char **argv);
+int main_usbassigned_list(int argc, char **argv);
+int main_usbctrl_attach(int argc, char **argv);
+int main_usbctrl_detach(int argc, char **argv);
+int main_usbattach(int argc, char **argv);
+int main_usbdetach(int argc, char **argv);
+int main_usblist(int argc, char **argv);
 int main_uptime(int argc, char **argv);
 int main_claims(int argc, char **argv);
 int main_tmem_list(int argc, char **argv);
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 64a1c77..5dba5ec 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -701,7 +701,7 @@ static void parse_config_data(const char *config_source,
     const char *buf;
     long l;
     XLU_Config *config;
-    XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms;
+    XLU_ConfigList *cpus, *vbds, *nics, *pcis, *usbs, *cvfbs, *cpuids, *vtpms;
     XLU_ConfigList *ioports, *irqs, *iomem;
     int num_ioports, num_irqs, num_iomem;
     int pci_power_mgmt = 0;
@@ -1460,6 +1460,44 @@ skip_vfb:
             libxl_defbool_set(&b_info->u.pv.e820_host, true);
     }
 
+    if (!xlu_cfg_get_list (config, "usb", &usbs, 0, 0) ) {
+        d_config->num_usbs = 0;
+        d_config->usbs = NULL;
+        while ((buf = xlu_cfg_get_listitem (usbs, d_config->num_usbs)) != NULL) {
+            libxl_device_usb *usb;
+            char *buf2 = strdup(buf);
+            char *p, *p2;
+    
+            d_config->usbs = (libxl_device_usb *) realloc(d_config->usbs, 
+                                sizeof (libxl_device_usb) * (d_config->num_usbs+1));
+            usb = d_config->usbs + d_config->num_usbs;
+            libxl_device_usb_init(usb);
+
+            p = strtok(buf2, ",");
+            if(p) {
+                usb->port = -1;
+                usb->ctrl = -1;
+                do {
+                    while(*p == ' ')
+                        ++p;
+                    if ((p2 = strchr(p, '=')) == NULL)
+                     break;
+                    *p2 = '\0';
+                    if (!strcmp(p, "type")) {
+                        //Set type in libxl_device_usb
+                    } else if (!strcmp(p, "interface") ){
+                        usb->intf = strdup(p2 + 1);
+                    } else {
+                        fprintf(stderr, "Unknown string `%s' in usb spec\n", p);
+                        exit(1);
+                    }
+                } while ((p = strtok(NULL, ",")) != NULL);
+            }
+            free(buf2);
+            d_config->num_usbs++;
+        }
+    }
+
     switch (xlu_cfg_get_list(config, "cpuid", &cpuids, 0, 1)) {
     case 0:
         {
@@ -2734,6 +2772,286 @@ int main_cd_insert(int argc, char **argv)
     return 0;
 }
 
+static void usbinfo_print(libxl_device_usb *usbs, int num) {
+    int i;
+    if ( usbs == NULL )
+         return;
+    libxl_usbinfo usbinfo;
+    for (i = 0; i < num; i++) {
+        /* TO BE Improved */
+        if (usbs[i].port )
+            printf("Port %d:", usbs[i].port);
+        printf("Interface %8s ", usbs[i].intf);
+        if (!libxl_device_usb_getinfo(ctx, usbs[i].intf, &usbinfo)) {
+            printf("Bus %03d Dev %03d: %04d:%04d %s %s\n",
+                    usbinfo.bus, usbinfo.devnum, usbinfo.idVendor,
+                    usbinfo.idProduct, usbinfo.manuf, usbinfo.prod);
+        }
+        libxl_usbinfo_dispose(&usbinfo);
+    }
+} 
+
+
+static void usb_assignable_list(void)
+{
+    libxl_device_usb *usbs;
+    int num;
+
+    usbs = libxl_device_usb_assignable_list(ctx, &num);
+    
+    usbinfo_print(usbs, num);
+
+    free(usbs);
+}
+
+int main_usbassignable_list(int argc, char **argv)
+{
+    int opt;
+    
+    SWITCH_FOREACH_OPT(opt, "", NULL, "usb-assignable-list", 0) {
+        /* No options */
+    }
+    
+    usb_assignable_list();
+    return 0;   
+}
+
+static void usb_assigned_list(void)
+{
+    libxl_device_usb *usbs;
+    int num;
+    usbs = libxl_device_usb_assigned_list(ctx, &num);
+    
+    usbinfo_print(usbs, num);
+    free(usbs);
+}
+
+int main_usbassigned_list(int argc, char **argv)
+{
+    int opt;
+    SWITCH_FOREACH_OPT(opt, "", NULL, "usb-assignable-list", 0) {
+        /* No options */
+    }
+    
+    usb_assigned_list();
+    return 0;
+}
+
+int main_usbctrl_attach(int argc, char **argv)
+{
+    uint32_t domid;
+    int opt;
+    char *oparg;
+    libxl_device_usbctrl usbctrl;
+    
+    SWITCH_FOREACH_OPT(opt, "", NULL, "usb-controller-attach", 1) {
+        /* No options */
+    }
+    
+    domid = find_domain(argv[optind]);
+    
+    libxl_device_usbctrl_init(&usbctrl);
+    
+    for (argv += optind+1, argc -= optind+1; argc > 0; ++argv, --argc) {
+        if (MATCH_OPTION("name", *argv, oparg)) {
+            replace_string(&usbctrl.name, oparg);
+        } else if (MATCH_OPTION("type",  *argv, oparg)) {
+            if (!strcmp("pv", oparg)) {
+                usbctrl.type = LIBXL_USBCTRL_TYPE_PV;
+            } else if(!strcmp("ioemu", oparg)) {
+                usbctrl.type = LIBXL_USBCTRL_TYPE_DEVICEMODEL;
+            } else {
+                fprintf(stderr, "Invalid parameter `type'.\n");
+                return 1;
+            }
+        } else if (MATCH_OPTION("version", *argv, oparg)) {
+            usbctrl.usb_version = atoi(oparg);
+        } else if (MATCH_OPTION("num_ports", *argv, oparg)) {
+            usbctrl.num_ports = atoi(oparg);
+        }  else {
+            fprintf(stderr, "unrecognized argument `%s'\n", *argv);
+            return 1;
+        }
+    }
+
+    if (dryrun_only) {
+       char* json = libxl_device_usbctrl_to_json(ctx, &usbctrl);
+       printf("usb controller: %s\n", json);
+       free(json);
+       libxl_device_usbctrl_dispose(&usbctrl);
+       if (ferror(stdout) || fflush(stdout)) { perror("stdout"); exit(-1); }
+       return 0;
+    }
+    
+    if (libxl_device_usbctrl_add(ctx, domid, &usbctrl, 0)) {
+        fprintf(stderr, "libxl_device_usbctrl_add failed.\n");
+        return 1;
+    }
+    libxl_device_usbctrl_dispose(&usbctrl);
+    return 0; 
+}
+
+int main_usbctrl_detach(int argc, char **argv)
+{
+    uint32_t domid;
+    int opt;
+    libxl_device_usbctrl usbctrl;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "usb-controller-dettach", 2) {
+        /* No options */
+    }
+
+    domid = find_domain(argv[optind]);
+
+    libxl_device_usbctrl_init(&usbctrl);
+
+    if (libxl_devid_to_device_usbctrl(ctx, domid, atoi(argv[optind+1]), &usbctrl)) {
+        fprintf(stderr, "Unknown device %s.\n", argv[optind+1]);
+        return 1;
+    }
+
+    if(libxl_device_usbctrl_remove(ctx, domid, &usbctrl, 0)) {
+        fprintf(stderr, "libxl_device_usbctrl_add failed.\n");
+        return 1;
+    }
+    libxl_device_usbctrl_dispose(&usbctrl);
+    return 0;
+    
+}
+
+int main_usbattach(int argc, char **argv)
+{
+    uint32_t domid;
+    int opt;
+    char *oparg;
+    libxl_device_usb usb;
+    
+    SWITCH_FOREACH_OPT(opt, "", NULL, "usb-attach", 1) {
+        /* No options */
+    }
+    domid = find_domain(argv[optind]);
+
+    libxl_device_usb_init(&usb);
+    
+    /* set default value for usb.ctrl and usb.port */
+    usb.ctrl = -1, usb.port = -1;
+    for (argv += optind+1, argc -= optind+1; argc > 0; ++argv, --argc) {
+        if (MATCH_OPTION("controller", *argv, oparg)) {
+            usb.ctrl = atoi(oparg);
+        } else if (MATCH_OPTION("hostdev", *argv, oparg)) {
+            /* TO-DO: convert the "lsusb" bus:addr to the sysfs usb address */
+        } else if (MATCH_OPTION("intf", *argv, oparg)) {
+            replace_string(&usb.intf, oparg);
+        } else if (MATCH_OPTION("port", *argv, oparg)) {
+            usb.port = atoi(oparg);
+        } else {
+            fprintf(stderr, "unrecognized argument `%s'\n", *argv);
+            return 1;
+        }
+
+    }
+
+    if (dryrun_only) {
+        char *json = libxl_device_usb_to_json(ctx, &usb);
+        printf("usb: %s\n", json);
+        free(json);
+        libxl_device_usb_dispose(&usb);
+        if (ferror(stdout) || fflush(stdout)) { perror("stdout"); exit(-1); }
+        return 0;
+    }
+    
+    if (libxl_device_usb_add(ctx, domid, &usb, 0)) {
+        fprintf(stderr, "libxl_device_usb_add failed.\n");
+        return 1;
+    }
+    
+    libxl_device_usb_dispose(&usb);
+    return 0;
+}
+
+int main_usbdetach(int argc, char **argv)
+{
+    uint32_t domid;
+    int opt;
+    libxl_device_usb usb;
+    char *oparg;
+    
+    SWITCH_FOREACH_OPT(opt, "", NULL, "usb-detach", 2) {
+        /* No options */
+    }
+
+    domid = find_domain(argv[optind]);
+
+    libxl_device_usb_init(&usb);
+
+    for (argv += optind+1, argc -= optind+1; argc > 0; ++argv, --argc) {
+        if (MATCH_OPTION("controller", *argv, oparg)) {
+            usb.ctrl = atoi(oparg);
+        } else if (MATCH_OPTION("intf", *argv, oparg)) {
+            replace_string(&usb.intf, oparg);
+        } else if (MATCH_OPTION("port", *argv, oparg)) {
+            usb.port = atoi(oparg);
+        } else {
+            fprintf(stderr, "unrecognized argument `%s'\n", *argv);
+            return 1;
+        }
+    }
+
+    if (libxl_intf_to_device_usb(ctx, domid, usb.intf, &usb) ) {
+        fprintf(stderr, "libxl_intf_to_device_usb failed.\n");
+        return 1;
+    }
+
+    if (libxl_device_usb_remove(ctx, domid, &usb, 0) ) {
+        fprintf(stderr, "libxl_device_usb_remove failed.\n");
+        return 1;
+    }
+    libxl_device_usb_dispose(&usb);
+    return 0;
+}
+
+int main_usblist(int argc, char **argv)
+{
+    uint32_t domid;
+    libxl_device_usbctrl *usbctrls;
+    libxl_device_usb *usbs;
+    libxl_usbctrlinfo usbctrlinfo;
+    int numctrl, numusb, i, opt;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "usb-list", 1) {
+        /* No options */
+    }
+
+    for (argv += optind, argc -= optind; argc > 0; --argc, ++argv) {
+        domid = find_domain(*argv);
+        usbctrls = libxl_device_usbctrl_list(ctx, domid, &numctrl);
+        if (!usbctrls) {
+            continue;
+        }
+        for (i = 0; i < numctrl; ++i) {
+            /* Idx  type BE state usb-ver BE-path */ 
+            printf("%-3s %-5s %-3s %-5s %-7s  %-30s\n",
+                    "Idx", "type", "BE", "state", "usb-ver", "BE-path");
+    
+            if (!libxl_device_usbctrl_getinfo(ctx, domid, 
+                                    &usbctrls[i], &usbctrlinfo)) {
+                printf("%-3d %-5s %-3d %-5d %-7d %-30s\n",
+                        i, usbctrlinfo.type, usbctrlinfo.backend_id,
+                        usbctrlinfo.state, usbctrlinfo.version,
+                        usbctrlinfo.backend );
+
+                usbs = libxl_device_usb_list(ctx, domid, usbctrlinfo.devid, &numusb);
+                usbinfo_print(usbs, numusb);
+
+                libxl_usbctrlinfo_dispose(&usbctrlinfo);
+            }
+            libxl_device_usbctrl_dispose(&usbctrls[i]); 
+        }
+        free(usbctrls);
+    }
+    return 0;
+}
+
 int main_console(int argc, char **argv)
 {
     uint32_t domid;
diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c
index 4279b9f..d2da271 100644
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -194,6 +194,39 @@ struct cmd_spec cmd_table[] = {
       "Eject a cdrom from a guest's cd drive",
       "<Domain> <VirtualDevice>",
     },
+	{ "usb-assignable-list",
+	  &main_usbassignable_list, 0, 0,
+	  "List all the assignable USB devices",
+	},
+	{ "usb-assigned-list",
+	  &main_usbassigned_list, 0, 0,
+	  "List all the USB devices that have been assigned",
+	},
+	{ "usb-controller-attach",
+	  &main_usbctrl_attach, 1, 1,
+	  "Create a virtual USB controller for a domain",
+	  "<Domain> [version=<version>] [numberOfPorts=<number>] [type=<type>]",
+	},
+	{ "usb-controller-detach",
+	  &main_usbctrl_detach, 0, 1,
+	  "Destory the virtual USB controller specified by <ControllerName> for a domain",
+	  "<Domain> <DevId|ControllerName['pv0'|'hci0'|..]>",
+	},
+	{ "usb-attach",
+	  &main_usbattach, 1, 1,
+	  "Attach a USB device to a domain",
+	  "<Domain> <hostdev=<Hostbus.Hostdev>> [ControllerName['pv0'|'hci0']]",
+	},
+	{ "usb-detach",
+	  &main_usbdetach, 0, 1,
+	  "Detach a USB device from a domain",
+	  "<Domain> <DevId|<Hostbus.Hostdev>>",
+	},
+	{ "usb-list",
+	  &main_usblist, 0, 0,
+	  "List information about USB devices for a domain",
+	  "<Domain>",
+	},
     { "mem-max",
       &main_memmax, 0, 1,
       "Set the maximum amount reservation for a domain",
-- 
1.7.10.4


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

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v0 RFC 1/2] libxl: Introduce functions in libxl to add and remove USB devices for an PV guest
  2014-08-10 20:23 ` [PATCH v0 RFC 1/2] libxl: Introduce functions in libxl to add and remove USB devices for an PV guest Bo Cao
@ 2014-08-12 16:11   ` Ian Jackson
  2014-08-13 13:18     ` Simon Cao
  0 siblings, 1 reply; 12+ messages in thread
From: Ian Jackson @ 2014-08-12 16:11 UTC (permalink / raw)
  To: Bo Cao; +Cc: George Dunlap, Lars Kurth, xen-devel, Ian Campbell

Bo Cao writes ("[Xen-devel][PATCH v0 RFC 1/2] libxl: Introduce functions in libxl to add and remove USB devices for an PV guest"):
> This patch exposes a generic interface which can be expanded in the
> future to implement USB for DEVICEMODEL. 

Thanks.  Can you arrange to wrap this code to 70-75 characters
please ?  It currently is very hard to read in my mailreader.


>  /* generic callback for devices that only need to set ao_complete */
> -static void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev)
> +void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev)
>  {

Extern functions must have namespaced names.  (libxl__...)


I noticed several C++-style // comments.  We generally use /* */.


That's all I spotted right away.  I'll take a proper look when it's
less wrap-damaged.

Thanks,
Ian.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v0 RFC 1/2] libxl: Introduce functions in libxl to add and remove USB devices for an PV guest
  2014-08-12 16:11   ` Ian Jackson
@ 2014-08-13 13:18     ` Simon Cao
  0 siblings, 0 replies; 12+ messages in thread
From: Simon Cao @ 2014-08-13 13:18 UTC (permalink / raw)
  To: Ian Jackson; +Cc: George Dunlap, Lars Kurth, xen-devel, Ian Campbell


[-- Attachment #1.1: Type: text/plain, Size: 1274 bytes --]

On Wed, Aug 13, 2014 at 12:11 AM, Ian Jackson <Ian.Jackson@eu.citrix.com>
wrote:

> Bo Cao writes ("[Xen-devel][PATCH v0 RFC 1/2] libxl: Introduce functions
> in libxl to add and remove USB devices for an PV guest"):
> > This patch exposes a generic interface which can be expanded in the
> > future to implement USB for DEVICEMODEL.
>
> Thanks.  Can you arrange to wrap this code to 70-75 characters
> please ?  It currently is very hard to read in my mailreader.
>
> yes, I will wrap that in the next version.

>
> >  /* generic callback for devices that only need to set ao_complete */
> > -static void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device
> *aodev)
> > +void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev)
> >  {
>
> Extern functions must have namespaced names.  (libxl__...)
>
> I have forgotten to modify this back to its original version since I won't
need it any more in this patch.
I will modify this in the next version.

>
> I noticed several C++-style // comments.  We generally use /* */.
>
> I will take care of this right away.

>
> That's all I spotted right away.  I'll take a proper look when it's
> less wrap-damaged.
>
> Thanks,
> Ian.
>
Thanks, I will send a renewed version as soon as possible.

Regards,
-Simon

[-- Attachment #1.2: Type: text/html, Size: 2244 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

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

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v0 RFC 0/2] xl/libxl support for PVUSB
  2014-08-10 20:23 [PATCH v0 RFC 0/2] xl/libxl support for PVUSB Bo Cao
  2014-08-10 20:23 ` [PATCH v0 RFC 1/2] libxl: Introduce functions in libxl to add and remove USB devices for an PV guest Bo Cao
  2014-08-10 20:23 ` [PATCH v0 RFC 2/2] xl: Add commands for usb hot-plug Bo Cao
@ 2014-08-14 15:04 ` George Dunlap
  2014-08-14 15:46   ` Simon Cao
  2014-11-10  8:37 ` Chun Yan Liu
  3 siblings, 1 reply; 12+ messages in thread
From: George Dunlap @ 2014-08-14 15:04 UTC (permalink / raw)
  To: Bo Cao; +Cc: Ian Jackson, xen-devel@lists.xensource.com, Ian Campbell,
	Lars Kurth

On Sun, Aug 10, 2014 at 4:23 PM, Bo Cao <caobosimon@gmail.com> wrote:
> 2. sysfs_intf_write
>     In the process of "xl usb-attach domid intf=1-1", after writing "1-1" to Xenstore entry, we need to
> bind the controller of this usb device to usbback driver so that it can be used by VM Guest. For exampele,
> for usb device "1-1", it's controller interface maybe "1-1:1.0", and we write this value to "/sys/bus/usb/driver/usbback/bind".
> But for some devices, they have two controllers, for example "1-1:1.0" and "1-1:1.1". I think this means it has two functions,
> such as usbhid and usb-storage. So in this case, we bind the two controller to usbback?

So looking at tools/python/xen/util/vusb_util.c:bind_usb_device(), it
looks like what xend did was take the "device" (which would be "1-1"),
and search the sysfs usb node for all "interfaces" (which would be
"1-1:.*"), and then unbind each of them and bind them to usbback.

(Obviously I needed to check out a 4.4 branch to look at the xend
code, since it's been deleted in the development branch.)

 -George

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v0 RFC 0/2] xl/libxl support for PVUSB
  2014-08-14 15:04 ` [PATCH v0 RFC 0/2] xl/libxl support for PVUSB George Dunlap
@ 2014-08-14 15:46   ` Simon Cao
  0 siblings, 0 replies; 12+ messages in thread
From: Simon Cao @ 2014-08-14 15:46 UTC (permalink / raw)
  To: George Dunlap
  Cc: Ian Jackson, xen-devel@lists.xensource.com, Ian Campbell,
	Lars Kurth


[-- Attachment #1.1: Type: text/plain, Size: 1509 bytes --]

Yes, I reviewed the codes in tools/python/xen/util/vusb_
util.c:bind_usb_device()
and what Xend did was take the "device" (which would be "1-1"),
and search the sysfs usb node for all "interfaces" (which would be
"1-1:.*"), and then unbind each of them and bind them to usbback.

This helps a lot.

Thanks!
-Bo


On Thu, Aug 14, 2014 at 11:04 PM, George Dunlap <George.Dunlap@eu.citrix.com
> wrote:

> On Sun, Aug 10, 2014 at 4:23 PM, Bo Cao <caobosimon@gmail.com> wrote:
> > 2. sysfs_intf_write
> >     In the process of "xl usb-attach domid intf=1-1", after writing
> "1-1" to Xenstore entry, we need to
> > bind the controller of this usb device to usbback driver so that it can
> be used by VM Guest. For exampele,
> > for usb device "1-1", it's controller interface maybe "1-1:1.0", and we
> write this value to "/sys/bus/usb/driver/usbback/bind".
> > But for some devices, they have two controllers, for example "1-1:1.0"
> and "1-1:1.1". I think this means it has two functions,
> > such as usbhid and usb-storage. So in this case, we bind the two
> controller to usbback?
>
> So looking at tools/python/xen/util/vusb_util.c:bind_usb_device(), it
> looks like what xend did was take the "device" (which would be "1-1"),
> and search the sysfs usb node for all "interfaces" (which would be
> "1-1:.*"), and then unbind each of them and bind them to usbback.
>
> (Obviously I needed to check out a 4.4 branch to look at the xend
> code, since it's been deleted in the development branch.)
>
>  -George
>

[-- Attachment #1.2: Type: text/html, Size: 3315 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

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

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v0 RFC 0/2] xl/libxl support for PVUSB
  2014-08-10 20:23 [PATCH v0 RFC 0/2] xl/libxl support for PVUSB Bo Cao
                   ` (2 preceding siblings ...)
  2014-08-14 15:04 ` [PATCH v0 RFC 0/2] xl/libxl support for PVUSB George Dunlap
@ 2014-11-10  8:37 ` Chun Yan Liu
  2014-11-10 15:01   ` Konrad Rzeszutek Wilk
  2014-11-16  2:36   ` Simon Cao
  3 siblings, 2 replies; 12+ messages in thread
From: Chun Yan Liu @ 2014-11-10  8:37 UTC (permalink / raw)
  To: Bo Cao, xen-devel; +Cc: George Dunlap, Ian Jackson, Ian Campbell, Lars Kurth

Is there any progress on this work? I didn't see new version after this.
Anyone knows the status?

Thanks,
Chunyan

>>> On 8/11/2014 at 04:23 AM, in message
<1407702234-22309-1-git-send-email-caobosimon@gmail.com>, Bo Cao
<caobosimon@gmail.com> wrote: 
> Finally I have a workable version xl/libxl support for PVUSB. Most of 
> its commands work property now, but there are still some probelm to be
> solved. 
> Please take a loot and give me some advices.
>  
> == What have been implemented ? == 
> I have implemented libxl functions for PVUSB in libxl_usb.c. It mainly  
> consists of two part: 
> usbctrl_add/remove/list and usb_add/remove/list in which usbctrl denote usb  
> controller in which 
> usd device can be plugged in. I don't use "ao_dev" in  
> libxl_deivce_usbctrl_add since we don't need to 
> execute hotplug script for usbctrl and without "ao_dev", adding default  
> usbctrl for usb device 
> would be easier. 
>  
> For the cammands to manipulate usb device such as "xl usb-attach" and "xl  
> usb-detach", this patch now only 
> support to specify usb devices by their interface in sysfs. Using this  
> interface, we can read usb device 
> information through sysfs and bind/unbind usb device. (The support for  
> mapping the "lsusb" bus:addr to the 
> sysfs usb interface will come later). 
>  
> == What needs to do next ? == 
> There are two main problems to be solved. 
>  
> 1.  PVUSB Options in VM Guest's Configuration File 
>     The interface in VM Guest's configuration file to add usb device is:  
> "usb=[interface="1-1"]". 
> But the problem is now is that after the default usbctrl is added, the state  
> of usbctrl is "2", e,g, "XenbusStateInitWait", 
> waiting for xen-usbfront to connect. The xen-usbfront in VM Guest isn't  
> loaded. Therefore, "sysfs_intf_write" 
> will report error. Does anyone have any clue how to solve this? 
>  
> 2. sysfs_intf_write 
>     In the process of "xl usb-attach domid intf=1-1", after writing "1-1" to  
> Xenstore entry, we need to 
> bind the controller of this usb device to usbback driver so that it can be  
> used by VM Guest. For exampele, 
> for usb device "1-1", it's controller interface maybe "1-1:1.0", and we  
> write this value to "/sys/bus/usb/driver/usbback/bind". 
> But for some devices, they have two controllers, for example "1-1:1.0" and  
> "1-1:1.1". I think this means it has two functions, 
> such as usbhid and usb-storage. So in this case, we bind the two controller  
> to usbback? 
>  
> ======== 
> There maybe some errors or bugs in the codes. Feel free to tell me. 
>  
> Cheers, 
>  
> - Simon 
>  
> --- 
> CC: George Dunlap <george.dunlap@eu.citrix.com> 
> CC: Ian Jackson <ian.jackson@citrix.com> 
> CC: Ian Campbell <ian.campbell@citrix.com> 
> CC: Pasi Kärkkäinen <pasik@iki.fi> 
> CC: Lars Kurth <lars.kurth@citrix.com> 
>  
>  
>  
> _______________________________________________ 
> Xen-devel mailing list 
> Xen-devel@lists.xen.org 
> http://lists.xen.org/xen-devel 
>  


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

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v0 RFC 0/2] xl/libxl support for PVUSB
  2014-11-10  8:37 ` Chun Yan Liu
@ 2014-11-10 15:01   ` Konrad Rzeszutek Wilk
  2014-11-11  5:06     ` Juergen Gross
  2014-11-16  2:36   ` Simon Cao
  1 sibling, 1 reply; 12+ messages in thread
From: Konrad Rzeszutek Wilk @ 2014-11-10 15:01 UTC (permalink / raw)
  To: Chun Yan Liu, jgross, olaf
  Cc: Lars Kurth, xen-devel, Ian Campbell, George Dunlap, Ian Jackson,
	Bo Cao

On Mon, Nov 10, 2014 at 01:37:44AM -0700, Chun Yan Liu wrote:
> Is there any progress on this work? I didn't see new version after this.
> Anyone knows the status?

I believe Olaf and Juergen were looking at this for Xen 4.6?

CC-ing them.
> 
> Thanks,
> Chunyan
> 
> >>> On 8/11/2014 at 04:23 AM, in message
> <1407702234-22309-1-git-send-email-caobosimon@gmail.com>, Bo Cao
> <caobosimon@gmail.com> wrote: 
> > Finally I have a workable version xl/libxl support for PVUSB. Most of 
> > its commands work property now, but there are still some probelm to be
> > solved. 
> > Please take a loot and give me some advices.
> >  
> > == What have been implemented ? == 
> > I have implemented libxl functions for PVUSB in libxl_usb.c. It mainly  
> > consists of two part: 
> > usbctrl_add/remove/list and usb_add/remove/list in which usbctrl denote usb  
> > controller in which 
> > usd device can be plugged in. I don't use "ao_dev" in  
> > libxl_deivce_usbctrl_add since we don't need to 
> > execute hotplug script for usbctrl and without "ao_dev", adding default  
> > usbctrl for usb device 
> > would be easier. 
> >  
> > For the cammands to manipulate usb device such as "xl usb-attach" and "xl  
> > usb-detach", this patch now only 
> > support to specify usb devices by their interface in sysfs. Using this  
> > interface, we can read usb device 
> > information through sysfs and bind/unbind usb device. (The support for  
> > mapping the "lsusb" bus:addr to the 
> > sysfs usb interface will come later). 
> >  
> > == What needs to do next ? == 
> > There are two main problems to be solved. 
> >  
> > 1.  PVUSB Options in VM Guest's Configuration File 
> >     The interface in VM Guest's configuration file to add usb device is:  
> > "usb=[interface="1-1"]". 
> > But the problem is now is that after the default usbctrl is added, the state  
> > of usbctrl is "2", e,g, "XenbusStateInitWait", 
> > waiting for xen-usbfront to connect. The xen-usbfront in VM Guest isn't  
> > loaded. Therefore, "sysfs_intf_write" 
> > will report error. Does anyone have any clue how to solve this? 
> >  
> > 2. sysfs_intf_write 
> >     In the process of "xl usb-attach domid intf=1-1", after writing "1-1" to  
> > Xenstore entry, we need to 
> > bind the controller of this usb device to usbback driver so that it can be  
> > used by VM Guest. For exampele, 
> > for usb device "1-1", it's controller interface maybe "1-1:1.0", and we  
> > write this value to "/sys/bus/usb/driver/usbback/bind". 
> > But for some devices, they have two controllers, for example "1-1:1.0" and  
> > "1-1:1.1". I think this means it has two functions, 
> > such as usbhid and usb-storage. So in this case, we bind the two controller  
> > to usbback? 
> >  
> > ======== 
> > There maybe some errors or bugs in the codes. Feel free to tell me. 
> >  
> > Cheers, 
> >  
> > - Simon 
> >  
> > --- 
> > CC: George Dunlap <george.dunlap@eu.citrix.com> 
> > CC: Ian Jackson <ian.jackson@citrix.com> 
> > CC: Ian Campbell <ian.campbell@citrix.com> 
> > CC: Pasi Kärkkäinen <pasik@iki.fi> 
> > CC: Lars Kurth <lars.kurth@citrix.com> 
> >  
> >  
> >  
> > _______________________________________________ 
> > Xen-devel mailing list 
> > Xen-devel@lists.xen.org 
> > http://lists.xen.org/xen-devel 
> >  
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v0 RFC 0/2] xl/libxl support for PVUSB
  2014-11-10 15:01   ` Konrad Rzeszutek Wilk
@ 2014-11-11  5:06     ` Juergen Gross
  0 siblings, 0 replies; 12+ messages in thread
From: Juergen Gross @ 2014-11-11  5:06 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk, Chun Yan Liu, olaf
  Cc: Lars Kurth, xen-devel, Ian Campbell, George Dunlap, Ian Jackson,
	Bo Cao

On 11/10/2014 04:01 PM, Konrad Rzeszutek Wilk wrote:
> On Mon, Nov 10, 2014 at 01:37:44AM -0700, Chun Yan Liu wrote:
>> Is there any progress on this work? I didn't see new version after this.
>> Anyone knows the status?
>
> I believe Olaf and Juergen were looking at this for Xen 4.6?

I'm working on the kernel pvusb drivers.

Juergen

>
> CC-ing them.
>>
>> Thanks,
>> Chunyan
>>
>>>>> On 8/11/2014 at 04:23 AM, in message
>> <1407702234-22309-1-git-send-email-caobosimon@gmail.com>, Bo Cao
>> <caobosimon@gmail.com> wrote:
>>> Finally I have a workable version xl/libxl support for PVUSB. Most of
>>> its commands work property now, but there are still some probelm to be
>>> solved.
>>> Please take a loot and give me some advices.
>>>
>>> == What have been implemented ? ==
>>> I have implemented libxl functions for PVUSB in libxl_usb.c. It mainly
>>> consists of two part:
>>> usbctrl_add/remove/list and usb_add/remove/list in which usbctrl denote usb
>>> controller in which
>>> usd device can be plugged in. I don't use "ao_dev" in
>>> libxl_deivce_usbctrl_add since we don't need to
>>> execute hotplug script for usbctrl and without "ao_dev", adding default
>>> usbctrl for usb device
>>> would be easier.
>>>
>>> For the cammands to manipulate usb device such as "xl usb-attach" and "xl
>>> usb-detach", this patch now only
>>> support to specify usb devices by their interface in sysfs. Using this
>>> interface, we can read usb device
>>> information through sysfs and bind/unbind usb device. (The support for
>>> mapping the "lsusb" bus:addr to the
>>> sysfs usb interface will come later).
>>>
>>> == What needs to do next ? ==
>>> There are two main problems to be solved.
>>>
>>> 1.  PVUSB Options in VM Guest's Configuration File
>>>      The interface in VM Guest's configuration file to add usb device is:
>>> "usb=[interface="1-1"]".
>>> But the problem is now is that after the default usbctrl is added, the state
>>> of usbctrl is "2", e,g, "XenbusStateInitWait",
>>> waiting for xen-usbfront to connect. The xen-usbfront in VM Guest isn't
>>> loaded. Therefore, "sysfs_intf_write"
>>> will report error. Does anyone have any clue how to solve this?
>>>
>>> 2. sysfs_intf_write
>>>      In the process of "xl usb-attach domid intf=1-1", after writing "1-1" to
>>> Xenstore entry, we need to
>>> bind the controller of this usb device to usbback driver so that it can be
>>> used by VM Guest. For exampele,
>>> for usb device "1-1", it's controller interface maybe "1-1:1.0", and we
>>> write this value to "/sys/bus/usb/driver/usbback/bind".
>>> But for some devices, they have two controllers, for example "1-1:1.0" and
>>> "1-1:1.1". I think this means it has two functions,
>>> such as usbhid and usb-storage. So in this case, we bind the two controller
>>> to usbback?
>>>
>>> ========
>>> There maybe some errors or bugs in the codes. Feel free to tell me.
>>>
>>> Cheers,
>>>
>>> - Simon
>>>
>>> ---
>>> CC: George Dunlap <george.dunlap@eu.citrix.com>
>>> CC: Ian Jackson <ian.jackson@citrix.com>
>>> CC: Ian Campbell <ian.campbell@citrix.com>
>>> CC: Pasi Kärkkäinen <pasik@iki.fi>
>>> CC: Lars Kurth <lars.kurth@citrix.com>
>>>
>>>
>>>
>>> _______________________________________________
>>> Xen-devel mailing list
>>> Xen-devel@lists.xen.org
>>> http://lists.xen.org/xen-devel
>>>
>>
>>
>> _______________________________________________
>> Xen-devel mailing list
>> Xen-devel@lists.xen.org
>> http://lists.xen.org/xen-devel
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v0 RFC 0/2] xl/libxl support for PVUSB
  2014-11-10  8:37 ` Chun Yan Liu
  2014-11-10 15:01   ` Konrad Rzeszutek Wilk
@ 2014-11-16  2:36   ` Simon Cao
  2014-11-19 21:32     ` Konrad Rzeszutek Wilk
  1 sibling, 1 reply; 12+ messages in thread
From: Simon Cao @ 2014-11-16  2:36 UTC (permalink / raw)
  To: Chun Yan Liu
  Cc: George Dunlap, Ian Jackson, xen-devel@lists.xensource.com,
	Ian Campbell, Lars Kurth


[-- Attachment #1.1: Type: text/plain, Size: 3433 bytes --]

Hi,

I was working on the work. But I was busing preparing some job interviews
in the last three months, sorry for this long delay. I will update my
progress in a few days.

Thanks!

Bo Cao

On Mon, Nov 10, 2014 at 4:37 PM, Chun Yan Liu <cyliu@suse.com> wrote:

> Is there any progress on this work? I didn't see new version after this.
> Anyone knows the status?
>
> Thanks,
> Chunyan
>
> >>> On 8/11/2014 at 04:23 AM, in message
> <1407702234-22309-1-git-send-email-caobosimon@gmail.com>, Bo Cao
> <caobosimon@gmail.com> wrote:
> > Finally I have a workable version xl/libxl support for PVUSB. Most of
> > its commands work property now, but there are still some probelm to be
> > solved.
> > Please take a loot and give me some advices.
> >
> > == What have been implemented ? ==
> > I have implemented libxl functions for PVUSB in libxl_usb.c. It mainly
> > consists of two part:
> > usbctrl_add/remove/list and usb_add/remove/list in which usbctrl denote
> usb
> > controller in which
> > usd device can be plugged in. I don't use "ao_dev" in
> > libxl_deivce_usbctrl_add since we don't need to
> > execute hotplug script for usbctrl and without "ao_dev", adding default
> > usbctrl for usb device
> > would be easier.
> >
> > For the cammands to manipulate usb device such as "xl usb-attach" and "xl
> > usb-detach", this patch now only
> > support to specify usb devices by their interface in sysfs. Using this
> > interface, we can read usb device
> > information through sysfs and bind/unbind usb device. (The support for
> > mapping the "lsusb" bus:addr to the
> > sysfs usb interface will come later).
> >
> > == What needs to do next ? ==
> > There are two main problems to be solved.
> >
> > 1.  PVUSB Options in VM Guest's Configuration File
> >     The interface in VM Guest's configuration file to add usb device is:
> > "usb=[interface="1-1"]".
> > But the problem is now is that after the default usbctrl is added, the
> state
> > of usbctrl is "2", e,g, "XenbusStateInitWait",
> > waiting for xen-usbfront to connect. The xen-usbfront in VM Guest isn't
> > loaded. Therefore, "sysfs_intf_write"
> > will report error. Does anyone have any clue how to solve this?
> >
> > 2. sysfs_intf_write
> >     In the process of "xl usb-attach domid intf=1-1", after writing
> "1-1" to
> > Xenstore entry, we need to
> > bind the controller of this usb device to usbback driver so that it can
> be
> > used by VM Guest. For exampele,
> > for usb device "1-1", it's controller interface maybe "1-1:1.0", and we
> > write this value to "/sys/bus/usb/driver/usbback/bind".
> > But for some devices, they have two controllers, for example "1-1:1.0"
> and
> > "1-1:1.1". I think this means it has two functions,
> > such as usbhid and usb-storage. So in this case, we bind the two
> controller
> > to usbback?
> >
> > ========
> > There maybe some errors or bugs in the codes. Feel free to tell me.
> >
> > Cheers,
> >
> > - Simon
> >
> > ---
> > CC: George Dunlap <george.dunlap@eu.citrix.com>
> > CC: Ian Jackson <ian.jackson@citrix.com>
> > CC: Ian Campbell <ian.campbell@citrix.com>
> > CC: Pasi Kärkkäinen <pasik@iki.fi>
> > CC: Lars Kurth <lars.kurth@citrix.com>
> >
> >
> >
> > _______________________________________________
> > Xen-devel mailing list
> > Xen-devel@lists.xen.org
> > http://lists.xen.org/xen-devel
> >
>
>

[-- Attachment #1.2: Type: text/html, Size: 4831 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

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

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v0 RFC 0/2] xl/libxl support for PVUSB
  2014-11-16  2:36   ` Simon Cao
@ 2014-11-19 21:32     ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 12+ messages in thread
From: Konrad Rzeszutek Wilk @ 2014-11-19 21:32 UTC (permalink / raw)
  To: Simon Cao
  Cc: Lars Kurth, xen-devel@lists.xensource.com, Ian Campbell,
	George Dunlap, Chun Yan Liu, Ian Jackson

On Sun, Nov 16, 2014 at 10:36:28AM +0800, Simon Cao wrote:
> Hi,
> 
> I was working on the work. But I was busing preparing some job interviews
> in the last three months, sorry for this long delay. I will update my
> progress in a few days.

OK, I put your name for this to be in Xen 4.6.

Thanks!
> 
> Thanks!
> 
> Bo Cao
> 
> On Mon, Nov 10, 2014 at 4:37 PM, Chun Yan Liu <cyliu@suse.com> wrote:
> 
> > Is there any progress on this work? I didn't see new version after this.
> > Anyone knows the status?
> >
> > Thanks,
> > Chunyan
> >
> > >>> On 8/11/2014 at 04:23 AM, in message
> > <1407702234-22309-1-git-send-email-caobosimon@gmail.com>, Bo Cao
> > <caobosimon@gmail.com> wrote:
> > > Finally I have a workable version xl/libxl support for PVUSB. Most of
> > > its commands work property now, but there are still some probelm to be
> > > solved.
> > > Please take a loot and give me some advices.
> > >
> > > == What have been implemented ? ==
> > > I have implemented libxl functions for PVUSB in libxl_usb.c. It mainly
> > > consists of two part:
> > > usbctrl_add/remove/list and usb_add/remove/list in which usbctrl denote
> > usb
> > > controller in which
> > > usd device can be plugged in. I don't use "ao_dev" in
> > > libxl_deivce_usbctrl_add since we don't need to
> > > execute hotplug script for usbctrl and without "ao_dev", adding default
> > > usbctrl for usb device
> > > would be easier.
> > >
> > > For the cammands to manipulate usb device such as "xl usb-attach" and "xl
> > > usb-detach", this patch now only
> > > support to specify usb devices by their interface in sysfs. Using this
> > > interface, we can read usb device
> > > information through sysfs and bind/unbind usb device. (The support for
> > > mapping the "lsusb" bus:addr to the
> > > sysfs usb interface will come later).
> > >
> > > == What needs to do next ? ==
> > > There are two main problems to be solved.
> > >
> > > 1.  PVUSB Options in VM Guest's Configuration File
> > >     The interface in VM Guest's configuration file to add usb device is:
> > > "usb=[interface="1-1"]".
> > > But the problem is now is that after the default usbctrl is added, the
> > state
> > > of usbctrl is "2", e,g, "XenbusStateInitWait",
> > > waiting for xen-usbfront to connect. The xen-usbfront in VM Guest isn't
> > > loaded. Therefore, "sysfs_intf_write"
> > > will report error. Does anyone have any clue how to solve this?
> > >
> > > 2. sysfs_intf_write
> > >     In the process of "xl usb-attach domid intf=1-1", after writing
> > "1-1" to
> > > Xenstore entry, we need to
> > > bind the controller of this usb device to usbback driver so that it can
> > be
> > > used by VM Guest. For exampele,
> > > for usb device "1-1", it's controller interface maybe "1-1:1.0", and we
> > > write this value to "/sys/bus/usb/driver/usbback/bind".
> > > But for some devices, they have two controllers, for example "1-1:1.0"
> > and
> > > "1-1:1.1". I think this means it has two functions,
> > > such as usbhid and usb-storage. So in this case, we bind the two
> > controller
> > > to usbback?
> > >
> > > ========
> > > There maybe some errors or bugs in the codes. Feel free to tell me.
> > >
> > > Cheers,
> > >
> > > - Simon
> > >
> > > ---
> > > CC: George Dunlap <george.dunlap@eu.citrix.com>
> > > CC: Ian Jackson <ian.jackson@citrix.com>
> > > CC: Ian Campbell <ian.campbell@citrix.com>
> > > CC: Pasi Kärkkäinen <pasik@iki.fi>
> > > CC: Lars Kurth <lars.kurth@citrix.com>
> > >
> > >
> > >
> > > _______________________________________________
> > > Xen-devel mailing list
> > > Xen-devel@lists.xen.org
> > > http://lists.xen.org/xen-devel
> > >
> >
> >

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

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2014-11-19 21:32 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-10 20:23 [PATCH v0 RFC 0/2] xl/libxl support for PVUSB Bo Cao
2014-08-10 20:23 ` [PATCH v0 RFC 1/2] libxl: Introduce functions in libxl to add and remove USB devices for an PV guest Bo Cao
2014-08-12 16:11   ` Ian Jackson
2014-08-13 13:18     ` Simon Cao
2014-08-10 20:23 ` [PATCH v0 RFC 2/2] xl: Add commands for usb hot-plug Bo Cao
2014-08-14 15:04 ` [PATCH v0 RFC 0/2] xl/libxl support for PVUSB George Dunlap
2014-08-14 15:46   ` Simon Cao
2014-11-10  8:37 ` Chun Yan Liu
2014-11-10 15:01   ` Konrad Rzeszutek Wilk
2014-11-11  5:06     ` Juergen Gross
2014-11-16  2:36   ` Simon Cao
2014-11-19 21:32     ` Konrad Rzeszutek Wilk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).