Import of kernel-5.14.0-611.11.1.el9_7
This commit is contained in:
parent
d18cc6d0be
commit
1e764b8f70
@ -12,7 +12,7 @@ RHEL_MINOR = 7
|
||||
#
|
||||
# Use this spot to avoid future merge conflicts.
|
||||
# Do not trim this comment.
|
||||
RHEL_RELEASE = 611.9.1
|
||||
RHEL_RELEASE = 611.11.1
|
||||
|
||||
#
|
||||
# ZSTREAM
|
||||
|
||||
@ -542,7 +542,8 @@ enum {
|
||||
#define pasid_supported(iommu) (sm_supported(iommu) && \
|
||||
ecap_pasid((iommu)->ecap))
|
||||
#define ssads_supported(iommu) (sm_supported(iommu) && \
|
||||
ecap_slads((iommu)->ecap))
|
||||
ecap_slads((iommu)->ecap) && \
|
||||
ecap_smpwc(iommu->ecap))
|
||||
#define nested_supported(iommu) (sm_supported(iommu) && \
|
||||
ecap_nest((iommu)->ecap))
|
||||
|
||||
|
||||
@ -549,12 +549,12 @@ static int e1000_set_eeprom(struct net_device *netdev,
|
||||
{
|
||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
size_t total_len, max_len;
|
||||
u16 *eeprom_buff;
|
||||
void *ptr;
|
||||
int max_len;
|
||||
int ret_val = 0;
|
||||
int first_word;
|
||||
int last_word;
|
||||
int ret_val = 0;
|
||||
void *ptr;
|
||||
u16 i;
|
||||
|
||||
if (eeprom->len == 0)
|
||||
@ -569,6 +569,10 @@ static int e1000_set_eeprom(struct net_device *netdev,
|
||||
|
||||
max_len = hw->nvm.word_size * 2;
|
||||
|
||||
if (check_add_overflow(eeprom->offset, eeprom->len, &total_len) ||
|
||||
total_len > max_len)
|
||||
return -EFBIG;
|
||||
|
||||
first_word = eeprom->offset >> 1;
|
||||
last_word = (eeprom->offset + eeprom->len - 1) >> 1;
|
||||
eeprom_buff = kmalloc(max_len, GFP_KERNEL);
|
||||
|
||||
@ -98,19 +98,21 @@ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
|
||||
|
||||
index = ice_adapter_xa_index(pdev);
|
||||
scoped_guard(mutex, &ice_adapters_mutex) {
|
||||
err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL);
|
||||
if (err == -EBUSY) {
|
||||
adapter = xa_load(&ice_adapters, index);
|
||||
if (adapter) {
|
||||
refcount_inc(&adapter->refcount);
|
||||
WARN_ON_ONCE(adapter->index != ice_adapter_index(pdev));
|
||||
return adapter;
|
||||
}
|
||||
err = xa_reserve(&ice_adapters, index, GFP_KERNEL);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
adapter = ice_adapter_new(pdev);
|
||||
if (!adapter)
|
||||
if (!adapter) {
|
||||
xa_release(&ice_adapters, index);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
|
||||
}
|
||||
return adapter;
|
||||
|
||||
@ -1677,6 +1677,10 @@ void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid)
|
||||
skb_queue_splice_tail_init(&wcid->tx_pending, &list);
|
||||
spin_unlock(&wcid->tx_pending.lock);
|
||||
|
||||
spin_lock(&wcid->tx_offchannel.lock);
|
||||
skb_queue_splice_tail_init(&wcid->tx_offchannel, &list);
|
||||
spin_unlock(&wcid->tx_offchannel.lock);
|
||||
|
||||
spin_unlock_bh(&phy->tx_lock);
|
||||
|
||||
while ((skb = __skb_dequeue(&list)) != NULL) {
|
||||
@ -1688,7 +1692,7 @@ EXPORT_SYMBOL_GPL(mt76_wcid_cleanup);
|
||||
|
||||
void mt76_wcid_add_poll(struct mt76_dev *dev, struct mt76_wcid *wcid)
|
||||
{
|
||||
if (test_bit(MT76_MCU_RESET, &dev->phy.state))
|
||||
if (test_bit(MT76_MCU_RESET, &dev->phy.state) || !wcid->sta)
|
||||
return;
|
||||
|
||||
spin_lock_bh(&dev->sta_poll_lock);
|
||||
|
||||
@ -645,6 +645,7 @@ mt76_txq_schedule_pending_wcid(struct mt76_phy *phy, struct mt76_wcid *wcid,
|
||||
static void mt76_txq_schedule_pending(struct mt76_phy *phy)
|
||||
{
|
||||
LIST_HEAD(tx_list);
|
||||
int ret = 0;
|
||||
|
||||
if (list_empty(&phy->tx_list))
|
||||
return;
|
||||
@ -656,12 +657,12 @@ static void mt76_txq_schedule_pending(struct mt76_phy *phy)
|
||||
list_splice_init(&phy->tx_list, &tx_list);
|
||||
while (!list_empty(&tx_list)) {
|
||||
struct mt76_wcid *wcid;
|
||||
int ret;
|
||||
|
||||
wcid = list_first_entry(&tx_list, struct mt76_wcid, tx_list);
|
||||
list_del_init(&wcid->tx_list);
|
||||
|
||||
spin_unlock(&phy->tx_lock);
|
||||
if (ret >= 0)
|
||||
ret = mt76_txq_schedule_pending_wcid(phy, wcid, &wcid->tx_offchannel);
|
||||
if (ret >= 0 && !phy->offchannel)
|
||||
ret = mt76_txq_schedule_pending_wcid(phy, wcid, &wcid->tx_pending);
|
||||
@ -671,9 +672,6 @@ static void mt76_txq_schedule_pending(struct mt76_phy *phy)
|
||||
!skb_queue_empty(&wcid->tx_offchannel) &&
|
||||
list_empty(&wcid->tx_list))
|
||||
list_add_tail(&wcid->tx_list, &phy->tx_list);
|
||||
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
spin_unlock(&phy->tx_lock);
|
||||
|
||||
|
||||
@ -167,7 +167,7 @@ static int tpmi_get_logical_id(unsigned int cpu, struct tpmi_cpu_info *info)
|
||||
|
||||
info->punit_thread_id = FIELD_GET(LP_ID_MASK, data);
|
||||
info->punit_core_id = FIELD_GET(MODULE_ID_MASK, data);
|
||||
info->pkg_id = topology_physical_package_id(cpu);
|
||||
info->pkg_id = topology_logical_package_id(cpu);
|
||||
info->linux_cpu = cpu;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -4543,10 +4543,16 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
|
||||
}
|
||||
status = nfs_ok;
|
||||
if (conf) {
|
||||
if (get_client_locked(conf) == nfs_ok) {
|
||||
old = unconf;
|
||||
unhash_client_locked(old);
|
||||
nfsd4_change_callback(conf, &unconf->cl_cb_conn);
|
||||
} else {
|
||||
conf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!conf) {
|
||||
old = find_confirmed_client_by_name(&unconf->cl_name, nn);
|
||||
if (old) {
|
||||
status = nfserr_clid_inuse;
|
||||
@ -4563,10 +4569,14 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
|
||||
}
|
||||
trace_nfsd_clid_replaced(&old->cl_clientid);
|
||||
}
|
||||
status = get_client_locked(unconf);
|
||||
if (status != nfs_ok) {
|
||||
old = NULL;
|
||||
goto out;
|
||||
}
|
||||
move_to_confirmed(unconf);
|
||||
conf = unconf;
|
||||
}
|
||||
get_client_locked(conf);
|
||||
spin_unlock(&nn->client_lock);
|
||||
if (conf == unconf)
|
||||
fsnotify_dentry(conf->cl_nfsd_info_dentry, FS_MODIFY);
|
||||
|
||||
@ -542,6 +542,7 @@ struct hci_dev {
|
||||
struct hci_conn_hash conn_hash;
|
||||
|
||||
struct list_head mesh_pending;
|
||||
struct mutex mgmt_pending_lock;
|
||||
struct list_head mgmt_pending;
|
||||
struct list_head reject_list;
|
||||
struct list_head accept_list;
|
||||
@ -2409,7 +2410,6 @@ void mgmt_advertising_added(struct sock *sk, struct hci_dev *hdev,
|
||||
u8 instance);
|
||||
void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev,
|
||||
u8 instance);
|
||||
void mgmt_adv_monitor_removed(struct hci_dev *hdev, u16 handle);
|
||||
int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip);
|
||||
void mgmt_adv_monitor_device_lost(struct hci_dev *hdev, u16 handle,
|
||||
bdaddr_t *bdaddr, u8 addr_type);
|
||||
|
||||
@ -93,7 +93,7 @@ int hci_update_class_sync(struct hci_dev *hdev);
|
||||
|
||||
int hci_update_eir_sync(struct hci_dev *hdev);
|
||||
int hci_update_class_sync(struct hci_dev *hdev);
|
||||
int hci_update_name_sync(struct hci_dev *hdev);
|
||||
int hci_update_name_sync(struct hci_dev *hdev, const u8 *name);
|
||||
int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode);
|
||||
|
||||
int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
|
||||
|
||||
@ -848,7 +848,7 @@ struct mgmt_cp_set_mesh {
|
||||
__le16 window;
|
||||
__le16 period;
|
||||
__u8 num_ad_types;
|
||||
__u8 ad_types[];
|
||||
__u8 ad_types[] __counted_by(num_ad_types);
|
||||
} __packed;
|
||||
#define MGMT_SET_MESH_RECEIVER_SIZE 6
|
||||
|
||||
|
||||
@ -1895,10 +1895,8 @@ void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
|
||||
if (monitor->handle)
|
||||
idr_remove(&hdev->adv_monitors_idr, monitor->handle);
|
||||
|
||||
if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) {
|
||||
if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED)
|
||||
hdev->adv_monitors_cnt--;
|
||||
mgmt_adv_monitor_removed(hdev, monitor->handle);
|
||||
}
|
||||
|
||||
kfree(monitor);
|
||||
}
|
||||
@ -2510,6 +2508,7 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
|
||||
|
||||
mutex_init(&hdev->lock);
|
||||
mutex_init(&hdev->req_lock);
|
||||
mutex_init(&hdev->mgmt_pending_lock);
|
||||
|
||||
ida_init(&hdev->unset_handle_ida);
|
||||
|
||||
|
||||
@ -3412,13 +3412,13 @@ int hci_update_scan_sync(struct hci_dev *hdev)
|
||||
return hci_write_scan_enable_sync(hdev, scan);
|
||||
}
|
||||
|
||||
int hci_update_name_sync(struct hci_dev *hdev)
|
||||
int hci_update_name_sync(struct hci_dev *hdev, const u8 *name)
|
||||
{
|
||||
struct hci_cp_write_local_name cp;
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
|
||||
memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
|
||||
memcpy(cp.name, name, sizeof(cp.name));
|
||||
|
||||
return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME,
|
||||
sizeof(cp), &cp,
|
||||
@ -3471,7 +3471,7 @@ int hci_powered_update_sync(struct hci_dev *hdev)
|
||||
hci_write_fast_connectable_sync(hdev, false);
|
||||
hci_update_scan_sync(hdev);
|
||||
hci_update_class_sync(hdev);
|
||||
hci_update_name_sync(hdev);
|
||||
hci_update_name_sync(hdev, hdev->dev_name);
|
||||
hci_update_eir_sync(hdev);
|
||||
}
|
||||
|
||||
|
||||
@ -1324,8 +1324,7 @@ static void mgmt_set_powered_complete(struct hci_dev *hdev, void *data, int err)
|
||||
struct mgmt_mode *cp;
|
||||
|
||||
/* Make sure cmd still outstanding. */
|
||||
if (err == -ECANCELED ||
|
||||
cmd != pending_find(MGMT_OP_SET_POWERED, hdev))
|
||||
if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
|
||||
return;
|
||||
|
||||
cp = cmd->param;
|
||||
@ -1352,23 +1351,29 @@ static void mgmt_set_powered_complete(struct hci_dev *hdev, void *data, int err)
|
||||
mgmt_status(err));
|
||||
}
|
||||
|
||||
mgmt_pending_remove(cmd);
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
static int set_powered_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_mode *cp;
|
||||
struct mgmt_mode cp;
|
||||
|
||||
mutex_lock(&hdev->mgmt_pending_lock);
|
||||
|
||||
/* Make sure cmd still outstanding. */
|
||||
if (cmd != pending_find(MGMT_OP_SET_POWERED, hdev))
|
||||
if (!__mgmt_pending_listed(hdev, cmd)) {
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
cp = cmd->param;
|
||||
memcpy(&cp, cmd->param, sizeof(cp));
|
||||
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
||||
return hci_set_powered_sync(hdev, cp->val);
|
||||
return hci_set_powered_sync(hdev, cp.val);
|
||||
}
|
||||
|
||||
static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||
@ -1447,22 +1452,17 @@ static void settings_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
||||
|
||||
send_settings_rsp(cmd->sk, cmd->opcode, match->hdev);
|
||||
|
||||
list_del(&cmd->list);
|
||||
|
||||
if (match->sk == NULL) {
|
||||
match->sk = cmd->sk;
|
||||
sock_hold(match->sk);
|
||||
}
|
||||
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
||||
{
|
||||
u8 *status = data;
|
||||
|
||||
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, *status);
|
||||
mgmt_pending_remove(cmd);
|
||||
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, *status);
|
||||
}
|
||||
|
||||
static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
||||
@ -1476,8 +1476,6 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
||||
|
||||
if (cmd->cmd_complete) {
|
||||
cmd->cmd_complete(cmd, match->mgmt_status);
|
||||
mgmt_pending_remove(cmd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1486,13 +1484,13 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
||||
|
||||
static int generic_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
|
||||
{
|
||||
return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status,
|
||||
return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status,
|
||||
cmd->param, cmd->param_len);
|
||||
}
|
||||
|
||||
static int addr_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
|
||||
{
|
||||
return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status,
|
||||
return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status,
|
||||
cmd->param, sizeof(struct mgmt_addr_info));
|
||||
}
|
||||
|
||||
@ -1524,15 +1522,14 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
/* Make sure cmd still outstanding. */
|
||||
if (err == -ECANCELED ||
|
||||
cmd != pending_find(MGMT_OP_SET_DISCOVERABLE, hdev))
|
||||
if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
|
||||
return;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
if (err) {
|
||||
u8 mgmt_err = mgmt_status(err);
|
||||
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
|
||||
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
|
||||
hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
|
||||
goto done;
|
||||
}
|
||||
@ -1547,12 +1544,15 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
|
||||
new_settings(hdev, cmd->sk);
|
||||
|
||||
done:
|
||||
mgmt_pending_remove(cmd);
|
||||
mgmt_pending_free(cmd);
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static int set_discoverable_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
if (!mgmt_pending_listed(hdev, data))
|
||||
return -ECANCELED;
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
||||
return hci_update_discoverable_sync(hdev);
|
||||
@ -1699,15 +1699,14 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
/* Make sure cmd still outstanding. */
|
||||
if (err == -ECANCELED ||
|
||||
cmd != pending_find(MGMT_OP_SET_CONNECTABLE, hdev))
|
||||
if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
|
||||
return;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
if (err) {
|
||||
u8 mgmt_err = mgmt_status(err);
|
||||
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
|
||||
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -1715,7 +1714,7 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
|
||||
new_settings(hdev, cmd->sk);
|
||||
|
||||
done:
|
||||
mgmt_pending_remove(cmd);
|
||||
mgmt_pending_free(cmd);
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
@ -1751,6 +1750,9 @@ static int set_connectable_update_settings(struct hci_dev *hdev,
|
||||
|
||||
static int set_connectable_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
if (!mgmt_pending_listed(hdev, data))
|
||||
return -ECANCELED;
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
||||
return hci_update_connectable_sync(hdev);
|
||||
@ -1927,14 +1929,17 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
struct cmd_lookup match = { NULL, hdev };
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_mode *cp = cmd->param;
|
||||
u8 enable = cp->val;
|
||||
struct mgmt_mode *cp;
|
||||
u8 enable;
|
||||
bool changed;
|
||||
|
||||
/* Make sure cmd still outstanding. */
|
||||
if (err == -ECANCELED || cmd != pending_find(MGMT_OP_SET_SSP, hdev))
|
||||
if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
|
||||
return;
|
||||
|
||||
cp = cmd->param;
|
||||
enable = cp->val;
|
||||
|
||||
if (err) {
|
||||
u8 mgmt_err = mgmt_status(err);
|
||||
|
||||
@ -1943,8 +1948,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
|
||||
new_settings(hdev, NULL);
|
||||
}
|
||||
|
||||
mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, cmd_status_rsp,
|
||||
&mgmt_err);
|
||||
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1954,7 +1958,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
|
||||
changed = hci_dev_test_and_clear_flag(hdev, HCI_SSP_ENABLED);
|
||||
}
|
||||
|
||||
mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match);
|
||||
settings_rsp(cmd, &match);
|
||||
|
||||
if (changed)
|
||||
new_settings(hdev, match.sk);
|
||||
@ -1968,14 +1972,25 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
|
||||
static int set_ssp_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_mode *cp = cmd->param;
|
||||
struct mgmt_mode cp;
|
||||
bool changed = false;
|
||||
int err;
|
||||
|
||||
if (cp->val)
|
||||
mutex_lock(&hdev->mgmt_pending_lock);
|
||||
|
||||
if (!__mgmt_pending_listed(hdev, cmd)) {
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
memcpy(&cp, cmd->param, sizeof(cp));
|
||||
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
|
||||
if (cp.val)
|
||||
changed = !hci_dev_test_and_set_flag(hdev, HCI_SSP_ENABLED);
|
||||
|
||||
err = hci_write_ssp_mode_sync(hdev, cp->val);
|
||||
err = hci_write_ssp_mode_sync(hdev, cp.val);
|
||||
|
||||
if (!err && changed)
|
||||
hci_dev_clear_flag(hdev, HCI_SSP_ENABLED);
|
||||
@ -2068,32 +2083,50 @@ static int set_hs(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
||||
|
||||
static void set_le_complete(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct cmd_lookup match = { NULL, hdev };
|
||||
u8 status = mgmt_status(err);
|
||||
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
if (status) {
|
||||
mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, cmd_status_rsp,
|
||||
&status);
|
||||
if (err == -ECANCELED || !mgmt_pending_valid(hdev, data))
|
||||
return;
|
||||
|
||||
if (status) {
|
||||
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, settings_rsp, &match);
|
||||
settings_rsp(cmd, &match);
|
||||
|
||||
new_settings(hdev, match.sk);
|
||||
|
||||
if (match.sk)
|
||||
sock_put(match.sk);
|
||||
|
||||
done:
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
static int set_le_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_mode *cp = cmd->param;
|
||||
u8 val = !!cp->val;
|
||||
struct mgmt_mode cp;
|
||||
u8 val;
|
||||
int err;
|
||||
|
||||
mutex_lock(&hdev->mgmt_pending_lock);
|
||||
|
||||
if (!__mgmt_pending_listed(hdev, cmd)) {
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
memcpy(&cp, cmd->param, sizeof(cp));
|
||||
val = !!cp.val;
|
||||
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
|
||||
if (!val) {
|
||||
hci_clear_adv_instance_sync(hdev, NULL, 0x00, true);
|
||||
|
||||
@ -2135,23 +2168,45 @@ static void set_mesh_complete(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
u8 status = mgmt_status(err);
|
||||
struct sock *sk = cmd->sk;
|
||||
struct sock *sk;
|
||||
|
||||
if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
|
||||
return;
|
||||
|
||||
sk = cmd->sk;
|
||||
|
||||
if (status) {
|
||||
mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev,
|
||||
mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER,
|
||||
status);
|
||||
mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, true,
|
||||
cmd_status_rsp, &status);
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
|
||||
mgmt_pending_remove(cmd);
|
||||
mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER, 0, NULL, 0);
|
||||
|
||||
done:
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
static int set_mesh_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_cp_set_mesh *cp = cmd->param;
|
||||
size_t len = cmd->param_len;
|
||||
DEFINE_FLEX(struct mgmt_cp_set_mesh, cp, ad_types, num_ad_types,
|
||||
sizeof(hdev->mesh_ad_types));
|
||||
size_t len;
|
||||
|
||||
mutex_lock(&hdev->mgmt_pending_lock);
|
||||
|
||||
if (!__mgmt_pending_listed(hdev, cmd)) {
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
len = cmd->param_len;
|
||||
memcpy(cp, cmd->param, min(__struct_size(cp), len));
|
||||
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
|
||||
memset(hdev->mesh_ad_types, 0, sizeof(hdev->mesh_ad_types));
|
||||
|
||||
@ -2160,7 +2215,10 @@ static int set_mesh_sync(struct hci_dev *hdev, void *data)
|
||||
else
|
||||
hci_dev_clear_flag(hdev, HCI_MESH);
|
||||
|
||||
len -= sizeof(*cp);
|
||||
hdev->le_scan_interval = __le16_to_cpu(cp->period);
|
||||
hdev->le_scan_window = __le16_to_cpu(cp->window);
|
||||
|
||||
len -= sizeof(struct mgmt_cp_set_mesh);
|
||||
|
||||
/* If filters don't fit, forward all adv pkts */
|
||||
if (len <= sizeof(hdev->mesh_ad_types))
|
||||
@ -2174,6 +2232,7 @@ static int set_mesh(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
||||
{
|
||||
struct mgmt_cp_set_mesh *cp = data;
|
||||
struct mgmt_pending_cmd *cmd;
|
||||
__u16 period, window;
|
||||
int err = 0;
|
||||
|
||||
bt_dev_dbg(hdev, "sock %p", sk);
|
||||
@ -2187,6 +2246,23 @@ static int set_mesh(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
||||
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER,
|
||||
MGMT_STATUS_INVALID_PARAMS);
|
||||
|
||||
/* Keep allowed ranges in sync with set_scan_params() */
|
||||
period = __le16_to_cpu(cp->period);
|
||||
|
||||
if (period < 0x0004 || period > 0x4000)
|
||||
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER,
|
||||
MGMT_STATUS_INVALID_PARAMS);
|
||||
|
||||
window = __le16_to_cpu(cp->window);
|
||||
|
||||
if (window < 0x0004 || window > 0x4000)
|
||||
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER,
|
||||
MGMT_STATUS_INVALID_PARAMS);
|
||||
|
||||
if (window > period)
|
||||
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER,
|
||||
MGMT_STATUS_INVALID_PARAMS);
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
cmd = mgmt_pending_add(sk, MGMT_OP_SET_MESH_RECEIVER, hdev, data, len);
|
||||
@ -2637,7 +2713,7 @@ static void mgmt_class_complete(struct hci_dev *hdev, void *data, int err)
|
||||
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
||||
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
|
||||
mgmt_status(err), hdev->dev_class, 3);
|
||||
|
||||
mgmt_pending_free(cmd);
|
||||
@ -3425,7 +3501,7 @@ static int pairing_complete(struct mgmt_pending_cmd *cmd, u8 status)
|
||||
bacpy(&rp.addr.bdaddr, &conn->dst);
|
||||
rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
|
||||
|
||||
err = mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE,
|
||||
err = mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_PAIR_DEVICE,
|
||||
status, &rp, sizeof(rp));
|
||||
|
||||
/* So we don't get further callbacks for this connection */
|
||||
@ -3851,15 +3927,16 @@ static int name_changed_sync(struct hci_dev *hdev, void *data)
|
||||
static void set_name_complete(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_cp_set_local_name *cp = cmd->param;
|
||||
struct mgmt_cp_set_local_name *cp;
|
||||
u8 status = mgmt_status(err);
|
||||
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
if (err == -ECANCELED ||
|
||||
cmd != pending_find(MGMT_OP_SET_LOCAL_NAME, hdev))
|
||||
if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
|
||||
return;
|
||||
|
||||
cp = cmd->param;
|
||||
|
||||
if (status) {
|
||||
mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
|
||||
status);
|
||||
@ -3871,13 +3948,27 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
|
||||
hci_cmd_sync_queue(hdev, name_changed_sync, NULL, NULL);
|
||||
}
|
||||
|
||||
mgmt_pending_remove(cmd);
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
static int set_name_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_cp_set_local_name cp;
|
||||
|
||||
mutex_lock(&hdev->mgmt_pending_lock);
|
||||
|
||||
if (!__mgmt_pending_listed(hdev, cmd)) {
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
memcpy(&cp, cmd->param, sizeof(cp));
|
||||
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
|
||||
if (lmp_bredr_capable(hdev)) {
|
||||
hci_update_name_sync(hdev);
|
||||
hci_update_name_sync(hdev, cp.name);
|
||||
hci_update_eir_sync(hdev);
|
||||
}
|
||||
|
||||
@ -4029,12 +4120,10 @@ int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip)
|
||||
static void set_default_phy_complete(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct sk_buff *skb = cmd->skb;
|
||||
struct sk_buff *skb;
|
||||
u8 status = mgmt_status(err);
|
||||
|
||||
if (err == -ECANCELED ||
|
||||
cmd != pending_find(MGMT_OP_SET_PHY_CONFIGURATION, hdev))
|
||||
return;
|
||||
skb = cmd->skb;
|
||||
|
||||
if (!status) {
|
||||
if (!skb)
|
||||
@ -4061,7 +4150,7 @@ static void set_default_phy_complete(struct hci_dev *hdev, void *data, int err)
|
||||
if (skb && !IS_ERR(skb))
|
||||
kfree_skb(skb);
|
||||
|
||||
mgmt_pending_remove(cmd);
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
static int set_default_phy_sync(struct hci_dev *hdev, void *data)
|
||||
@ -4069,7 +4158,9 @@ static int set_default_phy_sync(struct hci_dev *hdev, void *data)
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_cp_set_phy_configuration *cp = cmd->param;
|
||||
struct hci_cp_le_set_default_phy cp_phy;
|
||||
u32 selected_phys = __le32_to_cpu(cp->selected_phys);
|
||||
u32 selected_phys;
|
||||
|
||||
selected_phys = __le32_to_cpu(cp->selected_phys);
|
||||
|
||||
memset(&cp_phy, 0, sizeof(cp_phy));
|
||||
|
||||
@ -4209,7 +4300,7 @@ static int set_phy_configuration(struct sock *sk, struct hci_dev *hdev,
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
cmd = mgmt_pending_add(sk, MGMT_OP_SET_PHY_CONFIGURATION, hdev, data,
|
||||
cmd = mgmt_pending_new(sk, MGMT_OP_SET_PHY_CONFIGURATION, hdev, data,
|
||||
len);
|
||||
if (!cmd)
|
||||
err = -ENOMEM;
|
||||
@ -5106,24 +5197,14 @@ static void mgmt_adv_monitor_added(struct sock *sk, struct hci_dev *hdev,
|
||||
mgmt_event(MGMT_EV_ADV_MONITOR_ADDED, hdev, &ev, sizeof(ev), sk);
|
||||
}
|
||||
|
||||
void mgmt_adv_monitor_removed(struct hci_dev *hdev, u16 handle)
|
||||
static void mgmt_adv_monitor_removed(struct sock *sk, struct hci_dev *hdev,
|
||||
__le16 handle)
|
||||
{
|
||||
struct mgmt_ev_adv_monitor_removed ev;
|
||||
struct mgmt_pending_cmd *cmd;
|
||||
struct sock *sk_skip = NULL;
|
||||
struct mgmt_cp_remove_adv_monitor *cp;
|
||||
|
||||
cmd = pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev);
|
||||
if (cmd) {
|
||||
cp = cmd->param;
|
||||
ev.monitor_handle = handle;
|
||||
|
||||
if (cp->monitor_handle)
|
||||
sk_skip = cmd->sk;
|
||||
}
|
||||
|
||||
ev.monitor_handle = cpu_to_le16(handle);
|
||||
|
||||
mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk_skip);
|
||||
mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk);
|
||||
}
|
||||
|
||||
static int read_adv_mon_features(struct sock *sk, struct hci_dev *hdev,
|
||||
@ -5180,7 +5261,17 @@ static void mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev,
|
||||
{
|
||||
struct mgmt_rp_add_adv_patterns_monitor rp;
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct adv_monitor *monitor = cmd->user_data;
|
||||
struct adv_monitor *monitor;
|
||||
|
||||
/* This is likely the result of hdev being closed and mgmt_index_removed
|
||||
* is attempting to clean up any pending command so
|
||||
* hci_adv_monitors_clear is about to be called which will take care of
|
||||
* freeing the adv_monitor instances.
|
||||
*/
|
||||
if (status == -ECANCELED && !mgmt_pending_valid(hdev, cmd))
|
||||
return;
|
||||
|
||||
monitor = cmd->user_data;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
@ -5194,7 +5285,7 @@ static void mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev,
|
||||
hci_update_passive_scan(hdev);
|
||||
}
|
||||
|
||||
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
||||
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
|
||||
mgmt_status(status), &rp, sizeof(rp));
|
||||
mgmt_pending_remove(cmd);
|
||||
|
||||
@ -5206,9 +5297,20 @@ static void mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev,
|
||||
static int mgmt_add_adv_patterns_monitor_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct adv_monitor *monitor = cmd->user_data;
|
||||
struct adv_monitor *mon;
|
||||
|
||||
return hci_add_adv_monitor(hdev, monitor);
|
||||
mutex_lock(&hdev->mgmt_pending_lock);
|
||||
|
||||
if (!__mgmt_pending_listed(hdev, cmd)) {
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
mon = cmd->user_data;
|
||||
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
|
||||
return hci_add_adv_monitor(hdev, mon);
|
||||
}
|
||||
|
||||
static int __add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev,
|
||||
@ -5225,8 +5327,7 @@ static int __add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev,
|
||||
|
||||
if (pending_find(MGMT_OP_SET_LE, hdev) ||
|
||||
pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR, hdev) ||
|
||||
pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev) ||
|
||||
pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev)) {
|
||||
pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev)) {
|
||||
status = MGMT_STATUS_BUSY;
|
||||
goto unlock;
|
||||
}
|
||||
@ -5396,8 +5497,7 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev,
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_cp_remove_adv_monitor *cp;
|
||||
|
||||
if (status == -ECANCELED ||
|
||||
cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev))
|
||||
if (status == -ECANCELED)
|
||||
return;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
@ -5406,12 +5506,14 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev,
|
||||
|
||||
rp.monitor_handle = cp->monitor_handle;
|
||||
|
||||
if (!status)
|
||||
if (!status) {
|
||||
mgmt_adv_monitor_removed(cmd->sk, hdev, cp->monitor_handle);
|
||||
hci_update_passive_scan(hdev);
|
||||
}
|
||||
|
||||
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
||||
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
|
||||
mgmt_status(status), &rp, sizeof(rp));
|
||||
mgmt_pending_remove(cmd);
|
||||
mgmt_pending_free(cmd);
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
bt_dev_dbg(hdev, "remove monitor %d complete, status %d",
|
||||
@ -5421,10 +5523,6 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev,
|
||||
static int mgmt_remove_adv_monitor_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
|
||||
if (cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev))
|
||||
return -ECANCELED;
|
||||
|
||||
struct mgmt_cp_remove_adv_monitor *cp = cmd->param;
|
||||
u16 handle = __le16_to_cpu(cp->monitor_handle);
|
||||
|
||||
@ -5443,14 +5541,13 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
if (pending_find(MGMT_OP_SET_LE, hdev) ||
|
||||
pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev) ||
|
||||
pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR, hdev) ||
|
||||
pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev)) {
|
||||
status = MGMT_STATUS_BUSY;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
cmd = mgmt_pending_add(sk, MGMT_OP_REMOVE_ADV_MONITOR, hdev, data, len);
|
||||
cmd = mgmt_pending_new(sk, MGMT_OP_REMOVE_ADV_MONITOR, hdev, data, len);
|
||||
if (!cmd) {
|
||||
status = MGMT_STATUS_NO_RESOURCES;
|
||||
goto unlock;
|
||||
@ -5460,7 +5557,7 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
|
||||
mgmt_remove_adv_monitor_complete);
|
||||
|
||||
if (err) {
|
||||
mgmt_pending_remove(cmd);
|
||||
mgmt_pending_free(cmd);
|
||||
|
||||
if (err == -ENOMEM)
|
||||
status = MGMT_STATUS_NO_RESOURCES;
|
||||
@ -5480,7 +5577,8 @@ unlock:
|
||||
status);
|
||||
}
|
||||
|
||||
static void read_local_oob_data_complete(struct hci_dev *hdev, void *data, int err)
|
||||
static void read_local_oob_data_complete(struct hci_dev *hdev, void *data,
|
||||
int err)
|
||||
{
|
||||
struct mgmt_rp_read_local_oob_data mgmt_rp;
|
||||
size_t rp_size = sizeof(mgmt_rp);
|
||||
@ -5500,7 +5598,8 @@ static void read_local_oob_data_complete(struct hci_dev *hdev, void *data, int e
|
||||
bt_dev_dbg(hdev, "status %d", status);
|
||||
|
||||
if (status) {
|
||||
mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, status);
|
||||
mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
|
||||
status);
|
||||
goto remove;
|
||||
}
|
||||
|
||||
@ -5782,17 +5881,12 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err)
|
||||
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
if (err == -ECANCELED)
|
||||
if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
|
||||
return;
|
||||
|
||||
if (cmd != pending_find(MGMT_OP_START_DISCOVERY, hdev) &&
|
||||
cmd != pending_find(MGMT_OP_START_LIMITED_DISCOVERY, hdev) &&
|
||||
cmd != pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev))
|
||||
return;
|
||||
|
||||
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err),
|
||||
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err),
|
||||
cmd->param, 1);
|
||||
mgmt_pending_remove(cmd);
|
||||
mgmt_pending_free(cmd);
|
||||
|
||||
hci_discovery_set_state(hdev, err ? DISCOVERY_STOPPED:
|
||||
DISCOVERY_FINDING);
|
||||
@ -5800,6 +5894,9 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err)
|
||||
|
||||
static int start_discovery_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
if (!mgmt_pending_listed(hdev, data))
|
||||
return -ECANCELED;
|
||||
|
||||
return hci_start_discovery_sync(hdev);
|
||||
}
|
||||
|
||||
@ -6005,15 +6102,14 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
|
||||
if (err == -ECANCELED ||
|
||||
cmd != pending_find(MGMT_OP_STOP_DISCOVERY, hdev))
|
||||
if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
|
||||
return;
|
||||
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err),
|
||||
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err),
|
||||
cmd->param, 1);
|
||||
mgmt_pending_remove(cmd);
|
||||
mgmt_pending_free(cmd);
|
||||
|
||||
if (!err)
|
||||
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
|
||||
@ -6021,6 +6117,9 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err)
|
||||
|
||||
static int stop_discovery_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
if (!mgmt_pending_listed(hdev, data))
|
||||
return -ECANCELED;
|
||||
|
||||
return hci_stop_discovery_sync(hdev);
|
||||
}
|
||||
|
||||
@ -6230,14 +6329,18 @@ static void enable_advertising_instance(struct hci_dev *hdev, int err)
|
||||
|
||||
static void set_advertising_complete(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct cmd_lookup match = { NULL, hdev };
|
||||
u8 instance;
|
||||
struct adv_info *adv_instance;
|
||||
u8 status = mgmt_status(err);
|
||||
|
||||
if (err == -ECANCELED || !mgmt_pending_valid(hdev, data))
|
||||
return;
|
||||
|
||||
if (status) {
|
||||
mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev,
|
||||
cmd_status_rsp, &status);
|
||||
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, status);
|
||||
mgmt_pending_free(cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -6246,8 +6349,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err)
|
||||
else
|
||||
hci_dev_clear_flag(hdev, HCI_ADVERTISING);
|
||||
|
||||
mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp,
|
||||
&match);
|
||||
settings_rsp(cmd, &match);
|
||||
|
||||
new_settings(hdev, match.sk);
|
||||
|
||||
@ -6279,10 +6381,23 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err)
|
||||
static int set_adv_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_mode *cp = cmd->param;
|
||||
u8 val = !!cp->val;
|
||||
struct mgmt_mode cp;
|
||||
u8 val;
|
||||
|
||||
if (cp->val == 0x02)
|
||||
mutex_lock(&hdev->mgmt_pending_lock);
|
||||
|
||||
if (!__mgmt_pending_listed(hdev, cmd)) {
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
memcpy(&cp, cmd->param, sizeof(cp));
|
||||
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
|
||||
val = !!cp.val;
|
||||
|
||||
if (cp.val == 0x02)
|
||||
hci_dev_set_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
|
||||
else
|
||||
hci_dev_clear_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
|
||||
@ -6452,6 +6567,7 @@ static int set_scan_params(struct sock *sk, struct hci_dev *hdev,
|
||||
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
|
||||
MGMT_STATUS_NOT_SUPPORTED);
|
||||
|
||||
/* Keep allowed ranges in sync with set_mesh() */
|
||||
interval = __le16_to_cpu(cp->interval);
|
||||
|
||||
if (interval < 0x0004 || interval > 0x4000)
|
||||
@ -6590,7 +6706,7 @@ static void set_bredr_complete(struct hci_dev *hdev, void *data, int err)
|
||||
*/
|
||||
hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED);
|
||||
|
||||
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
|
||||
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
|
||||
} else {
|
||||
send_settings_rsp(cmd->sk, MGMT_OP_SET_BREDR, hdev);
|
||||
new_settings(hdev, cmd->sk);
|
||||
@ -6727,7 +6843,7 @@ static void set_secure_conn_complete(struct hci_dev *hdev, void *data, int err)
|
||||
if (err) {
|
||||
u8 mgmt_err = mgmt_status(err);
|
||||
|
||||
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
|
||||
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -7174,7 +7290,7 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err)
|
||||
rp.max_tx_power = HCI_TX_POWER_INVALID;
|
||||
}
|
||||
|
||||
mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status,
|
||||
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_GET_CONN_INFO, status,
|
||||
&rp, sizeof(rp));
|
||||
|
||||
mgmt_pending_free(cmd);
|
||||
@ -7335,7 +7451,7 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err)
|
||||
}
|
||||
|
||||
complete:
|
||||
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp,
|
||||
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, &rp,
|
||||
sizeof(rp));
|
||||
|
||||
mgmt_pending_free(cmd);
|
||||
@ -8035,10 +8151,6 @@ static void read_local_oob_ext_data_complete(struct hci_dev *hdev, void *data,
|
||||
u8 status = mgmt_status(err);
|
||||
u16 eir_len;
|
||||
|
||||
if (err == -ECANCELED ||
|
||||
cmd != pending_find(MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev))
|
||||
return;
|
||||
|
||||
if (!status) {
|
||||
if (!skb)
|
||||
status = MGMT_STATUS_FAILED;
|
||||
@ -8145,7 +8257,7 @@ done:
|
||||
kfree_skb(skb);
|
||||
|
||||
kfree(mgmt_rp);
|
||||
mgmt_pending_remove(cmd);
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
static int read_local_ssp_oob_req(struct hci_dev *hdev, struct sock *sk,
|
||||
@ -8154,7 +8266,7 @@ static int read_local_ssp_oob_req(struct hci_dev *hdev, struct sock *sk,
|
||||
struct mgmt_pending_cmd *cmd;
|
||||
int err;
|
||||
|
||||
cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev,
|
||||
cmd = mgmt_pending_new(sk, MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev,
|
||||
cp, sizeof(*cp));
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
@ -8585,10 +8697,10 @@ static void add_advertising_complete(struct hci_dev *hdev, void *data, int err)
|
||||
rp.instance = cp->instance;
|
||||
|
||||
if (err)
|
||||
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
|
||||
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
|
||||
mgmt_status(err));
|
||||
else
|
||||
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
||||
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
|
||||
mgmt_status(err), &rp, sizeof(rp));
|
||||
|
||||
add_adv_complete(hdev, cmd->sk, cp->instance, err);
|
||||
@ -8776,10 +8888,10 @@ static void add_ext_adv_params_complete(struct hci_dev *hdev, void *data,
|
||||
|
||||
hci_remove_adv_instance(hdev, cp->instance);
|
||||
|
||||
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
|
||||
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
|
||||
mgmt_status(err));
|
||||
} else {
|
||||
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
||||
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
|
||||
mgmt_status(err), &rp, sizeof(rp));
|
||||
}
|
||||
|
||||
@ -8926,10 +9038,10 @@ static void add_ext_adv_data_complete(struct hci_dev *hdev, void *data, int err)
|
||||
rp.instance = cp->instance;
|
||||
|
||||
if (err)
|
||||
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
|
||||
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
|
||||
mgmt_status(err));
|
||||
else
|
||||
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
||||
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
|
||||
mgmt_status(err), &rp, sizeof(rp));
|
||||
|
||||
mgmt_pending_free(cmd);
|
||||
@ -9088,10 +9200,10 @@ static void remove_advertising_complete(struct hci_dev *hdev, void *data,
|
||||
rp.instance = cp->instance;
|
||||
|
||||
if (err)
|
||||
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
|
||||
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
|
||||
mgmt_status(err));
|
||||
else
|
||||
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
||||
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
|
||||
MGMT_STATUS_SUCCESS, &rp, sizeof(rp));
|
||||
|
||||
mgmt_pending_free(cmd);
|
||||
@ -9363,7 +9475,7 @@ void mgmt_index_removed(struct hci_dev *hdev)
|
||||
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
|
||||
return;
|
||||
|
||||
mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match);
|
||||
mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match);
|
||||
|
||||
if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
|
||||
mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0,
|
||||
@ -9401,7 +9513,8 @@ void mgmt_power_on(struct hci_dev *hdev, int err)
|
||||
hci_update_passive_scan(hdev);
|
||||
}
|
||||
|
||||
mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
|
||||
mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp,
|
||||
&match);
|
||||
|
||||
new_settings(hdev, match.sk);
|
||||
|
||||
@ -9416,7 +9529,8 @@ void __mgmt_power_off(struct hci_dev *hdev)
|
||||
struct cmd_lookup match = { NULL, hdev };
|
||||
u8 zero_cod[] = { 0, 0, 0 };
|
||||
|
||||
mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
|
||||
mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp,
|
||||
&match);
|
||||
|
||||
/* If the power off is because of hdev unregistration let
|
||||
* use the appropriate INVALID_INDEX status. Otherwise use
|
||||
@ -9430,7 +9544,7 @@ void __mgmt_power_off(struct hci_dev *hdev)
|
||||
else
|
||||
match.mgmt_status = MGMT_STATUS_NOT_POWERED;
|
||||
|
||||
mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match);
|
||||
mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match);
|
||||
|
||||
if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) {
|
||||
mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev,
|
||||
@ -9671,7 +9785,6 @@ static void unpair_device_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
||||
device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk);
|
||||
|
||||
cmd->cmd_complete(cmd, 0);
|
||||
mgmt_pending_remove(cmd);
|
||||
}
|
||||
|
||||
bool mgmt_powering_down(struct hci_dev *hdev)
|
||||
@ -9727,8 +9840,8 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
struct mgmt_cp_disconnect *cp;
|
||||
struct mgmt_pending_cmd *cmd;
|
||||
|
||||
mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
|
||||
hdev);
|
||||
mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, true,
|
||||
unpair_device_rsp, hdev);
|
||||
|
||||
cmd = pending_find(MGMT_OP_DISCONNECT, hdev);
|
||||
if (!cmd)
|
||||
@ -9921,7 +10034,7 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
|
||||
|
||||
if (status) {
|
||||
u8 mgmt_err = mgmt_status(status);
|
||||
mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev,
|
||||
mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true,
|
||||
cmd_status_rsp, &mgmt_err);
|
||||
return;
|
||||
}
|
||||
@ -9931,8 +10044,8 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
|
||||
else
|
||||
changed = hci_dev_test_and_clear_flag(hdev, HCI_LINK_SECURITY);
|
||||
|
||||
mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp,
|
||||
&match);
|
||||
mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true,
|
||||
settings_rsp, &match);
|
||||
|
||||
if (changed)
|
||||
new_settings(hdev, match.sk);
|
||||
@ -9956,9 +10069,12 @@ void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
|
||||
{
|
||||
struct cmd_lookup match = { NULL, hdev, mgmt_status(status) };
|
||||
|
||||
mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, sk_lookup, &match);
|
||||
mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, sk_lookup, &match);
|
||||
mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match);
|
||||
mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, false, sk_lookup,
|
||||
&match);
|
||||
mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, false, sk_lookup,
|
||||
&match);
|
||||
mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, false, sk_lookup,
|
||||
&match);
|
||||
|
||||
if (!status) {
|
||||
mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class,
|
||||
|
||||
@ -217,30 +217,47 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
|
||||
struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode,
|
||||
struct hci_dev *hdev)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd;
|
||||
struct mgmt_pending_cmd *cmd, *tmp;
|
||||
|
||||
list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
|
||||
mutex_lock(&hdev->mgmt_pending_lock);
|
||||
|
||||
list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) {
|
||||
if (hci_sock_get_channel(cmd->sk) != channel)
|
||||
continue;
|
||||
if (cmd->opcode == opcode)
|
||||
|
||||
if (cmd->opcode == opcode) {
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
return cmd;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev,
|
||||
void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove,
|
||||
void (*cb)(struct mgmt_pending_cmd *cmd, void *data),
|
||||
void *data)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd, *tmp;
|
||||
|
||||
mutex_lock(&hdev->mgmt_pending_lock);
|
||||
|
||||
list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) {
|
||||
if (opcode > 0 && cmd->opcode != opcode)
|
||||
continue;
|
||||
|
||||
if (remove)
|
||||
list_del(&cmd->list);
|
||||
|
||||
cb(cmd, data);
|
||||
|
||||
if (remove)
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
}
|
||||
|
||||
struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode,
|
||||
@ -254,7 +271,7 @@ struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode,
|
||||
return NULL;
|
||||
|
||||
cmd->opcode = opcode;
|
||||
cmd->index = hdev->id;
|
||||
cmd->hdev = hdev;
|
||||
|
||||
cmd->param = kmemdup(data, len, GFP_KERNEL);
|
||||
if (!cmd->param) {
|
||||
@ -280,7 +297,9 @@ struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
|
||||
if (!cmd)
|
||||
return NULL;
|
||||
|
||||
mutex_lock(&hdev->mgmt_pending_lock);
|
||||
list_add_tail(&cmd->list, &hdev->mgmt_pending);
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
|
||||
return cmd;
|
||||
}
|
||||
@ -294,10 +313,59 @@ void mgmt_pending_free(struct mgmt_pending_cmd *cmd)
|
||||
|
||||
void mgmt_pending_remove(struct mgmt_pending_cmd *cmd)
|
||||
{
|
||||
mutex_lock(&cmd->hdev->mgmt_pending_lock);
|
||||
list_del(&cmd->list);
|
||||
mutex_unlock(&cmd->hdev->mgmt_pending_lock);
|
||||
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
bool __mgmt_pending_listed(struct hci_dev *hdev, struct mgmt_pending_cmd *cmd)
|
||||
{
|
||||
struct mgmt_pending_cmd *tmp;
|
||||
|
||||
lockdep_assert_held(&hdev->mgmt_pending_lock);
|
||||
|
||||
if (!cmd)
|
||||
return false;
|
||||
|
||||
list_for_each_entry(tmp, &hdev->mgmt_pending, list) {
|
||||
if (cmd == tmp)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mgmt_pending_listed(struct hci_dev *hdev, struct mgmt_pending_cmd *cmd)
|
||||
{
|
||||
bool listed;
|
||||
|
||||
mutex_lock(&hdev->mgmt_pending_lock);
|
||||
listed = __mgmt_pending_listed(hdev, cmd);
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
|
||||
return listed;
|
||||
}
|
||||
|
||||
bool mgmt_pending_valid(struct hci_dev *hdev, struct mgmt_pending_cmd *cmd)
|
||||
{
|
||||
bool listed;
|
||||
|
||||
if (!cmd)
|
||||
return false;
|
||||
|
||||
mutex_lock(&hdev->mgmt_pending_lock);
|
||||
|
||||
listed = __mgmt_pending_listed(hdev, cmd);
|
||||
if (listed)
|
||||
list_del(&cmd->list);
|
||||
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
|
||||
return listed;
|
||||
}
|
||||
|
||||
void mgmt_mesh_foreach(struct hci_dev *hdev,
|
||||
void (*cb)(struct mgmt_mesh_tx *mesh_tx, void *data),
|
||||
void *data, struct sock *sk)
|
||||
|
||||
@ -33,7 +33,7 @@ struct mgmt_mesh_tx {
|
||||
struct mgmt_pending_cmd {
|
||||
struct list_head list;
|
||||
u16 opcode;
|
||||
int index;
|
||||
struct hci_dev *hdev;
|
||||
void *param;
|
||||
size_t param_len;
|
||||
struct sock *sk;
|
||||
@ -54,7 +54,7 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
|
||||
|
||||
struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode,
|
||||
struct hci_dev *hdev);
|
||||
void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev,
|
||||
void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove,
|
||||
void (*cb)(struct mgmt_pending_cmd *cmd, void *data),
|
||||
void *data);
|
||||
struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
|
||||
@ -65,6 +65,9 @@ struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode,
|
||||
void *data, u16 len);
|
||||
void mgmt_pending_free(struct mgmt_pending_cmd *cmd);
|
||||
void mgmt_pending_remove(struct mgmt_pending_cmd *cmd);
|
||||
bool __mgmt_pending_listed(struct hci_dev *hdev, struct mgmt_pending_cmd *cmd);
|
||||
bool mgmt_pending_listed(struct hci_dev *hdev, struct mgmt_pending_cmd *cmd);
|
||||
bool mgmt_pending_valid(struct hci_dev *hdev, struct mgmt_pending_cmd *cmd);
|
||||
void mgmt_mesh_foreach(struct hci_dev *hdev,
|
||||
void (*cb)(struct mgmt_mesh_tx *mesh_tx, void *data),
|
||||
void *data, struct sock *sk);
|
||||
|
||||
@ -3162,6 +3162,7 @@ int tcp_disconnect(struct sock *sk, int flags)
|
||||
struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
int old_state = sk->sk_state;
|
||||
struct request_sock *req;
|
||||
u32 seq;
|
||||
|
||||
if (old_state != TCP_CLOSE)
|
||||
@ -3272,6 +3273,10 @@ int tcp_disconnect(struct sock *sk, int flags)
|
||||
|
||||
|
||||
/* Clean up fastopen related fields */
|
||||
req = rcu_dereference_protected(tp->fastopen_rsk,
|
||||
lockdep_sock_is_held(sk));
|
||||
if (req)
|
||||
reqsk_fastopen_remove(sk, req, false);
|
||||
tcp_free_fastopen_req(tp);
|
||||
inet->defer_connect = 0;
|
||||
tp->fastopen_client_fail = 0;
|
||||
|
||||
@ -7111,7 +7111,6 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
|
||||
&foc, TCP_SYNACK_FASTOPEN, skb);
|
||||
/* Add the child socket directly into the accept queue */
|
||||
if (!inet_csk_reqsk_queue_add(sk, req, fastopen_sk)) {
|
||||
reqsk_fastopen_remove(fastopen_sk, req, false);
|
||||
bh_unlock_sock(fastopen_sk);
|
||||
sock_put(fastopen_sk);
|
||||
goto drop_and_free;
|
||||
|
||||
@ -1905,6 +1905,7 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
|
||||
*/
|
||||
|
||||
f = rcu_access_pointer(new->pub.beacon_ies);
|
||||
if (!new->pub.hidden_beacon_bss)
|
||||
kfree_rcu((struct cfg80211_bss_ies *)f, rcu_head);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,3 +1,27 @@
|
||||
* Tue Nov 25 2025 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-611.11.1.el9_7]
|
||||
- tcp: Don't call reqsk_fastopen_remove() in tcp_conn_request(). (Antoine Tenart) [RHEL-120668]
|
||||
- tcp: Clear tcp_sk(sk)->fastopen_rsk in tcp_disconnect(). (Antoine Tenart) [RHEL-120668] {CVE-2025-39955}
|
||||
- Bluetooth: MGMT: fix crash in set_mesh_sync and set_mesh_complete (CKI Backport Bot) [RHEL-122892] {CVE-2025-39981}
|
||||
- Bluetooth: MGMT: Fix sparse errors (CKI Backport Bot) [RHEL-122892] {CVE-2025-39981}
|
||||
- Bluetooth: MGMT: Fix possible UAFs (CKI Backport Bot) [RHEL-122892] {CVE-2025-39981}
|
||||
- Bluetooth: hci_sync: fix set_local_name race condition (CKI Backport Bot) [RHEL-122892] {CVE-2025-39981}
|
||||
- Bluetooth: MGMT: set_mesh: update LE scan interval and window (CKI Backport Bot) [RHEL-122892] {CVE-2025-39981}
|
||||
- Bluetooth: MGMT: Protect mgmt_pending list with its own lock (CKI Backport Bot) [RHEL-122892] {CVE-2025-39981}
|
||||
- Bluetooth: MGMT: Fix UAF on mgmt_remove_adv_monitor_complete (CKI Backport Bot) [RHEL-122892] {CVE-2025-39981}
|
||||
- wifi: mt76: free pending offchannel tx frames on wcid cleanup (Jose Ignacio Tornos Martinez) [RHEL-123064]
|
||||
- wifi: mt76: do not add non-sta wcid entries to the poll list (Jose Ignacio Tornos Martinez) [RHEL-123064]
|
||||
- wifi: mt76: fix linked list corruption (Jose Ignacio Tornos Martinez) [RHEL-123064] {CVE-2025-39918}
|
||||
Resolves: RHEL-120668, RHEL-122892, RHEL-123064
|
||||
|
||||
* Thu Nov 20 2025 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-611.10.1.el9_7]
|
||||
- ice: ice_adapter: release xa entry on adapter allocation failure (CKI Backport Bot) [RHEL-128469] {CVE-2025-40185}
|
||||
- iommu/vt-d: Disallow dirty tracking if incoherent page walk (Eder Zulian) [RHEL-125478] {CVE-2025-40058}
|
||||
- e1000e: fix heap overflow in e1000_set_eeprom (Corinna Vinschen) [RHEL-123111] {CVE-2025-39898}
|
||||
- nfsd: handle get_client_locked() failure in nfsd4_setclientid_confirm() (CKI Backport Bot) [RHEL-125604] {CVE-2025-38724}
|
||||
- wifi: cfg80211: fix use-after-free in cmp_bss() (CKI Backport Bot) [RHEL-122874] {CVE-2025-39864}
|
||||
- platform/x86/intel: power-domains: Use topology_logical_package_id() for package ID (Jay Shin) [RHEL-116680]
|
||||
Resolves: RHEL-116680, RHEL-122874, RHEL-123111, RHEL-125478, RHEL-125604, RHEL-128469
|
||||
|
||||
* Sat Nov 15 2025 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-611.9.1.el9_7]
|
||||
- NFSv4: handle ERR_GRACE on delegation recalls (Olga Kornievskaia) [RHEL-124651]
|
||||
- nfsd: nfserr_jukebox in nlm_fopen should lead to a retry (Olga Kornievskaia) [RHEL-124651]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user