Framework architecture

Updated: April 19, 2023

The Shared USB framework enables guests running in virtual machines (VMs) to access USB devices connected to a QNX Hypervisor host.

The framework provides a USB virtual device (vdev) that emulates a host controller interface and allows guests to access USB devices. An enumerator service is also required, to perform guest and USB device discovery and to expose an interface that allows host applications to monitor and respond to device insertions and removals. We provide an example of an enumerator but you can write your own.

Note:

This chapter assumes that you are already familiar with the concepts presented in the following documentation:

USB device sharing

The hypervisor host manages all interactions between guests and USB devices, as follows:

The diagram below illustrates the components involved in interactions between guests and USB devices, managed by the hypervisor host.

Architectural diagram showing how guest, host, and hardware components interact to allow guest and host applications to share USB devices
Figure 1. Shared USB framework architecture
Note: For more information on device sharing in the QNX Hypervisor, see the section on “Devices” in the “Understanding QNX Virtual Environments” chapter of the QNX Hypervisor User's Guide.

Handling of device insertions and removals

The USB framework differs from other shared frameworks because the xHCI vdev must respond dynamically to device insertions and removals. Other frameworks provide guests with access to shared resources that either are always present on the host system (e.g., the VPU) or allow the guest to access data whenever it's available, without having to know if the device is still physically connected (e.g., sensors, cameras). But USB devices can be added or removed at any time, and the vdev must respond in turn.

The USB stack is the service that detects whenever a device is inserted or removed, and it notifies the enumerator in both cases. When the enumerator learns of a device insertion, it publishes information about the device through the Persistent Publish/Subscribe (PPS) service. A privileged application, such as the main HMI process, that's subscribed to the appropriate PPS objects can respond to device insertions. For instance, the HMI process can learn that a USB stick has been inserted and ask the user a question such as “Play music on new device?”. If the user says yes, the HMI process informs the enumerator through PPS.

If the HMI input information indicates that the device belongs to the host, the enumerator launches the necessary class- or function-specific device driver (e.g., devb-ustor for mass storage devices). If the device belongs to the guest system, the enumerator sends a command to the vdev that tells it to attach to the device via the USB stack. This device can then be used by guest applications.

If the user chooses to detach a device through the HMI process, this process informs the enumerator. When the enumerator receives this notice through its PPS interface, it stops the associated device driver, removes the device information from PPS, and if the device belongs to the guest system, the enumerator sends the vdev a command telling it to detach from the device.

The vdev also monitors the stack for device removals (but not insertions), so it can handle the case when a device is physically disconnected. When this happens, the vdev detaches from this device, which is then no longer accessible to guest applications. This design means the vdev interacts directly with both the enumerator and the USB stack, for different purposes. Because the enumerator also receives notice when a device is disconnected, it can respond by removing the device information from PPS.