]> git.hungrycats.org Git - linux/commitdiff
http://www.kernel.org/pub/linux/kernel/people/holtmann/patch-2.6.27-mh1.gz v2.6.27-mh1
authorZygo Blaxell <zblaxell@dactyl.hungrycats.org>
Thu, 28 May 2009 16:33:12 +0000 (12:33 -0400)
committerZygo Blaxell <zblaxell@dactyl.hungrycats.org>
Thu, 28 May 2009 16:33:12 +0000 (12:33 -0400)
Makefile
drivers/bluetooth/bpa10x.c
drivers/bluetooth/bt3c_cs.c
drivers/bluetooth/btsdio.c
drivers/bluetooth/btusb.c
drivers/bluetooth/hci_ldisc.c
drivers/bluetooth/hci_ll.c
include/net/bluetooth/hci.h
net/bluetooth/af_bluetooth.c
net/bluetooth/hci_core.c
net/bluetooth/rfcomm/tty.c

index 16e3fbb968a8966bc58570ca117349631e81f2d7..21000dbb6c817216800e4ca7e8ba6debc1d24c7e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 27
-EXTRAVERSION =
+EXTRAVERSION = -mh1
 NAME = Rotary Wombat
 
 # *DOCUMENTATION*
index 32f3a8ed8d3d20e568e5547a48b559537de5fac1..0b4f0f4999bcaf077b9e54ca7f460f1e402c2eb1 100644 (file)
@@ -489,6 +489,8 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
 
        hdev->owner = THIS_MODULE;
 
