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 Kernel
Packages, which is subscribed to linux in Ubuntu.
https://bugs.launchpad.net/bugs/2100787

Title:
  USB FM transmitter not recognized after kernel update

Status in linux package in Ubuntu:
  Fix Released

Bug description:
  Hello,

  I occasionally use an USB FM transmitter to send audio from my laptop to 
hi-fi systems that don't have the ability to receive a bluetooth stream but 
have a FM tuner. I use that kind of cheap module which works great, in stereo 
mode (see picture in the JPG attachment):
  
https://fr.aliexpress.com/item/32921292502.html?spm=a2g0o.store_pc_allItems_or_groupList.0.0.677dd1cb71GfSm&pdp_npi=4%40dis%21EUR%21%E2%82%AC%205%2C74%21%E2%82%AC%205%2C69%21%21%215.84%215.79%21%40211b6c1917410185656756898ea2ae%2166245292113%21sh%21FR%210%21X&_gl=1*xvmald*_gcl_au*NDk2OTk1ODI3LjE3NDEwMTgyMzE.*_ga*NjA0NjU3MDUyLjE3NDEwMTgyMzE.*_ga_VED1YSGNC7*MTc0MTAxODIzMS4xLjEuMTc0MTAxODU2My4xLjAuMA..&gatewayAdapt=glo2fra

  It is recognized on Ubuntu Desktop as an external sound card with the
  HID driver. It worked well until kernel 5.4.0-167 on Ubuntu 20.04 and
  it fails since 5.4.0-169. Bug occurs also on an updated Ubuntu desktop
  22.04 with kernel 5.15.0-133.

  The USB device is working in USB 1.1 (see attached lsusb.txt file) and
  plugged into an USB 2.0 port. You will find in attachment the kernel
  logs (dmesg.txt) when device is recognized in 5.4.0-167 and when it is
  not recognized in 5.15.0-133 (dmesg_fail.txt). This bug exists since
  November 2023 but I may not have used my USB device since then, as I
  weekly update my software packages.

  When we look at the changelog of the identified patch, it fixes only
  bug #2043197. This bug was fixed by commit
  
https://github.com/torvalds/linux/commit/59cf445754566984fd55af19ba7146c76e6627bc

  So, not sure about that but I assume the bug I encounter deals with
  the following code in drivers/usb/core/hub.c, as seen now on master
  branch:

        /*
         * Check the ep0 maxpacket guess and correct it if necessary.
         * maxp0 is the value stored in the device descriptor;
         * i is the value it encodes (logarithmic for SuperSpeed or greater).
         */
        i = maxp0;
        if (udev->speed >= USB_SPEED_SUPER) {
                if (maxp0 <= 16)
                        i = 1 << maxp0;
                else
                        i = 0;          /* Invalid */
        }
        if (usb_endpoint_maxp(&udev->ep0.desc) == i) {
                ;       /* Initial ep0 maxpacket guess is right */
        } else if (((udev->speed == USB_SPEED_FULL ||
                                udev->speed == USB_SPEED_HIGH) &&
                        (i == 8 || i == 16 || i == 32 || i == 64)) ||
                        (udev->speed >= USB_SPEED_SUPER && i > 0)) {
                /* Initial guess is wrong; use the descriptor's value */
                if (udev->speed == USB_SPEED_FULL)
                        dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
                else
                        dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i);
                udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);
                usb_ep0_reinit(udev);
        } else {
                /* Initial guess is wrong and descriptor's value is invalid */
                dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", maxp0);
                retval = -EMSGSIZE;
                goto fail;
        }

  I am not a kernel source code specialist but as far as I understand,
  is there a missing part in the code not taking the "USB_SPEED_LOW"
  devices into account?

  Kind regards.
  --- 
  ProblemType: Bug
  ApportVersion: 2.20.11-0ubuntu27.27
  Architecture: amd64
  AudioDevicesInUse:
   USER        PID ACCESS COMMAND
   /dev/snd/controlC0:  julien     1825 F.... pulseaudio
  CasperMD5CheckResult: skip
  CurrentDesktop: ubuntu:GNOME
  DistroRelease: Ubuntu 20.04
  HibernationDevice: RESUME=UUID=6e70bb6c-220e-4305-a3bc-ad053501dceb
  InstallationDate: Installed on 2016-10-07 (3069 days ago)
  InstallationMedia: Ubuntu 16.04.1 LTS "Xenial Xerus" - Release amd64 
(20160719)
  MachineType: Dell Inc. Inspiron N5010
  Package: linux (not installed)
  ProcEnviron:
   TERM=xterm-256color
   PATH=(custom, no user)
   XDG_RUNTIME_DIR=<set>
   LANG=fr_FR.UTF-8
   SHELL=/bin/bash
  ProcFB: 0 i915drmfb
  ProcKernelCmdLine: BOOT_IMAGE=/boot/vmlinuz-5.4.0-167-generic 
root=UUID=f1cf9527-1952-4da1-8cbd-1e9e652b733e ro quiet splash vt.handoff=7
  ProcVersionSignature: Ubuntu 5.4.0-167.184-generic 5.4.252
  RelatedPackageVersions:
   linux-restricted-modules-5.4.0-167-generic N/A
   linux-backports-modules-5.4.0-167-generic  N/A
   linux-firmware                             1.187.39
  Tags:  focal
  Uname: Linux 5.4.0-167-generic x86_64
  UpgradeStatus: Upgraded to focal on 2023-05-18 (655 days ago)
  UserGroups: adm cdrom dip lpadmin plugdev sambashare sudo
  _MarkForUpload: True
  dmi.bios.date: 01/25/2011
  dmi.bios.vendor: Dell Inc.
  dmi.bios.version: A12
  dmi.board.name: 0WXY9J
  dmi.board.vendor: Dell Inc.
  dmi.board.version: A12
  dmi.chassis.type: 8
  dmi.chassis.vendor: Dell Inc.
  dmi.chassis.version: A12
  dmi.modalias: 
dmi:bvnDellInc.:bvrA12:bd01/25/2011:svnDellInc.:pnInspironN5010:pvrA12:rvnDellInc.:rn0WXY9J:rvrA12:cvnDellInc.:ct8:cvrA12:
  dmi.product.name: Inspiron N5010
  dmi.product.sku: To be filled by O.E.M.
  dmi.product.version: A12
  dmi.sys.vendor: Dell Inc.

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2100787/+subscriptions


-- 
Mailing list: https://launchpad.net/~kernel-packages
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~kernel-packages
More help   : https://help.launchpad.net/ListHelp

Reply via email to