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

Johan Hedberg says:

====================
pull request: bluetooth-next 2015-08-28

One more bunch of Bluetooth patches for 4.3:

 - Crash fix for hci_bcm driver
 - Enhancements to hci_intel driver (e.g. baudrate configuration)
 - Fix for SCO link type after multiple connect attempts
 - Cleanups & minor fixes in a few other places

Please let me know if there are any issues pulling. Thanks.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2015-08-29 13:15:03 -07:00
commit f5004a14fa
9 changed files with 372 additions and 40 deletions

View File

@ -173,3 +173,5 @@ MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth support for Intel devices ver " VERSION); MODULE_DESCRIPTION("Bluetooth support for Intel devices ver " VERSION);
MODULE_VERSION(VERSION); MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_FIRMWARE("intel/ibt-11-5.sfi");
MODULE_FIRMWARE("intel/ibt-11-5.ddc");

View File

@ -1376,8 +1376,7 @@ static void btmrvl_sdio_dump_firmware(struct btmrvl_private *priv)
/* fw_dump_data will be free in device coredump release function /* fw_dump_data will be free in device coredump release function
after 5 min*/ after 5 min*/
dev_coredumpv(&priv->btmrvl_dev.hcidev->dev, fw_dump_data, dev_coredumpv(&card->func->dev, fw_dump_data, fw_dump_len, GFP_KERNEL);
fw_dump_len, GFP_KERNEL);
BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump end"); BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump end");
} }

View File

