[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH V6 7/7] domcreate: support pvusb in configuration file
Add code to support pvusb in domain config file. One could specify usbctrl and usb in domain's configuration file and create domain, then usb controllers will be created and usb device would be attached to guest automatically. One could specify usb controllers and usb devices in config file like this: usbctrl=['version=2,ports=4', 'version=1, ports=4', ] usbdev=['2.1,controller=0,port=1', ] Signed-off-by: Chunyan Liu <cyliu@xxxxxxxx> Signed-off-by: Simon Cao <caobosimon@xxxxxxxxx> --- docs/man/xl.cfg.pod.5 | 75 +++++++++++++++++++++++++++++ tools/libxl/libxl_create.c | 73 ++++++++++++++++++++++++++-- tools/libxl/libxl_device.c | 4 ++ tools/libxl/libxl_internal.h | 8 ++++ tools/libxl/xl_cmdimpl.c | 112 ++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 268 insertions(+), 4 deletions(-) diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5 index 80e51bb..45f3ff3 100644 --- a/docs/man/xl.cfg.pod.5 +++ b/docs/man/xl.cfg.pod.5 @@ -709,6 +709,81 @@ Note this may be overridden by rdm_policy option in PCI device configuration. =back +=item B<usbctrl=[ "USBCTRL_SPEC_STRING", "USBCTRL_SPEC_STRING", ... ]> + +Specifies the USB controllers created for this guest. Each +B<USB_SPEC_STRING> has the form C<KEY=VALUE,KEY=VALUE,...> where: + +=over 4 + +=item B<KEY=VALUE> + +Possible B<KEY>s are: + +=over 4 + +=item B<type=TYPE> + +Specifies the protocol to implement USB controller, could be "pv" (indicates +PVUSB) or "qemu" (indicates QEMU emulated). Currently only "pv" is supported. + +=item B<version=VERSION> + +Specifies version of the USB controller, could be 1 (USB1.1) or 2 (USB2.0). +Default is 2 (USB2.0). + +=item B<ports=PORTS> + +Specifies port number of the USB controller. Default is 8. + +Each USB controller will have an index starting from 0. On the same +controller, each port will have an index starting from 1. + +E.g. +usbctrl=["version=1,ports=4", "version=2,ports=8",] +The first controller has: +controller index = 0, and port 1,2,3,4. +The second controller has: +controller index = 1, and port 1,2,3,4,5,6,7,8. + +=back + +=back + +=item B<usbdev=[ "USB_SPEC_STRING", "USB_SPEC_STRING", ... ]> + +Specifies the host USB devices to passthrough to this guest. Each +B<USB_SPEC_STRING> has the form C<bus.addr,KEY=VALUE,KEY=VALUE,...> where: + +=over 4 + +=item B<bus.addr> + +Identifies the busnum.devnum of the USB device from the host perspective. +This is the same scheme as used in the output of C<lsusb> for the device in +question. + +=item B<KEY=VALUE> + +Possible B<KEY>s are: + +=over 4 + +=item B<controller=CONTROLLER> + +Specifies USB controller index, to which controller the USB device is attached. + +=item B<port=PORT> + +Specifies USB port index, to which port the USB device is attached. B<port=PORT> +is valid only when B<controller=CONTROLLER> is specified. Without +B<controller=CONTROLLER>, it will find the first available USB controller:port +and use it. If there is no controller at all, it will create one. + +=back + +=back + =item B<pci=[ "PCI_SPEC_STRING", "PCI_SPEC_STRING", ... ]> Specifies the host PCI devices to passthrough to this guest. Each B<PCI_SPEC_STRING> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c index 2348ffc..2988991 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -729,6 +729,10 @@ 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_usbctrls(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); static void domcreate_attach_dtdev(libxl__egc *egc, @@ -1385,13 +1389,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_usbctrls; 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_usbctrls(egc, multidev, 0); return; error_out: @@ -1399,6 +1403,69 @@ error_out: domcreate_complete(egc, dcs, ret); } +static void domcreate_attach_usbctrls(libxl__egc *egc, + libxl__multidev *multidev, int ret) +{ + libxl__domain_create_state *dcs = CONTAINER_OF(multidev, *dcs, multidev); + STATE_AO_GC(dcs->ao); + 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; + } + + if (d_config->num_usbctrls > 0) { + /* Attach usbctrls */ + libxl__multidev_begin(ao, &dcs->multidev); + dcs->multidev.callback = domcreate_attach_usbs; + libxl__add_usbctrls(egc, ao, domid, d_config, &dcs->multidev); + libxl__multidev_prepared(egc, &dcs->multidev, 0); + return; + } + + domcreate_attach_usbs(egc, multidev, 0); + return; + +error_out: + assert(ret); + 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 domid = dcs->guest_domid; + + libxl_domain_config *const d_config = dcs->guest_config; + + if (ret) { + LOG(ERROR, "unable to add usbctrl devices"); + goto error_out; + } + + if (d_config->num_usbs > 0) { + /* Attach usbctrls */ + libxl__multidev_begin(ao, &dcs->multidev); + dcs->multidev.callback = domcreate_attach_pci; + libxl__add_usbs(egc, ao, domid, d_config, &dcs->multidev); + libxl__multidev_prepared(egc, &dcs->multidev, 0); + return; + } + + 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) { @@ -1412,7 +1479,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_device.c b/tools/libxl/libxl_device.c index 935f25b..92d5d10 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -544,6 +544,8 @@ void libxl__multidev_prepared(libxl__egc *egc, * libxl__add_disks * libxl__add_nics * libxl__add_vtpms + * libxl__add_usbctrls + * libxl__add_usbs */ #define DEFINE_DEVICES_ADD(type) \ @@ -563,6 +565,8 @@ void libxl__multidev_prepared(libxl__egc *egc, DEFINE_DEVICES_ADD(disk) DEFINE_DEVICES_ADD(nic) DEFINE_DEVICES_ADD(vtpm) +DEFINE_DEVICES_ADD(usbctrl) +DEFINE_DEVICES_ADD(usb) #undef DEFINE_DEVICES_ADD diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 5be3b3a..c23741a 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -3283,6 +3283,14 @@ _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_usbctrls(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/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index e33871c..632d32f 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -1226,6 +1226,79 @@ static void parse_vnuma_config(const XLU_Config *config, free(vcpu_parsed); } +static void parse_usbctrl_config(libxl_device_usbctrl *usbctrl, + const char *buf) +{ + char *buf2 = strdup(buf); + char *p, *p2; + + p = strtok(buf2, ","); + if (!p) + goto out; + do { + while (*p == ' ') + p++; + if ((p2 = strchr(p, '=')) == NULL) + break; + *p2 = '\0'; + if (!strcmp(p, "type")) { + if (!strcmp(p2 + 1, "pv")) { + usbctrl->type = LIBXL_USBCTRL_TYPE_PV; + } else { + fprintf(stderr, + "Unsupported USB controller type '%s'\n", + p2 + 1); + exit(1); + } + } else if (!strcmp(p, "version")){ + usbctrl->version = atoi(p2 + 1); + } else if (!strcmp(p, "ports")){ + usbctrl->ports = atoi(p2 + 1); + } else { + fprintf(stderr, "Unknown string `%s' in usb spec\n", p); + exit(1); + } + } while ((p = strtok(NULL, ",")) != NULL); + +out: + free(buf2); +} + +static void parse_usb_config(libxl_device_usb *usb, const char *buf) +{ + char *buf2 = strdup(buf); + char *p, *p2; + + p = strtok(buf2, ","); + if (!p) + goto out; + do { + while(*p == ' ') + ++p; + if ((p2 = strchr(p, '=')) == NULL) { + char *busaddr = p; + p = strchr(busaddr, '.'); + if (p) { + usb->u.hostdev.hostbus = strtoul(busaddr, NULL, 0); + usb->u.hostdev.hostaddr = strtoul(p + 1, NULL, 0); + } + continue; + } + *p2 = '\0'; + if (!strcmp(p, "controller")) { + usb->ctrl = atoi(p2 + 1); + } else if (!strcmp(p, "port")) { + usb->port = atoi(p2 + 1); + } else { + fprintf(stderr, "Unknown string `%s' in usb spec\n", p); + exit(1); + } + } while ((p = strtok(NULL, ",")) != NULL); + +out: + free(buf2); +} + static void parse_config_data(const char *config_source, const char *config_data, int config_len, @@ -1234,7 +1307,8 @@ static void parse_config_data(const char *config_source, const char *buf; long l, vcpus = 0; XLU_Config *config; - XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms; + XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms, + *usbctrls, *usbs; XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs; int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian; int pci_power_mgmt = 0; @@ -2042,6 +2116,42 @@ skip_vfb: } } + if (!xlu_cfg_get_list(config, "usbctrl", &usbctrls, 0, 0)) { + d_config->num_usbctrls = 0; + d_config->usbctrls = NULL; + while ((buf = xlu_cfg_get_listitem(usbctrls, d_config->num_usbctrls)) + != NULL) { + libxl_device_usbctrl *usbctrl; + + d_config->usbctrls = + (libxl_device_usbctrl *)realloc(d_config->usbctrls, + sizeof(libxl_device_usbctrl) * (d_config->num_usbctrls + 1)); + usbctrl = d_config->usbctrls + d_config->num_usbctrls; + libxl_device_usbctrl_init(usbctrl); + + parse_usbctrl_config(usbctrl, buf); + + d_config->num_usbctrls++; + } + } + + if (!xlu_cfg_get_list(config, "usbdev", &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; + + 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); + + parse_usb_config(usb, buf); + + d_config->num_usbs++; + } + } + switch (xlu_cfg_get_list(config, "cpuid", &cpuids, 0, 1)) { case 0: { -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |