Bug 217651

Summary: BCM20702B0 Bluetooth device in MacBook no longer working
Product: Drivers Reporter: johnbholland
Component: BluetoothAssignee: linux-bluetooth (linux-bluetooth)
Status: NEW ---    
Severity: normal CC: alexucu, bagasdotme, desowin, josacar+kernel, krakenfury, nick4temp-lfsofm, pmenzel+bugzilla.kernel.org, regressions
Priority: P3    
Hardware: All   
OS: Linux   
Kernel Version: Subsystem:
Regression: No Bisected commit-id:
Attachments: lspci from arch kernel 6.3.9
dmesg from arch kernel 6.3.9
lspci from arch kernel 6.4.1
dmesg from arch kernel 6.4.1

Description johnbholland 2023-07-09 22:56:17 UTC
BCM20702B0 Bluetooth device on intel MacBook from 2014 not found by kernel 6.4.2.
Comment 1 johnbholland 2023-07-09 22:57:49 UTC
Based on using kernel supplied by arch Linux. 6.1 kernel finds the device.
Comment 2 Bagas Sanjaya 2023-07-10 03:33:56 UTC
Can you attach lspci and dmesg? Can you also perform bisection to find the culprit commit (see Documentation/admin-guide/bug-bisect.rst for details)?
You'll most likely need to compile your own kernel anyway, so read Documentation/admin-guide/quickly-build-trimmed-linux.rst for the instructions.
Comment 3 johnbholland 2023-07-10 12:08:29 UTC
Created attachment 304584 [details]
lspci from arch kernel 6.3.9

this is the latest 6.3.9 kernel in the arch archive, and bluetooth works with it
Comment 4 johnbholland 2023-07-10 12:09:07 UTC
Created attachment 304585 [details]
dmesg from arch kernel 6.3.9

this is the latest 6.3.9 kernel in the arch archive, and bluetooth works with it
Comment 5 johnbholland 2023-07-10 12:09:57 UTC
Created attachment 304586 [details]
lspci from arch kernel 6.4.1

this is the first 6.4.1 kernel in the arch archive, and bluetooth doesn't work with it
Comment 6 johnbholland 2023-07-10 12:10:38 UTC
Created attachment 304587 [details]
dmesg from arch kernel 6.4.1

this is the first 6.4.1 kernel in the arch archive, and bluetooth doesn't work with it
Comment 7 johnbholland 2023-07-10 12:11:23 UTC
Comment on attachment 304586 [details]
lspci from arch kernel 6.4.1

this is the first 6.4.1 kernel in the arch archive, and bluetooth doesn't work  with it
Comment 8 johnbholland 2023-07-10 12:13:47 UTC
(In reply to Bagas Sanjaya from comment #2)
> Can you attach lspci and dmesg? Can you also perform bisection to find the
> culprit commit (see Documentation/admin-guide/bug-bisect.rst for details)?
> You'll most likely need to compile your own kernel anyway, so read
> Documentation/admin-guide/quickly-build-trimmed-linux.rst for the
> instructions.

Hi,
I installed 6.3.9 and 6.4.1 kernels from arch archive and found that 6.3.9 produces working bluetooth and 6.4.1 does not. I will look into building and running from mainline but that may be beyond my skills.
Comment 9 johnbholland 2023-07-10 12:14:10 UTC
(In reply to Bagas Sanjaya from comment #2)
> Can you attach lspci and dmesg? Can you also perform bisection to find the
> culprit commit (see Documentation/admin-guide/bug-bisect.rst for details)?
> You'll most likely need to compile your own kernel anyway, so read
> Documentation/admin-guide/quickly-build-trimmed-linux.rst for the
> instructions.

working and non-working lspci and dmesg output is attached.
Comment 10 johnbholland 2023-07-10 18:50:16 UTC
Since I recently retired, I have some time to put into this. I have 
built 6.3.12 and 6.4.0-rc1 from kernel.org sources and tested, the 
6.3.12 works and the 6.4.0-rc1 does not (in terms of the bluetooth 
issue). Looking at the git log of 6.4.0 there was a lot of bluetooth 
related activity. I've chosen a commit from before that and am trying to 
build that and test it. If it boots and the bluetooth works, I guess 
6.4.0-rc1 and that starting point could be initial points to use in 
bisecting? This is somewhat new territory for me but so far it's been 
pretty straightforward.  The kernel builds take a long time on this 
macbook pro from 2014.

On 7/9/23 23:33, bugzilla-daemon@kernel.org wrote:
> https://bugzilla.kernel.org/show_bug.cgi?id=217651
>
> Bagas Sanjaya (bagasdotme@gmail.com) changed:
>
>             What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                   CC|                            |bagasdotme@gmail.com
>
> --- Comment #2 from Bagas Sanjaya (bagasdotme@gmail.com) ---
> Can you attach lspci and dmesg? Can you also perform bisection to find the
> culprit commit (see Documentation/admin-guide/bug-bisect.rst for details)?
> You'll most likely need to compile your own kernel anyway, so read
> Documentation/admin-guide/quickly-build-trimmed-linux.rst for the
> instructions.
>
Comment 11 Bagas Sanjaya 2023-07-11 01:18:49 UTC
On 7/11/23 01:50, John Holland wrote:
> Since I recently retired, I have some time to put into this. I have built
> 6.3.12 and 6.4.0-rc1 from kernel.org sources and tested, the 6.3.12 works and
> the 6.4.0-rc1 does not (in terms of the bluetooth issue). Looking at the git
> log of 6.4.0 there was a lot of bluetooth related activity. I've chosen a
> commit from before that and am trying to build that and test it. If it boots
> and the bluetooth works, I guess 6.4.0-rc1 and that starting point could be
> initial points to use in bisecting? This is somewhat new territory for me but
> so far it's been pretty straightforward.  The kernel builds take a long time
> on this macbook pro from 2014.

tl;dr:

> A: http://en.wikipedia.org/wiki/Top_post
> Q: Were do I find info about this thing called top-posting?
> A: Because it messes up the order in which people normally read text.
> Q: Why is top-posting such a bad thing?
> A: Top-posting.
> Q: What is the most annoying thing in e-mail?
> 
> A: No.
> Q: Should I include quotations after my reply?
> 
> http://daringfireball.net/2007/07/on_top

Please see Documentation/admin-guide/quickly-build-trimmed-linux.rst
for how to quickly compile your own kernel.

Bye!
Comment 12 The Linux kernel's regression tracker (Thorsten Leemhuis) 2023-07-11 14:37:46 UTC
(In reply to johnbholland from comment #10)
> I've chosen a commit from before that and am trying to 
> build that and test it. If it boots and the bluetooth works, I guess 
> 6.4.0-rc1 and that starting point could be initial points to use in 
> bisecting? 

Thanks for trying to find the cause, that helpful and simply needed in cases like this. You might want to bisect between 6.3 and 6.4, as maybe it's some change outside of bluetooth that broke things (but it's possible that you are on the right track, too). 

Side notes: 
* might be worth giving 6.5-rc1 a try, with a bit of luck it might contain a fix (but there is a decent chance we are unlucky).
* cross-compiling might help to speed things up.
Comment 13 johnbholland 2023-07-11 16:13:15 UTC
> Thanks for trying to find the cause, that helpful and simply needed in cases
> like this. You might want to bisect between 6.3 and 6.4, as maybe it's some
> change outside of bluetooth that broke things (but it's possible that you are
> on the right track, too).
>
> Side notes:
> * might be worth giving 6.5-rc1 a try, with a bit of luck it might contain a
> fix (but there is a decent chance we are unlucky).
> * cross-compiling might help to speed things up.


You're welcome. This is a new experience for me. It's pretty mechanical 
at this point, it just takes a while for each kernel rebuild. I hope at 
the end of it to have some useful information.I may be doing this off 
and on for a couple days :) . I'm getting much more comfortable with the 
steps to make my system boot with a new kernel.
Comment 14 johnbholland 2023-07-12 22:59:51 UTC
I believe I have identified the problem and a fix. Commit c13380a55522bf14e54779a142487c224509db95 is the cause, found by bisecting and testing. Without it (built from immediately prior commit) the problem goes away. Also, in the current code, this change is there and the latest version 6.5.0-rc1 has the issue, and it can be fixed by reverting this change. The change in question is:

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 5c536151ef83..4ca91c033d2f 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -3831,13 +3831,9 @@ static int btusb_probe(struct usb_interface *intf,
 
        BT_DBG("intf %p id %p", intf, id);
 
-       /* interface numbers are hardcoded in the spec */
-       if (intf->cur_altsetting->desc.bInterfaceNumber != 0) {
-               if (!(id->driver_info & BTUSB_IFNUM_2))
-                       return -ENODEV;
-               if (intf->cur_altsetting->desc.bInterfaceNumber != 2)
-                       return -ENODEV;
-       }
+       if ((id->driver_info & BTUSB_IFNUM_2) &&
+           (intf->cur_altsetting->desc.bInterfaceNumber != 2))
+               return -ENODEV;
 
        ifnum_base = intf->cur_altsetting->desc.bInterfaceNumber;

( - is the code that works, + is the code that doesn't). 
Looking at the code, it looks like it was meant to remove the outer if statement and turn the inner part into something simpler. I think it is missing an ! and uses && instead of || if that is what it intends. 

When I changed it to that though, the problem still existed. So what worked for me was to revert this block of code to the previous version, in both 6.3 and 6.5.  In 6.5 this file has changed a lot, but this block is the same as the commit made it. 

My 2014 Macbook Pro is perhaps an obscure bit of hardware and I don't know whether this change was fixing something on other hardware. On my Macbook, though, it causes the internal Bluetooth controller to not be seen. 
I will also send an email to the people in the commit,
 Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
    Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Comment 15 Paul Menzel 2023-07-13 04:18:01 UTC
John sent a notification to the mailing list, so I am adding the back link: https://lore.kernel.org/linux-bluetooth/552a361b-d699-5d96-543a-e3aa09e6c05c@molgen.mpg.de/T/#t
Comment 16 Tomasz Moń 2023-07-13 05:36:09 UTC
Could you please attach "lsusb -d 05ac: -v" output?
Comment 17 Tomasz Moń 2023-07-13 05:45:28 UTC
I think I understand the issue now, but the lsusb output would confirm it. Before my patch, the driver would allow both interface 0 and 2, after it only interface 2 is allowed for devices with BTUSB_IFNUM_2 flag set.

I see two potential solutions:
  1. Remove the check completely
  2. Change the if condition to allow both interface 0 and 2.

For the second solution, please try following patch:

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 5ec4ad0a5c86..46844194f54e 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -4104,7 +4104,8 @@ static int btusb_probe(struct usb_interface *intf,
        BT_DBG("intf %p id %p", intf, id);
 
        if ((id->driver_info & BTUSB_IFNUM_2) &&
-           (intf->cur_altsetting->desc.bInterfaceNumber != 2))
+           ((intf->cur_altsetting->desc.bInterfaceNumber != 0) ||
+            (intf->cur_altsetting->desc.bInterfaceNumber != 2))
                return -ENODEV;
 
        ifnum_base = intf->cur_altsetting->desc.bInterfaceNumber;
Comment 18 Tomasz Moń 2023-07-13 05:58:19 UTC
The previous proposal is bogus as I messed up the conditions again. It would reject anything with BTUSB_IFNUM_2 when the interface is either 0 or 2. What we want is to allow either 0 or 2 when BTUSB_IFNUM_2 is set.

The correct patch to try would be:

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 5ec4ad0a5c86..764d176e9735 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -4104,6 +4104,7 @@ static int btusb_probe(struct usb_interface *intf,
        BT_DBG("intf %p id %p", intf, id);
 
        if ((id->driver_info & BTUSB_IFNUM_2) &&
+           (intf->cur_altsetting->desc.bInterfaceNumber != 0) &&
            (intf->cur_altsetting->desc.bInterfaceNumber != 2))
                return -ENODEV;
Comment 19 Nick Bates 2023-07-13 11:31:09 UTC
I also have a problem with bluetooth, also on ArchLinux, but on a Dell Latitude E7240. I'll try with the kernel versions mentioned above, and also try Tomasz's patch, in the next few days (urgent tasks first ...).

Bear in mind, I still see the bluetooth controller, but bluetoothd either crashes or exhibits strange behaviour when my Plantronics BackBeat GO 600 headphones connect.

Does anyone want to see my lspci/journalctl output?
Comment 20 Paul Menzel 2023-07-13 11:46:09 UTC
Nick, thank you for the report, but please create a new issue with all the information like all logs, what devices work and what do not and if it’s a regression.
Comment 21 johnbholland 2023-07-13 11:54:10 UTC
Hi,
the following code is working on my 2014 Intel Macbook Pro -

Thanks for the good work!

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 5ec4ad0a5c86..596dc69ce510 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -4103,9 +4103,11 @@ static int btusb_probe(struct usb_interface *intf,
 
        BT_DBG("intf %p id %p", intf, id);
 
-       if ((id->driver_info & BTUSB_IFNUM_2) &&
-           (intf->cur_altsetting->desc.bInterfaceNumber != 2))
-               return -ENODEV;
+
+               if ((id->driver_info & BTUSB_IFNUM_2) &&
+           (intf->cur_altsetting->desc.bInterfaceNumber != 0) &&
+           (intf->cur_altsetting->desc.bInterfaceNumber != 2))
+               return -ENODEV;
 
        ifnum_base = intf->cur_altsetting->desc.bInterfaceNumber;
Comment 22 alexucu 2023-08-28 20:34:20 UTC
I can also confirm it's now working on my 2017 Intel Macbook Air. Thank you all for testing & fixing this so quickly.