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:
commit
f5004a14fa
9 changed files with 372 additions and 40 deletions
|
@ -173,3 +173,5 @@ MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
|
|||
MODULE_DESCRIPTION("Bluetooth support for Intel devices ver " VERSION);
|
||||
MODULE_VERSION(VERSION);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_FIRMWARE("intel/ibt-11-5.sfi");
|
||||
MODULE_FIRMWARE("intel/ibt-11-5.ddc");
|
||||
|
|
|
@ -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
|
||||
after 5 min*/
|
||||
dev_coredumpv(&priv->btmrvl_dev.hcidev->dev, fw_dump_data,
|
||||
fw_dump_len, GFP_KERNEL);
|
||||
dev_coredumpv(&card->func->dev, fw_dump_data, fw_dump_len, GFP_KERNEL);
|
||||
BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump end");
|
||||
}
|
||||
|
||||
|
|
|
@ -1581,7 +1581,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
|
|||
|
||||
/* 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.
|
||||
* 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) {
|
||||
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;
|
||||
|
||||
/* 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
|
||||
* contains proper Intel_NOP commands to align the fragments
|
||||
* as needed.
|
||||
|
|
|
@ -66,7 +66,7 @@ struct bcm_data {
|
|||
};
|
||||
|
||||
/* 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 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;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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)
|
||||
clk_enable(dev->clk);
|
||||
|
||||
gpiod_set_value_cansleep(dev->shutdown, powered);
|
||||
gpiod_set_value_cansleep(dev->device_wakeup, powered);
|
||||
gpiod_set_value(dev->shutdown, powered);
|
||||
gpiod_set_value(dev->device_wakeup, powered);
|
||||
|
||||
if (!powered && !IS_ERR(dev->clk) && dev->clk_enabled)
|
||||
clk_disable(dev->clk);
|
||||
|
@ -164,7 +164,7 @@ static int bcm_open(struct hci_uart *hu)
|
|||
|
||||
hu->priv = bcm;
|
||||
|
||||
spin_lock(&bcm_device_list_lock);
|
||||
spin_lock(&bcm_device_lock);
|
||||
list_for_each(p, &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)
|
||||
bcm_gpio_set_power(bcm->dev, true);
|
||||
|
||||
spin_unlock(&bcm_device_list_lock);
|
||||
spin_unlock(&bcm_device_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -197,14 +197,14 @@ static int bcm_close(struct hci_uart *hu)
|
|||
BT_DBG("hu %p", hu);
|
||||
|
||||
/* 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)) {
|
||||
bcm_gpio_set_power(bcm->dev, false);
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
bcm->dev->hu = NULL;
|
||||
#endif
|
||||
}
|
||||
spin_unlock(&bcm_device_list_lock);
|
||||
spin_unlock(&bcm_device_lock);
|
||||
|
||||
skb_queue_purge(&bcm->txq);
|
||||
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);
|
||||
|
||||
spin_lock(&bcm_device_lock);
|
||||
|
||||
if (!bdev->hu)
|
||||
goto unlock;
|
||||
|
||||
if (!bdev->is_suspended) {
|
||||
hci_uart_set_flow_control(bdev->hu, true);
|
||||
|
||||
|
@ -352,6 +357,9 @@ static int bcm_suspend(struct device *dev)
|
|||
mdelay(15);
|
||||
}
|
||||
|
||||
unlock:
|
||||
spin_unlock(&bcm_device_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -362,6 +370,11 @@ static int bcm_resume(struct device *dev)
|
|||
|
||||
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) {
|
||||
gpiod_set_value(bdev->device_wakeup, true);
|
||||
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);
|
||||
}
|
||||
|
||||
unlock:
|
||||
spin_unlock(&bcm_device_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -488,9 +504,9 @@ static int bcm_probe(struct platform_device *pdev)
|
|||
dev_info(&pdev->dev, "%s device registered.\n", dev->name);
|
||||
|
||||
/* 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);
|
||||
spin_unlock(&bcm_device_list_lock);
|
||||
spin_unlock(&bcm_device_lock);
|
||||
|
||||
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);
|
||||
|
||||
spin_lock(&bcm_device_list_lock);
|
||||
spin_lock(&bcm_device_lock);
|
||||
list_del(&dev->list);
|
||||
spin_unlock(&bcm_device_list_lock);
|
||||
spin_unlock(&bcm_device_lock);
|
||||
|
||||
acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev));
|
||||
|
||||
|
|
|
@ -223,8 +223,7 @@ struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb,
|
|||
switch ((&pkts[i])->lsize) {
|
||||
case 0:
|
||||
/* No variable data length */
|
||||
(&pkts[i])->recv(hdev, skb);
|
||||
skb = NULL;
|
||||
dlen = 0;
|
||||
break;
|
||||
case 1:
|
||||
/* 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);
|
||||
return ERR_PTR(-EILSEQ);
|
||||
}
|
||||
|
||||
if (!dlen) {
|
||||
/* No more data, complete frame */
|
||||
(&pkts[i])->recv(hdev, skb);
|
||||
skb = NULL;
|
||||
}
|
||||
} else {
|
||||
/* Complete frame */
|
||||
(&pkts[i])->recv(hdev, skb);
|
||||
|
|
|
@ -25,7 +25,12 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/module.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/hci_core.h>
|
||||
|
@ -39,12 +44,108 @@
|
|||
#define STATE_FIRMWARE_FAILED 3
|
||||
#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 sk_buff *rx_skb;
|
||||
struct sk_buff_head txq;
|
||||
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)
|
||||
{
|
||||
struct intel_data *intel;
|
||||
|
@ -58,6 +159,10 @@ static int intel_open(struct hci_uart *hu)
|
|||
skb_queue_head_init(&intel->txq);
|
||||
|
||||
hu->priv = intel;
|
||||
|
||||
if (!intel_set_power(hu, true))
|
||||
set_bit(STATE_BOOTING, &intel->flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -67,6 +172,8 @@ static int intel_close(struct hci_uart *hu)
|
|||
|
||||
BT_DBG("hu %p", hu);
|
||||
|
||||
intel_set_power(hu, false);
|
||||
|
||||
skb_queue_purge(&intel->txq);
|
||||
kfree_skb(intel->rx_skb);
|
||||
kfree(intel);
|
||||
|
@ -111,6 +218,68 @@ static int inject_cmd_complete(struct hci_dev *hdev, __u16 opcode)
|
|||
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 const u8 reset_param[] = { 0x00, 0x01, 0x00, 0x01,
|
||||
|
@ -126,6 +295,8 @@ static int intel_setup(struct hci_uart *hu)
|
|||
u32 frag_len;
|
||||
ktime_t calltime, delta, rettime;
|
||||
unsigned long long duration;
|
||||
unsigned int init_speed, oper_speed;
|
||||
int speed_change = 0;
|
||||
int err;
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
@ -134,6 +305,28 @@ static int intel_setup(struct hci_uart *hu)
|
|||
|
||||
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);
|
||||
|
||||
/* 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)
|
||||
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();
|
||||
|
||||
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);
|
||||
|
||||
err = wait_on_bit_timeout(&intel->flags, STATE_BOOTING,
|
||||
TASK_INTERRUPTIBLE,
|
||||
msecs_to_jiffies(1000));
|
||||
err = intel_wait_booting(hu);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (err == 1) {
|
||||
BT_ERR("%s: Device boot interrupted", hdev->name);
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
BT_ERR("%s: Device boot timeout", hdev->name);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
clear_bit(STATE_BOOTING, &intel->flags);
|
||||
|
||||
rettime = ktime_get();
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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 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;
|
||||
|
||||
hdr = (void *)skb->data;
|
||||
|
@ -572,21 +778,110 @@ static const struct hci_uart_proto intel_proto = {
|
|||
.id = HCI_UART_INTEL,
|
||||
.name = "Intel",
|
||||
.init_speed = 115200,
|
||||
.oper_speed = 3000000,
|
||||
.open = intel_open,
|
||||
.close = intel_close,
|
||||
.flush = intel_flush,
|
||||
.setup = intel_setup,
|
||||
.set_baudrate = intel_set_baudrate,
|
||||
.recv = intel_recv,
|
||||
.enqueue = intel_enqueue,
|
||||
.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)
|
||||
{
|
||||
platform_driver_register(&intel_driver);
|
||||
|
||||
return hci_uart_register_proto(&intel_proto);
|
||||
}
|
||||
|
||||
int __exit intel_deinit(void)
|
||||
{
|
||||
platform_driver_unregister(&intel_driver);
|
||||
|
||||
return hci_uart_unregister_proto(&intel_proto);
|
||||
}
|
||||
|
|
|
@ -3726,17 +3726,25 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
|
|||
if (ev->link_type == ESCO_LINK)
|
||||
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);
|
||||
if (!conn)
|
||||
goto unlock;
|
||||
|
||||
conn->type = SCO_LINK;
|
||||
}
|
||||
|
||||
switch (ev->status) {
|
||||
case 0x00:
|
||||
conn->handle = __le16_to_cpu(ev->handle);
|
||||
conn->state = BT_CONNECTED;
|
||||
conn->type = ev->link_type;
|
||||
|
||||
hci_debugfs_create_conn(conn);
|
||||
hci_conn_add_sysfs(conn);
|
||||
|
|
|
@ -154,13 +154,13 @@ static void sco_chan_del(struct sock *sk, int err)
|
|||
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 sock *sk;
|
||||
|
||||
if (!conn)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
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;
|
||||
kfree(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
|
||||
|
|
|
@ -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 net_device *dev = info->user_ptr[1];
|
||||
struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
|
||||
bool mode;
|
||||
int mode;
|
||||
|
||||
if (netif_running(dev))
|
||||
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])
|
||||
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))
|
||||
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 net_device *dev = info->user_ptr[1];
|
||||
struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
|
||||
bool ackreq;
|
||||
int ackreq;
|
||||
|
||||
if (netif_running(dev))
|
||||
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])
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue