[PATCH] add check to /proc/devices read routines
[linux-2.6] / drivers / bluetooth / hci_h4.c
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  * Bluetooth HCI UART(H4) protocol.
27  *
28  * $Id: hci_h4.c,v 1.3 2002/09/09 01:17:32 maxk Exp $    
29  */
30 #define VERSION "1.2"
31
32 #include <linux/config.h>
33 #include <linux/module.h>
34
35 #include <linux/kernel.h>
36 #include <linux/init.h>
37 #include <linux/sched.h>
38 #include <linux/types.h>
39 #include <linux/fcntl.h>
40 #include <linux/interrupt.h>
41 #include <linux/ptrace.h>
42 #include <linux/poll.h>
43
44 #include <linux/slab.h>
45 #include <linux/tty.h>
46 #include <linux/errno.h>
47 #include <linux/string.h>
48 #include <linux/signal.h>
49 #include <linux/ioctl.h>
50 #include <linux/skbuff.h>
51
52 #include <net/bluetooth/bluetooth.h>
53 #include <net/bluetooth/hci_core.h>
54 #include "hci_uart.h"
55 #include "hci_h4.h"
56
57 #ifndef CONFIG_BT_HCIUART_DEBUG
58 #undef  BT_DBG
59 #define BT_DBG( A... )
60 #undef  BT_DMP
61 #define BT_DMP( A... )
62 #endif
63
64 /* Initialize protocol */
65 static int h4_open(struct hci_uart *hu)
66 {
67         struct h4_struct *h4;
68         
69         BT_DBG("hu %p", hu);
70         
71         h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
72         if (!h4)
73                 return -ENOMEM;
74         memset(h4, 0, sizeof(*h4));
75
76         skb_queue_head_init(&h4->txq);
77
78         hu->priv = h4;
79         return 0;
80 }
81
82 /* Flush protocol data */
83 static int h4_flush(struct hci_uart *hu)
84 {
85         struct h4_struct *h4 = hu->priv;
86
87         BT_DBG("hu %p", hu);
88         skb_queue_purge(&h4->txq);
89         return 0;
90 }
91
92 /* Close protocol */
93 static int h4_close(struct hci_uart *hu)
94 {
95         struct h4_struct *h4 = hu->priv;
96         hu->priv = NULL;
97
98         BT_DBG("hu %p", hu);
99
100         skb_queue_purge(&h4->txq);
101         if (h4->rx_skb)
102                 kfree_skb(h4->rx_skb);
103
104         hu->priv = NULL;
105         kfree(h4);
106         return 0;
107 }
108
109 /* Enqueue frame for transmittion (padding, crc, etc) */
110 static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
111 {
112         struct h4_struct *h4 = hu->priv;
113
114         BT_DBG("hu %p skb %p", hu, skb);
115
116         /* Prepend skb with frame type */
117         memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
118         skb_queue_tail(&h4->txq, skb);
119         return 0;
120 }
121
122 static inline int h4_check_data_len(struct h4_struct *h4, int len)
123 {
124         register int room = skb_tailroom(h4->rx_skb);
125
126         BT_DBG("len %d room %d", len, room);
127         if (!len) {
128                 BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
129                 hci_recv_frame(h4->rx_skb);
130         } else if (len > room) {
131                 BT_ERR("Data length is too large");
132                 kfree_skb(h4->rx_skb);
133         } else {
134                 h4->rx_state = H4_W4_DATA;
135                 h4->rx_count = len;
136                 return len;
137         }
138
139         h4->rx_state = H4_W4_PACKET_TYPE;
140         h4->rx_skb   = NULL;
141         h4->rx_count = 0;
142         return 0;
143 }
144
145 /* Recv data */
146 static int h4_recv(struct hci_uart *hu, void *data, int count)
147 {
148         struct h4_struct *h4 = hu->priv;
149         register char *ptr;
150         struct hci_event_hdr *eh;
151         struct hci_acl_hdr   *ah;
152         struct hci_sco_hdr   *sh;
153         register int len, type, dlen;
154
155         BT_DBG("hu %p count %d rx_state %ld rx_count %ld", 
156                         hu, count, h4->rx_state, h4->rx_count);
157
158         ptr = data;
159         while (count) {
160                 if (h4->rx_count) {
161                         len = min_t(unsigned int, h4->rx_count, count);
162                         memcpy(skb_put(h4->rx_skb, len), ptr, len);
163                         h4->rx_count -= len; count -= len; ptr += len;
164
165                         if (h4->rx_count)
166                                 continue;
167
168                         switch (h4->rx_state) {
169                         case H4_W4_DATA:
170                                 BT_DBG("Complete data");
171
172                                 BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
173
174                                 hci_recv_frame(h4->rx_skb);
175
176                                 h4->rx_state = H4_W4_PACKET_TYPE;
177                                 h4->rx_skb = NULL;
178                                 continue;
179
180                         case H4_W4_EVENT_HDR:
181                                 eh = (struct hci_event_hdr *) h4->rx_skb->data;
182
183                                 BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
184
185                                 h4_check_data_len(h4, eh->plen);
186                                 continue;
187
188                         case H4_W4_ACL_HDR:
189                                 ah = (struct hci_acl_hdr *) h4->rx_skb->data;
190                                 dlen = __le16_to_cpu(ah->dlen);
191
192                                 BT_DBG("ACL header: dlen %d", dlen);
193
194                                 h4_check_data_len(h4, dlen);
195                                 continue;
196
197                         case H4_W4_SCO_HDR:
198                                 sh = (struct hci_sco_hdr *) h4->rx_skb->data;
199
200                                 BT_DBG("SCO header: dlen %d", sh->dlen);
201
202                                 h4_check_data_len(h4, sh->dlen);
203                                 continue;
204                         }
205                 }
206
207                 /* H4_W4_PACKET_TYPE */
208                 switch (*ptr) {
209                 case HCI_EVENT_PKT:
210                         BT_DBG("Event packet");
211                         h4->rx_state = H4_W4_EVENT_HDR;
212                         h4->rx_count = HCI_EVENT_HDR_SIZE;
213                         type = HCI_EVENT_PKT;
214                         break;
215
216                 case HCI_ACLDATA_PKT:
217                         BT_DBG("ACL packet");
218                         h4->rx_state = H4_W4_ACL_HDR;
219                         h4->rx_count = HCI_ACL_HDR_SIZE;
220                         type = HCI_ACLDATA_PKT;
221                         break;
222
223                 case HCI_SCODATA_PKT:
224                         BT_DBG("SCO packet");
225                         h4->rx_state = H4_W4_SCO_HDR;
226                         h4->rx_count = HCI_SCO_HDR_SIZE;
227                         type = HCI_SCODATA_PKT;
228                         break;
229
230                 default:
231                         BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
232                         hu->hdev->stat.err_rx++;
233                         ptr++; count--;
234                         continue;
235                 };
236                 ptr++; count--;
237
238                 /* Allocate packet */
239                 h4->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
240                 if (!h4->rx_skb) {
241                         BT_ERR("Can't allocate mem for new packet");
242                         h4->rx_state = H4_W4_PACKET_TYPE;
243                         h4->rx_count = 0;
244                         return 0;
245                 }
246                 h4->rx_skb->dev = (void *) hu->hdev;
247                 h4->rx_skb->pkt_type = type;
248         }
249         return count;
250 }
251
252 static struct sk_buff *h4_dequeue(struct hci_uart *hu)
253 {
254         struct h4_struct *h4 = hu->priv;
255         return skb_dequeue(&h4->txq);
256 }
257
258 static struct hci_uart_proto h4p = {
259         .id      = HCI_UART_H4,
260         .open    = h4_open,
261         .close   = h4_close,
262         .recv    = h4_recv,
263         .enqueue = h4_enqueue,
264         .dequeue = h4_dequeue,
265         .flush   = h4_flush,
266 };
267               
268 int h4_init(void)
269 {
270         int err = hci_uart_register_proto(&h4p);
271         if (!err)
272                 BT_INFO("HCI H4 protocol initialized");
273         else
274                 BT_ERR("HCI H4 protocol registration failed");
275         
276         return err;
277 }
278
279 int h4_deinit(void)
280 {
281         return hci_uart_unregister_proto(&h4p);
282 }