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_usb.c
index b120ecf..92382e8 100644 (file)
@@ -57,8 +57,6 @@
 #ifndef CONFIG_BT_HCIUSB_DEBUG
 #undef  BT_DBG
 #define BT_DBG(D...)
-#undef  BT_DMP
-#define BT_DMP(D...)
 #endif
 
 #ifndef CONFIG_BT_HCIUSB_ZERO_PACKET
 #endif
 
 static int ignore = 0;
+static int ignore_dga = 0;
+static int ignore_csr = 0;
+static int ignore_sniffer = 0;
 static int reset = 0;
 
 #ifdef CONFIG_BT_HCIUSB_SCO
 static int isoc = 2;
 #endif
 
-#define VERSION "2.8"
+#define VERSION "2.9"
 
 static struct usb_driver hci_usb_driver; 
 
@@ -100,6 +101,9 @@ static struct usb_device_id bluetooth_ids[] = {
 MODULE_DEVICE_TABLE (usb, bluetooth_ids);
 
 static struct usb_device_id blacklist_ids[] = {
+       /* CSR BlueCore devices */
+       { USB_DEVICE(0x0a12, 0x0001), .driver_info = HCI_CSR },
+
        /* Broadcom BCM2033 without firmware */
        { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE },
 
@@ -110,6 +114,9 @@ static struct usb_device_id blacklist_ids[] = {
        /* Microsoft Wireless Transceiver for Bluetooth 2.0 */
        { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
 
+       /* Kensington Bluetooth USB adapter */
+       { USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET },
+
        /* ISSC Bluetooth Adapter v3.1 */
        { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
 
@@ -126,7 +133,7 @@ static struct usb_device_id blacklist_ids[] = {
        { }     /* Terminating entry */
 };
 
-static struct _urb *_urb_alloc(int isoc, int gfp)
+static struct _urb *_urb_alloc(int isoc, gfp_t gfp)
 {
        struct _urb *_urb = kmalloc(sizeof(struct _urb) +
                                sizeof(struct usb_iso_packet_descriptor) * isoc, gfp);
@@ -387,10 +394,8 @@ static void hci_usb_unlink_urbs(struct hci_usb *husb)
                        urb = &_urb->urb;
                        BT_DBG("%s freeing _urb %p type %d urb %p",
                                        husb->hdev->name, _urb, _urb->type, urb);
-                       if (urb->setup_packet)
-                               kfree(urb->setup_packet);
-                       if (urb->transfer_buffer)
-                               kfree(urb->transfer_buffer);
+                       kfree(urb->setup_packet);
+                       kfree(urb->transfer_buffer);
                        _urb_free(_urb);
                }
 
@@ -444,7 +449,7 @@ static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
 
 static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
 {
-       struct _urb *_urb = __get_completed(husb, skb->pkt_type);
+       struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
        struct usb_ctrlrequest *dr;
        struct urb *urb;
 
@@ -452,7 +457,7 @@ static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
                _urb = _urb_alloc(0, GFP_ATOMIC);
                if (!_urb)
                        return -ENOMEM;
-               _urb->type = skb->pkt_type;
+               _urb->type = bt_cb(skb)->pkt_type;
 
                dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
                if (!dr) {
@@ -480,7 +485,7 @@ static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
 
 static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
 {
-       struct _urb *_urb = __get_completed(husb, skb->pkt_type);
+       struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
        struct urb *urb;
        int pipe;
 
@@ -488,7 +493,7 @@ static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
                _urb = _urb_alloc(0, GFP_ATOMIC);
                if (!_urb)
                        return -ENOMEM;
-               _urb->type = skb->pkt_type;
+               _urb->type = bt_cb(skb)->pkt_type;
        }
 
        urb  = &_urb->urb;
@@ -506,14 +511,14 @@ static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
 #ifdef CONFIG_BT_HCIUSB_SCO
 static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
 {
-       struct _urb *_urb = __get_completed(husb, skb->pkt_type);
+       struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
        struct urb *urb;
 
        if (!_urb) {
                _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
                if (!_urb)
                        return -ENOMEM;
-               _urb->type = skb->pkt_type;
+               _urb->type = bt_cb(skb)->pkt_type;
        }
 
        BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
@@ -602,11 +607,11 @@ static int hci_usb_send_frame(struct sk_buff *skb)
        if (!test_bit(HCI_RUNNING, &hdev->flags))
                return -EBUSY;
 
-       BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
+       BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
 
        husb = (struct hci_usb *) hdev->driver_data;
 
-       switch (skb->pkt_type) {
+       switch (bt_cb(skb)->pkt_type) {
        case HCI_COMMAND_PKT:
                hdev->stat.cmd_tx++;
                break;
@@ -628,7 +633,7 @@ static int hci_usb_send_frame(struct sk_buff *skb)
 
        read_lock(&husb->completion_lock);
 
-       skb_queue_tail(__transmit_q(husb, skb->pkt_type), skb);
+       skb_queue_tail(__transmit_q(husb, bt_cb(skb)->pkt_type), skb);
        hci_usb_tx_wakeup(husb);
 
        read_unlock(&husb->completion_lock);
@@ -683,7 +688,7 @@ static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int c
                                return -ENOMEM;
                        }
                        skb->dev = (void *) husb->hdev;
-                       skb->pkt_type = type;
+                       bt_cb(skb)->pkt_type = type;
        
                        __reassembly(husb, type) = skb;
 
@@ -703,6 +708,7 @@ static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int c
                if (!scb->expect) {
                        /* Complete frame */
                        __reassembly(husb, type) = NULL;
+                       bt_cb(skb)->pkt_type = type;
                        hci_recv_frame(skb);
                }
 
@@ -836,6 +842,15 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
        if (ignore || id->driver_info & HCI_IGNORE)
                return -ENODEV;
 
+       if (ignore_dga && id->driver_info & HCI_DIGIANSWER)
+               return -ENODEV;
+
+       if (ignore_csr && id->driver_info & HCI_CSR)
+               return -ENODEV;
+
+       if (ignore_sniffer && id->driver_info & HCI_SNIFFER)
+               return -ENODEV;
+
        if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
                return -ENODEV;
 
@@ -864,13 +879,11 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
                goto done;
        }
 
-       if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
+       if (!(husb = kzalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
                BT_ERR("Can't allocate: control structure");
                goto done;
        }
 
-       memset(husb, 0, sizeof(struct hci_usb));
-
        husb->udev = udev;
        husb->bulk_out_ep = bulk_out_ep;
        husb->bulk_in_ep  = bulk_in_ep;
@@ -1031,7 +1044,6 @@ static void hci_usb_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver hci_usb_driver = {
-       .owner          = THIS_MODULE,
        .name           = "hci_usb",
        .probe          = hci_usb_probe,
        .disconnect     = hci_usb_disconnect,
@@ -1061,6 +1073,15 @@ module_exit(hci_usb_exit);
 module_param(ignore, bool, 0644);
 MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
 
+module_param(ignore_dga, bool, 0644);
+MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
+
+module_param(ignore_csr, bool, 0644);
+MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
+
+module_param(ignore_sniffer, bool, 0644);
+MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
+
 module_param(reset, bool, 0644);
 MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");