diff options
author | David S. Miller <davem@davemloft.net> | 2015-05-13 14:31:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-05-13 14:31:43 -0400 |
commit | b04096ff33a977c01c8780ca3ee129dbd641bad4 (patch) | |
tree | 8652f27f158984e5aa4c00ddf1a4885a32435f28 /drivers/bluetooth/hci_ath.c | |
parent | 7f460d30c8e130382de1443fdbc4d040a9e062ec (diff) | |
parent | 110bc76729d448fdbcb5cdb63b83d9fd65ce5e26 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Four minor merge conflicts:
1) qca_spi.c renamed the local variable used for the SPI device
from spi_device to spi, meanwhile the spi_set_drvdata() call
got moved further up in the probe function.
2) Two changes were both adding new members to codel params
structure, and thus we had overlapping changes to the
initializer function.
3) 'net' was making a fix to sk_release_kernel() which is
completely removed in 'net-next'.
4) In net_namespace.c, the rtnl_net_fill() call for GET operations
had the command value fixed, meanwhile 'net-next' adjusted the
argument signature a bit.
This also matches example merge resolutions posted by Stephen
Rothwell over the past two days.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/bluetooth/hci_ath.c')
-rw-r--r-- | drivers/bluetooth/hci_ath.c | 98 |
1 files changed, 63 insertions, 35 deletions
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index 1b3f8647ea2f..ec8fa0e0f036 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c @@ -95,7 +95,6 @@ static void ath_hci_uart_work(struct work_struct *work) hci_uart_tx_wakeup(hu); } -/* Initialize protocol */ static int ath_open(struct hci_uart *hu) { struct ath_struct *ath; @@ -116,8 +115,7 @@ static int ath_open(struct hci_uart *hu) return 0; } -/* Flush protocol data */ -static int ath_flush(struct hci_uart *hu) +static int ath_close(struct hci_uart *hu) { struct ath_struct *ath = hu->priv; @@ -125,11 +123,17 @@ static int ath_flush(struct hci_uart *hu) skb_queue_purge(&ath->txq); + kfree_skb(ath->rx_skb); + + cancel_work_sync(&ath->ctxtsw); + + hu->priv = NULL; + kfree(ath); + return 0; } -/* Close protocol */ -static int ath_close(struct hci_uart *hu) +static int ath_flush(struct hci_uart *hu) { struct ath_struct *ath = hu->priv; @@ -137,19 +141,65 @@ static int ath_close(struct hci_uart *hu) skb_queue_purge(&ath->txq); - kfree_skb(ath->rx_skb); + return 0; +} - cancel_work_sync(&ath->ctxtsw); +static int ath_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) +{ + struct sk_buff *skb; + u8 buf[10]; + int err; + + buf[0] = 0x01; + buf[1] = 0x01; + buf[2] = 0x00; + buf[3] = sizeof(bdaddr_t); + memcpy(buf + 4, bdaddr, sizeof(bdaddr_t)); + + skb = __hci_cmd_sync(hdev, 0xfc0b, sizeof(buf), buf, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + BT_ERR("%s: Change address command failed (%d)", + hdev->name, err); + return err; + } + kfree_skb(skb); - hu->priv = NULL; - kfree(ath); + return 0; +} + +static int ath_setup(struct hci_uart *hu) +{ + BT_DBG("hu %p", hu); + + hu->hdev->set_bdaddr = ath_set_bdaddr; return 0; } +static const struct h4_recv_pkt ath_recv_pkts[] = { + { H4_RECV_ACL, .recv = hci_recv_frame }, + { H4_RECV_SCO, .recv = hci_recv_frame }, + { H4_RECV_EVENT, .recv = hci_recv_frame }, +}; + +static int ath_recv(struct hci_uart *hu, const void *data, int count) +{ + struct ath_struct *ath = hu->priv; + + ath->rx_skb = h4_recv_buf(hu->hdev, ath->rx_skb, data, count, + ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts)); + if (IS_ERR(ath->rx_skb)) { + int err = PTR_ERR(ath->rx_skb); + BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err); + return err; + } + + return count; +} + #define HCI_OP_ATH_SLEEP 0xFC04 -/* Enqueue frame for transmittion */ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb) { struct ath_struct *ath = hu->priv; @@ -159,8 +209,7 @@ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb) return 0; } - /* - * Update power management enable flag with parameters of + /* Update power management enable flag with parameters of * HCI sleep enable vendor specific HCI command. */ if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { @@ -190,37 +239,16 @@ static struct sk_buff *ath_dequeue(struct hci_uart *hu) return skb_dequeue(&ath->txq); } -static const struct h4_recv_pkt ath_recv_pkts[] = { - { H4_RECV_ACL, .recv = hci_recv_frame }, - { H4_RECV_SCO, .recv = hci_recv_frame }, - { H4_RECV_EVENT, .recv = hci_recv_frame }, -}; - -/* Recv data */ -static int ath_recv(struct hci_uart *hu, const void *data, int count) -{ - struct ath_struct *ath = hu->priv; - - ath->rx_skb = h4_recv_buf(hu->hdev, ath->rx_skb, data, count, - ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts)); - if (IS_ERR(ath->rx_skb)) { - int err = PTR_ERR(ath->rx_skb); - BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err); - return err; - } - - return count; -} - static const struct hci_uart_proto athp = { .id = HCI_UART_ATH3K, .name = "ATH3K", .open = ath_open, .close = ath_close, + .flush = ath_flush, + .setup = ath_setup, .recv = ath_recv, .enqueue = ath_enqueue, .dequeue = ath_dequeue, - .flush = ath_flush, }; int __init ath_init(void) |