Dear Canonical Kernel Team,
I ran several tests yesterday and the bug seems to be fixed now, my USB
FM transmitter works again!
Tests done on Ubuntu Jammy Jellyfish:
Kernel version Test result
<=5.15.0-89 OK (=device works)
5.15.0-92 KO (=USB device not enumerated)
-93 -> -138 KO
5.15.0-139 KO
>=5.15.0-140 OK
So first, what I suspected in my previous comment appears to be true.
The bug appears right after the -89 patch, in a similar context as what
I observed on Ubuntu Focal Fossa with the kernels 5.4.0-167 and
5.4.0-169.
I then tried to understand why the bug disappeared in -140 patch by
analyzing differences in source code. So I downloaded linux-
source-5.15.0_5.15.0-89.99_all.deb, linux-
source-5.15.0_5.15.0-92.102_all.deb, linux-
source-5.15.0_5.15.0-139.149_all.deb and linux-
source-5.15.0_5.15.0-140.150_all.deb, and extracted them to review the
code.
I first understood that I was misled in the original bug report due to
the changelogs of the patches which are not exhaustive at all. The
changes between -89 and -92 are huge and do not only correct bug
#2043197. So the piece of code I mentioned was actually not the culprit.
I think I found the problem by analyzing the differences between -139 and -140
source code. According to the differences seen in the kernel logs between a
working configuration and a failing configuration, I focused on the USB port
initialization mechanism found in the file drivers/usb/core/hub.c.
As far as I understood, an asynchronous event (like plugging the USB device)
triggers the hub_port_connect function. This function loops 4 times on
hub_port_init function, twice with the new scheme (get_descriptor with a 64
byte request), then powers down/up the device, and twice with the old scheme
(set_address and reads 8 bytes of the device descriptor to get the EP0 max
packet size).
In a working configuration, the USB connection process goes like this with my
device:
hub_port_connect
do_new_scheme (returns !old_scheme_first_port)
hub_port_init
maxp0=-32 -> device descriptor read/64 error
maxp0=-32 -> device descriptor read/64 error
hub_port_init
maxp0=-32 -> device descriptor read/64 error
maxp0=-32 -> device descriptor read/64 error
hub_port_power_cycle
!do_new_scheme (returns old_scheme_first_port)
hub_port_init
hub_set_address -> device not accepting address error
hub_port_init
Device is recognized.
In a failing configuration, the USB connection process goes like this:
hub_port_connect
do_new_scheme (returns !old_scheme_first_port)
hub_port_init
maxp0=-32 -> device descriptor read/64 error
maxp0=-32 -> device descriptor read/64 error
hub_port_init
maxp0=-32 -> device descriptor read/64 error
maxp0=-32 -> device descriptor read/64 error
hub_port_power_cycle
!do_new_scheme (returns old_scheme_first_port)
hub_port_init
maxp0=-32 -> device descriptor read/8 error
maxp0=-32 -> device descriptor read/8 error
hub_port_init
maxp0=-32 -> device descriptor read/8 error
maxp0=-32 -> device descriptor read/8 error
Device is not enumerated.
So the problem is the maxp0 value is wrong, it should be 8 with the old
scheme. It is returned by the get_bMaxPacketSize0 function and the code
of this function has changed between -139 and -140 patch, especially
these parts:
$ diff -u linux-source-5.15.0_5.15.0-139.149_all/usr/src/linux-
source-5.15.0/linux-source-5.15.0/drivers/usb/core/hub.c linux-
source-5.15.0_5.15.0-140.150_all/usr/src/linux-source-5.15.0/linux-
source-5.15.0/drivers/usb/core/hub.c
(...)
@@ -4673,7 +4684,6 @@
EXPORT_SYMBOL_GPL(usb_ep0_reinit);
#define usb_sndaddr0pipe() (PIPE_CONTROL << 30)
-#define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN)
static int hub_set_address(struct usb_device *udev, int devnum)
{
(...)
@@ -4774,7 +4784,7 @@
for (i = 0; i < GET_MAXPACKET0_TRIES; ++i) {
/* Start with invalid values in case the transfer fails */
buf->bDescriptorType = buf->bMaxPacketSize0 = 0;
- rc = usb_control_msg(udev, usb_rcvaddr0pipe(),
+ rc = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
USB_DT_DEVICE << 8, 0,
buf, size,
(...)
The use of usb_rcvaddr0pipe macro has been replaced by macro
usb_rcvctrlpipe which uses endpoint device number in the USB control
pipe, according to commit
https://github.com/torvalds/linux/commit/4aac0db5a0ebc599d4ad9bf5ebab78afa1f33e10
So I am not 100% sure but I really suspect this change to solve the bug!
Best regards.
** Changed in: linux (Ubuntu)
Status: New => Fix Released
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2100787
Title:
USB FM transmitter not recognized after kernel update
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2100787/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs