@@ -2731,17 +2731,19 @@ static void hci_remote_features_evt(struct hci_dev *hdev,
27312731 hci_dev_unlock (hdev );
27322732}
27332733
2734- static void hci_cmd_complete_evt (struct hci_dev * hdev , struct sk_buff * skb )
2734+ static void hci_cmd_complete_evt (struct hci_dev * hdev , struct sk_buff * skb ,
2735+ u16 * opcode , u8 * status ,
2736+ hci_req_complete_t * req_complete ,
2737+ hci_req_complete_skb_t * req_complete_skb )
27352738{
27362739 struct hci_ev_cmd_complete * ev = (void * ) skb -> data ;
2737- u8 status = skb -> data [sizeof (* ev )];
2738- __u16 opcode ;
27392740
2740- skb_pull (skb , sizeof (* ev ));
2741+ * opcode = __le16_to_cpu (ev -> opcode );
2742+ * status = skb -> data [sizeof (* ev )];
27412743
2742- opcode = __le16_to_cpu ( ev -> opcode );
2744+ skb_pull ( skb , sizeof ( * ev ) );
27432745
2744- switch (opcode ) {
2746+ switch (* opcode ) {
27452747 case HCI_OP_INQUIRY_CANCEL :
27462748 hci_cc_inquiry_cancel (hdev , skb );
27472749 break ;
@@ -3019,32 +3021,36 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
30193021 break ;
30203022
30213023 default :
3022- BT_DBG ("%s opcode 0x%4.4x" , hdev -> name , opcode );
3024+ BT_DBG ("%s opcode 0x%4.4x" , hdev -> name , * opcode );
30233025 break ;
30243026 }
30253027
3026- if (opcode != HCI_OP_NOP )
3028+ if (* opcode != HCI_OP_NOP )
30273029 cancel_delayed_work (& hdev -> cmd_timer );
30283030
30293031 if (ev -> ncmd && !test_bit (HCI_RESET , & hdev -> flags ))
30303032 atomic_set (& hdev -> cmd_cnt , 1 );
30313033
3032- hci_req_cmd_complete (hdev , opcode , status );
3034+ hci_req_cmd_complete (hdev , * opcode , * status , req_complete ,
3035+ req_complete_skb );
30333036
30343037 if (atomic_read (& hdev -> cmd_cnt ) && !skb_queue_empty (& hdev -> cmd_q ))
30353038 queue_work (hdev -> workqueue , & hdev -> cmd_work );
30363039}
30373040
3038- static void hci_cmd_status_evt (struct hci_dev * hdev , struct sk_buff * skb )
3041+ static void hci_cmd_status_evt (struct hci_dev * hdev , struct sk_buff * skb ,
3042+ u16 * opcode , u8 * status ,
3043+ hci_req_complete_t * req_complete ,
3044+ hci_req_complete_skb_t * req_complete_skb )
30393045{
30403046 struct hci_ev_cmd_status * ev = (void * ) skb -> data ;
3041- __u16 opcode ;
30423047
30433048 skb_pull (skb , sizeof (* ev ));
30443049
3045- opcode = __le16_to_cpu (ev -> opcode );
3050+ * opcode = __le16_to_cpu (ev -> opcode );
3051+ * status = ev -> status ;
30463052
3047- switch (opcode ) {
3053+ switch (* opcode ) {
30483054 case HCI_OP_INQUIRY :
30493055 hci_cs_inquiry (hdev , ev -> status );
30503056 break ;
@@ -3114,11 +3120,11 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
31143120 break ;
31153121
31163122 default :
3117- BT_DBG ("%s opcode 0x%4.4x" , hdev -> name , opcode );
3123+ BT_DBG ("%s opcode 0x%4.4x" , hdev -> name , * opcode );
31183124 break ;
31193125 }
31203126
3121- if (opcode != HCI_OP_NOP )
3127+ if (* opcode != HCI_OP_NOP )
31223128 cancel_delayed_work (& hdev -> cmd_timer );
31233129
31243130 if (ev -> ncmd && !test_bit (HCI_RESET , & hdev -> flags ))
@@ -3132,7 +3138,8 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
31323138 */
31333139 if (ev -> status ||
31343140 (hdev -> sent_cmd && !bt_cb (hdev -> sent_cmd )-> req .event ))
3135- hci_req_cmd_complete (hdev , opcode , ev -> status );
3141+ hci_req_cmd_complete (hdev , * opcode , ev -> status , req_complete ,
3142+ req_complete_skb );
31363143
31373144 if (atomic_read (& hdev -> cmd_cnt ) && !skb_queue_empty (& hdev -> cmd_q ))
31383145 queue_work (hdev -> workqueue , & hdev -> cmd_work );
@@ -5039,7 +5046,11 @@ static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
50395046void hci_event_packet (struct hci_dev * hdev , struct sk_buff * skb )
50405047{
50415048 struct hci_event_hdr * hdr = (void * ) skb -> data ;
5042- __u8 event = hdr -> evt ;
5049+ hci_req_complete_t req_complete = NULL ;
5050+ hci_req_complete_skb_t req_complete_skb = NULL ;
5051+ struct sk_buff * orig_skb = NULL ;
5052+ u8 status = 0 , event = hdr -> evt ;
5053+ u16 opcode = HCI_OP_NOP ;
50435054
50445055 hci_dev_lock (hdev );
50455056
@@ -5053,15 +5064,24 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
50535064
50545065 hci_dev_unlock (hdev );
50555066
5056- skb_pull (skb , HCI_EVENT_HDR_SIZE );
5057-
50585067 if (hdev -> sent_cmd && bt_cb (hdev -> sent_cmd )-> req .event == event ) {
50595068 struct hci_command_hdr * cmd_hdr = (void * ) hdev -> sent_cmd -> data ;
5060- u16 opcode = __le16_to_cpu (cmd_hdr -> opcode );
5061-
5062- hci_req_cmd_complete ( hdev , opcode , 0 );
5069+ opcode = __le16_to_cpu (cmd_hdr -> opcode );
5070+ hci_req_cmd_complete ( hdev , opcode , status , & req_complete ,
5071+ & req_complete_skb );
50635072 }
50645073
5074+ /* If it looks like we might end up having to call
5075+ * req_complete_skb, store a pristine copy of the skb since the
5076+ * various handlers may modify the original one through
5077+ * skb_pull() calls, etc.
5078+ */
5079+ if (req_complete_skb || event == HCI_EV_CMD_STATUS ||
5080+ event == HCI_EV_CMD_COMPLETE )
5081+ orig_skb = skb_clone (skb , GFP_KERNEL );
5082+
5083+ skb_pull (skb , HCI_EVENT_HDR_SIZE );
5084+
50655085 switch (event ) {
50665086 case HCI_EV_INQUIRY_COMPLETE :
50675087 hci_inquiry_complete_evt (hdev , skb );
@@ -5104,11 +5124,13 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
51045124 break ;
51055125
51065126 case HCI_EV_CMD_COMPLETE :
5107- hci_cmd_complete_evt (hdev , skb );
5127+ hci_cmd_complete_evt (hdev , skb , & opcode , & status ,
5128+ & req_complete , & req_complete_skb );
51085129 break ;
51095130
51105131 case HCI_EV_CMD_STATUS :
5111- hci_cmd_status_evt (hdev , skb );
5132+ hci_cmd_status_evt (hdev , skb , & opcode , & status , & req_complete ,
5133+ & req_complete_skb );
51125134 break ;
51135135
51145136 case HCI_EV_HARDWARE_ERROR :
@@ -5240,6 +5262,12 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
52405262 break ;
52415263 }
52425264
5265+ if (req_complete )
5266+ req_complete (hdev , status , opcode );
5267+ else if (req_complete_skb )
5268+ req_complete_skb (hdev , status , opcode , orig_skb );
5269+
5270+ kfree_skb (orig_skb );
52435271 kfree_skb (skb );
52445272 hdev -> stat .evt_rx ++ ;
52455273}
0 commit comments