]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville...
authorDavid S. Miller <davem@davemloft.net>
Wed, 16 May 2012 05:03:54 +0000 (01:03 -0400)
committerDavid S. Miller <davem@davemloft.net>
Wed, 16 May 2012 05:04:07 +0000 (01:04 -0400)
John Linville says:

Here are three more fixes that some of my developers are desperate to
see included in 3.4...

Johan Hedberg went to some length justifyng the inclusion of these two
Bluetooth fixes:

"The device_connected fix should be quite self-explanatory, but it's
actually a wider issue than just for keyboards. All profiles that do
incoming connection authorization (e.g. headsets) will break without it
with specific hardware. The reason it wasn't caught earlier is that it
only occurs with specific Bluetooth adapters.

As for the security level patch, this fixes L2CAP socket based security
level elevation during a connection. The HID profile needs this (for
keyboards) and it is the only way to achieve the security level
elevation when using the management interface to talk to the kernel
(hence the management enabling patch being the one that exposes this"

The rtlwifi fix addresses a regression related to firmware loading,
as described in kernel.org bug 43187.  It basically just moves a hunk
of code to a more appropriate place.

Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/usb.c
include/net/bluetooth/bluetooth.h
net/bluetooth/af_bluetooth.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c

index cc15fdb36060b3dd387124e6288ac288c901cc78..67f9430ee197743fa7d2f22a02f706c46cafdd98 100644 (file)
@@ -1851,14 +1851,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
        /*like read eeprom and so on */
        rtlpriv->cfg->ops->read_eeprom_info(hw);
 
-       if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
-               err = -ENODEV;
-               goto fail3;
-       }
-
-       rtlpriv->cfg->ops->init_sw_leds(hw);
-
        /*aspm */
        rtl_pci_init_aspm(hw);
 
@@ -1877,6 +1869,14 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
                goto fail3;
        }
 
+       if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
+               err = -ENODEV;
+               goto fail3;
+       }
+
+       rtlpriv->cfg->ops->init_sw_leds(hw);
+
        err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
index d04dbda13f5a3bd699e6265490736da54adc2702..a6049d7d51b39dc0dbb02cccad5bf6c24003b419 100644 (file)
@@ -971,11 +971,6 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
        rtlpriv->cfg->ops->read_chip_version(hw);
        /*like read eeprom and so on */
        rtlpriv->cfg->ops->read_eeprom_info(hw);
-       if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
-               goto error_out;
-       }
-       rtlpriv->cfg->ops->init_sw_leds(hw);
        err = _rtl_usb_init(hw);
        if (err)
                goto error_out;
@@ -987,6 +982,11 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
                         "Can't allocate sw for mac80211\n");
                goto error_out;
        }
+       if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
+               goto error_out;
+       }
+       rtlpriv->cfg->ops->init_sw_leds(hw);
 
        return 0;
 error_out:
index 262ebd1747d4d2d0121f20a5114741d48c8a48fe..a65910bda3811551ba0ae089abb47f428dee3e94 100644 (file)
@@ -191,6 +191,7 @@ struct bt_sock {
        struct list_head accept_q;
        struct sock *parent;
        u32 defer_setup;
+       bool suspended;
 };
 
 struct bt_sock_list {
index 72eb187a5f605f9835d71c2de9f980e1e52d6a4e..6fb68a9743af7ebef18adc506f55d1f048bc9181 100644 (file)
@@ -450,7 +450,7 @@ unsigned int bt_sock_poll(struct file *file, struct socket *sock, poll_table *wa
                        sk->sk_state == BT_CONFIG)
                return mask;
 
-       if (sock_writeable(sk))
+       if (!bt_sk(sk)->suspended && sock_writeable(sk))
                mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
        else
                set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
index edfd61addceca4b269891734646fedbe6fbe8606..d6dc44cd15b0729a90bc8963ae90182353ed7e10 100644 (file)
@@ -2784,6 +2784,14 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
        if (conn) {
                hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
 
+               hci_dev_lock(hdev);
+               if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
+                   !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
+                       mgmt_device_connected(hdev, &conn->dst, conn->type,
+                                             conn->dst_type, 0, NULL, 0,
+                                             conn->dev_class);
+               hci_dev_unlock(hdev);
+
                /* Send to upper protocol */
                l2cap_recv_acldata(conn, skb, flags);
                return;
index 6c065254afc03dcfbd11bad037791561b7f99f45..1266f78fa8e3283a6d854d1b808312b8916c981f 100644 (file)
@@ -2039,6 +2039,12 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
 
                clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
 
+               if (ev->status && conn->state == BT_CONNECTED) {
+                       hci_acl_disconn(conn, 0x13);
+                       hci_conn_put(conn);
+                       goto unlock;
+               }
+
                if (conn->state == BT_CONFIG) {
                        if (!ev->status)
                                conn->state = BT_CONNECTED;
@@ -2049,6 +2055,7 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
                        hci_encrypt_cfm(conn, ev->status, ev->encrypt);
        }
 
+unlock:
        hci_dev_unlock(hdev);
 }
 
@@ -2102,7 +2109,7 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
                goto unlock;
        }
 
-       if (!ev->status) {
+       if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
                struct hci_cp_remote_name_req cp;
                memset(&cp, 0, sizeof(cp));
                bacpy(&cp.bdaddr, &conn->dst);
@@ -2871,7 +2878,7 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
        if (conn->state != BT_CONFIG)
                goto unlock;
 
-       if (!ev->status) {
+       if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
                struct hci_cp_remote_name_req cp;
                memset(&cp, 0, sizeof(cp));
                bacpy(&cp.bdaddr, &conn->dst);
index 94552b33d528447eea4b604b996c7d90ba0ab036..6f9c25b633a604ce35824a8b466186df6ddb25c3 100644 (file)
@@ -4589,6 +4589,11 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 
                if (!status && (chan->state == BT_CONNECTED ||
                                                chan->state == BT_CONFIG)) {
+                       struct sock *sk = chan->sk;
+
+                       bt_sk(sk)->suspended = false;
+                       sk->sk_state_change(sk);
+
                        l2cap_check_encryption(chan, encrypt);
                        l2cap_chan_unlock(chan);
                        continue;
index 29122ed28ea96965433fb6086756244d9eabd508..04e7c172d49c9e0ce421b7f378f693e28bda888f 100644 (file)
@@ -592,10 +592,14 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
                        sk->sk_state = BT_CONFIG;
                        chan->state = BT_CONFIG;
 
-               /* or for ACL link, under defer_setup time */
-               } else if (sk->sk_state == BT_CONNECT2 &&
-                                       bt_sk(sk)->defer_setup) {
-                       err = l2cap_chan_check_security(chan);
+               /* or for ACL link */
+               } else if ((sk->sk_state == BT_CONNECT2 &&
+                          bt_sk(sk)->defer_setup) ||
+                          sk->sk_state == BT_CONNECTED) {
+                       if (!l2cap_chan_check_security(chan))
+                               bt_sk(sk)->suspended = true;
+                       else
+                               sk->sk_state_change(sk);
                } else {
                        err = -EINVAL;
                }