static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_role_change *ev = (void *) skb->data; struct hci_conn *conn; BT_DBG("%s status %d", hdev->name, ev->status); hci_dev_lock(hdev); conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); if (conn) { if (!ev->status) { if (ev->role) conn->link_mode &= ~HCI_LM_MASTER; else conn->link_mode |= HCI_LM_MASTER; } clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend); hci_role_switch_cfm(conn, ev->status, ev->role); } hci_dev_unlock(hdev); }
static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_role_change *ev = (void *) skb->data; struct hci_conn *conn; BT_DBG("%s status %d", hdev->name, ev->status); hci_dev_lock(hdev); conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); if (conn) { if (!ev->status) { if (ev->role) conn->link_mode &= ~HCI_LM_MASTER; else { conn->link_mode |= HCI_LM_MASTER; if (!(conn->features[3]&(0x02|0x04))) /* not support 2M/3M EDR. 0x02=2M 0x04=3M */ { struct hci_cp_write_link_policy cp; cp.handle = 0; /* init */ cp.policy = 0; /* disable role_switch when changed to master */ cp.handle = cpu_to_le16(conn->handle); conn->link_policy |= HCI_LP_SNIFF; conn->link_policy |= HCI_LP_HOLD; conn->link_policy &= ~HCI_LP_RSWITCH; cp.policy = cpu_to_le16(conn->link_policy); hci_send_cmd(conn->hdev, HCI_OP_WRITE_LINK_POLICY, sizeof(cp), &cp); } } } clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend); hci_role_switch_cfm(conn, ev->status, ev->role); } hci_dev_unlock(hdev); }