From: Juergen Gross <jgross@suse.com>
To: Chunyan Liu <cyliu@suse.com>, xen-devel@lists.xen.org
Cc: lars.kurth@citrix.com, wei.liu2@citrix.com,
ian.campbell@citrix.com, george.dunlap@eu.citrix.com,
ian.jackson@citrix.com, caobosimon@gmail.com
Subject: Re: [PATCH V3 3/6] libxl: add pvusb API
Date: Mon, 20 Apr 2015 07:53:24 +0200 [thread overview]
Message-ID: <55349454.30202@suse.com> (raw)
In-Reply-To: <1429415452-6161-4-git-send-email-cyliu@suse.com>
On 04/19/2015 05:50 AM, Chunyan Liu wrote:
> Add pvusb APIs, including:
> - attach/detach (create/destroy) virtual usb controller.
> - attach/detach usb device
> - list usb controller and usb devices
> - some other helper functions
>
> Signed-off-by: Chunyan Liu <cyliu@suse.com>
> Signed-off-by: Simon Cao <caobosimon@gmail.com>
> ---
> Changes to v2:
> * remove qemu emulated usb related definitions, keep the work pure pvusb.
> In last patch, will do all refactor work to unify pvusb and qemu emulated
> usb.
> * use bus.addr as user interface instead of busid to do usb-attach|detach
> * remove usb-assignable-list APIs and some other unnecessary APIs
> * reuse libxl_read_file_contents function instead of another new function
> to handle getting sysfs file content
> * fix build on different platforms as pci does
> * fix many coding style problems
> * address other comments in last version
> * adjust codes to let it look better
>
> tools/libxl/Makefile | 2 +-
> tools/libxl/libxl.c | 2 +
> tools/libxl/libxl.h | 45 ++
> tools/libxl/libxl_internal.h | 11 +-
> tools/libxl/libxl_osdeps.h | 13 +
> tools/libxl/libxl_pvusb.c | 1201 ++++++++++++++++++++++++++++++++++
> tools/libxl/libxl_types.idl | 41 ++
> tools/libxl/libxl_types_internal.idl | 1 +
> 8 files changed, 1314 insertions(+), 2 deletions(-)
> create mode 100644 tools/libxl/libxl_pvusb.c
>
...
> diff --git a/tools/libxl/libxl_pvusb.c b/tools/libxl/libxl_pvusb.c
> new file mode 100644
> index 0000000..4e4975a
> --- /dev/null
> +++ b/tools/libxl/libxl_pvusb.c
...
> +static int libxl__usbctrl_add_xenstore(libxl__gc *gc, uint32_t domid,
> + libxl_device_usbctrl *usbctrl)
> +{
> + flexarray_t *front;
> + flexarray_t *back;
> + libxl__device *device;
> + xs_transaction_t t = XBT_NULL;
> + int rc = 0;
> + libxl_domain_config d_config;
> + libxl_device_usbctrl usbctrl_saved;
> + libxl__domain_userdata_lock *lock = NULL;
> +
> + libxl_domain_config_init(&d_config);
> + libxl_device_usbctrl_init(&usbctrl_saved);
> + libxl_device_usbctrl_copy(CTX, &usbctrl_saved, usbctrl);
> +
> + GCNEW(device);
> + libxl__device_from_usbctrl(gc, domid, usbctrl, device);
> +
> + front = flexarray_make(gc, 4, 1);
> + back = flexarray_make(gc, 12, 1);
> +
> + flexarray_append_pair(back, "frontend-id", GCSPRINTF("%d", domid));
> + flexarray_append_pair(back, "online", "1");
> + flexarray_append_pair(back, "state", "1");
> + flexarray_append_pair(back, "usb-ver", GCSPRINTF("%d", usbctrl->version));
> + flexarray_append_pair(back, "num-ports", GCSPRINTF("%d", usbctrl->ports));
> + flexarray_append_pair(front, "backend-id", GCSPRINTF("%d", usbctrl->backend_domid));
> + flexarray_append_pair(front, "state", "1");
> +
> + 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(usbctrl, usbctrls, domid, &usbctrl_saved, COMPARE_USBCTRL, &d_config);
> +
> + for (;;) {
> + rc = libxl__xs_transaction_start(gc, &t);
> + if (rc) goto out;
> +
> + rc = libxl__device_exists(gc, t, device);
> + if (rc < 0) goto out;
> + if (rc == 1) {
> + /* already exists in xenstore */
> + LOG(ERROR, "device already exists in xenstore");
> + rc = ERROR_DEVICE_EXISTS;
> + goto out;
> + }
> +
> + rc = libxl__set_domain_configuration(gc, domid, &d_config);
> + if (rc) goto out;
> +
> + libxl__device_generic_add(gc, t, 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, t, domid, usbctrl);
Still no rc check.
> + rc = libxl__xs_transaction_commit(gc, &t);
> + if (!rc) break;
> + if (rc < 0) goto out;
> + }
> +
> +out:
> + if (lock) libxl__unlock_domain_userdata(lock);
> + libxl_device_usbctrl_dispose(&usbctrl_saved);
> + libxl_domain_config_dispose(&d_config);
> + return rc;
> +}
...
> +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_usbctrl *usbctrls = NULL;
> + libxl_device_usbctrl *usbctrl_find = NULL;
> + int numctrl = 0;
> + libxl_device_usb *usbs = NULL;
> + int numusb = 0;
> + int i, rc;
> +
> + assert(usbctrl->devid != -1);
> +
> + usbctrls = libxl_device_usbctrl_list(ctx, domid, &numctrl);
> + if (!numctrl) {
> + LOG(ERROR, "No USB controller exists in this domain");
> + rc = ERROR_FAIL;
> + goto out;
> + }
> +
> + for (i = 0; i < numctrl; i++) {
> + if (usbctrl->devid == usbctrls[i].devid) {
> + usbctrl_find = usbctrls + i;
> + break;
> + }
> + }
> +
> + if (!usbctrl_find) {
> + LOG(ERROR, "USB controller %d is not attached to this domain",
> + usbctrl->devid);
> + rc = ERROR_FAIL;
> + goto out;
> + }
> +
> + usbctrl = usbctrl_find;
> +
> + GCNEW(device);
> + libxl__device_from_usbctrl(gc, domid, usbctrl, device);
> +
> + /* 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 (do_usb_remove(gc, domid, &usbs[i])) {
> + LOG(ERROR, "do_usb_remove failed");
> + rc = ERROR_FAIL;
> + goto out;
> + }
> + }
> + /* 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:
> + free(usbctrls);
> + free(usbs);
> + if(rc) return AO_ABORT(rc);
Coding style.
> + 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 = GCSPRINTF("%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)++) {
Coding style.
> + 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->version = atoi(tmp);
> +
> + tmp = libxl__xs_read(gc, XBT_NULL,
> + GCSPRINTF("%s/num-ports", be_path));
> + if (!tmp) goto outerr;
> + usbctrl->ports = atoi(tmp);
> + }
> + }
> +
> + return usbctrls;
> +
> +outerr:
> + 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;
> +}
...
> +/* 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/%d/backend/vusb/%d",
> + LIBXL_TOOLSTACK_DOMID, 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++) {
Coding style.
> + usbs[*num].ctrl = tmp[j].ctrl;
> + usbs[*num].port = tmp[j].port;
> + usbs[*num].busid = strdup(tmp[j].busid);
> + (*num)++;
> + }
> + free(tmp);
> + }
> + return usbs;
> +}
...
> +/* set default value */
> +static char *usb_busaddr_to_busid(libxl__gc *gc, int bus, int addr)
> +{
> + libxl_ctx *ctx = libxl__gc_owner(gc);
> + struct dirent *de;
> + DIR *dir;
> + char *busid = NULL;
> +
> + if (bus < 1 || addr < 1)
> + return NULL;
> +
> + if (!(dir = opendir(SYSFS_USB_DEV)))
> + return NULL;
> +
> + while((de = readdir(dir))) {
Coding style.
> + char *filename;
> + void *buf;
> + int busnum = -1;
> + int devnum = -1;
> +
> + if (!de->d_name)
> + continue;
> +
> + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/devnum", de->d_name);
> + if (!libxl_read_file_contents(ctx, filename, &buf, NULL))
> + sscanf(buf, "%x", &devnum);
> +
> + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/busnum", de->d_name);
> + if (!libxl_read_file_contents(ctx, filename, &buf, NULL))
> + sscanf(buf, "%x", &busnum);
> +
> + if (bus == busnum && addr == devnum) {
> + busid = strdup(de->d_name);
> + break;
> + }
> + }
> +
> + closedir(dir);
> + return busid;
> +}
> +
> +/* find first unused controller:port and give that to usb device */
> +static int
> +libxl__device_usb_set_default_usbctrl(libxl__gc *gc, uint32_t domid,
> + 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)
Coding style.
> + 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].ports || numusb == usbctrls[i].ports)
> + continue;
> +
> + for (j = 1; i <= numusb; j++) {
> + be_path = GCSPRINTF("%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 = GCSPRINTF("%s/backend/vusb/%d/%d/port/%d",
> + libxl__xs_get_dompath(gc, 0),
> + domid, usb->ctrl, usb->port);
> + tmp = libxl__xs_read(gc, XBT_NULL, be_path);
> + if (!tmp || strcmp(tmp, "") ){
Coding style.
> + LOG(ERROR, "The controller port isn't available");
> + return ERROR_INVAL;
> + }
> +
> + return 0;
> +}
...
> +static int bind_usb_intf(libxl__gc *gc, char *intf, char *drvpath)
> +{
> + char *path;
> + struct stat st;
> + int fd, rc = 0;
> +
> + path = GCSPRINTF("%s/%s", drvpath, intf);
> + rc = lstat(path, &st);
> + /* already bind, return */
> + if(rc == 0)
Coding style.
> + return 0;
> +
> + path = GCSPRINTF("%s/bind", drvpath);
> + fd = open(path, O_WRONLY);
> + if (fd < 0)
> + return ERROR_FAIL;
> +
> + rc = write(fd, intf, strlen(intf));
> + close(fd);
> + if (rc < 0)
> + return ERROR_FAIL;
> +
> + return 0;
> +}
> +
> +/* Is usb interface bound to usbback? */
> +static int usb_intf_is_assigned(libxl__gc *gc, char *intf)
> +{
> + char *spath;
> + int rc;
> + struct stat st;
> +
> + spath = GCSPRINTF(SYSFS_USBBACK_DRIVER"/%s", intf);
> + rc = lstat(spath, &st);
> +
> + if(rc == 0)
Coding style.
> + return 1;
> + if (rc < 0 && errno == ENOENT)
> + return 0;
> + LOGE(ERROR, "Accessing %s", spath);
> + return -1;
> +}
Juergen
next prev parent reply other threads:[~2015-04-20 5:53 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-19 3:50 [PATCH V3 0/6] libxl pvusb toolstack work Chunyan Liu
2015-04-19 3:50 ` [PATCH V3 1/6] libxl: export some functions for pvusb use Chunyan Liu
2015-04-20 16:25 ` Olaf Hering
2015-05-18 13:34 ` George Dunlap
2015-05-18 14:05 ` Wei Liu
2015-04-19 3:50 ` [PATCH V3 2/6] libxl_read_file_contents: fix reading sysfs file Chunyan Liu
2015-05-18 14:23 ` Ian Jackson
2015-05-18 14:28 ` Ian Campbell
2015-05-18 14:30 ` Wei Liu
2015-05-19 3:21 ` Chun Yan Liu
2015-05-18 14:25 ` Wei Liu
2015-04-19 3:50 ` [PATCH V3 3/6] libxl: add pvusb API Chunyan Liu
2015-04-20 5:53 ` Juergen Gross [this message]
2015-05-18 13:55 ` Olaf Hering
2015-05-18 18:07 ` Wei Liu
2015-05-19 3:20 ` Chun Yan Liu
2015-05-19 10:20 ` George Dunlap
2015-05-19 11:31 ` Jürgen Groß
2015-05-20 9:04 ` Wei Liu
2015-05-20 9:12 ` Ian Campbell
2015-05-20 9:30 ` Chun Yan Liu
2015-06-11 16:54 ` Ian Jackson
2015-05-19 18:06 ` George Dunlap
2015-05-19 18:24 ` Ian Campbell
2015-06-08 9:06 ` 答复: " Chun Yan Liu
2015-05-19 18:16 ` George Dunlap
2015-06-08 11:15 ` 答复: " Chun Yan Liu
2015-05-19 18:20 ` George Dunlap
2015-04-19 3:50 ` [PATCH V3 4/6] xl: add pvusb commands Chunyan Liu
2015-04-20 8:12 ` Juergen Gross
2015-04-21 2:21 ` Chun Yan Liu
2015-05-20 14:20 ` George Dunlap
2015-05-20 14:33 ` Juergen Gross
2015-05-20 14:41 ` George Dunlap
2015-05-20 14:55 ` Juergen Gross
2015-05-20 15:25 ` George Dunlap
2015-05-21 3:35 ` Juergen Gross
2015-05-21 10:37 ` George Dunlap
2015-05-21 10:52 ` Juergen Gross
2015-05-21 11:11 ` George Dunlap
2015-05-21 11:58 ` Juergen Gross
2015-05-21 13:01 ` George Dunlap
2015-05-21 13:08 ` Juergen Gross
2015-05-21 13:43 ` George Dunlap
2015-05-21 13:55 ` Juergen Gross
2015-05-21 14:00 ` George Dunlap
2015-05-21 14:14 ` Juergen Gross
2015-05-20 14:23 ` George Dunlap
2015-05-20 15:46 ` George Dunlap
2015-05-20 15:55 ` George Dunlap
2015-04-19 3:50 ` [PATCH V3 5/6] domcreate: support pvusb in configuration file Chunyan Liu
2015-04-19 3:50 ` [PATCH V3 6/6] refactor codes to unify pvusb and qemu emulated usb Chunyan Liu
2015-05-21 14:17 ` George Dunlap
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55349454.30202@suse.com \
--to=jgross@suse.com \
--cc=caobosimon@gmail.com \
--cc=cyliu@suse.com \
--cc=george.dunlap@eu.citrix.com \
--cc=ian.campbell@citrix.com \
--cc=ian.jackson@citrix.com \
--cc=lars.kurth@citrix.com \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.