lesavka/scripts/kernel/uvc-bulk.patch

174 lines
6.6 KiB
Diff
Raw Normal View History

2026-01-22 15:23:25 -03:00
diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
index aa6ab666741a..7fb30b09e980 100644
--- a/drivers/usb/gadget/function/f_uvc.c
+++ b/drivers/usb/gadget/function/f_uvc.c
@@ -652,22 +652,32 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
unsigned int max_packet_size;
struct usb_ep *ep;
struct f_uvc_opts *opts;
+ bool bulk;
int ret = -EINVAL;
uvcg_info(f, "%s()\n", __func__);
opts = fi_to_f_uvc_opts(f->fi);
+ bulk = opts->streaming_bulk;
/* Sanity check the streaming endpoint module parameters. */
opts->streaming_interval = clamp(opts->streaming_interval, 1U, 16U);
- opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U);
opts->streaming_maxburst = min(opts->streaming_maxburst, 15U);
- /* For SS, wMaxPacketSize has to be 1024 if bMaxBurst is not 0 */
- if (opts->streaming_maxburst &&
- (opts->streaming_maxpacket % 1024) != 0) {
- opts->streaming_maxpacket = roundup(opts->streaming_maxpacket, 1024);
- uvcg_info(f, "overriding streaming_maxpacket to %d\n",
- opts->streaming_maxpacket);
+ if (bulk) {
+ opts->streaming_maxpacket =
+ clamp(opts->streaming_maxpacket, 1U, 1024U);
+ } else {
+ opts->streaming_maxpacket =
+ clamp(opts->streaming_maxpacket, 1U, 3072U);
+ /* For SS, wMaxPacketSize has to be 1024 if bMaxBurst is not 0 */
+ if (opts->streaming_maxburst &&
+ (opts->streaming_maxpacket % 1024) != 0) {
+ opts->streaming_maxpacket =
+ roundup(opts->streaming_maxpacket, 1024);
+ uvcg_info(f,
+ "overriding streaming_maxpacket to %d\n",
+ opts->streaming_maxpacket);
+ }
}
/*
@@ -677,37 +687,70 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
* NOTE: We assume that the user knows what they are doing and won't
* give parameters that their UDC doesn't support.
*/
- if (opts->streaming_maxpacket <= 1024) {
+ if (bulk) {
max_packet_mult = 1;
max_packet_size = opts->streaming_maxpacket;
- } else if (opts->streaming_maxpacket <= 2048) {
- max_packet_mult = 2;
- max_packet_size = opts->streaming_maxpacket / 2;
- } else {
- max_packet_mult = 3;
- max_packet_size = opts->streaming_maxpacket / 3;
- }
- uvc_fs_streaming_ep.wMaxPacketSize =
- cpu_to_le16(min(opts->streaming_maxpacket, 1023U));
- uvc_fs_streaming_ep.bInterval = opts->streaming_interval;
+ uvc_fs_streaming_ep.bmAttributes = USB_ENDPOINT_XFER_BULK;
+ uvc_hs_streaming_ep.bmAttributes = USB_ENDPOINT_XFER_BULK;
+ uvc_ss_streaming_ep.bmAttributes = USB_ENDPOINT_XFER_BULK;
- uvc_hs_streaming_ep.wMaxPacketSize =
- cpu_to_le16(max_packet_size | ((max_packet_mult - 1) << 11));
+ uvc_fs_streaming_ep.wMaxPacketSize =
+ cpu_to_le16(min(opts->streaming_maxpacket, 64U));
+ uvc_fs_streaming_ep.bInterval = 0;
- /* A high-bandwidth endpoint must specify a bInterval value of 1 */
- if (max_packet_mult > 1)
- uvc_hs_streaming_ep.bInterval = 1;
- else
- uvc_hs_streaming_ep.bInterval = opts->streaming_interval;
-
- uvc_ss_streaming_ep.wMaxPacketSize = cpu_to_le16(max_packet_size);
- uvc_ss_streaming_ep.bInterval = opts->streaming_interval;
- uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1;
- uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst;
- uvc_ss_streaming_comp.wBytesPerInterval =
- cpu_to_le16(max_packet_size * max_packet_mult *
- (opts->streaming_maxburst + 1));
+ uvc_hs_streaming_ep.wMaxPacketSize =
+ cpu_to_le16(min(opts->streaming_maxpacket, 512U));
+ uvc_hs_streaming_ep.bInterval = 0;
+
+ uvc_ss_streaming_ep.wMaxPacketSize =
+ cpu_to_le16(min(opts->streaming_maxpacket, 1024U));
+ uvc_ss_streaming_ep.bInterval = 0;
+ uvc_ss_streaming_comp.bmAttributes = 0;
+ uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst;
+ uvc_ss_streaming_comp.wBytesPerInterval = cpu_to_le16(0);
+ } else {
+ if (opts->streaming_maxpacket <= 1024) {
+ max_packet_mult = 1;
+ max_packet_size = opts->streaming_maxpacket;
+ } else if (opts->streaming_maxpacket <= 2048) {
+ max_packet_mult = 2;
+ max_packet_size = opts->streaming_maxpacket / 2;
+ } else {
+ max_packet_mult = 3;
+ max_packet_size = opts->streaming_maxpacket / 3;
+ }
+
+ uvc_fs_streaming_ep.bmAttributes =
+ USB_ENDPOINT_SYNC_ASYNC | USB_ENDPOINT_XFER_ISOC;
+ uvc_hs_streaming_ep.bmAttributes =
+ USB_ENDPOINT_SYNC_ASYNC | USB_ENDPOINT_XFER_ISOC;
+ uvc_ss_streaming_ep.bmAttributes =
+ USB_ENDPOINT_SYNC_ASYNC | USB_ENDPOINT_XFER_ISOC;
+
+ uvc_fs_streaming_ep.wMaxPacketSize =
+ cpu_to_le16(min(opts->streaming_maxpacket, 1023U));
+ uvc_fs_streaming_ep.bInterval = opts->streaming_interval;
+
+ uvc_hs_streaming_ep.wMaxPacketSize =
+ cpu_to_le16(max_packet_size |
+ ((max_packet_mult - 1) << 11));
+
+ /* A high-bandwidth endpoint must specify a bInterval value of 1 */
+ if (max_packet_mult > 1)
+ uvc_hs_streaming_ep.bInterval = 1;
+ else
+ uvc_hs_streaming_ep.bInterval = opts->streaming_interval;
+
+ uvc_ss_streaming_ep.wMaxPacketSize =
+ cpu_to_le16(max_packet_size);
+ uvc_ss_streaming_ep.bInterval = opts->streaming_interval;
+ uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1;
+ uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst;
+ uvc_ss_streaming_comp.wBytesPerInterval =
+ cpu_to_le16(max_packet_size * max_packet_mult *
+ (opts->streaming_maxburst + 1));
+ }
/* Allocate endpoints. */
if (opts->enable_interrupt_ep) {
diff --git a/drivers/usb/gadget/function/u_uvc.h b/drivers/usb/gadget/function/u_uvc.h
index 3ac392cbb779..b57e2d10ddcd 100644
--- a/drivers/usb/gadget/function/u_uvc.h
+++ b/drivers/usb/gadget/function/u_uvc.h
@@ -24,6 +24,7 @@ struct f_uvc_opts {
unsigned int streaming_interval;
unsigned int streaming_maxpacket;
unsigned int streaming_maxburst;
+ unsigned int streaming_bulk;
unsigned int control_interface;
unsigned int streaming_interface;
diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c
index a4a2d3dcb0d6..80817ff1b6fe 100644
--- a/drivers/usb/gadget/function/uvc_configfs.c
+++ b/drivers/usb/gadget/function/uvc_configfs.c
@@ -3751,6 +3751,7 @@ UVC_ATTR(f_uvc_opts_, cname, cname)
UVCG_OPTS_ATTR(streaming_interval, streaming_interval, 16);
UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, 3072);
UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, 15);
+UVCG_OPTS_ATTR(streaming_bulk, streaming_bulk, 1);
#undef UVCG_OPTS_ATTR
@@ -3800,6 +3801,7 @@ static struct configfs_attribute *uvc_attrs[] = {
&f_uvc_opts_attr_streaming_interval,
&f_uvc_opts_attr_streaming_maxpacket,
&f_uvc_opts_attr_streaming_maxburst,
+ &f_uvc_opts_attr_streaming_bulk,
&f_uvc_opts_string_attr_function_name,
NULL,
};