* Re: Bluetooth: btusb: Add VID/PID 0489:e156 for MediaTek MT7902
From: Kirill Shubin @ 2026-05-03 8:43 UTC (permalink / raw)
To: Sean Wang
Cc: sean.wang, luiz.von.dentz, linux-bluetooth,
moderated list:ARM/Mediatek SoC support
In-Reply-To: <CAGp9LzqXKwJf7=bFuv_gW9yFH7uBuXva398TC=XOrZkyd-ermQ@mail.gmail.com>
Hi Sean,
On Sat, May 2, 2026, Sean Wang wrote:
> Could you help get the USB device information from your test machine
> as the following and reply to the mail?
Sure, here is the full information for 0489:e156 from
/sys/kernel/debug/usb/devices:
T: Bus=01 Lev=01 Prnt=01 Port=09 Cnt=05 Dev#= 6 Spd=480 MxCh= 0
D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=0489 ProdID=e156 Rev= 1.00
S: Manufacturer=MediaTek Inc.
S: Product=Wireless_Device
S: SerialNumber=000000000
C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us
E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms
I: If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us
E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us
I:* If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us
> I will send the patch including the VID/PID
> thanks
Thanks for your help!
Best regards,
Kirill Shubin
вс, 3 мая 2026 г. в 02:17, Sean Wang <sean.wang@kernel.org>:
>
> Hi Кирилл,
>
> Could you help get the USB device information from your test machine
> as the following and reply to the mail?
>
> The information in /sys/kernel/debug/usb/devices about the Bluetooth
> device is listed as the below.
>
> T: Bus=07 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0
> D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1
> P: Vendor=13d3 ProdID=3596 Rev= 1.00
> S: Manufacturer=MediaTek Inc.
> S: Product=Wireless_Device
> S: SerialNumber=000000000
> C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
> A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
> I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us
> E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
> I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
> I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
> I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
> I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
> I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
> I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms
> I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
> E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us
> E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us
> I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
> E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
> E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us
>
> I will send the patch including the VID/PID
> thanks
>
> On Sat, May 2, 2026 at 12:20 PM Кирилл <kirill.kz.902@gmail.com> wrote:
> >
> > Hi Sean,
> >
> > Following your MT7902 series, here is one more VID/PID variant
> > that is currently not recognized by btusb: 0489:e156 (Foxconn).
> >
> > Adding the entry below makes Bluetooth work on v7.1-rc1:
> >
> > /* Additional MediaTek MT7902 Bluetooth devices */
> > { USB_DEVICE(0x0489, 0xe156), .driver_info = BTUSB_MEDIATEK |
> > BTUSB_WIDEBAND_SPEECH },
> >
> > dmesg after loading the patched module:
> >
> > Bluetooth: hci0: HW/SW Version: 0x008a008a,
> > Build Time: 20250826211444
> >
> > /sys/kernel/debug/usb/devices:
> >
> > T: Bus=01 Lev=01 Prnt=01 Port=09 Cnt=05 Dev#=6 Spd=480 MxCh=0
> > D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=1
> > P: Vendor=0489 ProdID=e156 Rev= 1.00
> > S: Manufacturer=MediaTek Inc.
> > S: Product=Wireless_Device
> > C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
> >
> > Could you include this VID/PID in the next MT7902 round?
> >
> > Tested-by: Kirill Shubin <kirill.kz.902@gmail.com>
> >
> > Thanks,
> > Kirill
> >
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-05-03 6:34 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1076781
Home: https://github.com/bluez/bluez
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* RE: [bluetooth-next,v2] bluetooth: remove all PCMCIA drivers
From: bluez.test.bot @ 2026-05-03 5:30 UTC (permalink / raw)
To: linux-bluetooth, enelsonmoore
In-Reply-To: <20260503033201.19719-1-enelsonmoore@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4773 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1088873
---Test result---
Test Summary:
CheckPatch FAIL 2.54 seconds
GitLint FAIL 0.23 seconds
SubjectPrefix FAIL 0.08 seconds
BuildKernel PASS 26.12 seconds
CheckAllWarning PASS 29.00 seconds
CheckSparse PASS 27.51 seconds
BuildKernel32 PASS 25.41 seconds
TestRunnerSetup PASS 573.71 seconds
TestRunner_l2cap-tester FAIL 6.60 seconds
TestRunner_iso-tester PASS 295.80 seconds
TestRunner_bnep-tester FAIL 6.69 seconds
TestRunner_mgmt-tester FAIL 8.93 seconds
TestRunner_rfcomm-tester PASS 29.00 seconds
TestRunner_sco-tester PASS 66.20 seconds
TestRunner_ioctl-tester FAIL 37.46 seconds
TestRunner_mesh-tester PASS 27.03 seconds
TestRunner_smp-tester PASS 6.68 seconds
TestRunner_userchan-tester FAIL 6.77 seconds
TestRunner_6lowpan-tester PASS 23.02 seconds
IncrementalBuild PASS 25.68 seconds
Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[bluetooth-next,v2] bluetooth: remove all PCMCIA drivers
WARNING: Prefer a maximum 75 chars per line (possible unwrapped commit description?)
#135:
[1] https://lore.kernel.org/all/c5b39544-a4fb-4796-a046-0b9be9853787@app.fastmail.com/
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#309:
deleted file mode 100644
total: 0 errors, 2 warnings, 109 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/github/workspace/src/patch/14551781.patch has style problems, please review.
NOTE: Ignored message types: UNKNOWN_COMMIT_ID
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[bluetooth-next,v2] bluetooth: remove all PCMCIA drivers
WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
24: B1 Line exceeds max length (86>80): "[1] https://lore.kernel.org/all/c5b39544-a4fb-4796-a046-0b9be9853787@app.fastmail.com/"
##############################
Test: SubjectPrefix - FAIL
Desc: Check subject contains "Bluetooth" prefix
Output:
"Bluetooth: " prefix is not specified in the subject
##############################
Test: TestRunner_l2cap-tester - FAIL
Desc: Run l2cap-tester with test-runner
Output:
No test result found
##############################
Test: TestRunner_bnep-tester - FAIL
Desc: Run bnep-tester with test-runner
Output:
No test result found
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
No test result found
##############################
Test: TestRunner_ioctl-tester - FAIL
Desc: Run ioctl-tester with test-runner
Output:
Total: 28, Passed: 0 (0.0%), Failed: 11, Not Run: 17
Failed Test Cases
Device List Timed out -30.832 seconds
Device Info Timed out -6.180 seconds
Reset Stat Timed out -6.183 seconds
Set Link Mode - ACCEPT Timed out -6.186 seconds
Set Pkt Type - DM Timed out -14.376 seconds
Set Pkt Type - DH Timed out -14.379 seconds
Set Pkt Type - HV Timed out -14.382 seconds
Set Pkt Type - 2-DH Timed out -14.385 seconds
Set Pkt Type - 2-DH Timed out -14.389 seconds
Set Pkt Type - ALL Timed out -14.392 seconds
Set ACL MTU - 1 Timed out -14.395 seconds
##############################
Test: TestRunner_userchan-tester - FAIL
Desc: Run userchan-tester with test-runner
Output:
No test result found
https://github.com/bluez/bluetooth-next/pull/141
---
Regards,
Linux Bluetooth
^ permalink raw reply
* Security: sdp_extract_seqtype() signed/unsigned confusion → OOB heap read (no pairing required, 8.1H)
From: admin @ 2026-05-03 4:02 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org
To: linux-bluetooth@vger.kernel.org
Subject: Security: sdp_extract_seqtype() signed/unsigned confusion → OOB heap read (no pairing required, 8.1H)
Hi Marcel,
Reporting a vulnerability in BlueZ lib/sdp.c.
File: lib/sdp.c:1262 — sdp_extract_seqtype()
CVSS: 8.1H (AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H)
SDP_SEQ32 stores a uint32_t data length into a signed int* with no overflow check. Value 0x80000000 becomes INT_MIN. Downstream at extract_seq()
(sdp.c:1392) and sdp_extract_pdu() (sdp-client.c:174) that signed value is used as a length/offset → OOB heap read.
Trigger: Crafted SDP response from a malicious Bluetooth device. No pairing required. Bluetooth adjacency (~10m), passive service discovery path.
Fix: Use uint32_t throughout the SDP sequence extraction chain, or add explicit overflow check before assigning to int*.
Please let me know if you need a PoC.
Martin Brodeur Ottawa Canada
^ permalink raw reply
* [PATCH bluetooth-next v2] bluetooth: remove all PCMCIA drivers
From: Ethan Nelson-Moore @ 2026-05-03 3:31 UTC (permalink / raw)
To: linux-mips, linux-bluetooth
Cc: Ethan Nelson-Moore, Russell King, Huacai Chen, WANG Xuerui,
Thomas Bogendoerfer, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Marcel Holtmann,
Luiz Augusto von Dentz, Eric Biggers, Ard Biesheuvel, Herbert Xu,
Theodore Ts'o, André Draszik, Geert Uytterhoeven,
Jakub Kicinski, Simon Horman, Johan Korsnes, David Heidelberg
PCMCIA is almost completely obsolete (the last computers supporting it
natively were from ~2009), and the general consensus [1] seems to be
that support for it should be gradually removed from the kernel.
In 2023, an initial step of removing all the PCMCIA char drivers was
taken in commit 9b12f050c76f ("char: pcmcia: remove all the drivers"),
and that has not been reverted, so it seems logical to continue this
process by removing more low-hanging fruit.
These three Bluetooth drivers have had no meaningful changes since
their status was discussed in 2022 [2], and are unlikely to have any
remaining users. The latest functional change to any of them was a
patch to bluecard_cs to fix LED blinking behavior in 2017. The other
two drivers have not had any meaningful changes made since 2007. Remove
them.
Note that even with these drivers removed, it is still possible to use
other PCMCIA Bluetooth cards that present themselves as a standard
serial port via serial_cs and hciattach while the serial_cs driver is
still present.
[1] https://lore.kernel.org/all/c5b39544-a4fb-4796-a046-0b9be9853787@app.fastmail.com/
[2] https://lore.kernel.org/all/Y07d7rMvd5++85BJ@owl.dominikbrodowski.net/
Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
---
This patch is identical to my previous RFC patch, but rebased on
the latest bluetooth-next tree.
arch/arm/configs/pxa_defconfig | 3 -
arch/arm/configs/spitz_defconfig | 3 -
arch/loongarch/configs/loongson32_defconfig | 3 -
arch/loongarch/configs/loongson64_defconfig | 3 -
arch/mips/configs/mtx1_defconfig | 3 -
arch/powerpc/configs/ppc6xx_defconfig | 3 -
drivers/bluetooth/Kconfig | 40 -
drivers/bluetooth/Makefile | 3 -
drivers/bluetooth/bluecard_cs.c | 908 --------------------
drivers/bluetooth/bt3c_cs.c | 749 ----------------
drivers/bluetooth/dtl1_cs.c | 614 -------------
11 files changed, 2332 deletions(-)
delete mode 100644 drivers/bluetooth/bluecard_cs.c
delete mode 100644 drivers/bluetooth/bt3c_cs.c
delete mode 100644 drivers/bluetooth/dtl1_cs.c
diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig
index c51ae373ca88..78942ebe3fc2 100644
--- a/arch/arm/configs/pxa_defconfig
+++ b/arch/arm/configs/pxa_defconfig
@@ -77,9 +77,6 @@ CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBPA10X=m
CONFIG_BT_HCIBFUSB=m
-CONFIG_BT_HCIDTL1=m
-CONFIG_BT_HCIBT3C=m
-CONFIG_BT_HCIBLUECARD=m
CONFIG_BT_HCIBTUART=m
CONFIG_BT_HCIVHCI=m
CONFIG_BT_MRVL=m
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index f116a01c3f5f..8f8a058294fb 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -62,9 +62,6 @@ CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBPA10X=m
CONFIG_BT_HCIBFUSB=m
-CONFIG_BT_HCIDTL1=m
-CONFIG_BT_HCIBT3C=m
-CONFIG_BT_HCIBLUECARD=m
CONFIG_BT_HCIBTUART=m
CONFIG_BT_HCIVHCI=m
CONFIG_PCCARD=y
diff --git a/arch/loongarch/configs/loongson32_defconfig b/arch/loongarch/configs/loongson32_defconfig
index d5ef396dffe3..f319c880127c 100644
--- a/arch/loongarch/configs/loongson32_defconfig
+++ b/arch/loongarch/configs/loongson32_defconfig
@@ -383,9 +383,6 @@ CONFIG_BT_HCIUART_AG6XX=y
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBPA10X=m
CONFIG_BT_HCIBFUSB=m
-CONFIG_BT_HCIDTL1=m
-CONFIG_BT_HCIBT3C=m
-CONFIG_BT_HCIBLUECARD=m
CONFIG_BT_HCIVHCI=m
CONFIG_BT_MRVL=m
CONFIG_BT_ATH3K=m
diff --git a/arch/loongarch/configs/loongson64_defconfig b/arch/loongarch/configs/loongson64_defconfig
index cba4cdff5acd..ffa8ae26d713 100644
--- a/arch/loongarch/configs/loongson64_defconfig
+++ b/arch/loongarch/configs/loongson64_defconfig
@@ -399,9 +399,6 @@ CONFIG_BT_HCIUART_AG6XX=y
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBPA10X=m
CONFIG_BT_HCIBFUSB=m
-CONFIG_BT_HCIDTL1=m
-CONFIG_BT_HCIBT3C=m
-CONFIG_BT_HCIBLUECARD=m
CONFIG_BT_HCIVHCI=m
CONFIG_BT_MRVL=m
CONFIG_BT_ATH3K=m
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
index 3629afbe5d75..aec719b1b193 100644
--- a/arch/mips/configs/mtx1_defconfig
+++ b/arch/mips/configs/mtx1_defconfig
@@ -184,9 +184,6 @@ CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBPA10X=m
CONFIG_BT_HCIBFUSB=m
-CONFIG_BT_HCIDTL1=m
-CONFIG_BT_HCIBT3C=m
-CONFIG_BT_HCIBLUECARD=m
CONFIG_BT_HCIVHCI=m
CONFIG_CONNECTOR=m
CONFIG_MTD=y
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig
index ccabc6e17168..7f4f8ff3965c 100644
--- a/arch/powerpc/configs/ppc6xx_defconfig
+++ b/arch/powerpc/configs/ppc6xx_defconfig
@@ -282,9 +282,6 @@ CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBPA10X=m
CONFIG_BT_HCIBFUSB=m
-CONFIG_BT_HCIDTL1=m
-CONFIG_BT_HCIBT3C=m
-CONFIG_BT_HCIBLUECARD=m
CONFIG_BT_HCIVHCI=m
CONFIG_CFG80211=m
CONFIG_MAC80211=m
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index fc1b37044a9b..4e8c24d757e9 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -337,46 +337,6 @@ config BT_HCIBFUSB
Say Y here to compile support for HCI BFUSB devices into the
kernel or say M to compile it as module (bfusb).
-config BT_HCIDTL1
- tristate "HCI DTL1 (PC Card) driver"
- depends on PCMCIA && HAS_IOPORT
- help
- Bluetooth HCI DTL1 (PC Card) driver.
- This driver provides support for Bluetooth PCMCIA devices with
- Nokia DTL1 interface:
- Nokia Bluetooth Card
- Socket Bluetooth CF Card
-
- Say Y here to compile support for HCI DTL1 devices into the
- kernel or say M to compile it as module (dtl1_cs).
-
-config BT_HCIBT3C
- tristate "HCI BT3C (PC Card) driver"
- depends on PCMCIA && HAS_IOPORT
- select FW_LOADER
- help
- Bluetooth HCI BT3C (PC Card) driver.
- This driver provides support for Bluetooth PCMCIA devices with
- 3Com BT3C interface:
- 3Com Bluetooth Card (3CRWB6096)
- HP Bluetooth Card
-
- Say Y here to compile support for HCI BT3C devices into the
- kernel or say M to compile it as module (bt3c_cs).
-
-config BT_HCIBLUECARD
- tristate "HCI BlueCard (PC Card) driver"
- depends on PCMCIA && HAS_IOPORT
- help
- Bluetooth HCI BlueCard (PC Card) driver.
- This driver provides support for Bluetooth PCMCIA devices with
- Anycom BlueCard interface:
- Anycom Bluetooth PC Card
- Anycom Bluetooth CF Card
-
- Say Y here to compile support for HCI BlueCard devices into the
- kernel or say M to compile it as module (bluecard_cs).
-
config BT_HCIVHCI
tristate "HCI VHCI (Virtual HCI device) driver"
select WANT_DEV_COREDUMP
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 81856512ddd0..bafc26250b63 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -9,9 +9,6 @@ obj-$(CONFIG_BT_HCIBCM203X) += bcm203x.o
obj-$(CONFIG_BT_HCIBCM4377) += hci_bcm4377.o
obj-$(CONFIG_BT_HCIBPA10X) += bpa10x.o
obj-$(CONFIG_BT_HCIBFUSB) += bfusb.o
-obj-$(CONFIG_BT_HCIDTL1) += dtl1_cs.o
-obj-$(CONFIG_BT_HCIBT3C) += bt3c_cs.o
-obj-$(CONFIG_BT_HCIBLUECARD) += bluecard_cs.o
obj-$(CONFIG_BT_HCIBTUSB) += btusb.o
obj-$(CONFIG_BT_HCIBTSDIO) += btsdio.o
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
deleted file mode 100644
index 1e3a56e9b139..000000000000
--- a/drivers/bluetooth/bluecard_cs.c
+++ /dev/null
@@ -1,908 +0,0 @@
-/*
- *
- * Bluetooth driver for the Anycom BlueCard (LSE039/LSE041)
- *
- * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The initial developer of the original code is David A. Hinds
- * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
- * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
- *
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/spinlock.h>
-#include <linux/moduleparam.h>
-#include <linux/wait.h>
-
-#include <linux/skbuff.h>
-#include <linux/io.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ciscode.h>
-#include <pcmcia/ds.h>
-#include <pcmcia/cisreg.h>
-
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/hci_core.h>
-
-
-
-/* ======================== Module parameters ======================== */
-
-
-MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-MODULE_DESCRIPTION("Bluetooth driver for the Anycom BlueCard (LSE039/LSE041)");
-MODULE_LICENSE("GPL");
-
-
-
-/* ======================== Local structures ======================== */
-
-
-struct bluecard_info {
- struct pcmcia_device *p_dev;
-
- struct hci_dev *hdev;
-
- spinlock_t lock; /* For serializing operations */
- struct timer_list timer; /* For LED control */
-
- struct sk_buff_head txq;
- unsigned long tx_state;
-
- unsigned long rx_state;
- unsigned long rx_count;
- struct sk_buff *rx_skb;
-
- unsigned char ctrl_reg;
- unsigned long hw_state; /* Status of the hardware and LED control */
-};
-
-
-static int bluecard_config(struct pcmcia_device *link);
-static void bluecard_release(struct pcmcia_device *link);
-
-static void bluecard_detach(struct pcmcia_device *p_dev);
-
-
-/* Default baud rate: 57600, 115200, 230400 or 460800 */
-#define DEFAULT_BAUD_RATE 230400
-
-
-/* Hardware states */
-#define CARD_READY 1
-#define CARD_ACTIVITY 2
-#define CARD_HAS_PCCARD_ID 4
-#define CARD_HAS_POWER_LED 5
-#define CARD_HAS_ACTIVITY_LED 6
-
-/* Transmit states */
-#define XMIT_SENDING 1
-#define XMIT_WAKEUP 2
-#define XMIT_BUFFER_NUMBER 5 /* unset = buffer one, set = buffer two */
-#define XMIT_BUF_ONE_READY 6
-#define XMIT_BUF_TWO_READY 7
-#define XMIT_SENDING_READY 8
-
-/* Receiver states */
-#define RECV_WAIT_PACKET_TYPE 0
-#define RECV_WAIT_EVENT_HEADER 1
-#define RECV_WAIT_ACL_HEADER 2
-#define RECV_WAIT_SCO_HEADER 3
-#define RECV_WAIT_DATA 4
-
-/* Special packet types */
-#define PKT_BAUD_RATE_57600 0x80
-#define PKT_BAUD_RATE_115200 0x81
-#define PKT_BAUD_RATE_230400 0x82
-#define PKT_BAUD_RATE_460800 0x83
-
-
-/* These are the register offsets */
-#define REG_COMMAND 0x20
-#define REG_INTERRUPT 0x21
-#define REG_CONTROL 0x22
-#define REG_RX_CONTROL 0x24
-#define REG_CARD_RESET 0x30
-#define REG_LED_CTRL 0x30
-
-/* REG_COMMAND */
-#define REG_COMMAND_TX_BUF_ONE 0x01
-#define REG_COMMAND_TX_BUF_TWO 0x02
-#define REG_COMMAND_RX_BUF_ONE 0x04
-#define REG_COMMAND_RX_BUF_TWO 0x08
-#define REG_COMMAND_RX_WIN_ONE 0x00
-#define REG_COMMAND_RX_WIN_TWO 0x10
-
-/* REG_CONTROL */
-#define REG_CONTROL_BAUD_RATE_57600 0x00
-#define REG_CONTROL_BAUD_RATE_115200 0x01
-#define REG_CONTROL_BAUD_RATE_230400 0x02
-#define REG_CONTROL_BAUD_RATE_460800 0x03
-#define REG_CONTROL_RTS 0x04
-#define REG_CONTROL_BT_ON 0x08
-#define REG_CONTROL_BT_RESET 0x10
-#define REG_CONTROL_BT_RES_PU 0x20
-#define REG_CONTROL_INTERRUPT 0x40
-#define REG_CONTROL_CARD_RESET 0x80
-
-/* REG_RX_CONTROL */
-#define RTS_LEVEL_SHIFT_BITS 0x02
-
-
-
-/* ======================== LED handling routines ======================== */
-
-
-static void bluecard_activity_led_timeout(struct timer_list *t)
-{
- struct bluecard_info *info = timer_container_of(info, t, timer);
- unsigned int iobase = info->p_dev->resource[0]->start;
-
- if (test_bit(CARD_ACTIVITY, &(info->hw_state))) {
- /* leave LED in inactive state for HZ/10 for blink effect */
- clear_bit(CARD_ACTIVITY, &(info->hw_state));
- mod_timer(&(info->timer), jiffies + HZ / 10);
- }
-
- /* Disable activity LED, enable power LED */
- outb(0x08 | 0x20, iobase + 0x30);
-}
-
-
-static void bluecard_enable_activity_led(struct bluecard_info *info)
-{
- unsigned int iobase = info->p_dev->resource[0]->start;
-
- /* don't disturb running blink timer */
- if (timer_pending(&(info->timer)))
- return;
-
- set_bit(CARD_ACTIVITY, &(info->hw_state));
-
- if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
- /* Enable activity LED, keep power LED enabled */
- outb(0x18 | 0x60, iobase + 0x30);
- } else {
- /* Disable power LED */
- outb(0x00, iobase + 0x30);
- }
-
- /* Stop the LED after HZ/10 */
- mod_timer(&(info->timer), jiffies + HZ / 10);
-}
-
-
-
-/* ======================== Interrupt handling ======================== */
-
-
-static int bluecard_write(unsigned int iobase, unsigned int offset, __u8 *buf, int len)
-{
- int i, actual;
-
- actual = (len > 15) ? 15 : len;
-
- outb_p(actual, iobase + offset);
-
- for (i = 0; i < actual; i++)
- outb_p(buf[i], iobase + offset + i + 1);
-
- return actual;
-}
-
-
-static void bluecard_write_wakeup(struct bluecard_info *info)
-{
- if (!info) {
- BT_ERR("Unknown device");
- return;
- }
-
- if (!test_bit(XMIT_SENDING_READY, &(info->tx_state)))
- return;
-
- if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
- set_bit(XMIT_WAKEUP, &(info->tx_state));
- return;
- }
-
- do {
- unsigned int iobase = info->p_dev->resource[0]->start;
- unsigned int offset;
- unsigned char command;
- unsigned long ready_bit;
- register struct sk_buff *skb;
- int len;
-
- clear_bit(XMIT_WAKEUP, &(info->tx_state));
-
- if (!pcmcia_dev_present(info->p_dev))
- return;
-
- if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) {
- if (!test_bit(XMIT_BUF_TWO_READY, &(info->tx_state)))
- break;
- offset = 0x10;
- command = REG_COMMAND_TX_BUF_TWO;
- ready_bit = XMIT_BUF_TWO_READY;
- } else {
- if (!test_bit(XMIT_BUF_ONE_READY, &(info->tx_state)))
- break;
- offset = 0x00;
- command = REG_COMMAND_TX_BUF_ONE;
- ready_bit = XMIT_BUF_ONE_READY;
- }
-
- skb = skb_dequeue(&(info->txq));
- if (!skb)
- break;
-
- if (hci_skb_pkt_type(skb) & 0x80) {
- /* Disable RTS */
- info->ctrl_reg |= REG_CONTROL_RTS;
- outb(info->ctrl_reg, iobase + REG_CONTROL);
- }
-
- /* Activate LED */
- bluecard_enable_activity_led(info);
-
- /* Send frame */
- len = bluecard_write(iobase, offset, skb->data, skb->len);
-
- /* Tell the FPGA to send the data */
- outb_p(command, iobase + REG_COMMAND);
-
- /* Mark the buffer as dirty */
- clear_bit(ready_bit, &(info->tx_state));
-
- if (hci_skb_pkt_type(skb) & 0x80) {
- DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
- DEFINE_WAIT(wait);
-
- unsigned char baud_reg;
-
- switch (hci_skb_pkt_type(skb)) {
- case PKT_BAUD_RATE_460800:
- baud_reg = REG_CONTROL_BAUD_RATE_460800;
- break;
- case PKT_BAUD_RATE_230400:
- baud_reg = REG_CONTROL_BAUD_RATE_230400;
- break;
- case PKT_BAUD_RATE_115200:
- baud_reg = REG_CONTROL_BAUD_RATE_115200;
- break;
- case PKT_BAUD_RATE_57600:
- default:
- baud_reg = REG_CONTROL_BAUD_RATE_57600;
- break;
- }
-
- /* Wait until the command reaches the baseband */
- mdelay(100);
-
- /* Set baud on baseband */
- info->ctrl_reg &= ~0x03;
- info->ctrl_reg |= baud_reg;
- outb(info->ctrl_reg, iobase + REG_CONTROL);
-
- /* Enable RTS */
- info->ctrl_reg &= ~REG_CONTROL_RTS;
- outb(info->ctrl_reg, iobase + REG_CONTROL);
-
- /* Wait before the next HCI packet can be send */
- mdelay(1000);
- }
-
- if (len == skb->len) {
- kfree_skb(skb);
- } else {
- skb_pull(skb, len);
- skb_queue_head(&(info->txq), skb);
- }
-
- info->hdev->stat.byte_tx += len;
-
- /* Change buffer */
- change_bit(XMIT_BUFFER_NUMBER, &(info->tx_state));
-
- } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-
- clear_bit(XMIT_SENDING, &(info->tx_state));
-}
-
-
-static int bluecard_read(unsigned int iobase, unsigned int offset, __u8 *buf, int size)
-{
- int i, n, len;
-
- outb(REG_COMMAND_RX_WIN_ONE, iobase + REG_COMMAND);
-
- len = inb(iobase + offset);
- n = 0;
- i = 1;
-
- while (n < len) {
-
- if (i == 16) {
- outb(REG_COMMAND_RX_WIN_TWO, iobase + REG_COMMAND);
- i = 0;
- }
-
- buf[n] = inb(iobase + offset + i);
-
- n++;
- i++;
-
- }
-
- return len;
-}
-
-
-static void bluecard_receive(struct bluecard_info *info,
- unsigned int offset)
-{
- unsigned int iobase;
- unsigned char buf[31];
- int i, len;
-
- if (!info) {
- BT_ERR("Unknown device");
- return;
- }
-
- iobase = info->p_dev->resource[0]->start;
-
- if (test_bit(XMIT_SENDING_READY, &(info->tx_state)))
- bluecard_enable_activity_led(info);
-
- len = bluecard_read(iobase, offset, buf, sizeof(buf));
-
- for (i = 0; i < len; i++) {
-
- /* Allocate packet */
- if (!info->rx_skb) {
- info->rx_state = RECV_WAIT_PACKET_TYPE;
- info->rx_count = 0;
- info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
- if (!info->rx_skb) {
- BT_ERR("Can't allocate mem for new packet");
- return;
- }
- }
-
- if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-
- hci_skb_pkt_type(info->rx_skb) = buf[i];
-
- switch (hci_skb_pkt_type(info->rx_skb)) {
-
- case 0x00:
- /* init packet */
- if (offset != 0x00) {
- set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
- set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
- set_bit(XMIT_SENDING_READY, &(info->tx_state));
- bluecard_write_wakeup(info);
- }
-
- kfree_skb(info->rx_skb);
- info->rx_skb = NULL;
- break;
-
- case HCI_EVENT_PKT:
- info->rx_state = RECV_WAIT_EVENT_HEADER;
- info->rx_count = HCI_EVENT_HDR_SIZE;
- break;
-
- case HCI_ACLDATA_PKT:
- info->rx_state = RECV_WAIT_ACL_HEADER;
- info->rx_count = HCI_ACL_HDR_SIZE;
- break;
-
- case HCI_SCODATA_PKT:
- info->rx_state = RECV_WAIT_SCO_HEADER;
- info->rx_count = HCI_SCO_HDR_SIZE;
- break;
-
- default:
- /* unknown packet */
- BT_ERR("Unknown HCI packet with type 0x%02x received",
- hci_skb_pkt_type(info->rx_skb));
- info->hdev->stat.err_rx++;
-
- kfree_skb(info->rx_skb);
- info->rx_skb = NULL;
- break;
-
- }
-
- } else {
-
- skb_put_u8(info->rx_skb, buf[i]);
- info->rx_count--;
-
- if (info->rx_count == 0) {
-
- int dlen;
- struct hci_event_hdr *eh;
- struct hci_acl_hdr *ah;
- struct hci_sco_hdr *sh;
-
- switch (info->rx_state) {
-
- case RECV_WAIT_EVENT_HEADER:
- eh = hci_event_hdr(info->rx_skb);
- info->rx_state = RECV_WAIT_DATA;
- info->rx_count = eh->plen;
- break;
-
- case RECV_WAIT_ACL_HEADER:
- ah = hci_acl_hdr(info->rx_skb);
- dlen = __le16_to_cpu(ah->dlen);
- info->rx_state = RECV_WAIT_DATA;
- info->rx_count = dlen;
- break;
-
- case RECV_WAIT_SCO_HEADER:
- sh = hci_sco_hdr(info->rx_skb);
- info->rx_state = RECV_WAIT_DATA;
- info->rx_count = sh->dlen;
- break;
-
- case RECV_WAIT_DATA:
- hci_recv_frame(info->hdev, info->rx_skb);
- info->rx_skb = NULL;
- break;
-
- }
-
- }
-
- }
-
-
- }
-
- info->hdev->stat.byte_rx += len;
-}
-
-
-static irqreturn_t bluecard_interrupt(int irq, void *dev_inst)
-{
- struct bluecard_info *info = dev_inst;
- unsigned int iobase;
- unsigned char reg;
-
- if (!info || !info->hdev)
- /* our irq handler is shared */
- return IRQ_NONE;
-
- if (!test_bit(CARD_READY, &(info->hw_state)))
- return IRQ_HANDLED;
-
- iobase = info->p_dev->resource[0]->start;
-
- spin_lock(&(info->lock));
-
- /* Disable interrupt */
- info->ctrl_reg &= ~REG_CONTROL_INTERRUPT;
- outb(info->ctrl_reg, iobase + REG_CONTROL);
-
- reg = inb(iobase + REG_INTERRUPT);
-
- if ((reg != 0x00) && (reg != 0xff)) {
-
- if (reg & 0x04) {
- bluecard_receive(info, 0x00);
- outb(0x04, iobase + REG_INTERRUPT);
- outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
- }
-
- if (reg & 0x08) {
- bluecard_receive(info, 0x10);
- outb(0x08, iobase + REG_INTERRUPT);
- outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
- }
-
- if (reg & 0x01) {
- set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
- outb(0x01, iobase + REG_INTERRUPT);
- bluecard_write_wakeup(info);
- }
-
- if (reg & 0x02) {
- set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
- outb(0x02, iobase + REG_INTERRUPT);
- bluecard_write_wakeup(info);
- }
-
- }
-
- /* Enable interrupt */
- info->ctrl_reg |= REG_CONTROL_INTERRUPT;
- outb(info->ctrl_reg, iobase + REG_CONTROL);
-
- spin_unlock(&(info->lock));
-
- return IRQ_HANDLED;
-}
-
-
-
-/* ======================== Device specific HCI commands ======================== */
-
-
-static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
-{
- struct bluecard_info *info = hci_get_drvdata(hdev);
- struct sk_buff *skb;
-
- /* Ericsson baud rate command */
- unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 };
-
- skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_KERNEL);
- if (!skb) {
- BT_ERR("Can't allocate mem for new packet");
- return -1;
- }
-
- switch (baud) {
- case 460800:
- cmd[4] = 0x00;
- hci_skb_pkt_type(skb) = PKT_BAUD_RATE_460800;
- break;
- case 230400:
- cmd[4] = 0x01;
- hci_skb_pkt_type(skb) = PKT_BAUD_RATE_230400;
- break;
- case 115200:
- cmd[4] = 0x02;
- hci_skb_pkt_type(skb) = PKT_BAUD_RATE_115200;
- break;
- case 57600:
- default:
- cmd[4] = 0x03;
- hci_skb_pkt_type(skb) = PKT_BAUD_RATE_57600;
- break;
- }
-
- skb_put_data(skb, cmd, sizeof(cmd));
-
- skb_queue_tail(&(info->txq), skb);
-
- bluecard_write_wakeup(info);
-
- return 0;
-}
-
-
-
-/* ======================== HCI interface ======================== */
-
-
-static int bluecard_hci_flush(struct hci_dev *hdev)
-{
- struct bluecard_info *info = hci_get_drvdata(hdev);
-
- /* Drop TX queue */
- skb_queue_purge(&(info->txq));
-
- return 0;
-}
-
-
-static int bluecard_hci_open(struct hci_dev *hdev)
-{
- struct bluecard_info *info = hci_get_drvdata(hdev);
- unsigned int iobase = info->p_dev->resource[0]->start;
-
- if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
- bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
-
- /* Enable power LED */
- outb(0x08 | 0x20, iobase + 0x30);
-
- return 0;
-}
-
-
-static int bluecard_hci_close(struct hci_dev *hdev)
-{
- struct bluecard_info *info = hci_get_drvdata(hdev);
- unsigned int iobase = info->p_dev->resource[0]->start;
-
- bluecard_hci_flush(hdev);
-
- /* Stop LED timer */
- timer_delete_sync(&(info->timer));
-
- /* Disable power LED */
- outb(0x00, iobase + 0x30);
-
- return 0;
-}
-
-
-static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
-{
- struct bluecard_info *info = hci_get_drvdata(hdev);
-
- switch (hci_skb_pkt_type(skb)) {
- case HCI_COMMAND_PKT:
- hdev->stat.cmd_tx++;
- break;
- case HCI_ACLDATA_PKT:
- hdev->stat.acl_tx++;
- break;
- case HCI_SCODATA_PKT:
- hdev->stat.sco_tx++;
- break;
- }
-
- /* Prepend skb with frame type */
- memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
- skb_queue_tail(&(info->txq), skb);
-
- bluecard_write_wakeup(info);
-
- return 0;
-}
-
-
-
-/* ======================== Card services HCI interaction ======================== */
-
-
-static int bluecard_open(struct bluecard_info *info)
-{
- unsigned int iobase = info->p_dev->resource[0]->start;
- struct hci_dev *hdev;
- unsigned char id;
-
- spin_lock_init(&(info->lock));
-
- timer_setup(&info->timer, bluecard_activity_led_timeout, 0);
-
- skb_queue_head_init(&(info->txq));
-
- info->rx_state = RECV_WAIT_PACKET_TYPE;
- info->rx_count = 0;
- info->rx_skb = NULL;
-
- /* Initialize HCI device */
- hdev = hci_alloc_dev();
- if (!hdev) {
- BT_ERR("Can't allocate HCI device");
- return -ENOMEM;
- }
-
- info->hdev = hdev;
-
- hdev->bus = HCI_PCCARD;
- hci_set_drvdata(hdev, info);
- SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
-
- hdev->open = bluecard_hci_open;
- hdev->close = bluecard_hci_close;
- hdev->flush = bluecard_hci_flush;
- hdev->send = bluecard_hci_send_frame;
-
- id = inb(iobase + 0x30);
-
- if ((id & 0x0f) == 0x02)
- set_bit(CARD_HAS_PCCARD_ID, &(info->hw_state));
-
- if (id & 0x10)
- set_bit(CARD_HAS_POWER_LED, &(info->hw_state));
-
- if (id & 0x20)
- set_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state));
-
- /* Reset card */
- info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
- outb(info->ctrl_reg, iobase + REG_CONTROL);
-
- /* Turn FPGA off */
- outb(0x80, iobase + 0x30);
-
- /* Wait some time */
- msleep(10);
-
- /* Turn FPGA on */
- outb(0x00, iobase + 0x30);
-
- /* Activate card */
- info->ctrl_reg = REG_CONTROL_BT_ON | REG_CONTROL_BT_RES_PU;
- outb(info->ctrl_reg, iobase + REG_CONTROL);
-
- /* Enable interrupt */
- outb(0xff, iobase + REG_INTERRUPT);
- info->ctrl_reg |= REG_CONTROL_INTERRUPT;
- outb(info->ctrl_reg, iobase + REG_CONTROL);
-
- if ((id & 0x0f) == 0x03) {
- /* Disable RTS */
- info->ctrl_reg |= REG_CONTROL_RTS;
- outb(info->ctrl_reg, iobase + REG_CONTROL);
-
- /* Set baud rate */
- info->ctrl_reg |= 0x03;
- outb(info->ctrl_reg, iobase + REG_CONTROL);
-
- /* Enable RTS */
- info->ctrl_reg &= ~REG_CONTROL_RTS;
- outb(info->ctrl_reg, iobase + REG_CONTROL);
-
- set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
- set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
- set_bit(XMIT_SENDING_READY, &(info->tx_state));
- }
-
- /* Start the RX buffers */
- outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
- outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
-
- /* Signal that the hardware is ready */
- set_bit(CARD_READY, &(info->hw_state));
-
- /* Drop TX queue */
- skb_queue_purge(&(info->txq));
-
- /* Control the point at which RTS is enabled */
- outb((0x0f << RTS_LEVEL_SHIFT_BITS) | 1, iobase + REG_RX_CONTROL);
-
- /* Timeout before it is safe to send the first HCI packet */
- msleep(1250);
-
- /* Register HCI device */
- if (hci_register_dev(hdev) < 0) {
- BT_ERR("Can't register HCI device");
- info->hdev = NULL;
- hci_free_dev(hdev);
- return -ENODEV;
- }
-
- return 0;
-}
-
-
-static int bluecard_close(struct bluecard_info *info)
-{
- unsigned int iobase = info->p_dev->resource[0]->start;
- struct hci_dev *hdev = info->hdev;
-
- if (!hdev)
- return -ENODEV;
-
- bluecard_hci_close(hdev);
-
- clear_bit(CARD_READY, &(info->hw_state));
-
- /* Reset card */
- info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
- outb(info->ctrl_reg, iobase + REG_CONTROL);
-
- /* Turn FPGA off */
- outb(0x80, iobase + 0x30);
-
- hci_unregister_dev(hdev);
- hci_free_dev(hdev);
-
- return 0;
-}
-
-static int bluecard_probe(struct pcmcia_device *link)
-{
- struct bluecard_info *info;
-
- /* Create new info device */
- info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- info->p_dev = link;
- link->priv = info;
-
- link->config_flags |= CONF_ENABLE_IRQ;
-
- return bluecard_config(link);
-}
-
-
-static void bluecard_detach(struct pcmcia_device *link)
-{
- bluecard_release(link);
-}
-
-
-static int bluecard_config(struct pcmcia_device *link)
-{
- struct bluecard_info *info = link->priv;
- int i, n;
-
- link->config_index = 0x20;
-
- link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
- link->resource[0]->end = 64;
- link->io_lines = 6;
-
- for (n = 0; n < 0x400; n += 0x40) {
- link->resource[0]->start = n ^ 0x300;
- i = pcmcia_request_io(link);
- if (i == 0)
- break;
- }
-
- if (i != 0)
- goto failed;
-
- i = pcmcia_request_irq(link, bluecard_interrupt);
- if (i != 0)
- goto failed;
-
- i = pcmcia_enable_device(link);
- if (i != 0)
- goto failed;
-
- if (bluecard_open(info) != 0)
- goto failed;
-
- return 0;
-
-failed:
- bluecard_release(link);
- return -ENODEV;
-}
-
-
-static void bluecard_release(struct pcmcia_device *link)
-{
- struct bluecard_info *info = link->priv;
-
- bluecard_close(info);
-
- timer_delete_sync(&(info->timer));
-
- pcmcia_disable_device(link);
-}
-
-static const struct pcmcia_device_id bluecard_ids[] = {
- PCMCIA_DEVICE_PROD_ID12("BlueCard", "LSE041", 0xbaf16fbf, 0x657cc15e),
- PCMCIA_DEVICE_PROD_ID12("BTCFCARD", "LSE139", 0xe3987764, 0x2524b59c),
- PCMCIA_DEVICE_PROD_ID12("WSS", "LSE039", 0x0a0736ec, 0x24e6dfab),
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, bluecard_ids);
-
-static struct pcmcia_driver bluecard_driver = {
- .owner = THIS_MODULE,
- .name = "bluecard_cs",
- .probe = bluecard_probe,
- .remove = bluecard_detach,
- .id_table = bluecard_ids,
-};
-module_pcmcia_driver(bluecard_driver);
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
deleted file mode 100644
index 54713833951a..000000000000
--- a/drivers/bluetooth/bt3c_cs.c
+++ /dev/null
@@ -1,749 +0,0 @@
-/*
- *
- * Driver for the 3Com Bluetooth PCMCIA card
- *
- * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
- * Jose Orlando Pereira <jop@di.uminho.pt>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The initial developer of the original code is David A. Hinds
- * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
- * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
- *
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/spinlock.h>
-#include <linux/moduleparam.h>
-
-#include <linux/skbuff.h>
-#include <linux/string.h>
-#include <linux/serial.h>
-#include <linux/serial_reg.h>
-#include <linux/bitops.h>
-#include <asm/io.h>
-
-#include <linux/device.h>
-#include <linux/firmware.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ciscode.h>
-#include <pcmcia/ds.h>
-#include <pcmcia/cisreg.h>
-
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/hci_core.h>
-
-
-
-/* ======================== Module parameters ======================== */
-
-
-MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE("BT3CPCC.bin");
-
-
-
-/* ======================== Local structures ======================== */
-
-
-struct bt3c_info {
- struct pcmcia_device *p_dev;
-
- struct hci_dev *hdev;
-
- spinlock_t lock; /* For serializing operations */
-
- struct sk_buff_head txq;
- unsigned long tx_state;
-
- unsigned long rx_state;
- unsigned long rx_count;
- struct sk_buff *rx_skb;
-};
-
-
-static int bt3c_config(struct pcmcia_device *link);
-static void bt3c_release(struct pcmcia_device *link);
-
-static void bt3c_detach(struct pcmcia_device *p_dev);
-
-
-/* Transmit states */
-#define XMIT_SENDING 1
-#define XMIT_WAKEUP 2
-#define XMIT_WAITING 8
-
-/* Receiver states */
-#define RECV_WAIT_PACKET_TYPE 0
-#define RECV_WAIT_EVENT_HEADER 1
-#define RECV_WAIT_ACL_HEADER 2
-#define RECV_WAIT_SCO_HEADER 3
-#define RECV_WAIT_DATA 4
-
-
-
-/* ======================== Special I/O functions ======================== */
-
-
-#define DATA_L 0
-#define DATA_H 1
-#define ADDR_L 2
-#define ADDR_H 3
-#define CONTROL 4
-
-
-static inline void bt3c_address(unsigned int iobase, unsigned short addr)
-{
- outb(addr & 0xff, iobase + ADDR_L);
- outb((addr >> 8) & 0xff, iobase + ADDR_H);
-}
-
-
-static inline void bt3c_put(unsigned int iobase, unsigned short value)
-{
- outb(value & 0xff, iobase + DATA_L);
- outb((value >> 8) & 0xff, iobase + DATA_H);
-}
-
-
-static inline void bt3c_io_write(unsigned int iobase, unsigned short addr, unsigned short value)
-{
- bt3c_address(iobase, addr);
- bt3c_put(iobase, value);
-}
-
-
-static inline unsigned short bt3c_get(unsigned int iobase)
-{
- unsigned short value = inb(iobase + DATA_L);
-
- value |= inb(iobase + DATA_H) << 8;
-
- return value;
-}
-
-
-static inline unsigned short bt3c_read(unsigned int iobase, unsigned short addr)
-{
- bt3c_address(iobase, addr);
-
- return bt3c_get(iobase);
-}
-
-
-
-/* ======================== Interrupt handling ======================== */
-
-
-static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
-{
- int actual = 0;
-
- bt3c_address(iobase, 0x7080);
-
- /* Fill FIFO with current frame */
- while (actual < len) {
- /* Transmit next byte */
- bt3c_put(iobase, buf[actual]);
- actual++;
- }
-
- bt3c_io_write(iobase, 0x7005, actual);
-
- return actual;
-}
-
-
-static void bt3c_write_wakeup(struct bt3c_info *info)
-{
- if (!info) {
- BT_ERR("Unknown device");
- return;
- }
-
- if (test_and_set_bit(XMIT_SENDING, &(info->tx_state)))
- return;
-
- do {
- unsigned int iobase = info->p_dev->resource[0]->start;
- register struct sk_buff *skb;
- int len;
-
- if (!pcmcia_dev_present(info->p_dev))
- break;
-
- skb = skb_dequeue(&(info->txq));
- if (!skb) {
- clear_bit(XMIT_SENDING, &(info->tx_state));
- break;
- }
-
- /* Send frame */
- len = bt3c_write(iobase, 256, skb->data, skb->len);
-
- if (len != skb->len)
- BT_ERR("Very strange");
-
- kfree_skb(skb);
-
- info->hdev->stat.byte_tx += len;
-
- } while (0);
-}
-
-
-static void bt3c_receive(struct bt3c_info *info)
-{
- unsigned int iobase;
- int size = 0, avail;
-
- if (!info) {
- BT_ERR("Unknown device");
- return;
- }
-
- iobase = info->p_dev->resource[0]->start;
-
- avail = bt3c_read(iobase, 0x7006);
-
- bt3c_address(iobase, 0x7480);
- while (size < avail) {
- size++;
- info->hdev->stat.byte_rx++;
-
- /* Allocate packet */
- if (!info->rx_skb) {
- info->rx_state = RECV_WAIT_PACKET_TYPE;
- info->rx_count = 0;
- info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
- if (!info->rx_skb) {
- BT_ERR("Can't allocate mem for new packet");
- return;
- }
- }
-
-
- if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-
- hci_skb_pkt_type(info->rx_skb) = inb(iobase + DATA_L);
- inb(iobase + DATA_H);
-
- switch (hci_skb_pkt_type(info->rx_skb)) {
-
- case HCI_EVENT_PKT:
- info->rx_state = RECV_WAIT_EVENT_HEADER;
- info->rx_count = HCI_EVENT_HDR_SIZE;
- break;
-
- case HCI_ACLDATA_PKT:
- info->rx_state = RECV_WAIT_ACL_HEADER;
- info->rx_count = HCI_ACL_HDR_SIZE;
- break;
-
- case HCI_SCODATA_PKT:
- info->rx_state = RECV_WAIT_SCO_HEADER;
- info->rx_count = HCI_SCO_HDR_SIZE;
- break;
-
- default:
- /* Unknown packet */
- BT_ERR("Unknown HCI packet with type 0x%02x received",
- hci_skb_pkt_type(info->rx_skb));
- info->hdev->stat.err_rx++;
-
- kfree_skb(info->rx_skb);
- info->rx_skb = NULL;
- break;
-
- }
-
- } else {
-
- __u8 x = inb(iobase + DATA_L);
-
- skb_put_u8(info->rx_skb, x);
- inb(iobase + DATA_H);
- info->rx_count--;
-
- if (info->rx_count == 0) {
-
- int dlen;
- struct hci_event_hdr *eh;
- struct hci_acl_hdr *ah;
- struct hci_sco_hdr *sh;
-
- switch (info->rx_state) {
-
- case RECV_WAIT_EVENT_HEADER:
- eh = hci_event_hdr(info->rx_skb);
- info->rx_state = RECV_WAIT_DATA;
- info->rx_count = eh->plen;
- break;
-
- case RECV_WAIT_ACL_HEADER:
- ah = hci_acl_hdr(info->rx_skb);
- dlen = __le16_to_cpu(ah->dlen);
- info->rx_state = RECV_WAIT_DATA;
- info->rx_count = dlen;
- break;
-
- case RECV_WAIT_SCO_HEADER:
- sh = hci_sco_hdr(info->rx_skb);
- info->rx_state = RECV_WAIT_DATA;
- info->rx_count = sh->dlen;
- break;
-
- case RECV_WAIT_DATA:
- hci_recv_frame(info->hdev, info->rx_skb);
- info->rx_skb = NULL;
- break;
-
- }
-
- }
-
- }
-
- }
-
- bt3c_io_write(iobase, 0x7006, 0x0000);
-}
-
-
-static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
-{
- struct bt3c_info *info = dev_inst;
- unsigned int iobase;
- int iir;
- irqreturn_t r = IRQ_NONE;
-
- if (!info || !info->hdev)
- /* our irq handler is shared */
- return IRQ_NONE;
-
- iobase = info->p_dev->resource[0]->start;
-
- spin_lock(&(info->lock));
-
- iir = inb(iobase + CONTROL);
- if (iir & 0x80) {
- int stat = bt3c_read(iobase, 0x7001);
-
- if ((stat & 0xff) == 0x7f) {
- BT_ERR("Very strange (stat=0x%04x)", stat);
- } else if ((stat & 0xff) != 0xff) {
- if (stat & 0x0020) {
- int status = bt3c_read(iobase, 0x7002) & 0x10;
- bt_dev_info(info->hdev, "Antenna %s",
- status ? "out" : "in");
- }
- if (stat & 0x0001)
- bt3c_receive(info);
- if (stat & 0x0002) {
- clear_bit(XMIT_SENDING, &(info->tx_state));
- bt3c_write_wakeup(info);
- }
-
- bt3c_io_write(iobase, 0x7001, 0x0000);
-
- outb(iir, iobase + CONTROL);
- }
- r = IRQ_HANDLED;
- }
-
- spin_unlock(&(info->lock));
-
- return r;
-}
-
-
-
-/* ======================== HCI interface ======================== */
-
-
-static int bt3c_hci_flush(struct hci_dev *hdev)
-{
- struct bt3c_info *info = hci_get_drvdata(hdev);
-
- /* Drop TX queue */
- skb_queue_purge(&(info->txq));
-
- return 0;
-}
-
-
-static int bt3c_hci_open(struct hci_dev *hdev)
-{
- return 0;
-}
-
-
-static int bt3c_hci_close(struct hci_dev *hdev)
-{
- bt3c_hci_flush(hdev);
-
- return 0;
-}
-
-
-static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
-{
- struct bt3c_info *info = hci_get_drvdata(hdev);
- unsigned long flags;
-
- switch (hci_skb_pkt_type(skb)) {
- case HCI_COMMAND_PKT:
- hdev->stat.cmd_tx++;
- break;
- case HCI_ACLDATA_PKT:
- hdev->stat.acl_tx++;
- break;
- case HCI_SCODATA_PKT:
- hdev->stat.sco_tx++;
- break;
- }
-
- /* Prepend skb with frame type */
- memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
- skb_queue_tail(&(info->txq), skb);
-
- spin_lock_irqsave(&(info->lock), flags);
-
- bt3c_write_wakeup(info);
-
- spin_unlock_irqrestore(&(info->lock), flags);
-
- return 0;
-}
-
-
-
-/* ======================== Card services HCI interaction ======================== */
-
-
-static int bt3c_load_firmware(struct bt3c_info *info,
- const unsigned char *firmware,
- int count)
-{
- char *ptr = (char *) firmware;
- char b[9];
- unsigned int iobase, tmp, tn;
- unsigned long size, addr, fcs;
- int i, err = 0;
-
- iobase = info->p_dev->resource[0]->start;
-
- /* Reset */
- bt3c_io_write(iobase, 0x8040, 0x0404);
- bt3c_io_write(iobase, 0x8040, 0x0400);
-
- udelay(1);
-
- bt3c_io_write(iobase, 0x8040, 0x0404);
-
- udelay(17);
-
- /* Load */
- while (count) {
- if (ptr[0] != 'S') {
- BT_ERR("Bad address in firmware");
- err = -EFAULT;
- goto error;
- }
-
- memset(b, 0, sizeof(b));
- memcpy(b, ptr + 2, 2);
- if (kstrtoul(b, 16, &size) < 0)
- return -EINVAL;
-
- memset(b, 0, sizeof(b));
- memcpy(b, ptr + 4, 8);
- if (kstrtoul(b, 16, &addr) < 0)
- return -EINVAL;
-
- memset(b, 0, sizeof(b));
- memcpy(b, ptr + (size * 2) + 2, 2);
- if (kstrtoul(b, 16, &fcs) < 0)
- return -EINVAL;
-
- memset(b, 0, sizeof(b));
- for (tmp = 0, i = 0; i < size; i++) {
- memcpy(b, ptr + (i * 2) + 2, 2);
- if (kstrtouint(b, 16, &tn))
- return -EINVAL;
- tmp += tn;
- }
-
- if (((tmp + fcs) & 0xff) != 0xff) {
- BT_ERR("Checksum error in firmware");
- err = -EILSEQ;
- goto error;
- }
-
- if (ptr[1] == '3') {
- bt3c_address(iobase, addr);
-
- memset(b, 0, sizeof(b));
- for (i = 0; i < (size - 4) / 2; i++) {
- memcpy(b, ptr + (i * 4) + 12, 4);
- if (kstrtouint(b, 16, &tmp))
- return -EINVAL;
- bt3c_put(iobase, tmp);
- }
- }
-
- ptr += (size * 2) + 6;
- count -= (size * 2) + 6;
- }
-
- udelay(17);
-
- /* Boot */
- bt3c_address(iobase, 0x3000);
- outb(inb(iobase + CONTROL) | 0x40, iobase + CONTROL);
-
-error:
- udelay(17);
-
- /* Clear */
- bt3c_io_write(iobase, 0x7006, 0x0000);
- bt3c_io_write(iobase, 0x7005, 0x0000);
- bt3c_io_write(iobase, 0x7001, 0x0000);
-
- return err;
-}
-
-
-static int bt3c_open(struct bt3c_info *info)
-{
- const struct firmware *firmware;
- struct hci_dev *hdev;
- int err;
-
- spin_lock_init(&(info->lock));
-
- skb_queue_head_init(&(info->txq));
-
- info->rx_state = RECV_WAIT_PACKET_TYPE;
- info->rx_count = 0;
- info->rx_skb = NULL;
-
- /* Initialize HCI device */
- hdev = hci_alloc_dev();
- if (!hdev) {
- BT_ERR("Can't allocate HCI device");
- return -ENOMEM;
- }
-
- info->hdev = hdev;
-
- hdev->bus = HCI_PCCARD;
- hci_set_drvdata(hdev, info);
- SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
-
- hdev->open = bt3c_hci_open;
- hdev->close = bt3c_hci_close;
- hdev->flush = bt3c_hci_flush;
- hdev->send = bt3c_hci_send_frame;
-
- /* Load firmware */
- err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev);
- if (err < 0) {
- BT_ERR("Firmware request failed");
- goto error;
- }
-
- err = bt3c_load_firmware(info, firmware->data, firmware->size);
-
- release_firmware(firmware);
-
- if (err < 0) {
- BT_ERR("Firmware loading failed");
- goto error;
- }
-
- /* Timeout before it is safe to send the first HCI packet */
- msleep(1000);
-
- /* Register HCI device */
- err = hci_register_dev(hdev);
- if (err < 0) {
- BT_ERR("Can't register HCI device");
- goto error;
- }
-
- return 0;
-
-error:
- info->hdev = NULL;
- hci_free_dev(hdev);
- return err;
-}
-
-
-static int bt3c_close(struct bt3c_info *info)
-{
- struct hci_dev *hdev = info->hdev;
-
- if (!hdev)
- return -ENODEV;
-
- bt3c_hci_close(hdev);
-
- hci_unregister_dev(hdev);
- hci_free_dev(hdev);
-
- return 0;
-}
-
-static int bt3c_probe(struct pcmcia_device *link)
-{
- struct bt3c_info *info;
-
- /* Create new info device */
- info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- info->p_dev = link;
- link->priv = info;
-
- link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
- CONF_AUTO_SET_IO;
-
- return bt3c_config(link);
-}
-
-
-static void bt3c_detach(struct pcmcia_device *link)
-{
- bt3c_release(link);
-}
-
-static int bt3c_check_config(struct pcmcia_device *p_dev, void *priv_data)
-{
- int *try = priv_data;
-
- if (!try)
- p_dev->io_lines = 16;
-
- if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0))
- return -EINVAL;
-
- p_dev->resource[0]->end = 8;
- p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
- p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
-
- return pcmcia_request_io(p_dev);
-}
-
-static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
- void *priv_data)
-{
- static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
- int j;
-
- if (p_dev->io_lines > 3)
- return -ENODEV;
-
- p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
- p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
- p_dev->resource[0]->end = 8;
-
- for (j = 0; j < 5; j++) {
- p_dev->resource[0]->start = base[j];
- p_dev->io_lines = base[j] ? 16 : 3;
- if (!pcmcia_request_io(p_dev))
- return 0;
- }
- return -ENODEV;
-}
-
-static int bt3c_config(struct pcmcia_device *link)
-{
- struct bt3c_info *info = link->priv;
- int i;
- unsigned long try;
-
- /* First pass: look for a config entry that looks normal.
- * Two tries: without IO aliases, then with aliases
- */
- for (try = 0; try < 2; try++)
- if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))
- goto found_port;
-
- /* Second pass: try to find an entry that isn't picky about
- * its base address, then try to grab any standard serial port
- * address, and finally try to get any free port.
- */
- if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))
- goto found_port;
-
- BT_ERR("No usable port range found");
- goto failed;
-
-found_port:
- i = pcmcia_request_irq(link, &bt3c_interrupt);
- if (i != 0)
- goto failed;
-
- i = pcmcia_enable_device(link);
- if (i != 0)
- goto failed;
-
- if (bt3c_open(info) != 0)
- goto failed;
-
- return 0;
-
-failed:
- bt3c_release(link);
- return -ENODEV;
-}
-
-
-static void bt3c_release(struct pcmcia_device *link)
-{
- struct bt3c_info *info = link->priv;
-
- bt3c_close(info);
-
- pcmcia_disable_device(link);
-}
-
-
-static const struct pcmcia_device_id bt3c_ids[] = {
- PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02),
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, bt3c_ids);
-
-static struct pcmcia_driver bt3c_driver = {
- .owner = THIS_MODULE,
- .name = "bt3c_cs",
- .probe = bt3c_probe,
- .remove = bt3c_detach,
- .id_table = bt3c_ids,
-};
-module_pcmcia_driver(bt3c_driver);
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
deleted file mode 100644
index 2adfe4fade76..000000000000
--- a/drivers/bluetooth/dtl1_cs.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- *
- * A driver for Nokia Connectivity Card DTL-1 devices
- *
- * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The initial developer of the original code is David A. Hinds
- * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
- * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
- *
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/spinlock.h>
-#include <linux/moduleparam.h>
-
-#include <linux/skbuff.h>
-#include <linux/string.h>
-#include <linux/serial.h>
-#include <linux/serial_reg.h>
-#include <linux/bitops.h>
-#include <asm/io.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ciscode.h>
-#include <pcmcia/ds.h>
-#include <pcmcia/cisreg.h>
-
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/hci_core.h>
-
-
-
-/* ======================== Module parameters ======================== */
-
-
-MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-MODULE_DESCRIPTION("Bluetooth driver for Nokia Connectivity Card DTL-1");
-MODULE_LICENSE("GPL");
-
-
-
-/* ======================== Local structures ======================== */
-
-
-struct dtl1_info {
- struct pcmcia_device *p_dev;
-
- struct hci_dev *hdev;
-
- spinlock_t lock; /* For serializing operations */
-
- unsigned long flowmask; /* HCI flow mask */
- int ri_latch;
-
- struct sk_buff_head txq;
- unsigned long tx_state;
-
- unsigned long rx_state;
- unsigned long rx_count;
- struct sk_buff *rx_skb;
-};
-
-
-static int dtl1_config(struct pcmcia_device *link);
-
-
-/* Transmit states */
-#define XMIT_SENDING 1
-#define XMIT_WAKEUP 2
-#define XMIT_WAITING 8
-
-/* Receiver States */
-#define RECV_WAIT_NSH 0
-#define RECV_WAIT_DATA 1
-
-
-struct nsh {
- u8 type;
- u8 zero;
- u16 len;
-} __packed; /* Nokia Specific Header */
-
-#define NSHL 4 /* Nokia Specific Header Length */
-
-
-
-/* ======================== Interrupt handling ======================== */
-
-
-static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
-{
- int actual = 0;
-
- /* Tx FIFO should be empty */
- if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
- return 0;
-
- /* Fill FIFO with current frame */
- while ((fifo_size-- > 0) && (actual < len)) {
- /* Transmit next byte */
- outb(buf[actual], iobase + UART_TX);
- actual++;
- }
-
- return actual;
-}
-
-
-static void dtl1_write_wakeup(struct dtl1_info *info)
-{
- if (!info) {
- BT_ERR("Unknown device");
- return;
- }
-
- if (test_bit(XMIT_WAITING, &(info->tx_state))) {
- set_bit(XMIT_WAKEUP, &(info->tx_state));
- return;
- }
-
- if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
- set_bit(XMIT_WAKEUP, &(info->tx_state));
- return;
- }
-
- do {
- unsigned int iobase = info->p_dev->resource[0]->start;
- register struct sk_buff *skb;
- int len;
-
- clear_bit(XMIT_WAKEUP, &(info->tx_state));
-
- if (!pcmcia_dev_present(info->p_dev))
- return;
-
- skb = skb_dequeue(&(info->txq));
- if (!skb)
- break;
-
- /* Send frame */
- len = dtl1_write(iobase, 32, skb->data, skb->len);
-
- if (len == skb->len) {
- set_bit(XMIT_WAITING, &(info->tx_state));
- kfree_skb(skb);
- } else {
- skb_pull(skb, len);
- skb_queue_head(&(info->txq), skb);
- }
-
- info->hdev->stat.byte_tx += len;
-
- } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-
- clear_bit(XMIT_SENDING, &(info->tx_state));
-}
-
-
-static void dtl1_control(struct dtl1_info *info, struct sk_buff *skb)
-{
- u8 flowmask = *(u8 *)skb->data;
- int i;
-
- printk(KERN_INFO "Bluetooth: Nokia control data =");
- for (i = 0; i < skb->len; i++)
- printk(" %02x", skb->data[i]);
-
- printk("\n");
-
- /* transition to active state */
- if (((info->flowmask & 0x07) == 0) && ((flowmask & 0x07) != 0)) {
- clear_bit(XMIT_WAITING, &(info->tx_state));
- dtl1_write_wakeup(info);
- }
-
- info->flowmask = flowmask;
-
- kfree_skb(skb);
-}
-
-
-static void dtl1_receive(struct dtl1_info *info)
-{
- unsigned int iobase;
- struct nsh *nsh;
- int boguscount = 0;
-
- if (!info) {
- BT_ERR("Unknown device");
- return;
- }
-
- iobase = info->p_dev->resource[0]->start;
-
- do {
- info->hdev->stat.byte_rx++;
-
- /* Allocate packet */
- if (info->rx_skb == NULL) {
- info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
- if (!info->rx_skb) {
- BT_ERR("Can't allocate mem for new packet");
- info->rx_state = RECV_WAIT_NSH;
- info->rx_count = NSHL;
- return;
- }
- }
-
- skb_put_u8(info->rx_skb, inb(iobase + UART_RX));
- nsh = (struct nsh *)info->rx_skb->data;
-
- info->rx_count--;
-
- if (info->rx_count == 0) {
-
- switch (info->rx_state) {
- case RECV_WAIT_NSH:
- info->rx_state = RECV_WAIT_DATA;
- info->rx_count = nsh->len + (nsh->len & 0x0001);
- break;
- case RECV_WAIT_DATA:
- hci_skb_pkt_type(info->rx_skb) = nsh->type;
-
- /* remove PAD byte if it exists */
- if (nsh->len & 0x0001) {
- info->rx_skb->tail--;
- info->rx_skb->len--;
- }
-
- /* remove NSH */
- skb_pull(info->rx_skb, NSHL);
-
- switch (hci_skb_pkt_type(info->rx_skb)) {
- case 0x80:
- /* control data for the Nokia Card */
- dtl1_control(info, info->rx_skb);
- break;
- case 0x82:
- case 0x83:
- case 0x84:
- /* send frame to the HCI layer */
- hci_skb_pkt_type(info->rx_skb) &= 0x0f;
- hci_recv_frame(info->hdev, info->rx_skb);
- break;
- default:
- /* unknown packet */
- BT_ERR("Unknown HCI packet with type 0x%02x received",
- hci_skb_pkt_type(info->rx_skb));
- kfree_skb(info->rx_skb);
- break;
- }
-
- info->rx_state = RECV_WAIT_NSH;
- info->rx_count = NSHL;
- info->rx_skb = NULL;
- break;
- }
-
- }
-
- /* Make sure we don't stay here too long */
- if (boguscount++ > 32)
- break;
-
- } while (inb(iobase + UART_LSR) & UART_LSR_DR);
-}
-
-
-static irqreturn_t dtl1_interrupt(int irq, void *dev_inst)
-{
- struct dtl1_info *info = dev_inst;
- unsigned int iobase;
- unsigned char msr;
- int boguscount = 0;
- int iir, lsr;
- irqreturn_t r = IRQ_NONE;
-
- if (!info || !info->hdev)
- /* our irq handler is shared */
- return IRQ_NONE;
-
- iobase = info->p_dev->resource[0]->start;
-
- spin_lock(&(info->lock));
-
- iir = inb(iobase + UART_IIR) & UART_IIR_ID;
- while (iir) {
-
- r = IRQ_HANDLED;
- /* Clear interrupt */
- lsr = inb(iobase + UART_LSR);
-
- switch (iir) {
- case UART_IIR_RLSI:
- BT_ERR("RLSI");
- break;
- case UART_IIR_RDI:
- /* Receive interrupt */
- dtl1_receive(info);
- break;
- case UART_IIR_THRI:
- if (lsr & UART_LSR_THRE) {
- /* Transmitter ready for data */
- dtl1_write_wakeup(info);
- }
- break;
- default:
- BT_ERR("Unhandled IIR=%#x", iir);
- break;
- }
-
- /* Make sure we don't stay here too long */
- if (boguscount++ > 100)
- break;
-
- iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-
- }
-
- msr = inb(iobase + UART_MSR);
-
- if (info->ri_latch ^ (msr & UART_MSR_RI)) {
- info->ri_latch = msr & UART_MSR_RI;
- clear_bit(XMIT_WAITING, &(info->tx_state));
- dtl1_write_wakeup(info);
- r = IRQ_HANDLED;
- }
-
- spin_unlock(&(info->lock));
-
- return r;
-}
-
-
-
-/* ======================== HCI interface ======================== */
-
-
-static int dtl1_hci_open(struct hci_dev *hdev)
-{
- return 0;
-}
-
-
-static int dtl1_hci_flush(struct hci_dev *hdev)
-{
- struct dtl1_info *info = hci_get_drvdata(hdev);
-
- /* Drop TX queue */
- skb_queue_purge(&(info->txq));
-
- return 0;
-}
-
-
-static int dtl1_hci_close(struct hci_dev *hdev)
-{
- dtl1_hci_flush(hdev);
-
- return 0;
-}
-
-
-static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
-{
- struct dtl1_info *info = hci_get_drvdata(hdev);
- struct sk_buff *s;
- struct nsh nsh;
-
- switch (hci_skb_pkt_type(skb)) {
- case HCI_COMMAND_PKT:
- hdev->stat.cmd_tx++;
- nsh.type = 0x81;
- break;
- case HCI_ACLDATA_PKT:
- hdev->stat.acl_tx++;
- nsh.type = 0x82;
- break;
- case HCI_SCODATA_PKT:
- hdev->stat.sco_tx++;
- nsh.type = 0x83;
- break;
- default:
- return -EILSEQ;
- }
-
- nsh.zero = 0;
- nsh.len = skb->len;
-
- s = bt_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC);
- if (!s)
- return -ENOMEM;
-
- skb_reserve(s, NSHL);
- skb_copy_from_linear_data(skb, skb_put(s, skb->len), skb->len);
- if (skb->len & 0x0001)
- skb_put_u8(s, 0); /* PAD */
-
- /* Prepend skb with Nokia frame header and queue */
- memcpy(skb_push(s, NSHL), &nsh, NSHL);
- skb_queue_tail(&(info->txq), s);
-
- dtl1_write_wakeup(info);
-
- kfree_skb(skb);
-
- return 0;
-}
-
-
-
-/* ======================== Card services HCI interaction ======================== */
-
-
-static int dtl1_open(struct dtl1_info *info)
-{
- unsigned long flags;
- unsigned int iobase = info->p_dev->resource[0]->start;
- struct hci_dev *hdev;
-
- spin_lock_init(&(info->lock));
-
- skb_queue_head_init(&(info->txq));
-
- info->rx_state = RECV_WAIT_NSH;
- info->rx_count = NSHL;
- info->rx_skb = NULL;
-
- set_bit(XMIT_WAITING, &(info->tx_state));
-
- /* Initialize HCI device */
- hdev = hci_alloc_dev();
- if (!hdev) {
- BT_ERR("Can't allocate HCI device");
- return -ENOMEM;
- }
-
- info->hdev = hdev;
-
- hdev->bus = HCI_PCCARD;
- hci_set_drvdata(hdev, info);
- SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
-
- hdev->open = dtl1_hci_open;
- hdev->close = dtl1_hci_close;
- hdev->flush = dtl1_hci_flush;
- hdev->send = dtl1_hci_send_frame;
-
- spin_lock_irqsave(&(info->lock), flags);
-
- /* Reset UART */
- outb(0, iobase + UART_MCR);
-
- /* Turn off interrupts */
- outb(0, iobase + UART_IER);
-
- /* Initialize UART */
- outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
- outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
-
- info->ri_latch = inb(info->p_dev->resource[0]->start + UART_MSR)
- & UART_MSR_RI;
-
- /* Turn on interrupts */
- outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
-
- spin_unlock_irqrestore(&(info->lock), flags);
-
- /* Timeout before it is safe to send the first HCI packet */
- msleep(2000);
-
- /* Register HCI device */
- if (hci_register_dev(hdev) < 0) {
- BT_ERR("Can't register HCI device");
- info->hdev = NULL;
- hci_free_dev(hdev);
- return -ENODEV;
- }
-
- return 0;
-}
-
-
-static int dtl1_close(struct dtl1_info *info)
-{
- unsigned long flags;
- unsigned int iobase = info->p_dev->resource[0]->start;
- struct hci_dev *hdev = info->hdev;
-
- if (!hdev)
- return -ENODEV;
-
- dtl1_hci_close(hdev);
-
- spin_lock_irqsave(&(info->lock), flags);
-
- /* Reset UART */
- outb(0, iobase + UART_MCR);
-
- /* Turn off interrupts */
- outb(0, iobase + UART_IER);
-
- spin_unlock_irqrestore(&(info->lock), flags);
-
- hci_unregister_dev(hdev);
- hci_free_dev(hdev);
-
- return 0;
-}
-
-static int dtl1_probe(struct pcmcia_device *link)
-{
- struct dtl1_info *info;
-
- /* Create new info device */
- info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- info->p_dev = link;
- link->priv = info;
-
- link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
-
- return dtl1_config(link);
-}
-
-
-static void dtl1_detach(struct pcmcia_device *link)
-{
- struct dtl1_info *info = link->priv;
-
- dtl1_close(info);
- pcmcia_disable_device(link);
-}
-
-static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data)
-{
- if ((p_dev->resource[1]->end) || (p_dev->resource[1]->end < 8))
- return -ENODEV;
-
- p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
- p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
-
- return pcmcia_request_io(p_dev);
-}
-
-static int dtl1_config(struct pcmcia_device *link)
-{
- struct dtl1_info *info = link->priv;
- int ret;
-
- /* Look for a generic full-sized window */
- link->resource[0]->end = 8;
- ret = pcmcia_loop_config(link, dtl1_confcheck, NULL);
- if (ret)
- goto failed;
-
- ret = pcmcia_request_irq(link, dtl1_interrupt);
- if (ret)
- goto failed;
-
- ret = pcmcia_enable_device(link);
- if (ret)
- goto failed;
-
- ret = dtl1_open(info);
- if (ret)
- goto failed;
-
- return 0;
-
-failed:
- dtl1_detach(link);
- return ret;
-}
-
-static const struct pcmcia_device_id dtl1_ids[] = {
- PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
- PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-4", 0xe1bfdd64, 0x9102bc82),
- PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863),
- PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3),
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, dtl1_ids);
-
-static struct pcmcia_driver dtl1_driver = {
- .owner = THIS_MODULE,
- .name = "dtl1_cs",
- .probe = dtl1_probe,
- .remove = dtl1_detach,
- .id_table = dtl1_ids,
-};
-module_pcmcia_driver(dtl1_driver);
--
2.43.0
^ permalink raw reply related
* Re: Bluetooth: btusb: Add VID/PID 0489:e156 for MediaTek MT7902
From: Sean Wang @ 2026-05-02 23:17 UTC (permalink / raw)
To: Кирилл
Cc: sean.wang, luiz.von.dentz, linux-bluetooth,
moderated list:ARM/Mediatek SoC support
In-Reply-To: <CAL2ecxgBeZNSSuwJROmuvGFsajjpxqV1+LYnoz5dYGUPA30HeA@mail.gmail.com>
Hi Кирилл,
Could you help get the USB device information from your test machine
as the following and reply to the mail?
The information in /sys/kernel/debug/usb/devices about the Bluetooth
device is listed as the below.
T: Bus=07 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0
D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=13d3 ProdID=3596 Rev= 1.00
S: Manufacturer=MediaTek Inc.
S: Product=Wireless_Device
S: SerialNumber=000000000
C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us
E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms
I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us
E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us
I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us
I will send the patch including the VID/PID
thanks
On Sat, May 2, 2026 at 12:20 PM Кирилл <kirill.kz.902@gmail.com> wrote:
>
> Hi Sean,
>
> Following your MT7902 series, here is one more VID/PID variant
> that is currently not recognized by btusb: 0489:e156 (Foxconn).
>
> Adding the entry below makes Bluetooth work on v7.1-rc1:
>
> /* Additional MediaTek MT7902 Bluetooth devices */
> { USB_DEVICE(0x0489, 0xe156), .driver_info = BTUSB_MEDIATEK |
> BTUSB_WIDEBAND_SPEECH },
>
> dmesg after loading the patched module:
>
> Bluetooth: hci0: HW/SW Version: 0x008a008a,
> Build Time: 20250826211444
>
> /sys/kernel/debug/usb/devices:
>
> T: Bus=01 Lev=01 Prnt=01 Port=09 Cnt=05 Dev#=6 Spd=480 MxCh=0
> D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=1
> P: Vendor=0489 ProdID=e156 Rev= 1.00
> S: Manufacturer=MediaTek Inc.
> S: Product=Wireless_Device
> C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
>
> Could you include this VID/PID in the next MT7902 round?
>
> Tested-by: Kirill Shubin <kirill.kz.902@gmail.com>
>
> Thanks,
> Kirill
>
^ permalink raw reply
* RE: [v2] Bluetooth: HIDP: serialise l2cap_unregister_user via hidp_session_sem
From: bluez.test.bot @ 2026-05-02 17:44 UTC (permalink / raw)
To: linux-bluetooth, michael.bommarito
In-Reply-To: <20260502164303.2299816-1-michael.bommarito@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3741 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1088829
---Test result---
Test Summary:
CheckPatch PASS 0.64 seconds
GitLint FAIL 0.24 seconds
SubjectPrefix PASS 0.09 seconds
BuildKernel PASS 28.18 seconds
CheckAllWarning PASS 30.05 seconds
CheckSparse PASS 28.76 seconds
BuildKernel32 PASS 26.27 seconds
TestRunnerSetup PASS 579.48 seconds
TestRunner_l2cap-tester FAIL 6.77 seconds
TestRunner_iso-tester PASS 295.82 seconds
TestRunner_bnep-tester FAIL 6.75 seconds
TestRunner_mgmt-tester FAIL 8.99 seconds
TestRunner_rfcomm-tester PASS 29.07 seconds
TestRunner_sco-tester PASS 68.13 seconds
TestRunner_ioctl-tester FAIL 37.43 seconds
TestRunner_mesh-tester PASS 27.11 seconds
TestRunner_smp-tester PASS 6.58 seconds
TestRunner_userchan-tester FAIL 6.68 seconds
TestRunner_6lowpan-tester PASS 22.83 seconds
IncrementalBuild PASS 25.14 seconds
Details
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[v2] Bluetooth: HIDP: serialise l2cap_unregister_user via hidp_session_sem
WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
42: B1 Line exceeds max length (86>80): "Link: https://lore.kernel.org/all/20260422011437.176643-1-michael.bommarito@gmail.com/"
##############################
Test: TestRunner_l2cap-tester - FAIL
Desc: Run l2cap-tester with test-runner
Output:
No test result found
##############################
Test: TestRunner_bnep-tester - FAIL
Desc: Run bnep-tester with test-runner
Output:
No test result found
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
No test result found
##############################
Test: TestRunner_ioctl-tester - FAIL
Desc: Run ioctl-tester with test-runner
Output:
Total: 28, Passed: 0 (0.0%), Failed: 11, Not Run: 17
Failed Test Cases
Device List Timed out -30.849 seconds
Device Info Timed out -6.201 seconds
Reset Stat Timed out -6.204 seconds
Set Link Mode - ACCEPT Timed out -6.207 seconds
Set Pkt Type - DM Timed out -14.394 seconds
Set Pkt Type - DH Timed out -14.397 seconds
Set Pkt Type - HV Timed out -14.400 seconds
Set Pkt Type - 2-DH Timed out -14.403 seconds
Set Pkt Type - 2-DH Timed out -14.406 seconds
Set Pkt Type - ALL Timed out -14.409 seconds
Set ACL MTU - 1 Timed out -14.411 seconds
##############################
Test: TestRunner_userchan-tester - FAIL
Desc: Run userchan-tester with test-runner
Output:
No test result found
https://github.com/bluez/bluetooth-next/pull/140
---
Regards,
Linux Bluetooth
^ permalink raw reply
* Bluetooth: btusb: Add VID/PID 0489:e156 for MediaTek MT7902
From: Кирилл @ 2026-05-02 17:20 UTC (permalink / raw)
To: sean.wang; +Cc: luiz.von.dentz, linux-bluetooth
Hi Sean,
Following your MT7902 series, here is one more VID/PID variant
that is currently not recognized by btusb: 0489:e156 (Foxconn).
Adding the entry below makes Bluetooth work on v7.1-rc1:
/* Additional MediaTek MT7902 Bluetooth devices */
{ USB_DEVICE(0x0489, 0xe156), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH },
dmesg after loading the patched module:
Bluetooth: hci0: HW/SW Version: 0x008a008a,
Build Time: 20250826211444
/sys/kernel/debug/usb/devices:
T: Bus=01 Lev=01 Prnt=01 Port=09 Cnt=05 Dev#=6 Spd=480 MxCh=0
D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=1
P: Vendor=0489 ProdID=e156 Rev= 1.00
S: Manufacturer=MediaTek Inc.
S: Product=Wireless_Device
C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
Could you include this VID/PID in the next MT7902 round?
Tested-by: Kirill Shubin <kirill.kz.902@gmail.com>
Thanks,
Kirill
^ permalink raw reply
* [bluetooth-next:master] BUILD SUCCESS f2f6f881510396c54bc2e4391d3c4067fbdfdd25
From: kernel test robot @ 2026-05-02 16:47 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
branch HEAD: f2f6f881510396c54bc2e4391d3c4067fbdfdd25 Bluetooth: SMP: Use AES-CMAC library API
elapsed time: 2684m
configs tested: 173
configs skipped: 2
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-15.2.0
alpha allyesconfig gcc-15.2.0
alpha defconfig gcc-15.2.0
arc allmodconfig clang-16
arc allnoconfig gcc-15.2.0
arc allyesconfig clang-23
arc defconfig gcc-15.2.0
arc randconfig-001 gcc-8.5.0
arc randconfig-001-20260502 gcc-8.5.0
arc randconfig-002 gcc-8.5.0
arc randconfig-002-20260502 gcc-8.5.0
arm allnoconfig gcc-15.2.0
arm allyesconfig clang-16
arm defconfig gcc-15.2.0
arm randconfig-001 gcc-8.5.0
arm randconfig-001-20260502 gcc-8.5.0
arm randconfig-002 gcc-8.5.0
arm randconfig-002-20260502 gcc-8.5.0
arm randconfig-003 gcc-8.5.0
arm randconfig-003-20260502 gcc-8.5.0
arm randconfig-004 gcc-8.5.0
arm randconfig-004-20260502 gcc-8.5.0
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-15.2.0
arm64 defconfig gcc-15.2.0
arm64 randconfig-001 gcc-10.5.0
arm64 randconfig-001-20260502 gcc-10.5.0
arm64 randconfig-002 gcc-10.5.0
arm64 randconfig-002-20260502 gcc-10.5.0
arm64 randconfig-003 gcc-10.5.0
arm64 randconfig-003-20260502 gcc-10.5.0
arm64 randconfig-004 gcc-10.5.0
arm64 randconfig-004-20260502 gcc-10.5.0
csky allmodconfig gcc-15.2.0
csky allnoconfig gcc-15.2.0
csky defconfig gcc-15.2.0
csky randconfig-001 gcc-10.5.0
csky randconfig-001-20260502 gcc-10.5.0
csky randconfig-002 gcc-10.5.0
csky randconfig-002-20260502 gcc-10.5.0
hexagon allmodconfig gcc-15.2.0
hexagon allnoconfig gcc-15.2.0
hexagon defconfig gcc-15.2.0
hexagon randconfig-001-20260502 clang-23
hexagon randconfig-002-20260502 clang-23
i386 allmodconfig clang-20
i386 allnoconfig gcc-15.2.0
i386 allyesconfig clang-20
i386 buildonly-randconfig-001-20260502 gcc-14
i386 buildonly-randconfig-002-20260502 gcc-14
i386 buildonly-randconfig-003-20260502 gcc-14
i386 buildonly-randconfig-004-20260502 gcc-14
i386 buildonly-randconfig-005-20260502 gcc-14
i386 buildonly-randconfig-006-20260502 gcc-14
i386 defconfig gcc-15.2.0
loongarch allmodconfig clang-23
loongarch allnoconfig gcc-15.2.0
loongarch defconfig clang-19
loongarch randconfig-001-20260502 clang-23
loongarch randconfig-002-20260502 clang-23
m68k allmodconfig gcc-15.2.0
m68k allnoconfig gcc-15.2.0
m68k allyesconfig clang-16
m68k defconfig clang-19
m68k mvme147_defconfig gcc-15.2.0
microblaze allnoconfig gcc-15.2.0
microblaze allyesconfig gcc-15.2.0
microblaze defconfig clang-19
mips allmodconfig gcc-15.2.0
mips allnoconfig gcc-15.2.0
mips allyesconfig gcc-15.2.0
nios2 allmodconfig clang-23
nios2 allnoconfig clang-23
nios2 defconfig clang-19
nios2 randconfig-001-20260502 clang-23
nios2 randconfig-002-20260502 clang-23
openrisc allmodconfig clang-23
openrisc allnoconfig clang-23
openrisc defconfig gcc-15.2.0
parisc allmodconfig gcc-15.2.0
parisc allnoconfig clang-23
parisc allyesconfig clang-19
parisc defconfig gcc-15.2.0
parisc randconfig-001 gcc-12.5.0
parisc randconfig-001-20260502 gcc-12.5.0
parisc randconfig-002 gcc-12.5.0
parisc randconfig-002-20260502 gcc-12.5.0
parisc64 defconfig clang-19
powerpc allmodconfig gcc-15.2.0
powerpc allnoconfig clang-23
powerpc randconfig-001 gcc-12.5.0
powerpc randconfig-001-20260502 gcc-12.5.0
powerpc randconfig-002 gcc-12.5.0
powerpc randconfig-002-20260502 gcc-12.5.0
powerpc64 randconfig-001 gcc-12.5.0
powerpc64 randconfig-001-20260502 gcc-12.5.0
powerpc64 randconfig-002 gcc-12.5.0
powerpc64 randconfig-002-20260502 gcc-12.5.0
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allyesconfig clang-16
riscv defconfig gcc-15.2.0
riscv randconfig-001-20260502 gcc-14.3.0
riscv randconfig-002-20260502 gcc-14.3.0
s390 allmodconfig clang-19
s390 allnoconfig clang-23
s390 allyesconfig gcc-15.2.0
s390 defconfig gcc-15.2.0
s390 randconfig-001-20260502 gcc-14.3.0
s390 randconfig-002-20260502 gcc-14.3.0
sh allmodconfig gcc-15.2.0
sh allnoconfig clang-23
sh allyesconfig clang-19
sh defconfig gcc-14
sh randconfig-001-20260502 gcc-14.3.0
sh randconfig-002-20260502 gcc-14.3.0
sh rts7751r2d1_defconfig gcc-15.2.0
sparc allnoconfig clang-23
sparc defconfig gcc-15.2.0
sparc randconfig-001-20260502 gcc-8.5.0
sparc randconfig-002-20260502 gcc-8.5.0
sparc64 allmodconfig clang-23
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260502 gcc-8.5.0
sparc64 randconfig-002-20260502 gcc-8.5.0
um allmodconfig clang-19
um allnoconfig clang-23
um allyesconfig gcc-15.2.0
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260502 gcc-8.5.0
um randconfig-002-20260502 gcc-8.5.0
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-20
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-20
x86_64 buildonly-randconfig-001 clang-20
x86_64 buildonly-randconfig-001-20260502 clang-20
x86_64 buildonly-randconfig-002 clang-20
x86_64 buildonly-randconfig-002-20260502 clang-20
x86_64 buildonly-randconfig-003 clang-20
x86_64 buildonly-randconfig-003-20260502 clang-20
x86_64 buildonly-randconfig-004 clang-20
x86_64 buildonly-randconfig-004-20260502 clang-20
x86_64 buildonly-randconfig-005 clang-20
x86_64 buildonly-randconfig-005-20260502 clang-20
x86_64 buildonly-randconfig-006 clang-20
x86_64 buildonly-randconfig-006-20260502 clang-20
x86_64 defconfig gcc-14
x86_64 kexec clang-20
x86_64 randconfig-001-20260502 clang-20
x86_64 randconfig-002-20260502 clang-20
x86_64 randconfig-003-20260502 clang-20
x86_64 randconfig-004-20260502 clang-20
x86_64 randconfig-005-20260502 clang-20
x86_64 randconfig-006-20260502 clang-20
x86_64 randconfig-071-20260502 gcc-14
x86_64 randconfig-072-20260502 gcc-14
x86_64 randconfig-073-20260502 gcc-14
x86_64 randconfig-074-20260502 gcc-14
x86_64 randconfig-075-20260502 gcc-14
x86_64 randconfig-076-20260502 gcc-14
x86_64 rhel-9.4 clang-20
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-20
x86_64 rhel-9.4-kselftests clang-20
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-20
xtensa allnoconfig clang-23
xtensa allyesconfig clang-23
xtensa randconfig-001-20260502 gcc-8.5.0
xtensa randconfig-002-20260502 gcc-8.5.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* [PATCH v2] Bluetooth: HIDP: serialise l2cap_unregister_user via hidp_session_sem
From: Michael Bommarito @ 2026-05-02 16:43 UTC (permalink / raw)
To: Marcel Holtmann
Cc: Luiz Augusto von Dentz, Pauli Virtanen, linux-bluetooth,
linux-kernel
In-Reply-To: <20260422011437.176643-1-michael.bommarito@gmail.com>
Commit dbf666e4fc9b ("Bluetooth: HIDP: Fix possible UAF") made
hidp_session_remove() drop the L2CAP reference and set
session->conn = NULL once the session is considered removed, and
added a bare if (session->conn) guard around the kthread-exit
l2cap_unregister_user() call in hidp_session_thread(). The sibling
ioctl site in hidp_connection_del() still reads session->conn
unlocked and unguarded, and the kthread-exit guard itself is a
lockless double-read.
hidp_session_find() drops hidp_session_sem before returning, so
hidp_session_remove() can null session->conn between the lookup and
the call in hidp_connection_del(). Worse, since commit 752a6c9596dd
("Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user")
takes mutex_lock(&conn->lock) inside l2cap_unregister_user(), a
stale non-NULL snapshot also UAFs on conn->lock. v1 only added an
if (session->conn) guard at the ioctl site, which doesn't address
either race; Luiz suggested snapshotting session->conn under the
sem and clearing it before the call.
Taking hidp_session_sem across l2cap_unregister_user() would be
wrong: l2cap_conn_del() already establishes the lock order
conn->lock -> hidp_session_sem
via l2cap_unregister_all_users() -> user->remove ==
hidp_session_remove(), so taking hidp_session_sem before conn->lock
would AB/BA deadlock.
Factor a helper hidp_session_unregister_conn() that under
down_write(&hidp_session_sem) snapshots session->conn and clears
the member, then outside the sem calls l2cap_unregister_user() and
l2cap_conn_put() on the snapshot. Call it from both
hidp_connection_del() and hidp_session_thread()'s exit path. At
most one consumer wins the write-sem; later callers observe
session->conn == NULL and skip the unregister and put, so the
reference hidp_session_new() took via l2cap_conn_get() is consumed
exactly once. session_free() already tolerates a NULL session->conn.
Fixes: dbf666e4fc9b ("Bluetooth: HIDP: Fix possible UAF")
Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Link: https://lore.kernel.org/all/20260422011437.176643-1-michael.bommarito@gmail.com/
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Assisted-by: Claude:claude-opus-4-7
---
Tested under UML with CONFIG_BT_HIDP=y, CONFIG_KASAN=y, and
CONFIG_PROVE_LOCKING=y. W=1 build of net/bluetooth/hidp/ clean;
boot clean. A KCFLAGS-gated test stub (not part of this patch)
drove hidp_session_unregister_conn() twice in a row against a fake
session with conn = NULL: the helper short-circuited both times and
lockdep stayed silent.
net/bluetooth/hidp/core.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 7bcf8c5ceaee..976f91eeb745 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -1035,6 +1035,28 @@ static struct hidp_session *hidp_session_find(const bdaddr_t *bdaddr)
return session;
}
+/*
+ * Consume session->conn: clear the member under hidp_session_sem, then
+ * l2cap_unregister_user() and l2cap_conn_put() the snapshot outside the
+ * sem. At most one caller wins; later callers see NULL and skip. The
+ * reference is the one hidp_session_new() took via l2cap_conn_get().
+ */
+static void hidp_session_unregister_conn(struct hidp_session *session)
+{
+ struct l2cap_conn *conn;
+
+ down_write(&hidp_session_sem);
+ conn = session->conn;
+ if (conn)
+ session->conn = NULL;
+ up_write(&hidp_session_sem);
+
+ if (conn) {
+ l2cap_unregister_user(conn, &session->user);
+ l2cap_conn_put(conn);
+ }
+}
+
/*
* Start session synchronously
* This starts a session thread and waits until initialization
@@ -1311,8 +1333,7 @@ static int hidp_session_thread(void *arg)
* Instead, this call has the same semantics as if user-space tried to
* delete the session.
*/
- if (session->conn)
- l2cap_unregister_user(session->conn, &session->user);
+ hidp_session_unregister_conn(session);
hidp_session_put(session);
@@ -1418,7 +1439,7 @@ int hidp_connection_del(struct hidp_conndel_req *req)
HIDP_CTRL_VIRTUAL_CABLE_UNPLUG,
NULL, 0);
else
- l2cap_unregister_user(session->conn, &session->user);
+ hidp_session_unregister_conn(session);
hidp_session_put(session);
--
2.53.0
^ permalink raw reply related
* [syzbot] Monthly bluetooth report (May 2026)
From: syzbot @ 2026-05-02 12:32 UTC (permalink / raw)
To: linux-bluetooth, linux-kernel, luiz.dentz, marcel, syzkaller-bugs
Hello bluetooth maintainers/developers,
This is a 31-day syzbot report for the bluetooth subsystem.
All related reports/information can be found at:
https://syzkaller.appspot.com/upstream/s/bluetooth
During the period, 3 new issues were detected and 0 were fixed.
In total, 32 issues are still open and 101 have already been fixed.
Some of the still happening issues:
Ref Crashes Repro Title
<1> 13915 Yes WARNING in hci_conn_timeout (2)
https://syzkaller.appspot.com/bug?extid=fc4b5b2477d4ca272907
<2> 8770 Yes WARNING in call_timer_fn
https://syzkaller.appspot.com/bug?extid=6fb78d577e89e69602f9
<3> 4488 Yes general protection fault in lock_sock_nested
https://syzkaller.appspot.com/bug?extid=d3ccfb78a0dc16ffebe3
<4> 1766 No KASAN: vmalloc-out-of-bounds Read in kcov_remote_start
https://syzkaller.appspot.com/bug?extid=8a173e13208949931dc7
<5> 524 Yes WARNING: ODEBUG bug in hci_release_dev (2)
https://syzkaller.appspot.com/bug?extid=b170dbf55520ebf5969a
<6> 358 No WARNING in l2cap_chan_del
https://syzkaller.appspot.com/bug?extid=3272785b7a1fc9b510f6
<7> 295 Yes KASAN: wild-memory-access Read in l2cap_connect_cfm
https://syzkaller.appspot.com/bug?extid=0e4ebcc970728e056324
<8> 217 Yes WARNING in hci_recv_frame
https://syzkaller.appspot.com/bug?extid=3e07a461b836821ff70e
<9> 163 Yes KASAN: slab-use-after-free Read in l2cap_sock_new_connection_cb
https://syzkaller.appspot.com/bug?extid=cdae834448ec8c3602fe
<10> 135 Yes KASAN: slab-use-after-free Read in bt_accept_unlink
https://syzkaller.appspot.com/bug?extid=a1595e656a83ea5b78eb
---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
To disable reminders for individual bugs, reply with the following command:
#syz set <Ref> no-reminders
To change bug's subsystems, reply with:
#syz set <Ref> subsystems: new-subsystem
You may send multiple commands in a single email message.
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-05-02 9:11 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1076276
Home: https://github.com/bluez/bluez
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* [Bug 221449] Wireless gamepad stopped working through Bluetooth
From: bugzilla-daemon @ 2026-05-01 23:36 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <bug-221449-62941@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=221449
--- Comment #1 from Arvin Ignaci (arvin.ignaci@gmail.com) ---
To clarify, the gamepad stopped working after a system update, which is why I
suspected a kernel regression and posted this issue here.
--
You may reply to this email to add a comment.
You are receiving this mail because:
You are the assignee for the bug.
^ permalink raw reply
* [Bug 221449] New: Wireless gamepad stopped working through Bluetooth
From: bugzilla-daemon @ 2026-05-01 22:37 UTC (permalink / raw)
To: linux-bluetooth
https://bugzilla.kernel.org/show_bug.cgi?id=221449
Bug ID: 221449
Summary: Wireless gamepad stopped working through Bluetooth
Product: Drivers
Version: 2.5
Hardware: Intel
OS: Linux
Status: NEW
Severity: normal
Priority: P3
Component: Bluetooth
Assignee: linux-bluetooth@vger.kernel.org
Reporter: arvin.ignaci@gmail.com
Regression: No
I'm running Fedora Silverblue 44 (Universal Blue image) with kernel version
6.19.14. Some time in the last month or so, a Bluetooth gamepad I had stopped
working. It started with inputs being mapped incorrectly and certain inputs not
being recognized. Now, I don't get any input at all. The same gamepad used to
work just fine over Bluetooth and still works over USB.
The gamepad is a GuliKit KK3 set to the "Android" pairing mode; It shows up as
an "Xbox Wireless Controller" in Linux. My Bluetooth controller appears to be
an Intel AX200 modem (according to lsusb). When I connect the gamepad via
Bluetooth and try pressing some buttons or moving the sticks around, the dmesg
output is filled with these messages:
> [ 2041.273972] hid_report_raw_event: 14 callbacks suppressed
> [ 2041.273976] microsoft 0005:045E:02FD.000C: Event data for report 1 was too
> short (16 vs 15)
> [ 2041.277912] microsoft 0005:045E:02FD.000C: Event data for report 1 was too
> short (16 vs 15)
> [ 2041.280044] microsoft 0005:045E:02FD.000C: Event data for report 1 was too
> short (16 vs 15)
> [ 2041.288927] microsoft 0005:045E:02FD.000C: Event data for report 1 was too
> short (16 vs 15)
> [ 2041.300915] microsoft 0005:045E:02FD.000C: Event data for report 1 was too
> short (16 vs 15)
> [ 2041.309919] microsoft 0005:045E:02FD.000C: Event data for report 1 was too
> short (16 vs 15)
--
You may reply to this email to add a comment.
You are receiving this mail because:
You are the assignee for the bug.
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-05-01 21:07 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1076045
Home: https://github.com/bluez/bluez
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* RE: [BlueZ,v1,1/4] shared/hci: Add BPF filter for registered events
From: bluez.test.bot @ 2026-05-01 15:56 UTC (permalink / raw)
To: linux-bluetooth, luiz.dentz
In-Reply-To: <20260501143847.724150-1-luiz.dentz@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4532 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1088547
---Test result---
Test Summary:
CheckPatch FAIL 1.94 seconds
GitLint PASS 1.17 seconds
BuildEll PASS 20.18 seconds
BluezMake PASS 654.89 seconds
CheckSmatch PASS 350.12 seconds
bluezmakeextell PASS 182.29 seconds
IncrementalBuild PASS 707.45 seconds
ScanBuild PASS 1006.46 seconds
Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ,v1,1/4] shared/hci: Add BPF filter for registered events
WARNING:BAD_SIGN_OFF: Non-standard signature: Assisted-by:
#105:
Assisted-by: Claude:claude-opus-4.6
ERROR:BAD_SIGN_OFF: Unrecognized email address: 'Claude:claude-opus-4.6'
#105:
Assisted-by: Claude:claude-opus-4.6
/github/workspace/src/patch/14550825.patch total: 1 errors, 1 warnings, 108 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/github/workspace/src/patch/14550825.patch has style problems, please review.
NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
[BlueZ,v1,2/4] shared/hci: Add bt_hci_register_subevent for LE Meta events
WARNING:BAD_SIGN_OFF: Non-standard signature: Assisted-by:
#111:
Assisted-by: Claude:claude-opus-4.6
ERROR:BAD_SIGN_OFF: Unrecognized email address: 'Claude:claude-opus-4.6'
#111:
Assisted-by: Claude:claude-opus-4.6
/github/workspace/src/patch/14550827.patch total: 1 errors, 1 warnings, 317 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/github/workspace/src/patch/14550827.patch has style problems, please review.
NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
[BlueZ,v1,3/4] ranging/rap_hci: Use bt_hci_register_subevent for LE CS events
WARNING:BAD_SIGN_OFF: Non-standard signature: Assisted-by:
#109:
Assisted-by: Claude:claude-opus-4.6
ERROR:BAD_SIGN_OFF: Unrecognized email address: 'Claude:claude-opus-4.6'
#109:
Assisted-by: Claude:claude-opus-4.6
/github/workspace/src/patch/14550828.patch total: 1 errors, 1 warnings, 269 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/github/workspace/src/patch/14550828.patch has style problems, please review.
NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
[BlueZ,v1,4/4] hci-tester: Use bt_hci_register_subevent for LE Meta events
WARNING:BAD_SIGN_OFF: Non-standard signature: Assisted-by:
#107:
Assisted-by: Claude:claude-opus-4.6
ERROR:BAD_SIGN_OFF: Unrecognized email address: 'Claude:claude-opus-4.6'
#107:
Assisted-by: Claude:claude-opus-4.6
/github/workspace/src/patch/14550826.patch total: 1 errors, 1 warnings, 116 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/github/workspace/src/patch/14550826.patch has style problems, please review.
NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
https://github.com/bluez/bluez/pull/2091
---
Regards,
Linux Bluetooth
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-05-01 15:06 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1088223
Home: https://github.com/bluez/bluez
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-05-01 15:06 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1088308
Home: https://github.com/bluez/bluez
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* [bluez/bluez] 323d54: shared/hci: Add BPF filter for registered events
From: Luiz Augusto von Dentz @ 2026-05-01 15:06 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1088547
Home: https://github.com/bluez/bluez
Commit: 323d54f958ff446ecd6897c8ce1aade29639e454
https://github.com/bluez/bluez/commit/323d54f958ff446ecd6897c8ce1aade29639e454
Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: 2026-05-01 (Fri, 01 May 2026)
Changed paths:
M src/shared/hci.c
Log Message:
-----------
shared/hci: Add BPF filter for registered events
Implement a BPF socket filter in bt_hci_register/bt_hci_unregister that
uses setsockopt(SO_ATTACH_FILTER) to only accept HCI events that have
been registered, plus BT_HCI_EVT_CMD_COMPLETE and BT_HCI_EVT_CMD_STATUS
which are always needed for command response processing.
The filter is rebuilt each time an event is registered or unregistered,
and only applies to non-stream (raw socket) connections.
Assisted-by: Claude:claude-opus-4.6
Commit: 445437b236ab5b3c7b9c888ae1baa52176216928
https://github.com/bluez/bluez/commit/445437b236ab5b3c7b9c888ae1baa52176216928
Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: 2026-05-01 (Fri, 01 May 2026)
Changed paths:
M src/shared/hci.c
M src/shared/hci.h
Log Message:
-----------
shared/hci: Add bt_hci_register_subevent for LE Meta events
Add bt_hci_register_subevent/bt_hci_unregister_subevent API that allows
registering for specific LE Meta Event subevents. The BPF filter is
extended to accept BT_HCI_EVT_LE_META_EVENT packets and then check the
subevent byte (offset 4) against registered subevents.
Since bt_hci_register_subevent is only used with BT_HCI_EVT_LE_META_EVENT,
the event parameter is omitted. The subevent list reuses struct evt where
evt->event stores the subevent code.
Assisted-by: Claude:claude-opus-4.6
Commit: 5b1e05389d250781fbfd1e72308395b297f9414a
https://github.com/bluez/bluez/commit/5b1e05389d250781fbfd1e72308395b297f9414a
Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: 2026-05-01 (Fri, 01 May 2026)
Changed paths:
M profiles/ranging/rap_hci.c
Log Message:
-----------
ranging/rap_hci: Use bt_hci_register_subevent for LE CS events
Replace the single BT_HCI_EVT_LE_META_EVENT registration and subevent
dispatch table with individual bt_hci_register_subevent calls for each
CS subevent. This enables BPF filtering at the socket level for each
specific subevent and removes the manual subevent dispatch logic.
Event IDs are stored in a struct queue for flexible management.
Assisted-by: Claude:claude-opus-4.6
Commit: dfbc31a733555c70ff0c6e74ba1834908485a950
https://github.com/bluez/bluez/commit/dfbc31a733555c70ff0c6e74ba1834908485a950
Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: 2026-05-01 (Fri, 01 May 2026)
Changed paths:
M tools/hci-tester.c
Log Message:
-----------
hci-tester: Use bt_hci_register_subevent for LE Meta events
Convert all bt_hci_register(BT_HCI_EVT_LE_META_EVENT) calls to use
bt_hci_register_subevent with the specific subevent code. Update
callbacks to work with data that no longer contains the subevent byte
prefix, since bt_hci_register_subevent strips it before dispatch.
Assisted-by: Claude:claude-opus-4.6
Compare: https://github.com/bluez/bluez/compare/323d54f958ff%5E...dfbc31a73355
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* [PATCH BlueZ v1 3/4] ranging/rap_hci: Use bt_hci_register_subevent for LE CS events
From: Luiz Augusto von Dentz @ 2026-05-01 14:38 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20260501143847.724150-1-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Replace the single BT_HCI_EVT_LE_META_EVENT registration and subevent
dispatch table with individual bt_hci_register_subevent calls for each
CS subevent. This enables BPF filtering at the socket level for each
specific subevent and removes the manual subevent dispatch logic.
Event IDs are stored in a struct queue for flexible management.
Assisted-by: Claude:claude-opus-4.6
---
profiles/ranging/rap_hci.c | 193 ++++++++++++++-----------------------
1 file changed, 71 insertions(+), 122 deletions(-)
diff --git a/profiles/ranging/rap_hci.c b/profiles/ranging/rap_hci.c
index 08ddc077ce94..8e65e5ef87bd 100644
--- a/profiles/ranging/rap_hci.c
+++ b/profiles/ranging/rap_hci.c
@@ -61,7 +61,7 @@ struct cs_state_machine {
enum cs_state old_state;
struct bt_hci *hci;
struct bt_rap *rap;
- unsigned int event_id;
+ struct queue *event_ids;
bool initiator;
bool procedure_active;
struct bt_rap_hci_cs_options cs_opt; /* Per-instance CS options */
@@ -302,7 +302,7 @@ static void rap_send_hci_def_settings_command(struct cs_state_machine *sm,
error("Failed to send default settings cmd");
}
-static void rap_rd_rmt_supp_cap_cmplt_evt(const uint8_t *data, uint8_t size,
+static void rap_rd_rmt_supp_cap_cmplt_evt(const void *data, uint8_t size,
void *user_data)
{
struct cs_state_machine *sm = user_data;
@@ -348,7 +348,7 @@ static void rap_rd_rmt_supp_cap_cmplt_evt(const uint8_t *data, uint8_t size,
cs_set_state(sm, CS_STATE_INIT);
}
-static void rap_cs_config_cmplt_evt(const uint8_t *data, uint8_t size,
+static void rap_cs_config_cmplt_evt(const void *data, uint8_t size,
void *user_data)
{
struct cs_state_machine *sm = user_data;
@@ -439,7 +439,7 @@ static void rap_cs_config_cmplt_evt(const uint8_t *data, uint8_t size,
bt_rap_hci_cs_config_complete_callback(size, &rap_ev, sm->rap);
}
-static void rap_cs_sec_enable_cmplt_evt(const uint8_t *data, uint8_t size,
+static void rap_cs_sec_enable_cmplt_evt(const void *data, uint8_t size,
void *user_data)
{
struct cs_state_machine *sm = user_data;
@@ -500,7 +500,7 @@ static void rap_cs_sec_enable_cmplt_evt(const uint8_t *data, uint8_t size,
bt_rap_hci_cs_sec_enable_complete_callback(size, &rap_ev, sm->rap);
}
-static void rap_cs_proc_enable_cmplt_evt(const uint8_t *data, uint8_t size,
+static void rap_cs_proc_enable_cmplt_evt(const void *data, uint8_t size,
void *user_data)
{
struct cs_state_machine *sm = user_data;
@@ -800,7 +800,7 @@ static void parse_cs_step(struct iovec *iov, struct cs_step_data *step,
}
}
-static void rap_cs_subevt_result_evt(const uint8_t *data, uint8_t size,
+static void rap_cs_subevt_result_evt(const void *data, uint8_t size,
void *user_data)
{
struct cs_state_machine *sm = (struct cs_state_machine *) user_data;
@@ -910,7 +910,7 @@ send_event:
free(rap_ev);
}
-static void rap_cs_subevt_result_cont_evt(const uint8_t *data, uint8_t size,
+static void rap_cs_subevt_result_cont_evt(const void *data, uint8_t size,
void *user_data)
{
struct cs_state_machine *sm = (struct cs_state_machine *) user_data;
@@ -1009,113 +1009,12 @@ send_event:
}
/* Subevent handler function type */
-typedef void (*subevent_handler_t)(const uint8_t *data, uint8_t size,
- void *user_data);
-/* Subevent table entry */
-struct subevent_entry {
- uint8_t opcode;
- uint8_t min_len;
- uint8_t max_len;
- subevent_handler_t handler;
- const char *name;
-};
-
-/* Macro to define HCI event entries
- * Note: min_len excludes the subevent byte since it's stripped before dispatch
- */
-#define HCI_EVT(_opcode, _struct, _handler, _name) \
- { \
- .opcode = _opcode, \
- .min_len = sizeof(_struct), \
- .max_len = 0xFF, \
- .handler = _handler, \
- .name = _name \
- }
-
-/* Subevent dispatch table */
-static const struct subevent_entry subevent_table[] = {
- HCI_EVT(BT_HCI_EVT_LE_CS_RD_REM_SUPP_CAP_COMPLETE,
- struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete,
- rap_rd_rmt_supp_cap_cmplt_evt,
- "CS Read Remote Supported Capabilities Complete"),
- HCI_EVT(BT_HCI_EVT_LE_CS_CONFIG_COMPLETE,
- struct bt_hci_evt_le_cs_config_complete,
- rap_cs_config_cmplt_evt,
- "CS Config Complete"),
- HCI_EVT(BT_HCI_EVT_LE_CS_SEC_ENABLE_COMPLETE,
- struct bt_hci_evt_le_cs_sec_enable_complete,
- rap_cs_sec_enable_cmplt_evt,
- "CS Security Enable Complete"),
- HCI_EVT(BT_HCI_EVT_LE_CS_PROC_ENABLE_COMPLETE,
- struct bt_hci_evt_le_cs_proc_enable_complete,
- rap_cs_proc_enable_cmplt_evt,
- "CS Procedure Enable Complete"),
- HCI_EVT(BT_HCI_EVT_LE_CS_SUBEVENT_RESULT,
- struct bt_hci_evt_le_cs_subevent_result,
- rap_cs_subevt_result_evt,
- "CS Subevent Result"),
- HCI_EVT(BT_HCI_EVT_LE_CS_SUBEVENT_RESULT_CONTINUE,
- struct bt_hci_evt_le_cs_subevent_result_continue,
- rap_cs_subevt_result_cont_evt,
- "CS Subevent Result Continue")
-};
-
-#undef HCI_EVT
-
-#define SUBEVENT_TABLE_SIZE ARRAY_SIZE(subevent_table)
-
-/* HCI Event Registration */
-static void rap_handle_hci_events(const void *data, uint8_t size,
- void *user_data)
+static void unregister_event_id(void *data, void *user_data)
{
- struct iovec iov;
- uint8_t subevent;
- const struct subevent_entry *entry = NULL;
- size_t i;
+ struct bt_hci *hci = user_data;
- /* Initialize iovec with the event data */
- iov.iov_base = (void *) data;
- iov.iov_len = size;
-
- /* Pull the subevent code */
- if (!util_iov_pull_u8(&iov, &subevent)) {
- DBG("Failed to parse subevent code");
- return;
- }
-
- /* Find the subevent in the table */
- for (i = 0; i < SUBEVENT_TABLE_SIZE; i++) {
- if (subevent_table[i].opcode == subevent) {
- entry = &subevent_table[i];
- break;
- }
- }
-
- /* Check if subevent is supported */
- if (!entry) {
- DBG("Unknown subevent: 0x%02X", subevent);
- return;
- }
-
- /* Validate payload length */
- if (iov.iov_len < entry->min_len) {
- DBG("%s: payload too short (%zu < %u)",
- entry->name, iov.iov_len, entry->min_len);
- return;
- }
-
- if (entry->max_len != 0xFF && iov.iov_len > entry->max_len) {
- DBG("%s: payload too long (%zu > %u)",
- entry->name, iov.iov_len, entry->max_len);
- return;
- }
-
- /* Call the handler */
- DBG("Handling %s (opcode=0x%02X, len=%zu)",
- entry->name, subevent, iov.iov_len);
-
- entry->handler(iov.iov_base, iov.iov_len, user_data);
+ bt_hci_unregister_subevent(hci, PTR_TO_UINT(data));
}
void *bt_rap_attach_hci(struct bt_rap *rap, struct bt_hci *hci,
@@ -1123,6 +1022,7 @@ void *bt_rap_attach_hci(struct bt_rap *rap, struct bt_hci *hci,
int8_t max_tx_power)
{
struct cs_state_machine *sm;
+ unsigned int id;
if (!rap || !hci) {
error("rap or hci null");
@@ -1140,22 +1040,68 @@ void *bt_rap_attach_hci(struct bt_rap *rap, struct bt_hci *hci,
cs_state_machine_init(sm, rap, hci, role, cs_sync_ant_sel,
max_tx_power);
- sm->event_id = bt_hci_register(hci, BT_HCI_EVT_LE_META_EVENT,
- rap_handle_hci_events, sm, NULL);
+ sm->event_ids = queue_new();
- DBG("bt_hci_register done, event_id : %d", sm->event_id);
+ /* Register each LE Meta subevent individually */
+ id = bt_hci_register_subevent(hci,
+ BT_HCI_EVT_LE_CS_RD_REM_SUPP_CAP_COMPLETE,
+ rap_rd_rmt_supp_cap_cmplt_evt, sm, NULL);
+ if (!id)
+ goto fail;
- if (!sm->event_id) {
- error("Failed to register hci le meta events");
- error("event_id=0x%02X", sm->event_id);
- free(sm);
- return NULL;
- }
+ queue_push_tail(sm->event_ids, UINT_TO_PTR(id));
+
+ id = bt_hci_register_subevent(hci,
+ BT_HCI_EVT_LE_CS_CONFIG_COMPLETE,
+ rap_cs_config_cmplt_evt, sm, NULL);
+ if (!id)
+ goto fail;
+
+ queue_push_tail(sm->event_ids, UINT_TO_PTR(id));
+
+ id = bt_hci_register_subevent(hci,
+ BT_HCI_EVT_LE_CS_SEC_ENABLE_COMPLETE,
+ rap_cs_sec_enable_cmplt_evt, sm, NULL);
+ if (!id)
+ goto fail;
+
+ queue_push_tail(sm->event_ids, UINT_TO_PTR(id));
+
+ id = bt_hci_register_subevent(hci,
+ BT_HCI_EVT_LE_CS_PROC_ENABLE_COMPLETE,
+ rap_cs_proc_enable_cmplt_evt, sm, NULL);
+ if (!id)
+ goto fail;
+
+ queue_push_tail(sm->event_ids, UINT_TO_PTR(id));
+
+ id = bt_hci_register_subevent(hci,
+ BT_HCI_EVT_LE_CS_SUBEVENT_RESULT,
+ rap_cs_subevt_result_evt, sm, NULL);
+ if (!id)
+ goto fail;
+
+ queue_push_tail(sm->event_ids, UINT_TO_PTR(id));
+
+ id = bt_hci_register_subevent(hci,
+ BT_HCI_EVT_LE_CS_SUBEVENT_RESULT_CONTINUE,
+ rap_cs_subevt_result_cont_evt, sm, NULL);
+ if (!id)
+ goto fail;
+
+ queue_push_tail(sm->event_ids, UINT_TO_PTR(id));
DBG("CS options: role=%u, cs_sync_ant_sel=%u, max_tx_power=%d",
role, cs_sync_ant_sel, max_tx_power);
return sm;
+
+fail:
+ error("Failed to register hci le meta subevents");
+ queue_foreach(sm->event_ids, unregister_event_id, hci);
+ queue_destroy(sm->event_ids, NULL);
+ free(sm);
+ return NULL;
}
bool bt_rap_set_conn_handle(void *hci_sm, struct bt_rap *rap, uint16_t handle,
@@ -1204,8 +1150,11 @@ void bt_rap_detach_hci(struct bt_rap *rap, void *hci_sm)
/* Cleanup the per-instance state machine */
if (sm) {
/* Unregister HCI events */
- if (sm->event_id && sm->hci)
- bt_hci_unregister(sm->hci, sm->event_id);
+ if (sm->hci)
+ queue_foreach(sm->event_ids, unregister_event_id,
+ sm->hci);
+
+ queue_destroy(sm->event_ids, NULL);
/* Clean up per-instance connection mappings */
remove_rap_mappings(sm);
--
2.53.0
^ permalink raw reply related
* [PATCH BlueZ v1 2/4] shared/hci: Add bt_hci_register_subevent for LE Meta events
From: Luiz Augusto von Dentz @ 2026-05-01 14:38 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20260501143847.724150-1-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Add bt_hci_register_subevent/bt_hci_unregister_subevent API that allows
registering for specific LE Meta Event subevents. The BPF filter is
extended to accept BT_HCI_EVT_LE_META_EVENT packets and then check the
subevent byte (offset 4) against registered subevents.
Since bt_hci_register_subevent is only used with BT_HCI_EVT_LE_META_EVENT,
the event parameter is omitted. The subevent list reuses struct evt where
evt->event stores the subevent code.
Assisted-by: Claude:claude-opus-4.6
---
src/shared/hci.c | 240 ++++++++++++++++++++++++++++++++++++++++-------
src/shared/hci.h | 6 ++
2 files changed, 212 insertions(+), 34 deletions(-)
diff --git a/src/shared/hci.c b/src/shared/hci.c
index 5105b0b2f320..40326fc810e6 100644
--- a/src/shared/hci.c
+++ b/src/shared/hci.c
@@ -45,6 +45,7 @@ struct bt_hci {
struct queue *cmd_queue;
struct queue *rsp_queue;
struct queue *evt_list;
+ struct queue *subevt_list;
struct queue *data_queue;
};
@@ -239,6 +240,21 @@ static void process_notify(void *data, void *user_data)
hdr->plen, evt->user_data);
}
+struct subevt_data {
+ uint8_t subevent;
+ const void *data;
+ uint8_t size;
+};
+
+static void process_subevt_notify(void *data, void *user_data)
+{
+ struct subevt_data *sd = user_data;
+ struct evt *evt = data;
+
+ if (evt->event == sd->subevent)
+ evt->callback(sd->data, sd->size, evt->user_data);
+}
+
static void process_event(struct bt_hci *hci, const void *data, size_t size)
{
const struct bt_hci_evt_hdr *hdr = data;
@@ -275,6 +291,16 @@ static void process_event(struct bt_hci *hci, const void *data, size_t size)
default:
queue_foreach(hci->evt_list, process_notify, (void *) hdr);
+ if (hdr->evt == BT_HCI_EVT_LE_META_EVENT && size > 0) {
+ const uint8_t *params = data;
+ struct subevt_data sd;
+
+ sd.subevent = params[0];
+ sd.data = data + 1;
+ sd.size = size - 1;
+ queue_foreach(hci->subevt_list,
+ process_subevt_notify, &sd);
+ }
break;
}
}
@@ -332,10 +358,12 @@ static struct bt_hci *create_hci(int fd)
hci->cmd_queue = queue_new();
hci->rsp_queue = queue_new();
hci->evt_list = queue_new();
+ hci->subevt_list = queue_new();
hci->data_queue = queue_new();
if (!io_set_read_handler(hci->io, io_read_callback, hci, NULL)) {
queue_destroy(hci->evt_list, NULL);
+ queue_destroy(hci->subevt_list, NULL);
queue_destroy(hci->rsp_queue, NULL);
queue_destroy(hci->cmd_queue, NULL);
queue_destroy(hci->data_queue, NULL);
@@ -458,6 +486,7 @@ void bt_hci_unref(struct bt_hci *hci)
return;
queue_destroy(hci->evt_list, evt_free);
+ queue_destroy(hci->subevt_list, evt_free);
queue_destroy(hci->cmd_queue, cmd_free);
queue_destroy(hci->rsp_queue, cmd_free);
queue_destroy(hci->data_queue, data_free);
@@ -571,7 +600,7 @@ static void update_evt_filter(struct bt_hci *hci)
const struct queue_entry *entry;
struct sock_filter *filters;
struct sock_fprog fprog;
- unsigned int count, i;
+ unsigned int evt_count, subevt_count, count, i;
int fd;
fd = io_get_fd(hci->io);
@@ -582,21 +611,38 @@ static void update_evt_filter(struct bt_hci *hci)
if (hci->is_stream)
return;
- count = queue_length(hci->evt_list);
+ evt_count = queue_length(hci->evt_list);
+ subevt_count = queue_length(hci->subevt_list);
- /* Build filter: load event code, check defaults + registered events.
- * Packet layout for HCI_CHANNEL_RAW: [H4 type (1 byte)][evt code (1)]
- * So event code is at offset 1.
+ /* Filter structure:
+ * Packet layout: [H4 type(1)][evt code(1)][plen(1)][params...]
+ * For LE Meta: params[0] is the subevent code (offset 3 from start)
*
- * Filter structure:
* [0] Load byte at offset 1 (event code)
- * [1] JEQ BT_HCI_EVT_CMD_COMPLETE -> accept
- * [2] JEQ BT_HCI_EVT_CMD_STATUS -> accept
- * [3..3+count-1] JEQ registered_event -> accept
- * [3+count] reject
- * [4+count] accept
+ * [1] JEQ CMD_COMPLETE -> accept
+ * [2] JEQ CMD_STATUS -> accept
+ * [3] JEQ LE_META -> subevent_check (if subevts registered)
+ * [4..4+evt_count-1] JEQ registered_event -> accept
+ * [4+evt_count] reject
+ * -- subevent section (if subevt_count > 0) --
+ * [5+evt_count] Load byte at offset 3 (subevent code)
+ * [6+evt_count..6+evt_count+subevt_count-1] JEQ subevent -> accept
+ * [6+evt_count+subevt_count] reject
+ * -- shared accept --
+ * [last] accept
*/
- filters = malloc(sizeof(*filters) * (count + 5));
+
+ /* Without subevents: 3 (defaults) + evt_count + reject + accept =
+ * evt_count + 5
+ * With subevents: 4 (defaults+LE_META) + evt_count + reject +
+ * 1 (load subevent) + subevt_count + reject + accept
+ */
+ if (subevt_count)
+ count = 4 + evt_count + 1 + 1 + subevt_count + 1 + 1;
+ else
+ count = 3 + evt_count + 1 + 1;
+
+ filters = malloc(sizeof(*filters) * count);
if (!filters)
return;
@@ -606,32 +652,106 @@ static void update_evt_filter(struct bt_hci *hci)
filters[i++] = (struct sock_filter)
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 1);
- /* Check BT_HCI_EVT_CMD_COMPLETE (0x0e) */
- filters[i++] = (struct sock_filter)
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BT_HCI_EVT_CMD_COMPLETE,
- count + 2, 0);
-
- /* Check BT_HCI_EVT_CMD_STATUS (0x0f) */
- filters[i++] = (struct sock_filter)
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BT_HCI_EVT_CMD_STATUS,
- count + 1, 0);
-
- /* Check each registered event */
- entry = queue_get_entries(hci->evt_list);
- while (entry) {
- const struct evt *evt = entry->data;
- unsigned int jump = count - (i - 3);
+ if (subevt_count) {
+ /* accept is at index: count - 1
+ * From instruction at index i, jump_true = (count-1) - (i+1)
+ */
+ /* Check BT_HCI_EVT_CMD_COMPLETE -> accept */
filters[i] = (struct sock_filter)
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, evt->event,
- jump, 0);
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K,
+ BT_HCI_EVT_CMD_COMPLETE,
+ count - 1 - (i + 1), 0);
i++;
- entry = entry->next;
- }
- /* Reject */
- filters[i++] = (struct sock_filter)
- BPF_STMT(BPF_RET | BPF_K, 0);
+ /* Check BT_HCI_EVT_CMD_STATUS -> accept */
+ filters[i] = (struct sock_filter)
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K,
+ BT_HCI_EVT_CMD_STATUS,
+ count - 1 - (i + 1), 0);
+ i++;
+
+ /* Check LE_META -> subevent section
+ * subevent section starts at: 4 + evt_count + 1
+ * (after the evt reject instruction)
+ */
+ filters[i] = (struct sock_filter)
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K,
+ BT_HCI_EVT_LE_META_EVENT,
+ 4 + evt_count + 1 - (i + 1), 0);
+ i++;
+
+ /* Check each registered event -> accept */
+ entry = queue_get_entries(hci->evt_list);
+ while (entry) {
+ const struct evt *evt = entry->data;
+
+ filters[i] = (struct sock_filter)
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K,
+ evt->event,
+ count - 1 - (i + 1), 0);
+ i++;
+ entry = entry->next;
+ }
+
+ /* Reject (for non-matching events) */
+ filters[i++] = (struct sock_filter)
+ BPF_STMT(BPF_RET | BPF_K, 0);
+
+ /* Subevent section: load subevent byte at offset 3 */
+ filters[i++] = (struct sock_filter)
+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 3);
+
+ /* Check each registered subevent -> accept */
+ entry = queue_get_entries(hci->subevt_list);
+ while (entry) {
+ const struct evt *evt = entry->data;
+
+ filters[i] = (struct sock_filter)
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K,
+ evt->event,
+ count - 1 - (i + 1), 0);
+ i++;
+ entry = entry->next;
+ }
+
+ /* Reject (for non-matching subevents) */
+ filters[i++] = (struct sock_filter)
+ BPF_STMT(BPF_RET | BPF_K, 0);
+ } else {
+ /* No subevents - simple filter */
+
+ /* Check BT_HCI_EVT_CMD_COMPLETE -> accept */
+ filters[i] = (struct sock_filter)
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K,
+ BT_HCI_EVT_CMD_COMPLETE,
+ count - 1 - (i + 1), 0);
+ i++;
+
+ /* Check BT_HCI_EVT_CMD_STATUS -> accept */
+ filters[i] = (struct sock_filter)
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K,
+ BT_HCI_EVT_CMD_STATUS,
+ count - 1 - (i + 1), 0);
+ i++;
+
+ /* Check each registered event -> accept */
+ entry = queue_get_entries(hci->evt_list);
+ while (entry) {
+ const struct evt *evt = entry->data;
+
+ filters[i] = (struct sock_filter)
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K,
+ evt->event,
+ count - 1 - (i + 1), 0);
+ i++;
+ entry = entry->next;
+ }
+
+ /* Reject */
+ filters[i++] = (struct sock_filter)
+ BPF_STMT(BPF_RET | BPF_K, 0);
+ }
/* Accept */
filters[i++] = (struct sock_filter)
@@ -744,6 +864,58 @@ bool bt_hci_unregister(struct bt_hci *hci, unsigned int id)
return true;
}
+
+unsigned int bt_hci_register_subevent(struct bt_hci *hci,
+ uint8_t subevent,
+ bt_hci_callback_func_t callback,
+ void *user_data, bt_hci_destroy_func_t destroy)
+{
+ struct evt *evt;
+
+ if (!hci)
+ return 0;
+
+ evt = new0(struct evt, 1);
+ evt->event = subevent;
+
+ if (hci->next_evt_id < 1)
+ hci->next_evt_id = 1;
+
+ evt->id = hci->next_evt_id++;
+
+ evt->callback = callback;
+ evt->destroy = destroy;
+ evt->user_data = user_data;
+
+ if (!queue_push_tail(hci->subevt_list, evt)) {
+ free(evt);
+ return 0;
+ }
+
+ update_evt_filter(hci);
+
+ return evt->id;
+}
+
+bool bt_hci_unregister_subevent(struct bt_hci *hci, unsigned int id)
+{
+ struct evt *evt;
+
+ if (!hci || !id)
+ return false;
+
+ evt = queue_remove_if(hci->subevt_list, match_evt_id,
+ UINT_TO_PTR(id));
+ if (!evt)
+ return false;
+
+ evt_free(evt);
+
+ update_evt_filter(hci);
+
+ return true;
+}
+
bool bt_hci_get_conn_handle(struct bt_hci *hci, const uint8_t *bdaddr,
uint16_t *handle)
{
diff --git a/src/shared/hci.h b/src/shared/hci.h
index 800dc4946b97..5be48577f9db 100644
--- a/src/shared/hci.h
+++ b/src/shared/hci.h
@@ -42,5 +42,11 @@ unsigned int bt_hci_register(struct bt_hci *hci, uint8_t event,
void *user_data, bt_hci_destroy_func_t destroy);
bool bt_hci_unregister(struct bt_hci *hci, unsigned int id);
+unsigned int bt_hci_register_subevent(struct bt_hci *hci,
+ uint8_t subevent,
+ bt_hci_callback_func_t callback,
+ void *user_data, bt_hci_destroy_func_t destroy);
+bool bt_hci_unregister_subevent(struct bt_hci *hci, unsigned int id);
+
bool bt_hci_get_conn_handle(struct bt_hci *hci, const uint8_t *bdaddr,
uint16_t *handle);
--
2.53.0
^ permalink raw reply related
* [PATCH BlueZ v1 4/4] hci-tester: Use bt_hci_register_subevent for LE Meta events
From: Luiz Augusto von Dentz @ 2026-05-01 14:38 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20260501143847.724150-1-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Convert all bt_hci_register(BT_HCI_EVT_LE_META_EVENT) calls to use
bt_hci_register_subevent with the specific subevent code. Update
callbacks to work with data that no longer contains the subevent byte
prefix, since bt_hci_register_subevent strips it before dispatch.
Assisted-by: Claude:claude-opus-4.6
---
tools/hci-tester.c | 59 +++++++++++++---------------------------------
1 file changed, 17 insertions(+), 42 deletions(-)
diff --git a/tools/hci-tester.c b/tools/hci-tester.c
index 79193220feec..b8446ee83ccf 100644
--- a/tools/hci-tester.c
+++ b/tools/hci-tester.c
@@ -407,17 +407,9 @@ static void test_le_rand(const void *test_data)
static void test_le_read_local_pk_complete(const void *data, uint8_t size,
void *user_data)
{
- const uint8_t *event = data;
- const struct bt_hci_evt_le_read_local_pk256_complete *evt;
+ const struct bt_hci_evt_le_read_local_pk256_complete *evt = data;
struct le_keys *keys = user_data;
- if (*event != BT_HCI_EVT_LE_READ_LOCAL_PK256_COMPLETE) {
- tester_warn("Failed Read Local PK256 command");
- tester_test_failed();
- return;
- }
-
- evt = (void *)(event + 1);
if (evt->status) {
tester_warn("HCI Read Local PK complete failed (0x%02x)",
evt->status);
@@ -450,7 +442,8 @@ static void test_le_read_local_pk(const void *test_data)
struct bt_hci_cmd_set_event_mask sem;
struct bt_hci_cmd_le_set_event_mask lsem;
- bt_hci_register(user->hci_ut, BT_HCI_EVT_LE_META_EVENT,
+ bt_hci_register_subevent(user->hci_ut,
+ BT_HCI_EVT_LE_READ_LOCAL_PK256_COMPLETE,
test_le_read_local_pk_complete,
(void *)test_data, NULL);
@@ -480,17 +473,9 @@ static void test_le_read_local_pk(const void *test_data)
static void setup_le_read_local_pk_complete(const void *data, uint8_t size,
void *user_data)
{
- const uint8_t *event = data;
- const struct bt_hci_evt_le_read_local_pk256_complete *evt;
+ const struct bt_hci_evt_le_read_local_pk256_complete *evt = data;
struct le_keys *keys = user_data;
- if (*event != BT_HCI_EVT_LE_READ_LOCAL_PK256_COMPLETE) {
- tester_warn("Failed Read Local PK256 command");
- tester_setup_failed();
- return;
- }
-
- evt = (void *)(event + 1);
if (evt->status) {
tester_warn("HCI Read Local PK complete failed (0x%02x)",
evt->status);
@@ -523,7 +508,8 @@ static void setup_le_generate_dhkey(const void *test_data)
struct bt_hci_cmd_set_event_mask sem;
struct bt_hci_cmd_le_set_event_mask lsem;
- bt_hci_register(user->hci_ut, BT_HCI_EVT_LE_META_EVENT,
+ bt_hci_register_subevent(user->hci_ut,
+ BT_HCI_EVT_LE_READ_LOCAL_PK256_COMPLETE,
setup_le_read_local_pk_complete,
(void *)test_data, NULL);
@@ -554,18 +540,10 @@ static void setup_le_generate_dhkey(const void *test_data)
static void test_le_generate_dhkey_complete(const void *data, uint8_t size,
void *user_data)
{
- const uint8_t *event = data;
- const struct bt_hci_evt_le_generate_dhkey_complete *evt;
+ const struct bt_hci_evt_le_generate_dhkey_complete *evt = data;
struct le_keys *keys = user_data;
uint8_t dhkey[32];
- if (*event != BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE) {
- tester_warn("Failed DHKey generation command");
- tester_test_failed();
- return;
- }
-
- evt = (void *)(event + 1);
if (evt->status) {
tester_warn("HCI Generate DHKey complete failed (0x%02x)",
evt->status);
@@ -613,10 +591,11 @@ static void test_le_generate_dhkey(const void *test_data)
ecc_make_key(cmd.remote_pk256, keys->remote_sk);
- /* Unregister handler for META event */
- bt_hci_unregister(user->hci_ut, 1);
+ /* Unregister handler for PK256 subevent */
+ bt_hci_unregister_subevent(user->hci_ut, 1);
- bt_hci_register(user->hci_ut, BT_HCI_EVT_LE_META_EVENT,
+ bt_hci_register_subevent(user->hci_ut,
+ BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE,
test_le_generate_dhkey_complete, keys,
NULL);
@@ -830,15 +809,10 @@ static void teardown_connection(const void *test_data)
static void test_adv_report(const void *data, uint8_t size, void *user_data)
{
struct user_data *user = tester_get_data();
- uint8_t subevent = *((uint8_t *) data);
- const struct bt_hci_evt_le_adv_report *lar = data + 1;
+ const struct bt_hci_evt_le_adv_report *lar = data;
- switch (subevent) {
- case BT_HCI_EVT_LE_ADV_REPORT:
- if (!memcmp(lar->addr, user->bdaddr_ut, 6))
- tester_setup_complete();
- break;
- }
+ if (!memcmp(lar->addr, user->bdaddr_ut, 6))
+ tester_setup_complete();
}
static void setup_advertising_initiated(const void *test_data)
@@ -850,8 +824,9 @@ static void setup_advertising_initiated(const void *test_data)
struct bt_hci_cmd_le_set_adv_parameters lsap;
struct bt_hci_cmd_le_set_adv_enable lsae;
- bt_hci_register(user->hci_lt, BT_HCI_EVT_LE_META_EVENT,
- test_adv_report, NULL, NULL);
+ bt_hci_register_subevent(user->hci_lt,
+ BT_HCI_EVT_LE_ADV_REPORT,
+ test_adv_report, NULL, NULL);
memset(sem.mask, 0, 8);
sem.mask[1] |= 0x20; /* Command Complete */
--
2.53.0
^ permalink raw reply related
* [PATCH BlueZ v1 1/4] shared/hci: Add BPF filter for registered events
From: Luiz Augusto von Dentz @ 2026-05-01 14:38 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Implement a BPF socket filter in bt_hci_register/bt_hci_unregister that
uses setsockopt(SO_ATTACH_FILTER) to only accept HCI events that have
been registered, plus BT_HCI_EVT_CMD_COMPLETE and BT_HCI_EVT_CMD_STATUS
which are always needed for command response processing.
The filter is rebuilt each time an event is registered or unregistered,
and only applies to non-stream (raw socket) connections.
Assisted-by: Claude:claude-opus-4.6
---
src/shared/hci.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/src/shared/hci.c b/src/shared/hci.c
index 0faa6dea555d..5105b0b2f320 100644
--- a/src/shared/hci.c
+++ b/src/shared/hci.c
@@ -23,6 +23,7 @@
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
+#include <linux/filter.h>
#include "bluetooth/hci.h"
#include "monitor/bt.h"
@@ -565,6 +566,85 @@ bool bt_hci_flush(struct bt_hci *hci)
return true;
}
+static void update_evt_filter(struct bt_hci *hci)
+{
+ const struct queue_entry *entry;
+ struct sock_filter *filters;
+ struct sock_fprog fprog;
+ unsigned int count, i;
+ int fd;
+
+ fd = io_get_fd(hci->io);
+ if (fd < 0)
+ return;
+
+ /* If stream-based (not a raw socket), no BPF filtering needed */
+ if (hci->is_stream)
+ return;
+
+ count = queue_length(hci->evt_list);
+
+ /* Build filter: load event code, check defaults + registered events.
+ * Packet layout for HCI_CHANNEL_RAW: [H4 type (1 byte)][evt code (1)]
+ * So event code is at offset 1.
+ *
+ * Filter structure:
+ * [0] Load byte at offset 1 (event code)
+ * [1] JEQ BT_HCI_EVT_CMD_COMPLETE -> accept
+ * [2] JEQ BT_HCI_EVT_CMD_STATUS -> accept
+ * [3..3+count-1] JEQ registered_event -> accept
+ * [3+count] reject
+ * [4+count] accept
+ */
+ filters = malloc(sizeof(*filters) * (count + 5));
+ if (!filters)
+ return;
+
+ i = 0;
+
+ /* Load event code byte */
+ filters[i++] = (struct sock_filter)
+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 1);
+
+ /* Check BT_HCI_EVT_CMD_COMPLETE (0x0e) */
+ filters[i++] = (struct sock_filter)
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BT_HCI_EVT_CMD_COMPLETE,
+ count + 2, 0);
+
+ /* Check BT_HCI_EVT_CMD_STATUS (0x0f) */
+ filters[i++] = (struct sock_filter)
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BT_HCI_EVT_CMD_STATUS,
+ count + 1, 0);
+
+ /* Check each registered event */
+ entry = queue_get_entries(hci->evt_list);
+ while (entry) {
+ const struct evt *evt = entry->data;
+ unsigned int jump = count - (i - 3);
+
+ filters[i] = (struct sock_filter)
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, evt->event,
+ jump, 0);
+ i++;
+ entry = entry->next;
+ }
+
+ /* Reject */
+ filters[i++] = (struct sock_filter)
+ BPF_STMT(BPF_RET | BPF_K, 0);
+
+ /* Accept */
+ filters[i++] = (struct sock_filter)
+ BPF_STMT(BPF_RET | BPF_K, 0x0fffffff);
+
+ fprog.len = i;
+ fprog.filter = filters;
+
+ setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
+
+ free(filters);
+}
+
unsigned int bt_hci_register(struct bt_hci *hci, uint8_t event,
bt_hci_callback_func_t callback,
void *user_data, bt_hci_destroy_func_t destroy)
@@ -591,6 +671,8 @@ unsigned int bt_hci_register(struct bt_hci *hci, uint8_t event,
return 0;
}
+ update_evt_filter(hci);
+
return evt->id;
}
@@ -657,6 +739,8 @@ bool bt_hci_unregister(struct bt_hci *hci, unsigned int id)
evt_free(evt);
+ update_evt_filter(hci);
+
return true;
}
--
2.53.0
^ permalink raw reply related
* Re: [PATCH BlueZ v1 1/2] shared/util: Add decoding support for HIDS 1.1 UUIDs
From: patchwork-bot+bluetooth @ 2026-05-01 14:10 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <20260430195114.608794-1-luiz.dentz@gmail.com>
Hello:
This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Thu, 30 Apr 2026 15:51:13 -0400 you wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This adds support for HIDS 1.1 SCI UUIDs:
>
> HID SCI Mode(0x2c39)
> HID SCI Information(0x2c3a)
>
> [...]
Here is the summary with links:
- [BlueZ,v1,1/2] shared/util: Add decoding support for HIDS 1.1 UUIDs
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=2128e1c73ff0
- [BlueZ,v1,2/2] monitor: Add decoding support for HIDS 1.1 flags and attributes
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=31e4fb1498f4
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* [bluez/bluez] 2128e1: shared/util: Add decoding support for HIDS 1.1 UUIDs
From: Luiz Augusto von Dentz @ 2026-05-01 14:04 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/master
Home: https://github.com/bluez/bluez
Commit: 2128e1c73ff0c0dffc4869b52a8664cac7560455
https://github.com/bluez/bluez/commit/2128e1c73ff0c0dffc4869b52a8664cac7560455
Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: 2026-04-30 (Thu, 30 Apr 2026)
Changed paths:
M src/shared/util.c
Log Message:
-----------
shared/util: Add decoding support for HIDS 1.1 UUIDs
This adds support for HIDS 1.1 SCI UUIDs:
HID SCI Mode(0x2c39)
HID SCI Information(0x2c3a)
Commit: 31e4fb1498f47dfbf18b414acbbbeac26dcda366
https://github.com/bluez/bluez/commit/31e4fb1498f47dfbf18b414acbbbeac26dcda366
Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: 2026-04-30 (Thu, 30 Apr 2026)
Changed paths:
M monitor/att.c
M src/main.conf
Log Message:
-----------
monitor: Add decoding support for HIDS 1.1 flags and attributes
This adds support for HIDS 1.1 SCI flags and attributes:
> LE-ACL: Handle 2048 flags 0x02 dlen 9
ATT: Read Response (0x0b) len 4
Handle: 0x0021 Type: HID Information (0x2a4a)
Value[4]:
11 01 00 0f ....
bcdHID: 0x0111
bCountryCode: 0x00
Flags: 0x0f
RemoteWake (0x01)
NormallyConnectable (0x02)
SCI Supported (0x04)
SCI Low Power Mode Supported (0x08)
< LE-ACL: Handle 2048 flags 0x00 dlen 7
ATT: Read Request (0x0a) len 2
Handle: 0x003d Type: HID SCI Information (0x2c3a)
> LE-ACL: Handle 2048 flags 0x02 dlen 19
ATT: Read Response (0x0b) len 14
Handle: 0x003d Type: HID SCI Information (0x2c3a)
Value[14]:
08 02 0a 00 14 00 0a 00 08 00 08 00 08 00 ..............
Minimum Supported Connection Interval: 1.000 ms (0x08)
Number of Supported Subgroups: 2
Minimum Connection Interval[0]: 1.250 ms (0x000a)
Maximum Connection Interval[0]: 2.500 ms (0x0014)
Connection Interval Stride[0]: 1.250 ms (0x000a)
Minimum Connection Interval[1]: 1.000 ms (0x0008)
Maximum Connection Interval[1]: 1.000 ms (0x0008)
Connection Interval Stride[1]: 1.000 ms (0x0008)
< LE-ACL: Handle 2048 flags 0x00 dlen 7
ATT: Read Request (0x0a) len 2
Handle: 0x003f Type: HID SCI Mode (0x2c39)
> LE-ACL: Handle 2048 flags 0x02 dlen 6
ATT: Read Response (0x0b) len 1
Handle: 0x003f Type: HID SCI Mode (0x2c39)
Value[1]:
00 .
Mode: None (0x00)
Compare: https://github.com/bluez/bluez/compare/d01616f0c276...31e4fb1498f4
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox