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);