@ -1581,7 +1581,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
/* fw_patch_num indicates the version of patch the device currently /* fw_patch_num indicates the version of patch the device currently
* have. If there is no patch data in the device, it is always 0x00. * have. If there is no patch data in the device, it is always 0x00.
* So, if it is other than 0x00, no need to patch the deivce again. * So, if it is other than 0x00, no need to patch the device again.
*/ */
if (ver->fw_patch_num) { if (ver->fw_patch_num) {
BT_INFO("%s: Intel device is already patched. patch num: %02x", BT_INFO("%s: Intel device is already patched. patch num: %02x",
@ -2100,7 +2100,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
frag_len += sizeof(*cmd) + cmd->plen; frag_len += sizeof(*cmd) + cmd->plen;
/* The paramter length of the secure send command requires /* The parameter length of the secure send command requires
* a 4 byte alignment. It happens so that the firmware file * a 4 byte alignment. It happens so that the firmware file
* contains proper Intel_NOP commands to align the fragments * contains proper Intel_NOP commands to align the fragments
* as needed. * as needed.

View File

@ -66,7 +66,7 @@ struct bcm_data {
}; };
/* List of BCM BT UART devices */ /* List of BCM BT UART devices */
static DEFINE_SPINLOCK(bcm_device_list_lock); static DEFINE_SPINLOCK(bcm_device_lock);
static LIST_HEAD(bcm_device_list); static LIST_HEAD(bcm_device_list);
static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed) static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed)
@ -118,7 +118,7 @@ static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed)
return 0; return 0;
} }
/* bcm_device_exists should be protected by bcm_device_list_lock */ /* bcm_device_exists should be protected by bcm_device_lock */
static bool bcm_device_exists(struct bcm_device *device) static bool bcm_device_exists(struct bcm_device *device)
{ {
struct list_head *p; struct list_head *p;
@ -138,8 +138,8 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered)
if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled) if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled)
clk_enable(dev->clk); clk_enable(dev->clk);
gpiod_set_value_cansleep(dev->shutdown, powered); gpiod_set_value(dev->shutdown, powered);
gpiod_set_value_cansleep(dev->device_wakeup, powered); gpiod_set_value(dev->device_wakeup, powered);
if (!powered && !IS_ERR(dev->clk) && dev->clk_enabled) if (!powered && !IS_ERR(dev->clk) && dev->clk_enabled)
clk_disable(dev->clk); clk_disable(dev->clk);
@ -164,7 +164,7 @@ static int bcm_open(struct hci_uart *hu)
hu->priv = bcm; hu->priv = bcm;
spin_lock(&bcm_device_list_lock); spin_lock(&bcm_device_lock);
list_for_each(p, &bcm_device_list) { list_for_each(p, &bcm_device_list) {
struct bcm_device *dev = list_entry(p, struct bcm_device, list); struct bcm_device *dev = list_entry(p, struct bcm_device, list);
@ -185,7 +185,7 @@ static int bcm_open(struct hci_uart *hu)
if (bcm->dev) if (bcm->dev)
bcm_gpio_set_power(bcm->dev, true); bcm_gpio_set_power(bcm->dev, true);
spin_unlock(&bcm_device_list_lock); spin_unlock(&bcm_device_lock);
return 0; return 0;
} }
@ -197,14 +197,14 @@ static int bcm_close(struct hci_uart *hu)
BT_DBG("hu %p", hu); BT_DBG("hu %p", hu);
/* Protect bcm->dev against removal of the device or driver */ /* Protect bcm->dev against removal of the device or driver */
spin_lock(&bcm_device_list_lock); spin_lock(&bcm_device_lock);
if (bcm_device_exists(bcm->dev)) { if (bcm_device_exists(bcm->dev)) {
bcm_gpio_set_power(bcm->dev, false); bcm_gpio_set_power(bcm->dev, false);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
bcm->dev->hu = NULL; bcm->dev->hu = NULL;
#endif #endif
} }
spin_unlock(&bcm_device_list_lock); spin_unlock(&bcm_device_lock);
skb_queue_purge(&bcm->txq); skb_queue_purge(&bcm->txq);
kfree_skb(bcm->rx_skb); kfree_skb(bcm->rx_skb);
@ -338,6 +338,11 @@ static int bcm_suspend(struct device *dev)
BT_DBG("suspend (%p): is_suspended %d", bdev, bdev->is_suspended); BT_DBG("suspend (%p): is_suspended %d", bdev, bdev->is_suspended);
spin_lock(&bcm_device_lock);
if (!bdev->hu)
goto unlock;
if (!bdev->is_suspended) { if (!bdev->is_suspended) {
hci_uart_set_flow_control(bdev->hu, true); hci_uart_set_flow_control(bdev->hu, true);
@ -352,6 +357,9 @@ static int bcm_suspend(struct device *dev)
mdelay(15); mdelay(15);
} }
unlock:
spin_unlock(&bcm_device_lock);
return 0; return 0;
} }
@ -362,6 +370,11 @@ static int bcm_resume(struct device *dev)
BT_DBG("resume (%p): is_suspended %d", bdev, bdev->is_suspended); BT_DBG("resume (%p): is_suspended %d", bdev, bdev->is_suspended);
spin_lock(&bcm_device_lock);
if (!bdev->hu)
goto unlock;
if (bdev->device_wakeup) { if (bdev->device_wakeup) {
gpiod_set_value(bdev->device_wakeup, true); gpiod_set_value(bdev->device_wakeup, true);
BT_DBG("resume, delaying 15 ms"); BT_DBG("resume, delaying 15 ms");
@ -375,6 +388,9 @@ static int bcm_resume(struct device *dev)
hci_uart_set_flow_control(bdev->hu, false); hci_uart_set_flow_control(bdev->hu, false);
} }
unlock:
spin_unlock(&bcm_device_lock);
return 0; return 0;
} }
#endif #endif
@ -488,9 +504,9 @@ static int bcm_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "%s device registered.\n", dev->name); dev_info(&pdev->dev, "%s device registered.\n", dev->name);
/* Place this instance on the device list */ /* Place this instance on the device list */
spin_lock(&bcm_device_list_lock); spin_lock(&bcm_device_lock);
list_add_tail(&dev->list, &bcm_device_list); list_add_tail(&dev->list, &bcm_device_list);
spin_unlock(&bcm_device_list_lock); spin_unlock(&bcm_device_lock);
bcm_gpio_set_power(dev, false); bcm_gpio_set_power(dev, false);
@ -501,9 +517,9 @@ static int bcm_remove(struct platform_device *pdev)
{ {
struct bcm_device *dev = platform_get_drvdata(pdev); struct bcm_device *dev = platform_get_drvdata(pdev);
spin_lock(&bcm_device_list_lock); spin_lock(&bcm_device_lock);
list_del(&dev->list); list_del(&dev->list);
spin_unlock(&bcm_device_list_lock); spin_unlock(&bcm_device_lock);
acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev)); acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev));

View File

