History

usb: raw-gadget: fix gadget endpoint selection

Currently automatic gadget endpoint selection based on required features doesn't work. Raw Gadget tries iterating over the list of available endpoints and finding one that has the right direction and transfer type. Unfortunately selecting arbitrary gadget endpoints (even if they satisfy feature requirements) doesn't work, as (depending on the UDC driver) they might have fixed addresses, and one also needs to provide matching endpoint addresses in the descriptors sent to the host. The composite framework deals with this by assigning endpoint addresses in usb_ep_autoconfig() before enumeration starts. This approach won't work with Raw Gadget as the endpoints are supposed to be enabled after a set_configuration/set_interface request from the host, so it's too late to patch the endpoint descriptors that had already been sent to the host. For Raw Gadget we take another approach. Similarly to GadgetFS, we allow the user to make the decision as to which gadget endpoints to use. This patch adds another Raw Gadget ioctl USB_RAW_IOCTL_EPS_INFO that exposes information about all non-control endpoints that a currently connected UDC has. This information includes endpoints addresses, as well as their capabilities and limits to allow the user to choose the most fitting gadget endpoint. The USB_RAW_IOCTL_EP_ENABLE ioctl is updated to use the proper endpoint validation routine usb_gadget_ep_match_desc(). These changes affect the portability of the gadgets that use Raw Gadget when running on different UDCs. Nevertheless, as long as the user relies on the information provided by USB_RAW_IOCTL_EPS_INFO to dynamically choose endpoint addresses, UDC-agnostic gadgets can still be written with Raw Gadget.

Andrey Konovalov committed 6 years ago

Commit 97df5e51 parent 17ff3b73 files · +194 −70Browse files

Showing the changes to include/uapi (1 of 3 files). Show all

Unified · Split

include/uapi/linux/usb/raw_gadget.h+69−3
@@ -93,6 +93,64 @@ struct usb_raw_ep_io { · 92 unmodified lines
93 __u8 data[0];93 __u8 data[0];
94};94};
95 95
96/* Maximum number of non-control endpoints in struct usb_raw_eps_info. */
97#define USB_RAW_EPS_NUM_MAX 30
98
99/* Maximum length of UDC endpoint name in struct usb_raw_ep_info. */
100#define USB_RAW_EP_NAME_MAX 16
101
102/* Used as addr in struct usb_raw_ep_info if endpoint accepts any address. */
103#define USB_RAW_EP_ADDR_ANY 0xff
104
105/*
106 * struct usb_raw_ep_caps - exposes endpoint capabilities from struct usb_ep
107 * (technically from its member struct usb_ep_caps).
108 */
109struct usb_raw_ep_caps {
110 __u32 type_control : 1;
111 __u32 type_iso : 1;
112 __u32 type_bulk : 1;
113 __u32 type_int : 1;
114 __u32 dir_in : 1;
115 __u32 dir_out : 1;
116};
117
118/*
119 * struct usb_raw_ep_limits - exposes endpoint limits from struct usb_ep.
120 * @maxpacket_limit: Maximum packet size value supported by this endpoint.
121 * @max_streams: maximum number of streams supported by this endpoint
122 * (actual number is 2^n).
123 * @reserved: Empty, reserved for potential future extensions.
124 */
125struct usb_raw_ep_limits {
126 __u16 maxpacket_limit;
127 __u16 max_streams;
128 __u32 reserved;
129};
130
131/*
132 * struct usb_raw_ep_info - stores information about a gadget endpoint.
133 * @name: Name of the endpoint as it is defined in the UDC driver.
134 * @addr: Address of the endpoint that must be specified in the endpoint
135 * descriptor passed to USB_RAW_IOCTL_EP_ENABLE ioctl.
136 * @caps: Endpoint capabilities.
137 * @limits: Endpoint limits.
138 */
139struct usb_raw_ep_info {
140 __u8 name[USB_RAW_EP_NAME_MAX];
141 __u32 addr;
142 struct usb_raw_ep_caps caps;
143 struct usb_raw_ep_limits limits;
144};
145
146/*
147 * struct usb_raw_eps_info - argument for USB_RAW_IOCTL_EPS_INFO ioctl.
148 * eps: Structures that store information about non-control endpoints.
149 */
150struct usb_raw_eps_info {
151 struct usb_raw_ep_info eps[USB_RAW_EPS_NUM_MAX];
152};
153
96/*154/*
97 * Initializes a Raw Gadget instance.155 * Initializes a Raw Gadget instance.
98 * Accepts a pointer to the usb_raw_init struct as an argument.156 * Accepts a pointer to the usb_raw_init struct as an argument.
@@ -126,9 +184,9 @@ struct usb_raw_ep_io { · 27 unmodified lines
126#define USB_RAW_IOCTL_EP0_READ _IOWR('U', 4, struct usb_raw_ep_io)184#define USB_RAW_IOCTL_EP0_READ _IOWR('U', 4, struct usb_raw_ep_io)
127 185
128/*186/*
129 * Finds an endpoint that supports the transfer type specified in the187 * Finds an endpoint that satisfies the parameters specified in the provided
130 * descriptor and enables it.188 * descriptors (address, transfer type, etc.) and enables it.
131 * Accepts a pointer to the usb_endpoint_descriptor struct as an argument.189 * Accepts a pointer to the usb_raw_ep_descs struct as an argument.
132 * Returns enabled endpoint handle on success or negative error code on failure.190 * Returns enabled endpoint handle on success or negative error code on failure.
133 */191 */
134#define USB_RAW_IOCTL_EP_ENABLE _IOW('U', 5, struct usb_endpoint_descriptor)192#define USB_RAW_IOCTL_EP_ENABLE _IOW('U', 5, struct usb_endpoint_descriptor)
@@ -165,4 +223,12 @@ struct usb_raw_ep_io { · 30 unmodified lines
165 */223 */
166#define USB_RAW_IOCTL_VBUS_DRAW _IOW('U', 10, __u32)224#define USB_RAW_IOCTL_VBUS_DRAW _IOW('U', 10, __u32)
167 225
226/*
227 * Fills in the usb_raw_eps_info structure with information about non-control
228 * endpoints available for the currently connected UDC.
229 * Returns the number of available endpoints on success or negative error code
230 * on failure.
231 */
232#define USB_RAW_IOCTL_EPS_INFO _IOR('U', 11, struct usb_raw_eps_info)
233
168#endif /* _UAPI__LINUX_USB_RAW_GADGET_H */234#endif /* _UAPI__LINUX_USB_RAW_GADGET_H */