diff mbox

[1/1] HID: usbhid: add usb_clear_halt determination for next hid_start_in

Message ID 1408692913-12336-1-git-send-email-vichy.kuo@gmail.com (mailing list archive)
State New, archived
Delegated to: Jiri Kosina
Headers show

Commit Message

pierre kuo Aug. 22, 2014, 7:35 a.m. UTC
HID IR device will not response to any command send from host when it is finishing paring and tring to reset itself.
During this period of time, usb_cleaer_halt will be fail and if hid_start_in soon again, we has the possibility trap in infinite loop.

Signed-off-by: CheChun Kuo <vichy.kuo@gmail.com>
---
 drivers/hid/usbhid/hid-core.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Jiri Kosina Aug. 22, 2014, 7:45 a.m. UTC | #1
On Fri, 22 Aug 2014, CheChun Kuo wrote:

> 	HID IR device will not response to any command send from host when 
> it is finishing paring and tring to reset itself. During this period of 
> time, usb_cleaer_halt will be fail and if hid_start_in soon again, we 
> has the possibility trap in infinite loop.
> 
> Signed-off-by: CheChun Kuo <vichy.kuo@gmail.com>
> ---
>  drivers/hid/usbhid/hid-core.c |    3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
> index 79cf503..256b102 100644
> --- a/drivers/hid/usbhid/hid-core.c
> +++ b/drivers/hid/usbhid/hid-core.c
> @@ -122,7 +122,8 @@ static void hid_reset(struct work_struct *work)
>  		dev_dbg(&usbhid->intf->dev, "clear halt\n");
>  		rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe);
>  		clear_bit(HID_CLEAR_HALT, &usbhid->iofl);
> -		hid_start_in(hid);
> +		if (rc == 0)
> +			hid_start_in(hid);
>  	}

I'd need a more detailed explanation for this patch, as I don't understand 
neither the text in the changelog nor the patch itself. Namely:

- which IR devices are showing this behavior?
- where does the infinite loop come from? hid_reset() should error out 
  properly if usb_clear_halt() fails and HID_IN_RUNNING flag is not set

Thanks,
pierre kuo Aug. 22, 2014, 10:43 a.m. UTC | #2
hi Jiri:

2014-08-22 15:45 GMT+08:00 Jiri Kosina <jkosina@suse.cz>:
> On Fri, 22 Aug 2014, CheChun Kuo wrote:
>
>>       HID IR device will not response to any command send from host when
>> it is finishing paring and tring to reset itself. During this period of
>> time, usb_cleaer_halt will be fail and if hid_start_in soon again, we
>> has the possibility trap in infinite loop.
>>
>> Signed-off-by: CheChun Kuo <vichy.kuo@gmail.com>
>> ---
>>  drivers/hid/usbhid/hid-core.c |    3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
>> index 79cf503..256b102 100644
>> --- a/drivers/hid/usbhid/hid-core.c
>> +++ b/drivers/hid/usbhid/hid-core.c
>> @@ -122,7 +122,8 @@ static void hid_reset(struct work_struct *work)
>>               dev_dbg(&usbhid->intf->dev, "clear halt\n");
>>               rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe);
>>               clear_bit(HID_CLEAR_HALT, &usbhid->iofl);
>> -             hid_start_in(hid);
>> +             if (rc == 0)
>> +                     hid_start_in(hid);
>>       }
>
> I'd need a more detailed explanation for this patch, as I don't understand
> neither the text in the changelog nor the patch itself. Namely:
>
> - which IR devices are showing this behavior?
The USB hid device that will transform IR signal to usb command when
user press "volume up/down", "voice recording", etc.

> - where does the infinite loop come from? hid_reset() should error out
>   properly if usb_clear_halt() fails and HID_IN_RUNNING flag is not set
Below I briefly draw the timing when this issue happen

i) hid_irq_in get URB status as -EPIPE
ii) set HID_CLEAR_HALT flag and schedule hid_reset work
iii) hid_reset call usb_clear_halt and hid_start_in again
iv) if device still doesn't response host command, it will go to i)
above and keep looping

thanks for your help,
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 79cf503..256b102 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -122,7 +122,8 @@  static void hid_reset(struct work_struct *work)
 		dev_dbg(&usbhid->intf->dev, "clear halt\n");
 		rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe);
 		clear_bit(HID_CLEAR_HALT, &usbhid->iofl);
-		hid_start_in(hid);
+		if (rc == 0)
+			hid_start_in(hid);
 	}
 
 	else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) {