mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-02-24 04:15:07 -05:00
Merge tag 'for-net-2025-01-08' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - btmtk: Fix failed to send func ctrl for MediaTek devices. - hci_sync: Fix not setting Random Address when required - MGMT: Fix Add Device to responding before completing - btnxpuart: Fix driver sending truncated data * tag 'for-net-2025-01-08' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: btmtk: Fix failed to send func ctrl for MediaTek devices. Bluetooth: btnxpuart: Fix driver sending truncated data Bluetooth: MGMT: Fix Add Device to responding before completing Bluetooth: hci_sync: Fix not setting Random Address when required ==================== Link: https://patch.msgid.link/20250108162627.1623760-1-luiz.dentz@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -1472,10 +1472,15 @@ EXPORT_SYMBOL_GPL(btmtk_usb_setup);
|
||||
|
||||
int btmtk_usb_shutdown(struct hci_dev *hdev)
|
||||
{
|
||||
struct btmtk_data *data = hci_get_priv(hdev);
|
||||
struct btmtk_hci_wmt_params wmt_params;
|
||||
u8 param = 0;
|
||||
int err;
|
||||
|
||||
err = usb_autopm_get_interface(data->intf);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Disable the device */
|
||||
wmt_params.op = BTMTK_WMT_FUNC_CTRL;
|
||||
wmt_params.flag = 0;
|
||||
@@ -1486,9 +1491,11 @@ int btmtk_usb_shutdown(struct hci_dev *hdev)
|
||||
err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
|
||||
usb_autopm_put_interface(data->intf);
|
||||
return err;
|
||||
}
|
||||
|
||||
usb_autopm_put_interface(data->intf);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(btmtk_usb_shutdown);
|
||||
|
||||
@@ -1381,6 +1381,7 @@ static void btnxpuart_tx_work(struct work_struct *work)
|
||||
|
||||
while ((skb = nxp_dequeue(nxpdev))) {
|
||||
len = serdev_device_write_buf(serdev, skb->data, skb->len);
|
||||
serdev_device_wait_until_sent(serdev, 0);
|
||||
hdev->stat.byte_tx += len;
|
||||
|
||||
skb_pull(skb, len);
|
||||
|
||||
@@ -1031,9 +1031,9 @@ static bool adv_use_rpa(struct hci_dev *hdev, uint32_t flags)
|
||||
|
||||
static int hci_set_random_addr_sync(struct hci_dev *hdev, bdaddr_t *rpa)
|
||||
{
|
||||
/* If we're advertising or initiating an LE connection we can't
|
||||
* go ahead and change the random address at this time. This is
|
||||
* because the eventual initiator address used for the
|
||||
/* If a random_addr has been set we're advertising or initiating an LE
|
||||
* connection we can't go ahead and change the random address at this
|
||||
* time. This is because the eventual initiator address used for the
|
||||
* subsequently created connection will be undefined (some
|
||||
* controllers use the new address and others the one we had
|
||||
* when the operation started).
|
||||
@@ -1041,8 +1041,9 @@ static int hci_set_random_addr_sync(struct hci_dev *hdev, bdaddr_t *rpa)
|
||||
* In this kind of scenario skip the update and let the random
|
||||
* address be updated at the next cycle.
|
||||
*/
|
||||
if (hci_dev_test_flag(hdev, HCI_LE_ADV) ||
|
||||
hci_lookup_le_connect(hdev)) {
|
||||
if (bacmp(&hdev->random_addr, BDADDR_ANY) &&
|
||||
(hci_dev_test_flag(hdev, HCI_LE_ADV) ||
|
||||
hci_lookup_le_connect(hdev))) {
|
||||
bt_dev_dbg(hdev, "Deferring random address update");
|
||||
hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
|
||||
return 0;
|
||||
|
||||
@@ -7655,6 +7655,24 @@ static void device_added(struct sock *sk, struct hci_dev *hdev,
|
||||
mgmt_event(MGMT_EV_DEVICE_ADDED, hdev, &ev, sizeof(ev), sk);
|
||||
}
|
||||
|
||||
static void add_device_complete(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_cp_add_device *cp = cmd->param;
|
||||
|
||||
if (!err) {
|
||||
device_added(cmd->sk, hdev, &cp->addr.bdaddr, cp->addr.type,
|
||||
cp->action);
|
||||
device_flags_changed(NULL, hdev, &cp->addr.bdaddr,
|
||||
cp->addr.type, hdev->conn_flags,
|
||||
PTR_UINT(cmd->user_data));
|
||||
}
|
||||
|
||||
mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_ADD_DEVICE,
|
||||
mgmt_status(err), &cp->addr, sizeof(cp->addr));
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
static int add_device_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
return hci_update_passive_scan_sync(hdev);
|
||||
@@ -7663,6 +7681,7 @@ static int add_device_sync(struct hci_dev *hdev, void *data)
|
||||
static int add_device(struct sock *sk, struct hci_dev *hdev,
|
||||
void *data, u16 len)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd;
|
||||
struct mgmt_cp_add_device *cp = data;
|
||||
u8 auto_conn, addr_type;
|
||||
struct hci_conn_params *params;
|
||||
@@ -7743,9 +7762,24 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
|
||||
current_flags = params->flags;
|
||||
}
|
||||
|
||||
err = hci_cmd_sync_queue(hdev, add_device_sync, NULL, NULL);
|
||||
if (err < 0)
|
||||
cmd = mgmt_pending_new(sk, MGMT_OP_ADD_DEVICE, hdev, data, len);
|
||||
if (!cmd) {
|
||||
err = -ENOMEM;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
cmd->user_data = UINT_PTR(current_flags);
|
||||
|
||||
err = hci_cmd_sync_queue(hdev, add_device_sync, cmd,
|
||||
add_device_complete);
|
||||
if (err < 0) {
|
||||
err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
|
||||
MGMT_STATUS_FAILED, &cp->addr,
|
||||
sizeof(cp->addr));
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
goto unlock;
|
||||
|
||||
added:
|
||||
device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action);
|
||||
|
||||
@@ -201,14 +201,14 @@ static ssize_t address_show(struct device *tty_dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
|
||||
return sprintf(buf, "%pMR\n", &dev->dst);
|
||||
return sysfs_emit(buf, "%pMR\n", &dev->dst);
|
||||
}
|
||||
|
||||
static ssize_t channel_show(struct device *tty_dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
|
||||
return sprintf(buf, "%d\n", dev->channel);
|
||||
return sysfs_emit(buf, "%d\n", dev->channel);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(address);
|
||||
|
||||
Reference in New Issue
Block a user