Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / bluetooth / hci_h4.c
index ade94a5..4804d47 100644 (file)
@@ -1,33 +1,27 @@
-/* 
-   BlueZ - Bluetooth protocol stack for Linux
-   Copyright (C) 2000-2001 Qualcomm Incorporated
-
-   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
-   SOFTWARE IS DISCLAIMED.
-*/
-
 /*
- * Bluetooth HCI UART(H4) protocol.
  *
- * $Id: hci_h4.c,v 1.3 2002/09/09 01:17:32 maxk Exp $    
+ *  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
+ *
  */
-#define VERSION "1.2"
 
 #include <linux/config.h>
 #include <linux/module.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
+
 #include "hci_uart.h"
-#include "hci_h4.h"
 
 #ifndef CONFIG_BT_HCIUART_DEBUG
 #undef  BT_DBG
 #define BT_DBG( A... )
-#undef  BT_DMP
-#define BT_DMP( A... )
 #endif
 
+#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
+
 /* Initialize protocol */
 static int h4_open(struct hci_uart *hu)
 {
        struct h4_struct *h4;
-       
+
        BT_DBG("hu %p", hu);
-       
-       h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
+
+       h4 = kzalloc(sizeof(*h4), GFP_ATOMIC);
        if (!h4)
                return -ENOMEM;
-       memset(h4, 0, sizeof(*h4));
 
        skb_queue_head_init(&h4->txq);
 
@@ -85,7 +92,9 @@ static int h4_flush(struct hci_uart *hu)
        struct h4_struct *h4 = hu->priv;
 
        BT_DBG("hu %p", hu);
+
        skb_queue_purge(&h4->txq);
+
        return 0;
 }
 
@@ -93,16 +102,19 @@ static int h4_flush(struct hci_uart *hu)
 static int h4_close(struct hci_uart *hu)
 {
        struct h4_struct *h4 = hu->priv;
+
        hu->priv = NULL;
 
        BT_DBG("hu %p", hu);
 
        skb_queue_purge(&h4->txq);
+
        if (h4->rx_skb)
                kfree_skb(h4->rx_skb);
 
        hu->priv = NULL;
        kfree(h4);
+
        return 0;
 }
 
@@ -114,8 +126,9 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
        BT_DBG("hu %p skb %p", hu, skb);
 
        /* Prepend skb with frame type */
-       memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
+       memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
        skb_queue_tail(&h4->txq, skb);
+
        return 0;
 }
 
@@ -124,8 +137,8 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
        register int room = skb_tailroom(h4->rx_skb);
 
        BT_DBG("len %d room %d", len, room);
+
        if (!len) {
-               BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
                hci_recv_frame(h4->rx_skb);
        } else if (len > room) {
                BT_ERR("Data length is too large");
@@ -139,6 +152,7 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
        h4->rx_state = H4_W4_PACKET_TYPE;
        h4->rx_skb   = NULL;
        h4->rx_count = 0;
+
        return 0;
 }
 
@@ -169,8 +183,6 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
                        case H4_W4_DATA:
                                BT_DBG("Complete data");
 
-                               BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
-
                                hci_recv_frame(h4->rx_skb);
 
                                h4->rx_state = H4_W4_PACKET_TYPE;
@@ -233,6 +245,7 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
                        ptr++; count--;
                        continue;
                };
+
                ptr++; count--;
 
                /* Allocate packet */
@@ -243,9 +256,11 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
                        h4->rx_count = 0;
                        return 0;
                }
+
                h4->rx_skb->dev = (void *) hu->hdev;
-               h4->rx_skb->pkt_type = type;
+               bt_cb(h4->rx_skb)->pkt_type = type;
        }
+
        return count;
 }
 
@@ -256,23 +271,24 @@ static struct sk_buff *h4_dequeue(struct hci_uart *hu)
 }
 
 static struct hci_uart_proto h4p = {
-       .id      = HCI_UART_H4,
-       .open    = h4_open,
-       .close   = h4_close,
-       .recv    = h4_recv,
-       .enqueue = h4_enqueue,
-       .dequeue = h4_dequeue,
-       .flush   = h4_flush,
+       .id             = HCI_UART_H4,
+       .open           = h4_open,
+       .close          = h4_close,
+       .recv           = h4_recv,
+       .enqueue        = h4_enqueue,
+       .dequeue        = h4_dequeue,
+       .flush          = h4_flush,
 };
-             
+
 int h4_init(void)
 {
        int err = hci_uart_register_proto(&h4p);
+
        if (!err)
                BT_INFO("HCI H4 protocol initialized");
        else
                BT_ERR("HCI H4 protocol registration failed");
-       
+
        return err;
 }