|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC V2 3/5] libxl: add pvusb API
Add pvusb APIs, including:
- attach/detach (create/destroy) virtual usb controller.
- attach/detach usb device
- list assignable usb devices in host
- some other helper functions
Signed-off-by: Chunyan Liu <cyliu@xxxxxxxx>
Signed-off-by: Simon Cao <caobosimon@xxxxxxxxx>
---
tools/libxl/Makefile | 2 +-
tools/libxl/libxl.c | 2 +
tools/libxl/libxl.h | 58 ++
tools/libxl/libxl_internal.h | 6 +
tools/libxl/libxl_usb.c | 1277 ++++++++++++++++++++++++++++++++++++++++++
tools/libxl/libxlu_cfg_y.c | 464 ++++++++-------
tools/libxl/libxlu_cfg_y.h | 38 +-
7 files changed, 1623 insertions(+), 224 deletions(-)
create mode 100644 tools/libxl/libxl_usb.c
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index b417372..08cdb12 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -95,7 +95,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o
libxl_pci.o \
libxl_internal.o libxl_utils.o libxl_uuid.o \
libxl_json.o libxl_aoutils.o libxl_numa.o \
libxl_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_genid.o
LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 3cd13db..dd76ac3 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -1594,6 +1594,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);
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 0a123f1..2e89244 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -98,6 +98,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
@@ -1168,6 +1174,56 @@ 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_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)
@@ -1294,6 +1350,8 @@ 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);
+libxl_device_usb *libxl_device_usb_assignable_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_internal.h b/tools/libxl/libxl_internal.h
index bcf43fb..dba1326 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -2395,6 +2395,11 @@ _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_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);
+
/* Internal function to connect a vkb device */
_hidden int libxl__device_vkb_add(libxl__gc *gc, uint32_t domid,
libxl_device_vkb *vkb);
@@ -3574,6 +3579,7 @@ static inline void libxl__update_config_vtpm(libxl__gc
*gc,
#define COMPARE_PCI(a, b) ((a)->func == (b)->func && \
(a)->bus == (b)->bus && \
(a)->dev == (b)->dev)
+#define COMPARE_USB(a, b) (!strcmp((a)->intf, (b)->intf))
/* DEVICE_ADD
*
diff --git a/tools/libxl/libxl_usb.c b/tools/libxl/libxl_usb.c
new file mode 100644
index 0000000..830a846
--- /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 SYSFS_USB_DEVS_PATH "/sys/bus/usb/devices"
+#define SYSFS_USBBACK_DRIVER "/sys/bus/usb/drivers/usbback"
+#define USBBACK_INFO_PATH "/libxl/usbback"
+
+#define USBHUB_CLASS_CODE "09"
+
+static int libxl__device_usbctrl_setdefault(libxl__gc *gc, uint32_t domid,
+ libxl_device_usbctrl *usbctrl)
+{
+ 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;
+
+ if (!usbctrl->type)
+ usbctrl->type = LIBXL_USBCTRL_TYPE_PV;
+
+ rc = libxl__resolve_domid(gc, usbctrl->backend_domname,
+ &usbctrl->backend_domid);
+
+ 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 libxl__usbport_add_xenstore(libxl__gc *gc,
+ xs_transaction_t tran,
+ uint32_t domid,
+ libxl_device_usbctrl *usbctrl)
+{
+ char *path;
+ int i;
+
+ path = GCSPRINTF("%s/backend/vusb/%d/%d/port",
+ libxl__xs_get_dompath(gc, 0), domid, usbctrl->devid);
+
+ libxl__xs_mkdir(gc, tran, path, NULL, 0);
+
+ for (i = 1; i <= usbctrl->num_ports; i++) {
+ if (libxl__xs_write_checked(gc, tran, GCSPRINTF("%s/%d", path, i), ""))
+ return ERROR_FAIL;
+ }
+
+ return 0;
+}
+
+static int libxl__usbctrl_add_xenstore(libxl__gc *gc, uint32_t domid,
+ libxl_device_usbctrl *usbctrl)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ flexarray_t *front;
+ flexarray_t *back;
+ libxl__device *device;
+ xs_transaction_t tran;
+ int rc = 0;
+
+ GCNEW(device);
+ rc = libxl__device_from_usbctrl(gc, domid, usbctrl, device);
+ if (rc) goto out;
+
+ front = flexarray_make(gc, 4, 1);
+ back = flexarray_make(gc, 12, 1);
+
+ 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:
+ /* not supported */
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ 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));
+
+retry_transaction:
+ tran = xs_transaction_start(ctx->xsh);
+
+ libxl__device_generic_add(gc, tran, device,
+ libxl__xs_kvs_of_flexarray(gc, back,
back->count),
+ libxl__xs_kvs_of_flexarray(gc, front,
front->count),
+ NULL);
+ libxl__usbport_add_xenstore(gc, tran, domid, usbctrl);
+
+ if (!xs_transaction_end(ctx->xsh, tran, 0)) {
+ if (errno == EAGAIN)
+ goto retry_transaction;
+ else {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ }
+
+out:
+ return rc;
+}
+
+static int libxl__device_usbctrl_add(libxl__gc *gc, uint32_t domid,
+ libxl_device_usbctrl *usbctrl)
+{
+ int rc = 0;
+
+ rc = libxl__device_usbctrl_setdefault(gc, domid, usbctrl);
+ if(rc) goto out;
+
+ if (usbctrl->devid == -1) {
+ if ((usbctrl->devid = libxl__device_nextid(gc, domid, "vusb")) < 0) {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ }
+
+ if (libxl__usbctrl_add_xenstore(gc, domid, usbctrl) < 0){
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+out:
+ return rc;
+}
+
+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;
+ 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)++) {
+ char *tmp;
+ 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);
+
+ tmp = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/%s/backend-id", fe_path, *dir));
+ if (!tmp) goto outerr;
+ usbctrl->backend_domid = atoi(tmp);
+
+ tmp = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/usb-ver", be_path));
+ if (!tmp) goto outerr;
+ usbctrl->usb_version = atoi(tmp);
+
+ tmp = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/num-ports", be_path));
+ if (!tmp) goto outerr;
+ usbctrl->num_ports = atoi(tmp);
+ }
+ }
+ *num = ndirs;
+
+ return usbctrls;
+
+outerr:
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to list USB Controllers");
+ for (int i = 0; i < *num; i++) {
+ libxl_device_usbctrl_dispose(usbctrls + i);
+ }
+ free(usbctrls);
+ *num = 0;
+ return NULL;
+}
+
+static int libxl__device_usb_list(libxl__gc *gc, uint32_t domid, int usbctrl,
+ libxl_device_usb **usbs, int *num);
+
+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;
+ libxl_device_usb *usbs = NULL;
+ int numusb = 0;
+ int i, rc;
+
+ GCNEW(device);
+ rc = libxl__device_from_usbctrl(gc, domid, usbctrl, device);
+ if(rc) goto out;
+
+ /* Remove usb devives first */
+ rc = libxl__device_usb_list(gc, domid, usbctrl->devid, &usbs, &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);
+
+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;
+ int rc = 0;
+
+ 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 = libxl__xs_read(gc, XBT_NULL,
+ libxl__sprintf(gc, "%s/backend", usbctrlpath));
+ if (!usbctrlinfo->backend) {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ val = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/backend-id", usbctrlpath));
+ usbctrlinfo->backend_id = val ? strtoul(val, NULL, 10) : -1;
+
+ val = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/state", usbctrlpath));
+ usbctrlinfo->state = val ? strtoul(val, NULL, 10) : -1;
+
+ val = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/event-channel", usbctrlpath));
+ usbctrlinfo->evtch = val ? strtoul(val, NULL, 10) : -1;
+
+ val = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/urb-ring-ref", usbctrlpath));
+ usbctrlinfo->ref_urb = val ? strtoul(val, NULL, 10) : -1;
+
+ val = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/conn-ring-ref", usbctrlpath));
+ usbctrlinfo->ref_conn= val ? strtoul(val, NULL, 10) : -1;
+
+ usbctrlinfo->type = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/type", usbctrlinfo->backend));
+
+ usbctrlinfo->frontend = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/frontend",
usbctrlinfo->backend));
+
+ val = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/frontend-id", usbctrlinfo->backend));
+ usbctrlinfo->frontend_id = val ? strtoul(val, NULL, 10) : -1;
+
+out:
+ GC_FREE;
+ return rc;
+}
+
+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;
+ int rc = 0;
+
+ libxl_device_usbctrl_init(usbctrl);
+ usbctrl->devid = devid;
+
+ 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));
+
+ tmp = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/%d/backend-id", fe_path, devid));
+ if (!tmp) {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ 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);
+
+out:
+ GC_FREE;
+ return rc;
+}
+
+/* usb device functions */
+
+/* Following functions are to get assignable usb devices */
+static 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;
+}
+
+static bool is_usb_in_array(libxl_device_usb *usbs, int num, char *intf)
+{
+ int i;
+
+ for (i = 0; i < num; i++) {
+ if (!strcmp(usbs[i].intf, intf) )
+ return true;
+ }
+
+ return false;
+}
+
+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;
+
+ fd = popen(GCSPRINTF("cat %s", path), "r");
+ rc = fscanf(fd, "%s", buf);
+ pclose(fd);
+
+ return (rc > 0) ? 0 : -1;
+}
+
+static bool is_usb_assignable(libxl__gc *gc, char *intf)
+{
+ char buf[5];
+
+ if (get_usb_bDeviceClass(gc, intf, buf) < 0)
+ return false;
+
+ if (strcmp(buf, USBHUB_CLASS_CODE))
+ return false;
+
+ return true;
+}
+
+libxl_device_usb *
+libxl_device_usb_assignable_list(libxl_ctx *ctx, int *num)
+{
+ GC_INIT(ctx);
+ libxl_device_usb *usbs = NULL;
+ libxl_device_usb *assigned;
+ int num_assigned;
+ struct dirent *de;
+ DIR *dir;
+
+ *num = 0;
+
+ if (libxl__device_usb_assigned_list(gc, &assigned, &num_assigned) < 0)
+ goto out;
+
+ if (!(dir = opendir(SYSFS_USB_DEVS_PATH)))
+ goto out;
+
+ while((de = readdir(dir))) {
+ if (!de->d_name)
+ continue;
+
+ if(is_usb_assignable(gc, de->d_name))
+ continue;
+
+ if (is_usb_in_array(assigned, num_assigned, de->d_name))
+ continue;
+
+ usbs = realloc(usbs, sizeof(*usbs)*((*num) + 1));
+ usbs[*num].intf = strdup(de->d_name);
+ (*num)++;
+ }
+
+ closedir(dir);
+
+out:
+ GC_FREE;
+ return usbs;
+}
+
+/* get usb devices under certain usb controller */
+static int libxl__device_usb_list(libxl__gc *gc, uint32_t domid, int usbctrl,
+ libxl_device_usb **usbs, int *num)
+{
+ char *be_path, *num_devs;
+ int n, i;
+ libxl_device_usb *usb = NULL;
+
+ 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)
+ return 0;
+
+ n = atoi(num_devs);
+ usb = calloc(n, sizeof(libxl_device_usb));
+ usbs = &usb;
+
+ for (i = 0; i < n; i++) {
+ char *intf;
+ intf = libxl__xs_read(gc, XBT_NULL,
+ libxl__sprintf(gc,"%s/port/%d", be_path, i + 1));
+ if (intf && strcmp(intf, "") ) {
+ usbs[i]->ctrl = usbctrl;
+ usbs[i]->port = i + 1;
+ usbs[i]->intf = strdup(intf);
+ (*num)++;
+ }
+ }
+
+ 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 = NULL;
+
+ libxl__device_usb_list(gc, domid, usbctrl, &usbs, num);
+
+ GC_FREE;
+ return usbs;
+}
+
+/* get all usb devices of the domain */
+static libxl_device_usb *
+libxl_device_usb_list_all(libxl__gc *gc, uint32_t domid, int *num)
+{
+ char **usbctrls;
+ unsigned int nd, i, j;
+ char *be_path;
+ int rc;
+ libxl_device_usb *usbs = NULL;
+
+ *num = 0;
+
+ be_path = GCSPRINTF("/local/domain/0/backend/vusb/%d", domid);
+ usbctrls = libxl__xs_directory(gc, XBT_NULL, be_path, &nd);
+
+ for (i = 0; i < nd; i++) {
+ int nc = 0;
+ libxl_device_usb *tmp = NULL;
+ rc = libxl__device_usb_list(gc, domid, atoi(usbctrls[i]), &tmp, &nc);
+ if (!nc) continue;
+
+ usbs = realloc(usbs, sizeof(libxl_device_usb)*((*num) + nc));
+ 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;
+}
+
+/* set default value */
+
+/* find first unused controller:port and give that to usb device */
+static int
+libxl__device_usb_set_default_usbctrl(libxl__gc *gc, uint32_t domid,
+ libxl_device_usb *usb)
+{
+ libxl_ctx *ctx = CTX;
+ libxl_device_usbctrl *usbctrls;
+ libxl_device_usb *usbs = NULL;
+ int numctrl, numusb, i, j, rc = -1;
+ 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, usbctrls[i].devid,
+ &usbs, &numusb);
+ if (rc) continue;
+
+ 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;
+ break;
+ }
+ }
+ }
+
+ rc = 0;
+
+out:
+ if (usbctrls)
+ free(usbctrls);
+ if (usbs)
+ free(usbs);
+ return rc;
+}
+
+static int libxl__device_usb_setdefault(libxl__gc *gc, uint32_t domid,
+ libxl_device_usb *usb)
+{
+ char *be_path, *tmp;
+
+ if (usb->ctrl == -1) {
+ int ret = libxl__device_usb_set_default_usbctrl(gc, domid, usb);
+ /* If no existing ctrl to host this usb device, setup a new one */
+ if (ret) {
+ 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);
+ }
+ }
+
+ be_path = libxl__sprintf(gc, "%s/backend/vusb/%d/path/%d",
+ libxl__xs_get_dompath(gc, 0), usb->ctrl, usb->port);
+ tmp = libxl__xs_read(gc, XBT_NULL, be_path);
+ if (!tmp || strcmp(tmp, "") ){
+ LOG(ERROR, "The controller port isn't available.");
+ return ERROR_INVAL;
+ }
+
+ return 0;
+}
+
+/* xenstore usb data */
+static int libxl__device_usb_add_xenstore(libxl__gc *gc, uint32_t domid,
+ libxl_device_usb *usb)
+{
+ libxl_ctx *ctx = CTX;
+ char *be_path;
+ int rc;
+ libxl_domain_config d_config;
+ libxl_device_usb usb_saved;
+ libxl__domain_userdata_lock *lock = NULL;
+
+ libxl_domain_config_init(&d_config);
+ libxl_device_usb_init(&usb_saved);
+ libxl_device_usb_copy(CTX, &usb_saved, usb);
+
+ be_path = libxl__sprintf(gc, "%s/backend/vusb/%d/%d",
+ libxl__xs_get_dompath(gc, 0), domid, usb->ctrl);
+ if (libxl__wait_for_backend(gc, be_path, "4") < 0) {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ lock = libxl__lock_domain_userdata(gc, domid);
+ if (!lock) {
+ rc = ERROR_LOCK_FAIL;
+ goto out;
+ }
+
+ rc = libxl__get_domain_configuration(gc, domid, &d_config);
+ if (rc) goto out;
+
+ DEVICE_ADD(usb, usbs, domid, &usb_saved, COMPARE_USB, &d_config);
+
+ rc = libxl__set_domain_configuration(gc, domid, &d_config);
+ if (rc) goto out;
+
+ 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_checked(gc, XBT_NULL, be_path, usb->intf)) {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ rc = 0;
+
+out:
+ if (lock) libxl__unlock_domain_userdata(lock);
+ libxl_device_usb_dispose(&usb_saved);
+ libxl_domain_config_dispose(&d_config);
+ return rc;
+
+}
+
+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);
+ 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_checked(gc,XBT_NULL, be_path, ""))
+ return ERROR_FAIL;
+
+ return 0;
+}
+
+/* bind/unbind usb device interface */
+static int unbind_usb_intf(libxl__gc *gc, char *intf, char *drvpath)
+{
+ char *path;
+ int fd, rc = 0;
+
+ drvpath = GCSPRINTF(SYSFS_USB_DEVS_PATH"/%s/driver", intf);
+
+ /* if not bound to a driver, return directly */
+ if (!drvpath)
+ return 0;
+
+ /* else, unbind from driver */
+ path = GCSPRINTF("%s/unbind", drvpath);
+ fd = open(path, O_WRONLY);
+ if (fd < 0) {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ if (write(fd, intf, strlen(intf)) < 0) {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ close(fd);
+
+out:
+ return rc;
+}
+
+static int bind_usb_intf(libxl__gc *gc, char *intf, char *drvpath)
+{
+ char *path;
+ int fd, rc = 0;
+
+ path = GCSPRINTF("%s/bind", drvpath);
+ fd = open(path, O_WRONLY);
+ if (fd < 0) {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ if (write(fd, intf, strlen(intf)) < 0) {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ close(fd);
+
+out:
+ return rc;
+}
+
+static int usb_get_all_interfaces(libxl__gc *gc, libxl_device_usb *usb,
+ char **intfs, int *num)
+{
+ DIR *dir;
+ struct dirent *entry;
+ char *buf;
+ int rc = 0;
+
+ intfs = NULL;
+ *num = 0;
+
+ buf = GCSPRINTF("%s:", usb->intf);
+
+ if (!(dir = opendir(SYSFS_USB_DEVS_PATH))) {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (!strncmp(entry->d_name, buf, strlen(buf))){
+ intfs = realloc(intfs, sizeof(char *) * (*num + 1));
+ if (!intfs) {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ intfs[*num] = strdup(entry->d_name);
+ (*num)++;
+ }
+ }
+
+ closedir(dir);
+
+out:
+ return rc;
+}
+
+/* unbind usb device from usbback driver, if there are many interfaces
+ * under the usb device, then check each interface, unbind from usbback
+ * driver and rebind to original driver
+ */
+static int unbind_usb_device_from_usbback(libxl__gc *gc, libxl_device_usb *usb)
+{
+ char **intfs = NULL;
+ char *path;
+ int num = 0, i;
+ int rc = 0;
+
+ if (usb_get_all_interfaces(gc, usb, intfs, &num) < 0)
+ return ERROR_FAIL;
+
+ for (i = 0; i < num; i++){
+ char *intf = intfs[i];
+ char *drvpath = NULL;
+ char *tmp = NULL;
+
+ drvpath = GCSPRINTF(SYSFS_USB_DEVS_PATH"/%s/driver", intf);
+ if (!drvpath || strcmp(drvpath, SYSFS_USBBACK_DRIVER))
+ continue;
+
+ /* unbind interface from usbback driver */
+ if (unbind_usb_intf(gc, intf, NULL) < 0) {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ /* bind interface to its originial driver */
+ tmp = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF(USBBACK_INFO_PATH"/%s/%s/driver_path",
+ usb->intf, intf));
+ if (tmp) {
+ if (bind_usb_intf(gc, intf, GCSPRINTF("%s/bind", tmp)) < 0) {
+ free(tmp);
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ free(tmp);
+ }
+ }
+
+ /* finally, remove xs driver path */
+ path = GCSPRINTF(USBBACK_INFO_PATH"/%s", usb->intf);
+ if (libxl__xs_rm_checked(gc, XBT_NULL, path) < 0)
+ rc = ERROR_FAIL;
+
+out:
+ if (intfs) {
+ for (i = 0; i < num; i++)
+ free(intfs[i]);
+ free(intfs);
+ }
+ return rc;
+}
+
+/* bind usb device to "usbback" driver, if there are many interfaces
+ * under the usb device, check each interface, unbind from original
+ * driver and bind to usbback driver.
+ */
+static int bind_usb_device_to_usbback(libxl__gc *gc, libxl_device_usb *usb)
+{
+ char **intfs = NULL;
+ int num = 0, i;
+ int rc = 0;
+
+ if (usb_get_all_interfaces(gc, usb, intfs, &num) < 0)
+ return ERROR_FAIL;
+
+ for (i = 0; i < num; i++){
+ char *intf = intfs[i];
+ char *path = NULL;
+ char *drvpath = NULL;
+
+ /* unbind interface from original driver */
+ if (unbind_usb_intf(gc, intf, drvpath) < 0) {
+ rc = ERROR_FAIL;
+ goto out_rebind;
+ }
+
+ if (drvpath) {
+ /* write driver path to xenstore for later rebinding */
+ path = GCSPRINTF(USBBACK_INFO_PATH"/%s/%s/driver_path",
+ usb->intf, intf);
+ if (libxl__xs_write_checked(gc, XBT_NULL, path, drvpath) < 0) {
+ rc = ERROR_FAIL;
+ goto out_rebind;
+ }
+ }
+
+ /* bind interface to usbback */
+ if (bind_usb_intf(gc, intf, SYSFS_USBBACK_DRIVER) < 0){
+ rc = ERROR_FAIL;
+ goto out_rebind;
+ }
+ }
+
+ goto out;
+
+out_rebind:
+ /* some interfaces might be bound to usbback, unbind it then and
+ * rebind to its original driver
+ */
+ unbind_usb_device_from_usbback(gc, usb);
+out:
+ if (intfs) {
+ for (i = 0; i < num; i++)
+ free(intfs[i]);
+ free(intfs);
+ }
+
+ return rc;
+}
+
+static int do_usb_add(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb)
+{
+ int rc = 0;
+
+ rc = libxl__device_usb_add_xenstore(gc, domid, usb);
+ if (rc) goto out;
+
+ rc = bind_usb_device_to_usbback(gc, usb);
+ if (rc)
+ libxl__device_usb_remove_xenstore(gc, domid, usb);
+
+out:
+ return rc;
+}
+
+int libxl__device_usb_add(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb)
+{
+ libxl_ctx *ctx = CTX;
+ libxl_device_usb *usbs;
+ int rc, num;
+
+ rc = libxl__device_usb_setdefault(gc, domid, usb);
+ if (rc) goto out;
+
+ rc = libxl__device_usb_assigned_list(gc, &usbs, &num);
+ if (rc) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Fail to get assigned usb list");
+ goto out;
+ }
+
+ if (is_usb_in_array(usbs, num, usb->intf)) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+ "USB device is already attached to a domain");
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ rc = do_usb_add(gc, domid, usb);
+
+out:
+ return rc;
+}
+
+int libxl_device_usb_add(libxl_ctx *ctx, uint32_t domid,
+ libxl_device_usb *usb,
+ const libxl_asyncop_how *ao_how)
+{
+ AO_CREATE(ctx, domid, ao_how);
+ int rc;
+
+ rc = libxl__device_usb_add(gc, domid, usb);
+ libxl__ao_complete(egc, ao, rc);
+ return AO_INPROGRESS;
+}
+
+static int do_usb_remove(libxl__gc *gc, uint32_t domid,
+ libxl_device_usb *usb, int force)
+{
+
+ libxl_ctx *ctx = CTX;
+ libxl_device_usb *usbs = NULL;
+ int rc = -1, num;
+
+ usbs = libxl_device_usb_list_all(gc, domid, &num);
+ if (!usbs) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+ "No USB device attached to this domain");
+ goto out;
+ }
+
+ if (!is_usb_in_array(usbs, num, usb->intf)) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+ "USB device is not attached to this domain");
+ goto out;
+ }
+
+ if (libxl__device_usb_remove_xenstore(gc, domid, usb))
+ goto out;
+
+ if (unbind_usb_device_from_usbback(gc, usb))
+ goto out;
+
+ rc = 0;
+
+out:
+ return rc;
+}
+
+static int libxl__device_usb_remove_common(libxl__gc *gc, uint32_t domid,
+ libxl_device_usb *usb, int force)
+{
+ return do_usb_remove(gc, domid, usb, force);
+}
+
+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_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)
+ 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;
+ goto out;
+ }
+ }
+
+out:
+ if (usbctrls)
+ free(usbctrls);
+ return rc;
+}
+
+/*Get usb device information */
+static int get_usb_devnum (libxl__gc *gc, const char *intf, char *buf)
+{
+ char *path;
+ int rc = 0;
+ FILE *fd;
+
+ path = libxl__sprintf(gc, "cat "SYSFS_USB_DEVS_PATH"/%s/devnum", intf);
+ fd = popen(path, "r");
+ if (fgets(buf, 512, fd) == NULL || ferror(fd))
+ rc = -1;
+ pclose(fd);
+
+ return rc;
+}
+
+static int get_usb_busnum(libxl__gc *gc, const char *intf, char *buf)
+{
+ char *path;
+ int rc = 0;
+ FILE *fd;
+
+ path = libxl__sprintf(gc, "cat "SYSFS_USB_DEVS_PATH"/%s/busnum", intf);
+ fd = popen(path, "r");
+ if (fgets(buf, 512, fd) == NULL || ferror(fd))
+ rc = -1;
+ pclose(fd);
+
+ return rc;
+}
+
+static int get_usb_idVendor(libxl__gc *gc, const char *intf, char *buf)
+{
+ char *path;
+ int rc = 0;
+ FILE *fd;
+
+ path = libxl__sprintf(gc, "cat "SYSFS_USB_DEVS_PATH"/%s/idVendor", intf);
+ fd = popen(path, "r");
+ if (fgets(buf, 512, fd) == NULL || ferror(fd))
+ rc = -1;
+ pclose(fd);
+
+ return rc;
+}
+
+static int get_usb_idProduct(libxl__gc *gc, const char *intf, char *buf)
+{
+ char *path;
+ int rc = 0;
+ FILE *fd;
+
+ path = libxl__sprintf(gc, "cat "SYSFS_USB_DEVS_PATH"/%s/idProduct", intf);
+ fd = popen(path, "r");
+ if (fgets(buf, 512, fd) == NULL || ferror(fd))
+ rc = -1;
+ pclose(fd);
+
+ return rc;
+}
+
+static int get_usb_manufacturer(libxl__gc *gc, const char *intf, char *buf)
+{
+ char *path;
+ int rc = 0;
+ FILE *fd;
+
+ path = libxl__sprintf(gc, "cat "SYSFS_USB_DEVS_PATH"/%s/manufacturer",
intf);
+ fd = popen(path, "r");
+ if (fgets(buf, 512, fd) == NULL || ferror(fd))
+ rc = -1;
+ pclose(fd);
+
+ return rc;
+}
+
+static int get_usb_product(libxl__gc *gc, const char *intf, char *buf)
+{
+ char *path;
+ int rc = 0;
+ FILE *fd;
+
+ path = libxl__sprintf(gc, "cat "SYSFS_USB_DEVS_PATH"/%s/product", intf);
+ fd = popen(path, "r");
+ if (fgets(buf, 512, fd) == NULL || ferror(fd))
+ rc = -1;
+ pclose(fd);
+
+ return rc;
+}
+
+int libxl_device_usb_getinfo(libxl_ctx *ctx, char *intf, libxl_usbinfo
*usbinfo)
+{
+ GC_INIT(ctx);
+ char buf[512];
+
+ 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_intf_to_device_usb(libxl_ctx *ctx, uint32_t domid,
+ char *intf, libxl_device_usb *usb)
+{
+ GC_INIT(ctx);
+ libxl_device_usb *usbs = NULL;
+ int num, i, rc;
+ bool find = false;
+
+ usbs = libxl_device_usb_list_all(gc, domid, &num);
+
+ 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);
+ find = 1;
+ break;
+ }
+ }
+
+ /* doesn't find the usb device in domain's usb device list*/
+ if (!find) {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ rc = 0;
+
+out:
+ GC_FREE;
+ if (usbs)
+ free(usbs);
+ return rc;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libxl/libxlu_cfg_y.c b/tools/libxl/libxlu_cfg_y.c
index 07b5a1d..78eccf2 100644
--- a/tools/libxl/libxlu_cfg_y.c
+++ b/tools/libxl/libxlu_cfg_y.c
@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 2.7. */
/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -44,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.5"
+#define YYBISON_VERSION "2.7"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -58,8 +58,6 @@
/* Pull parsers. */
#define YYPULL 1
-/* Using locations. */
-#define YYLSP_NEEDED 1
/* Substitute the variable and function names. */
#define yyparse xlu__cfg_yyparse
@@ -72,22 +70,23 @@
#define yylloc xlu__cfg_yylloc
/* Copy the first part of user declarations. */
-
-/* Line 268 of yacc.c */
+/* Line 371 of yacc.c */
#line 19 "libxlu_cfg_y.y"
#define ctx_scanner ctx->scanner
#include "libxlu_cfg_i.h"
#include "libxlu_cfg_l.h"
+/* Line 371 of yacc.c */
+#line 82 "libxlu_cfg_y.c"
-/* Line 268 of yacc.c */
-#line 86 "libxlu_cfg_y.c"
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
+# ifndef YY_NULL
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULL nullptr
+# else
+# define YY_NULL 0
+# endif
+# endif
/* Enabling verbose error messages. */
#ifdef YYERROR_VERBOSE
@@ -97,11 +96,17 @@
# define YYERROR_VERBOSE 1
#endif
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
+/* In a future release of Bison, this section will be replaced
+ by #include "libxlu_cfg_y.h". */
+#ifndef YY_XLU_CFG_YY_LIBXLU_CFG_Y_H_INCLUDED
+# define YY_XLU_CFG_YY_LIBXLU_CFG_Y_H_INCLUDED
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int xlu__cfg_yydebug;
#endif
-
/* Tokens. */
#ifndef YYTOKENTYPE
@@ -117,21 +122,18 @@
#endif
-
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
-
-/* Line 293 of yacc.c */
+/* Line 387 of yacc.c */
#line 25 "libxlu_cfg_y.y"
char *string;
XLU_ConfigSetting *setting;
-
-/* Line 293 of yacc.c */
-#line 135 "libxlu_cfg_y.c"
+/* Line 387 of yacc.c */
+#line 137 "libxlu_cfg_y.c"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
@@ -152,11 +154,26 @@ typedef struct YYLTYPE
#endif
-/* Copy the second part of user declarations. */
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int xlu__cfg_yyparse (void *YYPARSE_PARAM);
+#else
+int xlu__cfg_yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int xlu__cfg_yyparse (CfgParseContext *ctx);
+#else
+int xlu__cfg_yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+#endif /* !YY_XLU_CFG_YY_LIBXLU_CFG_Y_H_INCLUDED */
+
+/* Copy the second part of user declarations. */
-/* Line 343 of yacc.c */
-#line 160 "libxlu_cfg_y.c"
+/* Line 390 of yacc.c */
+#line 177 "libxlu_cfg_y.c"
#ifdef short
# undef short
@@ -209,24 +226,24 @@ typedef short int yytype_int16;
# if defined YYENABLE_NLS && YYENABLE_NLS
# if ENABLE_NLS
# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
# endif
# endif
# ifndef YY_
-# define YY_(msgid) msgid
+# define YY_(Msgid) Msgid
# endif
#endif
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
+# define YYUSE(E) ((void) (E))
#else
-# define YYUSE(e) /* empty */
+# define YYUSE(E) /* empty */
#endif
/* Identity function, used to suppress warnings about constant conditions. */
#ifndef lint
-# define YYID(n) (n)
+# define YYID(N) (N)
#else
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
@@ -262,6 +279,7 @@ YYID (yyi)
# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ ||
defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
@@ -355,20 +373,20 @@ union yyalloc
#endif
#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from FROM to TO. The source and destination do
+/* Copy COUNT objects from SRC to DST. The source and destination do
not overlap. */
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
while (YYID (0))
# endif
# endif
@@ -457,14 +475,14 @@ static const yytype_uint8 yyrline[] =
};
#endif
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+#if YYDEBUG || YYERROR_VERBOSE || 1
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
"$end", "error", "$undefined", "IDENT", "STRING", "NUMBER", "NEWLINE",
"'='", "';'", "'['", "']'", "','", "$accept", "file", "stmts", "stmt",
- "assignment", "endstmt", "value", "atom", "valuelist", "values", "nlok", 0
+ "assignment", "endstmt", "value", "atom", "valuelist", "values", "nlok",
YY_NULL
};
#endif
@@ -539,10 +557,10 @@ static const yytype_int8 yytable[] =
16, 26, 25, 20, 13
};
-#define yypact_value_is_default(yystate) \
- ((yystate) == (-18))
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-18)))
-#define yytable_value_is_error(yytable_value) \
+#define yytable_value_is_error(Yytable_value) \
YYID (0)
static const yytype_uint8 yycheck[] =
@@ -588,23 +606,24 @@ static const yytype_uint8 yystos[] =
#define YYRECOVERING() (!!yyerrstatus)
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- YYPOPSTACK (1); \
- goto yybackup; \
- } \
- else \
- { \
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
yyerror (&yylloc, ctx, YY_("syntax error: cannot back up")); \
YYERROR; \
} \
while (YYID (0))
-
+/* Error token number */
#define YYTERROR 1
#define YYERRCODE 256
@@ -613,27 +632,28 @@ while (YYID (0))
If N is 0, then set CURRENT to the empty location which ends
the previous symbol: RHS[0] (always defined). */
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- do \
- if (YYID (N)) \
- { \
- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
- } \
- else \
- { \
- (Current).first_line = (Current).last_line = \
- YYRHSLOC (Rhs, 0).last_line; \
- (Current).first_column = (Current).last_column = \
- YYRHSLOC (Rhs, 0).last_column; \
- } \
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
while (YYID (0))
#endif
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+
/* YY_LOCATION_PRINT -- Print the location on the stream.
This macro was not mandated originally: define only if we know
@@ -641,10 +661,46 @@ while (YYID (0))
#ifndef YY_LOCATION_PRINT
# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
-# define YY_LOCATION_PRINT(File, Loc) \
- fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
+
+/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
+
+__attribute__((__unused__))
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static unsigned
+yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
+#else
+static unsigned
+yy_location_print_ (yyo, yylocp)
+ FILE *yyo;
+ YYLTYPE const * const yylocp;
+#endif
+{
+ unsigned res = 0;
+ int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
+ if (0 <= yylocp->first_line)
+ {
+ res += fprintf (yyo, "%d", yylocp->first_line);
+ if (0 <= yylocp->first_column)
+ res += fprintf (yyo, ".%d", yylocp->first_column);
+ }
+ if (0 <= yylocp->last_line)
+ {
+ if (yylocp->first_line < yylocp->last_line)
+ {
+ res += fprintf (yyo, "-%d", yylocp->last_line);
+ if (0 <= end_col)
+ res += fprintf (yyo, ".%d", end_col);
+ }
+ else if (0 <= end_col && yylocp->first_column < end_col)
+ res += fprintf (yyo, "-%d", end_col);
+ }
+ return res;
+ }
+
+# define YY_LOCATION_PRINT(File, Loc) \
+ yy_location_print_ (File, &(Loc))
+
# else
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
# endif
@@ -652,7 +708,6 @@ while (YYID (0))
/* YYLEX -- calling `yylex' with the right arguments. */
-
#ifdef YYLEX_PARAM
# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
#else
@@ -704,6 +759,8 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep,
yylocationp, ctx)
CfgParseContext *ctx;
#endif
{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
if (!yyvaluep)
return;
YYUSE (yylocationp);
@@ -717,7 +774,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep,
yylocationp, ctx)
switch (yytype)
{
default:
- break;
+ break;
}
}
@@ -963,12 +1020,11 @@ static int
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yytype_int16 *yyssp, int yytoken)
{
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+ YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
- const char *yyformat = 0;
+ const char *yyformat = YY_NULL;
/* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per
@@ -1028,11 +1084,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
break;
}
yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL,
yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
}
}
}
@@ -1052,10 +1110,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
# undef YYCASE_
}
- yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
if (*yymsg_alloc < yysize)
{
@@ -1117,90 +1177,62 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, ctx)
switch (yytype)
{
- case 3: /* "IDENT" */
-
-/* Line 1391 of yacc.c */
+ case 3: /* IDENT */
+/* Line 1398 of yacc.c */
#line 40 "libxlu_cfg_y.y"
- { free((yyvaluep->string)); };
-
-/* Line 1391 of yacc.c */
-#line 1128 "libxlu_cfg_y.c"
- break;
- case 4: /* "STRING" */
-
-/* Line 1391 of yacc.c */
+ { free(((*yyvaluep).string)); };
+/* Line 1398 of yacc.c */
+#line 1186 "libxlu_cfg_y.c"
+ break;
+ case 4: /* STRING */
+/* Line 1398 of yacc.c */
#line 40 "libxlu_cfg_y.y"
- { free((yyvaluep->string)); };
-
-/* Line 1391 of yacc.c */
-#line 1137 "libxlu_cfg_y.c"
- break;
- case 5: /* "NUMBER" */
-
-/* Line 1391 of yacc.c */
+ { free(((*yyvaluep).string)); };
+/* Line 1398 of yacc.c */
+#line 1193 "libxlu_cfg_y.c"
+ break;
+ case 5: /* NUMBER */
+/* Line 1398 of yacc.c */
#line 40 "libxlu_cfg_y.y"
- { free((yyvaluep->string)); };
-
-/* Line 1391 of yacc.c */
-#line 1146 "libxlu_cfg_y.c"
- break;
- case 18: /* "value" */
-
-/* Line 1391 of yacc.c */
+ { free(((*yyvaluep).string)); };
+/* Line 1398 of yacc.c */
+#line 1200 "libxlu_cfg_y.c"
+ break;
+ case 18: /* value */
+/* Line 1398 of yacc.c */
#line 43 "libxlu_cfg_y.y"
- { xlu__cfg_set_free((yyvaluep->setting)); };
-
-/* Line 1391 of yacc.c */
-#line 1155 "libxlu_cfg_y.c"
- break;
- case 19: /* "atom" */
-
-/* Line 1391 of yacc.c */
+ { xlu__cfg_set_free(((*yyvaluep).setting)); };
+/* Line 1398 of yacc.c */
+#line 1207 "libxlu_cfg_y.c"
+ break;
+ case 19: /* atom */
+/* Line 1398 of yacc.c */
#line 40 "libxlu_cfg_y.y"
- { free((yyvaluep->string)); };
-
-/* Line 1391 of yacc.c */
-#line 1164 "libxlu_cfg_y.c"
- break;
- case 20: /* "valuelist" */
-
-/* Line 1391 of yacc.c */
+ { free(((*yyvaluep).string)); };
+/* Line 1398 of yacc.c */
+#line 1214 "libxlu_cfg_y.c"
+ break;
+ case 20: /* valuelist */
+/* Line 1398 of yacc.c */
#line 43 "libxlu_cfg_y.y"
- { xlu__cfg_set_free((yyvaluep->setting)); };
-
-/* Line 1391 of yacc.c */
-#line 1173 "libxlu_cfg_y.c"
- break;
- case 21: /* "values" */
-
-/* Line 1391 of yacc.c */
+ { xlu__cfg_set_free(((*yyvaluep).setting)); };
+/* Line 1398 of yacc.c */
+#line 1221 "libxlu_cfg_y.c"
+ break;
+ case 21: /* values */
+/* Line 1398 of yacc.c */
#line 43 "libxlu_cfg_y.y"
- { xlu__cfg_set_free((yyvaluep->setting)); };
-
-/* Line 1391 of yacc.c */
-#line 1182 "libxlu_cfg_y.c"
- break;
+ { xlu__cfg_set_free(((*yyvaluep).setting)); };
+/* Line 1398 of yacc.c */
+#line 1228 "libxlu_cfg_y.c"
+ break;
default:
- break;
+ break;
}
}
-/* Prevent warnings from -Wmissing-prototypes. */
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (CfgParseContext *ctx);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
/*----------.
@@ -1232,11 +1264,40 @@ yyparse (ctx)
/* The lookahead symbol. */
int yychar;
+
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+/* Default value used for initialization, for pacifying older GCCs
+ or non-GCC compilers. */
+static YYSTYPE yyval_default;
+# define YY_INITIAL_VALUE(Value) = Value
+#endif
+static YYLTYPE yyloc_default
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+ = { 1, 1, 1, 1 }
+# endif
+;
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
/* The semantic value of the lookahead symbol. */
-YYSTYPE yylval;
+YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
/* Location data for the lookahead symbol. */
-YYLTYPE yylloc;
+YYLTYPE yylloc = yyloc_default;
+
/* Number of syntax errors so far. */
int yynerrs;
@@ -1250,7 +1311,7 @@ YYLTYPE yylloc;
`yyvs': related to semantic values.
`yyls': related to locations.
- Refer to the stacks thru separate pointers, to allow yyoverflow
+ Refer to the stacks through separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
/* The state stack. */
@@ -1276,7 +1337,7 @@ YYLTYPE yylloc;
int yyn;
int yyresult;
/* Lookahead token as an internal (translated) token number. */
- int yytoken;
+ int yytoken = 0;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
@@ -1295,10 +1356,9 @@ YYLTYPE yylloc;
Keep to zero when no symbol should be popped. */
int yylen = 0;
- yytoken = 0;
- yyss = yyssa;
- yyvs = yyvsa;
- yyls = yylsa;
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;
+ yylsp = yyls = yylsa;
yystacksize = YYINITDEPTH;
YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1307,21 +1367,7 @@ YYLTYPE yylloc;
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
-
- /* Initialize stack pointers.
- Waste one element of value and location stack
- so that they stay on the same level as the state stack.
- The wasted elements are never initialized. */
- yyssp = yyss;
- yyvsp = yyvs;
- yylsp = yyls;
-
-#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
- /* Initialize the default location before parsing starts. */
- yylloc.first_line = yylloc.last_line = 1;
- yylloc.first_column = yylloc.last_column = 1;
-#endif
-
+ yylsp[0] = yylloc;
goto yysetstate;
/*------------------------------------------------------------.
@@ -1467,7 +1513,9 @@ yybackup:
yychar = YYEMPTY;
yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
*++yylsp = yylloc;
goto yynewstate;
@@ -1505,79 +1553,68 @@ yyreduce:
switch (yyn)
{
case 9:
-
-/* Line 1806 of yacc.c */
+/* Line 1792 of yacc.c */
#line 57 "libxlu_cfg_y.y"
{ xlu__cfg_set_store(ctx,(yyvsp[(1) - (3)].string),(yyvsp[(3) -
(3)].setting),(yylsp[(3) - (3)]).first_line); }
break;
case 12:
-
-/* Line 1806 of yacc.c */
+/* Line 1792 of yacc.c */
#line 62 "libxlu_cfg_y.y"
{ (yyval.setting)= xlu__cfg_set_mk(ctx,1,(yyvsp[(1) - (1)].string)); }
break;
case 13:
-
-/* Line 1806 of yacc.c */
+/* Line 1792 of yacc.c */
#line 63 "libxlu_cfg_y.y"
{ (yyval.setting)= (yyvsp[(3) - (4)].setting); }
break;
case 14:
-
-/* Line 1806 of yacc.c */
+/* Line 1792 of yacc.c */
#line 65 "libxlu_cfg_y.y"
{ (yyval.string)= (yyvsp[(1) - (1)].string); }
break;
case 15:
-
-/* Line 1806 of yacc.c */
+/* Line 1792 of yacc.c */
#line 66 "libxlu_cfg_y.y"
{ (yyval.string)= (yyvsp[(1) - (1)].string); }
break;
case 16:
-
-/* Line 1806 of yacc.c */
+/* Line 1792 of yacc.c */
#line 68 "libxlu_cfg_y.y"
{ (yyval.setting)= xlu__cfg_set_mk(ctx,0,0); }
break;
case 17:
-
-/* Line 1806 of yacc.c */
+/* Line 1792 of yacc.c */
#line 69 "libxlu_cfg_y.y"
{ (yyval.setting)= (yyvsp[(1) - (1)].setting); }
break;
case 18:
-
-/* Line 1806 of yacc.c */
+/* Line 1792 of yacc.c */
#line 70 "libxlu_cfg_y.y"
{ (yyval.setting)= (yyvsp[(1) - (3)].setting); }
break;
case 19:
-
-/* Line 1806 of yacc.c */
+/* Line 1792 of yacc.c */
#line 72 "libxlu_cfg_y.y"
{ (yyval.setting)= xlu__cfg_set_mk(ctx,2,(yyvsp[(1) - (2)].string)); }
break;
case 20:
-
-/* Line 1806 of yacc.c */
+/* Line 1792 of yacc.c */
#line 73 "libxlu_cfg_y.y"
{ xlu__cfg_set_add(ctx,(yyvsp[(1) - (5)].setting),(yyvsp[(4) -
(5)].string)); (yyval.setting)= (yyvsp[(1) - (5)].setting); }
break;
-
-/* Line 1806 of yacc.c */
-#line 1581 "libxlu_cfg_y.c"
+/* Line 1792 of yacc.c */
+#line 1618 "libxlu_cfg_y.c"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1742,7 +1779,9 @@ yyerrlab1:
YY_STACK_PRINT (yyss, yyssp);
}
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
yyerror_range[2] = yylloc;
/* Using YYLLOC is tempting, but would change the location of
@@ -1771,7 +1810,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#if !defined yyoverflow || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
@@ -1813,4 +1852,3 @@ yyreturn:
}
-
diff --git a/tools/libxl/libxlu_cfg_y.h b/tools/libxl/libxlu_cfg_y.h
index d7dfaf2..54d4f61 100644
--- a/tools/libxl/libxlu_cfg_y.h
+++ b/tools/libxl/libxlu_cfg_y.h
@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 2.7. */
/* Bison interface for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,6 +30,15 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
+#ifndef YY_XLU_CFG_YY_LIBXLU_CFG_Y_H_INCLUDED
+# define YY_XLU_CFG_YY_LIBXLU_CFG_Y_H_INCLUDED
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int xlu__cfg_yydebug;
+#endif
/* Tokens. */
#ifndef YYTOKENTYPE
@@ -45,29 +54,24 @@
#endif
-
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
-
-/* Line 2068 of yacc.c */
+/* Line 2058 of yacc.c */
#line 25 "libxlu_cfg_y.y"
char *string;
XLU_ConfigSetting *setting;
-
-/* Line 2068 of yacc.c */
-#line 63 "libxlu_cfg_y.h"
+/* Line 2058 of yacc.c */
+#line 69 "libxlu_cfg_y.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
-
-
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
typedef struct YYLTYPE
{
@@ -82,4 +86,18 @@ typedef struct YYLTYPE
#endif
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int xlu__cfg_yyparse (void *YYPARSE_PARAM);
+#else
+int xlu__cfg_yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int xlu__cfg_yyparse (CfgParseContext *ctx);
+#else
+int xlu__cfg_yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+#endif /* !YY_XLU_CFG_YY_LIBXLU_CFG_Y_H_INCLUDED */
--
1.8.4.5
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |