Skip to content

Commit afcb336

Browse files
jwrdegoedeVudentz
authored andcommitted
Bluetooth: hci_event: Fix vendor (unknown) opcode status handling
Commit c8992cf ("Bluetooth: hci_event: Use of a function table to handle Command Complete") was (presumably) meant to only refactor things without any functional changes. But it does have one undesirable side-effect, before *status would always be set to skb->data[0] and it might be overridden by some of the opcode specific handling. While now it always set by the opcode specific handlers. This means that if the opcode is not known *status does not get set any more at all! This behavior change has broken bluetooth support for BCM4343A0 HCIs, the hci_bcm.c code tries to configure UART attached HCIs at a higher baudraute using vendor specific opcodes. The BCM4343A0 does not support this and this used to simply fail: [ 25.646442] Bluetooth: hci0: BCM: failed to write clock (-56) [ 25.646481] Bluetooth: hci0: Failed to set baudrate After which things would continue with the initial baudraute. But now that hci_cmd_complete_evt() no longer sets status for unknown opcodes *status is left at 0. This causes the hci_bcm.c code to think the baudraute has been changed on the HCI side and to also adjust the UART baudrate, after which communication with the HCI is broken, leading to: [ 28.579042] Bluetooth: hci0: command 0x0c03 tx timeout [ 36.961601] Bluetooth: hci0: BCM: Reset failed (-110) And non working bluetooth. Fix this by restoring the previous default "*status = skb->data[0]" handling for unknown opcodes. Fixes: c8992cf ("Bluetooth: hci_event: Use of a function table to handle Command Complete") Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
1 parent 651cd3d commit afcb336

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

net/bluetooth/hci_event.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4179,6 +4179,17 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data,
41794179
}
41804180
}
41814181

4182+
if (i == ARRAY_SIZE(hci_cc_table)) {
4183+
/* Unknown opcode, assume byte 0 contains the status, so
4184+
* that e.g. __hci_cmd_sync() properly returns errors
4185+
* for vendor specific commands send by HCI drivers.
4186+
* If a vendor doesn't actually follow this convention we may
4187+
* need to introduce a vendor CC table in order to properly set
4188+
* the status.
4189+
*/
4190+
*status = skb->data[0];
4191+
}
4192+
41824193
handle_cmd_cnt_and_timer(hdev, ev->ncmd);
41834194

41844195
hci_req_cmd_complete(hdev, *opcode, *status, req_complete,

0 commit comments

Comments
 (0)