From nobody Sat Jul 25 03:17:11 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4h6VQh6QxLz6lmcs for ; Sat, 25 Jul 2026 03:17:16 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4h6VQh5vn9z3Z15 for ; Sat, 25 Jul 2026 03:17:16 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1784949436; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=POWth8xZLlKta4QS7aVH+WaqHIYkXPhJgw4fIj9g4I4=; b=SjOTf2qp09nezdL3oR4+C51k0fHrpKbldpsGhPT5GSrccNU8QfzWotOYoYQSUvhQnT3OTG XM4zftE0Vr9kDon4qZ0flfdq3+ImMCzHrjar2TT36McDwDgDCLC6LXH0mRL14OWea6FBfE hPzyWZEB5nkoPIgXUpKiaC1790FqdAWNPNgtWvdu2qLKVGfC0fQxGmnXnJABSWuo5xvdfY iblJjbyRHXKqPD8cdEbshlMaQeZLmVayZW972B/2mUiMJnek+64YO86QzSNn/wYrflS/eQ fgG4xBmUp8mOYpxw8pY3l0Yw2iJ52f5rcORp5JwUOnuGZTkqH2Bl9JQJl1ZIAg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1784949436; a=rsa-sha256; cv=none; b=okWWBBxdcESuaQUtRk58OgmbbLemLFXG/Xv2k4AYwP+7jyc4Wv7zedNQV6FGJxlGnYnlZp RR6s3+r/ReczrQM1thiL6xnKIrtFaB/3ZfrqeIPP9DBR86FYBeys2YRy2rBIe2dHJKfTmM k5CtOgMdxFVpiw+MeKXFn8Ulfz7Y85Xo0jc6edaNSSn7dPGSQqGrXgBWg3q7My2qpJIxON uhxRXCGtoD0vpXN5qrFpio9tAVGA+3wp9kJessZ1cGx6P7k3J6/+6zYv21Bx/WQfwwthu2 Ng0UTT4EIOGvl+LyTAaw9BWxyimZQUG5D56Xr2wDcaJrVRoVE2R6ydlIpaB0/w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1784949436; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=POWth8xZLlKta4QS7aVH+WaqHIYkXPhJgw4fIj9g4I4=; b=fXeZC1GuhbUDyMFwbfW212ohzcZdCXLYbqDreXam9SHIwlQq7Qvh+ZnJjwqbwIJ38JhGXk zoK7yvNaqAK815rsp0Gnt/OYcvUzrFZIJTBsHykz296hrsWSnYSoxxWdXj41yRpvzqJohb 6W6FyOV4pifn4og+c+IAIw9hJMgPIE6d9rKjcRy2Fr54UAQl52wXtCTjsUW7txJ6p3WiMs lU4VOuGgYShyR39cgOydtK4lxNP3IMJA4Szek2z9wtPj+TdUf9m/1j0GoG7r/mCKjneARl nz89gxkkDAmx2VbSfm4N3eDGfyvVph6IU6TfrVbAPWfnimAFv/cEIB73ixRTeA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4h6VQh4kz9z4BS for ; Sat, 25 Jul 2026 03:17:16 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3d7cc by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 25 Jul 2026 03:17:11 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: ShengYi Hung Subject: git: 2cf2d955635a - main - usb: preserve error when doing request List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: aokblast X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 2cf2d955635abb546e57296e06815dd71f8c16ad Auto-Submitted: auto-generated Date: Sat, 25 Jul 2026 03:17:11 +0000 Message-Id: <6a642ab7.3d7cc.34eedc2e@gitrepo.freebsd.org> The branch main has been updated by aokblast: URL: https://cgit.FreeBSD.org/src/commit/?id=2cf2d955635abb546e57296e06815dd71f8c16ad commit 2cf2d955635abb546e57296e06815dd71f8c16ad Author: ShengYi Hung AuthorDate: 2025-08-29 17:23:12 +0000 Commit: ShengYi Hung CommitDate: 2026-07-25 03:16:59 +0000 usb: preserve error when doing request Currently, USB request not distinguished different error and always return EIO. However, some error are recoverable or ignorable in userspace. Therefore, we preserve the meaning of different error to userspace then allow userspace to decide how to use the return error. Reviewed by: adrian Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D52244 --- lib/libusb/libusb10_io.c | 47 ++++++++++++++++++++++++++++++++++++++------ lib/libusb/libusb20_ugen20.c | 45 +++++++++++++++++++++++++++++++++++++++++- sys/dev/usb/usb_generic.c | 46 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 127 insertions(+), 11 deletions(-) diff --git a/lib/libusb/libusb10_io.c b/lib/libusb/libusb10_io.c index 2047712e9e39..bb4680daebdb 100644 --- a/lib/libusb/libusb10_io.c +++ b/lib/libusb/libusb10_io.c @@ -28,6 +28,7 @@ #ifdef LIBUSB_GLOBAL_INCLUDE_FILE #include LIBUSB_GLOBAL_INCLUDE_FILE #else +#include #include #include #include @@ -472,6 +473,44 @@ done: /* Synchronous device I/O */ +static int +libusb10_convert_libusb20_error(int err) +{ + /* LIBUSB20_ERROR_* values are always non-positive */ + assert(err <= 0); + + switch (err) { + case LIBUSB20_SUCCESS: + return (0); + case LIBUSB20_ERROR_IO: + return (LIBUSB_ERROR_IO); + case LIBUSB20_ERROR_INVALID_PARAM: + return (LIBUSB_ERROR_INVALID_PARAM); + case LIBUSB20_ERROR_ACCESS: + return (LIBUSB_ERROR_ACCESS); + case LIBUSB20_ERROR_NO_DEVICE: + return (LIBUSB_ERROR_NO_DEVICE); + case LIBUSB20_ERROR_NOT_FOUND: + return (LIBUSB_ERROR_NOT_FOUND); + case LIBUSB20_ERROR_BUSY: + return (LIBUSB_ERROR_BUSY); + case LIBUSB20_ERROR_TIMEOUT: + return (LIBUSB_ERROR_TIMEOUT); + case LIBUSB20_ERROR_OVERFLOW: + return (LIBUSB_ERROR_OVERFLOW); + case LIBUSB20_ERROR_PIPE: + return (LIBUSB_ERROR_PIPE); + case LIBUSB20_ERROR_INTERRUPTED: + return (LIBUSB_ERROR_INTERRUPTED); + case LIBUSB20_ERROR_NO_MEM: + return (LIBUSB_ERROR_NO_MEM); + case LIBUSB20_ERROR_NOT_SUPPORTED: + return (LIBUSB_ERROR_NOT_SUPPORTED); + default: + return (LIBUSB_ERROR_OTHER); + } +} + int libusb_control_transfer(libusb_device_handle *devh, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, @@ -498,12 +537,8 @@ libusb_control_transfer(libusb_device_handle *devh, err = libusb20_dev_request_sync(devh, &req, data, &actlen, timeout, 0); - if (err == LIBUSB20_ERROR_PIPE) - return (LIBUSB_ERROR_PIPE); - else if (err == LIBUSB20_ERROR_TIMEOUT) - return (LIBUSB_ERROR_TIMEOUT); - else if (err) - return (LIBUSB_ERROR_NO_DEVICE); + if (err) + return (libusb10_convert_libusb20_error(err)); return (actlen); } diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c index 32c8d53cd611..43d870fbe112 100644 --- a/lib/libusb/libusb20_ugen20.c +++ b/lib/libusb/libusb20_ugen20.c @@ -97,6 +97,49 @@ static const struct libusb20_device_methods libusb20_ugen20_device_methods = { LIBUSB20_DEVICE(LIBUSB20_DECLARE, ugen20) }; +static int +errno_to_libusb_error(int uerr) +{ + switch (uerr) { + case 0: + return (LIBUSB20_SUCCESS); + case EIO: + case ERANGE: + return (LIBUSB20_ERROR_IO); + case EINVAL: + case EFAULT: + case ENOBUFS: + return (LIBUSB20_ERROR_INVALID_PARAM); + case EACCES: + case EPERM: + return (LIBUSB20_ERROR_ACCESS); + case ENXIO: + case ENODEV: + return (LIBUSB20_ERROR_NO_DEVICE); + case ENOENT: + return (LIBUSB20_ERROR_NOT_FOUND); + case EBUSY: + case EALREADY: + case EADDRINUSE: + return (LIBUSB20_ERROR_BUSY); + case ETIMEDOUT: + return (LIBUSB20_ERROR_TIMEOUT); + case EMSGSIZE: + return (LIBUSB20_ERROR_OVERFLOW); + case EPIPE: + return (LIBUSB20_ERROR_PIPE); + case EINTR: + case ECANCELED: + return (LIBUSB20_ERROR_INTERRUPTED); + case ENOMEM: + return (LIBUSB20_ERROR_NO_MEM); + case ENOTSUP: + return (LIBUSB20_ERROR_NOT_SUPPORTED); + default: + return (LIBUSB20_ERROR_OTHER); + } +} + static const char * ugen20_get_backend_name(void) { @@ -746,7 +789,7 @@ ugen20_do_request_sync(struct libusb20_device *pdev, /* ignore */ } if (ioctl(pdev->file_ctrl, IOUSB(USB_DO_REQUEST), &req)) { - return (LIBUSB20_ERROR_OTHER); + return (errno_to_libusb_error(errno)); } if (pactlen) { /* get actual length */ diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c index c564585acd5a..fb2b4ce6dc1b 100644 --- a/sys/dev/usb/usb_generic.c +++ b/sys/dev/usb/usb_generic.c @@ -143,6 +143,38 @@ SYSCTL_INT(_hw_usb_ugen, OID_AUTO, debug, CTLFLAG_RWTUN, &ugen_debug, 0, "Debug level"); #endif +static const int usb_error_to_errno[USB_ERR_MAX] = { + [USB_ERR_NORMAL_COMPLETION] = 0, + [USB_ERR_PENDING_REQUESTS] = EALREADY, + [USB_ERR_NOT_STARTED] = EINVAL, + [USB_ERR_INVAL] = EINVAL, + [USB_ERR_NOMEM] = ENOMEM, + [USB_ERR_CANCELLED] = ECANCELED, + [USB_ERR_BAD_ADDRESS] = EFAULT, + [USB_ERR_BAD_BUFSIZE] = ENOBUFS, + [USB_ERR_BAD_FLAG] = EINVAL, + [USB_ERR_NO_CALLBACK] = EINVAL, + [USB_ERR_IN_USE] = EADDRINUSE, + [USB_ERR_NO_ADDR] = EADDRNOTAVAIL, + [USB_ERR_NO_PIPE] = ENOENT, + [USB_ERR_ZERO_NFRAMES] = EINVAL, + [USB_ERR_ZERO_MAXP] = EINVAL, + [USB_ERR_SET_ADDR_FAILED] = EADDRNOTAVAIL, + [USB_ERR_NO_POWER] = ENXIO, + [USB_ERR_TOO_DEEP] = EINVAL, + [USB_ERR_IOERROR] = EIO, + [USB_ERR_NOT_CONFIGURED] = ENXIO, + [USB_ERR_TIMEOUT] = ETIMEDOUT, + [USB_ERR_SHORT_XFER] = ERANGE, + [USB_ERR_STALLED] = EPIPE, + [USB_ERR_INTERRUPTED] = EINTR, + [USB_ERR_DMA_LOAD_FAILED] = EIO, + [USB_ERR_BAD_CONTEXT] = EBADMSG, + [USB_ERR_NO_ROOT_HUB] = EINVAL, + [USB_ERR_NO_INTR_THREAD] = EIO, + [USB_ERR_NOT_LOCKED] = EINVAL, +}; + /* prototypes */ static int @@ -861,10 +893,16 @@ ugen_do_request(struct usb_fifo *f, struct usb_ctl_request *ur) ur->ucr_actlen = actlen; - if (error) { - error = EIO; - } - return (error); + /* + * Fall back to EIO for USB errors without a table entry, so + * that an unmapped error cannot be reported as success. + */ + if (error < 0 || error >= USB_ERR_MAX || + (error != USB_ERR_NORMAL_COMPLETION && + usb_error_to_errno[error] == 0)) + return (EIO); + + return (usb_error_to_errno[error]); } #ifdef COMPAT_FREEBSD32