Skip to content

Commit c9209b2

Browse files
apusakaVudentz
authored andcommitted
Bluetooth: btusb: Introduce generic USB reset
On cmd_timeout with no reset_gpio, reset the USB port as a last resort. This patch changes the behavior of btusb_intel_cmd_timeout and btusb_rtl_cmd_timeout. Signed-off-by: Archie Pusaka <[email protected]> Reviewed-by: Abhishek Pandit-Subedi <[email protected]> Reviewed-by: Ying Hsu <[email protected]> Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent f9c5cbd commit c9209b2

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

drivers/bluetooth/btusb.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,28 @@ struct btusb_data {
696696
unsigned cmd_timeout_cnt;
697697
};
698698

699+
static void btusb_reset(struct hci_dev *hdev)
700+
{
701+
struct btusb_data *data;
702+
int err;
703+
704+
if (hdev->reset) {
705+
hdev->reset(hdev);
706+
return;
707+
}
708+
709+
data = hci_get_drvdata(hdev);
710+
/* This is not an unbalanced PM reference since the device will reset */
711+
err = usb_autopm_get_interface(data->intf);
712+
if (err) {
713+
bt_dev_err(hdev, "Failed usb_autopm_get_interface: %d", err);
714+
return;
715+
}
716+
717+
bt_dev_err(hdev, "Resetting usb device.");
718+
usb_queue_reset_device(data->intf);
719+
}
720+
699721
static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
700722
{
701723
struct btusb_data *data = hci_get_drvdata(hdev);
@@ -705,7 +727,7 @@ static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
705727
return;
706728

707729
if (!reset_gpio) {
708-
bt_dev_err(hdev, "No way to reset. Ignoring and continuing");
730+
btusb_reset(hdev);
709731
return;
710732
}
711733

@@ -736,7 +758,7 @@ static void btusb_rtl_cmd_timeout(struct hci_dev *hdev)
736758
return;
737759

738760
if (!reset_gpio) {
739-
bt_dev_err(hdev, "No gpio to reset Realtek device, ignoring");
761+
btusb_reset(hdev);
740762
return;
741763
}
742764

@@ -761,7 +783,6 @@ static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
761783
{
762784
struct btusb_data *data = hci_get_drvdata(hdev);
763785
struct gpio_desc *reset_gpio = data->reset_gpio;
764-
int err;
765786

766787
if (++data->cmd_timeout_cnt < 5)
767788
return;
@@ -787,13 +808,7 @@ static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
787808
return;
788809
}
789810

790-
bt_dev_err(hdev, "Multiple cmd timeouts seen. Resetting usb device.");
791-
/* This is not an unbalanced PM reference since the device will reset */
792-
err = usb_autopm_get_interface(data->intf);
793-
if (!err)
794-
usb_queue_reset_device(data->intf);
795-
else
796-
bt_dev_err(hdev, "Failed usb_autopm_get_interface with %d", err);
811+
btusb_reset(hdev);
797812
}
798813

799814
static inline void btusb_free_frags(struct btusb_data *data)

include/net/bluetooth/hci_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,7 @@ struct hci_dev {
659659
int (*set_diag)(struct hci_dev *hdev, bool enable);
660660
int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr);
661661
void (*cmd_timeout)(struct hci_dev *hdev);
662+
void (*reset)(struct hci_dev *hdev);
662663
bool (*wakeup)(struct hci_dev *hdev);
663664
int (*set_quality_report)(struct hci_dev *hdev, bool enable);
664665
int (*get_data_path_id)(struct hci_dev *hdev, __u8 *data_path);

0 commit comments

Comments
 (0)