@@ -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)
@@ -2017,68 +2016,103 @@ struct hci_cb {
20172016
20182017 char * name ;
20192018
2019+ bool (* match ) (struct hci_conn * conn );
20202020 void (* connect_cfm ) (struct hci_conn * conn , __u8 status );
20212021 void (* disconn_cfm ) (struct hci_conn * conn , __u8 status );
20222022 void (* security_cfm ) (struct hci_conn * conn , __u8 status ,
2023- __u8 encrypt );
2023+ __u8 encrypt );
20242024 void (* key_change_cfm ) (struct hci_conn * conn , __u8 status );
20252025 void (* role_switch_cfm ) (struct hci_conn * conn , __u8 status , __u8 role );
20262026};
20272027
2028+ static inline void hci_cb_lookup (struct hci_conn * conn , struct list_head * list )
2029+ {
2030+ struct hci_cb * cb , * cpy ;
2031+
2032+ rcu_read_lock ();
2033+ list_for_each_entry_rcu (cb , & hci_cb_list , list ) {
2034+ if (cb -> match && cb -> match (conn )) {
2035+ cpy = kmalloc (sizeof (* cpy ), GFP_ATOMIC );
2036+ if (!cpy )
2037+ break ;
2038+
2039+ * cpy = * cb ;
2040+ INIT_LIST_HEAD (& cpy -> list );
2041+ list_add_rcu (& cpy -> list , list );
2042+ }
2043+ }
2044+ rcu_read_unlock ();
2045+ }
2046+
20282047static inline void hci_connect_cfm (struct hci_conn * conn , __u8 status )
20292048{
2030- struct hci_cb * cb ;
2049+ struct list_head list ;
2050+ struct hci_cb * cb , * tmp ;
2051+
2052+ INIT_LIST_HEAD (& list );
2053+ hci_cb_lookup (conn , & list );
20312054
2032- mutex_lock (& hci_cb_list_lock );
2033- list_for_each_entry (cb , & hci_cb_list , list ) {
2055+ list_for_each_entry_safe (cb , tmp , & list , list ) {
20342056 if (cb -> connect_cfm )
20352057 cb -> connect_cfm (conn , status );
2058+ kfree (cb );
20362059 }
2037- mutex_unlock (& hci_cb_list_lock );
20382060
20392061 if (conn -> connect_cfm_cb )
20402062 conn -> connect_cfm_cb (conn , status );
20412063}
20422064
20432065static inline void hci_disconn_cfm (struct hci_conn * conn , __u8 reason )
20442066{
2045- struct hci_cb * cb ;
2067+ struct list_head list ;
2068+ struct hci_cb * cb , * tmp ;
2069+
2070+ INIT_LIST_HEAD (& list );
2071+ hci_cb_lookup (conn , & list );
20462072
2047- mutex_lock (& hci_cb_list_lock );
2048- list_for_each_entry (cb , & hci_cb_list , list ) {
2073+ list_for_each_entry_safe (cb , tmp , & list , list ) {
20492074 if (cb -> disconn_cfm )
20502075 cb -> disconn_cfm (conn , reason );
2076+ kfree (cb );
20512077 }
2052- mutex_unlock (& hci_cb_list_lock );
20532078
20542079 if (conn -> disconn_cfm_cb )
20552080 conn -> disconn_cfm_cb (conn , reason );
20562081}
20572082
2058- static inline void hci_auth_cfm (struct hci_conn * conn , __u8 status )
2083+ static inline void hci_security_cfm (struct hci_conn * conn , __u8 status ,
2084+ __u8 encrypt )
20592085{
2060- struct hci_cb * cb ;
2061- __u8 encrypt ;
2062-
2063- if (test_bit (HCI_CONN_ENCRYPT_PEND , & conn -> flags ))
2064- return ;
2086+ struct list_head list ;
2087+ struct hci_cb * cb , * tmp ;
20652088
2066- encrypt = test_bit (HCI_CONN_ENCRYPT , & conn -> flags ) ? 0x01 : 0x00 ;
2089+ INIT_LIST_HEAD (& list );
2090+ hci_cb_lookup (conn , & list );
20672091
2068- mutex_lock (& hci_cb_list_lock );
2069- list_for_each_entry (cb , & hci_cb_list , list ) {
2092+ list_for_each_entry_safe (cb , tmp , & list , list ) {
20702093 if (cb -> security_cfm )
20712094 cb -> security_cfm (conn , status , encrypt );
2095+ kfree (cb );
20722096 }
2073- mutex_unlock (& hci_cb_list_lock );
20742097
20752098 if (conn -> security_cfm_cb )
20762099 conn -> security_cfm_cb (conn , status );
20772100}
20782101
2102+ static inline void hci_auth_cfm (struct hci_conn * conn , __u8 status )
2103+ {
2104+ __u8 encrypt ;
2105+
2106+ if (test_bit (HCI_CONN_ENCRYPT_PEND , & conn -> flags ))
2107+ return ;
2108+
2109+ encrypt = test_bit (HCI_CONN_ENCRYPT , & conn -> flags ) ? 0x01 : 0x00 ;
2110+
2111+ hci_security_cfm (conn , status , encrypt );
2112+ }
2113+
20792114static inline void hci_encrypt_cfm (struct hci_conn * conn , __u8 status )
20802115{
2081- struct hci_cb * cb ;
20822116 __u8 encrypt ;
20832117
20842118 if (conn -> state == BT_CONFIG ) {
@@ -2105,40 +2139,38 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
21052139 conn -> sec_level = conn -> pending_sec_level ;
21062140 }
21072141
2108- mutex_lock (& hci_cb_list_lock );
2109- list_for_each_entry (cb , & hci_cb_list , list ) {
2110- if (cb -> security_cfm )
2111- cb -> security_cfm (conn , status , encrypt );
2112- }
2113- mutex_unlock (& hci_cb_list_lock );
2114-
2115- if (conn -> security_cfm_cb )
2116- conn -> security_cfm_cb (conn , status );
2142+ hci_security_cfm (conn , status , encrypt );
21172143}
21182144
21192145static inline void hci_key_change_cfm (struct hci_conn * conn , __u8 status )
21202146{
2121- struct hci_cb * cb ;
2147+ struct list_head list ;
2148+ struct hci_cb * cb , * tmp ;
2149+
2150+ INIT_LIST_HEAD (& list );
2151+ hci_cb_lookup (conn , & list );
21222152
2123- mutex_lock (& hci_cb_list_lock );
2124- list_for_each_entry (cb , & hci_cb_list , list ) {
2153+ list_for_each_entry_safe (cb , tmp , & list , list ) {
21252154 if (cb -> key_change_cfm )
21262155 cb -> key_change_cfm (conn , status );
2156+ kfree (cb );
21272157 }
2128- mutex_unlock (& hci_cb_list_lock );
21292158}
21302159
21312160static inline void hci_role_switch_cfm (struct hci_conn * conn , __u8 status ,
21322161 __u8 role )
21332162{
2134- struct hci_cb * cb ;
2163+ struct list_head list ;
2164+ struct hci_cb * cb , * tmp ;
2165+
2166+ INIT_LIST_HEAD (& list );
2167+ hci_cb_lookup (conn , & list );
21352168
2136- mutex_lock (& hci_cb_list_lock );
2137- list_for_each_entry (cb , & hci_cb_list , list ) {
2169+ list_for_each_entry_safe (cb , tmp , & list , list ) {
21382170 if (cb -> role_switch_cfm )
21392171 cb -> role_switch_cfm (conn , status , role );
2172+ kfree (cb );
21402173 }
2141- mutex_unlock (& hci_cb_list_lock );
21422174}
21432175
21442176static inline bool hci_bdaddr_is_rpa (bdaddr_t * bdaddr , u8 addr_type )
0 commit comments