Message ID | 20210819202819.v5.1.Id9bc5434114de07512661f002cdc0ada8b3d6d02@changeid |
---|---|
State | New |
Headers | show |
Series | [v5] Bluetooth: Keep MSFT ext info throughout a hci_dev's life cycle | expand |
Hi Manish, > This moves msft_do_close() from hci_dev_do_close() to > hci_unregister_dev() to avoid clearing MSFT extension info. This also > re-reads MSFT info upon every msft_do_open() even if MSFT extension has > been initialized. > > The following test steps were performed. > (1) boot the test device and verify the MSFT support debug log in syslog > (2) restart bluetoothd and verify msft_do_close() doesn't get invoked > and msft_do_open re-reads the MSFT support. so tell me how this can be correct. The msft_do_close does cleanup of instances. If we close the device via power down I would expect that these instances are cleared. Do they survive a HCI Reset command? I think it would be better to introduce an additional msft_register / msft_unregister pair if this needs to be more complex. Regards Marcel
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index fb296478b86e..681c6dabb550 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1798,7 +1798,6 @@ int hci_dev_do_close(struct hci_dev *hdev) hci_sock_dev_event(hdev, HCI_DEV_DOWN); aosp_do_close(hdev); - msft_do_close(hdev); if (hdev->flush) hdev->flush(hdev); @@ -4026,6 +4025,8 @@ void hci_unregister_dev(struct hci_dev *hdev) cancel_work_sync(&hdev->suspend_prepare); } + msft_do_close(hdev); + hci_dev_do_close(hdev); if (!test_bit(HCI_INIT, &hdev->flags) && diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c index b4bfae41e8a5..c2568e93598a 100644 --- a/net/bluetooth/msft.c +++ b/net/bluetooth/msft.c @@ -184,16 +184,30 @@ static void reregister_monitor_on_restart(struct hci_dev *hdev, int handle) void msft_do_open(struct hci_dev *hdev) { - struct msft_data *msft; + struct msft_data *msft = NULL; if (hdev->msft_opcode == HCI_OP_NOP) return; bt_dev_dbg(hdev, "Initialize MSFT extension"); - msft = kzalloc(sizeof(*msft), GFP_KERNEL); - if (!msft) + /* If MSFT data exists, reset its members */ + if (hdev->msft_data) { + msft = hdev->msft_data; + hdev->msft_data = NULL; + + msft->features = 0; + kfree(msft->evt_prefix); + msft->evt_prefix = NULL; + msft->evt_prefix_len = 0; + } else { + msft = kzalloc(sizeof(*msft), GFP_KERNEL); + } + + if (!msft) { + bt_dev_err(hdev, "Failed to init MSFT extension"); return; + } if (!read_supported_features(hdev, msft)) { kfree(msft);