On 02.03.2015 07:41, Georg Chini wrote: > On 23.02.2015 09:06, David Henningsson wrote: >> >> >> On 2015-02-21 23:14, Georg Chini wrote: >>> Hello, >>> >>> >>> >>> With the Plantronics 590, the connect() call in bluez5_sco_acquire_cb >>> returns >>> "Protocol not supported". The headset itself is functional, I tested >>> with my mobile. >>> >> I've heard of this, but never seen it myself. I suspect it's a kernel >> regression, but I'm not sure. Does it work with older kernels? Like, >> one, two, three years old kernels or such? >> > I had the chance to test this over the weekend. Works with kernel 3.10. > This was the oldest kernel I still had on my machine, so I'll do some > more > investigations to see where exactly it breaks. Yes, it is a kernel regression introduced in 3.12. There are two reasons why it does no longer work: 1) The driver expects the headset to issue a sync connection finished event (0x2c), even if the connection attempt fails, so that it can test various packet types until it succeeds. My old headset does not do so, it just sends a command status event (0x0f) with the status code 0x1a. So the driver tries its first option and then fails. 2) The headset apparently needs a retrans_effort of 0xff (whatever that parameter means) instead of 0x01. The following patch (for kernel 3.17.2) solves the issue for me. Even if this is not the right approach it at least shows where the problem is. --- a/net/bluetooth/hci_event.c 2014-10-30 17:43:25.000000000 +0100 +++ b/net/bluetooth/hci_event.c 2015-03-02 22:41:11.303887654 +0100 @@ -1738,6 +1738,8 @@ sco->state = BT_CLOSED; - hci_proto_connect_cfm(sco, status); - hci_conn_del(sco); + if (!hci_setup_sync(sco, handle)) { + hci_proto_connect_cfm(sco, status); + hci_conn_del(sco); + } } } --- a/net/bluetooth/hci_conn.c 2014-10-30 17:43:25.000000000 +0100 +++ b/net/bluetooth/hci_conn.c 2015-03-02 21:51:32.569179920 +0100 @@ -37,17 +37,18 @@ u16 pkt_type; u16 max_latency; + u8 retrans_effort; }; static const struct sco_param sco_param_cvsd[] = { - { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000a }, /* S3 */ - { EDR_ESCO_MASK & ~ESCO_2EV3, 0x0007 }, /* S2 */ - { EDR_ESCO_MASK | ESCO_EV3, 0x0007 }, /* S1 */ - { EDR_ESCO_MASK | ESCO_HV3, 0xffff }, /* D1 */ - { EDR_ESCO_MASK | ESCO_HV1, 0xffff }, /* D0 */ + { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000a, 0x01 }, /* S3 */ + { EDR_ESCO_MASK & ~ESCO_2EV3, 0x0007, 0x01 }, /* S2 */ + { EDR_ESCO_MASK | ESCO_EV3, 0x0007, 0x01 }, /* S1 */ + { EDR_ESCO_MASK | ESCO_HV3, 0xffff, 0x01 }, /* D1 */ + { EDR_ESCO_MASK | ESCO_HV1, 0xffff, 0xff }, /* D0 */ }; static const struct sco_param sco_param_wideband[] = { - { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000d }, /* T2 */ - { EDR_ESCO_MASK | ESCO_EV3, 0x0008 }, /* T1 */ + { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000d, 0x02 }, /* T2 */ + { EDR_ESCO_MASK | ESCO_EV3, 0x0008, 0x02 }, /* T1 */ }; @@ -191,5 +192,4 @@ if (conn->attempt > ARRAY_SIZE(sco_param_wideband)) return false; - cp.retrans_effort = 0x02; param = &sco_param_wideband[conn->attempt - 1]; break; @@ -197,5 +197,4 @@ if (conn->attempt > ARRAY_SIZE(sco_param_cvsd)) return false; - cp.retrans_effort = 0x01; param = &sco_param_cvsd[conn->attempt - 1]; break; @@ -206,4 +205,5 @@ cp.pkt_type = __cpu_to_le16(param->pkt_type); cp.max_latency = __cpu_to_le16(param->max_latency); + cp.retrans_effort = param->retrans_effort; if (hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp) < 0)