@@ -800,7 +800,6 @@ struct hci_conn_params {
800800extern struct list_head hci_dev_list ;
801801extern struct list_head hci_cb_list ;
802802extern rwlock_t hci_dev_list_lock ;
803- extern struct mutex hci_cb_list_lock ;
804803
805804#define hci_dev_set_flag (hdev , nr ) set_bit((nr), (hdev)->dev_flags)
806805#define hci_dev_clear_flag (hdev , nr ) clear_bit((nr), (hdev)->dev_flags)
@@ -1949,68 +1948,103 @@ struct hci_cb {
19491948
19501949 char * name ;
19511950
1951+ bool (* match ) (struct hci_conn * conn );
19521952 void (* connect_cfm ) (struct hci_conn * conn , __u8 status );
19531953 void (* disconn_cfm ) (struct hci_conn * conn , __u8 status );
19541954 void (* security_cfm ) (struct hci_conn * conn , __u8 status ,
1955- __u8 encrypt );
1955+ __u8 encrypt );
19561956 void (* key_change_cfm ) (struct hci_conn * conn , __u8 status );
19571957 void (* role_switch_cfm ) (struct hci_conn * conn , __u8 status , __u8 role );
19581958};
19591959
1960+ static inline void hci_cb_lookup (struct hci_conn * conn , struct list_head * list )
1961+ {
1962+ struct hci_cb * cb , * cpy ;
1963+
1964+ rcu_read_lock ();
1965+ list_for_each_entry_rcu (cb , & hci_cb_list , list ) {
1966+ if (cb -> match && cb -> match (conn )) {
1967+ cpy = kmalloc (sizeof (* cpy ), GFP_ATOMIC );
1968+ if (!cpy )
1969+ break ;
1970+
1971+ * cpy = * cb ;
1972+ INIT_LIST_HEAD (& cpy -> list );
1973+ list_add_rcu (& cpy -> list , list );
1974+ }
1975+ }
1976+ rcu_read_unlock ();
1977+ }
1978+
19601979static inline void hci_connect_cfm (struct hci_conn * conn , __u8 status )
19611980{
1962- struct hci_cb * cb ;
1981+ struct list_head list ;
1982+ struct hci_cb * cb , * tmp ;
1983+
1984+ INIT_LIST_HEAD (& list );
1985+ hci_cb_lookup (conn , & list );
19631986
1964- mutex_lock (& hci_cb_list_lock );
1965- list_for_each_entry (cb , & hci_cb_list , list ) {
1987+ list_for_each_entry_safe (cb , tmp , & list , list ) {
19661988 if (cb -> connect_cfm )
19671989 cb -> connect_cfm (conn , status );
1990+ kfree (cb );
19681991 }
1969- mutex_unlock (& hci_cb_list_lock );
19701992
19711993 if (conn -> connect_cfm_cb )
19721994 conn -> connect_cfm_cb (conn , status );
19731995}
19741996
19751997static inline void hci_disconn_cfm (struct hci_conn * conn , __u8 reason )
19761998{
1977- struct hci_cb * cb ;
1999+ struct list_head list ;
2000+ struct hci_cb * cb , * tmp ;
2001+
2002+ INIT_LIST_HEAD (& list );
2003+ hci_cb_lookup (conn , & list );
19782004
1979- mutex_lock (& hci_cb_list_lock );
1980- list_for_each_entry (cb , & hci_cb_list , list ) {
2005+ list_for_each_entry_safe (cb , tmp , & list , list ) {
19812006 if (cb -> disconn_cfm )
19822007 cb -> disconn_cfm (conn , reason );
2008+ kfree (cb );
19832009 }
1984- mutex_unlock (& hci_cb_list_lock );
19852010
19862011 if (conn -> disconn_cfm_cb )
19872012 conn -> disconn_cfm_cb (conn , reason );
19882013}
19892014
1990- static inline void hci_auth_cfm (struct hci_conn * conn , __u8 status )
2015+ static inline void hci_security_cfm (struct hci_conn * conn , __u8 status ,
2016+ __u8 encrypt )
19912017{
1992- struct hci_cb * cb ;
1993- __u8 encrypt ;
1994-
1995- if (test_bit (HCI_CONN_ENCRYPT_PEND , & conn -> flags ))
1996- return ;
2018+ struct list_head list ;
2019+ struct hci_cb * cb , * tmp ;
19972020
1998- encrypt = test_bit (HCI_CONN_ENCRYPT , & conn -> flags ) ? 0x01 : 0x00 ;
2021+ INIT_LIST_HEAD (& list );
2022+ hci_cb_lookup (conn , & list );
19992023
2000- mutex_lock (& hci_cb_list_lock );
2001- list_for_each_entry (cb , & hci_cb_list , list ) {
2024+ list_for_each_entry_safe (cb , tmp , & list , list ) {
20022025 if (cb -> security_cfm )
20032026 cb -> security_cfm (conn , status , encrypt );
2027+ kfree (cb );
20042028 }
2005- mutex_unlock (& hci_cb_list_lock );
20062029
20072030 if (conn -> security_cfm_cb )
20082031 conn -> security_cfm_cb (conn , status );
20092032}
20102033
2034+ static inline void hci_auth_cfm (struct hci_conn * conn , __u8 status )
2035+ {
2036+ __u8 encrypt ;
2037+
2038+ if (test_bit (HCI_CONN_ENCRYPT_PEND , & conn -> flags ))
2039+ return ;
2040+
2041+ encrypt = test_bit (HCI_CONN_ENCRYPT , & conn -> flags ) ? 0x01 : 0x00 ;
2042+
2043+ hci_security_cfm (conn , status , encrypt );
2044+ }
2045+
20112046static inline void hci_encrypt_cfm (struct hci_conn * conn , __u8 status )
20122047{
2013- struct hci_cb * cb ;
20142048 __u8 encrypt ;
20152049
20162050 if (conn -> state == BT_CONFIG ) {
@@ -2037,40 +2071,38 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
20372071 conn -> sec_level = conn -> pending_sec_level ;
20382072 }
20392073
2040- mutex_lock (& hci_cb_list_lock );
2041- list_for_each_entry (cb , & hci_cb_list , list ) {
2042- if (cb -> security_cfm )
2043- cb -> security_cfm (conn , status , encrypt );
2044- }
2045- mutex_unlock (& hci_cb_list_lock );
2046-
2047- if (conn -> security_cfm_cb )
2048- conn -> security_cfm_cb (conn , status );
2074+ hci_security_cfm (conn , status , encrypt );
20492075}
20502076
20512077static inline void hci_key_change_cfm (struct hci_conn * conn , __u8 status )
20522078{
2053- struct hci_cb * cb ;
2079+ struct list_head list ;
2080+ struct hci_cb * cb , * tmp ;
2081+
2082+ INIT_LIST_HEAD (& list );
2083+ hci_cb_lookup (conn , & list );
20542084
2055- mutex_lock (& hci_cb_list_lock );
2056- list_for_each_entry (cb , & hci_cb_list , list ) {
2085+ list_for_each_entry_safe (cb , tmp , & list , list ) {
20572086 if (cb -> key_change_cfm )
20582087 cb -> key_change_cfm (conn , status );
2088+ kfree (cb );
20592089 }
2060- mutex_unlock (& hci_cb_list_lock );
20612090}
20622091
20632092static inline void hci_role_switch_cfm (struct hci_conn * conn , __u8 status ,
20642093 __u8 role )
20652094{
2066- struct hci_cb * cb ;
2095+ struct list_head list ;
2096+ struct hci_cb * cb , * tmp ;
2097+
2098+ INIT_LIST_HEAD (& list );
2099+ hci_cb_lookup (conn , & list );
20672100
2068- mutex_lock (& hci_cb_list_lock );
2069- list_for_each_entry (cb , & hci_cb_list , list ) {
2101+ list_for_each_entry_safe (cb , tmp , & list , list ) {
20702102 if (cb -> role_switch_cfm )
20712103 cb -> role_switch_cfm (conn , status , role );
2104+ kfree (cb );
20722105 }
2073- mutex_unlock (& hci_cb_list_lock );
20742106}
20752107
20762108static inline bool hci_bdaddr_is_rpa (bdaddr_t * bdaddr , u8 addr_type )
0 commit comments