Commit dcfa61d5 authored by Marcel Holtmann's avatar Marcel Holtmann

Merge bk://linux.bkbits.net/linux-2.5

into hostme.bitkeeper.com:/ua/repos/l/linux-bt/bt-2.5
parents 5882eeaf 134c3f5a
menu "Bluetooth device drivers"
depends on BT!=n
depends on BT
config BT_HCIUSB
tristate "HCI USB driver"
......@@ -52,11 +52,19 @@ config BT_HCIUART_BCSP
help
BCSP (BlueCore Serial Protocol) is serial protocol for communication
between Bluetooth device and host. This protocol is required for non
USB Bluetooth devices based on CSR BlueCore chip, including PCMCIA and
USB Bluetooth devices based on CSR BlueCore chip, including PCMCIA and
CF cards.
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_HCIDTL1
tristate "HCI DTL1 (PC Card) driver"
depends on PCMCIA && BT
......@@ -64,8 +72,8 @@ config BT_HCIDTL1
Bluetooth HCI DTL1 (PC Card) driver.
This driver provides support for Bluetooth PCMCIA devices with
Nokia DTL1 interface:
Nokia Bluetooth Card
Socket Bluetooth CF Card
Nokia Bluetooth Card
Socket Bluetooth CF Card
Say Y here to compile support for HCI DTL1 devices into the
kernel or say M to compile it as module (dtl1_cs.o).
......@@ -73,12 +81,12 @@ config BT_HCIDTL1
config BT_HCIBT3C
tristate "HCI BT3C (PC Card) driver"
depends on PCMCIA && BT
---help---
help
Bluetooth HCI BT3C (PC Card) driver.
This driver provides support for Bluetooth PCMCIA devices with
3Com BT3C interface:
3Com Bluetooth Card (3CRWB6096)
HP Bluetooth Card
3Com Bluetooth Card (3CRWB6096)
HP Bluetooth Card
The HCI BT3C driver uses external firmware loader program provided in
the BlueFW package. For more information, see <http://bluez.sf.net>.
......@@ -92,13 +100,29 @@ config BT_HCIBLUECARD
help
Bluetooth HCI BlueCard (PC Card) driver.
This driver provides support for Bluetooth PCMCIA devices with
Anycom BlueCard interface:
Anycom Bluetooth PC Card
Anycom Bluetooth CF Card
Anycom BlueCard interface:
Anycom Bluetooth PC Card
Anycom Bluetooth CF Card
Say Y here to compile support for HCI BlueCard devices into the
kernel or say M to compile it as module (bluecard_cs.o).
config BT_HCIBTUART
tristate "HCI UART (PC Card) device driver"
depends on PCMCIA && BT
help
Bluetooth HCI UART (PC Card) driver.
This driver provides support for Bluetooth PCMCIA devices with
an UART interface:
Xircom CreditCard Bluetooth Adapter
Xircom RealPort2 Bluetooth Adapter
Sphinx PICO Card
H-Soft blue+Card
Cyber-blue Compact Flash Card
Say Y here to compile support for HCI UART devices into the
kernel or say M to compile it as module (btuart_cs.o).
config BT_HCIVHCI
tristate "HCI VHCI (Virtual HCI device) driver"
depends on BT
......
......@@ -8,6 +8,7 @@ obj-$(CONFIG_BT_HCIUART) += hci_uart.o
obj-$(CONFIG_BT_HCIDTL1) += dtl1_cs.o
obj-$(CONFIG_BT_HCIBT3C) += bt3c_cs.o
obj-$(CONFIG_BT_HCIBLUECARD) += bluecard_cs.o
obj-$(CONFIG_BT_HCIBTUART) += btuart_cs.o
hci_uart-y := hci_ldisc.o
hci_uart-$(CONFIG_BT_HCIUART_H4) += hci_h4.o
......
This diff is collapsed.
......@@ -48,6 +48,7 @@
#define HCI_PCCARD 2
#define HCI_UART 3
#define HCI_RS232 4
#define HCI_PCI 5
/* HCI device flags */
enum {
......
......@@ -224,6 +224,8 @@ struct l2cap_pinfo {
__u8 ident;
__u16 sport;
struct l2cap_conn *conn;
struct sock *next_c;
struct sock *prev_c;
......
......@@ -7,7 +7,7 @@ menu "Bluetooth support"
config BT
tristate "Bluetooth subsystem support"
---help---
help
Bluetooth is low-cost, low-power, short-range wireless technology.
It was designed as a replacement for cables and other short-range
technologies like IrDA. Bluetooth operates in personal area range
......@@ -15,12 +15,12 @@ config BT
Bluetooth can be found at <http://www.bluetooth.com/>.
Linux Bluetooth subsystem consist of several layers:
Bluetooth Core (HCI device and connection manager, scheduler)
HCI Device drivers (interface to the hardware)
L2CAP Module (L2CAP protocol)
SCO Module (SCO links)
RFCOMM Module (RFCOMM protocol)
BNEP Module (BNEP protocol)
Bluetooth Core (HCI device and connection manager, scheduler)
HCI Device drivers (interface to the hardware)
L2CAP Module (L2CAP protocol)
SCO Module (SCO links)
RFCOMM Module (RFCOMM protocol)
BNEP Module (BNEP protocol)
Say Y here to enable Linux Bluetooth support and to build Bluetooth Core
layer.
......
config BT_BNEP
tristate "BNEP protocol support"
depends on BT_L2CAP
---help---
depends on BT && BT_L2CAP
help
BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
emulation layer on top of Bluetooth. BNEP is required for Bluetooth
PAN (Personal Area Network).
......
......@@ -128,18 +128,17 @@ static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp)
return bnep_send(s, &rsp, sizeof(rsp));
}
static int bnep_ctrl_set_netfilter(struct bnep_session *s, struct sk_buff *skb)
static int bnep_ctrl_set_netfilter(struct bnep_session *s, u16 *data, int len)
{
u16 *data;
int n;
data = (void *) skb->data;
if (!skb_pull(skb, 2))
if (len < 2)
return -EILSEQ;
n = ntohs(get_unaligned(data));
data++; len -= 2;
data = (void *) skb->data;
if (!skb_pull(skb, n))
if (len < n)
return -EILSEQ;
BT_DBG("filter len %d", n);
......@@ -170,18 +169,17 @@ static int bnep_ctrl_set_netfilter(struct bnep_session *s, struct sk_buff *skb)
return 0;
}
static int bnep_ctrl_set_mcfilter(struct bnep_session *s, struct sk_buff *skb)
static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
{
u8 *data;
int n;
data = (void *) skb->data;
if (!skb_pull(skb, 2))
if (len < 2)
return -EILSEQ;
n = ntohs(get_unaligned((u16 *) data));
data = (void *) skb->data;
if (!skb_pull(skb, n))
n = ntohs(get_unaligned((u16 *) data));
data += 2; len -= 2;
if (len < n)
return -EILSEQ;
BT_DBG("filter len %d", n);
......@@ -225,12 +223,13 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, struct sk_buff *skb)
return 0;
}
static int bnep_rx_control(struct bnep_session *s, struct sk_buff *skb)
static int bnep_rx_control(struct bnep_session *s, void *data, int len)
{
u8 cmd = *(u8 *)data;
int err = 0;
u8 cmd = *(u8 *) skb->data;
skb_pull(skb, 1);
data++; len--;
switch (cmd) {
case BNEP_CMD_NOT_UNDERSTOOD:
case BNEP_SETUP_CONN_REQ:
......@@ -239,13 +238,13 @@ static int bnep_rx_control(struct bnep_session *s, struct sk_buff *skb)
case BNEP_FILTER_MULTI_ADDR_RSP:
/* Ignore these for now */
break;
case BNEP_FILTER_NET_TYPE_SET:
err = bnep_ctrl_set_netfilter(s, skb);
err = bnep_ctrl_set_netfilter(s, data, len);
break;
case BNEP_FILTER_MULTI_ADDR_SET:
err = bnep_ctrl_set_mcfilter(s, skb);
err = bnep_ctrl_set_mcfilter(s, data, len);
break;
default: {
......@@ -274,16 +273,19 @@ static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
}
BT_DBG("type 0x%x len %d", h->type, h->len);
switch (h->type & BNEP_TYPE_MASK) {
case BNEP_EXT_CONTROL:
err = bnep_rx_control(s, skb);
bnep_rx_control(s, skb->data, skb->len);
break;
default:
/* Unknown extension */
if (!skb_pull(skb, h->len))
err = -EILSEQ;
/* Unknown extension, skip it. */
break;
}
if (!skb_pull(skb, h->len)) {
err = -EILSEQ;
break;
}
} while (!err && (h->type & BNEP_EXT_HEADER));
......@@ -315,7 +317,7 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
goto badframe;
if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
bnep_rx_control(s, skb);
bnep_rx_control(s, skb->data, skb->len);
kfree_skb(skb);
return 0;
}
......
......@@ -718,7 +718,7 @@ int hci_get_dev_list(unsigned long arg)
if (!dev_num)
return -EINVAL;
size = dev_num * sizeof(struct hci_dev_req) + sizeof(__u16);
size = dev_num * sizeof(*dr) + sizeof(*dl);
if (verify_area(VERIFY_WRITE, (void *) arg, size))
return -EFAULT;
......@@ -739,7 +739,7 @@ int hci_get_dev_list(unsigned long arg)
read_unlock_bh(&hci_dev_list_lock);
dl->dev_num = n;
size = n * sizeof(struct hci_dev_req) + sizeof(__u16);
size = n * sizeof(*dr) + sizeof(*dl);
copy_to_user((void *) arg, dl, size);
kfree(dl);
......
......@@ -186,69 +186,12 @@ static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, stru
write_unlock(&l->lock);
}
int l2cap_connect(struct sock *sk)
{
bdaddr_t *src = &bt_sk(sk)->src;
bdaddr_t *dst = &bt_sk(sk)->dst;
struct l2cap_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
int err = 0;
BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
if (!(hdev = hci_get_route(dst, src)))
return -EHOSTUNREACH;
hci_dev_lock_bh(hdev);
err = -ENOMEM;
hcon = hci_connect(hdev, ACL_LINK, dst);
if (!hcon)
goto done;
conn = l2cap_conn_add(hcon, 0);
if (!conn) {
hci_conn_put(hcon);
goto done;
}
err = 0;
/* Update source addr of the socket */
bacpy(src, conn->src);
l2cap_chan_add(conn, sk, NULL);
sk->state = BT_CONNECT;
l2cap_sock_set_timer(sk, sk->sndtimeo);
if (hcon->state == BT_CONNECTED) {
if (sk->type == SOCK_SEQPACKET) {
struct l2cap_conn_req req;
req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
req.psm = l2cap_pi(sk)->psm;
l2cap_send_req(conn, L2CAP_CONN_REQ, sizeof(req), &req);
} else {
l2cap_sock_clear_timer(sk);
sk->state = BT_CONNECTED;
}
}
done:
hci_dev_unlock_bh(hdev);
hci_dev_put(hdev);
return err;
}
/* ---- Socket interface ---- */
static struct sock *__l2cap_get_sock_by_addr(u16 psm, bdaddr_t *src)
{
struct sock *sk;
for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
if (l2cap_pi(sk)->psm == psm &&
!bacmp(&bt_sk(sk)->src, src))
if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
break;
}
return sk;
......@@ -437,7 +380,10 @@ static int l2cap_sock_create(struct socket *sock, int protocol)
if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT;
if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW))
return -EPERM;
sock->ops = &l2cap_sock_ops;
sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL);
......@@ -472,7 +418,8 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_
} else {
/* Save source address */
bacpy(&bt_sk(sk)->src, &la->l2_bdaddr);
l2cap_pi(sk)->psm = la->l2_psm;
l2cap_pi(sk)->psm = la->l2_psm;
l2cap_pi(sk)->sport = la->l2_psm;
sk->state = BT_BOUND;
}
write_unlock_bh(&l2cap_sk_list.lock);
......@@ -482,6 +429,62 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_
return err;
}
static int l2cap_do_connect(struct sock *sk)
{
bdaddr_t *src = &bt_sk(sk)->src;
bdaddr_t *dst = &bt_sk(sk)->dst;
struct l2cap_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
int err = 0;
BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
if (!(hdev = hci_get_route(dst, src)))
return -EHOSTUNREACH;
hci_dev_lock_bh(hdev);
err = -ENOMEM;
hcon = hci_connect(hdev, ACL_LINK, dst);
if (!hcon)
goto done;
conn = l2cap_conn_add(hcon, 0);
if (!conn) {
hci_conn_put(hcon);
goto done;
}
err = 0;
/* Update source addr of the socket */
bacpy(src, conn->src);
l2cap_chan_add(conn, sk, NULL);
sk->state = BT_CONNECT;
l2cap_sock_set_timer(sk, sk->sndtimeo);
if (hcon->state == BT_CONNECTED) {
if (sk->type == SOCK_SEQPACKET) {
struct l2cap_conn_req req;
req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
req.psm = l2cap_pi(sk)->psm;
l2cap_send_req(conn, L2CAP_CONN_REQ, sizeof(req), &req);
} else {
l2cap_sock_clear_timer(sk);
sk->state = BT_CONNECTED;
}
}
done:
hci_dev_unlock_bh(hdev);
hci_dev_put(hdev);
return err;
}
static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
{
struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
......@@ -527,7 +530,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
bacpy(&bt_sk(sk)->dst, &la->l2_bdaddr);
l2cap_pi(sk)->psm = la->l2_psm;
if ((err = l2cap_connect(sk)))
if ((err = l2cap_do_connect(sk)))
goto done;
wait:
......@@ -2074,7 +2077,7 @@ static int __init l2cap_proc_init(void)
static void __init l2cap_proc_cleanup(void)
{
return 0;
return;
}
#endif /* CONFIG_PROC_FS */
......
config BT_RFCOMM
tristate "RFCOMM protocol support"
depends on BT_L2CAP
depends on BT && BT_L2CAP
help
RFCOMM provides connection oriented stream transport. RFCOMM
support is required for Dialup Networking, OBEX and other Bluetooth
......
......@@ -1312,6 +1312,9 @@ static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
rfcomm_send_test(s, 0, skb->data, skb->len);
break;
case RFCOMM_NSC:
break;
default:
BT_ERR("Unknown control type 0x%02x", type);
rfcomm_send_nsc(s, cr, type);
......@@ -1442,7 +1445,7 @@ static inline int rfcomm_process_tx(struct rfcomm_dlc *d)
/* Send pending MSC */
if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
rfcomm_send_msc(d->session, d->dlci, 1, d->v24_sig);
rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
if (d->credits) {
/* CFC enabled.
......@@ -1831,7 +1834,7 @@ static int __init rfcomm_proc_init(void)
static void __init rfcomm_proc_cleanup(void)
{
return 0;
return;
}
#endif /* CONFIG_PROC_FS */
......
......@@ -851,7 +851,7 @@ static int __init rfcomm_sock_proc_init(void)
static void __init rfcomm_sock_proc_cleanup(void)
{
return 0;
return;
}
#endif /* CONFIG_PROC_FS */
......
......@@ -442,7 +442,7 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
struct tty_struct *tty;
if (!dev || !(tty = dev->tty)) {
kfree(skb);
kfree_skb(skb);
return;
}
......@@ -669,12 +669,12 @@ static int rfcomm_tty_set_modem_status(uint cmd, struct rfcomm_dlc *dlc, uint st
else
rfcomm_dlc_get_modem_status(dlc, &v24_sig);
mask = (status & TIOCM_DSR) ? RFCOMM_V24_RTC : 0 |
(status & TIOCM_DTR) ? RFCOMM_V24_RTC : 0 |
(status & TIOCM_RTS) ? RFCOMM_V24_RTR : 0 |
(status & TIOCM_CTS) ? RFCOMM_V24_RTR : 0 |
(status & TIOCM_RI) ? RFCOMM_V24_IC : 0 |
(status & TIOCM_CD) ? RFCOMM_V24_DV : 0;
mask = ((status & TIOCM_DSR) ? RFCOMM_V24_RTC : 0) |
((status & TIOCM_DTR) ? RFCOMM_V24_RTC : 0) |
((status & TIOCM_RTS) ? RFCOMM_V24_RTR : 0) |
((status & TIOCM_CTS) ? RFCOMM_V24_RTR : 0) |
((status & TIOCM_RI) ? RFCOMM_V24_IC : 0) |
((status & TIOCM_CD) ? RFCOMM_V24_DV : 0);
if (cmd == TIOCMBIC)
v24_sig &= ~mask;
......
......@@ -962,7 +962,7 @@ static int __init sco_proc_init(void)
static void __init sco_proc_cleanup(void)
{
return 0;
return;
}
#endif /* CONFIG_PROC_FS */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment