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