Merge master.kernel.org:/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6
This commit is contained in:
commit
de5144164f
16 changed files with 341 additions and 420 deletions
|
@ -55,14 +55,6 @@ config BT_HCIUART_BCSP
|
||||||
|
|
||||||
Say Y here to compile support for HCI BCSP protocol.
|
Say Y here to compile support for HCI BCSP protocol.
|
||||||
|
|
||||||
config BT_HCIUART_BCSP_TXCRC
|
|
||||||
bool "Transmit CRC with every BCSP packet"
|
|
||||||
depends on BT_HCIUART_BCSP
|
|
||||||
help
|
|
||||||
If you say Y here, a 16-bit CRC checksum will be transmitted along with
|
|
||||||
every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip.
|
|
||||||
This increases reliability, but slightly reduces efficiency.
|
|
||||||
|
|
||||||
config BT_HCIBCM203X
|
config BT_HCIBCM203X
|
||||||
tristate "HCI BCM203x USB driver"
|
tristate "HCI BCM203x USB driver"
|
||||||
depends on USB
|
depends on USB
|
||||||
|
|
|
@ -550,6 +550,9 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
|
||||||
if (ignore)
|
if (ignore)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
data = kmalloc(sizeof(*data), GFP_KERNEL);
|
data = kmalloc(sizeof(*data), GFP_KERNEL);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
BT_ERR("Can't allocate data structure");
|
BT_ERR("Can't allocate data structure");
|
||||||
|
|
|
@ -1,35 +1,27 @@
|
||||||
/*
|
/*
|
||||||
BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
|
*
|
||||||
Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
|
* Bluetooth HCI UART driver
|
||||||
|
*
|
||||||
Based on
|
* Copyright (C) 2002-2003 Fabrizio Gennari <fabrizio.gennari@philips.com>
|
||||||
hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
|
* Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
|
||||||
ABCSP by Carl Orsborn <cjo@csr.com>
|
*
|
||||||
|
*
|
||||||
This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License as published by
|
||||||
published by the Free Software Foundation;
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
*
|
||||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* This program is distributed in the hope that it will be useful,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
* GNU General Public License for more details.
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
*
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* You should have received a copy of the GNU General Public License
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
*
|
||||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
|
||||||
SOFTWARE IS DISCLAIMED.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* $Id: hci_bcsp.c,v 1.2 2002/09/26 05:05:14 maxk Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VERSION "0.2"
|
|
||||||
|
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
@ -52,16 +44,56 @@
|
||||||
|
|
||||||
#include <net/bluetooth/bluetooth.h>
|
#include <net/bluetooth/bluetooth.h>
|
||||||
#include <net/bluetooth/hci_core.h>
|
#include <net/bluetooth/hci_core.h>
|
||||||
|
|
||||||
#include "hci_uart.h"
|
#include "hci_uart.h"
|
||||||
#include "hci_bcsp.h"
|
|
||||||
|
|
||||||
#ifndef CONFIG_BT_HCIUART_DEBUG
|
#ifndef CONFIG_BT_HCIUART_DEBUG
|
||||||
#undef BT_DBG
|
#undef BT_DBG
|
||||||
#define BT_DBG( A... )
|
#define BT_DBG( A... )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define VERSION "0.3"
|
||||||
|
|
||||||
|
static int txcrc = 1;
|
||||||
static int hciextn = 1;
|
static int hciextn = 1;
|
||||||
|
|
||||||
|
#define BCSP_TXWINSIZE 4
|
||||||
|
|
||||||
|
#define BCSP_ACK_PKT 0x05
|
||||||
|
#define BCSP_LE_PKT 0x06
|
||||||
|
|
||||||
|
struct bcsp_struct {
|
||||||
|
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 rx_count;
|
||||||
|
struct sk_buff *rx_skb;
|
||||||
|
u8 rxseq_txack; /* rxseq == txack. */
|
||||||
|
u8 rxack; /* Last packet sent by us that the peer ack'ed */
|
||||||
|
struct timer_list tbcsp;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
BCSP_W4_PKT_DELIMITER,
|
||||||
|
BCSP_W4_PKT_START,
|
||||||
|
BCSP_W4_BCSP_HDR,
|
||||||
|
BCSP_W4_DATA,
|
||||||
|
BCSP_W4_CRC
|
||||||
|
} rx_state;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
BCSP_ESCSTATE_NOESC,
|
||||||
|
BCSP_ESCSTATE_ESC
|
||||||
|
} rx_esc_state;
|
||||||
|
|
||||||
|
u8 use_crc;
|
||||||
|
u16 message_crc;
|
||||||
|
u8 txack_req; /* Do we need to send ack's to the peer? */
|
||||||
|
|
||||||
|
/* Reliable packet sequence number - used to assign seq to each rel pkt. */
|
||||||
|
u8 msgq_txseq;
|
||||||
|
};
|
||||||
|
|
||||||
/* ---- BCSP CRC calculation ---- */
|
/* ---- BCSP CRC calculation ---- */
|
||||||
|
|
||||||
/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
|
/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
|
||||||
|
@ -111,6 +143,7 @@ static u16 bcsp_crc_reverse(u16 crc)
|
||||||
rev |= (crc & 1);
|
rev |= (crc & 1);
|
||||||
crc = crc >> 1;
|
crc = crc >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (rev);
|
return (rev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +152,7 @@ static u16 bcsp_crc_reverse(u16 crc)
|
||||||
static void bcsp_slip_msgdelim(struct sk_buff *skb)
|
static void bcsp_slip_msgdelim(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
const char pkt_delim = 0xc0;
|
const char pkt_delim = 0xc0;
|
||||||
|
|
||||||
memcpy(skb_put(skb, 1), &pkt_delim, 1);
|
memcpy(skb_put(skb, 1), &pkt_delim, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,11 +207,8 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
|
||||||
{
|
{
|
||||||
struct sk_buff *nskb;
|
struct sk_buff *nskb;
|
||||||
u8 hdr[4], chan;
|
u8 hdr[4], chan;
|
||||||
int rel, i;
|
|
||||||
|
|
||||||
#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
|
|
||||||
u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
|
u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
|
||||||
#endif
|
int rel, i;
|
||||||
|
|
||||||
switch (pkt_type) {
|
switch (pkt_type) {
|
||||||
case HCI_ACLDATA_PKT:
|
case HCI_ACLDATA_PKT:
|
||||||
|
@ -240,9 +271,9 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
|
||||||
BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
|
BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
|
||||||
bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
|
bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
|
|
||||||
|
if (bcsp->use_crc)
|
||||||
hdr[0] |= 0x40;
|
hdr[0] |= 0x40;
|
||||||
#endif
|
|
||||||
|
|
||||||
hdr[1] = ((len << 4) & 0xff) | chan;
|
hdr[1] = ((len << 4) & 0xff) | chan;
|
||||||
hdr[2] = len >> 4;
|
hdr[2] = len >> 4;
|
||||||
|
@ -251,25 +282,25 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
|
||||||
/* Put BCSP header */
|
/* Put BCSP header */
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
bcsp_slip_one_byte(nskb, hdr[i]);
|
bcsp_slip_one_byte(nskb, hdr[i]);
|
||||||
#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
|
|
||||||
|
if (bcsp->use_crc)
|
||||||
bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
|
bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Put payload */
|
/* Put payload */
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
bcsp_slip_one_byte(nskb, data[i]);
|
bcsp_slip_one_byte(nskb, data[i]);
|
||||||
#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
|
|
||||||
|
if (bcsp->use_crc)
|
||||||
bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
|
bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
|
|
||||||
/* Put CRC */
|
/* Put CRC */
|
||||||
|
if (bcsp->use_crc) {
|
||||||
bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
|
bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
|
||||||
bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
|
bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
|
||||||
bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
|
bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
|
||||||
#endif
|
}
|
||||||
|
|
||||||
bcsp_slip_msgdelim(nskb);
|
bcsp_slip_msgdelim(nskb);
|
||||||
return nskb;
|
return nskb;
|
||||||
|
@ -317,7 +348,6 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bcsp->unack.lock, flags);
|
spin_unlock_irqrestore(&bcsp->unack.lock, flags);
|
||||||
|
|
||||||
|
|
||||||
/* We could not send a reliable packet, either because there are
|
/* We could not send a reliable packet, either because there are
|
||||||
none or because there are too many unack'ed pkts. Did we receive
|
none or because there are too many unack'ed pkts. Did we receive
|
||||||
any packets we have not acknowledged yet ? */
|
any packets we have not acknowledged yet ? */
|
||||||
|
@ -374,8 +404,10 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
skb = nskb;
|
skb = nskb;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bcsp->unack.qlen == 0)
|
if (bcsp->unack.qlen == 0)
|
||||||
del_timer(&bcsp->tbcsp);
|
del_timer(&bcsp->tbcsp);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bcsp->unack.lock, flags);
|
spin_unlock_irqrestore(&bcsp->unack.lock, flags);
|
||||||
|
|
||||||
if (i != pkts_to_be_removed)
|
if (i != pkts_to_be_removed)
|
||||||
|
@ -530,6 +562,7 @@ static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
|
||||||
|
|
||||||
hci_recv_frame(bcsp->rx_skb);
|
hci_recv_frame(bcsp->rx_skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
|
bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
|
||||||
bcsp->rx_skb = NULL;
|
bcsp->rx_skb = NULL;
|
||||||
}
|
}
|
||||||
|
@ -698,6 +731,9 @@ static int bcsp_open(struct hci_uart *hu)
|
||||||
|
|
||||||
bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
|
bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
|
||||||
|
|
||||||
|
if (txcrc)
|
||||||
|
bcsp->use_crc = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,6 +766,7 @@ static struct hci_uart_proto bcsp = {
|
||||||
int bcsp_init(void)
|
int bcsp_init(void)
|
||||||
{
|
{
|
||||||
int err = hci_uart_register_proto(&bcsp);
|
int err = hci_uart_register_proto(&bcsp);
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
BT_INFO("HCI BCSP protocol initialized");
|
BT_INFO("HCI BCSP protocol initialized");
|
||||||
else
|
else
|
||||||
|
@ -743,5 +780,8 @@ int bcsp_deinit(void)
|
||||||
return hci_uart_unregister_proto(&bcsp);
|
return hci_uart_unregister_proto(&bcsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module_param(txcrc, bool, 0644);
|
||||||
|
MODULE_PARM_DESC(txcrc, "Transmit CRC with every BCSP packet");
|
||||||
|
|
||||||
module_param(hciextn, bool, 0644);
|
module_param(hciextn, bool, 0644);
|
||||||
MODULE_PARM_DESC(hciextn, "Convert HCI Extensions into BCSP packets");
|
MODULE_PARM_DESC(hciextn, "Convert HCI Extensions into BCSP packets");
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
/*
|
|
||||||
BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
|
|
||||||
Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
|
|
||||||
|
|
||||||
Based on
|
|
||||||
hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
|
|
||||||
ABCSP by Carl Orsborn <cjo@csr.com>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License version 2 as
|
|
||||||
published by the Free Software Foundation;
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
|
||||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
|
|
||||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
|
||||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
|
||||||
SOFTWARE IS DISCLAIMED.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* $Id: hci_bcsp.h,v 1.2 2002/09/26 05:05:14 maxk Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __HCI_BCSP_H__
|
|
||||||
#define __HCI_BCSP_H__
|
|
||||||
|
|
||||||
#define BCSP_TXWINSIZE 4
|
|
||||||
|
|
||||||
#define BCSP_ACK_PKT 0x05
|
|
||||||
#define BCSP_LE_PKT 0x06
|
|
||||||
|
|
||||||
struct bcsp_struct {
|
|
||||||
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 rx_count;
|
|
||||||
struct sk_buff *rx_skb;
|
|
||||||
u8 rxseq_txack; /* rxseq == txack. */
|
|
||||||
u8 rxack; /* Last packet sent by us that the peer ack'ed */
|
|
||||||
struct timer_list tbcsp;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
BCSP_W4_PKT_DELIMITER,
|
|
||||||
BCSP_W4_PKT_START,
|
|
||||||
BCSP_W4_BCSP_HDR,
|
|
||||||
BCSP_W4_DATA,
|
|
||||||
BCSP_W4_CRC
|
|
||||||
} rx_state;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
BCSP_ESCSTATE_NOESC,
|
|
||||||
BCSP_ESCSTATE_ESC
|
|
||||||
} rx_esc_state;
|
|
||||||
|
|
||||||
u16 message_crc;
|
|
||||||
u8 txack_req; /* Do we need to send ack's to the peer? */
|
|
||||||
|
|
||||||
/* Reliable packet sequence number - used to assign seq to each rel pkt. */
|
|
||||||
u8 msgq_txseq;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* __HCI_BCSP_H__ */
|
|
|
@ -1,33 +1,27 @@
|
||||||
/*
|
/*
|
||||||
BlueZ - Bluetooth protocol stack for Linux
|
|
||||||
Copyright (C) 2000-2001 Qualcomm Incorporated
|
|
||||||
|
|
||||||
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License version 2 as
|
|
||||||
published by the Free Software Foundation;
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
|
||||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
|
|
||||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
|
||||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
|
||||||
SOFTWARE IS DISCLAIMED.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bluetooth HCI UART(H4) protocol.
|
|
||||||
*
|
*
|
||||||
* $Id: hci_h4.c,v 1.3 2002/09/09 01:17:32 maxk Exp $
|
* Bluetooth HCI UART driver
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||||
|
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||||
|
* Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
#define VERSION "1.2"
|
|
||||||
|
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -51,14 +45,30 @@
|
||||||
|
|
||||||
#include <net/bluetooth/bluetooth.h>
|
#include <net/bluetooth/bluetooth.h>
|
||||||
#include <net/bluetooth/hci_core.h>
|
#include <net/bluetooth/hci_core.h>
|
||||||
|
|
||||||
#include "hci_uart.h"
|
#include "hci_uart.h"
|
||||||
#include "hci_h4.h"
|
|
||||||
|
|
||||||
#ifndef CONFIG_BT_HCIUART_DEBUG
|
#ifndef CONFIG_BT_HCIUART_DEBUG
|
||||||
#undef BT_DBG
|
#undef BT_DBG
|
||||||
#define BT_DBG( A... )
|
#define BT_DBG( A... )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define VERSION "1.2"
|
||||||
|
|
||||||
|
struct h4_struct {
|
||||||
|
unsigned long rx_state;
|
||||||
|
unsigned long rx_count;
|
||||||
|
struct sk_buff *rx_skb;
|
||||||
|
struct sk_buff_head txq;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* H4 receiver States */
|
||||||
|
#define H4_W4_PACKET_TYPE 0
|
||||||
|
#define H4_W4_EVENT_HDR 1
|
||||||
|
#define H4_W4_ACL_HDR 2
|
||||||
|
#define H4_W4_SCO_HDR 3
|
||||||
|
#define H4_W4_DATA 4
|
||||||
|
|
||||||
/* Initialize protocol */
|
/* Initialize protocol */
|
||||||
static int h4_open(struct hci_uart *hu)
|
static int h4_open(struct hci_uart *hu)
|
||||||
{
|
{
|
||||||
|
@ -69,6 +79,7 @@ static int h4_open(struct hci_uart *hu)
|
||||||
h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
|
h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
|
||||||
if (!h4)
|
if (!h4)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
memset(h4, 0, sizeof(*h4));
|
memset(h4, 0, sizeof(*h4));
|
||||||
|
|
||||||
skb_queue_head_init(&h4->txq);
|
skb_queue_head_init(&h4->txq);
|
||||||
|
@ -83,7 +94,9 @@ static int h4_flush(struct hci_uart *hu)
|
||||||
struct h4_struct *h4 = hu->priv;
|
struct h4_struct *h4 = hu->priv;
|
||||||
|
|
||||||
BT_DBG("hu %p", hu);
|
BT_DBG("hu %p", hu);
|
||||||
|
|
||||||
skb_queue_purge(&h4->txq);
|
skb_queue_purge(&h4->txq);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,16 +104,19 @@ static int h4_flush(struct hci_uart *hu)
|
||||||
static int h4_close(struct hci_uart *hu)
|
static int h4_close(struct hci_uart *hu)
|
||||||
{
|
{
|
||||||
struct h4_struct *h4 = hu->priv;
|
struct h4_struct *h4 = hu->priv;
|
||||||
|
|
||||||
hu->priv = NULL;
|
hu->priv = NULL;
|
||||||
|
|
||||||
BT_DBG("hu %p", hu);
|
BT_DBG("hu %p", hu);
|
||||||
|
|
||||||
skb_queue_purge(&h4->txq);
|
skb_queue_purge(&h4->txq);
|
||||||
|
|
||||||
if (h4->rx_skb)
|
if (h4->rx_skb)
|
||||||
kfree_skb(h4->rx_skb);
|
kfree_skb(h4->rx_skb);
|
||||||
|
|
||||||
hu->priv = NULL;
|
hu->priv = NULL;
|
||||||
kfree(h4);
|
kfree(h4);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +130,7 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
|
||||||
/* Prepend skb with frame type */
|
/* Prepend skb with frame type */
|
||||||
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
|
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
|
||||||
skb_queue_tail(&h4->txq, skb);
|
skb_queue_tail(&h4->txq, skb);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +139,7 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
|
||||||
register int room = skb_tailroom(h4->rx_skb);
|
register int room = skb_tailroom(h4->rx_skb);
|
||||||
|
|
||||||
BT_DBG("len %d room %d", len, room);
|
BT_DBG("len %d room %d", len, room);
|
||||||
|
|
||||||
if (!len) {
|
if (!len) {
|
||||||
hci_recv_frame(h4->rx_skb);
|
hci_recv_frame(h4->rx_skb);
|
||||||
} else if (len > room) {
|
} else if (len > room) {
|
||||||
|
@ -136,6 +154,7 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
|
||||||
h4->rx_state = H4_W4_PACKET_TYPE;
|
h4->rx_state = H4_W4_PACKET_TYPE;
|
||||||
h4->rx_skb = NULL;
|
h4->rx_skb = NULL;
|
||||||
h4->rx_count = 0;
|
h4->rx_count = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,6 +247,7 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
|
||||||
ptr++; count--;
|
ptr++; count--;
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
ptr++; count--;
|
ptr++; count--;
|
||||||
|
|
||||||
/* Allocate packet */
|
/* Allocate packet */
|
||||||
|
@ -238,9 +258,11 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
|
||||||
h4->rx_count = 0;
|
h4->rx_count = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
h4->rx_skb->dev = (void *) hu->hdev;
|
h4->rx_skb->dev = (void *) hu->hdev;
|
||||||
bt_cb(h4->rx_skb)->pkt_type = type;
|
bt_cb(h4->rx_skb)->pkt_type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,6 +285,7 @@ static struct hci_uart_proto h4p = {
|
||||||
int h4_init(void)
|
int h4_init(void)
|
||||||
{
|
{
|
||||||
int err = hci_uart_register_proto(&h4p);
|
int err = hci_uart_register_proto(&h4p);
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
BT_INFO("HCI H4 protocol initialized");
|
BT_INFO("HCI H4 protocol initialized");
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
BlueZ - Bluetooth protocol stack for Linux
|
|
||||||
Copyright (C) 2000-2001 Qualcomm Incorporated
|
|
||||||
|
|
||||||
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License version 2 as
|
|
||||||
published by the Free Software Foundation;
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
|
||||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
|
|
||||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
|
||||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
|
||||||
SOFTWARE IS DISCLAIMED.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* $Id: hci_h4.h,v 1.2 2002/09/09 01:17:32 maxk Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
|
||||||
struct h4_struct {
|
|
||||||
unsigned long rx_state;
|
|
||||||
unsigned long rx_count;
|
|
||||||
struct sk_buff *rx_skb;
|
|
||||||
struct sk_buff_head txq;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* H4 receiver States */
|
|
||||||
#define H4_W4_PACKET_TYPE 0
|
|
||||||
#define H4_W4_EVENT_HDR 1
|
|
||||||
#define H4_W4_ACL_HDR 2
|
|
||||||
#define H4_W4_SCO_HDR 3
|
|
||||||
#define H4_W4_DATA 4
|
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
|
|
@ -1,33 +1,27 @@
|
||||||
/*
|
/*
|
||||||
BlueZ - Bluetooth protocol stack for Linux
|
|
||||||
Copyright (C) 2000-2001 Qualcomm Incorporated
|
|
||||||
|
|
||||||
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License version 2 as
|
|
||||||
published by the Free Software Foundation;
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
|
||||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
|
|
||||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
|
||||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
|
||||||
SOFTWARE IS DISCLAIMED.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bluetooth HCI UART driver.
|
|
||||||
*
|
*
|
||||||
* $Id: hci_ldisc.c,v 1.5 2002/10/02 18:37:20 maxk Exp $
|
* Bluetooth HCI UART driver
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||||
|
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||||
|
* Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
#define VERSION "2.1"
|
|
||||||
|
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -59,6 +53,8 @@
|
||||||
#define BT_DBG( A... )
|
#define BT_DBG( A... )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define VERSION "2.2"
|
||||||
|
|
||||||
static int reset = 0;
|
static int reset = 0;
|
||||||
|
|
||||||
static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
|
static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
|
||||||
|
@ -72,6 +68,7 @@ int hci_uart_register_proto(struct hci_uart_proto *p)
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
hup[p->id] = p;
|
hup[p->id] = p;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +81,7 @@ int hci_uart_unregister_proto(struct hci_uart_proto *p)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
hup[p->id] = NULL;
|
hup[p->id] = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +89,7 @@ static struct hci_uart_proto *hci_uart_get_proto(unsigned int id)
|
||||||
{
|
{
|
||||||
if (id >= HCI_UART_MAX_PROTO)
|
if (id >= HCI_UART_MAX_PROTO)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return hup[id];
|
return hup[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,10 +116,12 @@ static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
|
||||||
static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
|
static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb = hu->tx_skb;
|
struct sk_buff *skb = hu->tx_skb;
|
||||||
|
|
||||||
if (!skb)
|
if (!skb)
|
||||||
skb = hu->proto->dequeue(hu);
|
skb = hu->proto->dequeue(hu);
|
||||||
else
|
else
|
||||||
hu->tx_skb = NULL;
|
hu->tx_skb = NULL;
|
||||||
|
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,6 +174,7 @@ static int hci_uart_open(struct hci_dev *hdev)
|
||||||
/* Nothing to do for UART driver */
|
/* Nothing to do for UART driver */
|
||||||
|
|
||||||
set_bit(HCI_RUNNING, &hdev->flags);
|
set_bit(HCI_RUNNING, &hdev->flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,6 +236,7 @@ static int hci_uart_send_frame(struct sk_buff *skb)
|
||||||
hu->proto->enqueue(hu, skb);
|
hu->proto->enqueue(hu, skb);
|
||||||
|
|
||||||
hci_uart_tx_wakeup(hu);
|
hci_uart_tx_wakeup(hu);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +244,8 @@ static void hci_uart_destruct(struct hci_dev *hdev)
|
||||||
{
|
{
|
||||||
struct hci_uart *hu;
|
struct hci_uart *hu;
|
||||||
|
|
||||||
if (!hdev) return;
|
if (!hdev)
|
||||||
|
return;
|
||||||
|
|
||||||
BT_DBG("%s", hdev->name);
|
BT_DBG("%s", hdev->name);
|
||||||
|
|
||||||
|
@ -272,6 +276,7 @@ static int hci_uart_tty_open(struct tty_struct *tty)
|
||||||
BT_ERR("Can't allocate controll structure");
|
BT_ERR("Can't allocate controll structure");
|
||||||
return -ENFILE;
|
return -ENFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(hu, 0, sizeof(struct hci_uart));
|
memset(hu, 0, sizeof(struct hci_uart));
|
||||||
|
|
||||||
tty->disc_data = hu;
|
tty->disc_data = hu;
|
||||||
|
@ -280,8 +285,10 @@ static int hci_uart_tty_open(struct tty_struct *tty)
|
||||||
spin_lock_init(&hu->rx_lock);
|
spin_lock_init(&hu->rx_lock);
|
||||||
|
|
||||||
/* Flush any pending characters in the driver and line discipline. */
|
/* Flush any pending characters in the driver and line discipline. */
|
||||||
|
|
||||||
/* FIXME: why is this needed. Note don't use ldisc_ref here as the
|
/* FIXME: why is this needed. Note don't use ldisc_ref here as the
|
||||||
open path is before the ldisc is referencable */
|
open path is before the ldisc is referencable */
|
||||||
|
|
||||||
if (tty->ldisc.flush_buffer)
|
if (tty->ldisc.flush_buffer)
|
||||||
tty->ldisc.flush_buffer(tty);
|
tty->ldisc.flush_buffer(tty);
|
||||||
|
|
||||||
|
@ -446,6 +453,7 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id)
|
||||||
p->close(hu);
|
p->close(hu);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,27 +510,23 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
|
||||||
/*
|
/*
|
||||||
* We don't provide read/write/poll interface for user space.
|
* We don't provide read/write/poll interface for user space.
|
||||||
*/
|
*/
|
||||||
static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char __user *buf, size_t nr)
|
static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file,
|
||||||
{
|
unsigned char __user *buf, size_t nr)
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
static unsigned int hci_uart_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
|
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_BT_HCIUART_H4
|
static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file,
|
||||||
int h4_init(void);
|
const unsigned char *data, size_t count)
|
||||||
int h4_deinit(void);
|
{
|
||||||
#endif
|
return 0;
|
||||||
#ifdef CONFIG_BT_HCIUART_BCSP
|
}
|
||||||
int bcsp_init(void);
|
|
||||||
int bcsp_deinit(void);
|
static unsigned int hci_uart_tty_poll(struct tty_struct *tty,
|
||||||
#endif
|
struct file *filp, poll_table *wait)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int __init hci_uart_init(void)
|
static int __init hci_uart_init(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,29 +1,26 @@
|
||||||
/*
|
/*
|
||||||
BlueZ - Bluetooth protocol stack for Linux
|
*
|
||||||
Copyright (C) 2000-2001 Qualcomm Incorporated
|
* Bluetooth HCI UART driver
|
||||||
|
*
|
||||||
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
|
* Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||||
|
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||||
This program is free software; you can redistribute it and/or modify
|
* Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
|
||||||
it under the terms of the GNU General Public License version 2 as
|
*
|
||||||
published by the Free Software Foundation;
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
* it under the terms of the GNU General Public License as published by
|
||||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
* (at your option) any later version.
|
||||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
|
*
|
||||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
* This program is distributed in the hope that it will be useful,
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
* You should have received a copy of the GNU General Public License
|
||||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
* along with this program; if not, write to the Free Software
|
||||||
SOFTWARE IS DISCLAIMED.
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*
|
||||||
|
|
||||||
/*
|
|
||||||
* $Id: hci_uart.h,v 1.2 2002/09/09 01:17:32 maxk Exp $
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef N_HCI
|
#ifndef N_HCI
|
||||||
|
@ -42,7 +39,6 @@
|
||||||
#define HCI_UART_3WIRE 2
|
#define HCI_UART_3WIRE 2
|
||||||
#define HCI_UART_H4DS 3
|
#define HCI_UART_H4DS 3
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
|
||||||
struct hci_uart;
|
struct hci_uart;
|
||||||
|
|
||||||
struct hci_uart_proto {
|
struct hci_uart_proto {
|
||||||
|
@ -79,4 +75,12 @@ int hci_uart_register_proto(struct hci_uart_proto *p);
|
||||||
int hci_uart_unregister_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_tx_wakeup(struct hci_uart *hu);
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#ifdef CONFIG_BT_HCIUART_H4
|
||||||
|
int h4_init(void);
|
||||||
|
int h4_deinit(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BT_HCIUART_BCSP
|
||||||
|
int bcsp_init(void);
|
||||||
|
int bcsp_deinit(void);
|
||||||
|
#endif
|
||||||
|
|
|
@ -171,4 +171,10 @@ static inline int skb_frags_no(struct sk_buff *skb)
|
||||||
|
|
||||||
int bt_err(__u16 code);
|
int bt_err(__u16 code);
|
||||||
|
|
||||||
|
extern int hci_sock_init(void);
|
||||||
|
extern int hci_sock_cleanup(void);
|
||||||
|
|
||||||
|
extern int bt_sysfs_init(void);
|
||||||
|
extern void bt_sysfs_cleanup(void);
|
||||||
|
|
||||||
#endif /* __BLUETOOTH_H */
|
#endif /* __BLUETOOTH_H */
|
||||||
|
|
|
@ -275,9 +275,6 @@ static inline void rfcomm_session_hold(struct rfcomm_session *s)
|
||||||
atomic_inc(&s->refcnt);
|
atomic_inc(&s->refcnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- RFCOMM chechsum ---- */
|
|
||||||
extern u8 rfcomm_crc_table[];
|
|
||||||
|
|
||||||
/* ---- RFCOMM sockets ---- */
|
/* ---- RFCOMM sockets ---- */
|
||||||
struct sockaddr_rc {
|
struct sockaddr_rc {
|
||||||
sa_family_t rc_family;
|
sa_family_t rc_family;
|
||||||
|
|
|
@ -308,12 +308,6 @@ static struct net_proto_family bt_sock_family_ops = {
|
||||||
.create = bt_sock_create,
|
.create = bt_sock_create,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int hci_sock_init(void);
|
|
||||||
extern int hci_sock_cleanup(void);
|
|
||||||
|
|
||||||
extern int bt_sysfs_init(void);
|
|
||||||
extern int bt_sysfs_cleanup(void);
|
|
||||||
|
|
||||||
static int __init bt_init(void)
|
static int __init bt_init(void)
|
||||||
{
|
{
|
||||||
BT_INFO("Core ver %s", VERSION);
|
BT_INFO("Core ver %s", VERSION);
|
||||||
|
|
|
@ -87,7 +87,7 @@ int hci_unregister_notifier(struct notifier_block *nb)
|
||||||
return notifier_chain_unregister(&hci_notifier, nb);
|
return notifier_chain_unregister(&hci_notifier, nb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hci_notify(struct hci_dev *hdev, int event)
|
static void hci_notify(struct hci_dev *hdev, int event)
|
||||||
{
|
{
|
||||||
notifier_call_chain(&hci_notifier, event, hdev);
|
notifier_call_chain(&hci_notifier, event, hdev);
|
||||||
}
|
}
|
||||||
|
@ -1347,7 +1347,7 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hci_rx_task(unsigned long arg)
|
static void hci_rx_task(unsigned long arg)
|
||||||
{
|
{
|
||||||
struct hci_dev *hdev = (struct hci_dev *) arg;
|
struct hci_dev *hdev = (struct hci_dev *) arg;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
|
@ -66,20 +66,20 @@ static struct hci_sec_filter hci_sec_filter = {
|
||||||
/* Packet types */
|
/* Packet types */
|
||||||
0x10,
|
0x10,
|
||||||
/* Events */
|
/* Events */
|
||||||
{ 0x1000d9fe, 0x0000300c },
|
{ 0x1000d9fe, 0x0000b00c },
|
||||||
/* Commands */
|
/* Commands */
|
||||||
{
|
{
|
||||||
{ 0x0 },
|
{ 0x0 },
|
||||||
/* OGF_LINK_CTL */
|
/* OGF_LINK_CTL */
|
||||||
{ 0xbe000006, 0x00000001, 0x0000, 0x00 },
|
{ 0xbe000006, 0x00000001, 0x000000, 0x00 },
|
||||||
/* OGF_LINK_POLICY */
|
/* OGF_LINK_POLICY */
|
||||||
{ 0x00005200, 0x00000000, 0x0000, 0x00 },
|
{ 0x00005200, 0x00000000, 0x000000, 0x00 },
|
||||||
/* OGF_HOST_CTL */
|
/* OGF_HOST_CTL */
|
||||||
{ 0xaab00200, 0x2b402aaa, 0x0154, 0x00 },
|
{ 0xaab00200, 0x2b402aaa, 0x020154, 0x00 },
|
||||||
/* OGF_INFO_PARAM */
|
/* OGF_INFO_PARAM */
|
||||||
{ 0x000002be, 0x00000000, 0x0000, 0x00 },
|
{ 0x000002be, 0x00000000, 0x000000, 0x00 },
|
||||||
/* OGF_STATUS_PARAM */
|
/* OGF_STATUS_PARAM */
|
||||||
{ 0x000000ea, 0x00000000, 0x0000, 0x00 }
|
{ 0x000000ea, 0x00000000, 0x000000, 0x00 }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
obj-$(CONFIG_BT_RFCOMM) += rfcomm.o
|
obj-$(CONFIG_BT_RFCOMM) += rfcomm.o
|
||||||
|
|
||||||
rfcomm-y := core.o sock.o crc.o
|
rfcomm-y := core.o sock.o
|
||||||
rfcomm-$(CONFIG_BT_RFCOMM_TTY) += tty.o
|
rfcomm-$(CONFIG_BT_RFCOMM_TTY) += tty.o
|
||||||
|
|
|
@ -133,6 +133,49 @@ static inline void rfcomm_session_put(struct rfcomm_session *s)
|
||||||
|
|
||||||
/* ---- RFCOMM FCS computation ---- */
|
/* ---- RFCOMM FCS computation ---- */
|
||||||
|
|
||||||
|
/* reversed, 8-bit, poly=0x07 */
|
||||||
|
static unsigned char rfcomm_crc_table[256] = {
|
||||||
|
0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
|
||||||
|
0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
|
||||||
|
0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
|
||||||
|
0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
|
||||||
|
|
||||||
|
0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
|
||||||
|
0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
|
||||||
|
0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
|
||||||
|
0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
|
||||||
|
|
||||||
|
0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
|
||||||
|
0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
|
||||||
|
0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
|
||||||
|
0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
|
||||||
|
|
||||||
|
0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
|
||||||
|
0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
|
||||||
|
0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
|
||||||
|
0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
|
||||||
|
|
||||||
|
0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
|
||||||
|
0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
|
||||||
|
0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
|
||||||
|
0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
|
||||||
|
|
||||||
|
0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
|
||||||
|
0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
|
||||||
|
0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
|
||||||
|
0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
|
||||||
|
|
||||||
|
0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
|
||||||
|
0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
|
||||||
|
0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
|
||||||
|
0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
|
||||||
|
|
||||||
|
0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
|
||||||
|
0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
|
||||||
|
0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
|
||||||
|
0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
|
||||||
|
};
|
||||||
|
|
||||||
/* CRC on 2 bytes */
|
/* CRC on 2 bytes */
|
||||||
#define __crc(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
|
#define __crc(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
|
||||||
|
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
/*
|
|
||||||
RFCOMM implementation for Linux Bluetooth stack (BlueZ).
|
|
||||||
Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
|
|
||||||
Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License version 2 as
|
|
||||||
published by the Free Software Foundation;
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
|
||||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
|
|
||||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
|
||||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
|
||||||
SOFTWARE IS DISCLAIMED.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RFCOMM FCS calculation.
|
|
||||||
*
|
|
||||||
* $Id: crc.c,v 1.2 2002/09/21 09:54:32 holtmann Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* reversed, 8-bit, poly=0x07 */
|
|
||||||
unsigned char rfcomm_crc_table[256] = {
|
|
||||||
0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
|
|
||||||
0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
|
|
||||||
0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
|
|
||||||
0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
|
|
||||||
|
|
||||||
0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
|
|
||||||
0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
|
|
||||||
0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
|
|
||||||
0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
|
|
||||||
|
|
||||||
0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
|
|
||||||
0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
|
|
||||||
0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
|
|
||||||
0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
|
|
||||||
|
|
||||||
0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
|
|
||||||
0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
|
|
||||||
0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
|
|
||||||
0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
|
|
||||||
|
|
||||||
0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
|
|
||||||
0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
|
|
||||||
0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
|
|
||||||
0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
|
|
||||||
|
|
||||||
0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
|
|
||||||
0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
|
|
||||||
0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
|
|
||||||
0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
|
|
||||||
|
|
||||||
0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
|
|
||||||
0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
|
|
||||||
0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
|
|
||||||
0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
|
|
||||||
|
|
||||||
0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
|
|
||||||
0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
|
|
||||||
0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
|
|
||||||
0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
|
|
||||||
};
|
|
Reference in a new issue