Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth
John W. Linville [Wed, 2 Nov 2011 19:15:51 +0000 (15:15 -0400)]
drivers/bluetooth/ath3k.c
drivers/bluetooth/bcm203x.c
drivers/bluetooth/bfusb.c
include/net/bluetooth/rfcomm.h
net/bluetooth/hci_core.c
net/bluetooth/mgmt.c
net/bluetooth/rfcomm/core.c

index db7cb81..106beb1 100644 (file)
@@ -105,7 +105,7 @@ static int ath3k_load_firmware(struct usb_device *udev,
 
        pipe = usb_sndctrlpipe(udev, 0);
 
-       send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
+       send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);
        if (!send_buf) {
                BT_ERR("Can't allocate memory chunk for firmware");
                return -ENOMEM;
@@ -176,7 +176,7 @@ static int ath3k_load_fwfile(struct usb_device *udev,
 
        count = firmware->size;
 
-       send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
+       send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);
        if (!send_buf) {
                BT_ERR("Can't allocate memory chunk for firmware");
                return -ENOMEM;
index 8b1b643..54952ab 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/module.h>
 
+#include <linux/atomic.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -65,6 +66,7 @@ struct bcm203x_data {
        unsigned long           state;
 
        struct work_struct      work;
+       atomic_t                shutdown;
 
        struct urb              *urb;
        unsigned char           *buffer;
@@ -97,6 +99,7 @@ static void bcm203x_complete(struct urb *urb)
 
                data->state = BCM203X_SELECT_MEMORY;
 
+               /* use workqueue to have a small delay */
                schedule_work(&data->work);
                break;
 
@@ -155,7 +158,10 @@ static void bcm203x_work(struct work_struct *work)
        struct bcm203x_data *data =
                container_of(work, struct bcm203x_data, work);
 
-       if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
+       if (atomic_read(&data->shutdown))
+               return;
+
+       if (usb_submit_urb(data->urb, GFP_KERNEL) < 0)
                BT_ERR("Can't submit URB");
 }
 
@@ -243,6 +249,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
 
        usb_set_intfdata(intf, data);
 
+       /* use workqueue to have a small delay */
        schedule_work(&data->work);
 
        return 0;
@@ -254,6 +261,9 @@ static void bcm203x_disconnect(struct usb_interface *intf)
 
        BT_DBG("intf %p", intf);
 
+       atomic_inc(&data->shutdown);
+       cancel_work_sync(&data->work);
+
        usb_kill_urb(data->urb);
 
        usb_set_intfdata(intf, NULL);
index 005919a..61b5914 100644 (file)
@@ -568,22 +568,23 @@ static int bfusb_load_firmware(struct bfusb_data *data,
 
        BT_INFO("BlueFRITZ! USB loading firmware");
 
+       buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_KERNEL);
+       if (!buf) {
+               BT_ERR("Can't allocate memory chunk for firmware");
+               return -ENOMEM;
+       }
+
        pipe = usb_sndctrlpipe(data->udev, 0);
 
        if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
                                0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
                BT_ERR("Can't change to loading configuration");
+               kfree(buf);
                return -EBUSY;
        }
 
        data->udev->toggle[0] = data->udev->toggle[1] = 0;
 
-       buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
-       if (!buf) {
-               BT_ERR("Can't allocate memory chunk for firmware");
-               return -ENOMEM;
-       }
-
        pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
 
        while (count) {
index d5eee20..e2e3eca 100644 (file)
@@ -211,6 +211,7 @@ struct rfcomm_dlc {
 #define RFCOMM_AUTH_ACCEPT  6
 #define RFCOMM_AUTH_REJECT  7
 #define RFCOMM_DEFER_SETUP  8
+#define RFCOMM_ENC_DROP     9
 
 /* Scheduling flags and events */
 #define RFCOMM_SCHED_WAKEUP 31
index b84458d..be84ae3 100644 (file)
@@ -613,7 +613,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
        if (!test_bit(HCI_RAW, &hdev->flags)) {
                set_bit(HCI_INIT, &hdev->flags);
                __hci_request(hdev, hci_reset_req, 0,
-                                       msecs_to_jiffies(250));
+                                       msecs_to_jiffies(HCI_INIT_TIMEOUT));
                clear_bit(HCI_INIT, &hdev->flags);
        }
 
index 5a94eec..5caff4d 100644 (file)
@@ -147,8 +147,6 @@ static int read_index_list(struct sock *sk)
 
                hci_del_off_timer(d);
 
-               set_bit(HCI_MGMT, &d->flags);
-
                if (test_bit(HCI_SETUP, &d->flags))
                        continue;
 
index 38b618c..4e32e18 100644 (file)
@@ -1802,6 +1802,11 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
                        continue;
                }
 
+               if (test_bit(RFCOMM_ENC_DROP, &d->flags)) {
+                       __rfcomm_dlc_close(d, ECONNREFUSED);
+                       continue;
+               }
+
                if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) {
                        rfcomm_dlc_clear_timer(d);
                        if (d->out) {
@@ -2077,7 +2082,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
                if (test_and_clear_bit(RFCOMM_SEC_PENDING, &d->flags)) {
                        rfcomm_dlc_clear_timer(d);
                        if (status || encrypt == 0x00) {
-                               __rfcomm_dlc_close(d, ECONNREFUSED);
+                               set_bit(RFCOMM_ENC_DROP, &d->flags);
                                continue;
                        }
                }
@@ -2088,7 +2093,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
                                rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
                                continue;
                        } else if (d->sec_level == BT_SECURITY_HIGH) {
-                               __rfcomm_dlc_close(d, ECONNREFUSED);
+                               set_bit(RFCOMM_ENC_DROP, &d->flags);
                                continue;
                        }
                }