@ -223,8 +223,7 @@ struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb,
switch ((&pkts[i])->lsize) { switch ((&pkts[i])->lsize) {
case 0: case 0:
/* No variable data length */ /* No variable data length */
(&pkts[i])->recv(hdev, skb); dlen = 0;
skb = NULL;
break; break;
case 1: case 1:
/* Single octet variable length */ /* Single octet variable length */
@ -252,6 +251,12 @@ struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb,
kfree_skb(skb); kfree_skb(skb);
return ERR_PTR(-EILSEQ); return ERR_PTR(-EILSEQ);
} }
if (!dlen) {
/* No more data, complete frame */
(&pkts[i])->recv(hdev, skb);
skb = NULL;
}
} else { } else {
/* Complete frame */ /* Complete frame */
(&pkts[i])->recv(hdev, skb); (&pkts[i])->recv(hdev, skb);

View File

@ -25,7 +25,12 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/module.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/tty.h>
#include <linux/platform_device.h>
#include <linux/gpio/consumer.h>
#include <linux/acpi.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
@ -39,12 +44,108 @@
#define STATE_FIRMWARE_FAILED 3 #define STATE_FIRMWARE_FAILED 3
#define STATE_BOOTING 4 #define STATE_BOOTING 4
struct intel_device {
struct list_head list;
struct platform_device *pdev;
struct gpio_desc *reset;
};
static LIST_HEAD(intel_device_list);
static DEFINE_SPINLOCK(intel_device_list_lock);
struct intel_data { struct intel_data {
struct sk_buff *rx_skb; struct sk_buff *rx_skb;
struct sk_buff_head txq; struct sk_buff_head txq;
unsigned long flags; unsigned long flags;
}; };
static u8 intel_convert_speed(unsigned int speed)
{
switch (speed) {
case 9600:
return 0x00;
case 19200:
return 0x01;
case 38400:
return 0x02;
case 57600:
return 0x03;
case 115200:
return 0x04;
case 230400:
return 0x05;
case 460800:
return 0x06;
case 921600:
return 0x07;
case 1843200:
return 0x08;
case 3250000:
return 0x09;
case 2000000:
return 0x0a;
case 3000000:
return 0x0b;
default:
return 0xff;
}
}
static int intel_wait_booting(struct hci_uart *hu)
{
struct intel_data *intel = hu->priv;
int err;
err = wait_on_bit_timeout(&intel->flags, STATE_BOOTING,
TASK_INTERRUPTIBLE,
msecs_to_jiffies(1000));
if (err == 1) {
BT_ERR("%s: Device boot interrupted", hu->hdev->name);
return -EINTR;
}
if (err) {
BT_ERR("%s: Device boot timeout", hu->hdev->name);
return -ETIMEDOUT;
}
return err;
}
static int intel_set_power(struct hci_uart *hu, bool powered)
{
struct list_head *p;
int err = -ENODEV;
spin_lock(&intel_device_list_lock);
list_for_each(p, &intel_device_list) {
struct intel_device *idev = list_entry(p, struct intel_device,
list);
/* tty device and pdev device should share the same parent
* which is the UART port.
*/
if (hu->tty->dev->parent != idev->pdev->dev.parent)
continue;
if (!idev->reset) {
err = -ENOTSUPP;
break;
}
BT_INFO("hu %p, Switching compatible pm device (%s) to %u",
hu, dev_name(&idev->pdev->dev), powered);
gpiod_set_value(idev->reset, powered);
}
spin_unlock(&intel_device_list_lock);
return err;
}
static int intel_open(struct hci_uart *hu) static int intel_open(struct hci_uart *hu)
{ {
struct intel_data *intel; struct intel_data *intel;
@ -58,6 +159,10 @@ static int intel_open(struct hci_uart *hu)
skb_queue_head_init(&intel->txq); skb_queue_head_init(&intel->txq);
hu->priv = intel; hu->priv = intel;
if (!intel_set_power(hu, true))
set_bit(STATE_BOOTING, &intel->flags);
return 0; return 0;
} }
@ -67,6 +172,8 @@ static int intel_close(struct hci_uart *hu)
BT_DBG("hu %p", hu); BT_DBG("hu %p", hu);
intel_set_power(hu, false);
skb_queue_purge(&intel->txq); skb_queue_purge(&intel->txq);
kfree_skb(intel->rx_skb); kfree_skb(intel->rx_skb);
kfree(intel); kfree(intel);
@ -111,6 +218,68 @@ static int inject_cmd_complete(struct hci_dev *hdev, __u16 opcode)
return hci_recv_frame(hdev, skb); return hci_recv_frame(hdev, skb);
} }
static int intel_set_baudrate(struct hci_uart *hu, unsigned int speed)
{
struct intel_data *intel = hu->priv;
struct hci_dev *hdev = hu->hdev;
u8 speed_cmd[] = { 0x06, 0xfc, 0x01, 0x00 };
struct sk_buff *skb;
int err;
/* This can be the first command sent to the chip, check
* that the controller is ready.
*/
err = intel_wait_booting(hu);
clear_bit(STATE_BOOTING, &intel->flags);
/* In case of timeout, try to continue anyway */
if (err && err != ETIMEDOUT)
return err;
BT_INFO("%s: Change controller speed to %d", hdev->name, speed);
speed_cmd[3] = intel_convert_speed(speed);
if (speed_cmd[3] == 0xff) {
BT_ERR("%s: Unsupported speed", hdev->name);
return -EINVAL;
}
/* Device will not accept speed change if Intel version has not been
* previously requested.
*/
skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
if (IS_ERR(skb)) {
BT_ERR("%s: Reading Intel version information failed (%ld)",
hdev->name, PTR_ERR(skb));
return PTR_ERR(skb);
}
kfree_skb(skb);
skb = bt_skb_alloc(sizeof(speed_cmd), GFP_KERNEL);
if (!skb) {
BT_ERR("%s: Failed to allocate memory for baudrate packet",
hdev->name);
return -ENOMEM;
}
memcpy(skb_put(skb, sizeof(speed_cmd)), speed_cmd, sizeof(speed_cmd));
bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
hci_uart_set_flow_control(hu, true);
skb_queue_tail(&intel->txq, skb);
hci_uart_tx_wakeup(hu);
/* wait 100ms to change baudrate on controller side */
msleep(100);
hci_uart_set_baudrate(hu, speed);
hci_uart_set_flow_control(hu, false);
return 0;
}
static int intel_setup(struct hci_uart *hu) static int intel_setup(struct hci_uart *hu)
{ {
static const u8 reset_param[] = { 0x00, 0x01, 0x00, 0x01, static const u8 reset_param[] = { 0x00, 0x01, 0x00, 0x01,
@ -126,6 +295,8 @@ static int intel_setup(struct hci_uart *hu)
u32 frag_len; u32 frag_len;
ktime_t calltime, delta, rettime; ktime_t calltime, delta, rettime;
unsigned long long duration; unsigned long long duration;
unsigned int init_speed, oper_speed;
int speed_change = 0;
int err; int err;
BT_DBG("%s", hdev->name); BT_DBG("%s", hdev->name);
@ -134,6 +305,28 @@ static int intel_setup(struct hci_uart *hu)
calltime = ktime_get(); calltime = ktime_get();
if (hu->init_speed)
init_speed = hu->init_speed;
else
init_speed = hu->proto->init_speed;
if (hu->oper_speed)
oper_speed = hu->oper_speed;
else
oper_speed = hu->proto->oper_speed;
if (oper_speed && init_speed && oper_speed != init_speed)
speed_change = 1;
/* Check that the controller is ready */
err = intel_wait_booting(hu);
clear_bit(STATE_BOOTING, &intel->flags);
/* In case of timeout, try to continue anyway */
if (err && err != ETIMEDOUT)
return err;
set_bit(STATE_BOOTLOADER, &intel->flags); set_bit(STATE_BOOTLOADER, &intel->flags);
/* Read the Intel version information to determine if the device /* Read the Intel version information to determine if the device
@ -416,6 +609,13 @@ static int intel_setup(struct hci_uart *hu)
if (err < 0) if (err < 0)
return err; return err;
/* We need to restore the default speed before Intel reset */
if (speed_change) {
err = intel_set_baudrate(hu, init_speed);
if (err)
return err;
}
calltime = ktime_get(); calltime = ktime_get();
set_bit(STATE_BOOTING, &intel->flags); set_bit(STATE_BOOTING, &intel->flags);
@ -436,19 +636,11 @@ static int intel_setup(struct hci_uart *hu)
*/ */
BT_INFO("%s: Waiting for device to boot", hdev->name); BT_INFO("%s: Waiting for device to boot", hdev->name);
err = wait_on_bit_timeout(&intel->flags, STATE_BOOTING, err = intel_wait_booting(hu);
TASK_INTERRUPTIBLE, if (err)
msecs_to_jiffies(1000)); return err;
if (err == 1) { clear_bit(STATE_BOOTING, &intel->flags);
BT_ERR("%s: Device boot interrupted", hdev->name);
return -EINTR;
}
if (err) {
BT_ERR("%s: Device boot timeout", hdev->name);
return -ETIMEDOUT;
}
rettime = ktime_get(); rettime = ktime_get();
delta = ktime_sub(rettime, calltime); delta = ktime_sub(rettime, calltime);
@ -456,6 +648,19 @@ static int intel_setup(struct hci_uart *hu)
BT_INFO("%s: Device booted in %llu usecs", hdev->name, duration); BT_INFO("%s: Device booted in %llu usecs", hdev->name, duration);
skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_CMD_TIMEOUT);
if (IS_ERR(skb))
return PTR_ERR(skb);
kfree_skb(skb);
if (speed_change) {
err = intel_set_baudrate(hu, oper_speed);
if (err)
return err;
}
BT_INFO("%s: Setup complete", hdev->name);
clear_bit(STATE_BOOTLOADER, &intel->flags); clear_bit(STATE_BOOTLOADER, &intel->flags);
return 0; return 0;
@ -467,7 +672,8 @@ static int intel_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
struct intel_data *intel = hu->priv; struct intel_data *intel = hu->priv;
struct hci_event_hdr *hdr; struct hci_event_hdr *hdr;
if (!test_bit(STATE_BOOTLOADER, &intel->flags)) if (!test_bit(STATE_BOOTLOADER, &intel->flags) &&
!test_bit(STATE_BOOTING, &intel->flags))
goto recv; goto recv;
hdr = (void *)skb->data; hdr = (void *)skb->data;
@ -572,21 +778,110 @@ static const struct hci_uart_proto intel_proto = {
.id = HCI_UART_INTEL, .id = HCI_UART_INTEL,
.name = "Intel", .name = "Intel",
.init_speed = 115200, .init_speed = 115200,
.oper_speed = 3000000,
.open = intel_open, .open = intel_open,
.close = intel_close, .close = intel_close,
.flush = intel_flush, .flush = intel_flush,
.setup = intel_setup, .setup = intel_setup,
.set_baudrate = intel_set_baudrate,
.recv = intel_recv, .recv = intel_recv,
.enqueue = intel_enqueue, .enqueue = intel_enqueue,
.dequeue = intel_dequeue, .dequeue = intel_dequeue,
}; };
#ifdef CONFIG_ACPI
static const struct acpi_device_id intel_acpi_match[] = {
{ "INT33E1", 0 },
{ },
};
MODULE_DEVICE_TABLE(acpi, intel_acpi_match);
static int intel_acpi_probe(struct intel_device *idev)
{
const struct acpi_device_id *id;
id = acpi_match_device(intel_acpi_match, &idev->pdev->dev);
if (!id)
return -ENODEV;
return 0;
}
#else
static int intel_acpi_probe(struct intel_device *idev)
{
return -ENODEV;
}
#endif
static int intel_probe(struct platform_device *pdev)
{
struct intel_device *idev;
idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL);
if (!idev)
return -ENOMEM;
idev->pdev = pdev;
if (ACPI_HANDLE(&pdev->dev)) {
int err = intel_acpi_probe(idev);
if (err)
return err;
} else {
return -ENODEV;
}
idev->reset = devm_gpiod_get_optional(&pdev->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(idev->reset)) {
dev_err(&pdev->dev, "Unable to retrieve gpio\n");
return PTR_ERR(idev->reset);
}
platform_set_drvdata(pdev, idev);
/* Place this instance on the device list */
spin_lock(&intel_device_list_lock);
list_add_tail(&idev->list, &intel_device_list);
spin_unlock(&intel_device_list_lock);
dev_info(&pdev->dev, "registered.\n");
return 0;
}
static int intel_remove(struct platform_device *pdev)
{
struct intel_device *idev = platform_get_drvdata(pdev);
spin_lock(&intel_device_list_lock);
list_del(&idev->list);
spin_unlock(&intel_device_list_lock);
dev_info(&pdev->dev, "unregistered.\n");
return 0;
}
static struct platform_driver intel_driver = {
.probe = intel_probe,
.remove = intel_remove,
.driver = {
.name = "hci_intel",
.acpi_match_table = ACPI_PTR(intel_acpi_match),
},
};
int __init intel_init(void) int __init intel_init(void)
{ {
platform_driver_register(&intel_driver);
return hci_uart_register_proto(&intel_proto); return hci_uart_register_proto(&intel_proto);
} }
int __exit intel_deinit(void) int __exit intel_deinit(void)
{ {
platform_driver_unregister(&intel_driver);
return hci_uart_unregister_proto(&intel_proto); return hci_uart_unregister_proto(&intel_proto);
} }

View File

@ -3726,17 +3726,25 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
if (ev->link_type == ESCO_LINK) if (ev->link_type == ESCO_LINK)
goto unlock; goto unlock;
/* When the link type in the event indicates SCO connection
* and lookup of the connection object fails, then check
* if an eSCO connection object exists.
*
* The core limits the synchronous connections to either
* SCO or eSCO. The eSCO connection is preferred and tried
* to be setup first and until successfully established,
* the link type will be hinted as eSCO.
*/
conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
if (!conn) if (!conn)
goto unlock; goto unlock;
conn->type = SCO_LINK;
} }
switch (ev->status) { switch (ev->status) {
case 0x00: case 0x00:
conn->handle = __le16_to_cpu(ev->handle); conn->handle = __le16_to_cpu(ev->handle);
conn->state = BT_CONNECTED; conn->state = BT_CONNECTED;
conn->type = ev->link_type;
hci_debugfs_create_conn(conn); hci_debugfs_create_conn(conn);
hci_conn_add_sysfs(conn); hci_conn_add_sysfs(conn);

View File

@ -154,13 +154,13 @@ static void sco_chan_del(struct sock *sk, int err)
sock_set_flag(sk, SOCK_ZAPPED); sock_set_flag(sk, SOCK_ZAPPED);
} }
static int sco_conn_del(struct hci_conn *hcon, int err) static void sco_conn_del(struct hci_conn *hcon, int err)
{ {
struct sco_conn *conn = hcon->sco_data; struct sco_conn *conn = hcon->sco_data;
struct sock *sk; struct sock *sk;
if (!conn) if (!conn)
return 0; return;
BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
@ -179,7 +179,6 @@ static int sco_conn_del(struct hci_conn *hcon, int err)
hcon->sco_data = NULL; hcon->sco_data = NULL;
kfree(conn); kfree(conn);
return 0;
} }
static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent) static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)

