diff --git a/hosts/monolith/default.nix b/hosts/monolith/default.nix index 3350e0d..ff2b193 100644 --- a/hosts/monolith/default.nix +++ b/hosts/monolith/default.nix @@ -38,7 +38,14 @@ in boot.kernelPackages = pkgs.linuxPackages_latest; - boot.extraModulePackages = with config.boot.kernelPackages; [ zenpower ]; + boot.extraModulePackages = with config.boot.kernelPackages; [ + zenpower + (pkgs.linux-bluetooth.override { + kernel = config.boot.kernelPackages.kernel; + patches = [ ../../patches/linux/v2-Bluetooth-btusb-Fix-regression-with-CSR-controllers.diff ]; + }) + ]; + boot.initrd.kernelModules = [ "amdgpu" ]; boot.kernelModules = [ "kvm-amd" diff --git a/patches/linux/v2-Bluetooth-btusb-Fix-regression-with-CSR-controllers.diff b/patches/linux/v2-Bluetooth-btusb-Fix-regression-with-CSR-controllers.diff new file mode 100644 index 0000000..ae1adeb --- /dev/null +++ b/patches/linux/v2-Bluetooth-btusb-Fix-regression-with-CSR-controllers.diff @@ -0,0 +1,24 @@ +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index c0b6ef8ee5da..f72218c1037e 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -1366,10 +1366,15 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) + if (!urb) + return -ENOMEM; + +- /* Use maximum HCI Event size so the USB stack handles +- * ZPL/short-transfer automatically. +- */ +- size = HCI_MAX_EVENT_SIZE; ++ if (le16_to_cpu(data->udev->descriptor.idVendor) == 0x0a12 && ++ le16_to_cpu(data->udev->descriptor.idProduct) == 0x0001) ++ /* Fake CSR devices don't seem to support sort-transter */ ++ size = le16_to_cpu(data->intr_ep->wMaxPacketSize); ++ else ++ /* Use maximum HCI Event size so the USB stack handles ++ * ZPL/short-transfer automatically. ++ */ ++ size = HCI_MAX_EVENT_SIZE; + + buf = kmalloc(size, mem_flags); + if (!buf) { diff --git a/pkgs/default.nix b/pkgs/default.nix index b3f1b79..530d1cb 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -8,4 +8,5 @@ rec { emmet-cli = pkgs.callPackage ./emmet-cli.nix { }; material-wifi-icons = pkgs.callPackage ./material-wifi-icons.nix { }; gnome-pass-search-provider = pkgs.callPackage ./gnome-pass-search-provider.nix { }; + linux-bluetooth = pkgs.callPackage ./linux-bluetooth.nix { }; } diff --git a/pkgs/linux-bluetooth.nix b/pkgs/linux-bluetooth.nix new file mode 100644 index 0000000..609e775 --- /dev/null +++ b/pkgs/linux-bluetooth.nix @@ -0,0 +1,47 @@ +{ + pkgs, + lib, + kernel ? pkgs.linuxPackages_latest.kernel, + patches ? [ ], +}: + +pkgs.stdenv.mkDerivation { + pname = "bluetooth-kernel-module"; + inherit (kernel) + src + version + postPatch + nativeBuildInputs + ; + + inherit patches; + + kernel_dev = kernel.dev; + kernelVersion = kernel.modDirVersion; + + modulePath = "drivers/bluetooth"; + + buildPhase = '' + BUILT_KERNEL=$kernel_dev/lib/modules/$kernelVersion/build + + cp $BUILT_KERNEL/Module.symvers . + cp $BUILT_KERNEL/.config . + cp $kernel_dev/vmlinux . + + make "-j$NIX_BUILD_CORES" modules_prepare + make "-j$NIX_BUILD_CORES" M=$modulePath modules + ''; + + installPhase = '' + make \ + INSTALL_MOD_PATH="$out" \ + XZ="xz -T$NIX_BUILD_CORES" \ + M="$modulePath" \ + modules_install + ''; + + meta = { + description = "Bluetooth kernel module"; + license = lib.licenses.gpl3; + }; +}