On 02.03.2015 23:02, Georg Chini wrote: > 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? >>> >> > 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. Small correction, retrans_effort should be 0xff for D1 as well. --- 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, 0xff }, /* 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)