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