* [PATCH v3 1/2] Bluetooth: btintel_pcie: Fix potential race condition in firmware download
@ 2025-06-10 14:00 Kiran K
2025-06-10 14:00 ` [PATCH v3 2/2] Bluetooth: btintel_pcie: Support Function level reset Kiran K
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Kiran K @ 2025-06-10 14:00 UTC (permalink / raw)
To: linux-bluetooth
Cc: ravishankar.srivatsa, chethan.tumkur.narayan,
chandrashekar.devegowda, aluvala.sai.teja, Kiran K
During firmware download, if an error occurs, interrupts must be
disabled, synchronized, and re-enabled before retrying the download.
This change ensures proper interrupt handling to prevent race
conditions.
Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
Signed-off-by: Kiran K <kiran.k@intel.com>
---
drivers/bluetooth/btintel_pcie.c | 33 ++++++++++++++++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index 563165c5efae..e1c688dd2d45 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -2033,6 +2033,28 @@ static void btintel_pcie_release_hdev(struct btintel_pcie_data *data)
data->hdev = NULL;
}
+static void btintel_pcie_disable_interrupts(struct btintel_pcie_data *data)
+{
+ spin_lock(&data->irq_lock);
+ btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_MSIX_FH_INT_MASK, data->fh_init_mask);
+ btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_MSIX_HW_INT_MASK, data->hw_init_mask);
+ spin_unlock(&data->irq_lock);
+}
+
+static void btintel_pcie_enable_interrupts(struct btintel_pcie_data *data)
+{
+ spin_lock(&data->irq_lock);
+ btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_MSIX_FH_INT_MASK, ~data->fh_init_mask);
+ btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_MSIX_HW_INT_MASK, ~data->hw_init_mask);
+ spin_unlock(&data->irq_lock);
+}
+
+static void btintel_pcie_synchronize_irqs(struct btintel_pcie_data *data)
+{
+ for (int i = 0; i < data->alloc_vecs; i++)
+ synchronize_irq(data->msix_entries[i].vector);
+}
+
static int btintel_pcie_setup_internal(struct hci_dev *hdev)
{
struct btintel_pcie_data *data = hci_get_drvdata(hdev);
@@ -2152,6 +2174,8 @@ static int btintel_pcie_setup(struct hci_dev *hdev)
bt_dev_err(hdev, "Firmware download retry count: %d",
fw_dl_retry);
btintel_pcie_dump_debug_registers(hdev);
+ btintel_pcie_disable_interrupts(data);
+ btintel_pcie_synchronize_irqs(data);
err = btintel_pcie_reset_bt(data);
if (err) {
bt_dev_err(hdev, "Failed to do shr reset: %d", err);
@@ -2159,6 +2183,7 @@ static int btintel_pcie_setup(struct hci_dev *hdev)
}
usleep_range(10000, 12000);
btintel_pcie_reset_ia(data);
+ btintel_pcie_enable_interrupts(data);
btintel_pcie_config_msix(data);
err = btintel_pcie_enable_bt(data);
if (err) {
@@ -2291,6 +2316,12 @@ static void btintel_pcie_remove(struct pci_dev *pdev)
data = pci_get_drvdata(pdev);
+ btintel_pcie_disable_interrupts(data);
+
+ btintel_pcie_synchronize_irqs(data);
+
+ flush_work(&data->rx_work);
+
btintel_pcie_reset_bt(data);
for (int i = 0; i < data->alloc_vecs; i++) {
struct msix_entry *msix_entry;
@@ -2303,8 +2334,6 @@ static void btintel_pcie_remove(struct pci_dev *pdev)
btintel_pcie_release_hdev(data);
- flush_work(&data->rx_work);
-
destroy_workqueue(data->workqueue);
btintel_pcie_free(data);
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v3 2/2] Bluetooth: btintel_pcie: Support Function level reset 2025-06-10 14:00 [PATCH v3 1/2] Bluetooth: btintel_pcie: Fix potential race condition in firmware download Kiran K @ 2025-06-10 14:00 ` Kiran K 2025-06-10 15:01 ` Paul Menzel 2025-06-10 14:10 ` [v3,1/2] Bluetooth: btintel_pcie: Fix potential race condition in firmware download bluez.test.bot 2025-06-11 14:40 ` [PATCH v3 1/2] " patchwork-bot+bluetooth 2 siblings, 1 reply; 7+ messages in thread From: Kiran K @ 2025-06-10 14:00 UTC (permalink / raw) To: linux-bluetooth Cc: ravishankar.srivatsa, chethan.tumkur.narayan, chandrashekar.devegowda, aluvala.sai.teja, Kiran K From: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com> The driver supports Function Level Reset (FLR) to recover the controller upon hardware exceptions or hci command timeouts. FLR is triggered only when no prior reset has occurred within the retry window, with a maximum of one FLR allowed within this window. This patch is tested by, echo 1 > /sys/class/bluetooth/hciX/reset Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com> Signed-off-by: Kiran K <kiran.k@intel.com> --- changes in v3: - Fix typos, indentation issues - Update commit message to include test command - Keep the flr max retry to 1 drivers/bluetooth/btintel_pcie.c | 226 ++++++++++++++++++++++++++++++- drivers/bluetooth/btintel_pcie.h | 4 +- 2 files changed, 227 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c index e1c688dd2d45..87e4b3546c7a 100644 --- a/drivers/bluetooth/btintel_pcie.c +++ b/drivers/bluetooth/btintel_pcie.c @@ -41,6 +41,13 @@ static const struct pci_device_id btintel_pcie_table[] = { }; MODULE_DEVICE_TABLE(pci, btintel_pcie_table); +struct btintel_pcie_dev_restart_data { + struct list_head list; + u8 restart_count; + time64_t last_error; + char name[]; +}; + /* Intel PCIe uses 4 bytes of HCI type instead of 1 byte BT SIG HCI type */ #define BTINTEL_PCIE_HCI_TYPE_LEN 4 #define BTINTEL_PCIE_HCI_CMD_PKT 0x00000001 @@ -62,6 +69,9 @@ MODULE_DEVICE_TABLE(pci, btintel_pcie_table); #define BTINTEL_PCIE_TRIGGER_REASON_USER_TRIGGER 0x17A2 #define BTINTEL_PCIE_TRIGGER_REASON_FW_ASSERT 0x1E61 +#define BTINTEL_PCIE_RESET_WINDOW_SECS 5 +#define BTINTEL_PCIE_FLR_MAX_RETRY 1 + /* Alive interrupt context */ enum { BTINTEL_PCIE_ROM, @@ -99,6 +109,14 @@ struct btintel_pcie_dbgc_ctxt { struct btintel_pcie_dbgc_ctxt_buf bufs[BTINTEL_PCIE_DBGC_BUFFER_COUNT]; }; +struct btintel_pcie_removal { + struct pci_dev *pdev; + struct work_struct work; +}; + +static LIST_HEAD(btintel_pcie_restart_data_list); +static DEFINE_SPINLOCK(btintel_pcie_restart_data_lock); + /* This function initializes the memory for DBGC buffers and formats the * DBGC fragment which consists header info and DBGC buffer's LSB, MSB and * size as the payload @@ -1932,6 +1950,9 @@ static int btintel_pcie_send_frame(struct hci_dev *hdev, u32 type; u32 old_ctxt; + if (test_bit(BTINTEL_PCIE_CORE_HALTED, &data->flags)) + return -ENODEV; + /* Due to the fw limitation, the type header of the packet should be * 4 bytes unlike 1 byte for UART. In UART, the firmware can read * the first byte to get the packet type and redirect the rest of data @@ -2192,9 +2213,196 @@ static int btintel_pcie_setup(struct hci_dev *hdev) } btintel_pcie_start_rx(data); } + + if (!err) + set_bit(BTINTEL_PCIE_SETUP_DONE, &data->flags); return err; } +static struct btintel_pcie_dev_restart_data *btintel_pcie_get_restart_data(struct pci_dev *pdev, + struct device *dev) +{ + struct btintel_pcie_dev_restart_data *tmp, *data = NULL; + const char *name = pci_name(pdev); + struct hci_dev *hdev = to_hci_dev(dev); + + spin_lock(&btintel_pcie_restart_data_lock); + list_for_each_entry(tmp, &btintel_pcie_restart_data_list, list) { + if (strcmp(tmp->name, name)) + continue; + data = tmp; + break; + } + spin_unlock(&btintel_pcie_restart_data_lock); + + if (data) { + bt_dev_dbg(hdev, "Found restart data for BDF: %s", data->name); + return data; + } + + data = kzalloc(struct_size(data, name, strlen(name) + 1), GFP_ATOMIC); + if (!data) + return NULL; + + strscpy_pad(data->name, name, strlen(name) + 1); + spin_lock(&btintel_pcie_restart_data_lock); + list_add_tail(&data->list, &btintel_pcie_restart_data_list); + spin_unlock(&btintel_pcie_restart_data_lock); + + return data; +} + +static void btintel_pcie_free_restart_list(void) +{ + struct btintel_pcie_dev_restart_data *tmp; + + while ((tmp = list_first_entry_or_null(&btintel_pcie_restart_data_list, + typeof(*tmp), list))) { + list_del(&tmp->list); + kfree(tmp); + } +} + +static void btintel_pcie_inc_restart_count(struct pci_dev *pdev, + struct device *dev) +{ + struct btintel_pcie_dev_restart_data *data; + struct hci_dev *hdev = to_hci_dev(dev); + time64_t retry_window; + + data = btintel_pcie_get_restart_data(pdev, dev); + if (!data) + return; + + retry_window = ktime_get_boottime_seconds() - data->last_error; + if (data->restart_count == 0) { + data->last_error = ktime_get_boottime_seconds(); + data->restart_count++; + bt_dev_dbg(hdev, "First iteration initialise. last_error: %lld seconds restart_count: %d", + data->last_error, data->restart_count); + } else if (retry_window < BTINTEL_PCIE_RESET_WINDOW_SECS && + data->restart_count <= BTINTEL_PCIE_FLR_MAX_RETRY) { + data->restart_count++; + bt_dev_dbg(hdev, "Flr triggered within the max retry time so increment the restart_count: %d", + data->restart_count); + } else if (retry_window > BTINTEL_PCIE_RESET_WINDOW_SECS) { + data->last_error = 0; + data->restart_count = 0; + bt_dev_dbg(hdev, "Flr triggered out of the retry window, so reset counters"); + } +} + +static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data); + +static void btintel_pcie_removal_work(struct work_struct *wk) +{ + struct btintel_pcie_removal *removal = + container_of(wk, struct btintel_pcie_removal, work); + struct pci_dev *pdev = removal->pdev; + struct btintel_pcie_data *data; + int err; + + pci_lock_rescan_remove(); + + if (!pdev->bus) + goto error; + + data = pci_get_drvdata(pdev); + + btintel_pcie_disable_interrupts(data); + btintel_pcie_synchronize_irqs(data); + + flush_work(&data->rx_work); + flush_work(&data->hdev->dump.dump_rx); + + bt_dev_dbg(data->hdev, "Release bluetooth interface"); + btintel_pcie_release_hdev(data); + + err = pci_reset_function(pdev); + if (err) { + BT_ERR("Failed resetting the pcie device (%d)", err); + goto error; + } + + btintel_pcie_enable_interrupts(data); + btintel_pcie_config_msix(data); + + err = btintel_pcie_enable_bt(data); + if (err) { + BT_ERR("Failed to enable bluetooth hardware after reset (%d)", + err); + goto error; + } + + btintel_pcie_reset_ia(data); + btintel_pcie_start_rx(data); + data->flags = 0; + + err = btintel_pcie_setup_hdev(data); + if (err) { + BT_ERR("Failed registering hdev (%d)", err); + goto error; + } +error: + pci_dev_put(pdev); + pci_unlock_rescan_remove(); + kfree(removal); +} + +static void btintel_pcie_reset(struct hci_dev *hdev) +{ + struct btintel_pcie_removal *removal; + struct btintel_pcie_data *data; + + data = hci_get_drvdata(hdev); + + if (!test_bit(BTINTEL_PCIE_SETUP_DONE, &data->flags)) + return; + + if (test_and_set_bit(BTINTEL_PCIE_RECOVERY_IN_PROGRESS, &data->flags)) + return; + + removal = kzalloc(sizeof(*removal), GFP_ATOMIC); + if (!removal) + return; + + removal->pdev = data->pdev; + INIT_WORK(&removal->work, btintel_pcie_removal_work); + pci_dev_get(removal->pdev); + schedule_work(&removal->work); +} + +static void btintel_pcie_hw_error(struct hci_dev *hdev, u8 code) +{ + struct btintel_pcie_dev_restart_data *data; + struct btintel_pcie_data *dev_data = hci_get_drvdata(hdev); + struct pci_dev *pdev = dev_data->pdev; + time64_t retry_window; + + if (code == 0x13) { + bt_dev_err(hdev, "Encountered top exception"); + return; + } + + data = btintel_pcie_get_restart_data(pdev, &hdev->dev); + if (!data) + return; + + retry_window = ktime_get_boottime_seconds() - data->last_error; + + if (retry_window < BTINTEL_PCIE_RESET_WINDOW_SECS && + data->restart_count >= BTINTEL_PCIE_FLR_MAX_RETRY) { + bt_dev_err(hdev, "Exhausted maximum: %d recovery attempts: %d", + BTINTEL_PCIE_FLR_MAX_RETRY, data->restart_count); + bt_dev_dbg(hdev, "Boot time: %lld seconds first_flr at: %lld seconds restart_count: %d", + ktime_get_boottime_seconds(), data->last_error, + data->restart_count); + return; + } + btintel_pcie_inc_restart_count(pdev, &hdev->dev); + btintel_pcie_reset(hdev); +} + static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data) { int err; @@ -2216,9 +2424,10 @@ static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data) hdev->send = btintel_pcie_send_frame; hdev->setup = btintel_pcie_setup; hdev->shutdown = btintel_shutdown_combined; - hdev->hw_error = btintel_hw_error; + hdev->hw_error = btintel_pcie_hw_error; hdev->set_diag = btintel_set_diag; hdev->set_bdaddr = btintel_set_bdaddr; + hdev->reset = btintel_pcie_reset; err = hci_register_dev(hdev); if (err < 0) { @@ -2366,7 +2575,20 @@ static struct pci_driver btintel_pcie_driver = { .driver.coredump = btintel_pcie_coredump #endif }; -module_pci_driver(btintel_pcie_driver); + +static int __init btintel_pcie_init(void) +{ + return pci_register_driver(&btintel_pcie_driver); +} + +static void __exit btintel_pcie_exit(void) +{ + pci_unregister_driver(&btintel_pcie_driver); + btintel_pcie_free_restart_list(); +} + +module_init(btintel_pcie_init); +module_exit(btintel_pcie_exit); MODULE_AUTHOR("Tedd Ho-Jeong An <tedd.an@intel.com>"); MODULE_DESCRIPTION("Intel Bluetooth PCIe transport driver ver " VERSION); diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h index 7dad4523236c..0fa876c5b954 100644 --- a/drivers/bluetooth/btintel_pcie.h +++ b/drivers/bluetooth/btintel_pcie.h @@ -117,7 +117,9 @@ enum { enum { BTINTEL_PCIE_CORE_HALTED, BTINTEL_PCIE_HWEXP_INPROGRESS, - BTINTEL_PCIE_COREDUMP_INPROGRESS + BTINTEL_PCIE_COREDUMP_INPROGRESS, + BTINTEL_PCIE_RECOVERY_IN_PROGRESS, + BTINTEL_PCIE_SETUP_DONE }; enum btintel_pcie_tlv_type { -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v3 2/2] Bluetooth: btintel_pcie: Support Function level reset 2025-06-10 14:00 ` [PATCH v3 2/2] Bluetooth: btintel_pcie: Support Function level reset Kiran K @ 2025-06-10 15:01 ` Paul Menzel 2025-06-10 15:19 ` Luiz Augusto von Dentz 0 siblings, 1 reply; 7+ messages in thread From: Paul Menzel @ 2025-06-10 15:01 UTC (permalink / raw) To: Kiran K Cc: ravishankar.srivatsa, chethan.tumkur.narayan, chandrashekar.devegowda, aluvala.sai.teja, linux-bluetooth Dear Chandrashekar, dear Kiran, Thank you for the improved version. Sorry, but I still have a few minor comments. Am 10.06.25 um 16:00 schrieb Kiran K: > From: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com> > > The driver supports Function Level Reset (FLR) to recover the controller > upon hardware exceptions or hci command timeouts. FLR is triggered only > when no prior reset has occurred within the retry window, with a maximum > of one FLR allowed within this window. Why only one FLR? > This patch is tested by, > echo 1 > /sys/class/bluetooth/hciX/reset > > Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com> > Signed-off-by: Kiran K <kiran.k@intel.com> > --- > changes in v3: > - Fix typos, indentation issues > - Update commit message to include test command > - Keep the flr max retry to 1 > > drivers/bluetooth/btintel_pcie.c | 226 ++++++++++++++++++++++++++++++- > drivers/bluetooth/btintel_pcie.h | 4 +- > 2 files changed, 227 insertions(+), 3 deletions(-) > > diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c > index e1c688dd2d45..87e4b3546c7a 100644 > --- a/drivers/bluetooth/btintel_pcie.c > +++ b/drivers/bluetooth/btintel_pcie.c > @@ -41,6 +41,13 @@ static const struct pci_device_id btintel_pcie_table[] = { > }; > MODULE_DEVICE_TABLE(pci, btintel_pcie_table); > > +struct btintel_pcie_dev_restart_data { > + struct list_head list; > + u8 restart_count; > + time64_t last_error; > + char name[]; > +}; > + > /* Intel PCIe uses 4 bytes of HCI type instead of 1 byte BT SIG HCI type */ > #define BTINTEL_PCIE_HCI_TYPE_LEN 4 > #define BTINTEL_PCIE_HCI_CMD_PKT 0x00000001 > @@ -62,6 +69,9 @@ MODULE_DEVICE_TABLE(pci, btintel_pcie_table); > #define BTINTEL_PCIE_TRIGGER_REASON_USER_TRIGGER 0x17A2 > #define BTINTEL_PCIE_TRIGGER_REASON_FW_ASSERT 0x1E61 > > +#define BTINTEL_PCIE_RESET_WINDOW_SECS 5 > +#define BTINTEL_PCIE_FLR_MAX_RETRY 1 > + > /* Alive interrupt context */ > enum { > BTINTEL_PCIE_ROM, > @@ -99,6 +109,14 @@ struct btintel_pcie_dbgc_ctxt { > struct btintel_pcie_dbgc_ctxt_buf bufs[BTINTEL_PCIE_DBGC_BUFFER_COUNT]; > }; > > +struct btintel_pcie_removal { > + struct pci_dev *pdev; > + struct work_struct work; > +}; > + > +static LIST_HEAD(btintel_pcie_restart_data_list); > +static DEFINE_SPINLOCK(btintel_pcie_restart_data_lock); > + > /* This function initializes the memory for DBGC buffers and formats the > * DBGC fragment which consists header info and DBGC buffer's LSB, MSB and > * size as the payload > @@ -1932,6 +1950,9 @@ static int btintel_pcie_send_frame(struct hci_dev *hdev, > u32 type; > u32 old_ctxt; > > + if (test_bit(BTINTEL_PCIE_CORE_HALTED, &data->flags)) > + return -ENODEV; > + > /* Due to the fw limitation, the type header of the packet should be > * 4 bytes unlike 1 byte for UART. In UART, the firmware can read > * the first byte to get the packet type and redirect the rest of data > @@ -2192,9 +2213,196 @@ static int btintel_pcie_setup(struct hci_dev *hdev) > } > btintel_pcie_start_rx(data); > } > + > + if (!err) > + set_bit(BTINTEL_PCIE_SETUP_DONE, &data->flags); > return err; > } > > +static struct btintel_pcie_dev_restart_data *btintel_pcie_get_restart_data(struct pci_dev *pdev, > + struct device *dev) > +{ > + struct btintel_pcie_dev_restart_data *tmp, *data = NULL; > + const char *name = pci_name(pdev); > + struct hci_dev *hdev = to_hci_dev(dev); > + > + spin_lock(&btintel_pcie_restart_data_lock); > + list_for_each_entry(tmp, &btintel_pcie_restart_data_list, list) { > + if (strcmp(tmp->name, name)) > + continue; > + data = tmp; > + break; > + } > + spin_unlock(&btintel_pcie_restart_data_lock); > + > + if (data) { > + bt_dev_dbg(hdev, "Found restart data for BDF: %s", data->name); > + return data; > + } > + > + data = kzalloc(struct_size(data, name, strlen(name) + 1), GFP_ATOMIC); > + if (!data) > + return NULL; > + > + strscpy_pad(data->name, name, strlen(name) + 1); > + spin_lock(&btintel_pcie_restart_data_lock); > + list_add_tail(&data->list, &btintel_pcie_restart_data_list); > + spin_unlock(&btintel_pcie_restart_data_lock); > + > + return data; > +} > + > +static void btintel_pcie_free_restart_list(void) > +{ > + struct btintel_pcie_dev_restart_data *tmp; > + > + while ((tmp = list_first_entry_or_null(&btintel_pcie_restart_data_list, > + typeof(*tmp), list))) { > + list_del(&tmp->list); > + kfree(tmp); > + } > +} > + > +static void btintel_pcie_inc_restart_count(struct pci_dev *pdev, > + struct device *dev) > +{ > + struct btintel_pcie_dev_restart_data *data; > + struct hci_dev *hdev = to_hci_dev(dev); > + time64_t retry_window; > + > + data = btintel_pcie_get_restart_data(pdev, dev); > + if (!data) > + return; > + > + retry_window = ktime_get_boottime_seconds() - data->last_error; > + if (data->restart_count == 0) { > + data->last_error = ktime_get_boottime_seconds(); > + data->restart_count++; > + bt_dev_dbg(hdev, "First iteration initialise. last_error: %lld seconds restart_count: %d", > + data->last_error, data->restart_count); > + } else if (retry_window < BTINTEL_PCIE_RESET_WINDOW_SECS && > + data->restart_count <= BTINTEL_PCIE_FLR_MAX_RETRY) { > + data->restart_count++; > + bt_dev_dbg(hdev, "Flr triggered within the max retry time so increment the restart_count: %d", Spell it FLR? > + data->restart_count); > + } else if (retry_window > BTINTEL_PCIE_RESET_WINDOW_SECS) { > + data->last_error = 0; > + data->restart_count = 0; > + bt_dev_dbg(hdev, "Flr triggered out of the retry window, so reset counters"); Ditto. > + } > +} > + > +static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data); > + > +static void btintel_pcie_removal_work(struct work_struct *wk) > +{ > + struct btintel_pcie_removal *removal = > + container_of(wk, struct btintel_pcie_removal, work); > + struct pci_dev *pdev = removal->pdev; > + struct btintel_pcie_data *data; > + int err; > + > + pci_lock_rescan_remove(); > + > + if (!pdev->bus) > + goto error; > + > + data = pci_get_drvdata(pdev); > + > + btintel_pcie_disable_interrupts(data); > + btintel_pcie_synchronize_irqs(data); > + > + flush_work(&data->rx_work); > + flush_work(&data->hdev->dump.dump_rx); > + > + bt_dev_dbg(data->hdev, "Release bluetooth interface"); > + btintel_pcie_release_hdev(data); > + > + err = pci_reset_function(pdev); > + if (err) { > + BT_ERR("Failed resetting the pcie device (%d)", err); > + goto error; > + } > + > + btintel_pcie_enable_interrupts(data); > + btintel_pcie_config_msix(data); > + > + err = btintel_pcie_enable_bt(data); > + if (err) { > + BT_ERR("Failed to enable bluetooth hardware after reset (%d)", > + err); > + goto error; > + } > + > + btintel_pcie_reset_ia(data); > + btintel_pcie_start_rx(data); > + data->flags = 0; > + > + err = btintel_pcie_setup_hdev(data); > + if (err) { > + BT_ERR("Failed registering hdev (%d)", err); > + goto error; > + } > +error: > + pci_dev_put(pdev); > + pci_unlock_rescan_remove(); > + kfree(removal); > +} > + > +static void btintel_pcie_reset(struct hci_dev *hdev) > +{ > + struct btintel_pcie_removal *removal; > + struct btintel_pcie_data *data; > + > + data = hci_get_drvdata(hdev); > + > + if (!test_bit(BTINTEL_PCIE_SETUP_DONE, &data->flags)) > + return; > + > + if (test_and_set_bit(BTINTEL_PCIE_RECOVERY_IN_PROGRESS, &data->flags)) > + return; > + > + removal = kzalloc(sizeof(*removal), GFP_ATOMIC); > + if (!removal) > + return; > + > + removal->pdev = data->pdev; > + INIT_WORK(&removal->work, btintel_pcie_removal_work); > + pci_dev_get(removal->pdev); > + schedule_work(&removal->work); > +} > + > +static void btintel_pcie_hw_error(struct hci_dev *hdev, u8 code) > +{ > + struct btintel_pcie_dev_restart_data *data; Exactly one space after struct? > + struct btintel_pcie_data *dev_data = hci_get_drvdata(hdev); > + struct pci_dev *pdev = dev_data->pdev; > + time64_t retry_window; > + > + if (code == 0x13) { > + bt_dev_err(hdev, "Encountered top exception"); > + return; > + } > + > + data = btintel_pcie_get_restart_data(pdev, &hdev->dev); > + if (!data) > + return; > + > + retry_window = ktime_get_boottime_seconds() - data->last_error; > + > + if (retry_window < BTINTEL_PCIE_RESET_WINDOW_SECS && > + data->restart_count >= BTINTEL_PCIE_FLR_MAX_RETRY) { > + bt_dev_err(hdev, "Exhausted maximum: %d recovery attempts: %d", > + BTINTEL_PCIE_FLR_MAX_RETRY, data->restart_count); > + bt_dev_dbg(hdev, "Boot time: %lld seconds first_flr at: %lld seconds restart_count: %d", > + ktime_get_boottime_seconds(), data->last_error, > + data->restart_count); > + return; > + } > + btintel_pcie_inc_restart_count(pdev, &hdev->dev); > + btintel_pcie_reset(hdev); > +} > + > static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data) > { > int err; > @@ -2216,9 +2424,10 @@ static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data) > hdev->send = btintel_pcie_send_frame; > hdev->setup = btintel_pcie_setup; > hdev->shutdown = btintel_shutdown_combined; > - hdev->hw_error = btintel_hw_error; > + hdev->hw_error = btintel_pcie_hw_error; > hdev->set_diag = btintel_set_diag; > hdev->set_bdaddr = btintel_set_bdaddr; > + hdev->reset = btintel_pcie_reset; > > err = hci_register_dev(hdev); > if (err < 0) { > @@ -2366,7 +2575,20 @@ static struct pci_driver btintel_pcie_driver = { > .driver.coredump = btintel_pcie_coredump > #endif > }; > -module_pci_driver(btintel_pcie_driver); > + > +static int __init btintel_pcie_init(void) > +{ > + return pci_register_driver(&btintel_pcie_driver); > +} > + > +static void __exit btintel_pcie_exit(void) > +{ > + pci_unregister_driver(&btintel_pcie_driver); > + btintel_pcie_free_restart_list(); > +} > + > +module_init(btintel_pcie_init); > +module_exit(btintel_pcie_exit); > > MODULE_AUTHOR("Tedd Ho-Jeong An <tedd.an@intel.com>"); > MODULE_DESCRIPTION("Intel Bluetooth PCIe transport driver ver " VERSION); > diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h > index 7dad4523236c..0fa876c5b954 100644 > --- a/drivers/bluetooth/btintel_pcie.h > +++ b/drivers/bluetooth/btintel_pcie.h > @@ -117,7 +117,9 @@ enum { > enum { > BTINTEL_PCIE_CORE_HALTED, > BTINTEL_PCIE_HWEXP_INPROGRESS, > - BTINTEL_PCIE_COREDUMP_INPROGRESS > + BTINTEL_PCIE_COREDUMP_INPROGRESS, > + BTINTEL_PCIE_RECOVERY_IN_PROGRESS, > + BTINTEL_PCIE_SETUP_DONE > }; > > enum btintel_pcie_tlv_type { Kind regards, Paul ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 2/2] Bluetooth: btintel_pcie: Support Function level reset 2025-06-10 15:01 ` Paul Menzel @ 2025-06-10 15:19 ` Luiz Augusto von Dentz 0 siblings, 0 replies; 7+ messages in thread From: Luiz Augusto von Dentz @ 2025-06-10 15:19 UTC (permalink / raw) To: Paul Menzel Cc: Kiran K, ravishankar.srivatsa, chethan.tumkur.narayan, chandrashekar.devegowda, aluvala.sai.teja, linux-bluetooth Hi Paul, On Tue, Jun 10, 2025 at 11:08 AM Paul Menzel <pmenzel@molgen.mpg.de> wrote: > > Dear Chandrashekar, dear Kiran, > > > Thank you for the improved version. Sorry, but I still have a few minor > comments. > > Am 10.06.25 um 16:00 schrieb Kiran K: > > From: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com> > > > > The driver supports Function Level Reset (FLR) to recover the controller > > upon hardware exceptions or hci command timeouts. FLR is triggered only > > when no prior reset has occurred within the retry window, with a maximum > > of one FLR allowed within this window. > > Why only one FLR? FLR is used for recovery, if it can't recover on the first try then it probably can't be recovered with FLR alone. > > This patch is tested by, > > echo 1 > /sys/class/bluetooth/hciX/reset > > > > Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com> > > Signed-off-by: Kiran K <kiran.k@intel.com> > > --- > > changes in v3: > > - Fix typos, indentation issues > > - Update commit message to include test command > > - Keep the flr max retry to 1 > > > > drivers/bluetooth/btintel_pcie.c | 226 ++++++++++++++++++++++++++++++- > > drivers/bluetooth/btintel_pcie.h | 4 +- > > 2 files changed, 227 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c > > index e1c688dd2d45..87e4b3546c7a 100644 > > --- a/drivers/bluetooth/btintel_pcie.c > > +++ b/drivers/bluetooth/btintel_pcie.c > > @@ -41,6 +41,13 @@ static const struct pci_device_id btintel_pcie_table[] = { > > }; > > MODULE_DEVICE_TABLE(pci, btintel_pcie_table); > > > > +struct btintel_pcie_dev_restart_data { > > + struct list_head list; > > + u8 restart_count; > > + time64_t last_error; > > + char name[]; > > +}; > > + > > /* Intel PCIe uses 4 bytes of HCI type instead of 1 byte BT SIG HCI type */ > > #define BTINTEL_PCIE_HCI_TYPE_LEN 4 > > #define BTINTEL_PCIE_HCI_CMD_PKT 0x00000001 > > @@ -62,6 +69,9 @@ MODULE_DEVICE_TABLE(pci, btintel_pcie_table); > > #define BTINTEL_PCIE_TRIGGER_REASON_USER_TRIGGER 0x17A2 > > #define BTINTEL_PCIE_TRIGGER_REASON_FW_ASSERT 0x1E61 > > > > +#define BTINTEL_PCIE_RESET_WINDOW_SECS 5 > > +#define BTINTEL_PCIE_FLR_MAX_RETRY 1 > > + > > /* Alive interrupt context */ > > enum { > > BTINTEL_PCIE_ROM, > > @@ -99,6 +109,14 @@ struct btintel_pcie_dbgc_ctxt { > > struct btintel_pcie_dbgc_ctxt_buf bufs[BTINTEL_PCIE_DBGC_BUFFER_COUNT]; > > }; > > > > +struct btintel_pcie_removal { > > + struct pci_dev *pdev; > > + struct work_struct work; > > +}; > > + > > +static LIST_HEAD(btintel_pcie_restart_data_list); > > +static DEFINE_SPINLOCK(btintel_pcie_restart_data_lock); > > + > > /* This function initializes the memory for DBGC buffers and formats the > > * DBGC fragment which consists header info and DBGC buffer's LSB, MSB and > > * size as the payload > > @@ -1932,6 +1950,9 @@ static int btintel_pcie_send_frame(struct hci_dev *hdev, > > u32 type; > > u32 old_ctxt; > > > > + if (test_bit(BTINTEL_PCIE_CORE_HALTED, &data->flags)) > > + return -ENODEV; > > + > > /* Due to the fw limitation, the type header of the packet should be > > * 4 bytes unlike 1 byte for UART. In UART, the firmware can read > > * the first byte to get the packet type and redirect the rest of data > > @@ -2192,9 +2213,196 @@ static int btintel_pcie_setup(struct hci_dev *hdev) > > } > > btintel_pcie_start_rx(data); > > } > > + > > + if (!err) > > + set_bit(BTINTEL_PCIE_SETUP_DONE, &data->flags); > > return err; > > } > > > > +static struct btintel_pcie_dev_restart_data *btintel_pcie_get_restart_data(struct pci_dev *pdev, > > + struct device *dev) > > +{ > > + struct btintel_pcie_dev_restart_data *tmp, *data = NULL; > > + const char *name = pci_name(pdev); > > + struct hci_dev *hdev = to_hci_dev(dev); > > + > > + spin_lock(&btintel_pcie_restart_data_lock); > > + list_for_each_entry(tmp, &btintel_pcie_restart_data_list, list) { > > + if (strcmp(tmp->name, name)) > > + continue; > > + data = tmp; > > + break; > > + } > > + spin_unlock(&btintel_pcie_restart_data_lock); > > + > > + if (data) { > > + bt_dev_dbg(hdev, "Found restart data for BDF: %s", data->name); > > + return data; > > + } > > + > > + data = kzalloc(struct_size(data, name, strlen(name) + 1), GFP_ATOMIC); > > + if (!data) > > + return NULL; > > + > > + strscpy_pad(data->name, name, strlen(name) + 1); > > + spin_lock(&btintel_pcie_restart_data_lock); > > + list_add_tail(&data->list, &btintel_pcie_restart_data_list); > > + spin_unlock(&btintel_pcie_restart_data_lock); > > + > > + return data; > > +} > > + > > +static void btintel_pcie_free_restart_list(void) > > +{ > > + struct btintel_pcie_dev_restart_data *tmp; > > + > > + while ((tmp = list_first_entry_or_null(&btintel_pcie_restart_data_list, > > + typeof(*tmp), list))) { > > + list_del(&tmp->list); > > + kfree(tmp); > > + } > > +} > > + > > +static void btintel_pcie_inc_restart_count(struct pci_dev *pdev, > > + struct device *dev) > > +{ > > + struct btintel_pcie_dev_restart_data *data; > > + struct hci_dev *hdev = to_hci_dev(dev); > > + time64_t retry_window; > > + > > + data = btintel_pcie_get_restart_data(pdev, dev); > > + if (!data) > > + return; > > + > > + retry_window = ktime_get_boottime_seconds() - data->last_error; > > + if (data->restart_count == 0) { > > + data->last_error = ktime_get_boottime_seconds(); > > + data->restart_count++; > > + bt_dev_dbg(hdev, "First iteration initialise. last_error: %lld seconds restart_count: %d", > > + data->last_error, data->restart_count); > > + } else if (retry_window < BTINTEL_PCIE_RESET_WINDOW_SECS && > > + data->restart_count <= BTINTEL_PCIE_FLR_MAX_RETRY) { > > + data->restart_count++; > > + bt_dev_dbg(hdev, "Flr triggered within the max retry time so increment the restart_count: %d", > > Spell it FLR? This is maybe misleading since the idea now is that the FLR is only triggered once, we could probably remove restart_count altogether and just a flag to indicate FLR has been triggered. > > + data->restart_count); > > + } else if (retry_window > BTINTEL_PCIE_RESET_WINDOW_SECS) { > > + data->last_error = 0; > > + data->restart_count = 0; > > + bt_dev_dbg(hdev, "Flr triggered out of the retry window, so reset counters"); > > Ditto. > > > + } > > +} > > + > > +static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data); > > + > > +static void btintel_pcie_removal_work(struct work_struct *wk) > > +{ > > + struct btintel_pcie_removal *removal = > > + container_of(wk, struct btintel_pcie_removal, work); > > + struct pci_dev *pdev = removal->pdev; > > + struct btintel_pcie_data *data; > > + int err; > > + > > + pci_lock_rescan_remove(); > > + > > + if (!pdev->bus) > > + goto error; > > + > > + data = pci_get_drvdata(pdev); > > + > > + btintel_pcie_disable_interrupts(data); > > + btintel_pcie_synchronize_irqs(data); > > + > > + flush_work(&data->rx_work); > > + flush_work(&data->hdev->dump.dump_rx); > > + > > + bt_dev_dbg(data->hdev, "Release bluetooth interface"); > > + btintel_pcie_release_hdev(data); > > + > > + err = pci_reset_function(pdev); > > + if (err) { > > + BT_ERR("Failed resetting the pcie device (%d)", err); > > + goto error; > > + } > > + > > + btintel_pcie_enable_interrupts(data); > > + btintel_pcie_config_msix(data); > > + > > + err = btintel_pcie_enable_bt(data); > > + if (err) { > > + BT_ERR("Failed to enable bluetooth hardware after reset (%d)", > > + err); > > + goto error; > > + } > > + > > + btintel_pcie_reset_ia(data); > > + btintel_pcie_start_rx(data); > > + data->flags = 0; > > + > > + err = btintel_pcie_setup_hdev(data); > > + if (err) { > > + BT_ERR("Failed registering hdev (%d)", err); > > + goto error; > > + } > > +error: > > + pci_dev_put(pdev); > > + pci_unlock_rescan_remove(); > > + kfree(removal); > > +} > > + > > +static void btintel_pcie_reset(struct hci_dev *hdev) > > +{ > > + struct btintel_pcie_removal *removal; > > + struct btintel_pcie_data *data; > > + > > + data = hci_get_drvdata(hdev); > > + > > + if (!test_bit(BTINTEL_PCIE_SETUP_DONE, &data->flags)) > > + return; > > + > > + if (test_and_set_bit(BTINTEL_PCIE_RECOVERY_IN_PROGRESS, &data->flags)) > > + return; > > + > > + removal = kzalloc(sizeof(*removal), GFP_ATOMIC); > > + if (!removal) > > + return; > > + > > + removal->pdev = data->pdev; > > + INIT_WORK(&removal->work, btintel_pcie_removal_work); > > + pci_dev_get(removal->pdev); > > + schedule_work(&removal->work); > > +} > > + > > +static void btintel_pcie_hw_error(struct hci_dev *hdev, u8 code) > > +{ > > + struct btintel_pcie_dev_restart_data *data; > > Exactly one space after struct? > > > + struct btintel_pcie_data *dev_data = hci_get_drvdata(hdev); > > + struct pci_dev *pdev = dev_data->pdev; > > + time64_t retry_window; > > + > > + if (code == 0x13) { > > + bt_dev_err(hdev, "Encountered top exception"); > > + return; > > + } > > + > > + data = btintel_pcie_get_restart_data(pdev, &hdev->dev); > > + if (!data) > > + return; > > + > > + retry_window = ktime_get_boottime_seconds() - data->last_error; > > + > > + if (retry_window < BTINTEL_PCIE_RESET_WINDOW_SECS && > > + data->restart_count >= BTINTEL_PCIE_FLR_MAX_RETRY) { > > + bt_dev_err(hdev, "Exhausted maximum: %d recovery attempts: %d", > > + BTINTEL_PCIE_FLR_MAX_RETRY, data->restart_count); > > + bt_dev_dbg(hdev, "Boot time: %lld seconds first_flr at: %lld seconds restart_count: %d", > > + ktime_get_boottime_seconds(), data->last_error, > > + data->restart_count); > > + return; > > + } > > + btintel_pcie_inc_restart_count(pdev, &hdev->dev); > > + btintel_pcie_reset(hdev); > > +} > > + > > static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data) > > { > > int err; > > @@ -2216,9 +2424,10 @@ static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data) > > hdev->send = btintel_pcie_send_frame; > > hdev->setup = btintel_pcie_setup; > > hdev->shutdown = btintel_shutdown_combined; > > - hdev->hw_error = btintel_hw_error; > > + hdev->hw_error = btintel_pcie_hw_error; > > hdev->set_diag = btintel_set_diag; > > hdev->set_bdaddr = btintel_set_bdaddr; > > + hdev->reset = btintel_pcie_reset; > > > > err = hci_register_dev(hdev); > > if (err < 0) { > > @@ -2366,7 +2575,20 @@ static struct pci_driver btintel_pcie_driver = { > > .driver.coredump = btintel_pcie_coredump > > #endif > > }; > > -module_pci_driver(btintel_pcie_driver); > > + > > +static int __init btintel_pcie_init(void) > > +{ > > + return pci_register_driver(&btintel_pcie_driver); > > +} > > + > > +static void __exit btintel_pcie_exit(void) > > +{ > > + pci_unregister_driver(&btintel_pcie_driver); > > + btintel_pcie_free_restart_list(); > > +} > > + > > +module_init(btintel_pcie_init); > > +module_exit(btintel_pcie_exit); > > > > MODULE_AUTHOR("Tedd Ho-Jeong An <tedd.an@intel.com>"); > > MODULE_DESCRIPTION("Intel Bluetooth PCIe transport driver ver " VERSION); > > diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h > > index 7dad4523236c..0fa876c5b954 100644 > > --- a/drivers/bluetooth/btintel_pcie.h > > +++ b/drivers/bluetooth/btintel_pcie.h > > @@ -117,7 +117,9 @@ enum { > > enum { > > BTINTEL_PCIE_CORE_HALTED, > > BTINTEL_PCIE_HWEXP_INPROGRESS, > > - BTINTEL_PCIE_COREDUMP_INPROGRESS > > + BTINTEL_PCIE_COREDUMP_INPROGRESS, > > + BTINTEL_PCIE_RECOVERY_IN_PROGRESS, > > + BTINTEL_PCIE_SETUP_DONE > > }; > > > > enum btintel_pcie_tlv_type { > > > Kind regards, > > Paul > -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: [v3,1/2] Bluetooth: btintel_pcie: Fix potential race condition in firmware download 2025-06-10 14:00 [PATCH v3 1/2] Bluetooth: btintel_pcie: Fix potential race condition in firmware download Kiran K 2025-06-10 14:00 ` [PATCH v3 2/2] Bluetooth: btintel_pcie: Support Function level reset Kiran K @ 2025-06-10 14:10 ` bluez.test.bot 2025-06-11 14:40 ` [PATCH v3 1/2] " patchwork-bot+bluetooth 2 siblings, 0 replies; 7+ messages in thread From: bluez.test.bot @ 2025-06-10 14:10 UTC (permalink / raw) To: linux-bluetooth, kiran.k [-- Attachment #1: Type: text/plain, Size: 1950 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=970379 ---Test result--- Test Summary: CheckPatch PENDING 0.30 seconds GitLint PENDING 0.24 seconds SubjectPrefix PASS 0.20 seconds BuildKernel PASS 24.97 seconds CheckAllWarning PASS 27.17 seconds CheckSparse PASS 30.71 seconds BuildKernel32 PASS 24.63 seconds TestRunnerSetup PASS 466.61 seconds TestRunner_l2cap-tester PASS 25.77 seconds TestRunner_iso-tester PASS 38.91 seconds TestRunner_bnep-tester PASS 5.96 seconds TestRunner_mgmt-tester FAIL 137.16 seconds TestRunner_rfcomm-tester PASS 9.41 seconds TestRunner_sco-tester PASS 14.87 seconds TestRunner_ioctl-tester PASS 10.02 seconds TestRunner_mesh-tester PASS 7.38 seconds TestRunner_smp-tester PASS 8.62 seconds TestRunner_userchan-tester PASS 6.19 seconds IncrementalBuild PENDING 0.98 seconds Details ############################## Test: CheckPatch - PENDING Desc: Run checkpatch.pl script Output: ############################## Test: GitLint - PENDING Desc: Run gitlint Output: ############################## Test: TestRunner_mgmt-tester - FAIL Desc: Run mgmt-tester with test-runner Output: Total: 490, Passed: 485 (99.0%), Failed: 1, Not Run: 4 Failed Test Cases LL Privacy - Set Flags 4 (RL is full) Failed 0.302 seconds ############################## Test: IncrementalBuild - PENDING Desc: Incremental build with the patches in the series Output: --- Regards, Linux Bluetooth ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 1/2] Bluetooth: btintel_pcie: Fix potential race condition in firmware download 2025-06-10 14:00 [PATCH v3 1/2] Bluetooth: btintel_pcie: Fix potential race condition in firmware download Kiran K 2025-06-10 14:00 ` [PATCH v3 2/2] Bluetooth: btintel_pcie: Support Function level reset Kiran K 2025-06-10 14:10 ` [v3,1/2] Bluetooth: btintel_pcie: Fix potential race condition in firmware download bluez.test.bot @ 2025-06-11 14:40 ` patchwork-bot+bluetooth 2025-06-11 14:45 ` Luiz Augusto von Dentz 2 siblings, 1 reply; 7+ messages in thread From: patchwork-bot+bluetooth @ 2025-06-11 14:40 UTC (permalink / raw) To: Kiran K Cc: linux-bluetooth, ravishankar.srivatsa, chethan.tumkur.narayan, chandrashekar.devegowda, aluvala.sai.teja Hello: This series was applied to bluetooth/bluetooth-next.git (master) by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>: On Tue, 10 Jun 2025 19:30:37 +0530 you wrote: > During firmware download, if an error occurs, interrupts must be > disabled, synchronized, and re-enabled before retrying the download. > This change ensures proper interrupt handling to prevent race > conditions. > > Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com> > Signed-off-by: Kiran K <kiran.k@intel.com> > > [...] Here is the summary with links: - [v3,1/2] Bluetooth: btintel_pcie: Fix potential race condition in firmware download https://git.kernel.org/bluetooth/bluetooth-next/c/866fd57640ce - [v3,2/2] Bluetooth: btintel_pcie: Support Function level reset https://git.kernel.org/bluetooth/bluetooth-next/c/ba6b287d9f91 You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 1/2] Bluetooth: btintel_pcie: Fix potential race condition in firmware download 2025-06-11 14:40 ` [PATCH v3 1/2] " patchwork-bot+bluetooth @ 2025-06-11 14:45 ` Luiz Augusto von Dentz 0 siblings, 0 replies; 7+ messages in thread From: Luiz Augusto von Dentz @ 2025-06-11 14:45 UTC (permalink / raw) To: patchwork-bot+bluetooth Cc: Kiran K, linux-bluetooth, ravishankar.srivatsa, chethan.tumkur.narayan, chandrashekar.devegowda, aluvala.sai.teja Hi Kiran, Chandru, On Wed, Jun 11, 2025 at 10:42 AM <patchwork-bot+bluetooth@kernel.org> wrote: > > Hello: > > This series was applied to bluetooth/bluetooth-next.git (master) > by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>: > > On Tue, 10 Jun 2025 19:30:37 +0530 you wrote: > > During firmware download, if an error occurs, interrupts must be > > disabled, synchronized, and re-enabled before retrying the download. > > This change ensures proper interrupt handling to prevent race > > conditions. > > > > Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com> > > Signed-off-by: Kiran K <kiran.k@intel.com> > > > > [...] > > Here is the summary with links: > - [v3,1/2] Bluetooth: btintel_pcie: Fix potential race condition in firmware download > https://git.kernel.org/bluetooth/bluetooth-next/c/866fd57640ce > - [v3,2/2] Bluetooth: btintel_pcie: Support Function level reset > https://git.kernel.org/bluetooth/bluetooth-next/c/ba6b287d9f91 Note that I did add the following changes on top: https://github.com/bluez/bluetooth-next/commit/bd35cd12d915bc410c721ba28afcada16f0ebd16 > You are awesome, thank you! > -- > Deet-doot-dot, I am a bot. > https://korg.docs.kernel.org/patchwork/pwbot.html > > > -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-06-11 14:46 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-06-10 14:00 [PATCH v3 1/2] Bluetooth: btintel_pcie: Fix potential race condition in firmware download Kiran K 2025-06-10 14:00 ` [PATCH v3 2/2] Bluetooth: btintel_pcie: Support Function level reset Kiran K 2025-06-10 15:01 ` Paul Menzel 2025-06-10 15:19 ` Luiz Augusto von Dentz 2025-06-10 14:10 ` [v3,1/2] Bluetooth: btintel_pcie: Fix potential race condition in firmware download bluez.test.bot 2025-06-11 14:40 ` [PATCH v3 1/2] " patchwork-bot+bluetooth 2025-06-11 14:45 ` Luiz Augusto von Dentz
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.