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