@@ -804,7 +804,6 @@ struct hci_conn_params {
804804extern struct list_head hci_dev_list ;
805805extern struct list_head hci_cb_list ;
806806extern rwlock_t hci_dev_list_lock ;
807- extern struct mutex hci_cb_list_lock ;
808807
809808#define hci_dev_set_flag (hdev , nr ) set_bit((nr), (hdev)->dev_flags)
810809#define hci_dev_clear_flag (hdev , nr ) clear_bit((nr), (hdev)->dev_flags)
@@ -2007,68 +2006,103 @@ struct hci_cb {
20072006
20082007 char * name ;
20092008
2009+ bool (* match ) (struct hci_conn * conn );
20102010 void (* connect_cfm ) (struct hci_conn * conn , __u8 status );
20112011 void (* disconn_cfm ) (struct hci_conn * conn , __u8 status );
20122012 void (* security_cfm ) (struct hci_conn * conn , __u8 status ,
2013- __u8 encrypt );
2013+ __u8 encrypt );
20142014 void (* key_change_cfm ) (struct hci_conn * conn , __u8 status );
20152015 void (* role_switch_cfm ) (struct hci_conn * conn , __u8 status , __u8 role );
20162016};
20172017
2018+ static inline void hci_cb_lookup (struct hci_conn * conn , struct list_head * list )
2019+ {
2020+ struct hci_cb * cb , * cpy ;
2021+
2022+ rcu_read_lock ();
2023+ list_for_each_entry_rcu (cb , & hci_cb_list , list ) {
2024+ if (cb -> match && cb -> match (conn )) {
2025+ cpy = kmalloc (sizeof (* cpy ), GFP_ATOMIC );
2026+ if (!cpy )
2027+ break ;
2028+
2029+ * cpy = * cb ;
2030+ INIT_LIST_HEAD (& cpy -> list );
2031+ list_add_rcu (& cpy -> list , list );
2032+ }
2033+ }
2034+ rcu_read_unlock ();
2035+ }
2036+
20182037static inline void hci_connect_cfm (struct hci_conn * conn , __u8 status )
20192038{
2020- struct hci_cb * cb ;
2039+ struct list_head list ;
2040+ struct hci_cb * cb , * tmp ;
2041+
2042+ INIT_LIST_HEAD (& list );
2043+ hci_cb_lookup (conn , & list );
20212044
2022- mutex_lock (& hci_cb_list_lock );
2023- list_for_each_entry (cb , & hci_cb_list , list ) {
2045+ list_for_each_entry_safe (cb , tmp , & list , list ) {
20242046 if (cb -> connect_cfm )
20252047 cb -> connect_cfm (conn , status );
2048+ kfree (cb );
20262049 }
2027- mutex_unlock (& hci_cb_list_lock );
20282050
20292051 if (conn -> connect_cfm_cb )
20302052 conn -> connect_cfm_cb (conn , status );
20312053}
20322054
20332055static inline void hci_disconn_cfm (struct hci_conn * conn , __u8 reason )
20342056{
2035- struct hci_cb * cb ;
2057+ struct list_head list ;
2058+ struct hci_cb * cb , * tmp ;
2059+
2060+ INIT_LIST_HEAD (& list );
2061+ hci_cb_lookup (conn , & list );
20362062
2037- mutex_lock (& hci_cb_list_lock );
2038- list_for_each_entry (cb , & hci_cb_list , list ) {
2063+ list_for_each_entry_safe (cb , tmp , & list , list ) {
20392064 if (cb -> disconn_cfm )
20402065 cb -> disconn_cfm (conn , reason );
2066+ kfree (cb );
20412067 }
2042- mutex_unlock (& hci_cb_list_lock );
20432068
20442069 if (conn -> disconn_cfm_cb )
20452070 conn -> disconn_cfm_cb (conn , reason );
20462071}
20472072
2048- static inline void hci_auth_cfm (struct hci_conn * conn , __u8 status )
2073+ static inline void hci_security_cfm (struct hci_conn * conn , __u8 status ,
2074+ __u8 encrypt )
20492075{
2050- struct hci_cb * cb ;
2051- __u8 encrypt ;
2052-
2053- if (test_bit (HCI_CONN_ENCRYPT_PEND , & conn -> flags ))
2054- return ;
2076+ struct list_head list ;
2077+ struct hci_cb * cb , * tmp ;
20552078
2056- encrypt = test_bit (HCI_CONN_ENCRYPT , & conn -> flags ) ? 0x01 : 0x00 ;
2079+ INIT_LIST_HEAD (& list );
2080+ hci_cb_lookup (conn , & list );
20572081
2058- mutex_lock (& hci_cb_list_lock );
2059- list_for_each_entry (cb , & hci_cb_list , list ) {
2082+ list_for_each_entry_safe (cb , tmp , & list , list ) {
20602083 if (cb -> security_cfm )
20612084 cb -> security_cfm (conn , status , encrypt );
2085+ kfree (cb );
20622086 }
2063- mutex_unlock (& hci_cb_list_lock );
20642087
20652088 if (conn -> security_cfm_cb )
20662089 conn -> security_cfm_cb (conn , status );
20672090}
20682091
2092+ static inline void hci_auth_cfm (struct hci_conn * conn , __u8 status )
2093+ {
2094+ __u8 encrypt ;
2095+
2096+ if (test_bit (HCI_CONN_ENCRYPT_PEND , & conn -> flags ))
2097+ return ;
2098+
2099+ encrypt = test_bit (HCI_CONN_ENCRYPT , & conn -> flags ) ? 0x01 : 0x00 ;
2100+
2101+ hci_security_cfm (conn , status , encrypt );
2102+ }
2103+
20692104static inline void hci_encrypt_cfm (struct hci_conn * conn , __u8 status )
20702105{
2071- struct hci_cb * cb ;
20722106 __u8 encrypt ;
20732107
20742108 if (conn -> state == BT_CONFIG ) {
@@ -2095,40 +2129,38 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
20952129 conn -> sec_level = conn -> pending_sec_level ;
20962130 }
20972131
2098- mutex_lock (& hci_cb_list_lock );
2099- list_for_each_entry (cb , & hci_cb_list , list ) {
2100- if (cb -> security_cfm )
2101- cb -> security_cfm (conn , status , encrypt );
2102- }
2103- mutex_unlock (& hci_cb_list_lock );
2104-
2105- if (conn -> security_cfm_cb )
2106- conn -> security_cfm_cb (conn , status );
2132+ hci_security_cfm (conn , status , encrypt );
21072133}
21082134
21092135static inline void hci_key_change_cfm (struct hci_conn * conn , __u8 status )
21102136{
2111- struct hci_cb * cb ;
2137+ struct list_head list ;
2138+ struct hci_cb * cb , * tmp ;
2139+
2140+ INIT_LIST_HEAD (& list );
2141+ hci_cb_lookup (conn , & list );
21122142
2113- mutex_lock (& hci_cb_list_lock );
2114- list_for_each_entry (cb , & hci_cb_list , list ) {
2143+ list_for_each_entry_safe (cb , tmp , & list , list ) {
21152144 if (cb -> key_change_cfm )
21162145 cb -> key_change_cfm (conn , status );
2146+ kfree (cb );
21172147 }
2118- mutex_unlock (& hci_cb_list_lock );
21192148}
21202149
21212150static inline void hci_role_switch_cfm (struct hci_conn * conn , __u8 status ,
21222151 __u8 role )
21232152{
2124- struct hci_cb * cb ;
2153+ struct list_head list ;
2154+ struct hci_cb * cb , * tmp ;
2155+
2156+ INIT_LIST_HEAD (& list );
2157+ hci_cb_lookup (conn , & list );
21252158
2126- mutex_lock (& hci_cb_list_lock );
2127- list_for_each_entry (cb , & hci_cb_list , list ) {
2159+ list_for_each_entry_safe (cb , tmp , & list , list ) {
21282160 if (cb -> role_switch_cfm )
21292161 cb -> role_switch_cfm (conn , status , role );
2162+ kfree (cb );
21302163 }
2131- mutex_unlock (& hci_cb_list_lock );
21322164}
21332165
21342166static inline bool hci_bdaddr_is_rpa (bdaddr_t * bdaddr , u8 addr_type )
0 commit comments