Skip to content

Instantly share code, notes, and snippets.

@peterbudai
Last active April 24, 2020 18:46
Show Gist options
  • Save peterbudai/0f956568004c79d3c92bd8a48f5b2cf1 to your computer and use it in GitHub Desktop.
Save peterbudai/0f956568004c79d3c92bd8a48f5b2cf1 to your computer and use it in GitHub Desktop.
C snippet to check under which name Linux kernel looks for different Bluetooth firmware files listed in https://github.com/winterheart/broadcom-bt-firmware.
I cross-checked the device names, subversions and kernel behavior in devices/bluetooth/btbcm.c (Linux v5.6,
commit dde8010be0a0). The last two columns represent the firmware names the kernel will look for in USB or UART HCI
modes. @ denotes that the device is explicitly listed in kernel, . when the generic naming is used.
Source file name Device vID pID SubVer USB Firmware file UART Firmware file
BCM20702A1-0489-e032.hcd -> BCM20702A1 0489 e032 220e -> @ brcm/BCM20702A1-0489-e032.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0489-e042.hcd -> BCM20702A1 0489 e042 220e -> @ brcm/BCM20702A1-0489-e042.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0489-e046.hcd -> BCM20702A1 0489 e046 220e -> @ brcm/BCM20702A1-0489-e046.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0489-e04f.hcd -> BCM20702A1 0489 e04f 220e -> @ brcm/BCM20702A1-0489-e04f.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0489-e052.hcd -> BCM20702A1 0489 e052 220e -> @ brcm/BCM20702A1-0489-e052.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0489-e059.hcd -> BCM20702A1 0489 e059 220e -> @ brcm/BCM20702A1-0489-e059.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0489-e07a.hcd -> BCM20702A1 0489 e07a 220e -> @ brcm/BCM20702A1-0489-e07a.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0489-e087.hcd -> BCM20702A1 0489 e087 220e -> @ brcm/BCM20702A1-0489-e087.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-04ca-2003.hcd -> BCM20702A1 04ca 2003 220e -> @ brcm/BCM20702A1-04ca-2003.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-04ca-2004.hcd -> BCM20702A1 04ca 2004 220e -> @ brcm/BCM20702A1-04ca-2004.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-04ca-2005.hcd -> BCM20702A1 04ca 2005 220e -> @ brcm/BCM20702A1-04ca-2005.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-04ca-200a.hcd -> BCM20702A1 04ca 200a 220e -> @ brcm/BCM20702A1-04ca-200a.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-04ca-200b.hcd -> BCM20702A1 04ca 200b 220e -> @ brcm/BCM20702A1-04ca-200b.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-04ca-200c.hcd -> BCM20702A1 04ca 200c 220e -> @ brcm/BCM20702A1-04ca-200c.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-04ca-200e.hcd -> BCM20702A1 04ca 200e 220e -> @ brcm/BCM20702A1-04ca-200e.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-04ca-200f.hcd -> BCM20702A1 04ca 200f 220e -> @ brcm/BCM20702A1-04ca-200f.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-050d-065a.hcd -> BCM20702A1 050d 065a 220e -> @ brcm/BCM20702A1-050d-065a.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0930-021e.hcd -> BCM20702A1 0930 021e 220e -> @ brcm/BCM20702A1-0930-021e.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0930-0221.hcd -> BCM20702A1 0930 0221 220e -> @ brcm/BCM20702A1-0930-0221.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0930-0223.hcd -> BCM20702A1 0930 0223 220e -> @ brcm/BCM20702A1-0930-0223.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-2169.hcd -> BCM20702A1 0a5c 2169 220e -> @ brcm/BCM20702A1-0a5c-2169.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-216b.hcd -> BCM20702A1 0a5c 216b 220e -> @ brcm/BCM20702A1-0a5c-216b.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-216f.hcd -> BCM20702A1 0a5c 216f 220e -> @ brcm/BCM20702A1-0a5c-216f.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-21de.hcd -> BCM20702A1 0a5c 21de 220e -> @ brcm/BCM20702A1-0a5c-21de.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-21e1.hcd -> BCM20702A1 0a5c 21e1 220e -> @ brcm/BCM20702A1-0a5c-21e1.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-21e3.hcd -> BCM20702A1 0a5c 21e3 220e -> @ brcm/BCM20702A1-0a5c-21e3.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-21e6.hcd -> BCM20702A1 0a5c 21e6 220e -> @ brcm/BCM20702A1-0a5c-21e6.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-21e8.hcd -> BCM20702A1 0a5c 21e8 220e -> @ brcm/BCM20702A1-0a5c-21e8.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-21ec.hcd -> BCM20702A1 0a5c 21ec 220e -> @ brcm/BCM20702A1-0a5c-21ec.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-21f1.hcd -> BCM20702A1 0a5c 21f1 220e -> @ brcm/BCM20702A1-0a5c-21f1.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-21f3.hcd -> BCM20702A1 0a5c 21f3 220e -> @ brcm/BCM20702A1-0a5c-21f3.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-21f4.hcd -> BCM20702A1 0a5c 21f4 220e -> @ brcm/BCM20702A1-0a5c-21f4.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-21fb.hcd -> BCM20702A1 0a5c 21fb 220e -> @ brcm/BCM20702A1-0a5c-21fb.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-21fd.hcd -> BCM20702A1 0a5c 21fd 220e -> @ brcm/BCM20702A1-0a5c-21fd.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-640b.hcd -> BCM20702A1 0a5c 640b 220e -> @ brcm/BCM20702A1-0a5c-640b.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0a5c-6417.hcd -> BCM20702A1 0a5c 6417 220e -> @ brcm/BCM20702A1-0a5c-6417.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0b05-17b5.hcd -> BCM20702A1 0b05 17b5 220e -> @ brcm/BCM20702A1-0b05-17b5.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0b05-17cb.hcd -> BCM20702A1 0b05 17cb 220e -> @ brcm/BCM20702A1-0b05-17cb.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0b05-17cf.hcd -> BCM20702A1 0b05 17cf 220e -> @ brcm/BCM20702A1-0b05-17cf.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-0b05-180a.hcd -> BCM20702A1 0b05 180a 220e -> @ brcm/BCM20702A1-0b05-180a.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-105b-e066.hcd -> BCM20702A1 105b e066 220e -> @ brcm/BCM20702A1-105b-e066.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-13d3-3384.hcd -> BCM20702A1 13d3 3384 220e -> @ brcm/BCM20702A1-13d3-3384.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-13d3-3392.hcd -> BCM20702A1 13d3 3392 220e -> @ brcm/BCM20702A1-13d3-3392.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-13d3-3404.hcd -> BCM20702A1 13d3 3404 220e -> @ brcm/BCM20702A1-13d3-3404.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-13d3-3411.hcd -> BCM20702A1 13d3 3411 220e -> @ brcm/BCM20702A1-13d3-3411.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-13d3-3413.hcd -> BCM20702A1 13d3 3413 220e -> @ brcm/BCM20702A1-13d3-3413.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-13d3-3418.hcd -> BCM20702A1 13d3 3418 220e -> @ brcm/BCM20702A1-13d3-3418.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-13d3-3435.hcd -> BCM20702A1 13d3 3435 220e -> @ brcm/BCM20702A1-13d3-3435.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-13d3-3456.hcd -> BCM20702A1 13d3 3456 220e -> @ brcm/BCM20702A1-13d3-3456.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-13d3-3517.hcd -> BCM20702A1 13d3 3517 220e -> @ brcm/BCM20702A1-13d3-3517.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-145f-01a3.hcd -> BCM20702A1 145f 01a3 220e -> @ brcm/BCM20702A1-145f-01a3.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-413c-8143.hcd -> BCM20702A1 413c 8143 220e -> @ brcm/BCM20702A1-413c-8143.hcd @ brcm/BCM20702A1.hcd
BCM20702A1-413c-8197.hcd -> BCM20702A1 413c 8197 220e -> @ brcm/BCM20702A1-413c-8197.hcd @ brcm/BCM20702A1.hcd
-> https://google.com/search?q=%22Direct+firmware+load+for+brcm/BCM20702A1%22
The device is present in both USB and UART list. However, only the USB file name appears in search results, so we keep
that.
Source file name Device vID pID SubVer USB Firmware file UART Firmware file
BCM20702B0-19ff-0239.hcd -> BCM20702B0 19ff 0239 410e -> @ brcm/BCM20702B0-19ff-0239.hcd @ brcm/BCM43341B0.hcd
-> https://google.com/search?q=%22Direct+firmware+load+for+brcm/BCM20702B0%22
https://google.com/search?q=%22Direct+firmware+load+for+brcm/BCM43341B0%22
The device is present in both USB and UART list, although with different device names (maybe a bug in kernel, or the
same device was marketed under multiple names). Both file names appear in search results, so we keep the USB format.
We may also create a copy under the UART name, however it may break when a new variant of this device is added.
Source file name Device vID pID SubVer USB Firmware file UART Firmware file
BCM20703A1-0489-e0a1.hcd -> BCM20703A1 0489 e0a1 0000 -> . brcm/BCM-0489-e0a1.hcd . brcm/BCM.hcd
BCM20703A1-0a5c-6410.hcd -> BCM20703A1 0a5c 6410 0000 -> . brcm/BCM-0a5c-6410.hcd . brcm/BCM.hcd
BCM20703A1-0a5c-7460.hcd -> BCM20703A1 0a5c 7460 0000 -> . brcm/BCM-0a5c-7460.hcd . brcm/BCM.hcd
BCM20703A1-0bb4-0306.hcd -> BCM20703A1 0bb4 0306 0000 -> . brcm/BCM-0bb4-0306.hcd . brcm/BCM.hcd
-> https://google.com/search?q=%22Direct+firmware+load+for+brcm/BCM20703A1%22
This device is not listed in kernel, so it will look for firmware under a different name. Search results confirm this.
The files should be renamed to the shorter USB format, and it can be done unambiguously.
Source file name Device vID pID SubVer USB Firmware file UART Firmware file
BCM43142A0-0489-e055.hcd -> BCM43142A0 0489 e055 210b -> @ brcm/BCM43142A0-0489-e055.hcd . brcm/BCM.hcd
BCM43142A0-0489-e062.hcd -> BCM43142A0 0489 e062 210b -> @ brcm/BCM43142A0-0489-e062.hcd . brcm/BCM.hcd
BCM43142A0-0489-e096.hcd -> BCM43142A0 0489 e096 210b -> @ brcm/BCM43142A0-0489-e096.hcd . brcm/BCM.hcd
BCM43142A0-04ca-2006.hcd -> BCM43142A0 04ca 2006 210b -> @ brcm/BCM43142A0-04ca-2006.hcd . brcm/BCM.hcd
BCM43142A0-04ca-2007.hcd -> BCM43142A0 04ca 2007 210b -> @ brcm/BCM43142A0-04ca-2007.hcd . brcm/BCM.hcd
BCM43142A0-04ca-2009.hcd -> BCM43142A0 04ca 2009 210b -> @ brcm/BCM43142A0-04ca-2009.hcd . brcm/BCM.hcd
BCM43142A0-04ca-2012.hcd -> BCM43142A0 04ca 2012 210b -> @ brcm/BCM43142A0-04ca-2012.hcd . brcm/BCM.hcd
BCM43142A0-04f2-b49d.hcd -> BCM43142A0 04f2 b49d 210b -> @ brcm/BCM43142A0-04f2-b49d.hcd . brcm/BCM.hcd
BCM43142A0-04f2-b4a1.hcd -> BCM43142A0 04f2 b4a1 210b -> @ brcm/BCM43142A0-04f2-b4a1.hcd . brcm/BCM.hcd
BCM43142A0-0930-021f.hcd -> BCM43142A0 0930 021f 210b -> @ brcm/BCM43142A0-0930-021f.hcd . brcm/BCM.hcd
BCM43142A0-0930-0225.hcd -> BCM43142A0 0930 0225 210b -> @ brcm/BCM43142A0-0930-0225.hcd . brcm/BCM.hcd
BCM43142A0-0930-0226.hcd -> BCM43142A0 0930 0226 210b -> @ brcm/BCM43142A0-0930-0226.hcd . brcm/BCM.hcd
BCM43142A0-0a5c-2167.hcd -> BCM43142A0 0a5c 2167 210b -> @ brcm/BCM43142A0-0a5c-2167.hcd . brcm/BCM.hcd
BCM43142A0-0a5c-216a.hcd -> BCM43142A0 0a5c 216a 210b -> @ brcm/BCM43142A0-0a5c-216a.hcd . brcm/BCM.hcd
BCM43142A0-0a5c-216c.hcd -> BCM43142A0 0a5c 216c 210b -> @ brcm/BCM43142A0-0a5c-216c.hcd . brcm/BCM.hcd
BCM43142A0-0a5c-216d.hcd -> BCM43142A0 0a5c 216d 210b -> @ brcm/BCM43142A0-0a5c-216d.hcd . brcm/BCM.hcd
BCM43142A0-0a5c-21d3.hcd -> BCM43142A0 0a5c 21d3 210b -> @ brcm/BCM43142A0-0a5c-21d3.hcd . brcm/BCM.hcd
BCM43142A0-0a5c-21d6.hcd -> BCM43142A0 0a5c 21d6 210b -> @ brcm/BCM43142A0-0a5c-21d6.hcd . brcm/BCM.hcd
BCM43142A0-0a5c-21d7.hcd -> BCM43142A0 0a5c 21d7 210b -> @ brcm/BCM43142A0-0a5c-21d7.hcd . brcm/BCM.hcd
BCM43142A0-0a5c-21d8.hcd -> BCM43142A0 0a5c 21d8 210b -> @ brcm/BCM43142A0-0a5c-21d8.hcd . brcm/BCM.hcd
BCM43142A0-0a5c-21dc.hcd -> BCM43142A0 0a5c 21dc 210b -> @ brcm/BCM43142A0-0a5c-21dc.hcd . brcm/BCM.hcd
BCM43142A0-0a5c-21fe.hcd -> BCM43142A0 0a5c 21fe 210b -> @ brcm/BCM43142A0-0a5c-21fe.hcd . brcm/BCM.hcd
BCM43142A0-105b-e065.hcd -> BCM43142A0 105b e065 210b -> @ brcm/BCM43142A0-105b-e065.hcd . brcm/BCM.hcd
BCM43142A0-13d3-3388.hcd -> BCM43142A0 13d3 3388 210b -> @ brcm/BCM43142A0-13d3-3388.hcd . brcm/BCM.hcd
BCM43142A0-13d3-3389.hcd -> BCM43142A0 13d3 3389 210b -> @ brcm/BCM43142A0-13d3-3389.hcd . brcm/BCM.hcd
BCM43142A0-13d3-3427.hcd -> BCM43142A0 13d3 3427 210b -> @ brcm/BCM43142A0-13d3-3427.hcd . brcm/BCM.hcd
BCM43142A0-13d3-3482.hcd -> BCM43142A0 13d3 3482 210b -> @ brcm/BCM43142A0-13d3-3482.hcd . brcm/BCM.hcd
BCM43142A0-13d3-3484.hcd -> BCM43142A0 13d3 3484 210b -> @ brcm/BCM43142A0-13d3-3484.hcd . brcm/BCM.hcd
BCM43142A0-185f-2167.hcd -> BCM43142A0 185f 2167 210b -> @ brcm/BCM43142A0-185f-2167.hcd . brcm/BCM.hcd
-> https://google.com/search?q=%22Direct+firmware+load+for+brcm/BCM43142A0%22
This device is present only in the USB list, and search results confirm this. We should keep the original name.
Source file name Device vID pID SubVer USB Firmware file UART Firmware file
BCM4335C0-0489-e079.hcd -> BCM4335C0 0489 e079 6109 -> @ brcm/BCM4335C0-0489-e079.hcd @ brcm/BCM4335C0.hcd
BCM4335C0-04ca-2016.hcd -> BCM4335C0 04ca 2016 6109 -> @ brcm/BCM4335C0-04ca-2016.hcd @ brcm/BCM4335C0.hcd
BCM4335C0-0930-0229.hcd -> BCM4335C0 0930 0229 6109 -> @ brcm/BCM4335C0-0930-0229.hcd @ brcm/BCM4335C0.hcd
BCM4335C0-0a5c-2168.hcd -> BCM4335C0 0a5c 2168 6109 -> @ brcm/BCM4335C0-0a5c-2168.hcd @ brcm/BCM4335C0.hcd
BCM4335C0-0a5c-216e.hcd -> BCM4335C0 0a5c 216e 6109 -> @ brcm/BCM4335C0-0a5c-216e.hcd @ brcm/BCM4335C0.hcd
-> https://google.com/search?q=%22Direct+firmware+load+for+brcm/BCM4335C0%22
The device is present in both USB and UART list. However, only the UART file name appears in search results, so we
should rename to that format. However, that naming would be ambiguous, multiple files cannot have the same name, so
need keep the original name. We may notify the users via a message that they should check dmesg and rename the files
accordingly.
Source file name Device vID pID SubVer USB Firmware file UART Firmware file
BCM4350C5-0a5c-6412.hcd -> BCM4350C5 0a5c 6412 0000 -> . brcm/BCM-0a5c-6412.hcd . brcm/BCM.hcd
BCM4350C5-0a5c-6413.hcd -> BCM4350C5 0a5c 6413 0000 -> . brcm/BCM-0a5c-6413.hcd . brcm/BCM.hcd
BCM4350C5-0a5c-6414.hcd -> BCM4350C5 0a5c 6414 0000 -> . brcm/BCM-0a5c-6414.hcd . brcm/BCM.hcd
-> https://google.com/search?q=%22Direct+firmware+load+for+brcm/BCM4350C5%22
This device is not listed in kernel, so it will look for firmware under a different name. Search results confirm this.
The files should be renamed to the shorter USB format, and it can be done unambiguously.
Source file name Device vID pID SubVer USB Firmware file UART Firmware file
BCM4356A2-0489-e097.hcd -> BCM4356A2 0489 e097 230f -> @ brcm/BCM4354A2-0489-e097.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-04ca-2013.hcd -> BCM4356A2 04ca 2013 230f -> @ brcm/BCM4354A2-04ca-2013.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-04ca-2014.hcd -> BCM4356A2 04ca 2014 230f -> @ brcm/BCM4354A2-04ca-2014.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-04f2-b4a2.hcd -> BCM4356A2 04f2 b4a2 230f -> @ brcm/BCM4354A2-04f2-b4a2.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-0a5c-640a.hcd -> BCM4356A2 0a5c 640a 230f -> @ brcm/BCM4354A2-0a5c-640a.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-0a5c-640e.hcd -> BCM4356A2 0a5c 640e 230f -> @ brcm/BCM4354A2-0a5c-640e.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-0a5c-6419.hcd -> BCM4356A2 0a5c 6419 230f -> @ brcm/BCM4354A2-0a5c-6419.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-0a5c-6420.hcd -> BCM4356A2 0a5c 6420 230f -> @ brcm/BCM4354A2-0a5c-6420.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-0b05-181d.hcd -> BCM4356A2 0b05 181d 230f -> @ brcm/BCM4354A2-0b05-181d.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-13d3-3473.hcd -> BCM4356A2 13d3 3473 230f -> @ brcm/BCM4354A2-13d3-3473.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-13d3-3485.hcd -> BCM4356A2 13d3 3485 230f -> @ brcm/BCM4354A2-13d3-3485.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-13d3-3488.hcd -> BCM4356A2 13d3 3488 230f -> @ brcm/BCM4354A2-13d3-3488.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-13d3-3492.hcd -> BCM4356A2 13d3 3492 230f -> @ brcm/BCM4354A2-13d3-3492.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-2b54-5600.hcd -> BCM4356A2 2b54 5600 230f -> @ brcm/BCM4354A2-2b54-5600.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-2b54-5601.hcd -> BCM4356A2 2b54 5601 230f -> @ brcm/BCM4354A2-2b54-5601.hcd @ brcm/BCM4356A2.hcd
BCM4356A2-2b54-5602.hcd -> BCM4356A2 2b54 5602 230f -> @ brcm/BCM4354A2-2b54-5602.hcd @ brcm/BCM4356A2.hcd
-> https://google.com/search?q=%22Direct+firmware+load+for+brcm/BCM4356A2%22
https://google.com/search?q=%22Direct+firmware+load+for+brcm/BCM4354A2%22
The device is present in both USB and UART list, although with different device names (maybe a bug in kernel).
Both file names appear in search results, so we keep the USB format. We could also create copies under the UART name,
but that naming would be ambiguous, multiple files cannot have the same name, so it's not possible. We may notify the
users via a message that they should check dmesg and rename the files accordingly.
Source file name Device vID pID SubVer USB Firmware file UART Firmware file
BCM4371C2-0a5c-6418.hcd -> BCM4371C2 0a5c 6418 0000 -> . brcm/BCM-0a5c-6418.hcd . brcm/BCM.hcd
BCM4371C2-13d3-3504.hcd -> BCM4371C2 13d3 3504 0000 -> . brcm/BCM-13d3-3504.hcd . brcm/BCM.hcd
BCM4371C2-13d3-3508.hcd -> BCM4371C2 13d3 3508 0000 -> . brcm/BCM-13d3-3508.hcd . brcm/BCM.hcd
-> https://google.com/search?q=%22Direct+firmware+load+for+brcm/BCM4371C2%22
The device is not listed in kernel, so the generic firmware naming applies. Unfortunately, only the UART file name
appears in search results, so we should rename to that format. However, that naming would be ambiguous, multiple files
cannot have the same name, so need keep the original name. We may notify the users via a message that they should
check dmesg and rename the files accordingly.
// To run: gcc -o btbcm_test btbcm_test.c && ./btbcm_test > btbcm.txt
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
// These structures are from Linux kernel v5.6 source code
// drivers/bluetooth/btbcm.c (commit dde8010be0a0)
struct bcm_subver_table {
uint16_t subver;
const char* name;
};
static const struct bcm_subver_table bcm_uart_subver_table[] = {
{ 0x4103, "BCM4330B1" }, /* 002.001.003 */
{ 0x410d, "BCM4334B0" }, /* 002.001.013 */
{ 0x410e, "BCM43341B0" }, /* 002.001.014 */
{ 0x4204, "BCM2076B1" }, /* 002.002.004 */
{ 0x4406, "BCM4324B3" }, /* 002.004.006 */
{ 0x6109, "BCM4335C0" }, /* 003.001.009 */
{ 0x610c, "BCM4354" }, /* 003.001.012 */
{ 0x2122, "BCM4343A0" }, /* 001.001.034 */
{ 0x2209, "BCM43430A1" }, /* 001.002.009 */
{ 0x6119, "BCM4345C0" }, /* 003.001.025 */
{ 0x6606, "BCM4345C5" }, /* 003.006.006 */
{ 0x230f, "BCM4356A2" }, /* 001.003.015 */
{ 0x220e, "BCM20702A1" }, /* 001.002.014 */
{ 0x4217, "BCM4329B1" }, /* 002.002.023 */
{ 0x6106, "BCM4359C0" }, /* 003.001.006 */
{ 0x4106, "BCM4335A0" }, /* 002.001.006 */
{ }
};
static const struct bcm_subver_table bcm_usb_subver_table[] = {
{ 0x210b, "BCM43142A0" }, /* 001.001.011 */
{ 0x2112, "BCM4314A0" }, /* 001.001.018 */
{ 0x2118, "BCM20702A0" }, /* 001.001.024 */
{ 0x2126, "BCM4335A0" }, /* 001.001.038 */
{ 0x220e, "BCM20702A1" }, /* 001.002.014 */
{ 0x230f, "BCM4354A2" }, /* 001.003.015 */
{ 0x4106, "BCM4335B0" }, /* 002.001.006 */
{ 0x410e, "BCM20702B0" }, /* 002.001.014 */
{ 0x6109, "BCM4335C0" }, /* 003.001.009 */
{ 0x610c, "BCM4354" }, /* 003.001.012 */
{ }
};
enum hci_dev {
HCI_USB,
HCI_UART,
};
int btbcm_initialize(enum hci_dev hdev, char *fw_name, size_t len,
uint16_t subver, uint16_t vid, uint16_t pid)
{
// This function was stripped down with care, only the firmware name calculation
// part was kept so it can compile on its own out of the kernel tree
const char *hw_name = "BCM";
const struct bcm_subver_table *bcm_subver_table;
int i;
bcm_subver_table = (hdev == HCI_USB) ? bcm_usb_subver_table : bcm_uart_subver_table;
for (i = 0; bcm_subver_table[i].name; i++) {
if (subver == bcm_subver_table[i].subver) {
hw_name = bcm_subver_table[i].name;
break;
}
}
if (hdev == HCI_USB) {
snprintf(fw_name, len, "brcm/%s-%4.4x-%4.4x.hcd", hw_name, vid, pid);
} else {
snprintf(fw_name, len, "brcm/%s.hcd", hw_name);
}
return 0;
}
// This is the tester code that produces btbcm.txt without the comments
void g(char* h, int u1, int u2, char* w1, char* w2) {
char* x;
char q[200], Q[200] = "";
sprintf(Q, "https://google.com/search?q=%%22Direct+firmware+load+for+brcm/%s%%22", h);
printf("\n -> %s\n", Q);
if(u1) {
x = strchr(w1, '-');
if(!x) x = strchr(w1, '.');
*x = '\0';
if(strlen(w1) > 3) {
sprintf(q, "https://google.com/search?q=%%22Direct+firmware+load+for+%s%%22", w1);
if(strcmp(Q,q)) printf(" %s\n", q);
}
}
if(u2) {
x = strchr(w2, '-');
if(!x) x = strchr(w2, '.');
*x = '\0';
if(strlen(w2) > 3) {
sprintf(q, "https://google.com/search?q=%%22Direct+firmware+load+for+%s%%22", w2);
if(strcmp(Q,q)) printf(" %s\n", q);
}
}
printf("\n");
}
int main(int argc, const char* argv[])
{
FILE* f;
char l[50], h[20] = "BCM", H[20]="", w1[50], w2[50];
uint16_t s, v, p;
int i, u1, u2;
const struct bcm_subver_table* b;
f = fopen("btfw.txt", "r"); // List of file names in the firmware package
while(fgets(l, sizeof(l), f)) {
sscanf(l, "BCM%[0-9A-Z]-%hx-%hx.hcd\n", h+3, &v, &p);
l[strlen(l)-1] = '\0';
if(strcmp(H,h)) {
if(strlen(H) != 0) g(H, u1, u2, w1, w2);
printf("%-25s %-10s %-4s %-4s %-4s %-32s %-32s\n", "Source file name", "Device", "vID", "pID", "SubVer", "USB Firmware file", "UART Firmware file");
strcpy(H,h);
}
s = 0;
u1 = 0;
for (i = 0; (b = &bcm_usb_subver_table[i])->name; i++) {
if(strcmp(h, b->name) == 0) {
assert(s == 0 || s == b->subver);
s = b->subver;
u1 = 1;
}
}
u2 = 0;
for (i = 0; (b = &bcm_uart_subver_table[i])->name; i++) {
if(strcmp(h, b->name) == 0) {
assert(s == 0 || s == b->subver);
s = b->subver;
u2 = 1;
}
}
for (i = 0; (b = &bcm_usb_subver_table[i])->name; i++) {
if(s == b->subver) {
u1 = 1;
}
}
for (i = 0; (b = &bcm_uart_subver_table[i])->name; i++) {
if(s == b->subver) {
u2 = 1;
}
}
btbcm_initialize(HCI_USB, w1, sizeof(w1), s, v, p);
btbcm_initialize(HCI_UART, w2, sizeof(w2), s, v, p);
printf("%-25s -> %-10s %04x %04x %04x -> %c %-30s %c %-30s\n", l, h, v, p, s, u1?'@':'.', w1, u2?'@':'.', w2);
}
g(h, u1, u2, w1, w2);
return 0;
}
BCM20702A1-0489-e032.hcd
BCM20702A1-0489-e042.hcd
BCM20702A1-0489-e046.hcd
BCM20702A1-0489-e04f.hcd
BCM20702A1-0489-e052.hcd
BCM20702A1-0489-e059.hcd
BCM20702A1-0489-e07a.hcd
BCM20702A1-0489-e087.hcd
BCM20702A1-04ca-2003.hcd
BCM20702A1-04ca-2004.hcd
BCM20702A1-04ca-2005.hcd
BCM20702A1-04ca-200a.hcd
BCM20702A1-04ca-200b.hcd
BCM20702A1-04ca-200c.hcd
BCM20702A1-04ca-200e.hcd
BCM20702A1-04ca-200f.hcd
BCM20702A1-050d-065a.hcd
BCM20702A1-0930-021e.hcd
BCM20702A1-0930-0221.hcd
BCM20702A1-0930-0223.hcd
BCM20702A1-0a5c-2169.hcd
BCM20702A1-0a5c-216b.hcd
BCM20702A1-0a5c-216f.hcd
BCM20702A1-0a5c-21de.hcd
BCM20702A1-0a5c-21e1.hcd
BCM20702A1-0a5c-21e3.hcd
BCM20702A1-0a5c-21e6.hcd
BCM20702A1-0a5c-21e8.hcd
BCM20702A1-0a5c-21ec.hcd
BCM20702A1-0a5c-21f1.hcd
BCM20702A1-0a5c-21f3.hcd
BCM20702A1-0a5c-21f4.hcd
BCM20702A1-0a5c-21fb.hcd
BCM20702A1-0a5c-21fd.hcd
BCM20702A1-0a5c-640b.hcd
BCM20702A1-0a5c-6417.hcd
BCM20702A1-0b05-17b5.hcd
BCM20702A1-0b05-17cb.hcd
BCM20702A1-0b05-17cf.hcd
BCM20702A1-0b05-180a.hcd
BCM20702A1-105b-e066.hcd
BCM20702A1-13d3-3384.hcd
BCM20702A1-13d3-3392.hcd
BCM20702A1-13d3-3404.hcd
BCM20702A1-13d3-3411.hcd
BCM20702A1-13d3-3413.hcd
BCM20702A1-13d3-3418.hcd
BCM20702A1-13d3-3435.hcd
BCM20702A1-13d3-3456.hcd
BCM20702A1-13d3-3517.hcd
BCM20702A1-145f-01a3.hcd
BCM20702A1-413c-8143.hcd
BCM20702A1-413c-8197.hcd
BCM20702B0-19ff-0239.hcd
BCM20703A1-0489-e0a1.hcd
BCM20703A1-0a5c-6410.hcd
BCM20703A1-0a5c-7460.hcd
BCM20703A1-0bb4-0306.hcd
BCM43142A0-0489-e055.hcd
BCM43142A0-0489-e062.hcd
BCM43142A0-0489-e096.hcd
BCM43142A0-04ca-2006.hcd
BCM43142A0-04ca-2007.hcd
BCM43142A0-04ca-2009.hcd
BCM43142A0-04ca-2012.hcd
BCM43142A0-04f2-b49d.hcd
BCM43142A0-04f2-b4a1.hcd
BCM43142A0-0930-021f.hcd
BCM43142A0-0930-0225.hcd
BCM43142A0-0930-0226.hcd
BCM43142A0-0a5c-2167.hcd
BCM43142A0-0a5c-216a.hcd
BCM43142A0-0a5c-216c.hcd
BCM43142A0-0a5c-216d.hcd
BCM43142A0-0a5c-21d3.hcd
BCM43142A0-0a5c-21d6.hcd
BCM43142A0-0a5c-21d7.hcd
BCM43142A0-0a5c-21d8.hcd
BCM43142A0-0a5c-21dc.hcd
BCM43142A0-0a5c-21fe.hcd
BCM43142A0-105b-e065.hcd
BCM43142A0-13d3-3388.hcd
BCM43142A0-13d3-3389.hcd
BCM43142A0-13d3-3427.hcd
BCM43142A0-13d3-3482.hcd
BCM43142A0-13d3-3484.hcd
BCM43142A0-185f-2167.hcd
BCM4335C0-0489-e079.hcd
BCM4335C0-04ca-2016.hcd
BCM4335C0-0930-0229.hcd
BCM4335C0-0a5c-2168.hcd
BCM4335C0-0a5c-216e.hcd
BCM4350C5-0a5c-6412.hcd
BCM4350C5-0a5c-6413.hcd
BCM4350C5-0a5c-6414.hcd
BCM4356A2-0489-e097.hcd
BCM4356A2-04ca-2013.hcd
BCM4356A2-04ca-2014.hcd
BCM4356A2-04f2-b4a2.hcd
BCM4356A2-0a5c-640a.hcd
BCM4356A2-0a5c-640e.hcd
BCM4356A2-0a5c-6419.hcd
BCM4356A2-0a5c-6420.hcd
BCM4356A2-0b05-181d.hcd
BCM4356A2-13d3-3473.hcd
BCM4356A2-13d3-3485.hcd
BCM4356A2-13d3-3488.hcd
BCM4356A2-13d3-3492.hcd
BCM4356A2-2b54-5600.hcd
BCM4356A2-2b54-5601.hcd
BCM4356A2-2b54-5602.hcd
BCM4371C2-0a5c-6418.hcd
BCM4371C2-13d3-3504.hcd
BCM4371C2-13d3-3508.hcd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment