aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-04-19 13:14:14 -0400
committerMarcel Holtmann <marcel@holtmann.org>2009-04-19 13:14:14 -0400
commit732547f96ea2442965a24e0ed529d285321a0fff (patch)
tree315350b2dfafd90f06d28163e8f3cf4807e4a6a3
parente2139b32726e5dd184974c785ea3f62026590801 (diff)
Bluetooth: Fallback from eSCO to SCO on unspecified error
Some Bluetooth chips (like the ones from Texas Instruments) don't do proper eSCO negotiations inside the Link Manager. They just return an error code and in case of the Kyocera ED-8800 headset it is just a random error. < HCI Command: Setup Synchronous Connection 0x01|0x0028) plen 17 handle 1 voice setting 0x0060 > HCI Event: Command Status (0x0f) plen 4 Setup Synchronous Connection (0x01|0x0028) status 0x00 ncmd 1 > HCI Event: Synchronous Connect Complete (0x2c) plen 17 status 0x1f handle 257 bdaddr 00:14:0A:xx:xx:xx type eSCO Error: Unspecified Error In these cases it is up to the host stack to fallback to a SCO setup and so retry with SCO parameters. Based on a report by Nick Pelly <npelly@google.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--net/bluetooth/hci_event.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 55534244c3a0..963f9662eaa8 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1646,20 +1646,28 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu
1646 conn->type = SCO_LINK; 1646 conn->type = SCO_LINK;
1647 } 1647 }
1648 1648
1649 if (conn->out && ev->status == 0x1c && conn->attempt < 2) { 1649 switch (ev->status) {
1650 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | 1650 case 0x00:
1651 (hdev->esco_type & EDR_ESCO_MASK);
1652 hci_setup_sync(conn, conn->link->handle);
1653 goto unlock;
1654 }
1655
1656 if (!ev->status) {
1657 conn->handle = __le16_to_cpu(ev->handle); 1651 conn->handle = __le16_to_cpu(ev->handle);
1658 conn->state = BT_CONNECTED; 1652 conn->state = BT_CONNECTED;
1659 1653
1660 hci_conn_add_sysfs(conn); 1654 hci_conn_add_sysfs(conn);
1661 } else 1655 break;
1656
1657 case 0x1c: /* SCO interval rejected */
1658 case 0x1f: /* Unspecified error */
1659 if (conn->out && conn->attempt < 2) {
1660 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
1661 (hdev->esco_type & EDR_ESCO_MASK);
1662 hci_setup_sync(conn, conn->link->handle);
1663 goto unlock;
1664 }
1665 /* fall through */
1666
1667 default:
1662 conn->state = BT_CLOSED; 1668 conn->state = BT_CLOSED;
1669 break;
1670 }
1663 1671
1664 hci_proto_connect_cfm(conn, ev->status); 1672 hci_proto_connect_cfm(conn, ev->status);
1665 if (ev->status) 1673 if (ev->status)