View File

@ -1034,7 +1034,7 @@ static int nl802154_set_lbt_mode(struct sk_buff *skb, struct genl_info *info)
struct cfg802154_registered_device *rdev = info->user_ptr[0]; struct cfg802154_registered_device *rdev = info->user_ptr[0];
struct net_device *dev = info->user_ptr[1]; struct net_device *dev = info->user_ptr[1];
struct wpan_dev *wpan_dev = dev->ieee802154_ptr; struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
bool mode; int mode;
if (netif_running(dev)) if (netif_running(dev))
return -EBUSY; return -EBUSY;
@ -1042,7 +1042,11 @@ static int nl802154_set_lbt_mode(struct sk_buff *skb, struct genl_info *info)
if (!info->attrs[NL802154_ATTR_LBT_MODE]) if (!info->attrs[NL802154_ATTR_LBT_MODE])
return -EINVAL; return -EINVAL;
mode = !!nla_get_u8(info->attrs[NL802154_ATTR_LBT_MODE]); mode = nla_get_u8(info->attrs[NL802154_ATTR_LBT_MODE]);
if (mode != 0 && mode != 1)
return -EINVAL;
if (!wpan_phy_supported_bool(mode, rdev->wpan_phy.supported.lbt)) if (!wpan_phy_supported_bool(mode, rdev->wpan_phy.supported.lbt))
return -EINVAL; return -EINVAL;
@ -1055,7 +1059,7 @@ nl802154_set_ackreq_default(struct sk_buff *skb, struct genl_info *info)
struct cfg802154_registered_device *rdev = info->user_ptr[0]; struct cfg802154_registered_device *rdev = info->user_ptr[0];
struct net_device *dev = info->user_ptr[1]; struct net_device *dev = info->user_ptr[1];
struct wpan_dev *wpan_dev = dev->ieee802154_ptr; struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
bool ackreq; int ackreq;
if (netif_running(dev)) if (netif_running(dev))
return -EBUSY; return -EBUSY;
@ -1063,7 +1067,11 @@ nl802154_set_ackreq_default(struct sk_buff *skb, struct genl_info *info)
if (!info->attrs[NL802154_ATTR_ACKREQ_DEFAULT]) if (!info->attrs[NL802154_ATTR_ACKREQ_DEFAULT])
return -EINVAL; return -EINVAL;
ackreq = !!nla_get_u8(info->attrs[NL802154_ATTR_ACKREQ_DEFAULT]); ackreq = nla_get_u8(info->attrs[NL802154_ATTR_ACKREQ_DEFAULT]);
if (ackreq != 0 && ackreq != 1)
return -EINVAL;
return rdev_set_ackreq_default(rdev, wpan_dev, ackreq); return rdev_set_ackreq_default(rdev, wpan_dev, ackreq);
} }