linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / net / bluetooth / hci_event.c
index 3896dab..eb64555 100644 (file)
@@ -24,6 +24,7 @@
 
 /* Bluetooth HCI event handling. */
 
+#include <linux/config.h>
 #include <linux/module.h>
 
 #include <linux/types.h>
@@ -83,8 +84,6 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *
 {
        struct hci_conn *conn;
        struct hci_rp_role_discovery *rd;
-       struct hci_rp_write_link_policy *lp;
-       void *sent;
 
        BT_DBG("%s ocf 0x%x", hdev->name, ocf);
 
@@ -108,27 +107,6 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *
                hci_dev_unlock(hdev);
                break;
 
-       case OCF_WRITE_LINK_POLICY:
-               sent = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY);
-               if (!sent)
-                       break;
-
-               lp = (struct hci_rp_write_link_policy *) skb->data;
-
-               if (lp->status)
-                       break;
-
-               hci_dev_lock(hdev);
-
-               conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(lp->handle));
-               if (conn) {
-                       __le16 policy = get_unaligned((__le16 *) (sent + 2));
-                       conn->link_policy = __le16_to_cpu(policy);
-               }
-
-               hci_dev_unlock(hdev);
-               break;
-
        default:
                BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x", 
                                hdev->name, ocf);
@@ -297,7 +275,7 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
 /* Command Complete OGF INFO_PARAM  */
 static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
 {
-       struct hci_rp_read_local_features *lf;
+       struct hci_rp_read_loc_features *lf;
        struct hci_rp_read_buffer_size *bs;
        struct hci_rp_read_bd_addr *ba;
 
@@ -305,7 +283,7 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
 
        switch (ocf) {
        case OCF_READ_LOCAL_FEATURES:
-               lf = (struct hci_rp_read_local_features *) skb->data;
+               lf = (struct hci_rp_read_loc_features *) skb->data;
 
                if (lf->status) {
                        BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
@@ -342,17 +320,9 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
                }
 
                hdev->acl_mtu  = __le16_to_cpu(bs->acl_mtu);
-               hdev->sco_mtu  = bs->sco_mtu;
-               hdev->acl_pkts = __le16_to_cpu(bs->acl_max_pkt);
-               hdev->sco_pkts = __le16_to_cpu(bs->sco_max_pkt);
-
-               if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
-                       hdev->sco_mtu  = 64;
-                       hdev->sco_pkts = 8;
-               }
-
-               hdev->acl_cnt = hdev->acl_pkts;
-               hdev->sco_cnt = hdev->sco_pkts;
+               hdev->sco_mtu  = bs->sco_mtu ? bs->sco_mtu : 64;
+               hdev->acl_pkts = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
+               hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
 
                BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
                        hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
@@ -470,46 +440,8 @@ static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
        BT_DBG("%s ocf 0x%x", hdev->name, ocf);
 
        switch (ocf) {
-       case OCF_SNIFF_MODE:
-               if (status) {
-                       struct hci_conn *conn;
-                       struct hci_cp_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_SNIFF_MODE);
-
-                       if (!cp)
-                               break;
-
-                       hci_dev_lock(hdev);
-
-                       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
-                       if (conn) {
-                               clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
-                       }
-
-                       hci_dev_unlock(hdev);
-               }
-               break;
-
-       case OCF_EXIT_SNIFF_MODE:
-               if (status) {
-                       struct hci_conn *conn;
-                       struct hci_cp_exit_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_EXIT_SNIFF_MODE);
-
-                       if (!cp)
-                               break;
-
-                       hci_dev_lock(hdev);
-
-                       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
-                       if (conn) {
-                               clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
-                       }
-
-                       hci_dev_unlock(hdev);
-               }
-               break;
-
        default:
-               BT_DBG("%s Command status: ogf LINK_POLICY ocf %x", hdev->name, ocf);
+               BT_DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
                break;
        }
 }
@@ -691,16 +623,14 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
                else
                        cp.role = 0x01; /* Remain slave */
 
