diff --git a/src/bhyve/bhyve_capabilities.c b/src/bhyve/bhyve_capabilities.c index 6769f1888ae269515de4cd67e02c99950aaf050f..f97834242d512c95012537effc1194ad67b4981d 100644 --- a/src/bhyve/bhyve_capabilities.c +++ b/src/bhyve/bhyve_capabilities.c @@ -310,6 +310,18 @@ bhyveProbeCapsFramebuffer(unsigned int *caps, char *binary) BHYVE_CAP_FBUF); } + +static int +bhyveProbeCapsXHCIController(unsigned int *caps, char *binary) +{ + return bhyveProbeCapsDeviceHelper(caps, binary, + "-s", + "0,xhci", + "pci slot 0:0: unknown device \"xhci\"", + BHYVE_CAP_FBUF); +} + + int virBhyveProbeCaps(unsigned int *caps) { @@ -337,6 +349,9 @@ virBhyveProbeCaps(unsigned int *caps) if ((ret = bhyveProbeCapsFramebuffer(caps, binary))) goto out; + if ((ret = bhyveProbeCapsXHCIController(caps, binary))) + goto out; + out: VIR_FREE(binary); return ret; diff --git a/src/bhyve/bhyve_capabilities.h b/src/bhyve/bhyve_capabilities.h index 194061fde6dc09db3f6c6ad52bcbfb807a674a38..0e310e6eda7663af78be3c798e7c64f460371aa4 100644 --- a/src/bhyve/bhyve_capabilities.h +++ b/src/bhyve/bhyve_capabilities.h @@ -48,6 +48,7 @@ typedef enum { BHYVE_CAP_NET_E1000 = 1 << 2, BHYVE_CAP_LPC_BOOTROM = 1 << 3, BHYVE_CAP_FBUF = 1 << 4, + BHYVE_CAP_XHCI = 1 << 5, } virBhyveCapsFlags; int virBhyveProbeGrubCaps(virBhyveGrubCapsFlags *caps); diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index ec7a71572eb1ee8661e144e70badcf29dad321ae..e0528ed77a2c0259de5282b8c56c62bf4ef2f0b5 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -248,6 +248,45 @@ bhyveBuildAHCIControllerArgStr(const virDomainDef *def, return ret; } +static int +bhyveBuildUSBControllerArgStr(const virDomainDef *def, + virDomainControllerDefPtr controller, + virCommandPtr cmd) +{ + size_t i; + int ndevices = 0; + + for (i = 0; i < def->ninputs; i++) { + virDomainInputDefPtr input = def->inputs[i]; + + if (input->bus != VIR_DOMAIN_INPUT_BUS_USB) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("only USB input devices are supported")); + return -1; + } + + if (input->type != VIR_DOMAIN_INPUT_TYPE_TABLET) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("only tablet input devices are supported")); + return -1; + } + ndevices++; + } + + if (ndevices != 1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("only single input device is supported")); + return -1; + } + + virCommandAddArg(cmd, "-s"); + virCommandAddArgFormat(cmd, "%d:%d,xhci,tablet", + controller->info.addr.pci.slot, + controller->info.addr.pci.function); + + return 0; +} + static int bhyveBuildVirtIODiskArgStr(const virDomainDef *def ATTRIBUTE_UNUSED, virDomainDiskDefPtr disk, @@ -392,6 +431,7 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, */ size_t i; bool add_lpc = false; + int nusbcontrollers = 0; virCommandPtr cmd = virCommandNew(BHYVE); @@ -476,6 +516,16 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, if (bhyveBuildAHCIControllerArgStr(def, controller, conn, cmd) < 0) goto error; break; + case VIR_DOMAIN_CONTROLLER_TYPE_USB: + if (++nusbcontrollers > 1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + "%s", _("only single USB controller is supported")); + goto error; + } + + if (bhyveBuildUSBControllerArgStr(def, controller, cmd) < 0) + goto error; + break; } } for (i = 0; i < def->nnets; i++) { diff --git a/src/bhyve/bhyve_device.c b/src/bhyve/bhyve_device.c index a3a263b7e27954ec1bee8275f267a0026e18014d..fdfd512e1062ecfe70947b4d5b722e67a13bc9a5 100644 --- a/src/bhyve/bhyve_device.c +++ b/src/bhyve/bhyve_device.c @@ -106,7 +106,9 @@ bhyveAssignDevicePCISlots(virDomainDefPtr def, for (i = 0; i < def->ncontrollers; i++) { if ((def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) || - (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA)) { + (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA) || + ((def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) && + (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI))) { if (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT || !virDeviceInfoPCIAddressWanted(&def->controllers[i]->info)) continue; diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.args b/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.args new file mode 100644 index 0000000000000000000000000000000000000000..b1c0c94d030f571a22a1e2d3502beb8ceadc7173 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.args @@ -0,0 +1,9 @@ +/usr/sbin/bhyve \ +-c 1 \ +-m 214 \ +-u \ +-H \ +-P \ +-s 0:0,hostbridge \ +-s 2:0,xhci,tablet \ +-s 3:0,ahci-hd,/tmp/freebsd.img bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.ldargs new file mode 100644 index 0000000000000000000000000000000000000000..32538b558ef3174217a36f1890713552e64ce9be --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.ldargs @@ -0,0 +1,3 @@ +/usr/sbin/bhyveload \ +-m 214 \ +-d /tmp/freebsd.img bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.xml new file mode 100644 index 0000000000000000000000000000000000000000..95492e6cbefa60cd238474ae68a6ed58f5452bda --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.xml @@ -0,0 +1,18 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + + + + + + diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-controllers.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-controllers.xml new file mode 100644 index 0000000000000000000000000000000000000000..b3f259226795ee0bd1ae65addfe1186c30a83379 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-controllers.xml @@ -0,0 +1,19 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + + + + + + + diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-devs.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-devs.xml new file mode 100644 index 0000000000000000000000000000000000000000..b0828f63263977a8ae23bcd6acb369e67147a5a9 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-devs.xml @@ -0,0 +1,19 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + + + + + + + diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-no-devs.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-no-devs.xml new file mode 100644 index 0000000000000000000000000000000000000000..323063354c80d8b529507c0c09f0e638b2cf4d9e --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-no-devs.xml @@ -0,0 +1,17 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + + + + + diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c index 4cbc398b74c7027c4db5ac8fb3c79e46a3c39c6e..475e62666961aca75dd8d655c56fa1364bbba0b4 100644 --- a/tests/bhyvexml2argvtest.c +++ b/tests/bhyvexml2argvtest.c @@ -167,7 +167,7 @@ mymain(void) driver.grubcaps = BHYVE_GRUB_CAP_CONSDEV; driver.bhyvecaps = BHYVE_CAP_RTC_UTC | BHYVE_CAP_AHCI32SLOT | \ BHYVE_CAP_NET_E1000 | BHYVE_CAP_LPC_BOOTROM | \ - BHYVE_CAP_FBUF; + BHYVE_CAP_FBUF | BHYVE_CAP_XHCI; DO_TEST("base"); DO_TEST("acpiapic"); @@ -207,6 +207,14 @@ mymain(void) DO_TEST("addr-no32devs-multiple-sata-disks"); DO_TEST_FAILURE("addr-no32devs-more-than-32-sata-disks"); + /* USB xhci tablet */ + DO_TEST("input-xhci-tablet"); + DO_TEST_FAILURE("xhci-multiple-controllers"); + DO_TEST_FAILURE("xhci-no-devs"); + DO_TEST_FAILURE("xhci-multiple-devs"); + driver.bhyvecaps ^= BHYVE_CAP_XHCI; + DO_TEST_FAILURE("input-xhci-tablet"); + driver.grubcaps = 0; DO_TEST("serial-grub-nocons"); diff --git a/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-input-xhci-tablet.xml b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-input-xhci-tablet.xml new file mode 100644 index 0000000000000000000000000000000000000000..797868e7f2554ddfb472febe306fef97c392ae61 --- /dev/null +++ b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-input-xhci-tablet.xml @@ -0,0 +1,31 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + + + + +
+ + +
+ + + +
+ + + + diff --git a/tests/bhyvexml2xmltest.c b/tests/bhyvexml2xmltest.c index ba9af29960e7298890080d5f24ce31cbf0e18cf2..3270fee3ce00d75916e033dd348e7a76bb948eec 100644 --- a/tests/bhyvexml2xmltest.c +++ b/tests/bhyvexml2xmltest.c @@ -118,6 +118,9 @@ mymain(void) DO_TEST_DIFFERENT("addr-no32devs-multiple-sata-disks"); DO_TEST_FAILURE("addr-no32devs-more-than-32-sata-disks"); + /* USB xhci tablet */ + DO_TEST_DIFFERENT("input-xhci-tablet"); + virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt);