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

This commit is contained in:
John W. Linville 2012-07-18 14:53:10 -04:00
commit 0cd06647b7
21 changed files with 1124 additions and 286 deletions

View File

@ -81,6 +81,18 @@ config BT_HCIUART_LL
Say Y here to compile support for HCILL protocol.
config BT_HCIUART_3WIRE
bool "Three-wire UART (H5) protocol support"
depends on BT_HCIUART
help
The HCI Three-wire UART Transport Layer makes it possible to
user the Bluetooth HCI over a serial port interface. The HCI
Three-wire UART Transport Layer assumes that the UART
communication may have bit errors, overrun errors or burst
errors and thereby making CTS/RTS lines unnecessary.
Say Y here to compile support for Three-wire UART protocol.
config BT_HCIBCM203X
tristate "HCI BCM203x USB driver"
depends on USB

View File

@ -28,4 +28,5 @@ hci_uart-$(CONFIG_BT_HCIUART_H4) += hci_h4.o
hci_uart-$(CONFIG_BT_HCIUART_BCSP) += hci_bcsp.o
hci_uart-$(CONFIG_BT_HCIUART_LL) += hci_ll.o
hci_uart-$(CONFIG_BT_HCIUART_ATH3K) += hci_ath.o
hci_uart-$(CONFIG_BT_HCIUART_3WIRE) += hci_h5.o
hci_uart-objs := $(hci_uart-y)

View File

@ -621,7 +621,6 @@ static int bluecard_hci_flush(struct hci_dev *hdev)
static int bluecard_hci_open(struct hci_dev *hdev)
{
bluecard_info_t *info = hci_get_drvdata(hdev);
unsigned int iobase = info->p_dev->resource[0]->start;
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
@ -630,6 +629,8 @@ static int bluecard_hci_open(struct hci_dev *hdev)
return 0;
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) {
unsigned int iobase = info->p_dev->resource[0]->start;
/* Enable LED */
outb(0x08 | 0x20, iobase + 0x30);
}
@ -641,7 +642,6 @@ static int bluecard_hci_open(struct hci_dev *hdev)
static int bluecard_hci_close(struct hci_dev *hdev)
{
bluecard_info_t *info = hci_get_drvdata(hdev);
unsigned int iobase = info->p_dev->resource[0]->start;
if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
return 0;
@ -649,6 +649,8 @@ static int bluecard_hci_close(struct hci_dev *hdev)
bluecard_hci_flush(hdev);
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) {
unsigned int iobase = info->p_dev->resource[0]->start;
/* Disable LED */
outb(0x00, iobase + 0x30);
}

View File

@ -664,7 +664,7 @@ static int bt3c_check_config(struct pcmcia_device *p_dev, void *priv_data)
{
int *try = priv_data;
if (try == 0)
if (!try)
p_dev->io_lines = 16;
if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0))

View File

@ -47,10 +47,11 @@ EXPORT_SYMBOL_GPL(btmrvl_interrupt);
bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
{
struct hci_event_hdr *hdr = (void *) skb->data;
struct hci_ev_cmd_complete *ec;
u16 opcode, ocf, ogf;
if (hdr->evt == HCI_EV_CMD_COMPLETE) {
struct hci_ev_cmd_complete *ec;
u16 opcode, ocf, ogf;
ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE);
opcode = __le16_to_cpu(ec->opcode);
ocf = hci_opcode_ocf(opcode);
@ -64,7 +65,8 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
}
if (ogf == OGF) {
BT_DBG("vendor event skipped: ogf 0x%4.4x", ogf);
BT_DBG("vendor event skipped: ogf 0x%4.4x ocf 0x%4.4x",
ogf, ocf);
kfree_skb(skb);
return false;
}

View File

@ -568,8 +568,9 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
if (type == HCI_EVENT_PKT) {
if (btmrvl_check_evtpkt(priv, skb))
hci_recv_frame(skb);
} else
} else {
hci_recv_frame(skb);
}
hdev->stat.byte_rx += buf_len;
break;

View File

@ -593,7 +593,7 @@ static int btuart_check_config(struct pcmcia_device *p_dev, void *priv_data)
{
int *try = priv_data;
if (try == 0)
if (!try)
p_dev->io_lines = 16;
if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0))

View File

@ -586,29 +586,31 @@ static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data)
static int dtl1_config(struct pcmcia_device *link)
{
dtl1_info_t *info = link->priv;
int i;
int ret;
/* Look for a generic full-sized window */
link->resource[0]->end = 8;
if (pcmcia_loop_config(link, dtl1_confcheck, NULL) < 0)
ret = pcmcia_loop_config(link, dtl1_confcheck, NULL);
if (ret)
goto failed;
i = pcmcia_request_irq(link, dtl1_interrupt);
if (i != 0)
ret = pcmcia_request_irq(link, dtl1_interrupt);
if (ret)
goto failed;
i = pcmcia_enable_device(link);
if (i != 0)
ret = pcmcia_enable_device(link);
if (ret)
goto failed;
if (dtl1_open(info) != 0)
ret = dtl1_open(info);
if (ret)
goto failed;
return 0;
failed:
dtl1_detach(link);
return -ENODEV;
return ret;
}
static const struct pcmcia_device_id dtl1_ids[] = {

747
drivers/bluetooth/hci_h5.c Normal file
View File

@ -0,0 +1,747 @@
/*
*
* Bluetooth HCI Three-wire UART driver
*
* Copyright (C) 2012 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 <linux/kernel.h>
#include <linux/errno.h>
#include <linux/skbuff.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include "hci_uart.h"
#define HCI_3WIRE_ACK_PKT 0
#define HCI_3WIRE_LINK_PKT 15
/* Sliding window size */
#define H5_TX_WIN_MAX 4
#define H5_ACK_TIMEOUT msecs_to_jiffies(250)
#define H5_SYNC_TIMEOUT msecs_to_jiffies(100)
/*
* Maximum Three-wire packet:
* 4 byte header + max value for 12-bit length + 2 bytes for CRC
*/
#define H5_MAX_LEN (4 + 0xfff + 2)
/* Convenience macros for reading Three-wire header values */
#define H5_HDR_SEQ(hdr) ((hdr)[0] & 0x07)
#define H5_HDR_ACK(hdr) (((hdr)[0] >> 3) & 0x07)
#define H5_HDR_CRC(hdr) (((hdr)[0] >> 6) & 0x01)
#define H5_HDR_RELIABLE(hdr) (((hdr)[0] >> 7) & 0x01)
#define H5_HDR_PKT_TYPE(hdr) ((hdr)[1] & 0x0f)
#define H5_HDR_LEN(hdr) ((((hdr)[1] >> 4) & 0xff) + ((hdr)[2] << 4))
#define SLIP_DELIMITER 0xc0
#define SLIP_ESC 0xdb
#define SLIP_ESC_DELIM 0xdc
#define SLIP_ESC_ESC 0xdd
/* H5 state flags */
enum {
H5_RX_ESC, /* SLIP escape mode */
H5_TX_ACK_REQ, /* Pending ack to send */
};
struct h5 {
struct sk_buff_head unack; /* Unack'ed packets queue */
struct sk_buff_head rel; /* Reliable packets queue */
struct sk_buff_head unrel; /* Unreliable packets queue */
unsigned long flags;
struct sk_buff *rx_skb; /* Receive buffer */
size_t rx_pending; /* Expecting more bytes */
u8 rx_ack; /* Last ack number received */
int (*rx_func) (struct hci_uart *hu, u8 c);
struct timer_list timer; /* Retransmission timer */
u8 tx_seq; /* Next seq number to send */
u8 tx_ack; /* Next ack number to send */
u8 tx_win; /* Sliding window size */
enum {
H5_UNINITIALIZED,
H5_INITIALIZED,
H5_ACTIVE,
} state;
enum {
H5_AWAKE,
H5_SLEEPING,
H5_WAKING_UP,
} sleep;
};
static void h5_reset_rx(struct h5 *h5);
static void h5_link_control(struct hci_uart *hu, const void *data, size_t len)
{
struct h5 *h5 = hu->priv;
struct sk_buff *nskb;
nskb = alloc_skb(3, GFP_ATOMIC);
if (!nskb)
return;
bt_cb(nskb)->pkt_type = HCI_3WIRE_LINK_PKT;
memcpy(skb_put(nskb, len), data, len);
skb_queue_tail(&h5->unrel, nskb);
}
static u8 h5_cfg_field(struct h5 *h5)
{
u8 field = 0;
/* Sliding window size (first 3 bits) */
field |= (h5->tx_win & 7);
return field;
}
static void h5_timed_event(unsigned long arg)
{
const unsigned char sync_req[] = { 0x01, 0x7e };
unsigned char conf_req[] = { 0x03, 0xfc, 0x01 };
struct hci_uart *hu = (struct hci_uart *) arg;
struct h5 *h5 = hu->priv;
struct sk_buff *skb;
unsigned long flags;
BT_DBG("%s", hu->hdev->name);
if (h5->state == H5_UNINITIALIZED)
h5_link_control(hu, sync_req, sizeof(sync_req));
if (h5->state == H5_INITIALIZED) {
conf_req[2] = h5_cfg_field(h5);
h5_link_control(hu, conf_req, sizeof(conf_req));
}
if (h5->state != H5_ACTIVE) {
mod_timer(&h5->timer, jiffies + H5_SYNC_TIMEOUT);
goto wakeup;
}
if (h5->sleep != H5_AWAKE) {
h5->sleep = H5_SLEEPING;
goto wakeup;
}
BT_DBG("hu %p retransmitting %u pkts", hu, h5->unack.qlen);
spin_lock_irqsave_nested(&h5->unack.lock, flags, SINGLE_DEPTH_NESTING);
while ((skb = __skb_dequeue_tail(&h5->unack)) != NULL) {
h5->tx_seq = (h5->tx_seq - 1) & 0x07;
skb_queue_head(&h5->rel, skb);
}
spin_unlock_irqrestore(&h5->unack.lock, flags);
wakeup:
hci_uart_tx_wakeup(hu);
}
static int h5_open(struct hci_uart *hu)
{
struct h5 *h5;
const unsigned char sync[] = { 0x01, 0x7e };
BT_DBG("hu %p", hu);
h5 = kzalloc(sizeof(*h5), GFP_KERNEL);
if (!h5)
return -ENOMEM;
hu->priv = h5;
skb_queue_head_init(&h5->unack);
skb_queue_head_init(&h5->rel);
skb_queue_head_init(&h5->unrel);
h5_reset_rx(h5);
init_timer(&h5->timer);
h5->timer.function = h5_timed_event;
h5->timer.data = (unsigned long) hu;
h5->tx_win = H5_TX_WIN_MAX;
set_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags);
/* Send initial sync request */
h5_link_control(hu, sync, sizeof(sync));
mod_timer(&h5->timer, jiffies + H5_SYNC_TIMEOUT);
return 0;
}
static int h5_close(struct hci_uart *hu)
{
struct h5 *h5 = hu->priv;
skb_queue_purge(&h5->unack);
skb_queue_purge(&h5->rel);
skb_queue_purge(&h5->unrel);
del_timer(&h5->timer);
kfree(h5);
return 0;
}
static void h5_pkt_cull(struct h5 *h5)
{
struct sk_buff *skb, *tmp;
unsigned long flags;
int i, to_remove;
u8 seq;
spin_lock_irqsave(&h5->unack.lock, flags);
to_remove = skb_queue_len(&h5->unack);
if (to_remove == 0)
goto unlock;
seq = h5->tx_seq;
while (to_remove > 0) {
if (h5->rx_ack == seq)
break;
to_remove--;
seq = (seq - 1) % 8;
}
if (seq != h5->rx_ack)
BT_ERR("Controller acked invalid packet");
i = 0;
skb_queue_walk_safe(&h5->unack, skb, tmp) {
if (i++ >= to_remove)
break;
__skb_unlink(skb, &h5->unack);
kfree_skb(skb);
}
if (skb_queue_empty(&h5->unack))
del_timer(&h5->timer);
unlock:
spin_unlock_irqrestore(&h5->unack.lock, flags);
}
static void h5_handle_internal_rx(struct hci_uart *hu)
{
struct h5 *h5 = hu->priv;
const unsigned char sync_req[] = { 0x01, 0x7e };
const unsigned char sync_rsp[] = { 0x02, 0x7d };
unsigned char conf_req[] = { 0x03, 0xfc, 0x01 };
const unsigned char conf_rsp[] = { 0x04, 0x7b };
const unsigned char wakeup_req[] = { 0x05, 0xfa };
const unsigned char woken_req[] = { 0x06, 0xf9 };
const unsigned char sleep_req[] = { 0x07, 0x78 };
const unsigned char *hdr = h5->rx_skb->data;
const unsigned char *data = &h5->rx_skb->data[4];
BT_DBG("%s", hu->hdev->name);
if (H5_HDR_PKT_TYPE(hdr) != HCI_3WIRE_LINK_PKT)
return;
if (H5_HDR_LEN(hdr) < 2)
return;
conf_req[2] = h5_cfg_field(h5);
if (memcmp(data, sync_req, 2) == 0) {
h5_link_control(hu, sync_rsp, 2);
} else if (memcmp(data, sync_rsp, 2) == 0) {
h5->state = H5_INITIALIZED;
h5_link_control(hu, conf_req, 3);
} else if (memcmp(data, conf_req, 2) == 0) {
h5_link_control(hu, conf_rsp, 2);
h5_link_control(hu, conf_req, 3);
} else if (memcmp(data, conf_rsp, 2) == 0) {
if (H5_HDR_LEN(hdr) > 2)
h5->tx_win = (data[2] & 7);
BT_DBG("Three-wire init complete. tx_win %u", h5->tx_win);
h5->state = H5_ACTIVE;
hci_uart_init_ready(hu);
return;
} else if (memcmp(data, sleep_req, 2) == 0) {
BT_DBG("Peer went to sleep");
h5->sleep = H5_SLEEPING;
return;
} else if (memcmp(data, woken_req, 2) == 0) {
BT_DBG("Peer woke up");
h5->sleep = H5_AWAKE;
} else if (memcmp(data, wakeup_req, 2) == 0) {
BT_DBG("Peer requested wakeup");
h5_link_control(hu, woken_req, 2);
h5->sleep = H5_AWAKE;
} else {
BT_DBG("Link Control: 0x%02hhx 0x%02hhx", data[0], data[1]);
return;
}
hci_uart_tx_wakeup(hu);
}
static void h5_complete_rx_pkt(struct hci_uart *hu)
{
struct h5 *h5 = hu->priv;
const unsigned char *hdr = h5->rx_skb->data;
if (H5_HDR_RELIABLE(hdr)) {
h5->tx_ack = (h5->tx_ack + 1) % 8;
set_bit(H5_TX_ACK_REQ, &h5->flags);
hci_uart_tx_wakeup(hu);
}
h5->rx_ack = H5_HDR_ACK(hdr);
h5_pkt_cull(h5);
switch (H5_HDR_PKT_TYPE(hdr)) {
case HCI_EVENT_PKT:
case HCI_ACLDATA_PKT:
case HCI_SCODATA_PKT:
bt_cb(h5->rx_skb)->pkt_type = H5_HDR_PKT_TYPE(hdr);
/* Remove Three-wire header */
skb_pull(h5->rx_skb, 4);
hci_recv_frame(h5->rx_skb);
h5->rx_skb = NULL;
break;
default:
h5_handle_internal_rx(hu);
break;
}
h5_reset_rx(h5);
}
static int h5_rx_crc(struct hci_uart *hu, unsigned char c)
{
struct h5 *h5 = hu->priv;
h5_complete_rx_pkt(hu);
h5_reset_rx(h5);
return 0;
}
static int h5_rx_payload(struct hci_uart *hu, unsigned char c)
{
struct h5 *h5 = hu->priv;
const unsigned char *hdr = h5->rx_skb->data;
if (H5_HDR_CRC(hdr)) {
h5->rx_func = h5_rx_crc;
h5->rx_pending = 2;
} else {
h5_complete_rx_pkt(hu);
h5_reset_rx(h5);
}
return 0;
}
static int h5_rx_3wire_hdr(struct hci_uart *hu, unsigned char c)
{
struct h5 *h5 = hu->priv;
const unsigned char *hdr = h5->rx_skb->data;
BT_DBG("%s rx: seq %u ack %u crc %u rel %u type %u len %u",
hu->hdev->name, H5_HDR_SEQ(hdr), H5_HDR_ACK(hdr),
H5_HDR_CRC(hdr), H5_HDR_RELIABLE(hdr), H5_HDR_PKT_TYPE(hdr),
H5_HDR_LEN(hdr));
if (((hdr[0] + hdr[1] + hdr[2] + hdr[3]) & 0xff) != 0xff) {
BT_ERR("Invalid header checksum");
h5_reset_rx(h5);
return 0;
}
if (H5_HDR_RELIABLE(hdr) && H5_HDR_SEQ(hdr) != h5->tx_ack) {
BT_ERR("Out-of-order packet arrived (%u != %u)",
H5_HDR_SEQ(hdr), h5->tx_ack);
h5_reset_rx(h5);
return 0;
}
if (h5->state != H5_ACTIVE &&
H5_HDR_PKT_TYPE(hdr) != HCI_3WIRE_LINK_PKT) {
BT_ERR("Non-link packet received in non-active state");
h5_reset_rx(h5);
}
h5->rx_func = h5_rx_payload;
h5->rx_pending = H5_HDR_LEN(hdr);
return 0;
}
static int h5_rx_pkt_start(struct hci_uart *hu, unsigned char c)
{
struct h5 *h5 = hu->priv;
if (c == SLIP_DELIMITER)
return 1;
h5->rx_func = h5_rx_3wire_hdr;
h5->rx_pending = 4;
h5->rx_skb = bt_skb_alloc(H5_MAX_LEN, GFP_ATOMIC);
if (!h5->rx_skb) {
BT_ERR("Can't allocate mem for new packet");
h5_reset_rx(h5);
return -ENOMEM;
}
h5->rx_skb->dev = (void *) hu->hdev;
return 0;
}
static int h5_rx_delimiter(struct hci_uart *hu, unsigned char c)
{
struct h5 *h5 = hu->priv;
if (c == SLIP_DELIMITER)
h5->rx_func = h5_rx_pkt_start;
return 1;
}
static void h5_unslip_one_byte(struct h5 *h5, unsigned char c)
{
const u8 delim = SLIP_DELIMITER, esc = SLIP_ESC;
const u8 *byte = &c;
if (!test_bit(H5_RX_ESC, &h5->flags) && c == SLIP_ESC) {
set_bit(H5_RX_ESC, &h5->flags);
return;
}
if (test_and_clear_bit(H5_RX_ESC, &h5->flags)) {
switch (c) {
case SLIP_ESC_DELIM:
byte = &delim;
break;
case SLIP_ESC_ESC:
byte = &esc;
break;
default:
BT_ERR("Invalid esc byte 0x%02hhx", c);
h5_reset_rx(h5);
return;
}
}
memcpy(skb_put(h5->rx_skb, 1), byte, 1);
h5->rx_pending--;
BT_DBG("unsliped 0x%02hhx, rx_pending %zu", *byte, h5->rx_pending);
}
static void h5_reset_rx(struct h5 *h5)
{
if (h5->rx_skb) {
kfree_skb(h5->rx_skb);
h5->rx_skb = NULL;
}
h5->rx_func = h5_rx_delimiter;
h5->rx_pending = 0;
clear_bit(H5_RX_ESC, &h5->flags);
}
static int h5_recv(struct hci_uart *hu, void *data, int count)
{
struct h5 *h5 = hu->priv;
unsigned char *ptr = data;
BT_DBG("%s pending %zu count %d", hu->hdev->name, h5->rx_pending,
count);
while (count > 0) {
int processed;
if (h5->rx_pending > 0) {
if (*ptr == SLIP_DELIMITER) {
BT_ERR("Too short H5 packet");
h5_reset_rx(h5);
continue;
}
h5_unslip_one_byte(h5, *ptr);
ptr++; count--;
continue;
}
processed = h5->rx_func(hu, *ptr);
if (processed < 0)
return processed;
ptr += processed;
count -= processed;
}
return 0;
}
static int h5_enqueue(struct hci_uart *hu, struct sk_buff *skb)
{
struct h5 *h5 = hu->priv;
if (skb->len > 0xfff) {
BT_ERR("Packet too long (%u bytes)", skb->len);
kfree_skb(skb);
return 0;
}
if (h5->state != H5_ACTIVE) {
BT_ERR("Ignoring HCI data in non-active state");
kfree_skb(skb);
return 0;
}
switch (bt_cb(skb)->pkt_type) {
case HCI_ACLDATA_PKT:
case HCI_COMMAND_PKT:
skb_queue_tail(&h5->rel, skb);
break;
case HCI_SCODATA_PKT:
skb_queue_tail(&h5->unrel, skb);
break;
default:
BT_ERR("Unknown packet type %u", bt_cb(skb)->pkt_type);
kfree_skb(skb);
break;
}
return 0;
}
static void h5_slip_delim(struct sk_buff *skb)
{
const char delim = SLIP_DELIMITER;
memcpy(skb_put(skb, 1), &delim, 1);
}
static void h5_slip_one_byte(struct sk_buff *skb, u8 c)
{
const char esc_delim[2] = { SLIP_ESC, SLIP_ESC_DELIM };
const char esc_esc[2] = { SLIP_ESC, SLIP_ESC_ESC };
switch (c) {
case SLIP_DELIMITER:
memcpy(skb_put(skb, 2), &esc_delim, 2);
break;
case SLIP_ESC:
memcpy(skb_put(skb, 2), &esc_esc, 2);
break;
default:
memcpy(skb_put(skb, 1), &c, 1);
}
}
static bool valid_packet_type(u8 type)
{
switch (type) {
case HCI_ACLDATA_PKT:
case HCI_COMMAND_PKT:
case HCI_SCODATA_PKT:
case HCI_3WIRE_LINK_PKT:
case HCI_3WIRE_ACK_PKT:
return true;
default:
return false;
}
}
static struct sk_buff *h5_prepare_pkt(struct hci_uart *hu, u8 pkt_type,
const u8 *data, size_t len)
{
struct h5 *h5 = hu->priv;
struct sk_buff *nskb;
u8 hdr[4];
int i;
if (!valid_packet_type(pkt_type)) {
BT_ERR("Unknown packet type %u", pkt_type);
return NULL;
}
/*
* Max len of packet: (original len + 4 (H5 hdr) + 2 (crc)) * 2
* (because bytes 0xc0 and 0xdb are escaped, worst case is when
* the packet is all made of 0xc0 and 0xdb) + 2 (0xc0
* delimiters at start and end).
*/
nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
if (!nskb)
return NULL;
bt_cb(nskb)->pkt_type = pkt_type;
h5_slip_delim(nskb);
hdr[0] = h5->tx_ack << 3;
clear_bit(H5_TX_ACK_REQ, &h5->flags);
/* Reliable packet? */
if (pkt_type == HCI_ACLDATA_PKT || pkt_type == HCI_COMMAND_PKT) {
hdr[0] |= 1 << 7;
hdr[0] |= h5->tx_seq;
h5->tx_seq = (h5->tx_seq + 1) % 8;
}
hdr[1] = pkt_type | ((len & 0x0f) << 4);
hdr[2] = len >> 4;
hdr[3] = ~((hdr[0] + hdr[1] + hdr[2]) & 0xff);
BT_DBG("%s tx: seq %u ack %u crc %u rel %u type %u len %u",
hu->hdev->name, H5_HDR_SEQ(hdr), H5_HDR_ACK(hdr),
H5_HDR_CRC(hdr), H5_HDR_RELIABLE(hdr), H5_HDR_PKT_TYPE(hdr),
H5_HDR_LEN(hdr));
for (i = 0; i < 4; i++)
h5_slip_one_byte(nskb, hdr[i]);
for (i = 0; i < len; i++)
h5_slip_one_byte(nskb, data[i]);
h5_slip_delim(nskb);
return nskb;
}
static struct sk_buff *h5_dequeue(struct hci_uart *hu)
{
struct h5 *h5 = hu->priv;
unsigned long flags;
struct sk_buff *skb, *nskb;
if (h5->sleep != H5_AWAKE) {
const unsigned char wakeup_req[] = { 0x05, 0xfa };
if (h5->sleep == H5_WAKING_UP)
return NULL;
h5->sleep = H5_WAKING_UP;
BT_DBG("Sending wakeup request");
mod_timer(&h5->timer, jiffies + HZ / 100);
return h5_prepare_pkt(hu, HCI_3WIRE_LINK_PKT, wakeup_req, 2);
}
if ((skb = skb_dequeue(&h5->unrel)) != NULL) {
nskb = h5_prepare_pkt(hu, bt_cb(skb)->pkt_type,
skb->data, skb->len);
if (nskb) {
kfree_skb(skb);
return nskb;
}
skb_queue_head(&h5->unrel, skb);
BT_ERR("Could not dequeue pkt because alloc_skb failed");
}
spin_lock_irqsave_nested(&h5->unack.lock, flags, SINGLE_DEPTH_NESTING);
if (h5->unack.qlen >= h5->tx_win)
goto unlock;
if ((skb = skb_dequeue(&h5->rel)) != NULL) {
nskb = h5_prepare_pkt(hu, bt_cb(skb)->pkt_type,
skb->data, skb->len);
if (nskb) {
__skb_queue_tail(&h5->unack, skb);
mod_timer(&h5->timer, jiffies + H5_ACK_TIMEOUT);
spin_unlock_irqrestore(&h5->unack.lock, flags);
return nskb;
}
skb_queue_head(&h5->rel, skb);
BT_ERR("Could not dequeue pkt because alloc_skb failed");
}
unlock:
spin_unlock_irqrestore(&h5->unack.lock, flags);
if (test_bit(H5_TX_ACK_REQ, &h5->flags))
return h5_prepare_pkt(hu, HCI_3WIRE_ACK_PKT, NULL, 0);
return NULL;
}
static int h5_flush(struct hci_uart *hu)
{
BT_DBG("hu %p", hu);
return 0;
}
static struct hci_uart_proto h5p = {
.id = HCI_UART_3WIRE,
.open = h5_open,
.close = h5_close,
.recv = h5_recv,
.enqueue = h5_enqueue,
.dequeue = h5_dequeue,
.flush = h5_flush,
};
int __init h5_init(void)
{
int err = hci_uart_register_proto(&h5p);
if (!err)
BT_INFO("HCI Three-wire UART (H5) protocol initialized");
else
BT_ERR("HCI Three-wire UART (H5) protocol init failed");
return err;
}
int __exit h5_deinit(void)
{
return hci_uart_unregister_proto(&h5p);
}

