Discussion:
Indexing problem with address number of a USB device
Naina Patrascu
2021-05-11 15:47:54 UTC
Permalink
Hello,

We are working on the USB passthrough functionality for bhyve. We are
currently focusing on the passthrough of a USB stick and a USB keyboard.

We are facing an indexing problem when trying to assign a USB device to a
virtual machine.
For example, we have the USB keyboard at busnum=1 and devaddr=2 on the
FreeBSD host virtual machine:

# usbconfig -d ugen1.2
ugen1.2: <Gaming KB Gaming KB> at usbus1, cfg=0 md=HOST spd=LOW (1.5Mbps)
pwr=ON (100mA)

We specify to "bhyve" command to pass through the device to a guest virtual
machine: -s 30,xhci,1-2

As part of the enumeration process, the host controller executes the
internal scan to discover the physical devices and to compare them with the
ones assigned with the bhyve command.
But the USB device is discovered at bus 1 address 1, and we have to adjust
accordingly when parsing the bus-port to match the port number:

04f3:152e 1-1 connecting.
04f3:152e 1-1 belong to this vm.
04F3:152E 1-1 is attached to virtual port 5.

We hardcoded when parsing bus-port: port -= 1.
When trying to pass through a USB stick, we have to increase the port
number to match the one discovered in the internal scan:

# usbconfig -d ugen3.2
ugen3.2: <Kingston DataTraveler 3.0> at usbus3, cfg=0 md=HOST spd=HIGH
(480Mbps) pwr=ON (300mA)

0951:1666 3-3 connecting.
0951:1666 3-3 belong to this vm.
0951:1666 3-3 is attached to virtual port 1.

In our last investigation, we discovered that when increasing the number of
USB devices on the FreeBSD host vm, the port indexes of the devices
discovered by the internal scan, also varies.

In function [1] we get the physical devices using libusb library and then
we execute the internal scan using function [2]. We get the information
about the physical device in function [3], also using libusb library.

Can you help us understand where this problem could come from and how to
debug it?

Thank you!

[1]
https://github.com/FreeBSD-UPB/freebsd-src/blob/a861e57e10512c0e3406762ffba2249bbd786492/usr.sbin/bhyve/usb_pmapper.c#L121
[2]
https://github.com/FreeBSD-UPB/freebsd-src/blob/a861e57e10512c0e3406762ffba2249bbd786492/usr.sbin/bhyve/usb_pmapper.c#L76
[3]
https://github.com/FreeBSD-UPB/freebsd-src/blob/a861e57e10512c0e3406762ffba2249bbd786492/usr.sbin/bhyve/usb_pmapper.c#L24
John-Mark Gurney
2021-05-12 19:14:48 UTC
Permalink
Post by Naina Patrascu
We are working on the USB passthrough functionality for bhyve. We are
currently focusing on the passthrough of a USB stick and a USB keyboard.
We are facing an indexing problem when trying to assign a USB device to a
virtual machine.
For example, we have the USB keyboard at busnum=1 and devaddr=2 on the
# usbconfig -d ugen1.2
ugen1.2: <Gaming KB Gaming KB> at usbus1, cfg=0 md=HOST spd=LOW (1.5Mbps)
pwr=ON (100mA)
We specify to "bhyve" command to pass through the device to a guest virtual
machine: -s 30,xhci,1-2
As part of the enumeration process, the host controller executes the
internal scan to discover the physical devices and to compare them with the
ones assigned with the bhyve command.
But the USB device is discovered at bus 1 address 1, and we have to adjust
04f3:152e 1-1 connecting.
04f3:152e 1-1 belong to this vm.
04F3:152E 1-1 is attached to virtual port 5.
We hardcoded when parsing bus-port: port -= 1.
When trying to pass through a USB stick, we have to increase the port
# usbconfig -d ugen3.2
ugen3.2: <Kingston DataTraveler 3.0> at usbus3, cfg=0 md=HOST spd=HIGH
(480Mbps) pwr=ON (300mA)
0951:1666 3-3 connecting.
0951:1666 3-3 belong to this vm.
0951:1666 3-3 is attached to virtual port 1.
In our last investigation, we discovered that when increasing the number of
USB devices on the FreeBSD host vm, the port indexes of the devices
discovered by the internal scan, also varies.
In function [1] we get the physical devices using libusb library and then
we execute the internal scan using function [2]. We get the information
about the physical device in function [3], also using libusb library.
Can you help us understand where this problem could come from and how to
debug it?
Yes, the ugen named does not map to port naming. I ran across this when
I did the work to make serial devices consistent based upon the port
number. The review for that work is here:
https://reviews.freebsd.org/D21886#554613

The device address is a different enumeration from the port address
information. The script linked in the review creates a mapping from
the device name to the proper port number mapping.

To see this, you can look at devinfo -v, and look at the port value
vs the devaddr (device address assigned at enumeration).

Hope this helps.
--
John-Mark Gurney Voice: +1 415 225 5579

"All that I will do, has been done, All that I have, has not."
Hans Petter Selasky
2021-05-12 19:23:15 UTC
Permalink
Post by John-Mark Gurney
Post by Naina Patrascu
We are working on the USB passthrough functionality for bhyve. We are
currently focusing on the passthrough of a USB stick and a USB keyboard.
We are facing an indexing problem when trying to assign a USB device to a
virtual machine.
For example, we have the USB keyboard at busnum=1 and devaddr=2 on the
# usbconfig -d ugen1.2
ugen1.2: <Gaming KB Gaming KB> at usbus1, cfg=0 md=HOST spd=LOW (1.5Mbps)
pwr=ON (100mA)
We specify to "bhyve" command to pass through the device to a guest virtual
machine: -s 30,xhci,1-2
As part of the enumeration process, the host controller executes the
internal scan to discover the physical devices and to compare them with the
ones assigned with the bhyve command.
But the USB device is discovered at bus 1 address 1, and we have to adjust
04f3:152e 1-1 connecting.
04f3:152e 1-1 belong to this vm.
04F3:152E 1-1 is attached to virtual port 5.
We hardcoded when parsing bus-port: port -= 1.
When trying to pass through a USB stick, we have to increase the port
# usbconfig -d ugen3.2
ugen3.2: <Kingston DataTraveler 3.0> at usbus3, cfg=0 md=HOST spd=HIGH
(480Mbps) pwr=ON (300mA)
0951:1666 3-3 connecting.
0951:1666 3-3 belong to this vm.
0951:1666 3-3 is attached to virtual port 1.
In our last investigation, we discovered that when increasing the number of
USB devices on the FreeBSD host vm, the port indexes of the devices
discovered by the internal scan, also varies.
In function [1] we get the physical devices using libusb library and then
we execute the internal scan using function [2]. We get the information
about the physical device in function [3], also using libusb library.
Can you help us understand where this problem could come from and how to
debug it?
Yes, the ugen named does not map to port naming. I ran across this when
I did the work to make serial devices consistent based upon the port
https://reviews.freebsd.org/D21886#554613
The device address is a different enumeration from the port address
information. The script linked in the review creates a mapping from
the device name to the proper port number mapping.
To see this, you can look at devinfo -v, and look at the port value
vs the devaddr (device address assigned at enumeration).
Hope this helps.
Hi,

LibUSB in FreeBSD has a helper function to compute the full port topology:

libusb_get_port_numbers()
and:

libusb20_dev_get_port_path()

--HPS
Naina Patrascu
2021-06-01 09:09:59 UTC
Permalink
It worked!
Thank you!

You were right, we assigned the USB through bus and device address, but we
were comparing the port number in the enumeration process.
Post by Naina Patrascu
Post by John-Mark Gurney
Post by Naina Patrascu
We are working on the USB passthrough functionality for bhyve. We are
currently focusing on the passthrough of a USB stick and a USB keyboard.
We are facing an indexing problem when trying to assign a USB device to
a
Post by John-Mark Gurney
Post by Naina Patrascu
virtual machine.
For example, we have the USB keyboard at busnum=1 and devaddr=2 on the
# usbconfig -d ugen1.2
ugen1.2: <Gaming KB Gaming KB> at usbus1, cfg=0 md=HOST spd=LOW
(1.5Mbps)
Post by John-Mark Gurney
Post by Naina Patrascu
pwr=ON (100mA)
We specify to "bhyve" command to pass through the device to a guest
virtual
Post by John-Mark Gurney
Post by Naina Patrascu
machine: -s 30,xhci,1-2
As part of the enumeration process, the host controller executes the
internal scan to discover the physical devices and to compare them with
the
Post by John-Mark Gurney
Post by Naina Patrascu
ones assigned with the bhyve command.
But the USB device is discovered at bus 1 address 1, and we have to
adjust
Post by John-Mark Gurney
Post by Naina Patrascu
04f3:152e 1-1 connecting.
04f3:152e 1-1 belong to this vm.
04F3:152E 1-1 is attached to virtual port 5.
We hardcoded when parsing bus-port: port -= 1.
When trying to pass through a USB stick, we have to increase the port
# usbconfig -d ugen3.2
ugen3.2: <Kingston DataTraveler 3.0> at usbus3, cfg=0 md=HOST spd=HIGH
(480Mbps) pwr=ON (300mA)
0951:1666 3-3 connecting.
0951:1666 3-3 belong to this vm.
0951:1666 3-3 is attached to virtual port 1.
In our last investigation, we discovered that when increasing the
number of
Post by John-Mark Gurney
Post by Naina Patrascu
USB devices on the FreeBSD host vm, the port indexes of the devices
discovered by the internal scan, also varies.
In function [1] we get the physical devices using libusb library and
then
Post by John-Mark Gurney
Post by Naina Patrascu
we execute the internal scan using function [2]. We get the information
about the physical device in function [3], also using libusb library.
Can you help us understand where this problem could come from and how to
debug it?
Yes, the ugen named does not map to port naming. I ran across this when
I did the work to make serial devices consistent based upon the port
https://reviews.freebsd.org/D21886#554613
The device address is a different enumeration from the port address
information. The script linked in the review creates a mapping from
the device name to the proper port number mapping.
To see this, you can look at devinfo -v, and look at the port value
vs the devaddr (device address assigned at enumeration).
Hope this helps.
Hi,
libusb_get_port_numbers()
libusb20_dev_get_port_path()
--HPS
Continue reading on narkive:
Loading...