@@ -4793,28 +4793,33 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
47934793 status );
47944794}
47954795
4796- static void read_local_oob_data_complete (struct hci_dev * hdev , u8 status ,
4797- u16 opcode , struct sk_buff * skb )
4796+ static void read_local_oob_data_complete (struct hci_dev * hdev , void * data , int err )
47984797{
47994798 struct mgmt_rp_read_local_oob_data mgmt_rp ;
48004799 size_t rp_size = sizeof (mgmt_rp );
4801- struct mgmt_pending_cmd * cmd ;
4800+ struct mgmt_pending_cmd * cmd = data ;
4801+ struct sk_buff * skb = cmd -> skb ;
4802+ u8 status = mgmt_status (err );
48024803
4803- bt_dev_dbg (hdev , "status %u" , status );
4804+ if (!status ) {
4805+ if (!skb )
4806+ status = MGMT_STATUS_FAILED ;
4807+ else if (IS_ERR (skb ))
4808+ status = mgmt_status (PTR_ERR (skb ));
4809+ else
4810+ status = mgmt_status (skb -> data [0 ]);
4811+ }
48044812
4805- cmd = pending_find (MGMT_OP_READ_LOCAL_OOB_DATA , hdev );
4806- if (!cmd )
4807- return ;
4813+ bt_dev_dbg (hdev , "status %d" , status );
48084814
4809- if (status || !skb ) {
4810- mgmt_cmd_status (cmd -> sk , hdev -> id , MGMT_OP_READ_LOCAL_OOB_DATA ,
4811- status ? mgmt_status (status ) : MGMT_STATUS_FAILED );
4815+ if (status ) {
4816+ mgmt_cmd_status (cmd -> sk , hdev -> id , MGMT_OP_READ_LOCAL_OOB_DATA , status );
48124817 goto remove ;
48134818 }
48144819
48154820 memset (& mgmt_rp , 0 , sizeof (mgmt_rp ));
48164821
4817- if (opcode == HCI_OP_READ_LOCAL_OOB_DATA ) {
4822+ if (! bredr_sc_enabled ( hdev ) ) {
48184823 struct hci_rp_read_local_oob_data * rp = (void * ) skb -> data ;
48194824
48204825 if (skb -> len < sizeof (* rp )) {
@@ -4849,14 +4854,31 @@ static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
48494854 MGMT_STATUS_SUCCESS , & mgmt_rp , rp_size );
48504855
48514856remove :
4852- mgmt_pending_remove (cmd );
4857+ if (skb && !IS_ERR (skb ))
4858+ kfree_skb (skb );
4859+
4860+ mgmt_pending_free (cmd );
4861+ }
4862+
4863+ static int read_local_oob_data_sync (struct hci_dev * hdev , void * data )
4864+ {
4865+ struct mgmt_pending_cmd * cmd = data ;
4866+
4867+ if (bredr_sc_enabled (hdev ))
4868+ cmd -> skb = hci_read_local_oob_data_sync (hdev , true, cmd -> sk );
4869+ else
4870+ cmd -> skb = hci_read_local_oob_data_sync (hdev , false, cmd -> sk );
4871+
4872+ if (IS_ERR (cmd -> skb ))
4873+ return PTR_ERR (cmd -> skb );
4874+ else
4875+ return 0 ;
48534876}
48544877
48554878static int read_local_oob_data (struct sock * sk , struct hci_dev * hdev ,
48564879 void * data , u16 data_len )
48574880{
48584881 struct mgmt_pending_cmd * cmd ;
4859- struct hci_request req ;
48604882 int err ;
48614883
48624884 bt_dev_dbg (hdev , "sock %p" , sk );
@@ -4881,22 +4903,20 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev,
48814903 goto unlock ;
48824904 }
48834905
4884- cmd = mgmt_pending_add (sk , MGMT_OP_READ_LOCAL_OOB_DATA , hdev , NULL , 0 );
4885- if (!cmd ) {
4906+ cmd = mgmt_pending_new (sk , MGMT_OP_READ_LOCAL_OOB_DATA , hdev , NULL , 0 );
4907+ if (!cmd )
48864908 err = - ENOMEM ;
4887- goto unlock ;
4888- }
4889-
4890- hci_req_init (& req , hdev );
4891-
4892- if (bredr_sc_enabled (hdev ))
4893- hci_req_add (& req , HCI_OP_READ_LOCAL_OOB_EXT_DATA , 0 , NULL );
48944909 else
4895- hci_req_add (& req , HCI_OP_READ_LOCAL_OOB_DATA , 0 , NULL );
4910+ err = hci_cmd_sync_queue (hdev , read_local_oob_data_sync , cmd ,
4911+ read_local_oob_data_complete );
48964912
4897- err = hci_req_run_skb (& req , read_local_oob_data_complete );
4898- if (err < 0 )
4899- mgmt_pending_remove (cmd );
4913+ if (err < 0 ) {
4914+ err = mgmt_cmd_status (sk , hdev -> id , MGMT_OP_READ_LOCAL_OOB_DATA ,
4915+ MGMT_STATUS_FAILED );
4916+
4917+ if (cmd )
4918+ mgmt_pending_free (cmd );
4919+ }
49004920
49014921unlock :
49024922 hci_dev_unlock (hdev );
0 commit comments