View File

@ -156,6 +156,35 @@ restart:
return 0;
}
static void hci_uart_init_work(struct work_struct *work)
{
struct hci_uart *hu = container_of(work, struct hci_uart, init_ready);
int err;
if (!test_and_clear_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags))
return;
err = hci_register_dev(hu->hdev);
if (err < 0) {
BT_ERR("Can't register HCI device");
hci_free_dev(hu->hdev);
hu->hdev = NULL;
hu->proto->close(hu);
}
set_bit(HCI_UART_REGISTERED, &hu->flags);
}
int hci_uart_init_ready(struct hci_uart *hu)
{
if (!test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags))
return -EALREADY;
schedule_work(&hu->init_ready);
return 0;
}
/* ------- Interface to HCI layer ------ */
/* Initialize device */
static int hci_uart_open(struct hci_dev *hdev)
@ -264,6 +293,8 @@ static int hci_uart_tty_open(struct tty_struct *tty)
hu->tty = tty;
tty->receive_room = 65536;
INIT_WORK(&hu->init_ready, hci_uart_init_work);
spin_lock_init(&hu->rx_lock);
/* Flush any pending characters in the driver and line discipline. */
@ -286,28 +317,30 @@ static int hci_uart_tty_open(struct tty_struct *tty)
static void hci_uart_tty_close(struct tty_struct *tty)
{
struct hci_uart *hu = (void *)tty->disc_data;
struct hci_dev *hdev;
BT_DBG("tty %p", tty);
/* Detach from the tty */
tty->disc_data = NULL;
if (hu) {
struct hci_dev *hdev = hu->hdev;
if (!hu)
return;
if (hdev)
hci_uart_close(hdev);
hdev = hu->hdev;
if (hdev)
hci_uart_close(hdev);
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
if (hdev) {
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
if (hdev) {
if (test_bit(HCI_UART_REGISTERED, &hu->flags))
hci_unregister_dev(hdev);
hci_free_dev(hdev);
}
hu->proto->close(hu);
hci_free_dev(hdev);
}
kfree(hu);
hu->proto->close(hu);
}
kfree(hu);
}
/* hci_uart_tty_wakeup()
@ -401,12 +434,17 @@ static int hci_uart_register_dev(struct hci_uart *hu)
else
hdev->dev_type = HCI_BREDR;
if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags))
return 0;
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
hci_free_dev(hdev);
return -ENODEV;
}
set_bit(HCI_UART_REGISTERED, &hu->flags);
return 0;
}
@ -558,6 +596,9 @@ static int __init hci_uart_init(void)
#ifdef CONFIG_BT_HCIUART_ATH3K
ath_init();
#endif
#ifdef CONFIG_BT_HCIUART_3WIRE
h5_init();
#endif
return 0;
}
@ -578,6 +619,9 @@ static void __exit hci_uart_exit(void)
#ifdef CONFIG_BT_HCIUART_ATH3K
ath_deinit();
#endif
#ifdef CONFIG_BT_HCIUART_3WIRE
h5_deinit();
#endif
/* Release tty registration of line discipline */
if ((err = tty_unregister_ldisc(N_HCI)))

View File

@ -47,6 +47,7 @@
#define HCI_UART_RAW_DEVICE 0
#define HCI_UART_RESET_ON_INIT 1
#define HCI_UART_CREATE_AMP 2
#define HCI_UART_INIT_PENDING 3
struct hci_uart;
@ -66,6 +67,8 @@ struct hci_uart {
unsigned long flags;
unsigned long hdev_flags;
struct work_struct init_ready;
struct hci_uart_proto *proto;
void *priv;
@ -76,6 +79,7 @@ struct hci_uart {
/* HCI_UART proto flag bits */
#define HCI_UART_PROTO_SET 0
#define HCI_UART_REGISTERED 1
/* TX states */
#define HCI_UART_SENDING 1
@ -84,6 +88,7 @@ struct hci_uart {
int hci_uart_register_proto(struct hci_uart_proto *p);
int hci_uart_unregister_proto(struct hci_uart_proto *p);
int hci_uart_tx_wakeup(struct hci_uart *hu);
int hci_uart_init_ready(struct hci_uart *hu);
#ifdef CONFIG_BT_HCIUART_H4
int h4_init(void);
@ -104,3 +109,8 @@ int ll_deinit(void);
int ath_init(void);
int ath_deinit(void);
#endif
#ifdef CONFIG_BT_HCIUART_3WIRE
int h5_init(void);
int h5_deinit(void);
#endif

View File

@ -139,11 +139,12 @@ enum {
#define HCIINQUIRY _IOR('H', 240, int)
/* HCI timeouts */
#define HCI_DISCONN_TIMEOUT (2000) /* 2 seconds */
#define HCI_PAIRING_TIMEOUT (60000) /* 60 seconds */
#define HCI_INIT_TIMEOUT (10000) /* 10 seconds */
#define HCI_CMD_TIMEOUT (1000) /* 1 seconds */
#define HCI_ACL_TX_TIMEOUT (45000) /* 45 seconds */
#define HCI_DISCONN_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
#define HCI_PAIRING_TIMEOUT msecs_to_jiffies(60000) /* 60 seconds */
#define HCI_INIT_TIMEOUT msecs_to_jiffies(10000) /* 10 seconds */
#define HCI_CMD_TIMEOUT msecs_to_jiffies(1000) /* 1 second */
#define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */
#define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
/* HCI data types */
#define HCI_COMMAND_PKT 0x01

View File

@ -587,18 +587,24 @@ void hci_conn_put_device(struct hci_conn *conn);
static inline void hci_conn_hold(struct hci_conn *conn)
{
BT_DBG("hcon %p refcnt %d -> %d", conn, atomic_read(&conn->refcnt),
atomic_read(&conn->refcnt) + 1);
atomic_inc(&conn->refcnt);
cancel_delayed_work(&conn->disc_work);
}
static inline void hci_conn_put(struct hci_conn *conn)
{
BT_DBG("hcon %p refcnt %d -> %d", conn, atomic_read(&conn->refcnt),
atomic_read(&conn->refcnt) - 1);
if (atomic_dec_and_test(&conn->refcnt)) {
unsigned long timeo;
if (conn->type == ACL_LINK || conn->type == LE_LINK) {
del_timer(&conn->idle_timer);
if (conn->state == BT_CONNECTED) {
timeo = msecs_to_jiffies(conn->disc_timeout);
timeo = conn->disc_timeout;
if (!conn->out)
timeo *= 2;
} else {

View File

@ -464,6 +464,7 @@ struct l2cap_chan {
__u16 tx_win;
__u16 tx_win_max;
__u16 ack_win;
__u8 max_tx;
__u16 retrans_timeout;
__u16 monitor_timeout;
@ -672,11 +673,15 @@ enum {
static inline void l2cap_chan_hold(struct l2cap_chan *c)
{
BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt));
atomic_inc(&c->refcnt);
}
static inline void l2cap_chan_put(struct l2cap_chan *c)
{
BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt));
if (atomic_dec_and_test(&c->refcnt))
kfree(c);
}

View File

@ -444,7 +444,7 @@ struct mgmt_ev_auth_failed {
struct mgmt_ev_device_found {
struct mgmt_addr_info addr;
__s8 rssi;
__u8 flags[4];
__le32 flags;
__le16 eir_len;
__u8 eir[0];
} __packed;

View File

@ -501,7 +501,7 @@ static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn)
/* AMP Manager functions */
void amp_mgr_get(struct amp_mgr *mgr)
{
BT_DBG("mgr %p", mgr);
BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount));
kref_get(&mgr->kref);
}
@ -517,7 +517,7 @@ static void amp_mgr_destroy(struct kref *kref)
int amp_mgr_put(struct amp_mgr *mgr)
{
BT_DBG("mgr %p", mgr);
BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount));
return kref_put(&mgr->kref, &amp_mgr_destroy);
}

View File

@ -107,7 +107,7 @@ static void hci_acl_connect_cancel(struct hci_conn *conn)
{
struct hci_cp_create_conn_cancel cp;
BT_DBG("%p", conn);
BT_DBG("hcon %p", conn);
if (conn->hdev->hci_ver < BLUETOOTH_VER_1_2)
return;
@ -120,7 +120,7 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
{
struct hci_cp_disconnect cp;
BT_DBG("%p", conn);
BT_DBG("hcon %p", conn);
conn->state = BT_DISCONN;
@ -134,7 +134,7 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle)
struct hci_dev *hdev = conn->hdev;
struct hci_cp_add_sco cp;
BT_DBG("%p", conn);
BT_DBG("hcon %p", conn);
conn->state = BT_CONNECT;
conn->out = true;
@ -152,7 +152,7 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
struct hci_dev *hdev = conn->hdev;
struct hci_cp_setup_sync_conn cp;
BT_DBG("%p", conn);
BT_DBG("hcon %p", conn);
conn->state = BT_CONNECT;
conn->out = true;
@ -196,7 +196,7 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
struct hci_dev *hdev = conn->hdev;
struct hci_cp_le_start_enc cp;
BT_DBG("%p", conn);
BT_DBG("hcon %p", conn);
memset(&cp, 0, sizeof(cp));
@ -213,11 +213,11 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status)
{
struct hci_conn *sco = conn->link;
BT_DBG("%p", conn);
if (!sco)
return;
BT_DBG("hcon %p", conn);
if (!status) {
if (lmp_esco_capable(conn->hdev))
hci_setup_sync(sco, conn->handle);
@ -235,7 +235,7 @@ static void hci_conn_timeout(struct work_struct *work)
disc_work.work);
__u8 reason;
BT_DBG("conn %p state %s", conn, state_to_string(conn->state));
BT_DBG("hcon %p state %s", conn, state_to_string(conn->state));
if (atomic_read(&conn->refcnt))
return;
@ -266,7 +266,7 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
BT_DBG("conn %p mode %d", conn, conn->mode);
BT_DBG("hcon %p mode %d", conn, conn->mode);
if (test_bit(HCI_RAW, &hdev->flags))
return;
@ -301,7 +301,7 @@ static void hci_conn_idle(unsigned long arg)
{
struct hci_conn *conn = (void *) arg;
BT_DBG("conn %p mode %d", conn, conn->mode);
BT_DBG("hcon %p mode %d", conn, conn->mode);
hci_conn_enter_sniff_mode(conn);
}
@ -382,7 +382,7 @@ int hci_conn_del(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle);
del_timer(&conn->idle_timer);
@ -442,7 +442,8 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
list_for_each_entry(d, &hci_dev_list, list) {
if (!test_bit(HCI_UP, &d->flags) ||
test_bit(HCI_RAW, &d->flags))
test_bit(HCI_RAW, &d->flags) ||
d->dev_type != HCI_BREDR)
continue;
/* Simple routing:
@ -557,7 +558,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
/* Check link security requirement */
int hci_conn_check_link_mode(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
BT_DBG("hcon %p", conn);
if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT))
return 0;
@ -568,7 +569,7 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
/* Authenticate remote device */
static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
{
BT_DBG("conn %p", conn);
BT_DBG("hcon %p", conn);
if (conn->pending_sec_level > sec_level)
sec_level = conn->pending_sec_level;
@ -602,7 +603,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
/* Encrypt the the link */
static void hci_conn_encrypt(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
BT_DBG("hcon %p", conn);
if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
struct hci_cp_set_conn_encrypt cp;
@ -616,7 +617,7 @@ static void hci_conn_encrypt(struct hci_conn *conn)
/* Enable security */
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
{
BT_DBG("conn %p", conn);
BT_DBG("hcon %p", conn);
/* For sdp we don't need the link key. */
if (sec_level == BT_SECURITY_SDP)
@ -669,7 +670,7 @@ EXPORT_SYMBOL(hci_conn_security);
/* Check secure link requirement */
int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level)
{
BT_DBG("conn %p", conn);
BT_DBG("hcon %p", conn);
if (sec_level != BT_SECURITY_HIGH)
return 1; /* Accept if non-secure is required */
@ -684,7 +685,7 @@ EXPORT_SYMBOL(hci_conn_check_secure);
/* Change link key */
int hci_conn_change_link_key(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
BT_DBG("hcon %p", conn);
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
struct hci_cp_change_conn_link_key cp;
@ -699,7 +700,7 @@ int hci_conn_change_link_key(struct hci_conn *conn)
/* Switch role */
int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
{
BT_DBG("conn %p", conn);
BT_DBG("hcon %p", conn);
if (!role && conn->link_mode & HCI_LM_MASTER)
return 1;
@ -720,7 +721,7 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active)
{
struct hci_dev *hdev = conn->hdev;
BT_DBG("conn %p mode %d", conn, conn->mode);
BT_DBG("hcon %p mode %d", conn, conn->mode);
if (test_bit(HCI_RAW, &hdev->flags))
return;
@ -894,7 +895,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn)
struct hci_dev *hdev = conn->hdev;
struct hci_chan *chan;
BT_DBG("%s conn %p", hdev->name, conn);
BT_DBG("%s hcon %p", hdev->name, conn);
chan = kzalloc(sizeof(struct hci_chan), GFP_KERNEL);
if (!chan)
@ -913,7 +914,7 @@ int hci_chan_del(struct hci_chan *chan)
struct hci_conn *conn = chan->conn;
struct hci_dev *hdev = conn->hdev;
BT_DBG("%s conn %p chan %p", hdev->name, conn, chan);
BT_DBG("%s hcon %p chan %p", hdev->name, conn, chan);
list_del_rcu(&chan->list);
@ -929,7 +930,7 @@ void hci_chan_list_flush(struct hci_conn *conn)
{
struct hci_chan *chan, *n;
BT_DBG("conn %p", conn);
BT_DBG("hcon %p", conn);
list_for_each_entry_safe(chan, n, &conn->chan_list, list)
hci_chan_del(chan);

View File

@ -33,8 +33,6 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#define AUTO_OFF_TIMEOUT 2000
static void hci_rx_work(struct work_struct *work);
static void hci_cmd_work(struct work_struct *work);
static void hci_tx_work(struct work_struct *work);
@ -61,7 +59,7 @@ static void hci_notify(struct hci_dev *hdev, int event)
void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
{
BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result);
BT_DBG("%s command 0x%4.4x result 0x%2.2x", hdev->name, cmd, result);
/* If this is the init phase check if the completed command matches
* the last init command, and if not just return.
@ -188,12 +186,6 @@ static void bredr_init(struct hci_dev *hdev)
/* Mandatory initialization */
/* Reset */
if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
set_bit(HCI_RESET, &hdev->flags);
hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
}
/* Read Local Supported Features */
hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
@ -234,9 +226,6 @@ static void amp_init(struct hci_dev *hdev)
{
hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
/* Reset */
hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
/* Read Local Version */
hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
@ -262,6 +251,10 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
}
skb_queue_purge(&hdev->driver_init);
/* Reset */
if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
hci_reset_req(hdev, 0);
switch (hdev->dev_type) {
case HCI_BREDR:
bredr_init(hdev);
@ -690,12 +683,11 @@ int hci_dev_open(__u16 dev)
set_bit(HCI_INIT, &hdev->flags);
hdev->init_last_cmd = 0;
ret = __hci_request(hdev, hci_init_req, 0,
msecs_to_jiffies(HCI_INIT_TIMEOUT));
ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
if (lmp_host_le_capable(hdev))
ret = __hci_request(hdev, hci_le_init_req, 0,
msecs_to_jiffies(HCI_INIT_TIMEOUT));
HCI_INIT_TIMEOUT);
clear_bit(HCI_INIT, &hdev->flags);
}
@ -782,8 +774,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
if (!test_bit(HCI_RAW, &hdev->flags) &&
test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
set_bit(HCI_INIT, &hdev->flags);
__hci_request(hdev, hci_reset_req, 0,
msecs_to_jiffies(250));
__hci_request(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
clear_bit(HCI_INIT, &hdev->flags);
}
@ -872,8 +863,7 @@ int hci_dev_reset(__u16 dev)
hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
if (!test_bit(HCI_RAW, &hdev->flags))
ret = __hci_request(hdev, hci_reset_req, 0,
msecs_to_jiffies(HCI_INIT_TIMEOUT));
ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
done:
hci_req_unlock(hdev);
@ -913,7 +903,7 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
switch (cmd) {
case HCISETAUTH:
err = hci_request(hdev, hci_auth_req, dr.dev_opt,
msecs_to_jiffies(HCI_INIT_TIMEOUT));
HCI_INIT_TIMEOUT);
break;
case HCISETENCRYPT:
@ -925,23 +915,23 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
if (!test_bit(HCI_AUTH, &hdev->flags)) {
/* Auth must be enabled first */
err = hci_request(hdev, hci_auth_req, dr.dev_opt,
msecs_to_jiffies(HCI_INIT_TIMEOUT));
HCI_INIT_TIMEOUT);
if (err)
break;
}
err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
msecs_to_jiffies(HCI_INIT_TIMEOUT));
HCI_INIT_TIMEOUT);
break;
case HCISETSCAN:
err = hci_request(hdev, hci_scan_req, dr.dev_opt,
msecs_to_jiffies(HCI_INIT_TIMEOUT));
HCI_INIT_TIMEOUT);
break;
case HCISETLINKPOL:
err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
msecs_to_jiffies(HCI_INIT_TIMEOUT));
HCI_INIT_TIMEOUT);
break;
case HCISETLINKMODE:
@ -1091,8 +1081,7 @@ static void hci_power_on(struct work_struct *work)
return;
if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
schedule_delayed_work(&hdev->power_off,
msecs_to_jiffies(AUTO_OFF_TIMEOUT));
schedule_delayed_work(&hdev->power_off, HCI_AUTO_OFF_TIMEOUT);
if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
mgmt_index_added(hdev);
@ -1369,11 +1358,19 @@ int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
}
/* HCI command timer function */
static void hci_cmd_timer(unsigned long arg)
static void hci_cmd_timeout(unsigned long arg)
{
struct hci_dev *hdev = (void *) arg;
BT_ERR("%s command tx timeout", hdev->name);
if (hdev->sent_cmd) {
struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
u16 opcode = __le16_to_cpu(sent->opcode);
BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
} else {
BT_ERR("%s command tx timeout", hdev->name);
}
atomic_set(&hdev->cmd_cnt, 1);
queue_work(hdev->workqueue, &hdev->cmd_work);
}
@ -1671,7 +1668,7 @@ struct hci_dev *hci_alloc_dev(void)
init_waitqueue_head(&hdev->req_wait_q);
setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);
setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
hci_init_sysfs(hdev);
discovery_init(hdev);
@ -1746,8 +1743,11 @@ int hci_register_dev(struct hci_dev *hdev)
}
}
set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
set_bit(HCI_SETUP, &hdev->dev_flags);
if (hdev->dev_type != HCI_AMP)
set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
schedule_work(&hdev->power_on);
hci_notify(hdev, HCI_DEV_REG);
@ -2087,7 +2087,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
struct hci_command_hdr *hdr;
struct sk_buff *skb;
BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
skb = bt_skb_alloc(len, GFP_ATOMIC);
if (!skb) {
@ -2129,7 +2129,7 @@ void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
if (hdr->opcode != cpu_to_le16(opcode))
return NULL;
BT_DBG("%s opcode 0x%x", hdev->name, opcode);
BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
}
@ -2199,7 +2199,7 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
struct hci_conn *conn = chan->conn;
struct hci_dev *hdev = conn->hdev;
BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags);
BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
skb->dev = (void *) hdev;
@ -2455,7 +2455,7 @@ static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
/* ACL tx timeout must be longer than maximum
* link supervision timeout (40.9 seconds) */
if (!cnt && time_after(jiffies, hdev->acl_last_tx +
msecs_to_jiffies(HCI_ACL_TX_TIMEOUT)))
HCI_ACL_TX_TIMEOUT))
hci_link_tx_to(hdev, ACL_LINK);
}
}
@ -2699,7 +2699,7 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
flags = hci_flags(handle);
handle = hci_handle(handle);
BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len,
BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
handle, flags);
hdev->stat.acl_rx++;
@ -2741,7 +2741,7 @@ static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
handle = __le16_to_cpu(hdr->handle);
BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
hdev->stat.sco_rx++;
@ -2821,7 +2821,8 @@ static void hci_cmd_work(struct work_struct *work)
struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
struct sk_buff *skb;
BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
/* Send queued commands */
if (atomic_read(&hdev->cmd_cnt)) {
@ -2839,7 +2840,7 @@ static void hci_cmd_work(struct work_struct *work)
del_timer(&hdev->cmd_timer);
else
mod_timer(&hdev->cmd_timer,
jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
jiffies + HCI_CMD_TIMEOUT);
} else {
skb_queue_head(&hdev->cmd_q, skb);
queue_work(hdev->workqueue, &hdev->cmd_work);

View File

@ -36,7 +36,7 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status) {
hci_dev_lock(hdev);
@ -60,7 +60,7 @@ static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status)
return;
@ -72,7 +72,7 @@ static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status)
return;
@ -93,7 +93,7 @@ static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_rp_role_discovery *rp = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -116,7 +116,7 @@ static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_rp_read_link_policy *rp = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -136,7 +136,7 @@ static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_conn *conn;
void *sent;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -159,7 +159,7 @@ static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
{
struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -173,7 +173,7 @@ static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
__u8 status = *((__u8 *) skb->data);
void *sent;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
if (!sent)
@ -189,7 +189,7 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
clear_bit(HCI_RESET, &hdev->flags);
@ -207,7 +207,7 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
__u8 status = *((__u8 *) skb->data);
void *sent;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
if (!sent)
@ -229,7 +229,7 @@ static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_read_local_name *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -243,7 +243,7 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
__u8 status = *((__u8 *) skb->data);
void *sent;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
if (!sent)
@ -269,7 +269,7 @@ static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
__u8 status = *((__u8 *) skb->data);
void *sent;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
if (!sent)
@ -293,7 +293,7 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
int old_pscan, old_iscan;
void *sent;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
if (!sent)
@ -340,7 +340,7 @@ static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -356,7 +356,7 @@ static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
__u8 status = *((__u8 *) skb->data);
void *sent;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
if (!sent)
@ -378,7 +378,7 @@ static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_rp_read_voice_setting *rp = (void *) skb->data;
__u16 setting;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -390,7 +390,7 @@ static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
hdev->voice_setting = setting;
BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
if (hdev->notify)
hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
@ -403,7 +403,7 @@ static void hci_cc_write_voice_setting(struct hci_dev *hdev,
__u16 setting;
void *sent;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status)
return;
@ -419,7 +419,7 @@ static void hci_cc_write_voice_setting(struct hci_dev *hdev,
hdev->voice_setting = setting;
BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
if (hdev->notify)
hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
@ -429,7 +429,7 @@ static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
}
@ -439,7 +439,7 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
__u8 status = *((__u8 *) skb->data);
void *sent;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
if (!sent)
@ -597,7 +597,7 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_read_local_version *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
goto done;
@ -608,7 +608,7 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
if (test_bit(HCI_INIT, &hdev->flags))
@ -641,7 +641,7 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev,
{
struct hci_rp_read_local_commands *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
goto done;
@ -660,7 +660,7 @@ static void hci_cc_read_local_features(struct hci_dev *hdev,
{
struct hci_rp_read_local_features *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -732,7 +732,7 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
{
struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
goto done;
@ -758,7 +758,7 @@ static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
{
struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -772,7 +772,7 @@ static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_read_buffer_size *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -798,7 +798,7 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_read_bd_addr *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (!rp->status)
bacpy(&hdev->bdaddr, &rp->bdaddr);
@ -811,7 +811,7 @@ static void hci_cc_read_data_block_size(struct hci_dev *hdev,
{
struct hci_rp_read_data_block_size *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -832,7 +832,7 @@ static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
}
@ -842,7 +842,7 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
{
struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -866,7 +866,7 @@ static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
{
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
}
@ -875,7 +875,7 @@ static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
}
@ -885,7 +885,7 @@ static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
{
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
}
@ -895,7 +895,7 @@ static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
{
struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (!rp->status)
hdev->inq_tx_power = rp->tx_power;
@ -907,7 +907,7 @@ static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
}
@ -918,7 +918,7 @@ static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_cp_pin_code_reply *cp;
struct hci_conn *conn;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
hci_dev_lock(hdev);
@ -944,7 +944,7 @@ static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
hci_dev_lock(hdev);
@ -960,7 +960,7 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
{
struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -979,7 +979,7 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
hci_dev_lock(hdev);
@ -995,7 +995,7 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
{
struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
hci_dev_lock(hdev);
@ -1010,7 +1010,7 @@ static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
hci_dev_lock(hdev);
@ -1026,7 +1026,7 @@ static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
{
struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
hci_dev_lock(hdev);
@ -1042,7 +1042,7 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
{
struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
hci_dev_lock(hdev);
mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
@ -1054,7 +1054,7 @@ static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
@ -1072,7 +1072,7 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
struct hci_cp_le_set_scan_enable *cp;
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
if (!cp)
@ -1127,7 +1127,7 @@ static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -1139,7 +1139,7 @@ static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
@ -1153,7 +1153,7 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
struct hci_cp_write_le_host_supported *sent;
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
if (!sent)
@ -1175,7 +1175,7 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
{
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status) {
hci_req_complete(hdev, HCI_OP_INQUIRY, status);
@ -1199,7 +1199,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
struct hci_cp_create_conn *cp;
struct hci_conn *conn;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
if (!cp)
@ -1209,7 +1209,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
BT_DBG("%s bdaddr %s hcon %p", hdev->name, batostr(&cp->bdaddr), conn);
if (status) {
if (conn && conn->state == BT_CONNECT) {
@ -1240,7 +1240,7 @@ static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
struct hci_conn *acl, *sco;
__u16 handle;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (!status)
return;
@ -1251,7 +1251,7 @@ static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
handle = __le16_to_cpu(cp->handle);
BT_DBG("%s handle %d", hdev->name, handle);
BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
hci_dev_lock(hdev);
@ -1274,7 +1274,7 @@ static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
struct hci_cp_auth_requested *cp;
struct hci_conn *conn;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (!status)
return;
@ -1301,7 +1301,7 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
struct hci_cp_set_conn_encrypt *cp;
struct hci_conn *conn;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (!status)
return;
@ -1413,7 +1413,7 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
struct hci_cp_remote_name_req *cp;
struct hci_conn *conn;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
/* If successful wait for the name req complete event before
* checking for the need to do authentication */
@ -1452,7 +1452,7 @@ static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
struct hci_cp_read_remote_features *cp;
struct hci_conn *conn;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (!status)
return;
@ -1479,7 +1479,7 @@ static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
struct hci_cp_read_remote_ext_features *cp;
struct hci_conn *conn;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (!status)
return;
@ -1507,7 +1507,7 @@ static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
struct hci_conn *acl, *sco;
__u16 handle;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (!status)
return;
@ -1518,7 +1518,7 @@ static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
handle = __le16_to_cpu(cp->handle);
BT_DBG("%s handle %d", hdev->name, handle);
BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
hci_dev_lock(hdev);
@ -1541,7 +1541,7 @@ static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
struct hci_cp_sniff_mode *cp;
struct hci_conn *conn;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (!status)
return;
@ -1568,7 +1568,7 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
struct hci_cp_exit_sniff_mode *cp;
struct hci_conn *conn;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (!status)
return;
@ -1617,7 +1617,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
struct hci_cp_le_create_conn *cp;
struct hci_conn *conn;
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
if (!cp)
@ -1655,7 +1655,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
{
BT_DBG("%s status 0x%x", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
}
static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
@ -1664,7 +1664,7 @@ static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
struct discovery_state *discov = &hdev->discovery;
struct inquiry_entry *e;
BT_DBG("%s status %d", hdev->name, status);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
hci_req_complete(hdev, HCI_OP_INQUIRY, status);
@ -1893,7 +1893,7 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_ev_disconn_complete *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
hci_dev_lock(hdev);
@ -1930,7 +1930,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_ev_auth_complete *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
hci_dev_lock(hdev);
@ -2035,7 +2035,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_ev_encrypt_change *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
hci_dev_lock(hdev);
@ -2079,7 +2079,7 @@ static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
hci_dev_lock(hdev);
@ -2102,7 +2102,7 @@ static void hci_remote_features_evt(struct hci_dev *hdev,
struct hci_ev_remote_features *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
hci_dev_lock(hdev);
@ -2364,7 +2364,7 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
break;
default:
BT_DBG("%s opcode 0x%x", hdev->name, opcode);
BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
break;
}
@ -2445,7 +2445,7 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
break;
default:
BT_DBG("%s opcode 0x%x", hdev->name, opcode);
BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
break;
}
@ -2464,7 +2464,7 @@ static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_ev_role_change *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
hci_dev_lock(hdev);
@ -2605,7 +2605,7 @@ static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_ev_mode_change *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
hci_dev_lock(hdev);
@ -2763,7 +2763,7 @@ static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_ev_clock_offset *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
hci_dev_lock(hdev);
@ -2786,7 +2786,7 @@ static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_ev_pkt_type_change *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
hci_dev_lock(hdev);
@ -2930,7 +2930,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
hci_dev_lock(hdev);
@ -2989,7 +2989,7 @@ static void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_sniff_subrate *ev = (void *) skb->data;
BT_DBG("%s status %d", hdev->name, ev->status);
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
}
static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
@ -3046,7 +3046,7 @@ static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %u handle %u", hdev->name, ev->status,
BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
__le16_to_cpu(ev->handle));
hci_dev_lock(hdev);
@ -3346,7 +3346,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_ev_le_conn_complete *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
hci_dev_lock(hdev);
@ -3421,7 +3421,7 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_conn *conn;
struct smp_ltk *ltk;
BT_DBG("%s handle %d", hdev->name, __le16_to_cpu(ev->handle));
BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
hci_dev_lock(hdev);
@ -3645,7 +3645,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
break;
default:
BT_DBG("%s event 0x%x", hdev->name, event);
BT_DBG("%s event 0x%2.2x", hdev->name, event);
break;
}

View File

@ -431,6 +431,7 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan)
chan->max_tx = L2CAP_DEFAULT_MAX_TX;
chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
chan->sec_level = BT_SECURITY_LOW;
set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
@ -1657,7 +1658,7 @@ static void l2cap_streaming_send(struct l2cap_chan *chan,
l2cap_do_send(chan, skb);
BT_DBG("Sent txseq %d", (int)control->txseq);
BT_DBG("Sent txseq %u", control->txseq);
chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
chan->frames_sent++;
@ -1722,11 +1723,11 @@ static int l2cap_ertm_send(struct l2cap_chan *chan)
chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
l2cap_do_send(chan, tx_skb);
BT_DBG("Sent txseq %d", (int)control->txseq);
BT_DBG("Sent txseq %u", control->txseq);
}
BT_DBG("Sent %d, %d unacked, %d in ERTM queue", sent,
(int) chan->unacked_frames, skb_queue_len(&chan->tx_q));
BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
chan->unacked_frames, skb_queue_len(&chan->tx_q));
return sent;
}
@ -1877,14 +1878,14 @@ static void l2cap_send_ack(struct l2cap_chan *chan)
frames_to_ack = 0;
}
/* Ack now if the tx window is 3/4ths full.
/* Ack now if the window is 3/4ths full.
* Calculate without mul or div
*/
threshold = chan->tx_win;
threshold = chan->ack_win;
threshold += threshold << 1;
threshold >>= 2;
BT_DBG("frames_to_ack %d, threshold %d", (int)frames_to_ack,
BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
threshold);
if (frames_to_ack >= threshold) {
@ -1946,15 +1947,15 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
}
static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
struct msghdr *msg, size_t len,
u32 priority)
struct msghdr *msg, size_t len,
u32 priority)
{
struct l2cap_conn *conn = chan->conn;
struct sk_buff *skb;
int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
struct l2cap_hdr *lh;
BT_DBG("chan %p len %d priority %u", chan, (int)len, priority);
BT_DBG("chan %p len %zu priority %u", chan, len, priority);
count = min_t(unsigned int, (conn->mtu - hlen), len);
@ -1980,15 +1981,15 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
}
static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
struct msghdr *msg, size_t len,
u32 priority)
struct msghdr *msg, size_t len,
u32 priority)
{
struct l2cap_conn *conn = chan->conn;
struct sk_buff *skb;
int err, count;
struct l2cap_hdr *lh;
BT_DBG("chan %p len %d", chan, (int)len);
BT_DBG("chan %p len %zu", chan, len);
count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
@ -2013,15 +2014,15 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
}
static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
struct msghdr *msg, size_t len,
u16 sdulen)
struct msghdr *msg, size_t len,
u16 sdulen)
{
struct l2cap_conn *conn = chan->conn;
struct sk_buff *skb;
int err, count, hlen;
struct l2cap_hdr *lh;
BT_DBG("chan %p len %d", chan, (int)len);
BT_DBG("chan %p len %zu", chan, len);
if (!conn)
return ERR_PTR(-ENOTCONN);
@ -2075,7 +2076,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan,
size_t pdu_len;
u8 sar;
BT_DBG("chan %p, msg %p, len %d", chan, msg, (int)len);
BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
/* It is critical that ERTM PDUs fit in a single HCI fragment,
* so fragmented skbs are not used. The HCI layer's handling
@ -2219,7 +2220,7 @@ static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
struct l2cap_ctrl control;
u16 seq;
BT_DBG("chan %p, txseq %d", chan, txseq);
BT_DBG("chan %p, txseq %u", chan, txseq);
memset(&control, 0, sizeof(control));
control.sframe = 1;
@ -2259,7 +2260,7 @@ static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
u16 initial_head;
u16 seq;
BT_DBG("chan %p, txseq %d", chan, txseq);
BT_DBG("chan %p, txseq %u", chan, txseq);
memset(&control, 0, sizeof(control));
control.sframe = 1;
@ -2284,12 +2285,12 @@ static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
struct sk_buff *acked_skb;
u16 ackseq;
BT_DBG("chan %p, reqseq %d", chan, reqseq);
BT_DBG("chan %p, reqseq %u", chan, reqseq);
if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
return;
BT_DBG("expected_ack_seq %d, unacked_frames %d",
BT_DBG("expected_ack_seq %u, unacked_frames %u",
chan->expected_ack_seq, chan->unacked_frames);
for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
@ -2308,7 +2309,7 @@ static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
if (chan->unacked_frames == 0)
__clear_retrans_timer(chan);
BT_DBG("unacked_frames %d", (int) chan->unacked_frames);
BT_DBG("unacked_frames %u", chan->unacked_frames);
}
static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
@ -2534,16 +2535,16 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
}
/* ---- L2CAP signalling commands ---- */
static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
u8 code, u8 ident, u16 dlen, void *data)
static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
u8 ident, u16 dlen, void *data)
{
struct sk_buff *skb, **frag;
struct l2cap_cmd_hdr *cmd;
struct l2cap_hdr *lh;
int len, count;
BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
conn, code, ident, dlen);
BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
conn, code, ident, dlen);
len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
count = min_t(unsigned int, conn->mtu, len);
@ -2626,7 +2627,7 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned
break;
}
BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
return len;
}
@ -2634,7 +2635,7 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
{
struct l2cap_conf_opt *opt = *ptr;
BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
opt->type = type;
opt->len = len;
@ -2786,6 +2787,7 @@ static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
L2CAP_DEFAULT_TX_WINDOW);
chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
}
chan->ack_win = chan->tx_win;
}
static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
@ -3175,10 +3177,9 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
break;
case L2CAP_CONF_EWS:
chan->tx_win = min_t(u16, val,
L2CAP_DEFAULT_EXT_WINDOW);
chan->ack_win = min_t(u16, val, chan->ack_win);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
chan->tx_win);
chan->tx_win);
break;
case L2CAP_CONF_EFS:
@ -3207,6 +3208,9 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
chan->mps = le16_to_cpu(rfc.max_pdu_size);
if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
chan->ack_win = min_t(u16, chan->ack_win,
rfc.txwin_size);
if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
chan->local_msdu = le16_to_cpu(efs.msdu);
@ -3268,7 +3272,17 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
{
int type, olen;
unsigned long val;
struct l2cap_conf_rfc rfc;
/* Use sane default values in case a misbehaving remote device
* did not send an RFC or extended window size option.
*/
u16 txwin_ext = chan->ack_win;
struct l2cap_conf_rfc rfc = {
.mode = chan->mode,
.retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
.monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
.max_pdu_size = cpu_to_le16(chan->imtu),
.txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
};
BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
@ -3278,32 +3292,27 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
while (len >= L2CAP_CONF_OPT_SIZE) {
len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
if (type != L2CAP_CONF_RFC)
continue;
if (olen != sizeof(rfc))
switch (type) {
case L2CAP_CONF_RFC:
if (olen == sizeof(rfc))
memcpy(&rfc, (void *)val, olen);
break;
memcpy(&rfc, (void *)val, olen);
goto done;
case L2CAP_CONF_EWS:
txwin_ext = val;
break;
}
}
/* Use sane default values in case a misbehaving remote device
* did not send an RFC option.
*/
rfc.mode = chan->mode;
rfc.retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
rfc.monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
rfc.max_pdu_size = cpu_to_le16(chan->imtu);
BT_ERR("Expected RFC option was not found, using defaults");
done:
switch (rfc.mode) {
case L2CAP_MODE_ERTM:
chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
chan->mps = le16_to_cpu(rfc.max_pdu_size);
chan->mps = le16_to_cpu(rfc.max_pdu_size);
if (test_bit(FLAG_EXT_CTRL, &chan->flags))
chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
else
chan->ack_win = min_t(u16, chan->ack_win,
rfc.txwin_size);
break;
case L2CAP_MODE_STREAMING:
chan->mps = le16_to_cpu(rfc.max_pdu_size);
@ -3949,7 +3958,7 @@ static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
psm = le16_to_cpu(req->psm);
scid = le16_to_cpu(req->scid);
BT_DBG("psm %d, scid %d, amp_id %d", psm, scid, req->amp_id);
BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id);
/* Placeholder: Always reject */
rsp.dcid = 0;
@ -3972,11 +3981,11 @@ static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
}
static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
u16 icid, u16 result)
u16 icid, u16 result)
{
struct l2cap_move_chan_rsp rsp;
BT_DBG("icid %d, result %d", icid, result);
BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
rsp.icid = cpu_to_le16(icid);
rsp.result = cpu_to_le16(result);
@ -3985,12 +3994,13 @@ static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
}
static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn,
struct l2cap_chan *chan, u16 icid, u16 result)
struct l2cap_chan *chan,
u16 icid, u16 result)
{
struct l2cap_move_chan_cfm cfm;
u8 ident;
BT_DBG("icid %d, result %d", icid, result);
BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
ident = l2cap_get_ident(conn);
if (chan)
@ -4003,18 +4013,19 @@ static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn,
}
static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
u16 icid)
u16 icid)
{
struct l2cap_move_chan_cfm_rsp rsp;
BT_DBG("icid %d", icid);
BT_DBG("icid 0x%4.4x", icid);
rsp.icid = cpu_to_le16(icid);
l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
}
static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
struct l2cap_cmd_hdr *cmd,
u16 cmd_len, void *data)
{
struct l2cap_move_chan_req *req = data;
u16 icid = 0;
@ -4025,7 +4036,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
icid = le16_to_cpu(req->icid);
BT_DBG("icid %d, dest_amp_id %d", icid, req->dest_amp_id);
BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
if (!enable_hs)
return -EINVAL;
@ -4037,7 +4048,8 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
}
static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
struct l2cap_cmd_hdr *cmd,
u16 cmd_len, void *data)
{
struct l2cap_move_chan_rsp *rsp = data;
u16 icid, result;
@ -4048,7 +4060,7 @@ static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
icid = le16_to_cpu(rsp->icid);
result = le16_to_cpu(rsp->result);
BT_DBG("icid %d, result %d", icid, result);
BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
/* Placeholder: Always unconfirmed */
l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED);
@ -4057,7 +4069,8 @@ static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
}
static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
struct l2cap_cmd_hdr *cmd,
u16 cmd_len, void *data)
{
struct l2cap_move_chan_cfm *cfm = data;
u16 icid, result;
@ -4068,7 +4081,7 @@ static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
icid = le16_to_cpu(cfm->icid);
result = le16_to_cpu(cfm->result);
BT_DBG("icid %d, result %d", icid, result);
BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
@ -4076,7 +4089,8 @@ static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
}
static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
struct l2cap_cmd_hdr *cmd,
u16 cmd_len, void *data)
{
struct l2cap_move_chan_cfm_rsp *rsp = data;
u16 icid;
@ -4086,7 +4100,7 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
icid = le16_to_cpu(rsp->icid);
BT_DBG("icid %d", icid);
BT_DBG("icid 0x%4.4x", icid);
return 0;
}
@ -5374,7 +5388,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
if (!conn)
return 0;
BT_DBG("conn %p", conn);
BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
if (hcon->type == LE_LINK) {
if (!status && encrypt)
@ -5387,7 +5401,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
list_for_each_entry(chan, &conn->chan_l, list) {
l2cap_chan_lock(chan);
BT_DBG("chan->scid %d", chan->scid);
BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
state_to_string(chan->state));
if (chan->scid == L2CAP_CID_LE_DATA) {
if (!status && encrypt) {

View File

@ -210,7 +210,7 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status);
skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC);
skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_KERNEL);
if (!skb)
return -ENOMEM;
@ -241,7 +241,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
BT_DBG("sock %p", sk);
skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_ATOMIC);
skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_KERNEL);
if (!skb)
return -ENOMEM;
@ -687,14 +687,14 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
{
struct pending_cmd *cmd;
cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
if (!cmd)
return NULL;
cmd->opcode = opcode;
cmd->index = hdev->id;
cmd->param = kmalloc(len, GFP_ATOMIC);
cmd->param = kmalloc(len, GFP_KERNEL);
if (!cmd->param) {
kfree(cmd);
return NULL;
@ -812,7 +812,7 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len,
struct sk_buff *skb;
struct mgmt_hdr *hdr;
skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC);
skb = alloc_skb(sizeof(*hdr) + data_len, GFP_KERNEL);
if (!skb)
return -ENOMEM;
@ -1268,7 +1268,7 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
goto failed;
}
uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC);
uuid = kmalloc(sizeof(*uuid), GFP_KERNEL);
if (!uuid) {
err = -ENOMEM;
goto failed;
@ -1611,7 +1611,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
}
dc.handle = cpu_to_le16(conn->handle);
dc.reason = 0x13; /* Remote User Terminated Connection */
dc.reason = HCI_ERROR_REMOTE_USER_TERM;
err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc);
if (err < 0)
@ -1667,7 +1667,7 @@ static int get_connections(struct sock *sk, struct hci_dev *hdev, void *data,
}
rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info));
rp = kmalloc(rp_len, GFP_ATOMIC);
rp = kmalloc(rp_len, GFP_KERNEL);
if (!rp) {
err = -ENOMEM;
goto unlock;
@ -1778,29 +1778,6 @@ failed:
return err;
}
static int pin_code_neg_reply(struct sock *sk, struct hci_dev *hdev,
void *data, u16 len)
{
struct mgmt_cp_pin_code_neg_reply *cp = data;
int err;
BT_DBG("");
hci_dev_lock(hdev);
if (!hdev_is_powered(hdev)) {
err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY,
MGMT_STATUS_NOT_POWERED);
goto failed;
}
err = send_pin_code_neg_reply(sk, hdev, cp);
failed:
hci_dev_unlock(hdev);
return err;
}
static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data,
u16 len)
{
@ -2083,6 +2060,18 @@ done:
return err;
}
static int pin_code_neg_reply(struct sock *sk, struct hci_dev *hdev,
void *data, u16 len)
{
struct mgmt_cp_pin_code_neg_reply *cp = data;
BT_DBG("");
return user_pairing_resp(sk, hdev, &cp->addr.bdaddr, cp->addr.type,
MGMT_OP_PIN_CODE_NEG_REPLY,
HCI_OP_PIN_CODE_NEG_REPLY, 0);
}
static int user_confirm_reply(struct sock *sk, struct hci_dev *hdev, void *data,
u16 len)
{
@ -2607,8 +2596,8 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
if (cp->val) {
type = PAGE_SCAN_TYPE_INTERLACED;
/* 22.5 msec page scan interval */
acp.interval = __constant_cpu_to_le16(0x0024);
/* 160 msec page scan interval */
acp.interval = __constant_cpu_to_le16(0x0100);
} else {
type = PAGE_SCAN_TYPE_STANDARD; /* default */
@ -3546,9 +3535,9 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
ev->addr.type = link_to_bdaddr(link_type, addr_type);
ev->rssi = rssi;
if (cfm_name)
ev->flags[0] |= MGMT_DEV_FOUND_CONFIRM_NAME;
ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME);
if (!ssp)
ev->flags[0] |= MGMT_DEV_FOUND_LEGACY_PAIRING;
ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING);
if (eir_len > 0)
memcpy(ev->eir, eir, eir_len);
@ -3558,7 +3547,6 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
dev_class, 3);
ev->eir_len = cpu_to_le16(eir_len);
ev_size = sizeof(*ev) + eir_len;
return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL);