Linux Fu: The Bluetooth Regression  Al Williams | amznusa.com

There’s a line in a [Weird Al] (no relation) song that says, “I upgrade my system at least twice a day…” I know how that is. I primarily use a rolling distro, OpenSuse Tumbleweed, and if I’m having a problem that I’m too lazy to run down, it is extremely tempting to do an upgrade and see if it just happens to fix the problem.

Of course, the problem is often caused by a previous upgrade. Recently, I’ve been having a lot of trouble with the NVIDIA proprietary drivers, so I updated them yet again. After a huge amount of effort to sort out the video problems, I found that the latest kernel didn’t like my MediaTek Bluetooth adapter, which is built into the motherboard’s WiFi chipset.

This post isn’t about how to fix your Bluetooth problem. You probably don’t have the same setup I do, and even if you do, it will be sorted out in a week or two anyway. But how I temporarily fixed this issue is worth documenting. The details are going to apply to Tumbleweed and this particular adapter, but the general approach should work anywhere with any sort of kernel module problem.

My Own Fault

Part of my problem is my own fault, of course. I have a complex disk setup and do not use the recommended btrfs root file system. That means I can’t do the snapshot thing where I can just undo a bad upgrade. If I did, then sure, I should just roll back and wait for an upstream fix.

I do have “normal” backups, but they are not always totally up to date. Worse, I have found that for things like NVIDIA, the user stuff and the kernel module stuff have to match up. That makes it very hard to roll back a kernel with older modules. The modules themselves live with the kernel, but the user space stuff gets pushed out. Or, if you uninstall things, it uninstalls it for all kernels.

Truthfully, NVIDIA and others like that should keep all the user space stuff in a kernel-specific place, and then symlink it at boot to /usr/bin or wherever. But they don’t. In the end, I didn’t want to go through the trouble of rolling things back and decided to push ahead.

Modular

I did a quick search and found a four-day-old post that had the same error message I was getting and mentioned a patch to the kernel module source — literally just two lines needed changing in the btmtk module.

Of course, the trick is how to do that. If you’ve done kernel module development, you are probably all set up for it. If not, how to proceed will vary by distro. For Tumbleweed, something like:

sudo zypper in -t pattern devel_kernel
sudo zypper in kernel-source kernel-default-devel kernel-syms gcc make bc flex bison openssl-devel dwarves

For other distros, you need the current kernel’s source code and the same sort of build tools. For example, for Ubuntu and probably other Debian-based distros:

sudo apt update
sudo apt install build-essential linux-headers-$(uname -r) linux-source bc flex bison libssl-dev libelf-dev dwarves rsync

Then you’d still need to unpack the source tarball.

For Tumbleweed, you don’t need to unpack, but I did want to get it somewhere in my user directory:

mkdir -p ~/kernel-local
# Note: trailing slashes matter here!
rsync -a --delete /usr/src/linux/ ~/kernel-local/linux-btmtk/
cd ~/kernel-local/linux-btmtk

Either way, you need to get the running kernel’s configurations into the linux-btmtk directory:

cp /lib/modules/$(uname -r)/build/.config .
cp /lib/modules/$(uname -r)/build/Module.symvers . 2>/dev/null || true

The Patch

The next step is to find the btmtk.c file and patch it. In my case, I needed to find this code: case BTMTK_WMT_FUNC_CTRL: if (!skb_pull_data(data->evt_skb, sizeof(wmt_evt_funcc->status))) { err = -EINVAL; goto err_free_skb; }

 

and replace the error return/goto with:

status = BTMTK_WMT_ON_UNDONE;
break;

The Build

Now you just have to build and install the module:

make olddefconfig
make modules_prepare
make M=drivers/bluetooth modules

If you want to use multiple CPUs, put a -j=X line on make (e.g,. -j=8 to use eight cores). This will take a minute.

You’ll wind up with a drivers/bluetooth/btmtk.ko file. Your first instinct will be to simply copy it over the old one. Resist that urge. Instead, try this:

sudo mkdir -p /lib/modules/$(uname -r)/updates/drivers/bluetooth
sudo cp drivers/bluetooth/btmtk.ko /lib/modules/$(uname -r)/updates/drivers/bluetooth/
sudo depmod -a

Run It!

If you want to verify things, try:

modinfo -n btmtk

It should show your module and not the stock one. You could try to avoid rebooting by stopping the Bluetooth service, tearing down btusb and btmtk, and then reloading them along with the service. But, yeah, just reboot.

If your distro is different, you might have to modify these instructions a bit. Of course, you also need to know how to fix the bad module, too. Naturally, if you update the kernel, you might have to repeat it all unless your problem has been fixed. Then again, you could set up the module in DKMS to rebuild every time, but I wouldn’t unless you really thought this was going to be a long-term problem.

Once you have all this set up, you could also build your own kernel. That’s another set of headaches, but it can be worth it if you need special setups. Want to write your own modules? We’ve done that.

 

This articles is written by : Fady Askharoun Samy Askharoun

All Rights Reserved to Amznusa www.amznusa.com

Why Amznusa?

AMZNUSA is a dynamic website that focuses on three primary categories: Technology, e-commerce and cryptocurrency news. It provides users with the latest updates and insights into online retail trends and the rapidly evolving world of digital currencies, helping visitors stay informed about both markets.