Re: 3.10-rc: bluetooth disappeared on thinkpad x60 (regression)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Pavel,

On Tue, Jun 11, 2013, Johan Hedberg wrote:
> On Mon, Jun 10, 2013, Pavel Machek wrote:
> > < HCI Command: Delete Stored Link Key (0x03|0x0012) plen 7
> >     bdaddr 00:00:00:00:00:00 all 1
> > > HCI Event: Command Complete (0x0e) plen 4
> >     Delete Stored Link Key (0x03|0x0012) ncmd 1
> >     status 0x11 deleted 0
> >     Error: Unsupported Feature or Parameter Value
> 
> Here's the cause of your issue. It's not one of the recently added HCI
> commands but one that's been around for quite some time. I just checked
> and it's even there in kernel 3.9, so I'm surprised that you're saying
> this is a regression since that version. Are you completely sure about
> it?

Could you try if the attached patch helps? It modifies the HCI request
state tracking to allow flagging certain HCI commands as non-critical
and just ignores their failures.

If the patch helps, could you still provide a HCI trace (both plain text
and btsnoop format) of a successful "hciconfig hci0 up"? It might help
create a simpler patch for this issue.

Johan
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 10eb9b3..2ee2520 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -265,6 +265,7 @@ typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status);
 
 struct hci_req_ctrl {
 	bool			start;
+	bool			ignore_status;
 	u8			event;
 	hci_req_complete_t	complete;
 };
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 7cb6d36..f1d7500 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1084,7 +1084,7 @@ int hci_req_run(struct hci_request *req, hci_req_complete_t complete);
 void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
 		 const void *param);
 void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
-		    const void *param, u8 event);
+		    const void *param, u8 event, bool ignore_status);
 void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status);
 
 struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index d817c93..c3d5056 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -145,7 +145,7 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
 
 	hci_req_init(&req, hdev);
 
-	hci_req_add_ev(&req, opcode, plen, param, event);
+	hci_req_add_ev(&req, opcode, plen, param, event, false);
 
 	hdev->req_status = HCI_REQ_PEND;
 
@@ -367,7 +367,8 @@ static void bredr_setup(struct hci_request *req)
 
 	bacpy(&cp.bdaddr, BDADDR_ANY);
 	cp.delete_all = 0x01;
-	hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
+	hci_req_add_ev(req, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp,
+		       0, true);
 
 	/* Read page scan parameters */
 	if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) {
@@ -2669,7 +2670,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
 
 /* Queue a command to an asynchronous HCI request */
 void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
-		    const void *param, u8 event)
+		    const void *param, u8 event, bool ignore_status)
 {
 	struct hci_dev *hdev = req->hdev;
 	struct sk_buff *skb;
@@ -2694,6 +2695,7 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
 		bt_cb(skb)->req.start = true;
 
 	bt_cb(skb)->req.event = event;
+	bt_cb(skb)->req.ignore_status = ignore_status;
 
 	skb_queue_tail(&req->cmd_q, skb);
 }
@@ -2701,7 +2703,7 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
 void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
 		 const void *param)
 {
-	hci_req_add_ev(req, opcode, plen, param, 0);
+	hci_req_add_ev(req, opcode, plen, param, 0, false);
 }
 
 /* Get data from the previously sent command */
@@ -3425,6 +3427,10 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
 		return;
 	}
 
+	/* Check for commands whose failures aren't critical */
+	if (bt_cb(hdev->sent_cmd)->req.ignore_status)
+		status = 0;
+
 	/* If the command succeeded and there's still more commands in
 	 * this request the request is not yet complete.
 	 */

[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux