Skip to content

Commit 0b1a566

Browse files
beriberikixclaude
andcommitted
src/cyw43_ctrl: Lock the bus across BT HCI read/write.
cyw43_bluetooth_hci_read() and cyw43_bluetooth_hci_write() call cyw43_btbus_read()/cyw43_btbus_write() without holding the cyw43 bus lock. The BT shared bus runs over the same gSPI/SDIO backplane as WiFi, so a caller that does not already serialise against WiFi will interleave WiFi and BT transfers on the bus. The btstack HCI transport in pico-sdk already wraps these calls in CYW43_THREAD_ENTER/EXIT, so it is unaffected. But any other consumer that calls the BT HCI API directly (e.g. a non-btstack or multi-threaded port) is left unprotected. Take CYW43_THREAD_ENTER across the whole transfer so the functions are self-serialising. The lock is recursive, so the existing wrapping in the btstack transport and the nested cyw43_ensure_bt_up() continue to work unchanged. Signed-off-by: Jonathan Beri <jmberi@gmail.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 055d642 commit 0b1a566

1 file changed

Lines changed: 13 additions & 4 deletions

File tree

src/cyw43_ctrl.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -782,30 +782,39 @@ int cyw43_bluetooth_hci_init(void) {
782782
// Read data
783783
int cyw43_bluetooth_hci_read(uint8_t *buf, uint32_t max_size, uint32_t *len) {
784784
cyw43_t *self = &cyw43_state;
785+
// Hold the bus lock across the whole transfer: the BT shared bus runs over
786+
// the same gSPI/SDIO backplane as WiFi, so a caller that does not already
787+
// serialise against WiFi (i.e. anything other than the btstack transport)
788+
// would otherwise interleave WiFi and BT transfers on the bus.
789+
CYW43_THREAD_ENTER;
785790
int ret = cyw43_ensure_bt_up(self);
786791
if (ret) {
792+
CYW43_THREAD_EXIT;
787793
return ret;
788794
}
789795
ret = cyw43_btbus_read(buf, max_size, len);
790796
if (ret) {
791797
CYW43_PRINTF("cyw43_bluetooth_hci_read: failed to read from shared bus\n");
792-
return ret;
793798
}
794-
return 0;
799+
CYW43_THREAD_EXIT;
800+
return ret;
795801
}
796802

797803
// Write data, buffer needs to include space for a 4 byte header and include this in len
798804
int cyw43_bluetooth_hci_write(uint8_t *buf, size_t len) {
799805
cyw43_t *self = &cyw43_state;
806+
// See cyw43_bluetooth_hci_read: hold the bus lock across the whole transfer.
807+
CYW43_THREAD_ENTER;
800808
int ret = cyw43_ensure_bt_up(self);
801809
if (ret) {
810+
CYW43_THREAD_EXIT;
802811
return ret;
803812
}
804813
ret = cyw43_btbus_write(buf, len);
805814
if (ret) {
806815
CYW43_PRINTF("cyw43_bluetooth_hci_write: failed to write to shared bus\n");
807-
return ret;
808816
}
809-
return 0;
817+
CYW43_THREAD_EXIT;
818+
return ret;
810819
}
811820
#endif

0 commit comments

Comments
 (0)