aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-10-11 15:30:34 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-11 15:30:34 -0400
commitd122179a3c0fdc71b88cb9e3605f372b1651a9ff (patch)
tree63a48b333e7565967b6d7c9e246557bfcb9f225f /net/bluetooth
parent419c20465d6319274e7286f0966e2390540e6e0a (diff)
parentb00916b189d13a615ff05c9242201135992fcda3 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: net/core/ethtool.c
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/l2cap.c62
-rw-r--r--net/bluetooth/rfcomm/sock.c4
2 files changed, 33 insertions, 33 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index fadf26b4ed7c..0b54b7dd8401 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1441,33 +1441,23 @@ static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
1441 1441
1442static void l2cap_streaming_send(struct sock *sk) 1442static void l2cap_streaming_send(struct sock *sk)
1443{ 1443{
1444 struct sk_buff *skb, *tx_skb; 1444 struct sk_buff *skb;
1445 struct l2cap_pinfo *pi = l2cap_pi(sk); 1445 struct l2cap_pinfo *pi = l2cap_pi(sk);
1446 u16 control, fcs; 1446 u16 control, fcs;
1447 1447
1448 while ((skb = sk->sk_send_head)) { 1448 while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
1449 tx_skb = skb_clone(skb, GFP_ATOMIC); 1449 control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
1450
1451 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1452 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; 1450 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1453 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); 1451 put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
1454 1452
1455 if (pi->fcs == L2CAP_FCS_CRC16) { 1453 if (pi->fcs == L2CAP_FCS_CRC16) {
1456 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2); 1454 fcs = crc16(0, (u8 *)skb->data, skb->len - 2);
1457 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2); 1455 put_unaligned_le16(fcs, skb->data + skb->len - 2);
1458 } 1456 }
1459 1457
1460 l2cap_do_send(sk, tx_skb); 1458 l2cap_do_send(sk, skb);
1461 1459
1462 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; 1460 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1463
1464 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1465 sk->sk_send_head = NULL;
1466 else
1467 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1468
1469 skb = skb_dequeue(TX_QUEUE(sk));
1470 kfree_skb(skb);
1471 } 1461 }
1472} 1462}
1473 1463
@@ -1960,6 +1950,11 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
1960 1950
1961 switch (optname) { 1951 switch (optname) {
1962 case L2CAP_OPTIONS: 1952 case L2CAP_OPTIONS:
1953 if (sk->sk_state == BT_CONNECTED) {
1954 err = -EINVAL;
1955 break;
1956 }
1957
1963 opts.imtu = l2cap_pi(sk)->imtu; 1958 opts.imtu = l2cap_pi(sk)->imtu;
1964 opts.omtu = l2cap_pi(sk)->omtu; 1959 opts.omtu = l2cap_pi(sk)->omtu;
1965 opts.flush_to = l2cap_pi(sk)->flush_to; 1960 opts.flush_to = l2cap_pi(sk)->flush_to;
@@ -2771,10 +2766,10 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
2771 case L2CAP_CONF_MTU: 2766 case L2CAP_CONF_MTU:
2772 if (val < L2CAP_DEFAULT_MIN_MTU) { 2767 if (val < L2CAP_DEFAULT_MIN_MTU) {
2773 *result = L2CAP_CONF_UNACCEPT; 2768 *result = L2CAP_CONF_UNACCEPT;
2774 pi->omtu = L2CAP_DEFAULT_MIN_MTU; 2769 pi->imtu = L2CAP_DEFAULT_MIN_MTU;
2775 } else 2770 } else
2776 pi->omtu = val; 2771 pi->imtu = val;
2777 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu); 2772 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2778 break; 2773 break;
2779 2774
2780 case L2CAP_CONF_FLUSH_TO: 2775 case L2CAP_CONF_FLUSH_TO:
@@ -3071,6 +3066,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
3071 return 0; 3066 return 0;
3072} 3067}
3073 3068
3069static inline void set_default_fcs(struct l2cap_pinfo *pi)
3070{
3071 /* FCS is enabled only in ERTM or streaming mode, if one or both
3072 * sides request it.
3073 */
3074 if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
3075 pi->fcs = L2CAP_FCS_NONE;
3076 else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV))
3077 pi->fcs = L2CAP_FCS_CRC16;
3078}
3079
3074static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) 3080static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
3075{ 3081{
3076 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; 3082 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
@@ -3088,14 +3094,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
3088 if (!sk) 3094 if (!sk)
3089 return -ENOENT; 3095 return -ENOENT;
3090 3096
3091 if (sk->sk_state != BT_CONFIG) { 3097 if (sk->sk_state == BT_DISCONN)
3092 struct l2cap_cmd_rej rej;
3093
3094 rej.reason = cpu_to_le16(0x0002);
3095 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3096 sizeof(rej), &rej);
3097 goto unlock; 3098 goto unlock;
3098 }
3099 3099
3100 /* Reject if config buffer is too small. */ 3100 /* Reject if config buffer is too small. */
3101 len = cmd_len - sizeof(*req); 3101 len = cmd_len - sizeof(*req);
@@ -3135,9 +3135,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
3135 goto unlock; 3135 goto unlock;
3136 3136
3137 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { 3137 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
3138 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || 3138 set_default_fcs(l2cap_pi(sk));
3139 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
3140 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3141 3139
3142 sk->sk_state = BT_CONNECTED; 3140 sk->sk_state = BT_CONNECTED;
3143 3141
@@ -3225,9 +3223,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
3225 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE; 3223 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3226 3224
3227 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) { 3225 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
3228 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || 3226 set_default_fcs(l2cap_pi(sk));
3229 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
3230 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3231 3227
3232 sk->sk_state = BT_CONNECTED; 3228 sk->sk_state = BT_CONNECTED;
3233 l2cap_pi(sk)->next_tx_seq = 0; 3229 l2cap_pi(sk)->next_tx_seq = 0;
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 44a623275951..194b3a04cfd3 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -82,11 +82,14 @@ static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
82static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) 82static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
83{ 83{
84 struct sock *sk = d->owner, *parent; 84 struct sock *sk = d->owner, *parent;
85 unsigned long flags;
86
85 if (!sk) 87 if (!sk)
86 return; 88 return;
87 89
88 BT_DBG("dlc %p state %ld err %d", d, d->state, err); 90 BT_DBG("dlc %p state %ld err %d", d, d->state, err);
89 91
92 local_irq_save(flags);
90 bh_lock_sock(sk); 93 bh_lock_sock(sk);
91 94
92 if (err) 95 if (err)
@@ -108,6 +111,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
108 } 111 }
109 112
110 bh_unlock_sock(sk); 113 bh_unlock_sock(sk);
114 local_irq_restore(flags);
111 115
112 if (parent && sock_flag(sk, SOCK_ZAPPED)) { 116 if (parent && sock_flag(sk, SOCK_ZAPPED)) {
113 /* We have to drop DLC lock here, otherwise 117 /* We have to drop DLC lock here, otherwise