hidp: Make hidp_get_raw_report abort if the session is terminating.
Subsystems (2)
PATCH v2 1/1 hidp: Make hidp_get_raw_report abort if the session is terminating.
From: Karl Relton <[email protected]>
After linux 3.2 the hid_destroy_device call in hidp_session cleaning up invokes a hook to the power_supply code which in turn tries to read the battery capacity. This read will trigger a call to hidp_get_raw_report which is bound to fail because the device is being taken away - so rather than wait for the 5 second timeout failure this changes enables it to fail straight away.
--- net/bluetooth/hidp/core.c | 4 ++++ 1 file changed, 4 insertions(+)
net/bluetooth/hidp/core.c +4 -0
@@ -311,6 +311,9 @@ static int hidp_get_raw_report(struct hid_device *hid,int numbered_reports = hid->report_enum[report_type].numbered;int ret; +if (atomic_read (&session->terminate)) +return -EIO ; +switch (report_type) {case HID_FEATURE_REPORT : report_type =HIDP_TRANS_GET_REPORT |HIDP_DATA_RTYPE_FEATURE ;
@@ -722,6 +725,7 @@ static int hidp_session(void *arg)set_current_state (TASK_INTERRUPTIBLE ); }set_current_state (TASK_RUNNING ); +atomic_inc (&session->terminate);remove_wait_queue (sk_sleep (intr_sk), &intr_wait);remove_wait_queue (sk_sleep (ctrl_sk), &ctrl_wait);
Signature · 1 line
1.7.9.5
Quoted 21 lines · Karl Relton
From: Karl Relton <[email protected]>
After linux 3.2 the
hid_destroy_devicecall inhidp_sessioncleaning up invokes a hook to thepower_supplycode which in turn tries to read the battery capacity. This read will trigger a call tohidp_get_raw_reportwhich is bound to fail because the device is being taken away - so rather than wait for the 5 second timeout failure this changes enables it to fail straight away.Signed-off-by Karl Relton <[email protected]>Reviewed-by David Herrmann <[email protected]>--- net/bluetooth/hidp/core.c | 4 ++++ 1 file changed, 4 insertions(+)net/bluetooth/hidp/core.c +0
-0
net/bluetooth/hidp/core.c static int hidp_get_raw_report(struct hid_device *hid, · line 317
Quoted 7 lines
net/bluetooth/hidp/core.c +3
-0@@ -311,6 +311,9 @@ static int hidp_get_raw_report(struct hid_device *hid,int numbered_reports = hid->report_enum[report_type].numbered;int ret; +if (atomic_read (&session->terminate)) +return -EIO ; +switch (report_type) {
Actually I've just realised that hidp_get_raw_report calls __hidp_send_ctrl_message which already has the session->terminate test, also returning -EIO on failure. So adding it again here is redundant.
net/bluetooth/hidp/core.c static int hidp_session(void *arg) · line 731
Quoted 8 lines
net/bluetooth/hidp/core.c +1
-0@@ -722,6 +725,7 @@ static int hidp_session(void *arg)set_current_state (TASK_INTERRUPTIBLE ); }set_current_state (TASK_RUNNING ); +atomic_inc (&session->terminate);remove_wait_queue (sk_sleep (intr_sk), &intr_wait);remove_wait_queue (sk_sleep (ctrl_sk), &ctrl_wait);
So its just this one single line we need - to ensure session->terminate is non-zero, which will ensure calls to other things (like hidp_get_raw_report) abort swiftly.
I'll change the patch and send v3 this evening (need to get back to the day job!).
Karl
Hi Karl,
Quoted 10 lines · Karl Relton
From: Karl Relton <[email protected]>
After linux 3.2 the
hid_destroy_devicecall inhidp_sessioncleaning up invokes a hook to thepower_supplycode which in turn tries to read the battery capacity. This read will trigger a call tohidp_get_raw_reportwhich is bound to fail because the device is being taken away - so rather than wait for the 5 second timeout failure this changes enables it to fail straight away.
Quoted 5 lines
Signed-off-by Karl Relton <[email protected]>Reviewed-by David Herrmann <[email protected]>--- net/bluetooth/hidp/core.c | 4 ++++ 1 file changed, 4 insertions(+)
Patch has been applied to bluetooth-next. Thanks.
Gustavo