[PATCH] usb: Fix timeout check in usb_control_msg

Marek Vasut marek.vasut at mailbox.org
Mon Feb 23 19:55:28 CET 2026


On 2/23/26 3:20 AM, Ronan Dalton wrote:
> The timeout check after the while loop in the usb_control_msg function
> checks for equality with zero, which is incorrect because timeout will
> actually be -1 after exiting the while loop due to a timeout.
> 
> Currently this means that -1 is usually returned by this function when
> -ETIMEDOUT should have been returned instead.
> 
> Fix this by comparing timeout with -1 instead. Add a check for
> timeout being negative at the start of the function and return -EINVAL
> in that case, since a negative timeout doesn't make sense either.
> 
> Signed-off-by: Ronan Dalton <ronan.dalton at alliedtelesis.co.nz>
> Cc: Marek Vasut <marex at denx.de>
> Cc: Philip Oberfichtner <pro at denx.de>
> ---
>   common/usb.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/common/usb.c b/common/usb.c
> index 6a4ad346f4b..2cbc432b131 100644
> --- a/common/usb.c
> +++ b/common/usb.c
> @@ -226,6 +226,9 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
>   	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet, 1);
>   	int err;
>   
> +	if (timeout < 0)
> +		return -EINVAL;
> +
>   	if ((timeout == 0) && (!asynch_allowed)) {
>   		/* request for a asynch control pipe is not allowed */
>   		return -EINVAL;
> @@ -259,7 +262,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
>   		mdelay(1);
>   	}
>   
> -	if (timeout == 0)
> +	if (timeout == -1)
>   		return -ETIMEDOUT;

Can you convert this poll/timeout sequence to include/linux/iopoll.h 
read_poll_timeout() instead , to remove another ad-hoc polling ?

Something like this should work:

"
volatile unsigned long val;
ret = read_poll_timeout((volatile unsigned long), val,
    !(val & USB_ST_NOT_PROC), 1000, timeout * 1000, dev->status);
"

usb_bulk_msg() may benefit from similar update.


More information about the U-Boot mailing list