diff options
| -rw-r--r-- | drivers/bluetooth/hci_bcsp.c | 120 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_bcsp.h | 71 | ||||
| -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 |
6 files changed, 253 insertions, 301 deletions
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c index 91bd293d7a0a..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.3" | ||
| 32 | |||
| 33 | #include <linux/config.h> | 25 | #include <linux/config.h> |
| 34 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 35 | 27 | ||
| @@ -52,17 +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 | |||
| 63 | static int txcrc = 1; | 57 | static int txcrc = 1; |
| 64 | static int hciextn = 1; | 58 | static int hciextn = 1; |
| 65 | 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 | |||
| 66 | /* ---- BCSP CRC calculation ---- */ | 97 | /* ---- BCSP CRC calculation ---- */ |
| 67 | 98 | ||
| 68 | /* Table for calculating CRC for polynomial 0x1021, LSB processed first, | 99 | /* Table for calculating CRC for polynomial 0x1021, LSB processed first, |
| @@ -112,6 +143,7 @@ static u16 bcsp_crc_reverse(u16 crc) | |||
| 112 | rev |= (crc & 1); | 143 | rev |= (crc & 1); |
| 113 | crc = crc >> 1; | 144 | crc = crc >> 1; |
| 114 | } | 145 | } |
| 146 | |||
| 115 | return (rev); | 147 | return (rev); |
| 116 | } | 148 | } |
| 117 | 149 | ||
| @@ -120,6 +152,7 @@ static u16 bcsp_crc_reverse(u16 crc) | |||
| 120 | static void bcsp_slip_msgdelim(struct sk_buff *skb) | 152 | static void bcsp_slip_msgdelim(struct sk_buff *skb) |
| 121 | { | 153 | { |
| 122 | const char pkt_delim = 0xc0; | 154 | const char pkt_delim = 0xc0; |
| 155 | |||
| 123 | memcpy(skb_put(skb, 1), &pkt_delim, 1); | 156 | memcpy(skb_put(skb, 1), &pkt_delim, 1); |
| 124 | } | 157 | } |
| 125 | 158 | ||
| @@ -315,7 +348,6 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu) | |||
| 315 | 348 | ||
| 316 | spin_unlock_irqrestore(&bcsp->unack.lock, flags); | 349 | spin_unlock_irqrestore(&bcsp->unack.lock, flags); |
| 317 | 350 | ||
| 318 | |||
| 319 | /* We could not send a reliable packet, either because there are | 351 | /* We could not send a reliable packet, either because there are |
| 320 | 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 |
| 321 | any packets we have not acknowledged yet ? */ | 353 | any packets we have not acknowledged yet ? */ |
| @@ -361,7 +393,7 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp) | |||
| 361 | BT_ERR("Peer acked invalid packet"); | 393 | BT_ERR("Peer acked invalid packet"); |
| 362 | 394 | ||
| 363 | 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", |
| 364 | pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07); | 396 | pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07); |
| 365 | 397 | ||
| 366 | 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 |
| 367 | && skb != (struct sk_buff *) &bcsp->unack; i++) { | 399 | && skb != (struct sk_buff *) &bcsp->unack; i++) { |
| @@ -372,8 +404,10 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp) | |||
| 372 | kfree_skb(skb); | 404 | kfree_skb(skb); |
| 373 | skb = nskb; | 405 | skb = nskb; |
| 374 | } | 406 | } |
| 407 | |||
| 375 | if (bcsp->unack.qlen == 0) | 408 | if (bcsp->unack.qlen == 0) |
| 376 | del_timer(&bcsp->tbcsp); | 409 | del_timer(&bcsp->tbcsp); |
| 410 | |||
| 377 | spin_unlock_irqrestore(&bcsp->unack.lock, flags); | 411 | spin_unlock_irqrestore(&bcsp->unack.lock, flags); |
| 378 | 412 | ||
| 379 | if (i != pkts_to_be_removed) | 413 | if (i != pkts_to_be_removed) |
| @@ -528,6 +562,7 @@ static inline void bcsp_complete_rx_pkt(struct hci_uart *hu) | |||
| 528 | 562 | ||
| 529 | hci_recv_frame(bcsp->rx_skb); | 563 | hci_recv_frame(bcsp->rx_skb); |
| 530 | } | 564 | } |
| 565 | |||
| 531 | bcsp->rx_state = BCSP_W4_PKT_DELIMITER; | 566 | bcsp->rx_state = BCSP_W4_PKT_DELIMITER; |
| 532 | bcsp->rx_skb = NULL; | 567 | bcsp->rx_skb = NULL; |
| 533 | } | 568 | } |
| @@ -596,8 +631,8 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count) | |||
| 596 | 631 | ||
| 597 | BT_ERR ("Checksum failed: computed %04x received %04x", | 632 | BT_ERR ("Checksum failed: computed %04x received %04x", |
| 598 | bcsp_crc_reverse(bcsp->message_crc), | 633 | bcsp_crc_reverse(bcsp->message_crc), |
| 599 | (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) + | 634 | (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) + |
| 600 | bcsp->rx_skb->data[bcsp->rx_skb->len - 1]); | 635 | bcsp->rx_skb->data[bcsp->rx_skb->len - 1]); |
| 601 | 636 | ||
| 602 | kfree_skb(bcsp->rx_skb); | 637 | kfree_skb(bcsp->rx_skb); |
| 603 | bcsp->rx_state = BCSP_W4_PKT_DELIMITER; | 638 | bcsp->rx_state = BCSP_W4_PKT_DELIMITER; |
| @@ -631,7 +666,7 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count) | |||
| 631 | bcsp->rx_count = 4; | 666 | bcsp->rx_count = 4; |
| 632 | bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC; | 667 | bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC; |
| 633 | BCSP_CRC_INIT(bcsp->message_crc); | 668 | BCSP_CRC_INIT(bcsp->message_crc); |
| 634 | 669 | ||
| 635 | /* Do not increment ptr or decrement count | 670 | /* Do not increment ptr or decrement count |
| 636 | * Allocate packet. Max len of a BCSP pkt= | 671 | * Allocate packet. Max len of a BCSP pkt= |
| 637 | * 0xFFF (payload) +4 (header) +2 (crc) */ | 672 | * 0xFFF (payload) +4 (header) +2 (crc) */ |
| @@ -719,18 +754,19 @@ static int bcsp_close(struct hci_uart *hu) | |||
| 719 | } | 754 | } |
| 720 | 755 | ||
| 721 | static struct hci_uart_proto bcsp = { | 756 | static struct hci_uart_proto bcsp = { |
| 722 | .id = HCI_UART_BCSP, | 757 | .id = HCI_UART_BCSP, |
| 723 | .open = bcsp_open, | 758 | .open = bcsp_open, |
| 724 | .close = bcsp_close, | 759 | .close = bcsp_close, |
| 725 | .enqueue = bcsp_enqueue, | 760 | .enqueue = bcsp_enqueue, |
| 726 | .dequeue = bcsp_dequeue, | 761 | .dequeue = bcsp_dequeue, |
| 727 | .recv = bcsp_recv, | 762 | .recv = bcsp_recv, |
| 728 | .flush = bcsp_flush | 763 | .flush = bcsp_flush |
| 729 | }; | 764 | }; |
| 730 | 765 | ||
| 731 | int bcsp_init(void) | 766 | int bcsp_init(void) |
| 732 | { | 767 | { |
| 733 | int err = hci_uart_register_proto(&bcsp); | 768 | int err = hci_uart_register_proto(&bcsp); |
| 769 | |||
| 734 | if (!err) | 770 | if (!err) |
| 735 | BT_INFO("HCI BCSP protocol initialized"); | 771 | BT_INFO("HCI BCSP protocol initialized"); |
| 736 | else | 772 | else |
diff --git a/drivers/bluetooth/hci_bcsp.h b/drivers/bluetooth/hci_bcsp.h deleted file mode 100644 index 01bbc664db74..000000000000 --- a/drivers/bluetooth/hci_bcsp.h +++ /dev/null | |||
| @@ -1,71 +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 | u8 use_crc; | ||
| 64 | u16 message_crc; | ||
| 65 | u8 txack_req; /* Do we need to send ack's to the peer? */ | ||
| 66 | |||
| 67 | /* Reliable packet sequence number - used to assign seq to each rel pkt. */ | ||
| 68 | u8 msgq_txseq; | ||
| 69 | }; | ||
| 70 | |||
| 71 | #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 8c9317bcd53c..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.2" | ||
| 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 | ||
