Pull request: bluetooth-2.6 2010-02-05
Subsystems (4)
Marcel Holtmann
maintainerHi Dave,
here are a few more fixes that are mostly a result from the Bluetooth UnPlugFest testing in Seattle during this week.
The important one are the fix for the sleeping function call in the RFCOMM timer that show up with certain hardware (not all of them) and also the fix for double release of the underlaying L2CAP session.
With the HID subsystem changes that turns it into a proper bus, the HIDP code ended up with a potential case where we access userspace memory out of the scop of its ioctl() command. Fix this by just keeping a copy of the HID report descriptor around. The HID subsystem will need that anyway.
The rest are some SCO/eSCO audio setup fixes with broken hardware and closing a memory leak in the Marvell driver.
Regards
Marcel
Please pull from
git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git master
This will update the following files:
drivers/bluetooth/btmrvl_sdio.c | 1 + net/bluetooth/hci_conn.c | 3 ++ net/bluetooth/hci_event.c | 1 + net/bluetooth/hidp/core.c | 49 +++++++++++++++++++-------------------- net/bluetooth/hidp/hidp.h | 4 ++- net/bluetooth/rfcomm/core.c | 8 ++++- 6 files changed, 38 insertions(+), 28 deletions(-)
through these ChangeSets:
Marcel Holtmann (1):
Bluetooth: Fix sleeping function in RFCOMM within invalid context
Michael Poole (1):
Bluetooth: Keep a copy of each HID device's report descriptor
Nick Pelly (3):
Bluetooth: Fallback eSCO to SCO on error 0x1a (Unsupported Remote
Bluetooth: Do not call rfcomm_session_put() for RFCOMM UA on closed
Bluetooth: Enter active mode before establishing a SCO link.
Yoichi Yuasa (1):
Bluetooth: Fix memory leak in Marvell BT-over-SDIO driver
Marcel Holtmann
maintainerPATCH 1/6 Bluetooth: Fallback eSCO to SCO on error 0x1a (Unsupported Remote Feature)
From: Nick Pelly <[email protected]>
General Motors carkits that use LGE BT chipsets return this error code when an eSCO is attempted, despite advertising eSCO support.
2009-08-13 14:41:39.755518 < HCI Command: Setup Synchronous Connection (0x01|0x0028) plen 17 handle 1 voice setting 0x0060 2009-08-13 14:41:39.757563 > HCI Event: Command Status (0x0f) plen 4 Setup Synchronous Connection (0x01|0x0028) status 0x00 ncmd 1 2009-08-13 14:41:39.789484 > HCI Event: Synchronous Connect Complete (0x2c) plen 17 status 0x1a handle 257 bdaddr 00:1E:B2:23:5E:B3 type eSCO Error: Unsupported Remote Feature / Unsupported LMP Feature
--- net/bluetooth/hci_event.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
net/bluetooth/hci_event.c +1 -0
@@ -1699,6 +1699,7 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bubreak ;case 0x1c :/* SCO interval rejected */ +case 0x1a :/* Unsupported Remote Feature */ case 0x1f :/* Unspecified error */ if (conn->out && conn->attempt <2 ) { conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
Signature · 1 line
1.6.6
Marcel Holtmann
maintainerPATCH 2/6 Bluetooth: Fix sleeping function in RFCOMM within invalid context
With the commit 9e726b17422bade75fba94e625cd35fd1353e682 the rfcomm_session_put() gets accidentially called from a timeout callback and results in this:
BUG: sleeping function called from invalid context at net/core/sock.c:1897 in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper Pid: 0, comm: swapper Tainted: P 2.6.32 #31 Call Trace: <IRQ> [<ffffffff81036455>] __might_sleep+0xf8/0xfa [<ffffffff8138ef1d>] lock_sock_nested+0x29/0xc4 [<ffffffffa03921b3>] lock_sock+0xb/0xd [l2cap] [<ffffffffa03948e6>] l2cap_sock_shutdown+0x1c/0x76 [l2cap] [<ffffffff8106adea>] ? clockevents_program_event+0x75/0x7e [<ffffffff8106bea2>] ? tick_dev_program_event+0x37/0xa5 [<ffffffffa0394967>] l2cap_sock_release+0x27/0x67 [l2cap] [<ffffffff8138c971>] sock_release+0x1a/0x67 [<ffffffffa03d2492>] rfcomm_session_del+0x34/0x53 [rfcomm] [<ffffffffa03d24c5>] rfcomm_session_put+0x14/0x16 [rfcomm] [<ffffffffa03d28b4>] rfcomm_session_timeout+0xe/0x1a [rfcomm] [<ffffffff810554a8>] run_timer_softirq+0x1e2/0x29a [<ffffffffa03d28a6>] ? rfcomm_session_timeout+0x0/0x1a [rfcomm] [<ffffffff8104e0f6>] __do_softirq+0xfe/0x1c5 [<ffffffff8100e8ce>] ? timer_interrupt+0x1a/0x21 [<ffffffff8100cc4c>] call_softirq+0x1c/0x28 [<ffffffff8100e05b>] do_softirq+0x33/0x6b [<ffffffff8104daf6>] irq_exit+0x36/0x85 [<ffffffff8100d7a9>] do_IRQ+0xa6/0xbd [<ffffffff8100c493>] ret_from_intr+0x0/0xa <EOI> [<ffffffff812585b3>] ? acpi_idle_enter_bm+0x269/0x294 [<ffffffff812585a9>] ? acpi_idle_enter_bm+0x25f/0x294 [<ffffffff81373ddc>] ? cpuidle_idle_call+0x97/0x107 [<ffffffff8100aca0>] ? cpu_idle+0x53/0xaa [<ffffffff81429006>] ? rest_init+0x7a/0x7c [<ffffffff8177bc8c>] ? start_kernel+0x389/0x394 [<ffffffff8177b29c>] ? x86_64_start_reservations+0xac/0xb0 [<ffffffff8177b384>] ? x86_64_start_kernel+0xe4/0xeb
To fix this, the rfcomm_session_put() needs to be moved out of rfcomm_session_timeout() into rfcomm_process_sessions(). In that context it is perfectly fine to sleep and disconnect the socket.
--- net/bluetooth/rfcomm/core.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
net/bluetooth/rfcomm/core.c +1 -1
@@ -252,7 +252,6 @@ static void rfcomm_session_timeout(unsigned long arg)BT_DBG ("session %p state %ld" , s, s->state);set_bit (RFCOMM_TIMED_OUT , &s->flags); -rfcomm_session_put (s);rfcomm_schedule (RFCOMM_SCHED_TIMEO ); }
@@ -1920,6 +1919,7 @@ static inline void rfcomm_process_sessions(void)if (test_and_clear_bit (RFCOMM_TIMED_OUT , &s->flags)) { s->state =BT_DISCONN ;rfcomm_send_disc (s,0 ); +rfcomm_session_put (s);continue ; }
Signature · 1 line
1.6.6
Marcel Holtmann
maintainerPATCH 3/6 Bluetooth: Do not call rfcomm_session_put() for RFCOMM UA on closed socket
From: Nick Pelly <[email protected]>
When processing a RFCOMM UA frame when the socket is closed and we were not the RFCOMM initiator would cause rfcomm_session_put() to be called twice during rfcomm_process_rx(). This would cause a kernel panic in rfcomm_session_close() then.
This could be easily reproduced during disconnect with devices such as Motorola H270 that send RFCOMM UA followed quickly by L2CAP disconnect request. This trace for this looks like:
2009-09-21 17:22:37.788895 < ACL data: handle 1 flags 0x02 dlen 8
L2CAP(d): cid 0x0041 len 4 [psm 3]
RFCOMM(s): DISC: cr 0 dlci 20 pf 1 ilen 0 fcs 0x7d
2009-09-21 17:22:37.906204 > HCI Event: Number of Completed Packets (0x13) plen 5
handle 1 packets 1
2009-09-21 17:22:37.933090 > ACL data: handle 1 flags 0x02 dlen 8
L2CAP(d): cid 0x0040 len 4 [psm 3]
RFCOMM(s): UA: cr 0 dlci 20 pf 1 ilen 0 fcs 0x57
2009-09-21 17:22:38.636764 < ACL data: handle 1 flags 0x02 dlen 8
L2CAP(d): cid 0x0041 len 4 [psm 3]
RFCOMM(s): DISC: cr 0 dlci 0 pf 1 ilen 0 fcs 0x9c
2009-09-21 17:22:38.744125 > HCI Event: Number of Completed Packets (0x13) plen 5
handle 1 packets 1
2009-09-21 17:22:38.763687 > ACL data: handle 1 flags 0x02 dlen 8
L2CAP(d): cid 0x0040 len 4 [psm 3]
RFCOMM(s): UA: cr 0 dlci 0 pf 1 ilen 0 fcs 0xb6
2009-09-21 17:22:38.783554 > ACL data: handle 1 flags 0x02 dlen 12
L2CAP(s): Disconn req: dcid 0x0040 scid 0x0041Avoid calling rfcomm_session_put() twice by skipping this call in rfcomm_recv_ua() if the socket is closed.
--- net/bluetooth/rfcomm/core.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
net/bluetooth/rfcomm/core.c +5 -1
@@ -1150,7 +1150,11 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)break ;case BT_DISCONN : -rfcomm_session_put (s); +/* When socket is closed and we are not RFCOMM +* initiator rfcomm_process_rx already calls +* rfcomm_session_put() */ +if (s->sock->sk->sk_state !=BT_CLOSED ) +rfcomm_session_put (s);break ; } }
Signature · 1 line
1.6.6
Marcel Holtmann
maintainerPATCH 4/6 Bluetooth: Fix memory leak in Marvell BT-over-SDIO driver
From: Yoichi Yuasa <[email protected]>
--- drivers/bluetooth/btmrvl_sdio.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/bluetooth/btmrvl_sdio.c +1 -0
@@ -808,6 +808,7 @@ static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv, exit:sdio_release_host (card->func); +kfree (tmpbuf);return ret; }
Signature · 1 line
1.6.6
Marcel Holtmann
maintainerPATCH 5/6 Bluetooth: Enter active mode before establishing a SCO link.
From: Nick Pelly <[email protected]>
When in sniff mode with a long interval time (1.28s) it can take 4+ seconds to establish a SCO link. Fix by requesting active mode before requesting SCO connection. This improves SCO setup time to ~500ms.
Bluetooth headsets that use a long interval time, and exhibit the long SCO connection time include Motorola H790, HX1 and H17. They have a CSR 2.1 chipset.
Verified this behavior and fix with host Bluetooth chipsets: BCM4329 and TI1271.
2009-10-13 14:17:46.183722 > HCI Event: Mode Change (0x14) plen 6
status 0x00 handle 1 mode 0x02 interval 2048
Mode: Sniff
2009-10-13 14:17:53.436285 < HCI Command: Setup Synchronous Connection (0x01|0x0028) plen 17
handle 1 voice setting 0x0060
2009-10-13 14:17:53.445593 > HCI Event: Command Status (0x0f) plen 4
Setup Synchronous Connection (0x01|0x0028) status 0x00 ncmd 1
2009-10-13 14:17:57.788855 > HCI Event: Synchronous Connect Complete 0x2c) plen 17
status 0x00 handle 257 bdaddr 00:1A:0E:F1:A4:7F type eSCO
Air mode: CVSD--- net/bluetooth/hci_conn.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
net/bluetooth/hci_conn.c +3 -0
@@ -377,6 +377,9 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8if (acl->state ==BT_CONNECTED && (sco->state ==BT_OPEN || sco->state ==BT_CLOSED )) { + acl->power_save =1 ; +hci_conn_enter_active_mode (acl); +if (lmp_esco_capable (hdev))hci_setup_sync (sco, acl->handle);else
Signature · 1 line
1.6.6
Marcel Holtmann
maintainerPATCH 6/6 Bluetooth: Keep a copy of each HID device's report descriptor
From: Michael Poole <[email protected]>
The report descriptor is read by user space (via the Service Discovery Protocol), so it is only available during the ioctl to connect. However, the HID probe function that needs the descriptor might not be called until a specific module is loaded. Keep a copy of the descriptor so it is available for later use.
--- net/bluetooth/hidp/core.c | 49 ++++++++++++++++++++++----------------------- net/bluetooth/hidp/hidp.h | 4 ++- 2 files changed, 27 insertions(+), 26 deletions(-)
net/bluetooth/hidp/core.c +24 -25
@@ -703,29 +703,9 @@ static void hidp_close(struct hid_device *hid)static int hidp_parse (struct hid_device *hid) {struct hidp_session *session = hid->driver_data; -struct hidp_connadd_req *req = session->req; -unsigned char *buf; -int ret; - - buf =kmalloc (req->rd_size,GFP_KERNEL ); -if (!buf) -return -ENOMEM ; - -if (copy_from_user (buf, req->rd_data, req->rd_size)) { -kfree (buf); -return -EFAULT ; - } - - ret =hid_parse_report (session->hid, buf, req->rd_size); - -kfree (buf); - -if (ret) -return ret; - - session->req =NULL ; -return 0 ; +return hid_parse_report (session->hid, session->rd_data, + session->rd_size); }static int hidp_start (struct hid_device *hid)
@@ -770,12 +750,24 @@ static int hidp_setup_hid(struct hidp_session *session,bdaddr_t src, dst;int err; + session->rd_data =kzalloc (req->rd_size,GFP_KERNEL ); +if (!session->rd_data) +return -ENOMEM ; + +if (copy_from_user (session->rd_data, req->rd_data, req->rd_size)) { + err = -EFAULT ; + goto fault; + } + session->rd_size = req->rd_size; + hid =hid_allocate_device (); -if (IS_ERR (hid)) -return PTR_ERR (hid); +if (IS_ERR (hid)) { + err =PTR_ERR (hid); + goto fault; + } session->hid = hid; - session->req = req; + hid->driver_data = session;baswap (&src, &bt_sk (session->ctrl_sock->sk)->src);
@@ -806,6 +798,10 @@ failed:hid_destroy_device (hid); session->hid =NULL ; +fault: +kfree (session->rd_data); + session->rd_data =NULL ; +return err; }
@@ -900,6 +896,9 @@ unlink: session->hid =NULL ; } +kfree (session->rd_data); + session->rd_data =NULL ; + purge:skb_queue_purge (&session->ctrl_transmit);skb_queue_purge (&session->intr_transmit);
net/bluetooth/hidp/hidp.h +3 -1
@@ -154,7 +154,9 @@ struct hidp_session {struct sk_buff_head ctrl_transmit;struct sk_buff_head intr_transmit; -struct hidp_connadd_req *req; +/* Report descriptor */ +__u8 *rd_data; +uint rd_size; };static inline void hidp_schedule (struct hidp_session *session)
Signature · 1 line
1.6.6
David Miller
maintainerFrom: Marcel Holtmann <[email protected]>
Date: Fri, 5 Feb 2010 12:05:33 -0800
Quoted 2 lines
here are a few more fixes that are mostly a result from the Bluetooth UnPlugFest testing in Seattle during this week.
Man, I live in Seattle and I still never get invited to these cool events ;-)
Quoted 12 lines
The important one are the fix for the sleeping function call in the RFCOMM timer that show up with certain hardware (not all of them) and also the fix for double release of the underlaying L2CAP session.
With the HID subsystem changes that turns it into a proper bus, the HIDP code ended up with a potential case where we access userspace memory out of the scop of its
ioctl()command. Fix this by just keeping a copy of the HID report descriptor around. The HID subsystem will need that anyway.The rest are some SCO/eSCO audio setup fixes with broken hardware and closing a memory leak in the Marvell driver.
...
Quoted 3 lines
Please pull from
git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.gitmaster
Pulled, thanks!
Marcel Holtmann
maintainerHi Dave,
Quoted 5 lines
Quoted 2 lines
here are a few more fixes that are mostly a result from the Bluetooth UnPlugFest testing in Seattle during this week.
Man, I live in Seattle and I still never get invited to these cool events ;-)
I wouldn't call them cool actually. It is a stressful week of non-stop testing against other Bluetooth stacks and products. Also they are covered under an NDA since some companies are testing with prototypes.
Regards
Marcel
David Miller
maintainerFrom: Marcel Holtmann <[email protected]>
Date: Tue, 09 Feb 2010 16:52:04 +0100
Quoted 11 lines
Hi Dave,
Quoted 5 lines
Quoted 2 lines
here are a few more fixes that are mostly a result from the Bluetooth UnPlugFest testing in Seattle during this week.
Man, I live in Seattle and I still never get invited to these cool events ;-)
I wouldn't call them cool actually. It is a stressful week of non-stop testing against other Bluetooth stacks and products. Also they are covered under an NDA since some companies are testing with prototypes.
I guess I need to find a better emoticon to use for sarcasm.