Loading drivers/bluetooth/btusb.c +3 −7 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ static struct usb_device_id btusb_table[] = { { USB_DEVICE(0x0c10, 0x0000) }, /* Broadcom BCM20702A0 */ { USB_DEVICE(0x0a5c, 0x21e3) }, { USB_DEVICE(0x413c, 0x8197) }, { } /* Terminating entry */ Loading Loading @@ -508,15 +509,10 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags) pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress); urb->dev = data->udev; urb->pipe = pipe; urb->context = hdev; urb->complete = btusb_isoc_complete; urb->interval = data->isoc_rx_ep->bInterval; usb_fill_int_urb(urb, data->udev, pipe, buf, size, btusb_isoc_complete, hdev, data->isoc_rx_ep->bInterval); urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP; urb->transfer_buffer = buf; urb->transfer_buffer_length = size; __fill_isoc_descriptor(urb, size, le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize)); Loading include/net/bluetooth/bluetooth.h +0 −22 Original line number Diff line number Diff line Loading @@ -250,32 +250,10 @@ extern void bt_sysfs_cleanup(void); extern struct dentry *bt_debugfs; #ifdef CONFIG_BT_L2CAP int l2cap_init(void); void l2cap_exit(void); #else static inline int l2cap_init(void) { return 0; } static inline void l2cap_exit(void) { } #endif #ifdef CONFIG_BT_SCO int sco_init(void); void sco_exit(void); #else static inline int sco_init(void) { return 0; } static inline void sco_exit(void) { } #endif #endif /* __BLUETOOTH_H */ include/net/bluetooth/hci.h +13 −1 Original line number Diff line number Diff line Loading @@ -280,6 +280,10 @@ enum { #define HCI_ERROR_LOCAL_HOST_TERM 0x16 #define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18 /* Flow control modes */ #define HCI_FLOW_CTL_MODE_PACKET_BASED 0x00 #define HCI_FLOW_CTL_MODE_BLOCK_BASED 0x01 /* ----- HCI Commands ---- */ #define HCI_OP_NOP 0x0000 Loading Loading @@ -800,6 +804,9 @@ struct hci_cp_le_set_scan_param { __u8 filter_policy; } __packed; #define LE_SCANNING_DISABLED 0x00 #define LE_SCANNING_ENABLED 0x01 #define HCI_OP_LE_SET_SCAN_ENABLE 0x200c struct hci_cp_le_set_scan_enable { __u8 enable; Loading Loading @@ -975,9 +982,14 @@ struct hci_ev_role_change { } __packed; #define HCI_EV_NUM_COMP_PKTS 0x13 struct hci_comp_pkts_info { __le16 handle; __le16 count; } __packed; struct hci_ev_num_comp_pkts { __u8 num_hndl; /* variable length part */ struct hci_comp_pkts_info handles[0]; } __packed; #define HCI_EV_MODE_CHANGE 0x14 Loading include/net/bluetooth/hci_core.h +68 −94 Original line number Diff line number Diff line Loading @@ -28,10 +28,6 @@ #include <linux/interrupt.h> #include <net/bluetooth/hci.h> /* HCI upper protocols */ #define HCI_PROTO_L2CAP 0 #define HCI_PROTO_SCO 1 /* HCI priority */ #define HCI_PRIO_MAX 7 Loading @@ -54,7 +50,6 @@ struct inquiry_entry { }; struct inquiry_cache { spinlock_t lock; __u32 timestamp; struct inquiry_entry *list; }; Loading Loading @@ -314,6 +309,7 @@ struct hci_conn { struct hci_dev *hdev; void *l2cap_data; void *sco_data; void *smp_conn; struct hci_conn *link; Loading @@ -330,25 +326,31 @@ struct hci_chan { unsigned int sent; }; extern struct hci_proto *hci_proto[]; extern struct list_head hci_dev_list; extern struct list_head hci_cb_list; extern rwlock_t hci_dev_list_lock; extern rwlock_t hci_cb_list_lock; /* ----- HCI interface to upper protocols ----- */ extern int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); extern int l2cap_connect_cfm(struct hci_conn *hcon, u8 status); extern int l2cap_disconn_ind(struct hci_conn *hcon); extern int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason); extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt); extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags); extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); extern int sco_connect_cfm(struct hci_conn *hcon, __u8 status); extern int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason); extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb); /* ----- Inquiry cache ----- */ #define INQUIRY_CACHE_AGE_MAX (HZ*30) /* 30 seconds */ #define INQUIRY_ENTRY_AGE_MAX (HZ*60) /* 60 seconds */ #define inquiry_cache_lock(c) spin_lock(&c->lock) #define inquiry_cache_unlock(c) spin_unlock(&c->lock) #define inquiry_cache_lock_bh(c) spin_lock_bh(&c->lock) #define inquiry_cache_unlock_bh(c) spin_unlock_bh(&c->lock) static inline void inquiry_cache_init(struct hci_dev *hdev) { struct inquiry_cache *c = &hdev->inq_cache; spin_lock_init(&c->lock); c->list = NULL; } Loading Loading @@ -677,53 +679,40 @@ void hci_conn_del_sysfs(struct hci_conn *conn); #define lmp_host_le_capable(dev) ((dev)->extfeatures[0] & LMP_HOST_LE) /* ----- HCI protocols ----- */ struct hci_proto { char *name; unsigned int id; unsigned long flags; void *priv; int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type); int (*connect_cfm) (struct hci_conn *conn, __u8 status); int (*disconn_ind) (struct hci_conn *conn); int (*disconn_cfm) (struct hci_conn *conn, __u8 reason); int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags); int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); int (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); }; static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) { register struct hci_proto *hp; int mask = 0; hp = hci_proto[HCI_PROTO_L2CAP]; if (hp && hp->connect_ind) mask |= hp->connect_ind(hdev, bdaddr, type); switch (type) { case ACL_LINK: return l2cap_connect_ind(hdev, bdaddr); hp = hci_proto[HCI_PROTO_SCO]; if (hp && hp->connect_ind) mask |= hp->connect_ind(hdev, bdaddr, type); case SCO_LINK: case ESCO_LINK: return sco_connect_ind(hdev, bdaddr); return mask; default: BT_ERR("unknown link type %d", type); return -EINVAL; } } static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) { register struct hci_proto *hp; switch (conn->type) { case ACL_LINK: case LE_LINK: l2cap_connect_cfm(conn, status); break; hp = hci_proto[HCI_PROTO_L2CAP]; if (hp && hp->connect_cfm) hp->connect_cfm(conn, status); case SCO_LINK: case ESCO_LINK: sco_connect_cfm(conn, status); break; hp = hci_proto[HCI_PROTO_SCO]; if (hp && hp->connect_cfm) hp->connect_cfm(conn, status); default: BT_ERR("unknown link type %d", conn->type); break; } if (conn->connect_cfm_cb) conn->connect_cfm_cb(conn, status); Loading @@ -731,31 +720,29 @@ static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) static inline int hci_proto_disconn_ind(struct hci_conn *conn) { register struct hci_proto *hp; int reason = HCI_ERROR_REMOTE_USER_TERM; hp = hci_proto[HCI_PROTO_L2CAP]; if (hp && hp->disconn_ind) reason = hp->disconn_ind(conn); hp = hci_proto[HCI_PROTO_SCO]; if (hp && hp->disconn_ind) reason = hp->disconn_ind(conn); if (conn->type != ACL_LINK && conn->type != LE_LINK) return HCI_ERROR_REMOTE_USER_TERM; return reason; return l2cap_disconn_ind(conn); } static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason) { register struct hci_proto *hp; switch (conn->type) { case ACL_LINK: case LE_LINK: l2cap_disconn_cfm(conn, reason); break; hp = hci_proto[HCI_PROTO_L2CAP]; if (hp && hp->disconn_cfm) hp->disconn_cfm(conn, reason); case SCO_LINK: case ESCO_LINK: sco_disconn_cfm(conn, reason); break; hp = hci_proto[HCI_PROTO_SCO]; if (hp && hp->disconn_cfm) hp->disconn_cfm(conn, reason); default: BT_ERR("unknown link type %d", conn->type); break; } if (conn->disconn_cfm_cb) conn->disconn_cfm_cb(conn, reason); Loading @@ -763,21 +750,16 @@ static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason) static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) { register struct hci_proto *hp; __u8 encrypt; if (conn->type != ACL_LINK && conn->type != LE_LINK) return; if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) return; encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; hp = hci_proto[HCI_PROTO_L2CAP]; if (hp && hp->security_cfm) hp->security_cfm(conn, status, encrypt); hp = hci_proto[HCI_PROTO_SCO]; if (hp && hp->security_cfm) hp->security_cfm(conn, status, encrypt); l2cap_security_cfm(conn, status, encrypt); if (conn->security_cfm_cb) conn->security_cfm_cb(conn, status); Loading @@ -786,23 +768,15 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) { register struct hci_proto *hp; hp = hci_proto[HCI_PROTO_L2CAP]; if (hp && hp->security_cfm) hp->security_cfm(conn, status, encrypt); if (conn->type != ACL_LINK && conn->type != LE_LINK) return; hp = hci_proto[HCI_PROTO_SCO]; if (hp && hp->security_cfm) hp->security_cfm(conn, status, encrypt); l2cap_security_cfm(conn, status, encrypt); if (conn->security_cfm_cb) conn->security_cfm_cb(conn, status); } int hci_register_proto(struct hci_proto *hproto); int hci_unregister_proto(struct hci_proto *hproto); /* ----- HCI callbacks ----- */ struct hci_cb { struct list_head list; Loading @@ -827,13 +801,13 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; read_lock_bh(&hci_cb_list_lock); read_lock(&hci_cb_list_lock); list_for_each(p, &hci_cb_list) { struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->security_cfm) cb->security_cfm(conn, status, encrypt); } read_unlock_bh(&hci_cb_list_lock); read_unlock(&hci_cb_list_lock); } static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, Loading @@ -849,26 +823,26 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, hci_proto_encrypt_cfm(conn, status, encrypt); read_lock_bh(&hci_cb_list_lock); read_lock(&hci_cb_list_lock); list_for_each(p, &hci_cb_list) { struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->security_cfm) cb->security_cfm(conn, status, encrypt); } read_unlock_bh(&hci_cb_list_lock); read_unlock(&hci_cb_list_lock); } static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) { struct list_head *p; read_lock_bh(&hci_cb_list_lock); read_lock(&hci_cb_list_lock); list_for_each(p, &hci_cb_list) { struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->key_change_cfm) cb->key_change_cfm(conn, status); } read_unlock_bh(&hci_cb_list_lock); read_unlock(&hci_cb_list_lock); } static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, Loading @@ -876,13 +850,13 @@ static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, { struct list_head *p; read_lock_bh(&hci_cb_list_lock); read_lock(&hci_cb_list_lock); list_for_each(p, &hci_cb_list) { struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->role_switch_cfm) cb->role_switch_cfm(conn, status, role); } read_unlock_bh(&hci_cb_list_lock); read_unlock(&hci_cb_list_lock); } int hci_register_cb(struct hci_cb *hcb); Loading include/net/bluetooth/l2cap.h +34 −6 Original line number Diff line number Diff line Loading @@ -522,7 +522,7 @@ struct l2cap_conn { __u8 info_state; __u8 info_ident; struct delayed_work info_work; struct delayed_work info_timer; spinlock_t lock; Loading @@ -532,7 +532,7 @@ struct l2cap_conn { __u8 disc_reason; struct timer_list security_timer; struct delayed_work security_timer; struct smp_chan *smp_chan; struct list_head chan_l; Loading Loading @@ -595,17 +595,45 @@ enum { FLAG_EFS_ENABLE, }; static inline void l2cap_chan_hold(struct l2cap_chan *c) { atomic_inc(&c->refcnt); } static inline void l2cap_chan_put(struct l2cap_chan *c) { if (atomic_dec_and_test(&c->refcnt)) kfree(c); } static inline void l2cap_set_timer(struct l2cap_chan *chan, struct delayed_work *work, long timeout) { BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout); if (!__cancel_delayed_work(work)) l2cap_chan_hold(chan); schedule_delayed_work(work, timeout); } static inline void l2cap_clear_timer(struct l2cap_chan *chan, struct delayed_work *work) { if (__cancel_delayed_work(work)) l2cap_chan_put(chan); } #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) #define __clear_chan_timer(c) l2cap_clear_timer(&c->chan_timer) #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ L2CAP_DEFAULT_RETRANS_TO); #define __clear_retrans_timer(c) l2cap_clear_timer(&c->retrans_timer) #define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer) #define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \ L2CAP_DEFAULT_MONITOR_TO); #define __clear_monitor_timer(c) l2cap_clear_timer(&c->monitor_timer) #define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer) #define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \ L2CAP_DEFAULT_ACK_TO); #define __clear_ack_timer(c) l2cap_clear_timer(&c->ack_timer) #define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer) static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2) { Loading Loading
drivers/bluetooth/btusb.c +3 −7 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ static struct usb_device_id btusb_table[] = { { USB_DEVICE(0x0c10, 0x0000) }, /* Broadcom BCM20702A0 */ { USB_DEVICE(0x0a5c, 0x21e3) }, { USB_DEVICE(0x413c, 0x8197) }, { } /* Terminating entry */ Loading Loading @@ -508,15 +509,10 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags) pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress); urb->dev = data->udev; urb->pipe = pipe; urb->context = hdev; urb->complete = btusb_isoc_complete; urb->interval = data->isoc_rx_ep->bInterval; usb_fill_int_urb(urb, data->udev, pipe, buf, size, btusb_isoc_complete, hdev, data->isoc_rx_ep->bInterval); urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP; urb->transfer_buffer = buf; urb->transfer_buffer_length = size; __fill_isoc_descriptor(urb, size, le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize)); Loading
include/net/bluetooth/bluetooth.h +0 −22 Original line number Diff line number Diff line Loading @@ -250,32 +250,10 @@ extern void bt_sysfs_cleanup(void); extern struct dentry *bt_debugfs; #ifdef CONFIG_BT_L2CAP int l2cap_init(void); void l2cap_exit(void); #else static inline int l2cap_init(void) { return 0; } static inline void l2cap_exit(void) { } #endif #ifdef CONFIG_BT_SCO int sco_init(void); void sco_exit(void); #else static inline int sco_init(void) { return 0; } static inline void sco_exit(void) { } #endif #endif /* __BLUETOOTH_H */
include/net/bluetooth/hci.h +13 −1 Original line number Diff line number Diff line Loading @@ -280,6 +280,10 @@ enum { #define HCI_ERROR_LOCAL_HOST_TERM 0x16 #define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18 /* Flow control modes */ #define HCI_FLOW_CTL_MODE_PACKET_BASED 0x00 #define HCI_FLOW_CTL_MODE_BLOCK_BASED 0x01 /* ----- HCI Commands ---- */ #define HCI_OP_NOP 0x0000 Loading Loading @@ -800,6 +804,9 @@ struct hci_cp_le_set_scan_param { __u8 filter_policy; } __packed; #define LE_SCANNING_DISABLED 0x00 #define LE_SCANNING_ENABLED 0x01 #define HCI_OP_LE_SET_SCAN_ENABLE 0x200c struct hci_cp_le_set_scan_enable { __u8 enable; Loading Loading @@ -975,9 +982,14 @@ struct hci_ev_role_change { } __packed; #define HCI_EV_NUM_COMP_PKTS 0x13 struct hci_comp_pkts_info { __le16 handle; __le16 count; } __packed; struct hci_ev_num_comp_pkts { __u8 num_hndl; /* variable length part */ struct hci_comp_pkts_info handles[0]; } __packed; #define HCI_EV_MODE_CHANGE 0x14 Loading
include/net/bluetooth/hci_core.h +68 −94 Original line number Diff line number Diff line Loading @@ -28,10 +28,6 @@ #include <linux/interrupt.h> #include <net/bluetooth/hci.h> /* HCI upper protocols */ #define HCI_PROTO_L2CAP 0 #define HCI_PROTO_SCO 1 /* HCI priority */ #define HCI_PRIO_MAX 7 Loading @@ -54,7 +50,6 @@ struct inquiry_entry { }; struct inquiry_cache { spinlock_t lock; __u32 timestamp; struct inquiry_entry *list; }; Loading Loading @@ -314,6 +309,7 @@ struct hci_conn { struct hci_dev *hdev; void *l2cap_data; void *sco_data; void *smp_conn; struct hci_conn *link; Loading @@ -330,25 +326,31 @@ struct hci_chan { unsigned int sent; }; extern struct hci_proto *hci_proto[]; extern struct list_head hci_dev_list; extern struct list_head hci_cb_list; extern rwlock_t hci_dev_list_lock; extern rwlock_t hci_cb_list_lock; /* ----- HCI interface to upper protocols ----- */ extern int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); extern int l2cap_connect_cfm(struct hci_conn *hcon, u8 status); extern int l2cap_disconn_ind(struct hci_conn *hcon); extern int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason); extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt); extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags); extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); extern int sco_connect_cfm(struct hci_conn *hcon, __u8 status); extern int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason); extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb); /* ----- Inquiry cache ----- */ #define INQUIRY_CACHE_AGE_MAX (HZ*30) /* 30 seconds */ #define INQUIRY_ENTRY_AGE_MAX (HZ*60) /* 60 seconds */ #define inquiry_cache_lock(c) spin_lock(&c->lock) #define inquiry_cache_unlock(c) spin_unlock(&c->lock) #define inquiry_cache_lock_bh(c) spin_lock_bh(&c->lock) #define inquiry_cache_unlock_bh(c) spin_unlock_bh(&c->lock) static inline void inquiry_cache_init(struct hci_dev *hdev) { struct inquiry_cache *c = &hdev->inq_cache; spin_lock_init(&c->lock); c->list = NULL; } Loading Loading @@ -677,53 +679,40 @@ void hci_conn_del_sysfs(struct hci_conn *conn); #define lmp_host_le_capable(dev) ((dev)->extfeatures[0] & LMP_HOST_LE) /* ----- HCI protocols ----- */ struct hci_proto { char *name; unsigned int id; unsigned long flags; void *priv; int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type); int (*connect_cfm) (struct hci_conn *conn, __u8 status); int (*disconn_ind) (struct hci_conn *conn); int (*disconn_cfm) (struct hci_conn *conn, __u8 reason); int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags); int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); int (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); }; static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) { register struct hci_proto *hp; int mask = 0; hp = hci_proto[HCI_PROTO_L2CAP]; if (hp && hp->connect_ind) mask |= hp->connect_ind(hdev, bdaddr, type); switch (type) { case ACL_LINK: return l2cap_connect_ind(hdev, bdaddr); hp = hci_proto[HCI_PROTO_SCO]; if (hp && hp->connect_ind) mask |= hp->connect_ind(hdev, bdaddr, type); case SCO_LINK: case ESCO_LINK: return sco_connect_ind(hdev, bdaddr); return mask; default: BT_ERR("unknown link type %d", type); return -EINVAL; } } static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) { register struct hci_proto *hp; switch (conn->type) { case ACL_LINK: case LE_LINK: l2cap_connect_cfm(conn, status); break; hp = hci_proto[HCI_PROTO_L2CAP]; if (hp && hp->connect_cfm) hp->connect_cfm(conn, status); case SCO_LINK: case ESCO_LINK: sco_connect_cfm(conn, status); break; hp = hci_proto[HCI_PROTO_SCO]; if (hp && hp->connect_cfm) hp->connect_cfm(conn, status); default: BT_ERR("unknown link type %d", conn->type); break; } if (conn->connect_cfm_cb) conn->connect_cfm_cb(conn, status); Loading @@ -731,31 +720,29 @@ static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) static inline int hci_proto_disconn_ind(struct hci_conn *conn) { register struct hci_proto *hp; int reason = HCI_ERROR_REMOTE_USER_TERM; hp = hci_proto[HCI_PROTO_L2CAP]; if (hp && hp->disconn_ind) reason = hp->disconn_ind(conn); hp = hci_proto[HCI_PROTO_SCO]; if (hp && hp->disconn_ind) reason = hp->disconn_ind(conn); if (conn->type != ACL_LINK && conn->type != LE_LINK) return HCI_ERROR_REMOTE_USER_TERM; return reason; return l2cap_disconn_ind(conn); } static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason) { register struct hci_proto *hp; switch (conn->type) { case ACL_LINK: case LE_LINK: l2cap_disconn_cfm(conn, reason); break; hp = hci_proto[HCI_PROTO_L2CAP]; if (hp && hp->disconn_cfm) hp->disconn_cfm(conn, reason); case SCO_LINK: case ESCO_LINK: sco_disconn_cfm(conn, reason); break; hp = hci_proto[HCI_PROTO_SCO]; if (hp && hp->disconn_cfm) hp->disconn_cfm(conn, reason); default: BT_ERR("unknown link type %d", conn->type); break; } if (conn->disconn_cfm_cb) conn->disconn_cfm_cb(conn, reason); Loading @@ -763,21 +750,16 @@ static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason) static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) { register struct hci_proto *hp; __u8 encrypt; if (conn->type != ACL_LINK && conn->type != LE_LINK) return; if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) return; encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; hp = hci_proto[HCI_PROTO_L2CAP]; if (hp && hp->security_cfm) hp->security_cfm(conn, status, encrypt); hp = hci_proto[HCI_PROTO_SCO]; if (hp && hp->security_cfm) hp->security_cfm(conn, status, encrypt); l2cap_security_cfm(conn, status, encrypt); if (conn->security_cfm_cb) conn->security_cfm_cb(conn, status); Loading @@ -786,23 +768,15 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) { register struct hci_proto *hp; hp = hci_proto[HCI_PROTO_L2CAP]; if (hp && hp->security_cfm) hp->security_cfm(conn, status, encrypt); if (conn->type != ACL_LINK && conn->type != LE_LINK) return; hp = hci_proto[HCI_PROTO_SCO]; if (hp && hp->security_cfm) hp->security_cfm(conn, status, encrypt); l2cap_security_cfm(conn, status, encrypt); if (conn->security_cfm_cb) conn->security_cfm_cb(conn, status); } int hci_register_proto(struct hci_proto *hproto); int hci_unregister_proto(struct hci_proto *hproto); /* ----- HCI callbacks ----- */ struct hci_cb { struct list_head list; Loading @@ -827,13 +801,13 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; read_lock_bh(&hci_cb_list_lock); read_lock(&hci_cb_list_lock); list_for_each(p, &hci_cb_list) { struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->security_cfm) cb->security_cfm(conn, status, encrypt); } read_unlock_bh(&hci_cb_list_lock); read_unlock(&hci_cb_list_lock); } static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, Loading @@ -849,26 +823,26 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, hci_proto_encrypt_cfm(conn, status, encrypt); read_lock_bh(&hci_cb_list_lock); read_lock(&hci_cb_list_lock); list_for_each(p, &hci_cb_list) { struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->security_cfm) cb->security_cfm(conn, status, encrypt); } read_unlock_bh(&hci_cb_list_lock); read_unlock(&hci_cb_list_lock); } static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) { struct list_head *p; read_lock_bh(&hci_cb_list_lock); read_lock(&hci_cb_list_lock); list_for_each(p, &hci_cb_list) { struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->key_change_cfm) cb->key_change_cfm(conn, status); } read_unlock_bh(&hci_cb_list_lock); read_unlock(&hci_cb_list_lock); } static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, Loading @@ -876,13 +850,13 @@ static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, { struct list_head *p; read_lock_bh(&hci_cb_list_lock); read_lock(&hci_cb_list_lock); list_for_each(p, &hci_cb_list) { struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->role_switch_cfm) cb->role_switch_cfm(conn, status, role); } read_unlock_bh(&hci_cb_list_lock); read_unlock(&hci_cb_list_lock); } int hci_register_cb(struct hci_cb *hcb); Loading
include/net/bluetooth/l2cap.h +34 −6 Original line number Diff line number Diff line Loading @@ -522,7 +522,7 @@ struct l2cap_conn { __u8 info_state; __u8 info_ident; struct delayed_work info_work; struct delayed_work info_timer; spinlock_t lock; Loading @@ -532,7 +532,7 @@ struct l2cap_conn { __u8 disc_reason; struct timer_list security_timer; struct delayed_work security_timer; struct smp_chan *smp_chan; struct list_head chan_l; Loading Loading @@ -595,17 +595,45 @@ enum { FLAG_EFS_ENABLE, }; static inline void l2cap_chan_hold(struct l2cap_chan *c) { atomic_inc(&c->refcnt); } static inline void l2cap_chan_put(struct l2cap_chan *c) { if (atomic_dec_and_test(&c->refcnt)) kfree(c); } static inline void l2cap_set_timer(struct l2cap_chan *chan, struct delayed_work *work, long timeout) { BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout); if (!__cancel_delayed_work(work)) l2cap_chan_hold(chan); schedule_delayed_work(work, timeout); } static inline void l2cap_clear_timer(struct l2cap_chan *chan, struct delayed_work *work) { if (__cancel_delayed_work(work)) l2cap_chan_put(chan); } #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) #define __clear_chan_timer(c) l2cap_clear_timer(&c->chan_timer) #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ L2CAP_DEFAULT_RETRANS_TO); #define __clear_retrans_timer(c) l2cap_clear_timer(&c->retrans_timer) #define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer) #define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \ L2CAP_DEFAULT_MONITOR_TO); #define __clear_monitor_timer(c) l2cap_clear_timer(&c->monitor_timer) #define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer) #define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \ L2CAP_DEFAULT_ACK_TO); #define __clear_ack_timer(c) l2cap_clear_timer(&c->ack_timer) #define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer) static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2) { Loading