diff options
| author | Neill Kapron <nkapron@google.com> | 2026-06-19 04:06:05 +0000 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-07-10 15:00:45 +0200 |
| commit | c3249c462b30e003712cd80f05c26ae3ee29040c (patch) | |
| tree | 6375fc81a50a5eaf45819dc446996d15950325d8 /include/uapi/linux | |
| parent | 621707dc67c9846fd876d7579ec951d92aa033f1 (diff) | |
usb: gadget: f_fs: Add zero-length packet ioctl
When transferring data from a USB gadget to a host, a transfer is
considered complete when the host receives a short packet (a packet
smaller than wMaxPacketSize). If the total transfer length is an
exact multiple of wMaxPacketSize, a Zero-Length Packet (ZLP) must
be appended to signal the end of the transfer.
FunctionFS currently provides no mechanism for userspace to instruct
the kernel to set the `req->zero` flag on transfers. Userspace
workarounds, such as manually submitting separate 0-byte requests,
may not be available for legacy protocols which must maintain write
behavior compatibility when moved to functionfs implementations.
To resolve this, introduce a new ioctl, FUNCTIONFS_ENDPOINT_ENABLE_ZLP,
which takes a pointer to a __u32 flag. When enabled, all subsequent
transfers on that endpoint will have the `req->zero` flag set, allowing
the underlying USB Device Controller (UDC) hardware to automatically
append a ZLP only when mathematically required. For logical transfers
chunked across multiple requests, userspace can dynamically toggle this
flag, enabling it only prior to submitting the final chunk.
The flag defaults to false to maintain backward compatibility. Once
enabled, the state is persistent for the lifetime of the endpoint and
will not be reset by opening or closing the endpoint file descriptors.
Assisted-by: Gemini-CLI:gemini-3.1-pro-preview
Signed-off-by: Neill Kapron <nkapron@google.com>
Link: https://patch.msgid.link/20260619040609.4010746-4-nkapron@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/uapi/linux')
| -rw-r--r-- | include/uapi/linux/usb/functionfs.h | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/include/uapi/linux/usb/functionfs.h b/include/uapi/linux/usb/functionfs.h index beef1752e36e..06134dca4e8a 100644 --- a/include/uapi/linux/usb/functionfs.h +++ b/include/uapi/linux/usb/functionfs.h @@ -414,4 +414,27 @@ struct usb_functionfs_event { #define FUNCTIONFS_DMABUF_TRANSFER _IOW('g', 133, \ struct usb_ffs_dmabuf_transfer_req) +/* + * Enable or disable automatic zero-length packet (ZLP) appending for the + * endpoint. The argument is a pointer to a __u32: 0 to disable, non-zero to + * enable. + * + * When enabled, the kernel will automatically append a ZLP at the end of + * a transfer if the payload length is an exact multiple of the endpoint's + * max packet size. + * + * This is useful for compatibility with legacy protocols which require + * automatic ZLP appending to data written from userspace. + * + * This ioctl can only be used on IN endpoints. It can be called at any time + * after the FunctionFS instance is active, even before the host has connected + * or enabled the endpoint. + * + * Returns zero on success, or a negative errno value on error: + * -ENODEV: The FunctionFS instance is not active. + * -EINVAL: The endpoint is not an IN endpoint. + * -EFAULT: Invalid user space pointer for the argument. + */ +#define FUNCTIONFS_ENDPOINT_ENABLE_ZLP _IOW('g', 134, __u32) + #endif /* _UAPI__LINUX_FUNCTIONFS_H__ */ |