+       set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
+
        err = hci_register_dev(hdev);
        if (err < 0) {
                hci_free_dev(hdev);
index 27058477cc8b7722bdc901ec7edb21e1d503be27..302051c38e14d2d5b9afc24e27b2e11f302f061c 100644 (file)
@@ -500,15 +500,15 @@ static int bt3c_load_firmware(bt3c_info_t *info, const unsigned char *firmware,
 
                memset(b, 0, sizeof(b));
                memcpy(b, ptr + 2, 2);
-               size = simple_strtol(b, NULL, 16);
+               size = simple_strtoul(b, NULL, 16);
 
                memset(b, 0, sizeof(b));
                memcpy(b, ptr + 4, 8);
-               addr = simple_strtol(b, NULL, 16);
+               addr = simple_strtoul(b, NULL, 16);
 
                memset(b, 0, sizeof(b));
                memcpy(b, ptr + (size * 2) + 2, 2);
-               fcs = simple_strtol(b, NULL, 16);
+               fcs = simple_strtoul(b, NULL, 16);
 
                memset(b, 0, sizeof(b));
                for (tmp = 0, i = 0; i < size; i++) {
@@ -528,7 +528,7 @@ static int bt3c_load_firmware(bt3c_info_t *info, const unsigned char *firmware,
                        memset(b, 0, sizeof(b));
                        for (i = 0; i < (size - 4) / 2; i++) {
                                memcpy(b, ptr + (i * 4) + 12, 4);
-                               tmp = simple_strtol(b, NULL, 16);
+                               tmp = simple_strtoul(b, NULL, 16);
                                bt3c_put(iobase, tmp);
                        }
                }
index 58630cc1eff2f1047ed0049edcbb9c4e578d511f..c422e897c3b18ae774d12bef42be0c5bab12320c 100644 (file)
@@ -91,6 +91,7 @@ static int btsdio_tx_packet(struct btsdio_data *data, struct sk_buff *skb)
 
        err = sdio_writesb(data->func, REG_TDAT, skb->data, skb->len);
        if (err < 0) {
+               skb_pull(skb, 4);
                sdio_writeb(data->func, 0x01, REG_PC_WRT, NULL);
                return err;
        }
index af472e05273296e664e8ddcb7fa443f4bc0e60e8..7f7526c186d07cb0f884b8c618fbc488520e64bb 100644 (file)
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "0.3"
+#define VERSION "0.4"
 
 static int ignore_dga;
 static int ignore_csr;
 static int ignore_sniffer;
 static int disable_scofix;
 static int force_scofix;
-static int reset;
+
+static int reset = 1;
 
 static struct usb_driver btusb_driver;
 
 #define BTUSB_IGNORE           0x01
-#define BTUSB_RESET            0x02
-#define BTUSB_DIGIANSWER       0x04
-#define BTUSB_CSR              0x08
-#define BTUSB_SNIFFER          0x10
-#define BTUSB_BCM92035         0x20
-#define BTUSB_BROKEN_ISOC      0x40
-#define BTUSB_WRONG_SCO_MTU    0x80
+#define BTUSB_DIGIANSWER       0x02
+#define BTUSB_CSR              0x04
+#define BTUSB_SNIFFER          0x08
+#define BTUSB_BCM92035         0x10
+#define BTUSB_BROKEN_ISOC      0x20
+#define BTUSB_WRONG_SCO_MTU    0x40
 
 static struct usb_device_id btusb_table[] = {
        /* Generic Bluetooth USB device */
@@ -79,7 +79,7 @@ static struct usb_device_id btusb_table[] = {
        { USB_DEVICE(0x0bdb, 0x1002) },
 
        /* Canyon CN-BTU1 with HID interfaces */
-       { USB_DEVICE(0x0c10, 0x0000), .driver_info = BTUSB_RESET },
+       { USB_DEVICE(0x0c10, 0x0000) },
 
        { }     /* Terminating entry */
 };
@@ -94,52 +94,37 @@ static struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE },
 
        /* Broadcom BCM2035 */
-       { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
-       { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
+       { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
+       { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
+       { USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
 
        /* Broadcom BCM2045 */
-       { USB_DEVICE(0x0a5c, 0x2039), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
-       { USB_DEVICE(0x0a5c, 0x2101), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
-
-       /* Broadcom BCM2046 */
-       { USB_DEVICE(0x0a5c, 0x2146), .driver_info = BTUSB_RESET },
-       { USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET },
-
-       /* Apple MacBook Pro with Broadcom chip */
-       { USB_DEVICE(0x05ac, 0x820f), .driver_info = BTUSB_RESET },
+       { USB_DEVICE(0x0a5c, 0x2039), .driver_info = BTUSB_WRONG_SCO_MTU },
+       { USB_DEVICE(0x0a5c, 0x2101), .driver_info = BTUSB_WRONG_SCO_MTU },
 
        /* IBM/Lenovo ThinkPad with Broadcom chip */
-       { USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
-       { USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
-
-       /* Targus ACB10US */
-       { USB_DEVICE(0x0a5c, 0x2100), .driver_info = BTUSB_RESET },
-       { USB_DEVICE(0x0a5c, 0x2154), .driver_info = BTUSB_RESET },
-
-       /* ANYCOM Bluetooth USB-200 and USB-250 */
-       { USB_DEVICE(0x0a5c, 0x2111), .driver_info = BTUSB_RESET },
+       { USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_WRONG_SCO_MTU },
+       { USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_WRONG_SCO_MTU },
 
        /* HP laptop with Broadcom chip */
-       { USB_DEVICE(0x03f0, 0x171d), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
+       { USB_DEVICE(0x03f0, 0x171d), .driver_info = BTUSB_WRONG_SCO_MTU },
 
        /* Dell laptop with Broadcom chip */
-       { USB_DEVICE(0x413c, 0x8126), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
+       { USB_DEVICE(0x413c, 0x8126), .driver_info = BTUSB_WRONG_SCO_MTU },
 
-       /* Dell Wireless 370 */
-       { USB_DEVICE(0x413c, 0x8156), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
+       /* Dell Wireless 370 and 410 devices */
+       { USB_DEVICE(0x413c, 0x8152), .driver_info = BTUSB_WRONG_SCO_MTU },
+       { USB_DEVICE(0x413c, 0x8156), .driver_info = BTUSB_WRONG_SCO_MTU },
 
-       /* Dell Wireless 410 */
-       { USB_DEVICE(0x413c, 0x8152), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
+       /* Belkin F8T012 and F8T013 devices */
+       { USB_DEVICE(0x050d, 0x0012), .driver_info = BTUSB_WRONG_SCO_MTU },
+       { USB_DEVICE(0x050d, 0x0013), .driver_info = BTUSB_WRONG_SCO_MTU },
 
-       /* Microsoft Wireless Transceiver for Bluetooth 2.0 */
-       { USB_DEVICE(0x045e, 0x009c), .driver_info = BTUSB_RESET },
+       /* Asus WL-BTD202 device */
+       { USB_DEVICE(0x0b05, 0x1715), .driver_info = BTUSB_WRONG_SCO_MTU },
 
        /* Kensington Bluetooth USB adapter */
-       { USB_DEVICE(0x047d, 0x105d), .driver_info = BTUSB_RESET },
-       { USB_DEVICE(0x047d, 0x105e), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
-
-       /* ISSC Bluetooth Adapter v3.1 */
-       { USB_DEVICE(0x1131, 0x1001), .driver_info = BTUSB_RESET },
+       { USB_DEVICE(0x047d, 0x105e), .driver_info = BTUSB_WRONG_SCO_MTU },
 
        /* RTX Telecom based adapters with buggy SCO support */
        { USB_DEVICE(0x0400, 0x0807), .driver_info = BTUSB_BROKEN_ISOC },
@@ -148,13 +133,6 @@ static struct usb_device_id blacklist_table[] = {
        /* CONWISE Technology based adapters with buggy SCO support */
        { USB_DEVICE(0x0e5e, 0x6622), .driver_info = BTUSB_BROKEN_ISOC },
 
-       /* Belkin F8T012 and F8T013 devices */
-       { USB_DEVICE(0x050d, 0x0012), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
-       { USB_DEVICE(0x050d, 0x0013), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
-
-       /* Belkin F8T016 device */
-       { USB_DEVICE(0x050d, 0x016a), .driver_info = BTUSB_RESET },
-
        /* Digianswer devices */
        { USB_DEVICE(0x08fd, 0x0001), .driver_info = BTUSB_DIGIANSWER },
        { USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE },
@@ -197,7 +175,10 @@ struct btusb_data {
        struct usb_endpoint_descriptor *isoc_tx_ep;
        struct usb_endpoint_descriptor *isoc_rx_ep;
 
+       __u8 cmdreq_type;
+
        int isoc_altsetting;
+       int suspend_count;
 };
 
 static void btusb_intr_complete(struct urb *urb)
@@ -236,7 +217,7 @@ static void btusb_intr_complete(struct urb *urb)
        }
 }
 
-static int btusb_submit_intr_urb(struct hci_dev *hdev)
+static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
 {
        struct btusb_data *data = hdev->driver_data;
        struct urb *urb;
@@ -249,13 +230,13 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev)
        if (!data->intr_ep)
                return -ENODEV;
 
-       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       urb = usb_alloc_urb(0, mem_flags);
        if (!urb)
                return -ENOMEM;
 
        size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
 
-       buf = kmalloc(size, GFP_ATOMIC);
+       buf = kmalloc(size, mem_flags);
        if (!buf) {
                usb_free_urb(urb);
                return -ENOMEM;
@@ -271,7 +252,7 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev)
 
        usb_anchor_urb(urb, &data->intr_anchor);
 
-       err = usb_submit_urb(urb, GFP_ATOMIC);
+       err = usb_submit_urb(urb, mem_flags);
        if (err < 0) {
                BT_ERR("%s urb %p submission failed (%d)",
                                                hdev->name, urb, -err);
@@ -319,7 +300,7 @@ static void btusb_bulk_complete(struct urb *urb)
        }
 }
 
-static int btusb_submit_bulk_urb(struct hci_dev *hdev)
+static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
 {
        struct btusb_data *data = hdev->driver_data;
        struct urb *urb;
@@ -332,13 +313,13 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev)
        if (!data->bulk_rx_ep)
                return -ENODEV;
 
-       urb = usb_alloc_urb(0, GFP_KERNEL);
+       urb = usb_alloc_urb(0, mem_flags);
        if (!urb)
                return -ENOMEM;
 
        size = le16_to_cpu(data->bulk_rx_ep->wMaxPacketSize);
 
-       buf = kmalloc(size, GFP_KERNEL);
+       buf = kmalloc(size, mem_flags);
        if (!buf) {
                usb_free_urb(urb);
                return -ENOMEM;
@@ -353,7 +334,7 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev)
 
        usb_anchor_urb(urb, &data->bulk_anchor);
 
-       err = usb_submit_urb(urb, GFP_KERNEL);
+       err = usb_submit_urb(urb, mem_flags);
        if (err < 0) {
                BT_ERR("%s urb %p submission failed (%d)",
                                                hdev->name, urb, -err);
@@ -430,7 +411,7 @@ static void inline __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
        urb->number_of_packets = i;
 }
 
-static int btusb_submit_isoc_urb(struct hci_dev *hdev)
+static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
 {
        struct btusb_data *data = hdev->driver_data;
        struct urb *urb;
@@ -443,14 +424,14 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev)
        if (!data->isoc_rx_ep)
                return -ENODEV;
 
-       urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_KERNEL);
+       urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, mem_flags);
        if (!urb)
                return -ENOMEM;
 
        size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) *
                                                BTUSB_MAX_ISOC_FRAMES;
 
-       buf = kmalloc(size, GFP_KERNEL);
+       buf = kmalloc(size, mem_flags);
        if (!buf) {
                usb_free_urb(urb);
                return -ENOMEM;
@@ -473,7 +454,7 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev)
 
        usb_anchor_urb(urb, &data->isoc_anchor);
 
-       err = usb_submit_urb(urb, GFP_KERNEL);
+       err = usb_submit_urb(urb, mem_flags);
        if (err < 0) {
                BT_ERR("%s urb %p submission failed (%d)",
                                                hdev->name, urb, -err);
@@ -520,7 +501,7 @@ static int btusb_open(struct hci_dev *hdev)
        if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
                return 0;
 
-       err = btusb_submit_intr_urb(hdev);
+       err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
        if (err < 0) {
                clear_bit(BTUSB_INTR_RUNNING, &data->flags);
                clear_bit(HCI_RUNNING, &hdev->flags);
@@ -589,7 +570,7 @@ static int btusb_send_frame(struct sk_buff *skb)
                        return -ENOMEM;
                }
 
-               dr->bRequestType = USB_TYPE_CLASS;
+               dr->bRequestType = data->cmdreq_type;
                dr->bRequest     = 0;
                dr->wIndex       = 0;
                dr->wValue       = 0;
@@ -680,8 +661,19 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
 
        BT_DBG("%s evt %d", hdev->name, evt);
 
-       if (evt == HCI_NOTIFY_CONN_ADD || evt == HCI_NOTIFY_CONN_DEL)
-               schedule_work(&data->work);
+       if (hdev->conn_hash.acl_num > 0) {
+               if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
+                       if (btusb_submit_bulk_urb(hdev, GFP_ATOMIC) < 0)
+                               clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+                       else
+                               btusb_submit_bulk_urb(hdev, GFP_ATOMIC);
+               }
+       } else {
+               clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+               usb_unlink_anchored_urbs(&data->bulk_anchor);
+       }
+
+       schedule_work(&data->work);
 }
 
 static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
@@ -732,18 +724,6 @@ static void btusb_work(struct work_struct *work)
        struct btusb_data *data = container_of(work, struct btusb_data, work);
        struct hci_dev *hdev = data->hdev;
 
-       if (hdev->conn_hash.acl_num > 0) {
-               if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
-                       if (btusb_submit_bulk_urb(hdev) < 0)
-                               clear_bit(BTUSB_BULK_RUNNING, &data->flags);
-                       else
-                               btusb_submit_bulk_urb(hdev);
-               }
-       } else {
-               clear_bit(BTUSB_BULK_RUNNING, &data->flags);
-               usb_kill_anchored_urbs(&data->bulk_anchor);
-       }
-
        if (hdev->conn_hash.sco_num > 0) {
                if (data->isoc_altsetting != 2) {
                        clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
@@ -754,10 +734,10 @@ static void btusb_work(struct work_struct *work)
                }
 
                if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
-                       if (btusb_submit_isoc_urb(hdev) < 0)
+                       if (btusb_submit_isoc_urb(hdev, GFP_KERNEL) < 0)
                                clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
                        else
-                               btusb_submit_isoc_urb(hdev);
+                               btusb_submit_isoc_urb(hdev, GFP_KERNEL);
                }
        } else {
                clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
@@ -828,6 +808,8 @@ static int btusb_probe(struct usb_interface *intf,
                return -ENODEV;
        }
 
+       data->cmdreq_type = USB_TYPE_CLASS;
+
        data->udev = interface_to_usbdev(intf);
        data->intf = intf;
 
@@ -862,11 +844,11 @@ static int btusb_probe(struct usb_interface *intf,
 
        hdev->owner = THIS_MODULE;
 
-       /* interface numbers are hardcoded in the spec */
+       /* Interface numbers are hardcoded in the specification */
        data->isoc = usb_ifnum_to_if(data->udev, 1);
 
-       if (reset || id->driver_info & BTUSB_RESET)
-               set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
+       if (!reset)
+               set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
 
        if (force_scofix || id->driver_info & BTUSB_WRONG_SCO_MTU) {
                if (!disable_scofix)
@@ -876,9 +858,23 @@ static int btusb_probe(struct usb_interface *intf,
        if (id->driver_info & BTUSB_BROKEN_ISOC)
                data->isoc = NULL;
 
+       if (id->driver_info & BTUSB_DIGIANSWER) {
+               data->cmdreq_type = USB_TYPE_VENDOR;
+               set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
+       }
+
+       if (id->driver_info & BTUSB_CSR) {
+               struct usb_device *udev = data->udev;
+
+               /* Old firmware would otherwise execute USB reset */
+               if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x117)
+                       set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
+       }
+
        if (id->driver_info & BTUSB_SNIFFER) {
                struct usb_device *udev = data->udev;
 
+               /* New sniffer firmware has crippled HCI interface */
                if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
                        set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
 
@@ -949,10 +945,71 @@ static void btusb_disconnect(struct usb_interface *intf)
        hci_free_dev(hdev);
 }
 
+static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct btusb_data *data = usb_get_intfdata(intf);
+
+       BT_DBG("intf %p", intf);
+
+       if (data->suspend_count++)
+               return 0;
+
+       cancel_work_sync(&data->work);
+
+       usb_kill_anchored_urbs(&data->tx_anchor);
+
+       usb_kill_anchored_urbs(&data->isoc_anchor);
+       usb_kill_anchored_urbs(&data->bulk_anchor);
+       usb_kill_anchored_urbs(&data->intr_anchor);
+
+       return 0;
+}
+
+static int btusb_resume(struct usb_interface *intf)
+{
+       struct btusb_data *data = usb_get_intfdata(intf);
+       struct hci_dev *hdev = data->hdev;
+       int err;
+
+       BT_DBG("intf %p", intf);
+
+       if (--data->suspend_count)
+               return 0;
+
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
+               return 0;
+
+       if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) {
+               err = btusb_submit_intr_urb(hdev, GFP_NOIO);
+               if (err < 0) {
+                       clear_bit(BTUSB_INTR_RUNNING, &data->flags);
+                       return err;
+               }
+       }
+
+       if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
+               if (btusb_submit_bulk_urb(hdev, GFP_NOIO) < 0)
+                       clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+               else
+                       btusb_submit_bulk_urb(hdev, GFP_NOIO);
+       }
+
+       if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
+               if (btusb_submit_isoc_urb(hdev, GFP_NOIO) < 0)
+                       clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+               else
+                       btusb_submit_isoc_urb(hdev, GFP_NOIO);
+       }
+
+       return 0;
+}
+
 static struct usb_driver btusb_driver = {
        .name           = "btusb",
        .probe          = btusb_probe,
        .disconnect     = btusb_disconnect,
+       .suspend        = btusb_suspend,
+       .resume         = btusb_resume,
        .id_table       = btusb_table,
 };
 
index 8dfcf77cb71783c892437f5cb20eff417c1ee94e..9e31fc429b10cf2e6330b010e68d6ef7f64b22bd 100644 (file)
@@ -399,8 +399,8 @@ static int hci_uart_register_dev(struct hci_uart *hu)
 
        hdev->owner = THIS_MODULE;
 
-       if (reset)
-               set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
+       if (!reset)
+               set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
 
        if (hci_register_dev(hdev) < 0) {
                BT_ERR("Can't register HCI device");
index b91d45a41b2f6b7e88716626b392a33124b789d8..2d2f66e17fea65c6baed390a4129639fc0e0e7f2 100644 (file)
 
 #include "hci_uart.h"
 
+#ifndef CONFIG_BT_HCIUART_DEBUG
+#undef  BT_DBG
+#define BT_DBG( A... )
+#endif
+
 /* HCILL commands */
 #define HCILL_GO_TO_SLEEP_IND  0x30
 #define HCILL_GO_TO_SLEEP_ACK  0x31
index 3cc29491931268fab71e4c9663c0f6c13c671510..3645139e68c7d804dc53132435934f3325bb40f2 100644 (file)
@@ -54,7 +54,7 @@
 
 /* HCI device quirks */
 enum {
-       HCI_QUIRK_RESET_ON_INIT,
+       HCI_QUIRK_NO_RESET,
        HCI_QUIRK_RAW_DEVICE,
        HCI_QUIRK_FIXUP_BUFFER_SIZE
 };
index f6348e078aa434077bf26c57ffb8f0eabf4ecbe3..8dc78dc3898b7e48fd344679468d9a7408ac33e7 100644 (file)
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "2.13"
+#define VERSION "2.14"
 
 /* Bluetooth sockets */
 #define BT_MAX_PROTO   8
 static struct net_proto_family *bt_proto[BT_MAX_PROTO];
+static DEFINE_RWLOCK(bt_proto_lock);
 
-static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
 static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
 static const char *bt_key_strings[BT_MAX_PROTO] = {
        "sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
@@ -68,6 +69,7 @@ static const char *bt_key_strings[BT_MAX_PROTO] = {
        "sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP",
 };
 
+static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
 static const char *bt_slock_key_strings[BT_MAX_PROTO] = {
        "slock-AF_BLUETOOTH-BTPROTO_L2CAP",
        "slock-AF_BLUETOOTH-BTPROTO_HCI",
@@ -78,7 +80,25 @@ static const char *bt_slock_key_strings[BT_MAX_PROTO] = {
        "slock-AF_BLUETOOTH-BTPROTO_HIDP",
        "slock-AF_BLUETOOTH-BTPROTO_AVDTP",
 };
-static DEFINE_RWLOCK(bt_proto_lock);
+
+static inline void bt_sock_reclassify_lock(struct socket *sock, int proto)
+{
+       struct sock *sk = sock->sk;
+
+       if (!sk)
+               return;
+
+       BUG_ON(sock_owned_by_user(sk));
+
+       sock_lock_init_class_and_name(sk,
+                       bt_slock_key_strings[proto], &bt_slock_key[proto],
+                               bt_key_strings[proto], &bt_lock_key[proto]);
+}
+#else
+static inline void bt_sock_reclassify_lock(struct socket *sock, int proto)
+{
+}
+#endif
 
 int bt_sock_register(int proto, struct net_proto_family *ops)
 {
@@ -120,21 +140,6 @@ int bt_sock_unregister(int proto)
 }
 EXPORT_SYMBOL(bt_sock_unregister);
 
-static void bt_reclassify_sock_lock(struct socket *sock, int proto)
-{
-       struct sock *sk = sock->sk;
-
-       if (!sk)
-               return;
-       BUG_ON(sock_owned_by_user(sk));
-
-       sock_lock_init_class_and_name(sk,
-                       bt_slock_key_strings[proto],
-                       &bt_slock_key[proto],
-                       bt_key_strings[proto],
-                       &bt_lock_key[proto]);
-}
-
 static int bt_sock_create(struct net *net, struct socket *sock, int proto)
 {
        int err;
@@ -157,7 +162,7 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto)
 
        if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
                err = bt_proto[proto]->create(net, sock, proto);
-               bt_reclassify_sock_lock(sock, proto);
+               bt_sock_reclassify_lock(sock, proto);
                module_put(bt_proto[proto]->owner);
        }
 
index 278a3ace14f664e019a85109ae6450e9ed13cff6..4f40a64201f0ce6dd8ad9fd133b4594fc267a4d9 100644 (file)
@@ -205,7 +205,7 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
        /* Mandatory initialization */
 
        /* Reset */
-       if (test_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks))
+       if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks))
                        hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
 
        /* Read Local Supported Features */
@@ -756,7 +756,7 @@ int hci_get_dev_list(void __user *arg)
 
        size = sizeof(*dl) + dev_num * sizeof(*dr);
 
-       if (!(dl = kmalloc(size, GFP_KERNEL)))
+       if (!(dl = kzalloc(size, GFP_KERNEL)))
                return -ENOMEM;
 
        dr = dl->dev_req;
@@ -875,7 +875,7 @@ int hci_register_dev(struct hci_dev *hdev)
        hdev->esco_type = (ESCO_HV1);
        hdev->link_mode = (HCI_LM_ACCEPT);
 
-       hdev->idle_timeout = 0;
+       hdev->idle_timeout = HCI_IDLE_TIMEOUT;
        hdev->sniff_max_interval = 800;
        hdev->sniff_min_interval = 80;
 
index d3340dd52bcffd778f6604ed716cebf8f1577a42..4387e1089d00b062841d6e4a168690424120519f 100644 (file)
@@ -58,7 +58,7 @@ struct rfcomm_dev {
        char                    name[12];
        int                     id;
        unsigned long           flags;
-       int                     opened;
+       atomic_t                opened;
        int                     err;
 
        bdaddr_t                src;
@@ -261,6 +261,8 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
        dev->flags = req->flags &
                ((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
 
+       atomic_set(&dev->opened, 0);
+
        init_waitqueue_head(&dev->wait);
        tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev);
 
@@ -330,10 +332,10 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev)
 {
        BT_DBG("dev %p", dev);
 
-       if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
-               BUG_ON(1);
-       else
-               set_bit(RFCOMM_TTY_RELEASED, &dev->flags);
+       BUG_ON(test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags));
+
+       if (atomic_read(&dev->opened) > 0)
+               return;
 
        write_lock_bh(&rfcomm_dev_lock);
        list_del_init(&dev->list);
@@ -689,9 +691,10 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
        if (!dev)
                return -ENODEV;
 
-       BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst), dev->channel, dev->opened);
+       BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst),
+                               dev->channel, atomic_read(&dev->opened));
 
-       if (dev->opened++ != 0)
+       if (atomic_inc_return(&dev->opened) > 1)
                return 0;
 
        dlc = dev->dlc;
@@ -747,9 +750,10 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
        if (!dev)
                return;
 
-       BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, dev->opened);
+       BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc,
+                                               atomic_read(&dev->opened));
 
-       if (--dev->opened == 0) {
+       if (atomic_dec_and_test(&dev->opened)) {
                if (dev->tty_dev->parent)
                        device_move(dev->tty_dev, NULL);
 
@@ -763,6 +767,14 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
                tty->driver_data = NULL;
                dev->tty = NULL;
                rfcomm_dlc_unlock(dev->dlc);
+
+               if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) {
+                       write_lock_bh(&rfcomm_dev_lock);
+                       list_del_init(&dev->list);
+                       write_unlock_bh(&rfcomm_dev_lock);
+
+                       rfcomm_dev_put(dev);
+               }
        }
 
        rfcomm_dev_put(dev);