Blame view
drivers/bluetooth/hci_h4.c
3.53 KB
1da177e4c
|
1 |
/* |
1da177e4c
|
2 |
* |
0372a6627
|
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
* Bluetooth HCI UART driver * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org> * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * |
1da177e4c
|
24 |
*/ |
1da177e4c
|
25 |
|
1da177e4c
|
26 27 28 29 |
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> |
1da177e4c
|
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#include <linux/types.h> #include <linux/fcntl.h> #include <linux/interrupt.h> #include <linux/ptrace.h> #include <linux/poll.h> #include <linux/slab.h> #include <linux/tty.h> #include <linux/errno.h> #include <linux/string.h> #include <linux/signal.h> #include <linux/ioctl.h> #include <linux/skbuff.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> |
0372a6627
|
46 |
|
1da177e4c
|
47 |
#include "hci_uart.h" |
1da177e4c
|
48 |
|
0372a6627
|
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#define VERSION "1.2" struct h4_struct { unsigned long rx_state; unsigned long rx_count; struct sk_buff *rx_skb; struct sk_buff_head txq; }; /* H4 receiver States */ #define H4_W4_PACKET_TYPE 0 #define H4_W4_EVENT_HDR 1 #define H4_W4_ACL_HDR 2 #define H4_W4_SCO_HDR 3 #define H4_W4_DATA 4 |
1da177e4c
|
64 65 66 67 |
/* Initialize protocol */ static int h4_open(struct hci_uart *hu) { struct h4_struct *h4; |
0372a6627
|
68 |
|
1da177e4c
|
69 |
BT_DBG("hu %p", hu); |
0372a6627
|
70 |
|
fdcd1661a
|
71 |
h4 = kzalloc(sizeof(*h4), GFP_KERNEL); |
1da177e4c
|
72 73 |
if (!h4) return -ENOMEM; |
0372a6627
|
74 |
|
1da177e4c
|
75 76 77 78 79 80 81 82 83 84 85 86 |
skb_queue_head_init(&h4->txq); hu->priv = h4; return 0; } /* Flush protocol data */ static int h4_flush(struct hci_uart *hu) { struct h4_struct *h4 = hu->priv; BT_DBG("hu %p", hu); |
0372a6627
|
87 |
|
1da177e4c
|
88 |
skb_queue_purge(&h4->txq); |
0372a6627
|
89 |
|
1da177e4c
|
90 91 92 93 94 95 96 |
return 0; } /* Close protocol */ static int h4_close(struct hci_uart *hu) { struct h4_struct *h4 = hu->priv; |
0372a6627
|
97 |
|
1da177e4c
|
98 99 100 101 102 |
hu->priv = NULL; BT_DBG("hu %p", hu); skb_queue_purge(&h4->txq); |
0372a6627
|
103 |
|
b1fb06830
|
104 |
kfree_skb(h4->rx_skb); |
1da177e4c
|
105 106 107 |
hu->priv = NULL; kfree(h4); |
0372a6627
|
108 |
|
1da177e4c
|
109 110 111 112 113 114 115 116 117 118 119 |
return 0; } /* Enqueue frame for transmittion (padding, crc, etc) */ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb) { struct h4_struct *h4 = hu->priv; BT_DBG("hu %p skb %p", hu, skb); /* Prepend skb with frame type */ |
0d48d9394
|
120 |
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); |
1da177e4c
|
121 |
skb_queue_tail(&h4->txq, skb); |
0372a6627
|
122 |
|
1da177e4c
|
123 124 |
return 0; } |
1da177e4c
|
125 126 127 |
/* Recv data */ static int h4_recv(struct hci_uart *hu, void *data, int count) { |
b86ed368f
|
128 |
int ret; |
c25782029
|
129 130 |
if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) return -EUNATCH; |
b86ed368f
|
131 132 |
ret = hci_recv_stream_fragment(hu->hdev, data, count); if (ret < 0) { |
e9da101f6
|
133 |
BT_ERR("Frame Reassembly Failed"); |
b86ed368f
|
134 135 |
return ret; } |
0372a6627
|
136 |
|
1da177e4c
|
137 138 139 140 141 142 143 144 145 146 |
return count; } static struct sk_buff *h4_dequeue(struct hci_uart *hu) { struct h4_struct *h4 = hu->priv; return skb_dequeue(&h4->txq); } static struct hci_uart_proto h4p = { |
0372a6627
|
147 148 149 150 151 152 153 |
.id = HCI_UART_H4, .open = h4_open, .close = h4_close, .recv = h4_recv, .enqueue = h4_enqueue, .dequeue = h4_dequeue, .flush = h4_flush, |
1da177e4c
|
154 |
}; |
0372a6627
|
155 |
|
f2b94bb9e
|
156 |
int __init h4_init(void) |
1da177e4c
|
157 158 |
{ int err = hci_uart_register_proto(&h4p); |
0372a6627
|
159 |
|
1da177e4c
|
160 161 162 163 |
if (!err) BT_INFO("HCI H4 protocol initialized"); else BT_ERR("HCI H4 protocol registration failed"); |
0372a6627
|
164 |
|
1da177e4c
|
165 166 |
return err; } |
f2b94bb9e
|
167 |
int __exit h4_deinit(void) |
1da177e4c
|
168 169 170 |
{ return hci_uart_unregister_proto(&h4p); } |