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.
|
# Use this spot to avoid future merge conflicts.
|
||||||
# Do not trim this comment.
|
# Do not trim this comment.
|
||||||
RHEL_RELEASE = 611.9.1
|
RHEL_RELEASE = 611.11.1
|
||||||
|
|
||||||
#
|
#
|
||||||
# ZSTREAM
|
# ZSTREAM
|
||||||
|
|||||||
@ -542,7 +542,8 @@ enum {
|
|||||||
#define pasid_supported(iommu) (sm_supported(iommu) && \
|
#define pasid_supported(iommu) (sm_supported(iommu) && \
|
||||||
ecap_pasid((iommu)->ecap))
|
ecap_pasid((iommu)->ecap))
|
||||||
#define ssads_supported(iommu) (sm_supported(iommu) && \
|
#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) && \
|
#define nested_supported(iommu) (sm_supported(iommu) && \
|
||||||
ecap_nest((iommu)->ecap))
|
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_adapter *adapter = netdev_priv(netdev);
|
||||||
struct e1000_hw *hw = &adapter->hw;
|
struct e1000_hw *hw = &adapter->hw;
|
||||||
|
size_t total_len, max_len;
|
||||||
u16 *eeprom_buff;
|
u16 *eeprom_buff;
|
||||||
void *ptr;
|
int ret_val = 0;
|
||||||
int max_len;
|
|
||||||
int first_word;
|
int first_word;
|
||||||
int last_word;
|
int last_word;
|
||||||
int ret_val = 0;
|
void *ptr;
|
||||||
u16 i;
|
u16 i;
|
||||||
|
|
||||||
if (eeprom->len == 0)
|
if (eeprom->len == 0)
|
||||||
@ -569,6 +569,10 @@ static int e1000_set_eeprom(struct net_device *netdev,
|
|||||||
|
|
||||||
max_len = hw->nvm.word_size * 2;
|
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;
|
first_word = eeprom->offset >> 1;
|
||||||
last_word = (eeprom->offset + eeprom->len - 1) >> 1;
|
last_word = (eeprom->offset + eeprom->len - 1) >> 1;
|
||||||
eeprom_buff = kmalloc(max_len, GFP_KERNEL);
|
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);
|
index = ice_adapter_xa_index(pdev);
|
||||||
scoped_guard(mutex, &ice_adapters_mutex) {
|
scoped_guard(mutex, &ice_adapters_mutex) {
|
||||||
err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL);
|
adapter = xa_load(&ice_adapters, index);
|
||||||
if (err == -EBUSY) {
|
if (adapter) {
|
||||||
adapter = xa_load(&ice_adapters, index);
|
|
||||||
refcount_inc(&adapter->refcount);
|
refcount_inc(&adapter->refcount);
|
||||||
WARN_ON_ONCE(adapter->index != ice_adapter_index(pdev));
|
WARN_ON_ONCE(adapter->index != ice_adapter_index(pdev));
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
|
err = xa_reserve(&ice_adapters, index, GFP_KERNEL);
|
||||||
if (err)
|
if (err)
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
|
|
||||||
adapter = ice_adapter_new(pdev);
|
adapter = ice_adapter_new(pdev);
|
||||||
if (!adapter)
|
if (!adapter) {
|
||||||
|
xa_release(&ice_adapters, index);
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
}
|
||||||
xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
|
xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
|
||||||
}
|
}
|
||||||
return adapter;
|
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);
|
skb_queue_splice_tail_init(&wcid->tx_pending, &list);
|
||||||
spin_unlock(&wcid->tx_pending.lock);
|
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);
|
spin_unlock_bh(&phy->tx_lock);
|
||||||
|
|
||||||
while ((skb = __skb_dequeue(&list)) != NULL) {
|
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)
|
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;
|
return;
|
||||||
|
|
||||||
spin_lock_bh(&dev->sta_poll_lock);
|
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)
|
static void mt76_txq_schedule_pending(struct mt76_phy *phy)
|
||||||
{
|
{
|
||||||
LIST_HEAD(tx_list);
|
LIST_HEAD(tx_list);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (list_empty(&phy->tx_list))
|
if (list_empty(&phy->tx_list))
|
||||||
return;
|
return;
|
||||||
@ -656,13 +657,13 @@ static void mt76_txq_schedule_pending(struct mt76_phy *phy)
|
|||||||
list_splice_init(&phy->tx_list, &tx_list);
|
list_splice_init(&phy->tx_list, &tx_list);
|
||||||
while (!list_empty(&tx_list)) {
|
while (!list_empty(&tx_list)) {
|
||||||
struct mt76_wcid *wcid;
|
struct mt76_wcid *wcid;
|
||||||
int ret;
|
|
||||||
|
|
||||||
wcid = list_first_entry(&tx_list, struct mt76_wcid, tx_list);
|
wcid = list_first_entry(&tx_list, struct mt76_wcid, tx_list);
|
||||||
list_del_init(&wcid->tx_list);
|
list_del_init(&wcid->tx_list);
|
||||||
|
|
||||||
spin_unlock(&phy->tx_lock);
|
spin_unlock(&phy->tx_lock);
|
||||||
ret = mt76_txq_schedule_pending_wcid(phy, wcid, &wcid->tx_offchannel);
|
if (ret >= 0)
|
||||||
|
ret = mt76_txq_schedule_pending_wcid(phy, wcid, &wcid->tx_offchannel);
|
||||||
if (ret >= 0 && !phy->offchannel)
|
if (ret >= 0 && !phy->offchannel)
|
||||||
ret = mt76_txq_schedule_pending_wcid(phy, wcid, &wcid->tx_pending);
|
ret = mt76_txq_schedule_pending_wcid(phy, wcid, &wcid->tx_pending);
|
||||||
spin_lock(&phy->tx_lock);
|
spin_lock(&phy->tx_lock);
|
||||||
@ -671,9 +672,6 @@ static void mt76_txq_schedule_pending(struct mt76_phy *phy)
|
|||||||
!skb_queue_empty(&wcid->tx_offchannel) &&
|
!skb_queue_empty(&wcid->tx_offchannel) &&
|
||||||
list_empty(&wcid->tx_list))
|
list_empty(&wcid->tx_list))
|
||||||
list_add_tail(&wcid->tx_list, &phy->tx_list);
|
list_add_tail(&wcid->tx_list, &phy->tx_list);
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
spin_unlock(&phy->tx_lock);
|
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_thread_id = FIELD_GET(LP_ID_MASK, data);
|
||||||
info->punit_core_id = FIELD_GET(MODULE_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;
|
info->linux_cpu = cpu;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -4543,10 +4543,16 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
|
|||||||
}
|
}
|
||||||
status = nfs_ok;
|
status = nfs_ok;
|
||||||
if (conf) {
|
if (conf) {
|
||||||
old = unconf;
|
if (get_client_locked(conf) == nfs_ok) {
|
||||||
unhash_client_locked(old);
|
old = unconf;
|
||||||
nfsd4_change_callback(conf, &unconf->cl_cb_conn);
|
unhash_client_locked(old);
|
||||||
} else {
|
nfsd4_change_callback(conf, &unconf->cl_cb_conn);
|
||||||
|
} else {
|
||||||
|
conf = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!conf) {
|
||||||
old = find_confirmed_client_by_name(&unconf->cl_name, nn);
|
old = find_confirmed_client_by_name(&unconf->cl_name, nn);
|
||||||
if (old) {
|
if (old) {
|
||||||
status = nfserr_clid_inuse;
|
status = nfserr_clid_inuse;
|
||||||
@ -4563,10 +4569,14 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
|
|||||||
}
|
}
|
||||||
trace_nfsd_clid_replaced(&old->cl_clientid);
|
trace_nfsd_clid_replaced(&old->cl_clientid);
|
||||||
}
|
}
|
||||||
|
status = get_client_locked(unconf);
|
||||||
|
if (status != nfs_ok) {
|
||||||
|
old = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
move_to_confirmed(unconf);
|
move_to_confirmed(unconf);
|
||||||
conf = unconf;
|
conf = unconf;
|
||||||
}
|
}
|
||||||
get_client_locked(conf);
|
|
||||||
spin_unlock(&nn->client_lock);
|
spin_unlock(&nn->client_lock);
|
||||||
if (conf == unconf)
|
if (conf == unconf)
|
||||||
fsnotify_dentry(conf->cl_nfsd_info_dentry, FS_MODIFY);
|
fsnotify_dentry(conf->cl_nfsd_info_dentry, FS_MODIFY);
|
||||||
|
|||||||
@ -542,6 +542,7 @@ struct hci_dev {
|
|||||||
struct hci_conn_hash conn_hash;
|
struct hci_conn_hash conn_hash;
|
||||||
|
|
||||||
struct list_head mesh_pending;
|
struct list_head mesh_pending;
|
||||||
|
struct mutex mgmt_pending_lock;
|
||||||
struct list_head mgmt_pending;
|
struct list_head mgmt_pending;
|
||||||
struct list_head reject_list;
|
struct list_head reject_list;
|
||||||
struct list_head accept_list;
|
struct list_head accept_list;
|
||||||
@ -2409,7 +2410,6 @@ void mgmt_advertising_added(struct sock *sk, struct hci_dev *hdev,
|
|||||||
u8 instance);
|
u8 instance);
|
||||||
void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev,
|
void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev,
|
||||||
u8 instance);
|
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);
|
int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip);
|
||||||
void mgmt_adv_monitor_device_lost(struct hci_dev *hdev, u16 handle,
|
void mgmt_adv_monitor_device_lost(struct hci_dev *hdev, u16 handle,
|
||||||
bdaddr_t *bdaddr, u8 addr_type);
|
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_eir_sync(struct hci_dev *hdev);
|
||||||
int hci_update_class_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_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode);
|
||||||
|
|
||||||
int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
|
int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
|
||||||
|
|||||||
@ -848,7 +848,7 @@ struct mgmt_cp_set_mesh {
|
|||||||
__le16 window;
|
__le16 window;
|
||||||
__le16 period;
|
__le16 period;
|
||||||
__u8 num_ad_types;
|
__u8 num_ad_types;
|
||||||
__u8 ad_types[];
|
__u8 ad_types[] __counted_by(num_ad_types);
|
||||||
} __packed;
|
} __packed;
|
||||||
#define MGMT_SET_MESH_RECEIVER_SIZE 6
|
#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)
|
if (monitor->handle)
|
||||||
idr_remove(&hdev->adv_monitors_idr, 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--;
|
hdev->adv_monitors_cnt--;
|
||||||
mgmt_adv_monitor_removed(hdev, monitor->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
kfree(monitor);
|
kfree(monitor);
|
||||||
}
|
}
|
||||||
@ -2510,6 +2508,7 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
|
|||||||
|
|
||||||
mutex_init(&hdev->lock);
|
mutex_init(&hdev->lock);
|
||||||
mutex_init(&hdev->req_lock);
|
mutex_init(&hdev->req_lock);
|
||||||
|
mutex_init(&hdev->mgmt_pending_lock);
|
||||||
|
|
||||||
ida_init(&hdev->unset_handle_ida);
|
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);
|
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;
|
struct hci_cp_write_local_name cp;
|
||||||
|
|
||||||
memset(&cp, 0, sizeof(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,
|
return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME,
|
||||||
sizeof(cp), &cp,
|
sizeof(cp), &cp,
|
||||||
@ -3471,7 +3471,7 @@ int hci_powered_update_sync(struct hci_dev *hdev)
|
|||||||
hci_write_fast_connectable_sync(hdev, false);
|
hci_write_fast_connectable_sync(hdev, false);
|
||||||
hci_update_scan_sync(hdev);
|
hci_update_scan_sync(hdev);
|
||||||
hci_update_class_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);
|
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;
|
struct mgmt_mode *cp;
|
||||||
|
|
||||||
/* Make sure cmd still outstanding. */
|
/* Make sure cmd still outstanding. */
|
||||||
if (err == -ECANCELED ||
|
if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
|
||||||
cmd != pending_find(MGMT_OP_SET_POWERED, hdev))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cp = cmd->param;
|
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_status(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
mgmt_pending_remove(cmd);
|
mgmt_pending_free(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_powered_sync(struct hci_dev *hdev, void *data)
|
static int set_powered_sync(struct hci_dev *hdev, void *data)
|
||||||
{
|
{
|
||||||
struct mgmt_pending_cmd *cmd = 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. */
|
/* 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;
|
return -ECANCELED;
|
||||||
|
}
|
||||||
|
|
||||||
cp = cmd->param;
|
memcpy(&cp, cmd->param, sizeof(cp));
|
||||||
|
|
||||||
|
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||||
|
|
||||||
BT_DBG("%s", hdev->name);
|
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,
|
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);
|
send_settings_rsp(cmd->sk, cmd->opcode, match->hdev);
|
||||||
|
|
||||||
list_del(&cmd->list);
|
|
||||||
|
|
||||||
if (match->sk == NULL) {
|
if (match->sk == NULL) {
|
||||||
match->sk = cmd->sk;
|
match->sk = cmd->sk;
|
||||||
sock_hold(match->sk);
|
sock_hold(match->sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
mgmt_pending_free(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
||||||
{
|
{
|
||||||
u8 *status = data;
|
u8 *status = data;
|
||||||
|
|
||||||
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, *status);
|
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, *status);
|
||||||
mgmt_pending_remove(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
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) {
|
if (cmd->cmd_complete) {
|
||||||
cmd->cmd_complete(cmd, match->mgmt_status);
|
cmd->cmd_complete(cmd, match->mgmt_status);
|
||||||
mgmt_pending_remove(cmd);
|
|
||||||
|
|
||||||
return;
|
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)
|
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);
|
cmd->param, cmd->param_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int addr_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
|
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));
|
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);
|
bt_dev_dbg(hdev, "err %d", err);
|
||||||
|
|
||||||
/* Make sure cmd still outstanding. */
|
/* Make sure cmd still outstanding. */
|
||||||
if (err == -ECANCELED ||
|
if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
|
||||||
cmd != pending_find(MGMT_OP_SET_DISCOVERABLE, hdev))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hci_dev_lock(hdev);
|
hci_dev_lock(hdev);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
u8 mgmt_err = mgmt_status(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);
|
hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -1547,12 +1544,15 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
|
|||||||
new_settings(hdev, cmd->sk);
|
new_settings(hdev, cmd->sk);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
mgmt_pending_remove(cmd);
|
mgmt_pending_free(cmd);
|
||||||
hci_dev_unlock(hdev);
|
hci_dev_unlock(hdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_discoverable_sync(struct hci_dev *hdev, void *data)
|
static int set_discoverable_sync(struct hci_dev *hdev, void *data)
|
||||||
{
|
{
|
||||||
|
if (!mgmt_pending_listed(hdev, data))
|
||||||
|
return -ECANCELED;
|
||||||
|
|
||||||
BT_DBG("%s", hdev->name);
|
BT_DBG("%s", hdev->name);
|
||||||
|
|
||||||
return hci_update_discoverable_sync(hdev);
|
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);
|
bt_dev_dbg(hdev, "err %d", err);
|
||||||
|
|
||||||
/* Make sure cmd still outstanding. */
|
/* Make sure cmd still outstanding. */
|
||||||
if (err == -ECANCELED ||
|
if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
|
||||||
cmd != pending_find(MGMT_OP_SET_CONNECTABLE, hdev))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hci_dev_lock(hdev);
|
hci_dev_lock(hdev);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
u8 mgmt_err = mgmt_status(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;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1715,7 +1714,7 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
|
|||||||
new_settings(hdev, cmd->sk);
|
new_settings(hdev, cmd->sk);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
mgmt_pending_remove(cmd);
|
mgmt_pending_free(cmd);
|
||||||
|
|
||||||
hci_dev_unlock(hdev);
|
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)
|
static int set_connectable_sync(struct hci_dev *hdev, void *data)
|
||||||
{
|
{
|
||||||
|
if (!mgmt_pending_listed(hdev, data))
|
||||||
|
return -ECANCELED;
|
||||||
|
|
||||||
BT_DBG("%s", hdev->name);
|
BT_DBG("%s", hdev->name);
|
||||||
|
|
||||||
return hci_update_connectable_sync(hdev);
|
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 cmd_lookup match = { NULL, hdev };
|
||||||
struct mgmt_pending_cmd *cmd = data;
|
struct mgmt_pending_cmd *cmd = data;
|
||||||
struct mgmt_mode *cp = cmd->param;
|
struct mgmt_mode *cp;
|
||||||
u8 enable = cp->val;
|
u8 enable;
|
||||||
bool changed;
|
bool changed;
|
||||||
|
|
||||||
/* Make sure cmd still outstanding. */
|
/* 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;
|
return;
|
||||||
|
|
||||||
|
cp = cmd->param;
|
||||||
|
enable = cp->val;
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
u8 mgmt_err = mgmt_status(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);
|
new_settings(hdev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, cmd_status_rsp,
|
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
|
||||||
&mgmt_err);
|
|
||||||
return;
|
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);
|
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)
|
if (changed)
|
||||||
new_settings(hdev, match.sk);
|
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)
|
static int set_ssp_sync(struct hci_dev *hdev, void *data)
|
||||||
{
|
{
|
||||||
struct mgmt_pending_cmd *cmd = data;
|
struct mgmt_pending_cmd *cmd = data;
|
||||||
struct mgmt_mode *cp = cmd->param;
|
struct mgmt_mode cp;
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
int err;
|
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);
|
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)
|
if (!err && changed)
|
||||||
hci_dev_clear_flag(hdev, HCI_SSP_ENABLED);
|
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)
|
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 };
|
struct cmd_lookup match = { NULL, hdev };
|
||||||
u8 status = mgmt_status(err);
|
u8 status = mgmt_status(err);
|
||||||
|
|
||||||
bt_dev_dbg(hdev, "err %d", err);
|
bt_dev_dbg(hdev, "err %d", err);
|
||||||
|
|
||||||
if (status) {
|
if (err == -ECANCELED || !mgmt_pending_valid(hdev, data))
|
||||||
mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, cmd_status_rsp,
|
|
||||||
&status);
|
|
||||||
return;
|
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);
|
new_settings(hdev, match.sk);
|
||||||
|
|
||||||
if (match.sk)
|
if (match.sk)
|
||||||
sock_put(match.sk);
|
sock_put(match.sk);
|
||||||
|
|
||||||
|
done:
|
||||||
|
mgmt_pending_free(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_le_sync(struct hci_dev *hdev, void *data)
|
static int set_le_sync(struct hci_dev *hdev, void *data)
|
||||||
{
|
{
|
||||||
struct mgmt_pending_cmd *cmd = data;
|
struct mgmt_pending_cmd *cmd = data;
|
||||||
struct mgmt_mode *cp = cmd->param;
|
struct mgmt_mode cp;
|
||||||
u8 val = !!cp->val;
|
u8 val;
|
||||||
int err;
|
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) {
|
if (!val) {
|
||||||
hci_clear_adv_instance_sync(hdev, NULL, 0x00, true);
|
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;
|
struct mgmt_pending_cmd *cmd = data;
|
||||||
u8 status = mgmt_status(err);
|
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) {
|
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);
|
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);
|
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)
|
static int set_mesh_sync(struct hci_dev *hdev, void *data)
|
||||||
{
|
{
|
||||||
struct mgmt_pending_cmd *cmd = data;
|
struct mgmt_pending_cmd *cmd = data;
|
||||||
struct mgmt_cp_set_mesh *cp = cmd->param;
|
DEFINE_FLEX(struct mgmt_cp_set_mesh, cp, ad_types, num_ad_types,
|
||||||
size_t len = cmd->param_len;
|
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));
|
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
|
else
|
||||||
hci_dev_clear_flag(hdev, HCI_MESH);
|
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 filters don't fit, forward all adv pkts */
|
||||||
if (len <= sizeof(hdev->mesh_ad_types))
|
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_cp_set_mesh *cp = data;
|
||||||
struct mgmt_pending_cmd *cmd;
|
struct mgmt_pending_cmd *cmd;
|
||||||
|
__u16 period, window;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
bt_dev_dbg(hdev, "sock %p", sk);
|
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,
|
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER,
|
||||||
MGMT_STATUS_INVALID_PARAMS);
|
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);
|
hci_dev_lock(hdev);
|
||||||
|
|
||||||
cmd = mgmt_pending_add(sk, MGMT_OP_SET_MESH_RECEIVER, hdev, data, len);
|
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);
|
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_status(err), hdev->dev_class, 3);
|
||||||
|
|
||||||
mgmt_pending_free(cmd);
|
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);
|
bacpy(&rp.addr.bdaddr, &conn->dst);
|
||||||
rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
|
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));
|
status, &rp, sizeof(rp));
|
||||||
|
|
||||||
/* So we don't get further callbacks for this connection */
|
/* 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)
|
static void set_name_complete(struct hci_dev *hdev, void *data, int err)
|
||||||
{
|
{
|
||||||
struct mgmt_pending_cmd *cmd = data;
|
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);
|
u8 status = mgmt_status(err);
|
||||||
|
|
||||||
bt_dev_dbg(hdev, "err %d", err);
|
bt_dev_dbg(hdev, "err %d", err);
|
||||||
|
|
||||||
if (err == -ECANCELED ||
|
if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
|
||||||
cmd != pending_find(MGMT_OP_SET_LOCAL_NAME, hdev))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
cp = cmd->param;
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
|
mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
|
||||||
status);
|
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);
|
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)
|
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)) {
|
if (lmp_bredr_capable(hdev)) {
|
||||||
hci_update_name_sync(hdev);
|
hci_update_name_sync(hdev, cp.name);
|
||||||
hci_update_eir_sync(hdev);
|
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)
|
static void set_default_phy_complete(struct hci_dev *hdev, void *data, int err)
|
||||||
{
|
{
|
||||||
struct mgmt_pending_cmd *cmd = data;
|
struct mgmt_pending_cmd *cmd = data;
|
||||||
struct sk_buff *skb = cmd->skb;
|
struct sk_buff *skb;
|
||||||
u8 status = mgmt_status(err);
|
u8 status = mgmt_status(err);
|
||||||
|
|
||||||
if (err == -ECANCELED ||
|
skb = cmd->skb;
|
||||||
cmd != pending_find(MGMT_OP_SET_PHY_CONFIGURATION, hdev))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!status) {
|
if (!status) {
|
||||||
if (!skb)
|
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))
|
if (skb && !IS_ERR(skb))
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
|
||||||
mgmt_pending_remove(cmd);
|
mgmt_pending_free(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_default_phy_sync(struct hci_dev *hdev, void *data)
|
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_pending_cmd *cmd = data;
|
||||||
struct mgmt_cp_set_phy_configuration *cp = cmd->param;
|
struct mgmt_cp_set_phy_configuration *cp = cmd->param;
|
||||||
struct hci_cp_le_set_default_phy cp_phy;
|
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));
|
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;
|
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);
|
len);
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
err = -ENOMEM;
|
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);
|
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_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);
|
ev.monitor_handle = handle;
|
||||||
if (cmd) {
|
|
||||||
cp = cmd->param;
|
|
||||||
|
|
||||||
if (cp->monitor_handle)
|
mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk);
|
||||||
sk_skip = cmd->sk;
|
|
||||||
}
|
|
||||||
|
|
||||||
ev.monitor_handle = cpu_to_le16(handle);
|
|
||||||
|
|
||||||
mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk_skip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_adv_mon_features(struct sock *sk, struct hci_dev *hdev,
|
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_rp_add_adv_patterns_monitor rp;
|
||||||
struct mgmt_pending_cmd *cmd = data;
|
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);
|
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);
|
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_status(status), &rp, sizeof(rp));
|
||||||
mgmt_pending_remove(cmd);
|
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)
|
static int mgmt_add_adv_patterns_monitor_sync(struct hci_dev *hdev, void *data)
|
||||||
{
|
{
|
||||||
struct mgmt_pending_cmd *cmd = 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,
|
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) ||
|
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, hdev) ||
|
||||||
pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev) ||
|
pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev)) {
|
||||||
pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev)) {
|
|
||||||
status = MGMT_STATUS_BUSY;
|
status = MGMT_STATUS_BUSY;
|
||||||
goto unlock;
|
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_pending_cmd *cmd = data;
|
||||||
struct mgmt_cp_remove_adv_monitor *cp;
|
struct mgmt_cp_remove_adv_monitor *cp;
|
||||||
|
|
||||||
if (status == -ECANCELED ||
|
if (status == -ECANCELED)
|
||||||
cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hci_dev_lock(hdev);
|
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;
|
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);
|
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_status(status), &rp, sizeof(rp));
|
||||||
mgmt_pending_remove(cmd);
|
mgmt_pending_free(cmd);
|
||||||
|
|
||||||
hci_dev_unlock(hdev);
|
hci_dev_unlock(hdev);
|
||||||
bt_dev_dbg(hdev, "remove monitor %d complete, status %d",
|
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)
|
static int mgmt_remove_adv_monitor_sync(struct hci_dev *hdev, void *data)
|
||||||
{
|
{
|
||||||
struct mgmt_pending_cmd *cmd = 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;
|
struct mgmt_cp_remove_adv_monitor *cp = cmd->param;
|
||||||
u16 handle = __le16_to_cpu(cp->monitor_handle);
|
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);
|
hci_dev_lock(hdev);
|
||||||
|
|
||||||
if (pending_find(MGMT_OP_SET_LE, 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, hdev) ||
|
||||||
pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev)) {
|
pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev)) {
|
||||||
status = MGMT_STATUS_BUSY;
|
status = MGMT_STATUS_BUSY;
|
||||||
goto unlock;
|
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) {
|
if (!cmd) {
|
||||||
status = MGMT_STATUS_NO_RESOURCES;
|
status = MGMT_STATUS_NO_RESOURCES;
|
||||||
goto unlock;
|
goto unlock;
|
||||||
@ -5460,7 +5557,7 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
|
|||||||
mgmt_remove_adv_monitor_complete);
|
mgmt_remove_adv_monitor_complete);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
mgmt_pending_remove(cmd);
|
mgmt_pending_free(cmd);
|
||||||
|
|
||||||
if (err == -ENOMEM)
|
if (err == -ENOMEM)
|
||||||
status = MGMT_STATUS_NO_RESOURCES;
|
status = MGMT_STATUS_NO_RESOURCES;
|
||||||
@ -5480,7 +5577,8 @@ unlock:
|
|||||||
status);
|
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;
|
struct mgmt_rp_read_local_oob_data mgmt_rp;
|
||||||
size_t rp_size = sizeof(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);
|
bt_dev_dbg(hdev, "status %d", status);
|
||||||
|
|
||||||
if (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;
|
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);
|
bt_dev_dbg(hdev, "err %d", err);
|
||||||
|
|
||||||
if (err == -ECANCELED)
|
if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cmd != pending_find(MGMT_OP_START_DISCOVERY, hdev) &&
|
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err),
|
||||||
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),
|
|
||||||
cmd->param, 1);
|
cmd->param, 1);
|
||||||
mgmt_pending_remove(cmd);
|
mgmt_pending_free(cmd);
|
||||||
|
|
||||||
hci_discovery_set_state(hdev, err ? DISCOVERY_STOPPED:
|
hci_discovery_set_state(hdev, err ? DISCOVERY_STOPPED:
|
||||||
DISCOVERY_FINDING);
|
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)
|
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);
|
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;
|
struct mgmt_pending_cmd *cmd = data;
|
||||||
|
|
||||||
if (err == -ECANCELED ||
|
if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
|
||||||
cmd != pending_find(MGMT_OP_STOP_DISCOVERY, hdev))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bt_dev_dbg(hdev, "err %d", err);
|
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);
|
cmd->param, 1);
|
||||||
mgmt_pending_remove(cmd);
|
mgmt_pending_free(cmd);
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
|
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)
|
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);
|
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)
|
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 };
|
struct cmd_lookup match = { NULL, hdev };
|
||||||
u8 instance;
|
u8 instance;
|
||||||
struct adv_info *adv_instance;
|
struct adv_info *adv_instance;
|
||||||
u8 status = mgmt_status(err);
|
u8 status = mgmt_status(err);
|
||||||
|
|
||||||
|
if (err == -ECANCELED || !mgmt_pending_valid(hdev, data))
|
||||||
|
return;
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev,
|
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, status);
|
||||||
cmd_status_rsp, &status);
|
mgmt_pending_free(cmd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6246,8 +6349,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err)
|
|||||||
else
|
else
|
||||||
hci_dev_clear_flag(hdev, HCI_ADVERTISING);
|
hci_dev_clear_flag(hdev, HCI_ADVERTISING);
|
||||||
|
|
||||||
mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp,
|
settings_rsp(cmd, &match);
|
||||||
&match);
|
|
||||||
|
|
||||||
new_settings(hdev, match.sk);
|
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)
|
static int set_adv_sync(struct hci_dev *hdev, void *data)
|
||||||
{
|
{
|
||||||
struct mgmt_pending_cmd *cmd = data;
|
struct mgmt_pending_cmd *cmd = data;
|
||||||
struct mgmt_mode *cp = cmd->param;
|
struct mgmt_mode cp;
|
||||||
u8 val = !!cp->val;
|
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);
|
hci_dev_set_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
|
||||||
else
|
else
|
||||||
hci_dev_clear_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
|
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,
|
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
|
||||||
MGMT_STATUS_NOT_SUPPORTED);
|
MGMT_STATUS_NOT_SUPPORTED);
|
||||||
|
|
||||||
|
/* Keep allowed ranges in sync with set_mesh() */
|
||||||
interval = __le16_to_cpu(cp->interval);
|
interval = __le16_to_cpu(cp->interval);
|
||||||
|
|
||||||
if (interval < 0x0004 || interval > 0x4000)
|
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);
|
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 {
|
} else {
|
||||||
send_settings_rsp(cmd->sk, MGMT_OP_SET_BREDR, hdev);
|
send_settings_rsp(cmd->sk, MGMT_OP_SET_BREDR, hdev);
|
||||||
new_settings(hdev, cmd->sk);
|
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) {
|
if (err) {
|
||||||
u8 mgmt_err = mgmt_status(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;
|
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;
|
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));
|
&rp, sizeof(rp));
|
||||||
|
|
||||||
mgmt_pending_free(cmd);
|
mgmt_pending_free(cmd);
|
||||||
@ -7335,7 +7451,7 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err)
|
|||||||
}
|
}
|
||||||
|
|
||||||
complete:
|
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));
|
sizeof(rp));
|
||||||
|
|
||||||
mgmt_pending_free(cmd);
|
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);
|
u8 status = mgmt_status(err);
|
||||||
u16 eir_len;
|
u16 eir_len;
|
||||||
|
|
||||||
if (err == -ECANCELED ||
|
|
||||||
cmd != pending_find(MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!status) {
|
if (!status) {
|
||||||
if (!skb)
|
if (!skb)
|
||||||
status = MGMT_STATUS_FAILED;
|
status = MGMT_STATUS_FAILED;
|
||||||
@ -8145,7 +8257,7 @@ done:
|
|||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
|
||||||
kfree(mgmt_rp);
|
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,
|
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;
|
struct mgmt_pending_cmd *cmd;
|
||||||
int err;
|
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));
|
cp, sizeof(*cp));
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -8585,10 +8697,10 @@ static void add_advertising_complete(struct hci_dev *hdev, void *data, int err)
|
|||||||
rp.instance = cp->instance;
|
rp.instance = cp->instance;
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
|
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
|
||||||
mgmt_status(err));
|
mgmt_status(err));
|
||||||
else
|
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_status(err), &rp, sizeof(rp));
|
||||||
|
|
||||||
add_adv_complete(hdev, cmd->sk, cp->instance, err);
|
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);
|
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));
|
mgmt_status(err));
|
||||||
} else {
|
} 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_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;
|
rp.instance = cp->instance;
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
|
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
|
||||||
mgmt_status(err));
|
mgmt_status(err));
|
||||||
else
|
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_status(err), &rp, sizeof(rp));
|
||||||
|
|
||||||
mgmt_pending_free(cmd);
|
mgmt_pending_free(cmd);
|
||||||
@ -9088,10 +9200,10 @@ static void remove_advertising_complete(struct hci_dev *hdev, void *data,
|
|||||||
rp.instance = cp->instance;
|
rp.instance = cp->instance;
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
|
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
|
||||||
mgmt_status(err));
|
mgmt_status(err));
|
||||||
else
|
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_STATUS_SUCCESS, &rp, sizeof(rp));
|
||||||
|
|
||||||
mgmt_pending_free(cmd);
|
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))
|
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
|
||||||
return;
|
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)) {
|
if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
|
||||||
mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0,
|
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);
|
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);
|
new_settings(hdev, match.sk);
|
||||||
|
|
||||||
@ -9416,7 +9529,8 @@ void __mgmt_power_off(struct hci_dev *hdev)
|
|||||||
struct cmd_lookup match = { NULL, hdev };
|
struct cmd_lookup match = { NULL, hdev };
|
||||||
u8 zero_cod[] = { 0, 0, 0 };
|
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
|
/* If the power off is because of hdev unregistration let
|
||||||
* use the appropriate INVALID_INDEX status. Otherwise use
|
* use the appropriate INVALID_INDEX status. Otherwise use
|
||||||
@ -9430,7 +9544,7 @@ void __mgmt_power_off(struct hci_dev *hdev)
|
|||||||
else
|
else
|
||||||
match.mgmt_status = MGMT_STATUS_NOT_POWERED;
|
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) {
|
if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) {
|
||||||
mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev,
|
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);
|
device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk);
|
||||||
|
|
||||||
cmd->cmd_complete(cmd, 0);
|
cmd->cmd_complete(cmd, 0);
|
||||||
mgmt_pending_remove(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mgmt_powering_down(struct hci_dev *hdev)
|
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_cp_disconnect *cp;
|
||||||
struct mgmt_pending_cmd *cmd;
|
struct mgmt_pending_cmd *cmd;
|
||||||
|
|
||||||
mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
|
mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, true,
|
||||||
hdev);
|
unpair_device_rsp, hdev);
|
||||||
|
|
||||||
cmd = pending_find(MGMT_OP_DISCONNECT, hdev);
|
cmd = pending_find(MGMT_OP_DISCONNECT, hdev);
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
@ -9921,7 +10034,7 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
|
|||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
u8 mgmt_err = mgmt_status(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);
|
cmd_status_rsp, &mgmt_err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -9931,8 +10044,8 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
|
|||||||
else
|
else
|
||||||
changed = hci_dev_test_and_clear_flag(hdev, HCI_LINK_SECURITY);
|
changed = hci_dev_test_and_clear_flag(hdev, HCI_LINK_SECURITY);
|
||||||
|
|
||||||
mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp,
|
mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true,
|
||||||
&match);
|
settings_rsp, &match);
|
||||||
|
|
||||||
if (changed)
|
if (changed)
|
||||||
new_settings(hdev, match.sk);
|
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) };
|
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_SET_DEV_CLASS, hdev, false, sk_lookup,
|
||||||
mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, sk_lookup, &match);
|
&match);
|
||||||
mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, 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) {
|
if (!status) {
|
||||||
mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class,
|
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 mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode,
|
||||||
struct hci_dev *hdev)
|
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)
|
if (hci_sock_get_channel(cmd->sk) != channel)
|
||||||
continue;
|
continue;
|
||||||
if (cmd->opcode == opcode)
|
|
||||||
|
if (cmd->opcode == opcode) {
|
||||||
|
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||||
return cmd;
|
return cmd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||||
|
|
||||||
return NULL;
|
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 (*cb)(struct mgmt_pending_cmd *cmd, void *data),
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct mgmt_pending_cmd *cmd, *tmp;
|
struct mgmt_pending_cmd *cmd, *tmp;
|
||||||
|
|
||||||
|
mutex_lock(&hdev->mgmt_pending_lock);
|
||||||
|
|
||||||
list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) {
|
list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) {
|
||||||
if (opcode > 0 && cmd->opcode != opcode)
|
if (opcode > 0 && cmd->opcode != opcode)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (remove)
|
||||||
|
list_del(&cmd->list);
|
||||||
|
|
||||||
cb(cmd, data);
|
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,
|
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;
|
return NULL;
|
||||||
|
|
||||||
cmd->opcode = opcode;
|
cmd->opcode = opcode;
|
||||||
cmd->index = hdev->id;
|
cmd->hdev = hdev;
|
||||||
|
|
||||||
cmd->param = kmemdup(data, len, GFP_KERNEL);
|
cmd->param = kmemdup(data, len, GFP_KERNEL);
|
||||||
if (!cmd->param) {
|
if (!cmd->param) {
|
||||||
@ -280,7 +297,9 @@ struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
|
|||||||
if (!cmd)
|
if (!cmd)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
mutex_lock(&hdev->mgmt_pending_lock);
|
||||||
list_add_tail(&cmd->list, &hdev->mgmt_pending);
|
list_add_tail(&cmd->list, &hdev->mgmt_pending);
|
||||||
|
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||||
|
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
@ -294,10 +313,59 @@ void mgmt_pending_free(struct mgmt_pending_cmd *cmd)
|
|||||||
|
|
||||||
void mgmt_pending_remove(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);
|
list_del(&cmd->list);
|
||||||
|
mutex_unlock(&cmd->hdev->mgmt_pending_lock);
|
||||||
|
|
||||||
mgmt_pending_free(cmd);
|
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 mgmt_mesh_foreach(struct hci_dev *hdev,
|
||||||
void (*cb)(struct mgmt_mesh_tx *mesh_tx, void *data),
|
void (*cb)(struct mgmt_mesh_tx *mesh_tx, void *data),
|
||||||
void *data, struct sock *sk)
|
void *data, struct sock *sk)
|
||||||
|
|||||||
@ -33,7 +33,7 @@ struct mgmt_mesh_tx {
|
|||||||
struct mgmt_pending_cmd {
|
struct mgmt_pending_cmd {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
u16 opcode;
|
u16 opcode;
|
||||||
int index;
|
struct hci_dev *hdev;
|
||||||
void *param;
|
void *param;
|
||||||
size_t param_len;
|
size_t param_len;
|
||||||
struct sock *sk;
|
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 mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode,
|
||||||
struct hci_dev *hdev);
|
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 (*cb)(struct mgmt_pending_cmd *cmd, void *data),
|
||||||
void *data);
|
void *data);
|
||||||
struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
|
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 *data, u16 len);
|
||||||
void mgmt_pending_free(struct mgmt_pending_cmd *cmd);
|
void mgmt_pending_free(struct mgmt_pending_cmd *cmd);
|
||||||
void mgmt_pending_remove(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 mgmt_mesh_foreach(struct hci_dev *hdev,
|
||||||
void (*cb)(struct mgmt_mesh_tx *mesh_tx, void *data),
|
void (*cb)(struct mgmt_mesh_tx *mesh_tx, void *data),
|
||||||
void *data, struct sock *sk);
|
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 inet_connection_sock *icsk = inet_csk(sk);
|
||||||
struct tcp_sock *tp = tcp_sk(sk);
|
struct tcp_sock *tp = tcp_sk(sk);
|
||||||
int old_state = sk->sk_state;
|
int old_state = sk->sk_state;
|
||||||
|
struct request_sock *req;
|
||||||
u32 seq;
|
u32 seq;
|
||||||
|
|
||||||
if (old_state != TCP_CLOSE)
|
if (old_state != TCP_CLOSE)
|
||||||
@ -3272,6 +3273,10 @@ int tcp_disconnect(struct sock *sk, int flags)
|
|||||||
|
|
||||||
|
|
||||||
/* Clean up fastopen related fields */
|
/* 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);
|
tcp_free_fastopen_req(tp);
|
||||||
inet->defer_connect = 0;
|
inet->defer_connect = 0;
|
||||||
tp->fastopen_client_fail = 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);
|
&foc, TCP_SYNACK_FASTOPEN, skb);
|
||||||
/* Add the child socket directly into the accept queue */
|
/* Add the child socket directly into the accept queue */
|
||||||
if (!inet_csk_reqsk_queue_add(sk, req, fastopen_sk)) {
|
if (!inet_csk_reqsk_queue_add(sk, req, fastopen_sk)) {
|
||||||
reqsk_fastopen_remove(fastopen_sk, req, false);
|
|
||||||
bh_unlock_sock(fastopen_sk);
|
bh_unlock_sock(fastopen_sk);
|
||||||
sock_put(fastopen_sk);
|
sock_put(fastopen_sk);
|
||||||
goto drop_and_free;
|
goto drop_and_free;
|
||||||
|
|||||||
@ -1905,7 +1905,8 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
f = rcu_access_pointer(new->pub.beacon_ies);
|
f = rcu_access_pointer(new->pub.beacon_ies);
|
||||||
kfree_rcu((struct cfg80211_bss_ies *)f, rcu_head);
|
if (!new->pub.hidden_beacon_bss)
|
||||||
|
kfree_rcu((struct cfg80211_bss_ies *)f, rcu_head);
|
||||||
return false;
|
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]
|
* 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]
|
- 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]
|
- nfsd: nfserr_jukebox in nlm_fopen should lead to a retry (Olga Kornievskaia) [RHEL-124651]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user