Commit 859a5935 authored by David S. Miller's avatar David S. Miller

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next

Johan Hedberg says:

====================
pull request: bluetooth-next 2018-04-01

Here's (most likely) the last bluetooth-next pull request for the 4.17
kernel:

 - Remove unused btuart_cs driver (replaced by serial_cs + hci_uart)
 - New USB ID for Edimax EW-7611ULB controller
 - Cleanups & fixes to hci_bcm driver
 - Clenups to btmrvl driver

Please let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5366271c 9ea47132
......@@ -147,6 +147,7 @@ config BT_HCIUART_ATH3K
config BT_HCIUART_LL
bool "HCILL protocol support"
depends on BT_HCIUART_SERDEV
select BT_HCIUART_H4
help
HCILL (HCI Low Level) is a serial protocol for communication
between Bluetooth device and host. This protocol is required for
......@@ -242,8 +243,7 @@ config BT_HCIBCM203X
config BT_HCIBPA10X
tristate "HCI BPA10x USB driver"
depends on USB && BT_HCIUART
select BT_HCIUART_H4
depends on USB
help
Bluetooth HCI BPA10x USB driver.
This driver provides support for the Digianswer BPA 100/105 Bluetooth
......@@ -305,22 +305,6 @@ config BT_HCIBLUECARD
Say Y here to compile support for HCI BlueCard devices into the
kernel or say M to compile it as module (bluecard_cs).
config BT_HCIBTUART
tristate "HCI UART (PC Card) device driver"
depends on PCMCIA
help
Bluetooth HCI UART (PC Card) driver.
This driver provides support for Bluetooth PCMCIA devices with
an UART interface:
Xircom CreditCard Bluetooth Adapter
Xircom RealPort2 Bluetooth Adapter
Sphinx PICO Card
H-Soft blue+Card
Cyber-blue Compact Flash Card
Say Y here to compile support for HCI UART devices into the
kernel or say M to compile it as module (btuart_cs).
config BT_HCIVHCI
tristate "HCI VHCI (Virtual HCI device) driver"
help
......
......@@ -11,7 +11,6 @@ obj-$(CONFIG_BT_HCIBFUSB) += bfusb.o
obj-$(CONFIG_BT_HCIDTL1) += dtl1_cs.o
obj-$(CONFIG_BT_HCIBT3C) += bt3c_cs.o
obj-$(CONFIG_BT_HCIBLUECARD) += bluecard_cs.o
obj-$(CONFIG_BT_HCIBTUART) += btuart_cs.o
obj-$(CONFIG_BT_HCIBTUSB) += btusb.o
obj-$(CONFIG_BT_HCIBTSDIO) += btsdio.o
......
......@@ -35,7 +35,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include "hci_uart.h"
#include "h4_recv.h"
#define VERSION "0.11"
......
......@@ -689,7 +689,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
int ret, num_blocks, blksz;
struct sk_buff *skb = NULL;
u32 type;
u8 *payload = NULL;
u8 *payload;
struct hci_dev *hdev = priv->btmrvl_dev.hcidev;
struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
......@@ -920,7 +920,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
{
struct sdio_func *func;
u8 reg;
int ret = 0;
int ret;
if (!card || !card->func) {
BT_ERR("Error: card or function is NULL!");
......
......@@ -13,7 +13,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <net/bluetooth/bluetooth.h>
......
This diff is collapsed.
......@@ -368,6 +368,9 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3459), .driver_info = BTUSB_REALTEK },
{ USB_DEVICE(0x13d3, 0x3494), .driver_info = BTUSB_REALTEK },
/* Additional Realtek 8723BU Bluetooth devices */
{ USB_DEVICE(0x7392, 0xa611), .driver_info = BTUSB_REALTEK },
/* Additional Realtek 8821AE Bluetooth devices */
{ USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
{ USB_DEVICE(0x13d3, 0x3414), .driver_info = BTUSB_REALTEK },
......@@ -3060,6 +3063,7 @@ static int btusb_probe(struct usb_interface *intf,
if (id->driver_info & BTUSB_QCA_ROME) {
data->setup_on_usb = btusb_setup_qca;
hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
}
#ifdef CONFIG_BT_HCIBTUSB_RTL
......
/*
*
* Generic Bluetooth HCI UART driver
*
* Copyright (C) 2015-2018 Intel Corporation
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <asm/unaligned.h>
struct h4_recv_pkt {
u8 type; /* Packet type */
u8 hlen; /* Header length */
u8 loff; /* Data length offset in header */
u8 lsize; /* Data length field size */
u16 maxlen; /* Max overall packet length */
int (*recv)(struct hci_dev *hdev, struct sk_buff *skb);
};
#define H4_RECV_ACL \
.type = HCI_ACLDATA_PKT, \
.hlen = HCI_ACL_HDR_SIZE, \
.loff = 2, \
.lsize = 2, \
.maxlen = HCI_MAX_FRAME_SIZE \
#define H4_RECV_SCO \
.type = HCI_SCODATA_PKT, \
.hlen = HCI_SCO_HDR_SIZE, \
.loff = 2, \
.lsize = 1, \
.maxlen = HCI_MAX_SCO_SIZE
#define H4_RECV_EVENT \
.type = HCI_EVENT_PKT, \
.hlen = HCI_EVENT_HDR_SIZE, \
.loff = 1, \
.lsize = 1, \
.maxlen = HCI_MAX_EVENT_SIZE
static inline struct sk_buff *h4_recv_buf(struct hci_dev *hdev,
struct sk_buff *skb,
const unsigned char *buffer,
int count,
const struct h4_recv_pkt *pkts,
int pkts_count)
{
while (count) {
int i, len;
if (!count)
break;
if (!skb) {
for (i = 0; i < pkts_count; i++) {
if (buffer[0] != (&pkts[i])->type)
continue;
skb = bt_skb_alloc((&pkts[i])->maxlen,
GFP_ATOMIC);
if (!skb)
return ERR_PTR(-ENOMEM);
hci_skb_pkt_type(skb) = (&pkts[i])->type;
hci_skb_expect(skb) = (&pkts[i])->hlen;
break;
}
/* Check for invalid packet type */
if (!skb)
return ERR_PTR(-EILSEQ);
count -= 1;
buffer += 1;
}
len = min_t(uint, hci_skb_expect(skb) - skb->len, count);
skb_put_data(skb, buffer, len);
count -= len;
buffer += len;
/* Check for partial packet */
if (skb->len < hci_skb_expect(skb))
continue;
for (i = 0; i < pkts_count; i++) {
if (hci_skb_pkt_type(skb) == (&pkts[i])->type)
break;
}
if (i >= pkts_count) {
kfree_skb(skb);
return ERR_PTR(-EILSEQ);
}
if (skb->len == (&pkts[i])->hlen) {
u16 dlen;
switch ((&pkts[i])->lsize) {
case 0:
/* No variable data length */
dlen = 0;
break;
case 1:
/* Single octet variable length */
dlen = skb->data[(&pkts[i])->loff];
hci_skb_expect(skb) += dlen;
if (skb_tailroom(skb) < dlen) {
kfree_skb(skb);
return ERR_PTR(-EMSGSIZE);
}
break;
case 2:
/* Double octet variable length */
dlen = get_unaligned_le16(skb->data +
(&pkts[i])->loff);
hci_skb_expect(skb) += dlen;
if (skb_tailroom(skb) < dlen) {
kfree_skb(skb);
return ERR_PTR(-EMSGSIZE);
}
break;
default:
/* Unsupported variable length */
kfree_skb(skb);
return ERR_PTR(-EILSEQ);
}
if (!dlen) {
/* No more data, complete frame */
(&pkts[i])->recv(hdev, skb);
skb = NULL;
}
} else {
/* Complete frame */
(&pkts[i])->recv(hdev, skb);
skb = NULL;
}
}
return skb;
}
This diff is collapsed.
......@@ -67,13 +67,6 @@
#define HCILL_WAKE_UP_IND 0x32
#define HCILL_WAKE_UP_ACK 0x33
/* HCILL receiver States */
#define HCILL_W4_PACKET_TYPE 0
#define HCILL_W4_EVENT_HDR 1
#define HCILL_W4_ACL_HDR 2
#define HCILL_W4_SCO_HDR 3
#define HCILL_W4_DATA 4
/* HCILL states */
enum hcill_states_e {
HCILL_ASLEEP,
......@@ -82,10 +75,6 @@ enum hcill_states_e {
HCILL_AWAKE_TO_ASLEEP
};
struct hcill_cmd {
u8 cmd;
} __packed;
struct ll_device {
struct hci_uart hu;
struct serdev_device *serdev;
......@@ -95,8 +84,6 @@ struct ll_device {
};
struct ll_struct {
unsigned long rx_state;
unsigned long rx_count;
struct sk_buff *rx_skb;
struct sk_buff_head txq;
spinlock_t hcill_lock; /* HCILL state lock */
......@@ -113,7 +100,6 @@ static int send_hcill_cmd(u8 cmd, struct hci_uart *hu)
int err = 0;
struct sk_buff *skb = NULL;
struct ll_struct *ll = hu->priv;
struct hcill_cmd *hcill_packet;
BT_DBG("hu %p cmd 0x%x", hu, cmd);
......@@ -126,8 +112,7 @@ static int send_hcill_cmd(u8 cmd, struct hci_uart *hu)
}
/* prepare packet */
hcill_packet = skb_put(skb, 1);
hcill_packet->cmd = cmd;
skb_put_u8(skb, cmd);
/* send packet */
skb_queue_tail(&ll->txq, skb);
......@@ -379,155 +364,88 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb)
return 0;
}
static inline int ll_check_data_len(struct hci_dev *hdev, struct ll_struct *ll, int len)
static int ll_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
int room = skb_tailroom(ll->rx_skb);
BT_DBG("len %d room %d", len, room);
struct hci_uart *hu = hci_get_drvdata(hdev);
struct ll_struct *ll = hu->priv;
if (!len) {
hci_recv_frame(hdev, ll->rx_skb);
} else if (len > room) {
BT_ERR("Data length is too large");
kfree_skb(ll->rx_skb);
} else {
ll->rx_state = HCILL_W4_DATA;
ll->rx_count = len;
return len;
switch (hci_skb_pkt_type(skb)) {
case HCILL_GO_TO_SLEEP_IND:
BT_DBG("HCILL_GO_TO_SLEEP_IND packet");
ll_device_want_to_sleep(hu);
break;
case HCILL_GO_TO_SLEEP_ACK:
/* shouldn't happen */
bt_dev_err(hdev, "received HCILL_GO_TO_SLEEP_ACK in state %ld",
ll->hcill_state);
break;
case HCILL_WAKE_UP_IND:
BT_DBG("HCILL_WAKE_UP_IND packet");
ll_device_want_to_wakeup(hu);
break;
case HCILL_WAKE_UP_ACK:
BT_DBG("HCILL_WAKE_UP_ACK packet");
ll_device_woke_up(hu);
break;
}
ll->rx_state = HCILL_W4_PACKET_TYPE;
ll->rx_skb = NULL;
ll->rx_count = 0;
kfree_skb(skb);
return 0;
}
#define LL_RECV_SLEEP_IND \
.type = HCILL_GO_TO_SLEEP_IND, \
.hlen = 0, \
.loff = 0, \
.lsize = 0, \
.maxlen = 0
#define LL_RECV_SLEEP_ACK \
.type = HCILL_GO_TO_SLEEP_ACK, \
.hlen = 0, \
.loff = 0, \
.lsize = 0, \
.maxlen = 0
#define LL_RECV_WAKE_IND \
.type = HCILL_WAKE_UP_IND, \
.hlen = 0, \
.loff = 0, \
.lsize = 0, \
.maxlen = 0
#define LL_RECV_WAKE_ACK \
.type = HCILL_WAKE_UP_ACK, \
.hlen = 0, \
.loff = 0, \
.lsize = 0, \
.maxlen = 0
static const struct h4_recv_pkt ll_recv_pkts[] = {
{ H4_RECV_ACL, .recv = hci_recv_frame },
{ H4_RECV_SCO, .recv = hci_recv_frame },
{ H4_RECV_EVENT, .recv = hci_recv_frame },
{ LL_RECV_SLEEP_IND, .recv = ll_recv_frame },
{ LL_RECV_SLEEP_ACK, .recv = ll_recv_frame },
{ LL_RECV_WAKE_IND, .recv = ll_recv_frame },
{ LL_RECV_WAKE_ACK, .recv = ll_recv_frame },
};
/* Recv data */
static int ll_recv(struct hci_uart *hu, const void *data, int count)
{
struct ll_struct *ll = hu->priv;
const char *ptr;
struct hci_event_hdr *eh;
struct hci_acl_hdr *ah;
struct hci_sco_hdr *sh;
int len, type, dlen;
BT_DBG("hu %p count %d rx_state %ld rx_count %ld", hu, count, ll->rx_state, ll->rx_count);
ptr = data;
while (count) {
if (ll->rx_count) {
len = min_t(unsigned int, ll->rx_count, count);
skb_put_data(ll->rx_skb, ptr, len);
ll->rx_count -= len; count -= len; ptr += len;
if (ll->rx_count)
continue;
switch (ll->rx_state) {
case HCILL_W4_DATA:
BT_DBG("Complete data");
hci_recv_frame(hu->hdev, ll->rx_skb);
ll->rx_state = HCILL_W4_PACKET_TYPE;
ll->rx_skb = NULL;
continue;
case HCILL_W4_EVENT_HDR:
eh = hci_event_hdr(ll->rx_skb);
BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
ll_check_data_len(hu->hdev, ll, eh->plen);
continue;
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
return -EUNATCH;
case HCILL_W4_ACL_HDR:
ah = hci_acl_hdr(ll->rx_skb);
dlen = __le16_to_cpu(ah->dlen);
BT_DBG("ACL header: dlen %d", dlen);
ll_check_data_len(hu->hdev, ll, dlen);
continue;
case HCILL_W4_SCO_HDR:
sh = hci_sco_hdr(ll->rx_skb);
BT_DBG("SCO header: dlen %d", sh->dlen);
ll_check_data_len(hu->hdev, ll, sh->dlen);
continue;
}
}
/* HCILL_W4_PACKET_TYPE */
switch (*ptr) {
case HCI_EVENT_PKT:
BT_DBG("Event packet");
ll->rx_state = HCILL_W4_EVENT_HDR;
ll->rx_count = HCI_EVENT_HDR_SIZE;
type = HCI_EVENT_PKT;
break;
case HCI_ACLDATA_PKT:
BT_DBG("ACL packet");
ll->rx_state = HCILL_W4_ACL_HDR;
ll->rx_count = HCI_ACL_HDR_SIZE;
type = HCI_ACLDATA_PKT;
break;
case HCI_SCODATA_PKT:
BT_DBG("SCO packet");
ll->rx_state = HCILL_W4_SCO_HDR;
ll->rx_count = HCI_SCO_HDR_SIZE;
type = HCI_SCODATA_PKT;
break;
/* HCILL signals */
case HCILL_GO_TO_SLEEP_IND:
BT_DBG("HCILL_GO_TO_SLEEP_IND packet");
ll_device_want_to_sleep(hu);
ptr++; count--;
continue;
case HCILL_GO_TO_SLEEP_ACK:
/* shouldn't happen */
BT_ERR("received HCILL_GO_TO_SLEEP_ACK (in state %ld)", ll->hcill_state);
ptr++; count--;
continue;
case HCILL_WAKE_UP_IND:
BT_DBG("HCILL_WAKE_UP_IND packet");
ll_device_want_to_wakeup(hu);
ptr++; count--;
continue;
case HCILL_WAKE_UP_ACK:
BT_DBG("HCILL_WAKE_UP_ACK packet");
ll_device_woke_up(hu);
ptr++; count--;
continue;
default:
BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
hu->hdev->stat.err_rx++;
ptr++; count--;
continue;
}
ptr++; count--;
/* Allocate packet */
ll->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
if (!ll->rx_skb) {
BT_ERR("Can't allocate mem for new packet");
ll->rx_state = HCILL_W4_PACKET_TYPE;
ll->rx_count = 0;
return -ENOMEM;
}
hci_skb_pkt_type(ll->rx_skb) = type;
ll->rx_skb = h4_recv_buf(hu->hdev, ll->rx_skb, data, count,
ll_recv_pkts, ARRAY_SIZE(ll_recv_pkts));
if (IS_ERR(ll->rx_skb)) {
int err = PTR_ERR(ll->rx_skb);
bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
ll->rx_skb = NULL;
return err;
}
return count;
......
......@@ -600,7 +600,7 @@ struct mgmt_rp_read_ext_info {
#define MGMT_OP_SET_APPEARANCE 0x0043
struct mgmt_cp_set_appearance {
__u16 appearance;
__le16 appearance;
} __packed;
#define MGMT_SET_APPEARANCE_SIZE 2
......
......@@ -4801,6 +4801,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
case MGMT_LTK_P256_DEBUG:
authenticated = 0x00;
type = SMP_LTK_P256_DEBUG;
/* fall through */
default:
continue;
}
......
......@@ -221,6 +221,7 @@ static void __rfcomm_sock_close(struct sock *sk)
case BT_CONFIG:
case BT_CONNECTED:
rfcomm_dlc_close(d, 0);
/* fall through */
default:
sock_set_flag(sk, SOCK_ZAPPED);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment