Просмотр исходного кода

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6

Gustavo F. Padovan 14 лет назад
Родитель
Сommit
220b881a77

+ 5 - 1
drivers/bluetooth/btusb.c

@@ -71,6 +71,9 @@ static struct usb_device_id btusb_table[] = {
 	/* Apple MacBookAir3,1, MacBookAir3,2 */
 	/* Apple MacBookAir3,1, MacBookAir3,2 */
 	{ USB_DEVICE(0x05ac, 0x821b) },
 	{ USB_DEVICE(0x05ac, 0x821b) },
 
 
+	/* Apple MacBookPro8,2 */
+	{ USB_DEVICE(0x05ac, 0x821a) },
+
 	/* AVM BlueFRITZ! USB v2.0 */
 	/* AVM BlueFRITZ! USB v2.0 */
 	{ USB_DEVICE(0x057c, 0x3800) },
 	{ USB_DEVICE(0x057c, 0x3800) },
 
 
@@ -690,7 +693,8 @@ static int btusb_send_frame(struct sk_buff *skb)
 		break;
 		break;
 
 
 	case HCI_ACLDATA_PKT:
 	case HCI_ACLDATA_PKT:
-		if (!data->bulk_tx_ep || hdev->conn_hash.acl_num < 1)
+		if (!data->bulk_tx_ep || (hdev->conn_hash.acl_num < 1 &&
+						hdev->conn_hash.le_num < 1))
 			return -ENODEV;
 			return -ENODEV;
 
 
 		urb = usb_alloc_urb(0, GFP_ATOMIC);
 		urb = usb_alloc_urb(0, GFP_ATOMIC);

+ 2 - 0
include/net/bluetooth/hci.h

@@ -84,6 +84,8 @@ enum {
 	HCI_SERVICE_CACHE,
 	HCI_SERVICE_CACHE,
 	HCI_LINK_KEYS,
 	HCI_LINK_KEYS,
 	HCI_DEBUG_KEYS,
 	HCI_DEBUG_KEYS,
+
+	HCI_RESET,
 };
 };
 
 
 /* HCI ioctl defines */
 /* HCI ioctl defines */

+ 8 - 2
net/bluetooth/hci_core.c

@@ -185,6 +185,7 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
 	BT_DBG("%s %ld", hdev->name, opt);
 	BT_DBG("%s %ld", hdev->name, opt);
 
 
 	/* Reset device */
 	/* Reset device */
+	set_bit(HCI_RESET, &hdev->flags);
 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
 }
 }
 
 
@@ -212,8 +213,10 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
 	/* Mandatory initialization */
 	/* Mandatory initialization */
 
 
 	/* Reset */
 	/* Reset */
-	if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks))
+	if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
+			set_bit(HCI_RESET, &hdev->flags);
 			hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
 			hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
+	}
 
 
 	/* Read Local Supported Features */
 	/* Read Local Supported Features */
 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
@@ -583,6 +586,9 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 	hci_req_cancel(hdev, ENODEV);
 	hci_req_cancel(hdev, ENODEV);
 	hci_req_lock(hdev);
 	hci_req_lock(hdev);
 
 
+	/* Stop timer, it might be running */
+	del_timer_sync(&hdev->cmd_timer);
+
 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
 		hci_req_unlock(hdev);
 		hci_req_unlock(hdev);
 		return 0;
 		return 0;
@@ -622,7 +628,6 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 
 
 	/* Drop last sent command */
 	/* Drop last sent command */
 	if (hdev->sent_cmd) {
 	if (hdev->sent_cmd) {
-		del_timer_sync(&hdev->cmd_timer);
 		kfree_skb(hdev->sent_cmd);
 		kfree_skb(hdev->sent_cmd);
 		hdev->sent_cmd = NULL;
 		hdev->sent_cmd = NULL;
 	}
 	}
@@ -1073,6 +1078,7 @@ static void hci_cmd_timer(unsigned long arg)
 
 
 	BT_ERR("%s command tx timeout", hdev->name);
 	BT_ERR("%s command tx timeout", hdev->name);
 	atomic_set(&hdev->cmd_cnt, 1);
 	atomic_set(&hdev->cmd_cnt, 1);
+	clear_bit(HCI_RESET, &hdev->flags);
 	tasklet_schedule(&hdev->cmd_task);
 	tasklet_schedule(&hdev->cmd_task);
 }
 }
 
 

+ 3 - 1
net/bluetooth/hci_event.c

@@ -183,6 +183,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
 
 
 	BT_DBG("%s status 0x%x", hdev->name, status);
 	BT_DBG("%s status 0x%x", hdev->name, status);
 
 
+	clear_bit(HCI_RESET, &hdev->flags);
+
 	hci_req_complete(hdev, HCI_OP_RESET, status);
 	hci_req_complete(hdev, HCI_OP_RESET, status);
 }
 }
 
 
@@ -1865,7 +1867,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	if (ev->opcode != HCI_OP_NOP)
 	if (ev->opcode != HCI_OP_NOP)
 		del_timer(&hdev->cmd_timer);
 		del_timer(&hdev->cmd_timer);
 
 
-	if (ev->ncmd) {
+	if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
 		atomic_set(&hdev->cmd_cnt, 1);
 		atomic_set(&hdev->cmd_cnt, 1);
 		if (!skb_queue_empty(&hdev->cmd_q))
 		if (!skb_queue_empty(&hdev->cmd_q))
 			tasklet_schedule(&hdev->cmd_task);
 			tasklet_schedule(&hdev->cmd_task);

+ 3 - 1
net/bluetooth/l2cap_core.c

@@ -1115,7 +1115,9 @@ int l2cap_ertm_send(struct sock *sk)
 		bt_cb(skb)->tx_seq = pi->next_tx_seq;
 		bt_cb(skb)->tx_seq = pi->next_tx_seq;
 		pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
 		pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
 
 
-		pi->unacked_frames++;
+		if (bt_cb(skb)->retries == 1)
+			pi->unacked_frames++;
+
 		pi->frames_sent++;
 		pi->frames_sent++;
 
 
 		if (skb_queue_is_last(TX_QUEUE(sk), skb))
 		if (skb_queue_is_last(TX_QUEUE(sk), skb))

+ 3 - 2
net/bluetooth/l2cap_sock.c

@@ -923,8 +923,9 @@ void __l2cap_sock_close(struct sock *sk, int reason)
 			rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
 			rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
 			l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
 			l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
 					L2CAP_CONN_RSP, sizeof(rsp), &rsp);
 					L2CAP_CONN_RSP, sizeof(rsp), &rsp);
-		} else
-			l2cap_chan_del(sk, reason);
+		}
+
+		l2cap_chan_del(sk, reason);
 		break;
 		break;
 
 
 	case BT_CONNECT:
 	case BT_CONNECT:

+ 2 - 0
net/bluetooth/mgmt.c

@@ -1389,6 +1389,8 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data,
 	if (!hdev)
 	if (!hdev)
 		return cmd_status(sk, index, mgmt_op, ENODEV);
 		return cmd_status(sk, index, mgmt_op, ENODEV);
 
 
+	hci_dev_lock_bh(hdev);
+
 	if (!test_bit(HCI_UP, &hdev->flags)) {
 	if (!test_bit(HCI_UP, &hdev->flags)) {
 		err = cmd_status(sk, index, mgmt_op, ENETDOWN);
 		err = cmd_status(sk, index, mgmt_op, ENETDOWN);
 		goto failed;
 		goto failed;