-               hci_send_cmd(hdev, OGF_LINK_CTL,
-                               OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp);
+               hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp);
        } else {
                /* Connection rejected */
                struct hci_cp_reject_conn_req cp;
 
                bacpy(&cp.bdaddr, &ev->bdaddr);
                cp.reason = 0x0f;
-               hci_send_cmd(hdev, OGF_LINK_CTL,
-                               OCF_REJECT_CONN_REQ, sizeof(cp), &cp);
+               hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ, sizeof(cp), &cp);
        }
 }
 
@@ -708,7 +638,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
 static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data;
-       struct hci_conn *conn;
+       struct hci_conn *conn = NULL;
 
        BT_DBG("%s", hdev->name);
 
@@ -730,21 +660,12 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
                if (test_bit(HCI_ENCRYPT, &hdev->flags))
                        conn->link_mode |= HCI_LM_ENCRYPT;
 
-               /* Get remote features */
-               if (conn->type == ACL_LINK) {
-                       struct hci_cp_read_remote_features cp;
-                       cp.handle = ev->handle;
-                       hci_send_cmd(hdev, OGF_LINK_CTL,
-                               OCF_READ_REMOTE_FEATURES, sizeof(cp), &cp);
-               }
-
                /* Set link policy */
                if (conn->type == ACL_LINK && hdev->link_policy) {
                        struct hci_cp_write_link_policy cp;
                        cp.handle = ev->handle;
                        cp.policy = __cpu_to_le16(hdev->link_policy);
-                       hci_send_cmd(hdev, OGF_LINK_POLICY,
-                               OCF_WRITE_LINK_POLICY, sizeof(cp), &cp);
+                       hci_send_cmd(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY, sizeof(cp), &cp);
                }
 
                /* Set packet type for incoming connection */
@@ -755,8 +676,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
                                __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
                                __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
 
-                       hci_send_cmd(hdev, OGF_LINK_CTL,
-                               OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
+                       hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
                }
        } else
                conn->state = BT_CLOSED;
@@ -784,7 +704,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
 static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_ev_disconn_complete *ev = (struct hci_ev_disconn_complete *) skb->data;
-       struct hci_conn *conn;
+       struct hci_conn *conn = NULL;
+       __u16 handle = __le16_to_cpu(ev->handle);
 
        BT_DBG("%s status %d", hdev->name, ev->status);
 
@@ -793,7 +714,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
 
        hci_dev_lock(hdev);
 
-       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+       conn = hci_conn_hash_lookup_handle(hdev, handle);
        if (conn) {
                conn->state = BT_CLOSED;
                hci_proto_disconn_ind(conn, ev->reason);
@@ -850,7 +771,7 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
 static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_ev_role_change *ev = (struct hci_ev_role_change *) skb->data;
-       struct hci_conn *conn;
+       struct hci_conn *conn = NULL;
 
        BT_DBG("%s status %d", hdev->name, ev->status);
 
@@ -873,43 +794,18 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb
        hci_dev_unlock(hdev);
 }
 
-/* Mode Change */
-static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-       struct hci_ev_mode_change *ev = (struct hci_ev_mode_change *) skb->data;
-       struct hci_conn *conn;
-
-       BT_DBG("%s status %d", hdev->name, ev->status);
-
-       hci_dev_lock(hdev);
-
-       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
-       if (conn) {
-               conn->mode = ev->mode;
-               conn->interval = __le16_to_cpu(ev->interval);
-
-               if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
-                       if (conn->mode == HCI_CM_ACTIVE)
-                               conn->power_save = 1;
-                       else
-                               conn->power_save = 0;
-               }
-       }
-
-       hci_dev_unlock(hdev);
-}
-
 /* Authentication Complete */
 static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_ev_auth_complete *ev = (struct hci_ev_auth_complete *) skb->data;
-       struct hci_conn *conn;
+       struct hci_conn *conn = NULL;
+       __u16 handle = __le16_to_cpu(ev->handle);
 
        BT_DBG("%s status %d", hdev->name, ev->status);
 
        hci_dev_lock(hdev);
 
-       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+       conn = hci_conn_hash_lookup_handle(hdev, handle);
        if (conn) {
                if (!ev->status)
                        conn->link_mode |= HCI_LM_AUTH;
@@ -924,7 +820,8 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
                                cp.handle  = __cpu_to_le16(conn->handle);
                                cp.encrypt = 1;
                                hci_send_cmd(conn->hdev, OGF_LINK_CTL,
-                                       OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp);
+                                               OCF_SET_CONN_ENCRYPT,
+                                               sizeof(cp), &cp);
                        } else {
                                clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
                                hci_encrypt_cfm(conn, ev->status, 0x00);
@@ -939,13 +836,14 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
 static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_ev_encrypt_change *ev = (struct hci_ev_encrypt_change *) skb->data;
-       struct hci_conn *conn;
+       struct hci_conn *conn = NULL;
+       __u16 handle = __le16_to_cpu(ev->handle);
 
        BT_DBG("%s status %d", hdev->name, ev->status);
 
        hci_dev_lock(hdev);
 
-       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+       conn = hci_conn_hash_lookup_handle(hdev, handle);
        if (conn) {
                if (!ev->status) {
                        if (ev->encrypt)
@@ -966,13 +864,14 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
 static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_ev_change_conn_link_key_complete *ev = (struct hci_ev_change_conn_link_key_complete *) skb->data;
-       struct hci_conn *conn;
+       struct hci_conn *conn = NULL;
+       __u16 handle = __le16_to_cpu(ev->handle);
 
        BT_DBG("%s status %d", hdev->name, ev->status);
 
        hci_dev_lock(hdev);
 
-       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+       conn = hci_conn_hash_lookup_handle(hdev, handle);
        if (conn) {
                if (!ev->status)
                        conn->link_mode |= HCI_LM_SECURE;
@@ -1000,35 +899,18 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff
 {
 }
 
-/* Remote Features */
-static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-       struct hci_ev_remote_features *ev = (struct hci_ev_remote_features *) skb->data;
-       struct hci_conn *conn;
-
-       BT_DBG("%s status %d", hdev->name, ev->status);
-
-       hci_dev_lock(hdev);
-
-       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
-       if (conn && !ev->status) {
-               memcpy(conn->features, ev->features, sizeof(conn->features));
-       }
-
-       hci_dev_unlock(hdev);
-}
-
 /* Clock Offset */
 static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data;
-       struct hci_conn *conn;
+       struct hci_conn *conn = NULL;
+       __u16 handle = __le16_to_cpu(ev->handle);
 
        BT_DBG("%s status %d", hdev->name, ev->status);
 
        hci_dev_lock(hdev);
 
-       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+       conn = hci_conn_hash_lookup_handle(hdev, handle);
        if (conn && !ev->status) {
                struct inquiry_entry *ie;
 
@@ -1059,23 +941,6 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *
        hci_dev_unlock(hdev);
 }
 
-/* Sniff Subrate */
-static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-       struct hci_ev_sniff_subrate *ev = (struct hci_ev_sniff_subrate *) skb->data;
-       struct hci_conn *conn;
-
-       BT_DBG("%s status %d", hdev->name, ev->status);
-
-       hci_dev_lock(hdev);
-
-       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
-       if (conn) {
-       }
-
-       hci_dev_unlock(hdev);
-}
-
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
@@ -1124,10 +989,6 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
                hci_role_change_evt(hdev, skb);
                break;
 
-       case HCI_EV_MODE_CHANGE:
-               hci_mode_change_evt(hdev, skb);
-               break;
-
        case HCI_EV_AUTH_COMPLETE:
                hci_auth_complete_evt(hdev, skb);
                break;
@@ -1152,10 +1013,6 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
                hci_link_key_notify_evt(hdev, skb);
                break;
 
-       case HCI_EV_REMOTE_FEATURES:
-               hci_remote_features_evt(hdev, skb);
-               break;
-
        case HCI_EV_CLOCK_OFFSET:
                hci_clock_offset_evt(hdev, skb);
                break;
@@ -1164,10 +1021,6 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
                hci_pscan_rep_mode_evt(hdev, skb);
                break;
 
-       case HCI_EV_SNIFF_SUBRATE:
-               hci_sniff_subrate_evt(hdev, skb);
-               break;
-
        case HCI_EV_CMD_STATUS:
                cs = (struct hci_ev_cmd_status *) skb->data;
                skb_pull(skb, sizeof(cs));