Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(605)

Side by Side Diff: chromeos/compat-wireless/net/bluetooth/l2cap.c

Issue 5326002: Update compat-wireless to 2.6.36-5-spn (Closed) Base URL: http://git.chromium.org/git/kernel.git@master
Patch Set: Fixes for !ACK handling, missing local changes, log message fixes Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 BlueZ - Bluetooth protocol stack for Linux 2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated 3 Copyright (C) 2000-2001 Qualcomm Incorporated
4 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org> 4 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
5 Copyright (C) 2010 Google Inc. 5 Copyright (C) 2010 Google Inc.
6 6
7 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 7 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
8 8
9 This program is free software; you can redistribute it and/or modify 9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 2 as 10 it under the terms of the GNU General Public License version 2 as
(...skipping 1431 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 { 1442 {
1443 struct l2cap_pinfo *pi = l2cap_pi(sk); 1443 struct l2cap_pinfo *pi = l2cap_pi(sk);
1444 1444
1445 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len); 1445 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1446 1446
1447 hci_send_acl(pi->conn->hcon, skb, 0); 1447 hci_send_acl(pi->conn->hcon, skb, 0);
1448 } 1448 }
1449 1449
1450 static void l2cap_streaming_send(struct sock *sk) 1450 static void l2cap_streaming_send(struct sock *sk)
1451 { 1451 {
1452 » struct sk_buff *skb, *tx_skb; 1452 » struct sk_buff *skb;
1453 struct l2cap_pinfo *pi = l2cap_pi(sk); 1453 struct l2cap_pinfo *pi = l2cap_pi(sk);
1454 u16 control, fcs; 1454 u16 control, fcs;
1455 1455
1456 » while ((skb = sk->sk_send_head)) { 1456 » while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
1457 » » tx_skb = skb_clone(skb, GFP_ATOMIC); 1457 » » control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
1458
1459 » » control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1460 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; 1458 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1461 » » put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); 1459 » » put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
1462 1460
1463 if (pi->fcs == L2CAP_FCS_CRC16) { 1461 if (pi->fcs == L2CAP_FCS_CRC16) {
1464 » » » fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2); 1462 » » » fcs = crc16(0, (u8 *)skb->data, skb->len - 2);
1465 » » » put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2); 1463 » » » put_unaligned_le16(fcs, skb->data + skb->len - 2);
1466 } 1464 }
1467 1465
1468 » » l2cap_do_send(sk, tx_skb); 1466 » » l2cap_do_send(sk, skb);
1469 1467
1470 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; 1468 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1471
1472 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1473 sk->sk_send_head = NULL;
1474 else
1475 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1476
1477 skb = skb_dequeue(TX_QUEUE(sk));
1478 kfree_skb(skb);
1479 } 1469 }
1480 } 1470 }
1481 1471
1482 static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) 1472 static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
1483 { 1473 {
1484 struct l2cap_pinfo *pi = l2cap_pi(sk); 1474 struct l2cap_pinfo *pi = l2cap_pi(sk);
1485 struct sk_buff *skb, *tx_skb; 1475 struct sk_buff *skb, *tx_skb;
1486 u16 control, fcs; 1476 u16 control, fcs;
1487 1477
1488 skb = skb_peek(TX_QUEUE(sk)); 1478 skb = skb_peek(TX_QUEUE(sk));
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
1961 struct l2cap_options opts; 1951 struct l2cap_options opts;
1962 int len, err = 0; 1952 int len, err = 0;
1963 u32 opt; 1953 u32 opt;
1964 1954
1965 BT_DBG("sk %p", sk); 1955 BT_DBG("sk %p", sk);
1966 1956
1967 lock_sock(sk); 1957 lock_sock(sk);
1968 1958
1969 switch (optname) { 1959 switch (optname) {
1970 case L2CAP_OPTIONS: 1960 case L2CAP_OPTIONS:
1961 if (sk->sk_state == BT_CONNECTED) {
1962 err = -EINVAL;
1963 break;
1964 }
1965
1971 opts.imtu = l2cap_pi(sk)->imtu; 1966 opts.imtu = l2cap_pi(sk)->imtu;
1972 opts.omtu = l2cap_pi(sk)->omtu; 1967 opts.omtu = l2cap_pi(sk)->omtu;
1973 opts.flush_to = l2cap_pi(sk)->flush_to; 1968 opts.flush_to = l2cap_pi(sk)->flush_to;
1974 opts.mode = l2cap_pi(sk)->mode; 1969 opts.mode = l2cap_pi(sk)->mode;
1975 opts.fcs = l2cap_pi(sk)->fcs; 1970 opts.fcs = l2cap_pi(sk)->fcs;
1976 opts.max_tx = l2cap_pi(sk)->max_tx; 1971 opts.max_tx = l2cap_pi(sk)->max_tx;
1977 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win; 1972 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
1978 1973
1979 len = min_t(unsigned int, sizeof(opts), optlen); 1974 len = min_t(unsigned int, sizeof(opts), optlen);
1980 if (copy_from_user((char *) &opts, optval, len)) { 1975 if (copy_from_user((char *) &opts, optval, len)) {
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after
2776 2771
2777 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data); 2772 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2778 2773
2779 while (len >= L2CAP_CONF_OPT_SIZE) { 2774 while (len >= L2CAP_CONF_OPT_SIZE) {
2780 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); 2775 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2781 2776
2782 switch (type) { 2777 switch (type) {
2783 case L2CAP_CONF_MTU: 2778 case L2CAP_CONF_MTU:
2784 if (val < L2CAP_DEFAULT_MIN_MTU) { 2779 if (val < L2CAP_DEFAULT_MIN_MTU) {
2785 *result = L2CAP_CONF_UNACCEPT; 2780 *result = L2CAP_CONF_UNACCEPT;
2786 » » » » pi->omtu = L2CAP_DEFAULT_MIN_MTU; 2781 » » » » pi->imtu = L2CAP_DEFAULT_MIN_MTU;
2787 } else 2782 } else
2788 » » » » pi->omtu = val; 2783 » » » » pi->imtu = val;
2789 » » » l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu); 2784 » » » l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2790 break; 2785 break;
2791 2786
2792 case L2CAP_CONF_FLUSH_TO: 2787 case L2CAP_CONF_FLUSH_TO:
2793 pi->flush_to = val; 2788 pi->flush_to = val;
2794 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2789 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2795 2, pi->flush_to); 2790 2, pi->flush_to);
2796 break; 2791 break;
2797 2792
2798 case L2CAP_CONF_RFC: 2793 case L2CAP_CONF_RFC:
2799 if (olen == sizeof(rfc)) 2794 if (olen == sizeof(rfc))
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
3076 3071
3077 default: 3072 default:
3078 l2cap_chan_del(sk, ECONNREFUSED); 3073 l2cap_chan_del(sk, ECONNREFUSED);
3079 break; 3074 break;
3080 } 3075 }
3081 3076
3082 bh_unlock_sock(sk); 3077 bh_unlock_sock(sk);
3083 return 0; 3078 return 0;
3084 } 3079 }
3085 3080
3081 static inline void set_default_fcs(struct l2cap_pinfo *pi)
3082 {
3083 /* FCS is enabled only in ERTM or streaming mode, if one or both
3084 * sides request it.
3085 */
3086 if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
3087 pi->fcs = L2CAP_FCS_NONE;
3088 else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV))
3089 pi->fcs = L2CAP_FCS_CRC16;
3090 }
3091
3086 static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) 3092 static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
3087 { 3093 {
3088 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; 3094 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3089 u16 dcid, flags; 3095 u16 dcid, flags;
3090 u8 rsp[64]; 3096 u8 rsp[64];
3091 struct sock *sk; 3097 struct sock *sk;
3092 int len; 3098 int len;
3093 3099
3094 dcid = __le16_to_cpu(req->dcid); 3100 dcid = __le16_to_cpu(req->dcid);
3095 flags = __le16_to_cpu(req->flags); 3101 flags = __le16_to_cpu(req->flags);
3096 3102
3097 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags); 3103 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3098 3104
3099 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid); 3105 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3100 if (!sk) 3106 if (!sk)
3101 return -ENOENT; 3107 return -ENOENT;
3102 3108
3103 » if (sk->sk_state != BT_CONFIG) { 3109 » if (sk->sk_state == BT_DISCONN)
3104 » » struct l2cap_cmd_rej rej;
3105
3106 » » rej.reason = cpu_to_le16(0x0002);
3107 » » l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3108 » » » » sizeof(rej), &rej);
3109 goto unlock; 3110 goto unlock;
3110 }
3111 3111
3112 /* Reject if config buffer is too small. */ 3112 /* Reject if config buffer is too small. */
3113 len = cmd_len - sizeof(*req); 3113 len = cmd_len - sizeof(*req);
3114 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) { 3114 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
3115 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, 3115 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
3116 l2cap_build_conf_rsp(sk, rsp, 3116 l2cap_build_conf_rsp(sk, rsp,
3117 L2CAP_CONF_REJECT, flags), rsp); 3117 L2CAP_CONF_REJECT, flags), rsp);
3118 goto unlock; 3118 goto unlock;
3119 } 3119 }
3120 3120
(...skipping 19 matching lines...) Expand all
3140 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp); 3140 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
3141 l2cap_pi(sk)->num_conf_rsp++; 3141 l2cap_pi(sk)->num_conf_rsp++;
3142 3142
3143 /* Reset config buffer. */ 3143 /* Reset config buffer. */
3144 l2cap_pi(sk)->conf_len = 0; 3144 l2cap_pi(sk)->conf_len = 0;
3145 3145
3146 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE)) 3146 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
3147 goto unlock; 3147 goto unlock;
3148 3148
3149 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { 3149 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
3150 » » if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || 3150 » » set_default_fcs(l2cap_pi(sk));
3151 » » l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
3152 » » » l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3153 3151
3154 sk->sk_state = BT_CONNECTED; 3152 sk->sk_state = BT_CONNECTED;
3155 3153
3156 l2cap_pi(sk)->next_tx_seq = 0; 3154 l2cap_pi(sk)->next_tx_seq = 0;
3157 l2cap_pi(sk)->expected_tx_seq = 0; 3155 l2cap_pi(sk)->expected_tx_seq = 0;
3158 __skb_queue_head_init(TX_QUEUE(sk)); 3156 __skb_queue_head_init(TX_QUEUE(sk));
3159 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) 3157 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3160 l2cap_ertm_init(sk); 3158 l2cap_ertm_init(sk);
3161 3159
3162 l2cap_chan_ready(sk); 3160 l2cap_chan_ready(sk);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3230 l2cap_send_disconn_req(conn, sk, ECONNRESET); 3228 l2cap_send_disconn_req(conn, sk, ECONNRESET);
3231 goto done; 3229 goto done;
3232 } 3230 }
3233 3231
3234 if (flags & 0x01) 3232 if (flags & 0x01)
3235 goto done; 3233 goto done;
3236 3234
3237 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE; 3235 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3238 3236
3239 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) { 3237 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
3240 » » if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || 3238 » » set_default_fcs(l2cap_pi(sk));
3241 » » l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
3242 » » » l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3243 3239
3244 sk->sk_state = BT_CONNECTED; 3240 sk->sk_state = BT_CONNECTED;
3245 l2cap_pi(sk)->next_tx_seq = 0; 3241 l2cap_pi(sk)->next_tx_seq = 0;
3246 l2cap_pi(sk)->expected_tx_seq = 0; 3242 l2cap_pi(sk)->expected_tx_seq = 0;
3247 __skb_queue_head_init(TX_QUEUE(sk)); 3243 __skb_queue_head_init(TX_QUEUE(sk));
3248 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) 3244 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3249 l2cap_ertm_init(sk); 3245 l2cap_ertm_init(sk);
3250 3246
3251 l2cap_chan_ready(sk); 3247 l2cap_chan_ready(sk);
3252 } 3248 }
(...skipping 1631 matching lines...) Expand 10 before | Expand all | Expand 10 after
4884 module_exit(l2cap_exit); 4880 module_exit(l2cap_exit);
4885 4881
4886 module_param(disable_ertm, bool, 0644); 4882 module_param(disable_ertm, bool, 0644);
4887 MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode"); 4883 MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");
4888 4884
4889 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); 4885 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
4890 MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION); 4886 MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4891 MODULE_VERSION(VERSION); 4887 MODULE_VERSION(VERSION);
4892 MODULE_LICENSE("GPL"); 4888 MODULE_LICENSE("GPL");
4893 MODULE_ALIAS("bt-proto-0"); 4889 MODULE_ALIAS("bt-proto-0");
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698