diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-10-30 01:58:41 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-30 01:58:41 -0500 |
commit | fce45c1c8a6b5334fa88bbb9b1496b0699d3fef0 (patch) | |
tree | cba2597077cf33d122f8d771bf84618cc5374cf6 /drivers/bluetooth | |
parent | 15dbb5a3f971a28040ae6cbcd8bbdf19b629fa83 (diff) | |
parent | 81cfb8864c73230eb1c37753aba517db15cf4d8f (diff) |
Merge branch 'upstream'
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/Kconfig | 8 | ||||
-rw-r--r-- | drivers/bluetooth/bpa10x.c | 3 | ||||
-rw-r--r-- | drivers/bluetooth/hci_bcsp.c | 160 | ||||
-rw-r--r-- | drivers/bluetooth/hci_bcsp.h | 70 | ||||
-rw-r--r-- | drivers/bluetooth/hci_h4.c | 101 | ||||
-rw-r--r-- | drivers/bluetooth/hci_h4.h | 44 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ldisc.c | 134 | ||||
-rw-r--r-- | drivers/bluetooth/hci_uart.h | 84 |
8 files changed, 278 insertions, 326 deletions
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 543f93e0f23f..b9fbe6e7f9ae 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig | |||
@@ -55,14 +55,6 @@ config BT_HCIUART_BCSP | |||
55 | 55 | ||
56 | Say Y here to compile support for HCI BCSP protocol. | 56 | Say Y here to compile support for HCI BCSP protocol. |
57 | 57 | ||
58 | config BT_HCIUART_BCSP_TXCRC | ||
59 | bool "Transmit CRC with every BCSP packet" | ||
60 | depends on BT_HCIUART_BCSP | ||
61 | help | ||
62 | If you say Y here, a 16-bit CRC checksum will be transmitted along with | ||
63 | every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip. | ||
64 | This increases reliability, but slightly reduces efficiency. | ||
65 | |||
66 | config BT_HCIBCM203X | 58 | config BT_HCIBCM203X |
67 | tristate "HCI BCM203x USB driver" | 59 | tristate "HCI BCM203x USB driver" |
68 | depends on USB | 60 | depends on USB |
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c index 4fa85234d8b5..0db0400519c9 100644 --- a/drivers/bluetooth/bpa10x.c +++ b/drivers/bluetooth/bpa10x.c | |||
@@ -550,6 +550,9 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id * | |||
550 | if (ignore) | 550 | if (ignore) |
551 | return -ENODEV; | 551 | return -ENODEV; |
552 | 552 | ||
553 | if (intf->cur_altsetting->desc.bInterfaceNumber > 0) | ||
554 | return -ENODEV; | ||
555 | |||
553 | data = kmalloc(sizeof(*data), GFP_KERNEL); | 556 | data = kmalloc(sizeof(*data), GFP_KERNEL); |
554 | if (!data) { | 557 | if (!data) { |
555 | BT_ERR("Can't allocate data structure"); | 558 | BT_ERR("Can't allocate data structure"); |
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c index 0ee324e1265d..0a4761415ac3 100644 --- a/drivers/bluetooth/hci_bcsp.c +++ b/drivers/bluetooth/hci_bcsp.c | |||
@@ -1,35 +1,27 @@ | |||
1 | /* | ||
2 | BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ). | ||
3 | Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com> | ||
4 | |||
5 | Based on | ||
6 | hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com> | ||
7 | ABCSP by Carl Orsborn <cjo@csr.com> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License version 2 as | ||
11 | published by the Free Software Foundation; | ||
12 | |||
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
14 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
16 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
17 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
18 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
19 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
20 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
21 | |||
22 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
23 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
24 | SOFTWARE IS DISCLAIMED. | ||
25 | */ | ||
26 | |||
27 | /* | 1 | /* |
28 | * $Id: hci_bcsp.c,v 1.2 2002/09/26 05:05:14 maxk Exp $ | 2 | * |
3 | * Bluetooth HCI UART driver | ||
4 | * | ||
5 | * Copyright (C) 2002-2003 Fabrizio Gennari <fabrizio.gennari@philips.com> | ||
6 | * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org> | ||
7 | * | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
29 | */ | 23 | */ |
30 | 24 | ||
31 | #define VERSION "0.2" | ||
32 | |||
33 | #include <linux/config.h> | 25 | #include <linux/config.h> |
34 | #include <linux/module.h> | 26 | #include <linux/module.h> |
35 | 27 | ||
@@ -52,16 +44,56 @@ | |||
52 | 44 | ||
53 | #include <net/bluetooth/bluetooth.h> | 45 | #include <net/bluetooth/bluetooth.h> |
54 | #include <net/bluetooth/hci_core.h> | 46 | #include <net/bluetooth/hci_core.h> |
47 | |||
55 | #include "hci_uart.h" | 48 | #include "hci_uart.h" |
56 | #include "hci_bcsp.h" | ||
57 | 49 | ||
58 | #ifndef CONFIG_BT_HCIUART_DEBUG | 50 | #ifndef CONFIG_BT_HCIUART_DEBUG |
59 | #undef BT_DBG | 51 | #undef BT_DBG |
60 | #define BT_DBG( A... ) | 52 | #define BT_DBG( A... ) |
61 | #endif | 53 | #endif |
62 | 54 | ||
55 | #define VERSION "0.3" | ||
56 | |||
57 | static int txcrc = 1; | ||
63 | static int hciextn = 1; | 58 | static int hciextn = 1; |
64 | 59 | ||
60 | #define BCSP_TXWINSIZE 4 | ||
61 | |||
62 | #define BCSP_ACK_PKT 0x05 | ||
63 | #define BCSP_LE_PKT 0x06 | ||
64 | |||
65 | struct bcsp_struct { | ||
66 | struct sk_buff_head unack; /* Unack'ed packets queue */ | ||
67 | struct sk_buff_head rel; /* Reliable packets queue */ | ||
68 | struct sk_buff_head unrel; /* Unreliable packets queue */ | ||
69 | |||
70 | unsigned long rx_count; | ||
71 | struct sk_buff *rx_skb; | ||
72 | u8 rxseq_txack; /* rxseq == txack. */ | ||
73 | u8 rxack; /* Last packet sent by us that the peer ack'ed */ | ||
74 | struct timer_list tbcsp; | ||
75 | |||
76 | enum { | ||
77 | BCSP_W4_PKT_DELIMITER, | ||
78 | BCSP_W4_PKT_START, | ||
79 | BCSP_W4_BCSP_HDR, | ||
80 | BCSP_W4_DATA, | ||
81 | BCSP_W4_CRC | ||
82 | } rx_state; | ||
83 | |||
84 | enum { | ||
85 | BCSP_ESCSTATE_NOESC, | ||
86 | BCSP_ESCSTATE_ESC | ||
87 | } rx_esc_state; | ||
88 | |||
89 | u8 use_crc; | ||
90 | u16 message_crc; | ||
91 | u8 txack_req; /* Do we need to send ack's to the peer? */ | ||
92 | |||
93 | /* Reliable packet sequence number - used to assign seq to each rel pkt. */ | ||
94 | u8 msgq_txseq; | ||
95 | }; | ||
96 | |||
65 | /* ---- BCSP CRC calculation ---- */ | 97 | /* ---- BCSP CRC calculation ---- */ |
66 | 98 | ||
67 | /* Table for calculating CRC for polynomial 0x1021, LSB processed first, | 99 | /* Table for calculating CRC for polynomial 0x1021, LSB processed first, |
@@ -111,6 +143,7 @@ static u16 bcsp_crc_reverse(u16 crc) | |||
111 | rev |= (crc & 1); | 143 | rev |= (crc & 1); |
112 | crc = crc >> 1; | 144 | crc = crc >> 1; |
113 | } | 145 | } |
146 | |||
114 | return (rev); | 147 | return (rev); |
115 | } | 148 | } |
116 | 149 | ||
@@ -119,6 +152,7 @@ static u16 bcsp_crc_reverse(u16 crc) | |||
119 | static void bcsp_slip_msgdelim(struct sk_buff *skb) | 152 | static void bcsp_slip_msgdelim(struct sk_buff *skb) |
120 | { | 153 | { |
121 | const char pkt_delim = 0xc0; | 154 | const char pkt_delim = 0xc0; |
155 | |||
122 | memcpy(skb_put(skb, 1), &pkt_delim, 1); | 156 | memcpy(skb_put(skb, 1), &pkt_delim, 1); |
123 | } | 157 | } |
124 | 158 | ||
@@ -173,11 +207,8 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data, | |||
173 | { | 207 | { |
174 | struct sk_buff *nskb; | 208 | struct sk_buff *nskb; |
175 | u8 hdr[4], chan; | 209 | u8 hdr[4], chan; |
176 | int rel, i; | ||
177 | |||
178 | #ifdef CONFIG_BT_HCIUART_BCSP_TXCRC | ||
179 | u16 BCSP_CRC_INIT(bcsp_txmsg_crc); | 210 | u16 BCSP_CRC_INIT(bcsp_txmsg_crc); |
180 | #endif | 211 | int rel, i; |
181 | 212 | ||
182 | switch (pkt_type) { | 213 | switch (pkt_type) { |
183 | case HCI_ACLDATA_PKT: | 214 | case HCI_ACLDATA_PKT: |
@@ -240,9 +271,9 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data, | |||
240 | BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq); | 271 | BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq); |
241 | bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07; | 272 | bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07; |
242 | } | 273 | } |
243 | #ifdef CONFIG_BT_HCIUART_BCSP_TXCRC | 274 | |
244 | hdr[0] |= 0x40; | 275 | if (bcsp->use_crc) |
245 | #endif | 276 | hdr[0] |= 0x40; |
246 | 277 | ||
247 | hdr[1] = ((len << 4) & 0xff) | chan; | 278 | hdr[1] = ((len << 4) & 0xff) | chan; |
248 | hdr[2] = len >> 4; | 279 | hdr[2] = len >> 4; |
@@ -251,25 +282,25 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data, | |||
251 | /* Put BCSP header */ | 282 | /* Put BCSP header */ |
252 | for (i = 0; i < 4; i++) { | 283 | for (i = 0; i < 4; i++) { |
253 | bcsp_slip_one_byte(nskb, hdr[i]); | 284 | bcsp_slip_one_byte(nskb, hdr[i]); |
254 | #ifdef CONFIG_BT_HCIUART_BCSP_TXCRC | 285 | |
255 | bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]); | 286 | if (bcsp->use_crc) |
256 | #endif | 287 | bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]); |
257 | } | 288 | } |
258 | 289 | ||
259 | /* Put payload */ | 290 | /* Put payload */ |
260 | for (i = 0; i < len; i++) { | 291 | for (i = 0; i < len; i++) { |
261 | bcsp_slip_one_byte(nskb, data[i]); | 292 | bcsp_slip_one_byte(nskb, data[i]); |
262 | #ifdef CONFIG_BT_HCIUART_BCSP_TXCRC | 293 | |
263 | bcsp_crc_update(&bcsp_txmsg_crc, data[i]); | 294 | if (bcsp->use_crc) |
264 | #endif | 295 | bcsp_crc_update(&bcsp_txmsg_crc, data[i]); |
265 | } | 296 | } |
266 | 297 | ||
267 | #ifdef CONFIG_BT_HCIUART_BCSP_TXCRC | ||
268 | /* Put CRC */ | 298 | /* Put CRC */ |
269 | bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc); | 299 | if (bcsp->use_crc) { |
270 | bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff)); | 300 | bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc); |
271 | bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff)); | 301 | bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff)); |
272 | #endif | 302 | bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff)); |
303 | } | ||
273 | 304 | ||
274 | bcsp_slip_msgdelim(nskb); | 305 | bcsp_slip_msgdelim(nskb); |
275 | return nskb; | 306 | return nskb; |
@@ -317,7 +348,6 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu) | |||
317 | 348 | ||
318 | spin_unlock_irqrestore(&bcsp->unack.lock, flags); | 349 | spin_unlock_irqrestore(&bcsp->unack.lock, flags); |
319 | 350 | ||
320 | |||
321 | /* We could not send a reliable packet, either because there are | 351 | /* We could not send a reliable packet, either because there are |
322 | none or because there are too many unack'ed pkts. Did we receive | 352 | none or because there are too many unack'ed pkts. Did we receive |
323 | any packets we have not acknowledged yet ? */ | 353 | any packets we have not acknowledged yet ? */ |
@@ -363,7 +393,7 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp) | |||
363 | BT_ERR("Peer acked invalid packet"); | 393 | BT_ERR("Peer acked invalid packet"); |
364 | 394 | ||
365 | BT_DBG("Removing %u pkts out of %u, up to seqno %u", | 395 | BT_DBG("Removing %u pkts out of %u, up to seqno %u", |
366 | pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07); | 396 | pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07); |
367 | 397 | ||
368 | for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed | 398 | for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed |
369 | && skb != (struct sk_buff *) &bcsp->unack; i++) { | 399 | && skb != (struct sk_buff *) &bcsp->unack; i++) { |
@@ -374,8 +404,10 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp) | |||
374 | kfree_skb(skb); | 404 | kfree_skb(skb); |
375 | skb = nskb; | 405 | skb = nskb; |
376 | } | 406 | } |
407 | |||
377 | if (bcsp->unack.qlen == 0) | 408 | if (bcsp->unack.qlen == 0) |
378 | del_timer(&bcsp->tbcsp); | 409 | del_timer(&bcsp->tbcsp); |
410 | |||
379 | spin_unlock_irqrestore(&bcsp->unack.lock, flags); | 411 | spin_unlock_irqrestore(&bcsp->unack.lock, flags); |
380 | 412 | ||
381 | if (i != pkts_to_be_removed) | 413 | if (i != pkts_to_be_removed) |
@@ -530,6 +562,7 @@ static inline void bcsp_complete_rx_pkt(struct hci_uart *hu) | |||
530 | 562 | ||
531 | hci_recv_frame(bcsp->rx_skb); | 563 | hci_recv_frame(bcsp->rx_skb); |
532 | } | 564 | } |
565 | |||
533 | bcsp->rx_state = BCSP_W4_PKT_DELIMITER; | 566 | bcsp->rx_state = BCSP_W4_PKT_DELIMITER; |
534 | bcsp->rx_skb = NULL; | 567 | bcsp->rx_skb = NULL; |
535 | } | 568 | } |
@@ -598,8 +631,8 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count) | |||
598 | 631 | ||
599 | BT_ERR ("Checksum failed: computed %04x received %04x", | 632 | BT_ERR ("Checksum failed: computed %04x received %04x", |
600 | bcsp_crc_reverse(bcsp->message_crc), | 633 | bcsp_crc_reverse(bcsp->message_crc), |
601 | (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) + | 634 | (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) + |
602 | bcsp->rx_skb->data[bcsp->rx_skb->len - 1]); | 635 | bcsp->rx_skb->data[bcsp->rx_skb->len - 1]); |
603 | 636 | ||
604 | kfree_skb(bcsp->rx_skb); | 637 | kfree_skb(bcsp->rx_skb); |
605 | bcsp->rx_state = BCSP_W4_PKT_DELIMITER; | 638 | bcsp->rx_state = BCSP_W4_PKT_DELIMITER; |
@@ -633,7 +666,7 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count) | |||
633 | bcsp->rx_count = 4; | 666 | bcsp->rx_count = 4; |
634 | bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC; | 667 | bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC; |
635 | BCSP_CRC_INIT(bcsp->message_crc); | 668 | BCSP_CRC_INIT(bcsp->message_crc); |
636 | 669 | ||
637 | /* Do not increment ptr or decrement count | 670 | /* Do not increment ptr or decrement count |
638 | * Allocate packet. Max len of a BCSP pkt= | 671 | * Allocate packet. Max len of a BCSP pkt= |
639 | * 0xFFF (payload) +4 (header) +2 (crc) */ | 672 | * 0xFFF (payload) +4 (header) +2 (crc) */ |
@@ -698,6 +731,9 @@ static int bcsp_open(struct hci_uart *hu) | |||
698 | 731 | ||
699 | bcsp->rx_state = BCSP_W4_PKT_DELIMITER; | 732 | bcsp->rx_state = BCSP_W4_PKT_DELIMITER; |
700 | 733 | ||
734 | if (txcrc) | ||
735 | bcsp->use_crc = 1; | ||
736 | |||
701 | return 0; | 737 | return 0; |
702 | } | 738 | } |
703 | 739 | ||
@@ -718,18 +754,19 @@ static int bcsp_close(struct hci_uart *hu) | |||
718 | } | 754 | } |
719 | 755 | ||
720 | static struct hci_uart_proto bcsp = { | 756 | static struct hci_uart_proto bcsp = { |
721 | .id = HCI_UART_BCSP, | 757 | .id = HCI_UART_BCSP, |
722 | .open = bcsp_open, | 758 | .open = bcsp_open, |
723 | .close = bcsp_close, | 759 | .close = bcsp_close, |
724 | .enqueue = bcsp_enqueue, | 760 | .enqueue = bcsp_enqueue, |
725 | .dequeue = bcsp_dequeue, | 761 | .dequeue = bcsp_dequeue, |
726 | .recv = bcsp_recv, | 762 | .recv = bcsp_recv, |
727 | .flush = bcsp_flush | 763 | .flush = bcsp_flush |
728 | }; | 764 | }; |
729 | 765 | ||
730 | int bcsp_init(void) | 766 | int bcsp_init(void) |
731 | { | 767 | { |
732 | int err = hci_uart_register_proto(&bcsp); | 768 | int err = hci_uart_register_proto(&bcsp); |
769 | |||
733 | if (!err) | 770 | if (!err) |
734 | BT_INFO("HCI BCSP protocol initialized"); | 771 | BT_INFO("HCI BCSP protocol initialized"); |
735 | else | 772 | else |
@@ -743,5 +780,8 @@ int bcsp_deinit(void) | |||
743 | return hci_uart_unregister_proto(&bcsp); | 780 | return hci_uart_unregister_proto(&bcsp); |
744 | } | 781 | } |
745 | 782 | ||
783 | module_param(txcrc, bool, 0644); | ||
784 | MODULE_PARM_DESC(txcrc, "Transmit CRC with every BCSP packet"); | ||
785 | |||
746 | module_param(hciextn, bool, 0644); | 786 | module_param(hciextn, bool, 0644); |
747 | MODULE_PARM_DESC(hciextn, "Convert HCI Extensions into BCSP packets"); | 787 | MODULE_PARM_DESC(hciextn, "Convert HCI Extensions into BCSP packets"); |
diff --git a/drivers/bluetooth/hci_bcsp.h b/drivers/bluetooth/hci_bcsp.h deleted file mode 100644 index a2b3bb92274b..000000000000 --- a/drivers/bluetooth/hci_bcsp.h +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /* | ||
2 | BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ). | ||
3 | Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com> | ||
4 | |||
5 | Based on | ||
6 | hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com> | ||
7 | ABCSP by Carl Orsborn <cjo@csr.com> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License version 2 as | ||
11 | published by the Free Software Foundation; | ||
12 | |||
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
14 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
16 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
17 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
18 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
19 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
20 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
21 | |||
22 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
23 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
24 | SOFTWARE IS DISCLAIMED. | ||
25 | */ | ||
26 | |||
27 | /* | ||
28 | * $Id: hci_bcsp.h,v 1.2 2002/09/26 05:05:14 maxk Exp $ | ||
29 | */ | ||
30 | |||
31 | #ifndef __HCI_BCSP_H__ | ||
32 | #define __HCI_BCSP_H__ | ||
33 | |||
34 | #define BCSP_TXWINSIZE 4 | ||
35 | |||
36 | #define BCSP_ACK_PKT 0x05 | ||
37 | #define BCSP_LE_PKT 0x06 | ||
38 | |||
39 | struct bcsp_struct { | ||
40 | struct sk_buff_head unack; /* Unack'ed packets queue */ | ||
41 | struct sk_buff_head rel; /* Reliable packets queue */ | ||
42 | struct sk_buff_head unrel; /* Unreliable packets queue */ | ||
43 | |||
44 | unsigned long rx_count; | ||
45 | struct sk_buff *rx_skb; | ||
46 | u8 rxseq_txack; /* rxseq == txack. */ | ||
47 | u8 rxack; /* Last packet sent by us that the peer ack'ed */ | ||
48 | struct timer_list tbcsp; | ||
49 | |||
50 | enum { | ||
51 | BCSP_W4_PKT_DELIMITER, | ||
52 | BCSP_W4_PKT_START, | ||
53 | BCSP_W4_BCSP_HDR, | ||
54 | BCSP_W4_DATA, | ||
55 | BCSP_W4_CRC | ||
56 | } rx_state; | ||
57 | |||
58 | enum { | ||
59 | BCSP_ESCSTATE_NOESC, | ||
60 | BCSP_ESCSTATE_ESC | ||
61 | } rx_esc_state; | ||
62 | |||
63 | u16 message_crc; | ||
64 | u8 txack_req; /* Do we need to send ack's to the peer? */ | ||
65 | |||
66 | /* Reliable packet sequence number - used to assign seq to each rel pkt. */ | ||
67 | u8 msgq_txseq; | ||
68 | }; | ||
69 | |||
70 | #endif /* __HCI_BCSP_H__ */ | ||
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index cf8a22d58d96..12e369a66fc2 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c | |||
@@ -1,33 +1,27 @@ | |||
1 | /* | ||
2 | BlueZ - Bluetooth protocol stack for Linux | ||
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | ||
4 | |||
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License version 2 as | ||
9 | published by the Free Software Foundation; | ||
10 | |||
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
12 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
14 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
15 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
16 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
17 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
18 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
19 | |||
20 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
21 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
22 | SOFTWARE IS DISCLAIMED. | ||
23 | */ | ||
24 | |||
25 | /* | 1 | /* |
26 | * Bluetooth HCI UART(H4) protocol. | ||
27 | * | 2 | * |
28 | * $Id: hci_h4.c,v 1.3 2002/09/09 01:17:32 maxk Exp $ | 3 | * Bluetooth HCI UART driver |
4 | * | ||
5 | * Copyright (C) 2000-2001 Qualcomm Incorporated | ||
6 | * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> | ||
7 | * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org> | ||
8 | * | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | * | ||
29 | */ | 24 | */ |
30 | #define VERSION "1.2" | ||
31 | 25 | ||
32 | #include <linux/config.h> | 26 | #include <linux/config.h> |
33 | #include <linux/module.h> | 27 | #include <linux/module.h> |
@@ -51,24 +45,41 @@ | |||
51 | 45 | ||
52 | #include <net/bluetooth/bluetooth.h> | 46 | #include <net/bluetooth/bluetooth.h> |
53 | #include <net/bluetooth/hci_core.h> | 47 | #include <net/bluetooth/hci_core.h> |
48 | |||
54 | #include "hci_uart.h" | 49 | #include "hci_uart.h" |
55 | #include "hci_h4.h" | ||
56 | 50 | ||
57 | #ifndef CONFIG_BT_HCIUART_DEBUG | 51 | #ifndef CONFIG_BT_HCIUART_DEBUG |
58 | #undef BT_DBG | 52 | #undef BT_DBG |
59 | #define BT_DBG( A... ) | 53 | #define BT_DBG( A... ) |
60 | #endif | 54 | #endif |
61 | 55 | ||
56 | #define VERSION "1.2" | ||
57 | |||
58 | struct h4_struct { | ||
59 | unsigned long rx_state; | ||
60 | unsigned long rx_count; | ||
61 | struct sk_buff *rx_skb; | ||
62 | struct sk_buff_head txq; | ||
63 | }; | ||
64 | |||
65 | /* H4 receiver States */ | ||
66 | #define H4_W4_PACKET_TYPE 0 | ||
67 | #define H4_W4_EVENT_HDR 1 | ||
68 | #define H4_W4_ACL_HDR 2 | ||
69 | #define H4_W4_SCO_HDR 3 | ||
70 | #define H4_W4_DATA 4 | ||
71 | |||
62 | /* Initialize protocol */ | 72 | /* Initialize protocol */ |
63 | static int h4_open(struct hci_uart *hu) | 73 | static int h4_open(struct hci_uart *hu) |
64 | { | 74 | { |
65 | struct h4_struct *h4; | 75 | struct h4_struct *h4; |
66 | 76 | ||
67 | BT_DBG("hu %p", hu); | 77 | BT_DBG("hu %p", hu); |
68 | 78 | ||
69 | h4 = kmalloc(sizeof(*h4), GFP_ATOMIC); | 79 | h4 = kmalloc(sizeof(*h4), GFP_ATOMIC); |
70 | if (!h4) | 80 | if (!h4) |
71 | return -ENOMEM; | 81 | return -ENOMEM; |
82 | |||
72 | memset(h4, 0, sizeof(*h4)); | 83 | memset(h4, 0, sizeof(*h4)); |
73 | 84 | ||
74 | skb_queue_head_init(&h4->txq); | 85 | skb_queue_head_init(&h4->txq); |
@@ -83,7 +94,9 @@ static int h4_flush(struct hci_uart *hu) | |||
83 | struct h4_struct *h4 = hu->priv; | 94 | struct h4_struct *h4 = hu->priv; |
84 | 95 | ||
85 | BT_DBG("hu %p", hu); | 96 | BT_DBG("hu %p", hu); |
97 | |||
86 | skb_queue_purge(&h4->txq); | 98 | skb_queue_purge(&h4->txq); |
99 | |||
87 | return 0; | 100 | return 0; |
88 | } | 101 | } |
89 | 102 | ||
@@ -91,16 +104,19 @@ static int h4_flush(struct hci_uart *hu) | |||
91 | static int h4_close(struct hci_uart *hu) | 104 | static int h4_close(struct hci_uart *hu) |
92 | { | 105 | { |
93 | struct h4_struct *h4 = hu->priv; | 106 | struct h4_struct *h4 = hu->priv; |
107 | |||
94 | hu->priv = NULL; | 108 | hu->priv = NULL; |
95 | 109 | ||
96 | BT_DBG("hu %p", hu); | 110 | BT_DBG("hu %p", hu); |
97 | 111 | ||
98 | skb_queue_purge(&h4->txq); | 112 | skb_queue_purge(&h4->txq); |
113 | |||
99 | if (h4->rx_skb) | 114 | if (h4->rx_skb) |
100 | kfree_skb(h4->rx_skb); | 115 | kfree_skb(h4->rx_skb); |
101 | 116 | ||
102 | hu->priv = NULL; | 117 | hu->priv = NULL; |
103 | kfree(h4); | 118 | kfree(h4); |
119 | |||
104 | return 0; | 120 | return 0; |
105 | } | 121 | } |
106 | 122 | ||
@@ -114,6 +130,7 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb) | |||
114 | /* Prepend skb with frame type */ | 130 | /* Prepend skb with frame type */ |
115 | memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); | 131 | memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); |
116 | skb_queue_tail(&h4->txq, skb); | 132 | skb_queue_tail(&h4->txq, skb); |
133 | |||
117 | return 0; | 134 | return 0; |
118 | } | 135 | } |
119 | 136 | ||
@@ -122,6 +139,7 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len) | |||
122 | register int room = skb_tailroom(h4->rx_skb); | 139 | register int room = skb_tailroom(h4->rx_skb); |
123 | 140 | ||
124 | BT_DBG("len %d room %d", len, room); | 141 | BT_DBG("len %d room %d", len, room); |
142 | |||
125 | if (!len) { | 143 | if (!len) { |
126 | hci_recv_frame(h4->rx_skb); | 144 | hci_recv_frame(h4->rx_skb); |
127 | } else if (len > room) { | 145 | } else if (len > room) { |
@@ -136,6 +154,7 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len) | |||
136 | h4->rx_state = H4_W4_PACKET_TYPE; | 154 | h4->rx_state = H4_W4_PACKET_TYPE; |
137 | h4->rx_skb = NULL; | 155 | h4->rx_skb = NULL; |
138 | h4->rx_count = 0; | 156 | h4->rx_count = 0; |
157 | |||
139 | return 0; | 158 | return 0; |
140 | } | 159 | } |
141 | 160 | ||
@@ -228,6 +247,7 @@ static int h4_recv(struct hci_uart *hu, void *data, int count) | |||
228 | ptr++; count--; | 247 | ptr++; count--; |
229 | continue; | 248 | continue; |
230 | }; | 249 | }; |
250 | |||
231 | ptr++; count--; | 251 | ptr++; count--; |
232 | 252 | ||
233 | /* Allocate packet */ | 253 | /* Allocate packet */ |
@@ -238,9 +258,11 @@ static int h4_recv(struct hci_uart *hu, void *data, int count) | |||
238 | h4->rx_count = 0; | 258 | h4->rx_count = 0; |
239 | return 0; | 259 | return 0; |
240 | } | 260 | } |
261 | |||
241 | h4->rx_skb->dev = (void *) hu->hdev; | 262 | h4->rx_skb->dev = (void *) hu->hdev; |
242 | bt_cb(h4->rx_skb)->pkt_type = type; | 263 | bt_cb(h4->rx_skb)->pkt_type = type; |
243 | } | 264 | } |
265 | |||
244 | return count; | 266 | return count; |
245 | } | 267 | } |
246 | 268 | ||
@@ -251,23 +273,24 @@ static struct sk_buff *h4_dequeue(struct hci_uart *hu) | |||
251 | } | 273 | } |
252 | 274 | ||
253 | static struct hci_uart_proto h4p = { | 275 | static struct hci_uart_proto h4p = { |
254 | .id = HCI_UART_H4, | 276 | .id = HCI_UART_H4, |
255 | .open = h4_open, | 277 | .open = h4_open, |
256 | .close = h4_close, | 278 | .close = h4_close, |
257 | .recv = h4_recv, | 279 | .recv = h4_recv, |
258 | .enqueue = h4_enqueue, | 280 | .enqueue = h4_enqueue, |
259 | .dequeue = h4_dequeue, | 281 | .dequeue = h4_dequeue, |
260 | .flush = h4_flush, | 282 | .flush = h4_flush, |
261 | }; | 283 | }; |
262 | 284 | ||
263 | int h4_init(void) | 285 | int h4_init(void) |
264 | { | 286 | { |
265 | int err = hci_uart_register_proto(&h4p); | 287 | int err = hci_uart_register_proto(&h4p); |
288 | |||
266 | if (!err) | 289 | if (!err) |
267 | BT_INFO("HCI H4 protocol initialized"); | 290 | BT_INFO("HCI H4 protocol initialized"); |
268 | else | 291 | else |
269 | BT_ERR("HCI H4 protocol registration failed"); | 292 | BT_ERR("HCI H4 protocol registration failed"); |
270 | 293 | ||
271 | return err; | 294 | return err; |
272 | } | 295 | } |
273 | 296 | ||
diff --git a/drivers/bluetooth/hci_h4.h b/drivers/bluetooth/hci_h4.h deleted file mode 100644 index b95ff54bfd47..000000000000 --- a/drivers/bluetooth/hci_h4.h +++ /dev/null | |||
@@ -1,44 +0,0 @@ | |||
1 | /* | ||
2 | BlueZ - Bluetooth protocol stack for Linux | ||
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | ||
4 | |||
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License version 2 as | ||
9 | published by the Free Software Foundation; | ||
10 | |||
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
12 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
14 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
15 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
16 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
17 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
18 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
19 | |||
20 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
21 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
22 | SOFTWARE IS DISCLAIMED. | ||
23 | */ | ||
24 | |||
25 | /* | ||
26 | * $Id: hci_h4.h,v 1.2 2002/09/09 01:17:32 maxk Exp $ | ||
27 | */ | ||
28 | |||
29 | #ifdef __KERNEL__ | ||
30 | struct h4_struct { | ||
31 | unsigned long rx_state; | ||
32 | unsigned long rx_count; | ||
33 | struct sk_buff *rx_skb; | ||
34 | struct sk_buff_head txq; | ||
35 | }; | ||
36 | |||
37 | /* H4 receiver States */ | ||
38 | #define H4_W4_PACKET_TYPE 0 | ||
39 | #define H4_W4_EVENT_HDR 1 | ||
40 | #define H4_W4_ACL_HDR 2 | ||
41 | #define H4_W4_SCO_HDR 3 | ||
42 | #define H4_W4_DATA 4 | ||
43 | |||
44 | #endif /* __KERNEL__ */ | ||
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index aed80cc22890..4a775f6ea390 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -1,33 +1,27 @@ | |||
1 | /* | ||
2 | BlueZ - Bluetooth protocol stack for Linux | ||
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | ||
4 | |||
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License version 2 as | ||
9 | published by the Free Software Foundation; | ||
10 | |||
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
12 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
14 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
15 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
16 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
17 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
18 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
19 | |||
20 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
21 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
22 | SOFTWARE IS DISCLAIMED. | ||
23 | */ | ||
24 | |||
25 | /* | 1 | /* |
26 | * Bluetooth HCI UART driver. | ||
27 | * | 2 | * |
28 | * $Id: hci_ldisc.c,v 1.5 2002/10/02 18:37:20 maxk Exp $ | 3 | * Bluetooth HCI UART driver |
4 | * | ||
5 | * Copyright (C) 2000-2001 Qualcomm Incorporated | ||
6 | * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> | ||
7 | * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org> | ||
8 | * | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | * | ||
29 | */ | 24 | */ |
30 | #define VERSION "2.1" | ||
31 | 25 | ||
32 | #include <linux/config.h> | 26 | #include <linux/config.h> |
33 | #include <linux/module.h> | 27 | #include <linux/module.h> |
@@ -59,6 +53,8 @@ | |||
59 | #define BT_DBG( A... ) | 53 | #define BT_DBG( A... ) |
60 | #endif | 54 | #endif |
61 | 55 | ||
56 | #define VERSION "2.2" | ||
57 | |||
62 | static int reset = 0; | 58 | static int reset = 0; |
63 | 59 | ||
64 | static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO]; | 60 | static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO]; |
@@ -72,6 +68,7 @@ int hci_uart_register_proto(struct hci_uart_proto *p) | |||
72 | return -EEXIST; | 68 | return -EEXIST; |
73 | 69 | ||
74 | hup[p->id] = p; | 70 | hup[p->id] = p; |
71 | |||
75 | return 0; | 72 | return 0; |
76 | } | 73 | } |
77 | 74 | ||
@@ -84,6 +81,7 @@ int hci_uart_unregister_proto(struct hci_uart_proto *p) | |||
84 | return -EINVAL; | 81 | return -EINVAL; |
85 | 82 | ||
86 | hup[p->id] = NULL; | 83 | hup[p->id] = NULL; |
84 | |||
87 | return 0; | 85 | return 0; |
88 | } | 86 | } |
89 | 87 | ||
@@ -91,13 +89,14 @@ static struct hci_uart_proto *hci_uart_get_proto(unsigned int id) | |||
91 | { | 89 | { |
92 | if (id >= HCI_UART_MAX_PROTO) | 90 | if (id >= HCI_UART_MAX_PROTO) |
93 | return NULL; | 91 | return NULL; |
92 | |||
94 | return hup[id]; | 93 | return hup[id]; |
95 | } | 94 | } |
96 | 95 | ||
97 | static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type) | 96 | static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type) |
98 | { | 97 | { |
99 | struct hci_dev *hdev = hu->hdev; | 98 | struct hci_dev *hdev = hu->hdev; |
100 | 99 | ||
101 | /* Update HCI stat counters */ | 100 | /* Update HCI stat counters */ |
102 | switch (pkt_type) { | 101 | switch (pkt_type) { |
103 | case HCI_COMMAND_PKT: | 102 | case HCI_COMMAND_PKT: |
@@ -117,10 +116,12 @@ static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type) | |||
117 | static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu) | 116 | static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu) |
118 | { | 117 | { |
119 | struct sk_buff *skb = hu->tx_skb; | 118 | struct sk_buff *skb = hu->tx_skb; |
119 | |||
120 | if (!skb) | 120 | if (!skb) |
121 | skb = hu->proto->dequeue(hu); | 121 | skb = hu->proto->dequeue(hu); |
122 | else | 122 | else |
123 | hu->tx_skb = NULL; | 123 | hu->tx_skb = NULL; |
124 | |||
124 | return skb; | 125 | return skb; |
125 | } | 126 | } |
126 | 127 | ||
@@ -129,7 +130,7 @@ int hci_uart_tx_wakeup(struct hci_uart *hu) | |||
129 | struct tty_struct *tty = hu->tty; | 130 | struct tty_struct *tty = hu->tty; |
130 | struct hci_dev *hdev = hu->hdev; | 131 | struct hci_dev *hdev = hu->hdev; |
131 | struct sk_buff *skb; | 132 | struct sk_buff *skb; |
132 | 133 | ||
133 | if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) { | 134 | if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) { |
134 | set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state); | 135 | set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state); |
135 | return 0; | 136 | return 0; |
@@ -142,7 +143,7 @@ restart: | |||
142 | 143 | ||
143 | while ((skb = hci_uart_dequeue(hu))) { | 144 | while ((skb = hci_uart_dequeue(hu))) { |
144 | int len; | 145 | int len; |
145 | 146 | ||
146 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 147 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
147 | len = tty->driver->write(tty, skb->data, skb->len); | 148 | len = tty->driver->write(tty, skb->data, skb->len); |
148 | hdev->stat.byte_tx += len; | 149 | hdev->stat.byte_tx += len; |
@@ -152,11 +153,11 @@ restart: | |||
152 | hu->tx_skb = skb; | 153 | hu->tx_skb = skb; |
153 | break; | 154 | break; |
154 | } | 155 | } |
155 | 156 | ||
156 | hci_uart_tx_complete(hu, bt_cb(skb)->pkt_type); | 157 | hci_uart_tx_complete(hu, bt_cb(skb)->pkt_type); |
157 | kfree_skb(skb); | 158 | kfree_skb(skb); |
158 | } | 159 | } |
159 | 160 | ||
160 | if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state)) | 161 | if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state)) |
161 | goto restart; | 162 | goto restart; |
162 | 163 | ||
@@ -173,6 +174,7 @@ static int hci_uart_open(struct hci_dev *hdev) | |||
173 | /* Nothing to do for UART driver */ | 174 | /* Nothing to do for UART driver */ |
174 | 175 | ||
175 | set_bit(HCI_RUNNING, &hdev->flags); | 176 | set_bit(HCI_RUNNING, &hdev->flags); |
177 | |||
176 | return 0; | 178 | return 0; |
177 | } | 179 | } |
178 | 180 | ||
@@ -234,6 +236,7 @@ static int hci_uart_send_frame(struct sk_buff *skb) | |||
234 | hu->proto->enqueue(hu, skb); | 236 | hu->proto->enqueue(hu, skb); |
235 | 237 | ||
236 | hci_uart_tx_wakeup(hu); | 238 | hci_uart_tx_wakeup(hu); |
239 | |||
237 | return 0; | 240 | return 0; |
238 | } | 241 | } |
239 | 242 | ||
@@ -241,7 +244,8 @@ static void hci_uart_destruct(struct hci_dev *hdev) | |||
241 | { | 244 | { |
242 | struct hci_uart *hu; | 245 | struct hci_uart *hu; |
243 | 246 | ||
244 | if (!hdev) return; | 247 | if (!hdev) |
248 | return; | ||
245 | 249 | ||
246 | BT_DBG("%s", hdev->name); | 250 | BT_DBG("%s", hdev->name); |
247 | 251 | ||
@@ -272,6 +276,7 @@ static int hci_uart_tty_open(struct tty_struct *tty) | |||
272 | BT_ERR("Can't allocate controll structure"); | 276 | BT_ERR("Can't allocate controll structure"); |
273 | return -ENFILE; | 277 | return -ENFILE; |
274 | } | 278 | } |
279 | |||
275 | memset(hu, 0, sizeof(struct hci_uart)); | 280 | memset(hu, 0, sizeof(struct hci_uart)); |
276 | 281 | ||
277 | tty->disc_data = hu; | 282 | tty->disc_data = hu; |
@@ -280,8 +285,10 @@ static int hci_uart_tty_open(struct tty_struct *tty) | |||
280 | spin_lock_init(&hu->rx_lock); | 285 | spin_lock_init(&hu->rx_lock); |
281 | 286 | ||
282 | /* Flush any pending characters in the driver and line discipline. */ | 287 | /* Flush any pending characters in the driver and line discipline. */ |
288 | |||
283 | /* FIXME: why is this needed. Note don't use ldisc_ref here as the | 289 | /* FIXME: why is this needed. Note don't use ldisc_ref here as the |
284 | open path is before the ldisc is referencable */ | 290 | open path is before the ldisc is referencable */ |
291 | |||
285 | if (tty->ldisc.flush_buffer) | 292 | if (tty->ldisc.flush_buffer) |
286 | tty->ldisc.flush_buffer(tty); | 293 | tty->ldisc.flush_buffer(tty); |
287 | 294 | ||
@@ -372,13 +379,13 @@ static int hci_uart_tty_room (struct tty_struct *tty) | |||
372 | static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count) | 379 | static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count) |
373 | { | 380 | { |
374 | struct hci_uart *hu = (void *)tty->disc_data; | 381 | struct hci_uart *hu = (void *)tty->disc_data; |
375 | 382 | ||
376 | if (!hu || tty != hu->tty) | 383 | if (!hu || tty != hu->tty) |
377 | return; | 384 | return; |
378 | 385 | ||
379 | if (!test_bit(HCI_UART_PROTO_SET, &hu->flags)) | 386 | if (!test_bit(HCI_UART_PROTO_SET, &hu->flags)) |
380 | return; | 387 | return; |
381 | 388 | ||
382 | spin_lock(&hu->rx_lock); | 389 | spin_lock(&hu->rx_lock); |
383 | hu->proto->recv(hu, (void *) data, count); | 390 | hu->proto->recv(hu, (void *) data, count); |
384 | hu->hdev->stat.byte_rx += count; | 391 | hu->hdev->stat.byte_rx += count; |
@@ -429,8 +436,8 @@ static int hci_uart_register_dev(struct hci_uart *hu) | |||
429 | static int hci_uart_set_proto(struct hci_uart *hu, int id) | 436 | static int hci_uart_set_proto(struct hci_uart *hu, int id) |
430 | { | 437 | { |
431 | struct hci_uart_proto *p; | 438 | struct hci_uart_proto *p; |
432 | int err; | 439 | int err; |
433 | 440 | ||
434 | p = hci_uart_get_proto(id); | 441 | p = hci_uart_get_proto(id); |
435 | if (!p) | 442 | if (!p) |
436 | return -EPROTONOSUPPORT; | 443 | return -EPROTONOSUPPORT; |
@@ -446,6 +453,7 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id) | |||
446 | p->close(hu); | 453 | p->close(hu); |
447 | return err; | 454 | return err; |
448 | } | 455 | } |
456 | |||
449 | return 0; | 457 | return 0; |
450 | } | 458 | } |
451 | 459 | ||
@@ -463,7 +471,7 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id) | |||
463 | * Return Value: Command dependent | 471 | * Return Value: Command dependent |
464 | */ | 472 | */ |
465 | static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file, | 473 | static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file, |
466 | unsigned int cmd, unsigned long arg) | 474 | unsigned int cmd, unsigned long arg) |
467 | { | 475 | { |
468 | struct hci_uart *hu = (void *)tty->disc_data; | 476 | struct hci_uart *hu = (void *)tty->disc_data; |
469 | int err = 0; | 477 | int err = 0; |
@@ -483,14 +491,14 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file, | |||
483 | return err; | 491 | return err; |
484 | } | 492 | } |
485 | tty->low_latency = 1; | 493 | tty->low_latency = 1; |
486 | } else | 494 | } else |
487 | return -EBUSY; | 495 | return -EBUSY; |
488 | 496 | ||
489 | case HCIUARTGETPROTO: | 497 | case HCIUARTGETPROTO: |
490 | if (test_bit(HCI_UART_PROTO_SET, &hu->flags)) | 498 | if (test_bit(HCI_UART_PROTO_SET, &hu->flags)) |
491 | return hu->proto->id; | 499 | return hu->proto->id; |
492 | return -EUNATCH; | 500 | return -EUNATCH; |
493 | 501 | ||
494 | default: | 502 | default: |
495 | err = n_tty_ioctl(tty, file, cmd, arg); | 503 | err = n_tty_ioctl(tty, file, cmd, arg); |
496 | break; | 504 | break; |
@@ -502,28 +510,24 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file, | |||
502 | /* | 510 | /* |
503 | * We don't provide read/write/poll interface for user space. | 511 | * We don't provide read/write/poll interface for user space. |
504 | */ | 512 | */ |
505 | static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char __user *buf, size_t nr) | 513 | static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, |
514 | unsigned char __user *buf, size_t nr) | ||
506 | { | 515 | { |
507 | return 0; | 516 | return 0; |
508 | } | 517 | } |
509 | static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count) | 518 | |
519 | static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, | ||
520 | const unsigned char *data, size_t count) | ||
510 | { | 521 | { |
511 | return 0; | 522 | return 0; |
512 | } | 523 | } |
513 | static unsigned int hci_uart_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait) | 524 | |
525 | static unsigned int hci_uart_tty_poll(struct tty_struct *tty, | ||
526 | struct file *filp, poll_table *wait) | ||
514 | { | 527 | { |
515 | return 0; | 528 | return 0; |
516 | } | 529 | } |
517 | 530 | ||
518 | #ifdef CONFIG_BT_HCIUART_H4 | ||
519 | int h4_init(void); | ||
520 | int h4_deinit(void); | ||
521 | #endif | ||
522 | #ifdef CONFIG_BT_HCIUART_BCSP | ||
523 | int bcsp_init(void); | ||
524 | int bcsp_deinit(void); | ||
525 | #endif | ||
526 | |||
527 | static int __init hci_uart_init(void) | 531 | static int __init hci_uart_init(void) |
528 | { | 532 | { |
529 | static struct tty_ldisc hci_uart_ldisc; | 533 | static struct tty_ldisc hci_uart_ldisc; |
@@ -534,18 +538,18 @@ static int __init hci_uart_init(void) | |||
534 | /* Register the tty discipline */ | 538 | /* Register the tty discipline */ |
535 | 539 | ||
536 | memset(&hci_uart_ldisc, 0, sizeof (hci_uart_ldisc)); | 540 | memset(&hci_uart_ldisc, 0, sizeof (hci_uart_ldisc)); |
537 | hci_uart_ldisc.magic = TTY_LDISC_MAGIC; | 541 | hci_uart_ldisc.magic = TTY_LDISC_MAGIC; |
538 | hci_uart_ldisc.name = "n_hci"; | 542 | hci_uart_ldisc.name = "n_hci"; |
539 | hci_uart_ldisc.open = hci_uart_tty_open; | 543 | hci_uart_ldisc.open = hci_uart_tty_open; |
540 | hci_uart_ldisc.close = hci_uart_tty_close; | 544 | hci_uart_ldisc.close = hci_uart_tty_close; |
541 | hci_uart_ldisc.read = hci_uart_tty_read; | 545 | hci_uart_ldisc.read = hci_uart_tty_read; |
542 | hci_uart_ldisc.write = hci_uart_tty_write; | 546 | hci_uart_ldisc.write = hci_uart_tty_write; |
543 | hci_uart_ldisc.ioctl = hci_uart_tty_ioctl; | 547 | hci_uart_ldisc.ioctl = hci_uart_tty_ioctl; |
544 | hci_uart_ldisc.poll = hci_uart_tty_poll; | 548 | hci_uart_ldisc.poll = hci_uart_tty_poll; |
545 | hci_uart_ldisc.receive_room= hci_uart_tty_room; | 549 | hci_uart_ldisc.receive_room = hci_uart_tty_room; |
546 | hci_uart_ldisc.receive_buf = hci_uart_tty_receive; | 550 | hci_uart_ldisc.receive_buf = hci_uart_tty_receive; |
547 | hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup; | 551 | hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup; |
548 | hci_uart_ldisc.owner = THIS_MODULE; | 552 | hci_uart_ldisc.owner = THIS_MODULE; |
549 | 553 | ||
550 | if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) { | 554 | if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) { |
551 | BT_ERR("HCI line discipline registration failed. (%d)", err); | 555 | BT_ERR("HCI line discipline registration failed. (%d)", err); |
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h index 0a57d72790ec..b250e6789dee 100644 --- a/drivers/bluetooth/hci_uart.h +++ b/drivers/bluetooth/hci_uart.h | |||
@@ -1,32 +1,29 @@ | |||
1 | /* | ||
2 | BlueZ - Bluetooth protocol stack for Linux | ||
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | ||
4 | |||
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License version 2 as | ||
9 | published by the Free Software Foundation; | ||
10 | |||
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
12 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
14 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
15 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
16 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
17 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
18 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
19 | |||
20 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
21 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
22 | SOFTWARE IS DISCLAIMED. | ||
23 | */ | ||
24 | |||
25 | /* | 1 | /* |
26 | * $Id: hci_uart.h,v 1.2 2002/09/09 01:17:32 maxk Exp $ | 2 | * |
3 | * Bluetooth HCI UART driver | ||
4 | * | ||
5 | * Copyright (C) 2000-2001 Qualcomm Incorporated | ||
6 | * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> | ||
7 | * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org> | ||
8 | * | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | * | ||
27 | */ | 24 | */ |
28 | 25 | ||
29 | #ifndef N_HCI | 26 | #ifndef N_HCI |
30 | #define N_HCI 15 | 27 | #define N_HCI 15 |
31 | #endif | 28 | #endif |
32 | 29 | ||
@@ -42,7 +39,6 @@ | |||
42 | #define HCI_UART_3WIRE 2 | 39 | #define HCI_UART_3WIRE 2 |
43 | #define HCI_UART_H4DS 3 | 40 | #define HCI_UART_H4DS 3 |
44 | 41 | ||
45 | #ifdef __KERNEL__ | ||
46 | struct hci_uart; | 42 | struct hci_uart; |
47 | 43 | ||
48 | struct hci_uart_proto { | 44 | struct hci_uart_proto { |
@@ -56,27 +52,35 @@ struct hci_uart_proto { | |||
56 | }; | 52 | }; |
57 | 53 | ||
58 | struct hci_uart { | 54 | struct hci_uart { |
59 | struct tty_struct *tty; | 55 | struct tty_struct *tty; |
60 | struct hci_dev *hdev; | 56 | struct hci_dev *hdev; |
61 | unsigned long flags; | 57 | unsigned long flags; |
62 | 58 | ||
63 | struct hci_uart_proto *proto; | 59 | struct hci_uart_proto *proto; |
64 | void *priv; | 60 | void *priv; |
65 | 61 | ||
66 | struct sk_buff *tx_skb; | 62 | struct sk_buff *tx_skb; |
67 | unsigned long tx_state; | 63 | unsigned long tx_state; |
68 | spinlock_t rx_lock; | 64 | spinlock_t rx_lock; |
69 | }; | 65 | }; |
70 | 66 | ||
71 | /* HCI_UART flag bits */ | 67 | /* HCI_UART flag bits */ |
72 | #define HCI_UART_PROTO_SET 0 | 68 | #define HCI_UART_PROTO_SET 0 |
73 | 69 | ||
74 | /* TX states */ | 70 | /* TX states */ |
75 | #define HCI_UART_SENDING 1 | 71 | #define HCI_UART_SENDING 1 |
76 | #define HCI_UART_TX_WAKEUP 2 | 72 | #define HCI_UART_TX_WAKEUP 2 |
77 | 73 | ||
78 | int hci_uart_register_proto(struct hci_uart_proto *p); | 74 | int hci_uart_register_proto(struct hci_uart_proto *p); |
79 | int hci_uart_unregister_proto(struct hci_uart_proto *p); | 75 | int hci_uart_unregister_proto(struct hci_uart_proto *p); |
80 | int hci_uart_tx_wakeup(struct hci_uart *hu); | 76 | int hci_uart_tx_wakeup(struct hci_uart *hu); |
81 | 77 | ||
82 | #endif /* __KERNEL__ */ | 78 | #ifdef CONFIG_BT_HCIUART_H4 |
79 | int h4_init(void); | ||
80 | int h4_deinit(void); | ||
81 | #endif | ||
82 | |||
83 | #ifdef CONFIG_BT_HCIUART_BCSP | ||
84 | int bcsp_init(void); | ||
85 | int bcsp_deinit(void); | ||
86 | #endif | ||