diff options
author | David S. Miller <davem@davemloft.net> | 2009-12-03 16:51:02 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-03 16:51:02 -0500 |
commit | a7fca0ccecd3f5a111e08df8439f0b884099ad59 (patch) | |
tree | 44b360a8f367e2414daf3ad92622ab2544ac0fbd | |
parent | 424eff975192553a9ea8bfd51bf65039ffb356ef (diff) | |
parent | 2861453b1b5e022fd5e1294b8fbf39254440b661 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-next-2.6
-rw-r--r-- | drivers/bluetooth/btmrvl_debugfs.c | 1 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_drv.h | 1 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_main.c | 55 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_sdio.c | 4 | ||||
-rw-r--r-- | drivers/bluetooth/hci_vhci.c | 20 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 39 | ||||
-rw-r--r-- | include/net/bluetooth/l2cap.h | 2 | ||||
-rw-r--r-- | net/bluetooth/bnep/core.c | 5 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 39 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 6 | ||||
-rw-r--r-- | net/bluetooth/hci_sock.c | 11 | ||||
-rw-r--r-- | net/bluetooth/hidp/core.c | 9 | ||||
-rw-r--r-- | net/bluetooth/l2cap.c | 110 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 6 |
14 files changed, 192 insertions, 116 deletions
diff --git a/drivers/bluetooth/btmrvl_debugfs.c b/drivers/bluetooth/btmrvl_debugfs.c index 4617bd12f63b..d43b5cb864ef 100644 --- a/drivers/bluetooth/btmrvl_debugfs.c +++ b/drivers/bluetooth/btmrvl_debugfs.c | |||
@@ -29,7 +29,6 @@ struct btmrvl_debugfs_data { | |||
29 | struct dentry *root_dir, *config_dir, *status_dir; | 29 | struct dentry *root_dir, *config_dir, *status_dir; |
30 | 30 | ||
31 | /* config */ | 31 | /* config */ |
32 | struct dentry *drvdbg; | ||
33 | struct dentry *psmode; | 32 | struct dentry *psmode; |
34 | struct dentry *pscmd; | 33 | struct dentry *pscmd; |
35 | struct dentry *hsmode; | 34 | struct dentry *hsmode; |
diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h index 411c7a77082d..523d197b9824 100644 --- a/drivers/bluetooth/btmrvl_drv.h +++ b/drivers/bluetooth/btmrvl_drv.h | |||
@@ -131,6 +131,7 @@ void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); | |||
131 | int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb); | 131 | int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb); |
132 | 132 | ||
133 | int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd); | 133 | int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd); |
134 | int btmrvl_enable_ps(struct btmrvl_private *priv); | ||
134 | int btmrvl_prepare_command(struct btmrvl_private *priv); | 135 | int btmrvl_prepare_command(struct btmrvl_private *priv); |
135 | 136 | ||
136 | #ifdef CONFIG_DEBUG_FS | 137 | #ifdef CONFIG_DEBUG_FS |
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index e605563b4eaa..f97771ce432c 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c | |||
@@ -189,6 +189,38 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd) | |||
189 | } | 189 | } |
190 | EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd); | 190 | EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd); |
191 | 191 | ||
192 | int btmrvl_enable_ps(struct btmrvl_private *priv) | ||
193 | { | ||
194 | struct sk_buff *skb; | ||
195 | struct btmrvl_cmd *cmd; | ||
196 | |||
197 | skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC); | ||
198 | if (skb == NULL) { | ||
199 | BT_ERR("No free skb"); | ||
200 | return -ENOMEM; | ||
201 | } | ||
202 | |||
203 | cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd)); | ||
204 | cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, | ||
205 | BT_CMD_AUTO_SLEEP_MODE)); | ||
206 | cmd->length = 1; | ||
207 | |||
208 | if (priv->btmrvl_dev.psmode) | ||
209 | cmd->data[0] = BT_PS_ENABLE; | ||
210 | else | ||
211 | cmd->data[0] = BT_PS_DISABLE; | ||
212 | |||
213 | bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; | ||
214 | |||
215 | skb->dev = (void *) priv->btmrvl_dev.hcidev; | ||
216 | skb_queue_head(&priv->adapter->tx_queue, skb); | ||
217 | |||
218 | BT_DBG("Queue PSMODE Command:%d", cmd->data[0]); | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | EXPORT_SYMBOL_GPL(btmrvl_enable_ps); | ||
223 | |||
192 | static int btmrvl_enable_hs(struct btmrvl_private *priv) | 224 | static int btmrvl_enable_hs(struct btmrvl_private *priv) |
193 | { | 225 | { |
194 | struct sk_buff *skb; | 226 | struct sk_buff *skb; |
@@ -258,28 +290,7 @@ int btmrvl_prepare_command(struct btmrvl_private *priv) | |||
258 | 290 | ||
259 | if (priv->btmrvl_dev.pscmd) { | 291 | if (priv->btmrvl_dev.pscmd) { |
260 | priv->btmrvl_dev.pscmd = 0; | 292 | priv->btmrvl_dev.pscmd = 0; |
261 | 293 | btmrvl_enable_ps(priv); | |
262 | skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC); | ||
263 | if (skb == NULL) { | ||
264 | BT_ERR("No free skb"); | ||
265 | return -ENOMEM; | ||
266 | } | ||
267 | |||
268 | cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd)); | ||
269 | cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_AUTO_SLEEP_MODE)); | ||
270 | cmd->length = 1; | ||
271 | |||
272 | if (priv->btmrvl_dev.psmode) | ||
273 | cmd->data[0] = BT_PS_ENABLE; | ||
274 | else | ||
275 | cmd->data[0] = BT_PS_DISABLE; | ||
276 | |||
277 | bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; | ||
278 | |||
279 | skb->dev = (void *) priv->btmrvl_dev.hcidev; | ||
280 | skb_queue_head(&priv->adapter->tx_queue, skb); | ||
281 | |||
282 | BT_DBG("Queue PSMODE Command:%d", cmd->data[0]); | ||
283 | } | 294 | } |
284 | 295 | ||
285 | if (priv->btmrvl_dev.hscmd) { | 296 | if (priv->btmrvl_dev.hscmd) { |
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 5b33b85790f2..1e6eb1aeba2b 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c | |||
@@ -930,6 +930,8 @@ static int btmrvl_sdio_probe(struct sdio_func *func, | |||
930 | priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw; | 930 | priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw; |
931 | 931 | ||
932 | btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ); | 932 | btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ); |
933 | priv->btmrvl_dev.psmode = 1; | ||
934 | btmrvl_enable_ps(priv); | ||
933 | 935 | ||
934 | return 0; | 936 | return 0; |
935 | 937 | ||
@@ -1001,3 +1003,5 @@ MODULE_AUTHOR("Marvell International Ltd."); | |||
1001 | MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION); | 1003 | MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION); |
1002 | MODULE_VERSION(VERSION); | 1004 | MODULE_VERSION(VERSION); |
1003 | MODULE_LICENSE("GPL v2"); | 1005 | MODULE_LICENSE("GPL v2"); |
1006 | MODULE_FIRMWARE("sd8688_helper.bin"); | ||
1007 | MODULE_FIRMWARE("sd8688.bin"); | ||
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index d5cde6d86f89..7595274103fd 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c | |||
@@ -41,8 +41,6 @@ | |||
41 | 41 | ||
42 | #define VERSION "1.3" | 42 | #define VERSION "1.3" |
43 | 43 | ||
44 | static int minor = MISC_DYNAMIC_MINOR; | ||
45 | |||
46 | struct vhci_data { | 44 | struct vhci_data { |
47 | struct hci_dev *hdev; | 45 | struct hci_dev *hdev; |
48 | 46 | ||
@@ -218,12 +216,6 @@ static unsigned int vhci_poll(struct file *file, poll_table *wait) | |||
218 | return POLLOUT | POLLWRNORM; | 216 | return POLLOUT | POLLWRNORM; |
219 | } | 217 | } |
220 | 218 | ||
221 | static int vhci_ioctl(struct inode *inode, struct file *file, | ||
222 | unsigned int cmd, unsigned long arg) | ||
223 | { | ||
224 | return -EINVAL; | ||
225 | } | ||
226 | |||
227 | static int vhci_open(struct inode *inode, struct file *file) | 219 | static int vhci_open(struct inode *inode, struct file *file) |
228 | { | 220 | { |
229 | struct vhci_data *data; | 221 | struct vhci_data *data; |
@@ -284,10 +276,10 @@ static int vhci_release(struct inode *inode, struct file *file) | |||
284 | } | 276 | } |
285 | 277 | ||
286 | static const struct file_operations vhci_fops = { | 278 | static const struct file_operations vhci_fops = { |
279 | .owner = THIS_MODULE, | ||
287 | .read = vhci_read, | 280 | .read = vhci_read, |
288 | .write = vhci_write, | 281 | .write = vhci_write, |
289 | .poll = vhci_poll, | 282 | .poll = vhci_poll, |
290 | .ioctl = vhci_ioctl, | ||
291 | .open = vhci_open, | 283 | .open = vhci_open, |
292 | .release = vhci_release, | 284 | .release = vhci_release, |
293 | }; | 285 | }; |
@@ -302,18 +294,12 @@ static int __init vhci_init(void) | |||
302 | { | 294 | { |
303 | BT_INFO("Virtual HCI driver ver %s", VERSION); | 295 | BT_INFO("Virtual HCI driver ver %s", VERSION); |
304 | 296 | ||
305 | if (misc_register(&vhci_miscdev) < 0) { | 297 | return misc_register(&vhci_miscdev); |
306 | BT_ERR("Can't register misc device with minor %d", minor); | ||
307 | return -EIO; | ||
308 | } | ||
309 | |||
310 | return 0; | ||
311 | } | 298 | } |
312 | 299 | ||
313 | static void __exit vhci_exit(void) | 300 | static void __exit vhci_exit(void) |
314 | { | 301 | { |
315 | if (misc_deregister(&vhci_miscdev) < 0) | 302 | misc_deregister(&vhci_miscdev); |
316 | BT_ERR("Can't unregister misc device with minor %d", minor); | ||
317 | } | 303 | } |
318 | 304 | ||
319 | module_init(vhci_init); | 305 | module_init(vhci_init); |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 7b640aeddb64..7b86094a894b 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -367,22 +367,6 @@ static inline void hci_conn_put(struct hci_conn *conn) | |||
367 | } | 367 | } |
368 | } | 368 | } |
369 | 369 | ||
370 | /* ----- HCI tasks ----- */ | ||
371 | static inline void hci_sched_cmd(struct hci_dev *hdev) | ||
372 | { | ||
373 | tasklet_schedule(&hdev->cmd_task); | ||
374 | } | ||
375 | |||
376 | static inline void hci_sched_rx(struct hci_dev *hdev) | ||
377 | { | ||
378 | tasklet_schedule(&hdev->rx_task); | ||
379 | } | ||
380 | |||
381 | static inline void hci_sched_tx(struct hci_dev *hdev) | ||
382 | { | ||
383 | tasklet_schedule(&hdev->tx_task); | ||
384 | } | ||
385 | |||
386 | /* ----- HCI Devices ----- */ | 370 | /* ----- HCI Devices ----- */ |
387 | static inline void __hci_dev_put(struct hci_dev *d) | 371 | static inline void __hci_dev_put(struct hci_dev *d) |
388 | { | 372 | { |
@@ -437,28 +421,7 @@ int hci_inquiry(void __user *arg); | |||
437 | 421 | ||
438 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); | 422 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); |
439 | 423 | ||
440 | /* Receive frame from HCI drivers */ | 424 | int hci_recv_frame(struct sk_buff *skb); |
441 | static inline int hci_recv_frame(struct sk_buff *skb) | ||
442 | { | ||
443 | struct hci_dev *hdev = (struct hci_dev *) skb->dev; | ||
444 | if (!hdev || (!test_bit(HCI_UP, &hdev->flags) | ||
445 | && !test_bit(HCI_INIT, &hdev->flags))) { | ||
446 | kfree_skb(skb); | ||
447 | return -ENXIO; | ||
448 | } | ||
449 | |||
450 | /* Incomming skb */ | ||
451 | bt_cb(skb)->incoming = 1; | ||
452 | |||
453 | /* Time stamp */ | ||
454 | __net_timestamp(skb); | ||
455 | |||
456 | /* Queue frame for rx task */ | ||
457 | skb_queue_tail(&hdev->rx_q, skb); | ||
458 | hci_sched_rx(hdev); | ||
459 | return 0; | ||
460 | } | ||
461 | |||
462 | int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); | 425 | int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); |
463 | 426 | ||
464 | int hci_register_sysfs(struct hci_dev *hdev); | 427 | int hci_register_sysfs(struct hci_dev *hdev); |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 9516f4b4a3c2..17a689f27a6a 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -324,7 +324,6 @@ struct l2cap_pinfo { | |||
324 | 324 | ||
325 | __u8 next_tx_seq; | 325 | __u8 next_tx_seq; |
326 | __u8 expected_ack_seq; | 326 | __u8 expected_ack_seq; |
327 | __u8 req_seq; | ||
328 | __u8 expected_tx_seq; | 327 | __u8 expected_tx_seq; |
329 | __u8 buffer_seq; | 328 | __u8 buffer_seq; |
330 | __u8 buffer_seq_srej; | 329 | __u8 buffer_seq_srej; |
@@ -375,6 +374,7 @@ struct l2cap_pinfo { | |||
375 | #define L2CAP_CONN_SEND_PBIT 0x10 | 374 | #define L2CAP_CONN_SEND_PBIT 0x10 |
376 | #define L2CAP_CONN_REMOTE_BUSY 0x20 | 375 | #define L2CAP_CONN_REMOTE_BUSY 0x20 |
377 | #define L2CAP_CONN_LOCAL_BUSY 0x40 | 376 | #define L2CAP_CONN_LOCAL_BUSY 0x40 |
377 | #define L2CAP_CONN_REJ_ACT 0x80 | ||
378 | 378 | ||
379 | #define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \ | 379 | #define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \ |
380 | jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO)); | 380 | jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO)); |
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index cafe9f54d841..29b1b220d6cf 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
@@ -230,7 +230,6 @@ static int bnep_rx_control(struct bnep_session *s, void *data, int len) | |||
230 | 230 | ||
231 | switch (cmd) { | 231 | switch (cmd) { |
232 | case BNEP_CMD_NOT_UNDERSTOOD: | 232 | case BNEP_CMD_NOT_UNDERSTOOD: |
233 | case BNEP_SETUP_CONN_REQ: | ||
234 | case BNEP_SETUP_CONN_RSP: | 233 | case BNEP_SETUP_CONN_RSP: |
235 | case BNEP_FILTER_NET_TYPE_RSP: | 234 | case BNEP_FILTER_NET_TYPE_RSP: |
236 | case BNEP_FILTER_MULTI_ADDR_RSP: | 235 | case BNEP_FILTER_MULTI_ADDR_RSP: |
@@ -245,6 +244,10 @@ static int bnep_rx_control(struct bnep_session *s, void *data, int len) | |||
245 | err = bnep_ctrl_set_mcfilter(s, data, len); | 244 | err = bnep_ctrl_set_mcfilter(s, data, len); |
246 | break; | 245 | break; |
247 | 246 | ||
247 | case BNEP_SETUP_CONN_REQ: | ||
248 | err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP, BNEP_CONN_NOT_ALLOWED); | ||
249 | break; | ||
250 | |||
248 | default: { | 251 | default: { |
249 | u8 pkt[3]; | 252 | u8 pkt[3]; |
250 | pkt[0] = BNEP_CONTROL; | 253 | pkt[0] = BNEP_CONTROL; |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index e1da8f68759c..94ba34982021 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -193,8 +193,9 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) | |||
193 | while ((skb = skb_dequeue(&hdev->driver_init))) { | 193 | while ((skb = skb_dequeue(&hdev->driver_init))) { |
194 | bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; | 194 | bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; |
195 | skb->dev = (void *) hdev; | 195 | skb->dev = (void *) hdev; |
196 | |||
196 | skb_queue_tail(&hdev->cmd_q, skb); | 197 | skb_queue_tail(&hdev->cmd_q, skb); |
197 | hci_sched_cmd(hdev); | 198 | tasklet_schedule(&hdev->cmd_task); |
198 | } | 199 | } |
199 | skb_queue_purge(&hdev->driver_init); | 200 | skb_queue_purge(&hdev->driver_init); |
200 | 201 | ||
@@ -987,6 +988,30 @@ int hci_resume_dev(struct hci_dev *hdev) | |||
987 | } | 988 | } |
988 | EXPORT_SYMBOL(hci_resume_dev); | 989 | EXPORT_SYMBOL(hci_resume_dev); |
989 | 990 | ||
991 | /* Receive frame from HCI drivers */ | ||
992 | int hci_recv_frame(struct sk_buff *skb) | ||
993 | { | ||
994 | struct hci_dev *hdev = (struct hci_dev *) skb->dev; | ||
995 | if (!hdev || (!test_bit(HCI_UP, &hdev->flags) | ||
996 | && !test_bit(HCI_INIT, &hdev->flags))) { | ||
997 | kfree_skb(skb); | ||
998 | return -ENXIO; | ||
999 | } | ||
1000 | |||
1001 | /* Incomming skb */ | ||
1002 | bt_cb(skb)->incoming = 1; | ||
1003 | |||
1004 | /* Time stamp */ | ||
1005 | __net_timestamp(skb); | ||
1006 | |||
1007 | /* Queue frame for rx task */ | ||
1008 | skb_queue_tail(&hdev->rx_q, skb); | ||
1009 | tasklet_schedule(&hdev->rx_task); | ||
1010 | |||
1011 | return 0; | ||
1012 | } | ||
1013 | EXPORT_SYMBOL(hci_recv_frame); | ||
1014 | |||
990 | /* Receive packet type fragment */ | 1015 | /* Receive packet type fragment */ |
991 | #define __reassembly(hdev, type) ((hdev)->reassembly[(type) - 2]) | 1016 | #define __reassembly(hdev, type) ((hdev)->reassembly[(type) - 2]) |
992 | 1017 | ||
@@ -1193,8 +1218,9 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) | |||
1193 | 1218 | ||
1194 | bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; | 1219 | bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; |
1195 | skb->dev = (void *) hdev; | 1220 | skb->dev = (void *) hdev; |
1221 | |||
1196 | skb_queue_tail(&hdev->cmd_q, skb); | 1222 | skb_queue_tail(&hdev->cmd_q, skb); |
1197 | hci_sched_cmd(hdev); | 1223 | tasklet_schedule(&hdev->cmd_task); |
1198 | 1224 | ||
1199 | return 0; | 1225 | return 0; |
1200 | } | 1226 | } |
@@ -1271,7 +1297,8 @@ int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags) | |||
1271 | spin_unlock_bh(&conn->data_q.lock); | 1297 | spin_unlock_bh(&conn->data_q.lock); |
1272 | } | 1298 | } |
1273 | 1299 | ||
1274 | hci_sched_tx(hdev); | 1300 | tasklet_schedule(&hdev->tx_task); |
1301 | |||
1275 | return 0; | 1302 | return 0; |
1276 | } | 1303 | } |
1277 | EXPORT_SYMBOL(hci_send_acl); | 1304 | EXPORT_SYMBOL(hci_send_acl); |
@@ -1298,8 +1325,10 @@ int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) | |||
1298 | 1325 | ||
1299 | skb->dev = (void *) hdev; | 1326 | skb->dev = (void *) hdev; |
1300 | bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; | 1327 | bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; |
1328 | |||
1301 | skb_queue_tail(&conn->data_q, skb); | 1329 | skb_queue_tail(&conn->data_q, skb); |
1302 | hci_sched_tx(hdev); | 1330 | tasklet_schedule(&hdev->tx_task); |
1331 | |||
1303 | return 0; | 1332 | return 0; |
1304 | } | 1333 | } |
1305 | EXPORT_SYMBOL(hci_send_sco); | 1334 | EXPORT_SYMBOL(hci_send_sco); |
@@ -1612,7 +1641,7 @@ static void hci_cmd_task(unsigned long arg) | |||
1612 | hdev->cmd_last_tx = jiffies; | 1641 | hdev->cmd_last_tx = jiffies; |
1613 | } else { | 1642 | } else { |
1614 | skb_queue_head(&hdev->cmd_q, skb); | 1643 | skb_queue_head(&hdev->cmd_q, skb); |
1615 | hci_sched_cmd(hdev); | 1644 | tasklet_schedule(&hdev->cmd_task); |
1616 | } | 1645 | } |
1617 | } | 1646 | } |
1618 | } | 1647 | } |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index e99fe385fba2..28517bad796c 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -1320,7 +1320,7 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1320 | if (ev->ncmd) { | 1320 | if (ev->ncmd) { |
1321 | atomic_set(&hdev->cmd_cnt, 1); | 1321 | atomic_set(&hdev->cmd_cnt, 1); |
1322 | if (!skb_queue_empty(&hdev->cmd_q)) | 1322 | if (!skb_queue_empty(&hdev->cmd_q)) |
1323 | hci_sched_cmd(hdev); | 1323 | tasklet_schedule(&hdev->cmd_task); |
1324 | } | 1324 | } |
1325 | } | 1325 | } |
1326 | 1326 | ||
@@ -1386,7 +1386,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1386 | if (ev->ncmd) { | 1386 | if (ev->ncmd) { |
1387 | atomic_set(&hdev->cmd_cnt, 1); | 1387 | atomic_set(&hdev->cmd_cnt, 1); |
1388 | if (!skb_queue_empty(&hdev->cmd_q)) | 1388 | if (!skb_queue_empty(&hdev->cmd_q)) |
1389 | hci_sched_cmd(hdev); | 1389 | tasklet_schedule(&hdev->cmd_task); |
1390 | } | 1390 | } |
1391 | } | 1391 | } |
1392 | 1392 | ||
@@ -1454,7 +1454,7 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1454 | } | 1454 | } |
1455 | } | 1455 | } |
1456 | 1456 | ||
1457 | hci_sched_tx(hdev); | 1457 | tasklet_schedule(&hdev->tx_task); |
1458 | 1458 | ||
1459 | tasklet_enable(&hdev->tx_task); | 1459 | tasklet_enable(&hdev->tx_task); |
1460 | } | 1460 | } |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 1ca5c7ca9bd4..688cfebfbee0 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -414,6 +414,11 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
414 | goto done; | 414 | goto done; |
415 | } | 415 | } |
416 | 416 | ||
417 | if (!test_bit(HCI_UP, &hdev->flags)) { | ||
418 | err = -ENETDOWN; | ||
419 | goto done; | ||
420 | } | ||
421 | |||
417 | if (!(skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err))) | 422 | if (!(skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err))) |
418 | goto done; | 423 | goto done; |
419 | 424 | ||
@@ -440,10 +445,10 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
440 | 445 | ||
441 | if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) { | 446 | if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) { |
442 | skb_queue_tail(&hdev->raw_q, skb); | 447 | skb_queue_tail(&hdev->raw_q, skb); |
443 | hci_sched_tx(hdev); | 448 | tasklet_schedule(&hdev->tx_task); |
444 | } else { | 449 | } else { |
445 | skb_queue_tail(&hdev->cmd_q, skb); | 450 | skb_queue_tail(&hdev->cmd_q, skb); |
446 | hci_sched_cmd(hdev); | 451 | tasklet_schedule(&hdev->cmd_task); |
447 | } | 452 | } |
448 | } else { | 453 | } else { |
449 | if (!capable(CAP_NET_RAW)) { | 454 | if (!capable(CAP_NET_RAW)) { |
@@ -452,7 +457,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
452 | } | 457 | } |
453 | 458 | ||
454 | skb_queue_tail(&hdev->raw_q, skb); | 459 | skb_queue_tail(&hdev->raw_q, skb); |
455 | hci_sched_tx(hdev); | 460 | tasklet_schedule(&hdev->tx_task); |
456 | } | 461 | } |
457 | 462 | ||
458 | err = len; | 463 | err = len; |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 49d8495d69be..569750010fd3 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -280,6 +280,13 @@ static int hidp_send_report(struct hidp_session *session, struct hid_report *rep | |||
280 | return hidp_queue_report(session, buf, rsize); | 280 | return hidp_queue_report(session, buf, rsize); |
281 | } | 281 | } |
282 | 282 | ||
283 | static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count) | ||
284 | { | ||
285 | if (hidp_queue_report(hid->driver_data, data, count)) | ||
286 | return -ENOMEM; | ||
287 | return count; | ||
288 | } | ||
289 | |||
283 | static void hidp_idle_timeout(unsigned long arg) | 290 | static void hidp_idle_timeout(unsigned long arg) |
284 | { | 291 | { |
285 | struct hidp_session *session = (struct hidp_session *) arg; | 292 | struct hidp_session *session = (struct hidp_session *) arg; |
@@ -785,6 +792,8 @@ static int hidp_setup_hid(struct hidp_session *session, | |||
785 | hid->dev.parent = hidp_get_device(session); | 792 | hid->dev.parent = hidp_get_device(session); |
786 | hid->ll_driver = &hidp_hid_driver; | 793 | hid->ll_driver = &hidp_hid_driver; |
787 | 794 | ||
795 | hid->hid_output_raw_report = hidp_output_raw_report; | ||
796 | |||
788 | err = hid_add_device(hid); | 797 | err = hid_add_device(hid); |
789 | if (err < 0) | 798 | if (err < 0) |
790 | goto failed; | 799 | goto failed; |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 54992f782301..5129b88c8e5b 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #define VERSION "2.14" | 54 | #define VERSION "2.14" |
55 | 55 | ||
56 | static int enable_ertm = 0; | 56 | static int enable_ertm = 0; |
57 | static int max_transmit = L2CAP_DEFAULT_MAX_TX; | ||
57 | 58 | ||
58 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; | 59 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; |
59 | static u8 l2cap_fixed_chan[8] = { 0x02, }; | 60 | static u8 l2cap_fixed_chan[8] = { 0x02, }; |
@@ -373,6 +374,8 @@ static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control) | |||
373 | else | 374 | else |
374 | control |= L2CAP_SUPER_RCV_READY; | 375 | control |= L2CAP_SUPER_RCV_READY; |
375 | 376 | ||
377 | control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | ||
378 | |||
376 | return l2cap_send_sframe(pi, control); | 379 | return l2cap_send_sframe(pi, control); |
377 | } | 380 | } |
378 | 381 | ||
@@ -1333,7 +1336,7 @@ static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq) | |||
1333 | tx_skb = skb_clone(skb, GFP_ATOMIC); | 1336 | tx_skb = skb_clone(skb, GFP_ATOMIC); |
1334 | bt_cb(skb)->retries++; | 1337 | bt_cb(skb)->retries++; |
1335 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1338 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); |
1336 | control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT) | 1339 | control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) |
1337 | | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); | 1340 | | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); |
1338 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1341 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); |
1339 | 1342 | ||
@@ -1375,7 +1378,7 @@ static int l2cap_ertm_send(struct sock *sk) | |||
1375 | bt_cb(skb)->retries++; | 1378 | bt_cb(skb)->retries++; |
1376 | 1379 | ||
1377 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1380 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); |
1378 | control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT) | 1381 | control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) |
1379 | | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); | 1382 | | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); |
1380 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1383 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); |
1381 | 1384 | ||
@@ -2173,6 +2176,21 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) | |||
2173 | *ptr += L2CAP_CONF_OPT_SIZE + len; | 2176 | *ptr += L2CAP_CONF_OPT_SIZE + len; |
2174 | } | 2177 | } |
2175 | 2178 | ||
2179 | static inline void l2cap_ertm_init(struct sock *sk) | ||
2180 | { | ||
2181 | l2cap_pi(sk)->expected_ack_seq = 0; | ||
2182 | l2cap_pi(sk)->unacked_frames = 0; | ||
2183 | l2cap_pi(sk)->buffer_seq = 0; | ||
2184 | l2cap_pi(sk)->num_to_ack = 0; | ||
2185 | |||
2186 | setup_timer(&l2cap_pi(sk)->retrans_timer, | ||
2187 | l2cap_retrans_timeout, (unsigned long) sk); | ||
2188 | setup_timer(&l2cap_pi(sk)->monitor_timer, | ||
2189 | l2cap_monitor_timeout, (unsigned long) sk); | ||
2190 | |||
2191 | __skb_queue_head_init(SREJ_QUEUE(sk)); | ||
2192 | } | ||
2193 | |||
2176 | static int l2cap_mode_supported(__u8 mode, __u32 feat_mask) | 2194 | static int l2cap_mode_supported(__u8 mode, __u32 feat_mask) |
2177 | { | 2195 | { |
2178 | u32 local_feat_mask = l2cap_feat_mask; | 2196 | u32 local_feat_mask = l2cap_feat_mask; |
@@ -2236,7 +2254,7 @@ done: | |||
2236 | case L2CAP_MODE_ERTM: | 2254 | case L2CAP_MODE_ERTM: |
2237 | rfc.mode = L2CAP_MODE_ERTM; | 2255 | rfc.mode = L2CAP_MODE_ERTM; |
2238 | rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW; | 2256 | rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW; |
2239 | rfc.max_transmit = L2CAP_DEFAULT_MAX_TX; | 2257 | rfc.max_transmit = max_transmit; |
2240 | rfc.retrans_timeout = 0; | 2258 | rfc.retrans_timeout = 0; |
2241 | rfc.monitor_timeout = 0; | 2259 | rfc.monitor_timeout = 0; |
2242 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); | 2260 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); |
@@ -2761,17 +2779,13 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2761 | l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; | 2779 | l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; |
2762 | 2780 | ||
2763 | sk->sk_state = BT_CONNECTED; | 2781 | sk->sk_state = BT_CONNECTED; |
2764 | l2cap_pi(sk)->next_tx_seq = 0; | ||
2765 | l2cap_pi(sk)->expected_ack_seq = 0; | ||
2766 | l2cap_pi(sk)->unacked_frames = 0; | ||
2767 | |||
2768 | setup_timer(&l2cap_pi(sk)->retrans_timer, | ||
2769 | l2cap_retrans_timeout, (unsigned long) sk); | ||
2770 | setup_timer(&l2cap_pi(sk)->monitor_timer, | ||
2771 | l2cap_monitor_timeout, (unsigned long) sk); | ||
2772 | 2782 | ||
2783 | l2cap_pi(sk)->next_tx_seq = 0; | ||
2784 | l2cap_pi(sk)->expected_tx_seq = 0; | ||
2773 | __skb_queue_head_init(TX_QUEUE(sk)); | 2785 | __skb_queue_head_init(TX_QUEUE(sk)); |
2774 | __skb_queue_head_init(SREJ_QUEUE(sk)); | 2786 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) |
2787 | l2cap_ertm_init(sk); | ||
2788 | |||
2775 | l2cap_chan_ready(sk); | 2789 | l2cap_chan_ready(sk); |
2776 | goto unlock; | 2790 | goto unlock; |
2777 | } | 2791 | } |
@@ -2850,11 +2864,12 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2850 | l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; | 2864 | l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; |
2851 | 2865 | ||
2852 | sk->sk_state = BT_CONNECTED; | 2866 | sk->sk_state = BT_CONNECTED; |
2867 | l2cap_pi(sk)->next_tx_seq = 0; | ||
2853 | l2cap_pi(sk)->expected_tx_seq = 0; | 2868 | l2cap_pi(sk)->expected_tx_seq = 0; |
2854 | l2cap_pi(sk)->buffer_seq = 0; | ||
2855 | l2cap_pi(sk)->num_to_ack = 0; | ||
2856 | __skb_queue_head_init(TX_QUEUE(sk)); | 2869 | __skb_queue_head_init(TX_QUEUE(sk)); |
2857 | __skb_queue_head_init(SREJ_QUEUE(sk)); | 2870 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) |
2871 | l2cap_ertm_init(sk); | ||
2872 | |||
2858 | l2cap_chan_ready(sk); | 2873 | l2cap_chan_ready(sk); |
2859 | } | 2874 | } |
2860 | 2875 | ||
@@ -2886,9 +2901,12 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd | |||
2886 | sk->sk_shutdown = SHUTDOWN_MASK; | 2901 | sk->sk_shutdown = SHUTDOWN_MASK; |
2887 | 2902 | ||
2888 | skb_queue_purge(TX_QUEUE(sk)); | 2903 | skb_queue_purge(TX_QUEUE(sk)); |
2889 | skb_queue_purge(SREJ_QUEUE(sk)); | 2904 | |
2890 | del_timer(&l2cap_pi(sk)->retrans_timer); | 2905 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { |
2891 | del_timer(&l2cap_pi(sk)->monitor_timer); | 2906 | skb_queue_purge(SREJ_QUEUE(sk)); |
2907 | del_timer(&l2cap_pi(sk)->retrans_timer); | ||
2908 | del_timer(&l2cap_pi(sk)->monitor_timer); | ||
2909 | } | ||
2892 | 2910 | ||
2893 | l2cap_chan_del(sk, ECONNRESET); | 2911 | l2cap_chan_del(sk, ECONNRESET); |
2894 | bh_unlock_sock(sk); | 2912 | bh_unlock_sock(sk); |
@@ -2913,9 +2931,12 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd | |||
2913 | return 0; | 2931 | return 0; |
2914 | 2932 | ||
2915 | skb_queue_purge(TX_QUEUE(sk)); | 2933 | skb_queue_purge(TX_QUEUE(sk)); |
2916 | skb_queue_purge(SREJ_QUEUE(sk)); | 2934 | |
2917 | del_timer(&l2cap_pi(sk)->retrans_timer); | 2935 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { |
2918 | del_timer(&l2cap_pi(sk)->monitor_timer); | 2936 | skb_queue_purge(SREJ_QUEUE(sk)); |
2937 | del_timer(&l2cap_pi(sk)->retrans_timer); | ||
2938 | del_timer(&l2cap_pi(sk)->monitor_timer); | ||
2939 | } | ||
2919 | 2940 | ||
2920 | l2cap_chan_del(sk, 0); | 2941 | l2cap_chan_del(sk, 0); |
2921 | bh_unlock_sock(sk); | 2942 | bh_unlock_sock(sk); |
@@ -3280,12 +3301,16 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str | |||
3280 | { | 3301 | { |
3281 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 3302 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
3282 | u8 tx_seq = __get_txseq(rx_control); | 3303 | u8 tx_seq = __get_txseq(rx_control); |
3304 | u8 req_seq = __get_reqseq(rx_control); | ||
3283 | u16 tx_control = 0; | 3305 | u16 tx_control = 0; |
3284 | u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; | 3306 | u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; |
3285 | int err = 0; | 3307 | int err = 0; |
3286 | 3308 | ||
3287 | BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len); | 3309 | BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len); |
3288 | 3310 | ||
3311 | pi->expected_ack_seq = req_seq; | ||
3312 | l2cap_drop_acked_frames(sk); | ||
3313 | |||
3289 | if (tx_seq == pi->expected_tx_seq) | 3314 | if (tx_seq == pi->expected_tx_seq) |
3290 | goto expected; | 3315 | goto expected; |
3291 | 3316 | ||
@@ -3340,6 +3365,16 @@ expected: | |||
3340 | return 0; | 3365 | return 0; |
3341 | } | 3366 | } |
3342 | 3367 | ||
3368 | if (rx_control & L2CAP_CTRL_FINAL) { | ||
3369 | if (pi->conn_state & L2CAP_CONN_REJ_ACT) | ||
3370 | pi->conn_state &= ~L2CAP_CONN_REJ_ACT; | ||
3371 | else { | ||
3372 | sk->sk_send_head = TX_QUEUE(sk)->next; | ||
3373 | pi->next_tx_seq = pi->expected_ack_seq; | ||
3374 | l2cap_ertm_send(sk); | ||
3375 | } | ||
3376 | } | ||
3377 | |||
3343 | pi->buffer_seq = (pi->buffer_seq + 1) % 64; | 3378 | pi->buffer_seq = (pi->buffer_seq + 1) % 64; |
3344 | 3379 | ||
3345 | err = l2cap_sar_reassembly_sdu(sk, skb, rx_control); | 3380 | err = l2cap_sar_reassembly_sdu(sk, skb, rx_control); |
@@ -3376,6 +3411,14 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str | |||
3376 | pi->expected_ack_seq = tx_seq; | 3411 | pi->expected_ack_seq = tx_seq; |
3377 | l2cap_drop_acked_frames(sk); | 3412 | l2cap_drop_acked_frames(sk); |
3378 | 3413 | ||
3414 | if (pi->conn_state & L2CAP_CONN_REJ_ACT) | ||
3415 | pi->conn_state &= ~L2CAP_CONN_REJ_ACT; | ||
3416 | else { | ||
3417 | sk->sk_send_head = TX_QUEUE(sk)->next; | ||
3418 | pi->next_tx_seq = pi->expected_ack_seq; | ||
3419 | l2cap_ertm_send(sk); | ||
3420 | } | ||
3421 | |||
3379 | if (!(pi->conn_state & L2CAP_CONN_WAIT_F)) | 3422 | if (!(pi->conn_state & L2CAP_CONN_WAIT_F)) |
3380 | break; | 3423 | break; |
3381 | 3424 | ||
@@ -3403,10 +3446,24 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str | |||
3403 | pi->expected_ack_seq = __get_reqseq(rx_control); | 3446 | pi->expected_ack_seq = __get_reqseq(rx_control); |
3404 | l2cap_drop_acked_frames(sk); | 3447 | l2cap_drop_acked_frames(sk); |
3405 | 3448 | ||
3406 | sk->sk_send_head = TX_QUEUE(sk)->next; | 3449 | if (rx_control & L2CAP_CTRL_FINAL) { |
3407 | pi->next_tx_seq = pi->expected_ack_seq; | 3450 | if (pi->conn_state & L2CAP_CONN_REJ_ACT) |
3451 | pi->conn_state &= ~L2CAP_CONN_REJ_ACT; | ||
3452 | else { | ||
3453 | sk->sk_send_head = TX_QUEUE(sk)->next; | ||
3454 | pi->next_tx_seq = pi->expected_ack_seq; | ||
3455 | l2cap_ertm_send(sk); | ||
3456 | } | ||
3457 | } else { | ||
3458 | sk->sk_send_head = TX_QUEUE(sk)->next; | ||
3459 | pi->next_tx_seq = pi->expected_ack_seq; | ||
3460 | l2cap_ertm_send(sk); | ||
3408 | 3461 | ||
3409 | l2cap_ertm_send(sk); | 3462 | if (pi->conn_state & L2CAP_CONN_WAIT_F) { |
3463 | pi->srej_save_reqseq = tx_seq; | ||
3464 | pi->conn_state |= L2CAP_CONN_REJ_ACT; | ||
3465 | } | ||
3466 | } | ||
3410 | 3467 | ||
3411 | break; | 3468 | break; |
3412 | 3469 | ||
@@ -3425,7 +3482,7 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str | |||
3425 | } else if (rx_control & L2CAP_CTRL_FINAL) { | 3482 | } else if (rx_control & L2CAP_CTRL_FINAL) { |
3426 | if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) && | 3483 | if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) && |
3427 | pi->srej_save_reqseq == tx_seq) | 3484 | pi->srej_save_reqseq == tx_seq) |
3428 | pi->srej_save_reqseq &= ~L2CAP_CONN_SREJ_ACT; | 3485 | pi->conn_state &= ~L2CAP_CONN_SREJ_ACT; |
3429 | else | 3486 | else |
3430 | l2cap_retransmit_frame(sk, tx_seq); | 3487 | l2cap_retransmit_frame(sk, tx_seq); |
3431 | } | 3488 | } |
@@ -4004,6 +4061,9 @@ module_exit(l2cap_exit); | |||
4004 | module_param(enable_ertm, bool, 0644); | 4061 | module_param(enable_ertm, bool, 0644); |
4005 | MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode"); | 4062 | MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode"); |
4006 | 4063 | ||
4064 | module_param(max_transmit, uint, 0644); | ||
4065 | MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)"); | ||
4066 | |||
4007 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); | 4067 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); |
4008 | MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION); | 4068 | MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION); |
4009 | MODULE_VERSION(VERSION); | 4069 | MODULE_VERSION(VERSION); |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 25692bc0a342..fc5ee3296e22 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -51,6 +51,7 @@ | |||
51 | static int disable_cfc = 0; | 51 | static int disable_cfc = 0; |
52 | static int channel_mtu = -1; | 52 | static int channel_mtu = -1; |
53 | static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU; | 53 | static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU; |
54 | static int l2cap_ertm = 0; | ||
54 | 55 | ||
55 | static struct task_struct *rfcomm_thread; | 56 | static struct task_struct *rfcomm_thread; |
56 | 57 | ||
@@ -702,6 +703,8 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst | |||
702 | sk = sock->sk; | 703 | sk = sock->sk; |
703 | lock_sock(sk); | 704 | lock_sock(sk); |
704 | l2cap_pi(sk)->imtu = l2cap_mtu; | 705 | l2cap_pi(sk)->imtu = l2cap_mtu; |
706 | if (l2cap_ertm) | ||
707 | l2cap_pi(sk)->mode = L2CAP_MODE_ERTM; | ||
705 | release_sock(sk); | 708 | release_sock(sk); |
706 | 709 | ||
707 | s = rfcomm_session_add(sock, BT_BOUND); | 710 | s = rfcomm_session_add(sock, BT_BOUND); |
@@ -2185,6 +2188,9 @@ MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel"); | |||
2185 | module_param(l2cap_mtu, uint, 0644); | 2188 | module_param(l2cap_mtu, uint, 0644); |
2186 | MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection"); | 2189 | MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection"); |
2187 | 2190 | ||
2191 | module_param(l2cap_ertm, bool, 0644); | ||
2192 | MODULE_PARM_DESC(l2cap_ertm, "Use L2CAP ERTM mode for connection"); | ||
2193 | |||
2188 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); | 2194 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); |
2189 | MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION); | 2195 | MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION); |
2190 | MODULE_VERSION(VERSION); | 2196 | MODULE_VERSION(VERSION); |