Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says: ==================== pull request: bluetooth-next 2016-09-25 Here are a few more Bluetooth & 802.15.4 patches for the 4.9 kernel that have popped up during the past week: - New USB ID for QCA_ROME Bluetooth device - NULL pointer dereference fix for Bluetooth mgmt sockets - Fixes for BCSP driver - Fix for updating LE scan response Please let me know if there are any issues pulling. Thanks. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
71527eb2be
|
@ -253,6 +253,7 @@ static const struct usb_device_id blacklist_table[] = {
|
||||||
{ USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME },
|
{ USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME },
|
||||||
{ USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME },
|
{ USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME },
|
||||||
{ USB_DEVICE(0x0489, 0xe092), .driver_info = BTUSB_QCA_ROME },
|
{ USB_DEVICE(0x0489, 0xe092), .driver_info = BTUSB_QCA_ROME },
|
||||||
|
{ USB_DEVICE(0x04ca, 0x3011), .driver_info = BTUSB_QCA_ROME },
|
||||||
|
|
||||||
/* Broadcom BCM2035 */
|
/* Broadcom BCM2035 */
|
||||||
{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
|
{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
|
||||||
|
|
|
@ -245,6 +245,7 @@ static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct ti_st *hst;
|
struct ti_st *hst;
|
||||||
long len;
|
long len;
|
||||||
|
int pkt_type;
|
||||||
|
|
||||||
hst = hci_get_drvdata(hdev);
|
hst = hci_get_drvdata(hdev);
|
||||||
|
|
||||||
|
@ -258,6 +259,7 @@ static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
|
||||||
* Freeing skb memory is taken care in shared transport layer,
|
* Freeing skb memory is taken care in shared transport layer,
|
||||||
* so don't free skb memory here.
|
* so don't free skb memory here.
|
||||||
*/
|
*/
|
||||||
|
pkt_type = hci_skb_pkt_type(skb);
|
||||||
len = hst->st_write(skb);
|
len = hst->st_write(skb);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
@ -268,7 +270,7 @@ static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
|
||||||
|
|
||||||
/* ST accepted our skb. So, Go ahead and do rest */
|
/* ST accepted our skb. So, Go ahead and do rest */
|
||||||
hdev->stat.byte_tx += len;
|
hdev->stat.byte_tx += len;
|
||||||
ti_st_tx_complete(hst, hci_skb_pkt_type(skb));
|
ti_st_tx_complete(hst, pkt_type);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,8 @@ struct bcsp_struct {
|
||||||
/* ---- BCSP CRC calculation ---- */
|
/* ---- BCSP CRC calculation ---- */
|
||||||
|
|
||||||
/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
|
/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
|
||||||
initial value 0xffff, bits shifted in reverse order. */
|
* initial value 0xffff, bits shifted in reverse order.
|
||||||
|
*/
|
||||||
|
|
||||||
static const u16 crc_table[] = {
|
static const u16 crc_table[] = {
|
||||||
0x0000, 0x1081, 0x2102, 0x3183,
|
0x0000, 0x1081, 0x2102, 0x3183,
|
||||||
|
@ -213,6 +214,7 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
|
||||||
/* Vendor specific commands */
|
/* Vendor specific commands */
|
||||||
if (hci_opcode_ogf(__le16_to_cpu(opcode)) == 0x3f) {
|
if (hci_opcode_ogf(__le16_to_cpu(opcode)) == 0x3f) {
|
||||||
u8 desc = *(data + HCI_COMMAND_HDR_SIZE);
|
u8 desc = *(data + HCI_COMMAND_HDR_SIZE);
|
||||||
|
|
||||||
if ((desc & 0xf0) == 0xc0) {
|
if ((desc & 0xf0) == 0xc0) {
|
||||||
data += HCI_COMMAND_HDR_SIZE + 1;
|
data += HCI_COMMAND_HDR_SIZE + 1;
|
||||||
len -= HCI_COMMAND_HDR_SIZE + 1;
|
len -= HCI_COMMAND_HDR_SIZE + 1;
|
||||||
|
@ -287,7 +289,8 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
/* First of all, check for unreliable messages in the queue,
|
/* First of all, check for unreliable messages in the queue,
|
||||||
since they have priority */
|
* since they have priority
|
||||||
|
*/
|
||||||
|
|
||||||
skb = skb_dequeue(&bcsp->unrel);
|
skb = skb_dequeue(&bcsp->unrel);
|
||||||
if (skb != NULL) {
|
if (skb != NULL) {
|
||||||
|
@ -485,12 +488,27 @@ static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char
|
||||||
static void bcsp_complete_rx_pkt(struct hci_uart *hu)
|
static void bcsp_complete_rx_pkt(struct hci_uart *hu)
|
||||||
{
|
{
|
||||||
struct bcsp_struct *bcsp = hu->priv;
|
struct bcsp_struct *bcsp = hu->priv;
|
||||||
int pass_up;
|
int pass_up = 0;
|
||||||
|
|
||||||
if (bcsp->rx_skb->data[0] & 0x80) { /* reliable pkt */
|
if (bcsp->rx_skb->data[0] & 0x80) { /* reliable pkt */
|
||||||
BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
|
BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
|
||||||
|
|
||||||
|
/* check the rx sequence number is as expected */
|
||||||
|
if ((bcsp->rx_skb->data[0] & 0x07) == bcsp->rxseq_txack) {
|
||||||
bcsp->rxseq_txack++;
|
bcsp->rxseq_txack++;
|
||||||
bcsp->rxseq_txack %= 0x8;
|
bcsp->rxseq_txack %= 0x8;
|
||||||
|
} else {
|
||||||
|
/* handle re-transmitted packet or
|
||||||
|
* when packet was missed
|
||||||
|
*/
|
||||||
|
BT_ERR("Out-of-order packet arrived, got %u expected %u",
|
||||||
|
bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
|
||||||
|
|
||||||
|
/* do not process out-of-order packet payload */
|
||||||
|
pass_up = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send current txack value to all received reliable packets */
|
||||||
bcsp->txack_req = 1;
|
bcsp->txack_req = 1;
|
||||||
|
|
||||||
/* If needed, transmit an ack pkt */
|
/* If needed, transmit an ack pkt */
|
||||||
|
@ -500,13 +518,18 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu)
|
||||||
bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
|
bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
|
||||||
BT_DBG("Request for pkt %u from card", bcsp->rxack);
|
BT_DBG("Request for pkt %u from card", bcsp->rxack);
|
||||||
|
|
||||||
|
/* handle received ACK indications,
|
||||||
|
* including those from out-of-order packets
|
||||||
|
*/
|
||||||
bcsp_pkt_cull(bcsp);
|
bcsp_pkt_cull(bcsp);
|
||||||
|
|
||||||
|
if (pass_up != 2) {
|
||||||
if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
|
if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
|
||||||
bcsp->rx_skb->data[0] & 0x80) {
|
(bcsp->rx_skb->data[0] & 0x80)) {
|
||||||
hci_skb_pkt_type(bcsp->rx_skb) = HCI_ACLDATA_PKT;
|
hci_skb_pkt_type(bcsp->rx_skb) = HCI_ACLDATA_PKT;
|
||||||
pass_up = 1;
|
pass_up = 1;
|
||||||
} else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
|
} else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
|
||||||
bcsp->rx_skb->data[0] & 0x80) {
|
(bcsp->rx_skb->data[0] & 0x80)) {
|
||||||
hci_skb_pkt_type(bcsp->rx_skb) = HCI_EVENT_PKT;
|
hci_skb_pkt_type(bcsp->rx_skb) = HCI_EVENT_PKT;
|
||||||
pass_up = 1;
|
pass_up = 1;
|
||||||
} else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
|
} else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
|
||||||
|
@ -516,10 +539,12 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu)
|
||||||
!(bcsp->rx_skb->data[0] & 0x80)) {
|
!(bcsp->rx_skb->data[0] & 0x80)) {
|
||||||
bcsp_handle_le_pkt(hu);
|
bcsp_handle_le_pkt(hu);
|
||||||
pass_up = 0;
|
pass_up = 0;
|
||||||
} else
|
} else {
|
||||||
pass_up = 0;
|
pass_up = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!pass_up) {
|
if (pass_up == 0) {
|
||||||
struct hci_event_hdr hdr;
|
struct hci_event_hdr hdr;
|
||||||
u8 desc = (bcsp->rx_skb->data[1] & 0x0f);
|
u8 desc = (bcsp->rx_skb->data[1] & 0x0f);
|
||||||
|
|
||||||
|
@ -544,11 +569,16 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu)
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
kfree_skb(bcsp->rx_skb);
|
kfree_skb(bcsp->rx_skb);
|
||||||
} else {
|
} else if (pass_up == 1) {
|
||||||
/* Pull out BCSP hdr */
|
/* Pull out BCSP hdr */
|
||||||
skb_pull(bcsp->rx_skb, 4);
|
skb_pull(bcsp->rx_skb, 4);
|
||||||
|
|
||||||
hci_recv_frame(hu->hdev, bcsp->rx_skb);
|
hci_recv_frame(hu->hdev, bcsp->rx_skb);
|
||||||
|
} else {
|
||||||
|
/* ignore packet payload of already ACKed re-transmitted
|
||||||
|
* packets or when a packet was missed in the BCSP window
|
||||||
|
*/
|
||||||
|
kfree_skb(bcsp->rx_skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
|
bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
|
||||||
|
@ -594,16 +624,6 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count)
|
||||||
bcsp->rx_count = 0;
|
bcsp->rx_count = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */
|
|
||||||
&& (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
|
|
||||||
BT_ERR("Out-of-order packet arrived, got %u expected %u",
|
|
||||||
bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
|
|
||||||
|
|
||||||
kfree_skb(bcsp->rx_skb);
|
|
||||||
bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
|
|
||||||
bcsp->rx_count = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bcsp->rx_state = BCSP_W4_DATA;
|
bcsp->rx_state = BCSP_W4_DATA;
|
||||||
bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
|
bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
|
||||||
(bcsp->rx_skb->data[2] << 4); /* May be 0 */
|
(bcsp->rx_skb->data[2] << 4); /* May be 0 */
|
||||||
|
|
|
@ -697,34 +697,36 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file *file,
|
||||||
case HCIUARTSETPROTO:
|
case HCIUARTSETPROTO:
|
||||||
if (!test_and_set_bit(HCI_UART_PROTO_SET, &hu->flags)) {
|
if (!test_and_set_bit(HCI_UART_PROTO_SET, &hu->flags)) {
|
||||||
err = hci_uart_set_proto(hu, arg);
|
err = hci_uart_set_proto(hu, arg);
|
||||||
if (err) {
|
if (err)
|
||||||
clear_bit(HCI_UART_PROTO_SET, &hu->flags);
|
clear_bit(HCI_UART_PROTO_SET, &hu->flags);
|
||||||
return err;
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
return -EBUSY;
|
err = -EBUSY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCIUARTGETPROTO:
|
case HCIUARTGETPROTO:
|
||||||
if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
|
if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
|
||||||
return hu->proto->id;
|
err = hu->proto->id;
|
||||||
return -EUNATCH;
|
else
|
||||||
|
err = -EUNATCH;
|
||||||
|
break;
|
||||||
|
|
||||||
case HCIUARTGETDEVICE:
|
case HCIUARTGETDEVICE:
|
||||||
if (test_bit(HCI_UART_REGISTERED, &hu->flags))
|
if (test_bit(HCI_UART_REGISTERED, &hu->flags))
|
||||||
return hu->hdev->id;
|
err = hu->hdev->id;
|
||||||
return -EUNATCH;
|
else
|
||||||
|
err = -EUNATCH;
|
||||||
|
break;
|
||||||
|
|
||||||
case HCIUARTSETFLAGS:
|
case HCIUARTSETFLAGS:
|
||||||
if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
|
if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
|
||||||
return -EBUSY;
|
err = -EBUSY;
|
||||||
|
else
|
||||||
err = hci_uart_set_flags(hu, arg);
|
err = hci_uart_set_flags(hu, arg);
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCIUARTGETFLAGS:
|
case HCIUARTGETFLAGS:
|
||||||
return hu->hdev_flags;
|
err = hu->hdev_flags;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
err = n_tty_ioctl_helper(tty, file, cmd, arg);
|
err = n_tty_ioctl_helper(tty, file, cmd, arg);
|
||||||
|
|
|
@ -2541,6 +2541,8 @@ static int send_pin_code_neg_reply(struct sock *sk, struct hci_dev *hdev,
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
cmd->cmd_complete = addr_cmd_complete;
|
||||||
|
|
||||||
err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
|
err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
|
||||||
sizeof(cp->addr.bdaddr), &cp->addr.bdaddr);
|
sizeof(cp->addr.bdaddr), &cp->addr.bdaddr);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@ -3157,7 +3159,7 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||||
/* The name is stored in the scan response data and so
|
/* The name is stored in the scan response data and so
|
||||||
* no need to udpate the advertising data here.
|
* no need to udpate the advertising data here.
|
||||||
*/
|
*/
|
||||||
if (lmp_le_capable(hdev))
|
if (lmp_le_capable(hdev) && hci_dev_test_flag(hdev, HCI_ADVERTISING))
|
||||||
__hci_req_update_scan_rsp_data(&req, hdev->cur_adv_instance);
|
__hci_req_update_scan_rsp_data(&req, hdev->cur_adv_instance);
|
||||||
|
|
||||||
err = hci_req_run(&req, set_name_complete);
|
err = hci_req_run(&req, set_name_complete);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче