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

Unified · Split

3 files
  1. Documentation/usb/raw-gadget.rst +2 −3
  2. drivers/usb/gadget/legacy/raw_gadget.c +123 −64
  3. include/uapi/linux/usb/raw_gadget.h +69 −3
Documentation/usb/raw-gadget.rst+2−3
@@ -27,9 +27,8 @@ differences are: · 26 unmodified lines
273. Raw Gadget provides a way to select a UDC device/driver to bind to,273. Raw Gadget provides a way to select a UDC device/driver to bind to,
28 while GadgetFS currently binds to the first available UDC.28 while GadgetFS currently binds to the first available UDC.
29 29
304. Raw Gadget uses predictable endpoint names (handles) across different304. Raw Gadget explicitly exposes information about endpoints addresses and
31 UDCs (as long as UDCs have enough endpoints of each required transfer31 capabilities allowing a user to write UDC-agnostic gadgets.
32 type).
33 32
345. Raw Gadget has ioctl-based interface instead of a filesystem-based one.335. Raw Gadget has ioctl-based interface instead of a filesystem-based one.
35 34
drivers/usb/gadget/legacy/raw_gadget.c+123−64
@@ -7,6 +7,7 @@ · 6 unmodified lines
7 */7 */
8 8
9#include <linux/compiler.h>9#include <linux/compiler.h>
10#include <linux/ctype.h>
10#include <linux/debugfs.h>11#include <linux/debugfs.h>
11#include <linux/delay.h>12#include <linux/delay.h>
12#include <linux/kref.h>13#include <linux/kref.h>
@@ -123,8 +124,6 @@ static void raw_event_queue_destroy(struct raw_event_queue *queue) · 110 unmodified lines
123 124
124struct raw_dev;125struct raw_dev;
125 126
126#define USB_RAW_MAX_ENDPOINTS 32
127
128enum ep_state {127enum ep_state {
129 STATE_EP_DISABLED,128 STATE_EP_DISABLED,
130 STATE_EP_ENABLED,129 STATE_EP_ENABLED,
@@ -134,6 +133,7 @@ struct raw_ep { · 3 unmodified lines
134 struct raw_dev *dev;133 struct raw_dev *dev;
135 enum ep_state state;134 enum ep_state state;
136 struct usb_ep *ep;135 struct usb_ep *ep;
136 u8 addr;
137 struct usb_request *req;137 struct usb_request *req;
138 bool urb_queued;138 bool urb_queued;
139 bool disabling;139 bool disabling;
@@ -168,7 +168,8 @@ struct raw_dev { · 28 unmodified lines
168 bool ep0_out_pending;168 bool ep0_out_pending;
169 bool ep0_urb_queued;169 bool ep0_urb_queued;
170 ssize_t ep0_status;170 ssize_t ep0_status;
171 struct raw_ep eps[USB_RAW_MAX_ENDPOINTS];171 struct raw_ep eps[USB_RAW_EPS_NUM_MAX];
172 int eps_num;
172 173
173 struct completion ep0_done;174 struct completion ep0_done;
174 struct raw_event_queue queue;175 struct raw_event_queue queue;
@@ -202,7 +203,7 @@ static void dev_free(struct kref *kref) · 27 unmodified lines
202 usb_ep_free_request(dev->gadget->ep0, dev->req);203 usb_ep_free_request(dev->gadget->ep0, dev->req);
203 }204 }
204 raw_event_queue_destroy(&dev->queue);205 raw_event_queue_destroy(&dev->queue);
205 for (i = 0; i < USB_RAW_MAX_ENDPOINTS; i++) {206 for (i = 0; i < dev->eps_num; i++) {
206 if (dev->eps[i].state != STATE_EP_ENABLED)207 if (dev->eps[i].state != STATE_EP_ENABLED)
207 continue;208 continue;
208 usb_ep_disable(dev->eps[i].ep);209 usb_ep_disable(dev->eps[i].ep);
@@ -249,12 +250,26 @@ static void gadget_ep0_complete(struct usb_ep *ep, struct usb_request *req) · 40 unmodified lines
249 complete(&dev->ep0_done);250 complete(&dev->ep0_done);
250}251}
251 252
253static u8 get_ep_addr(const char *name)
254{
255 /* If the endpoint has fixed function (named as e.g. "ep12out-bulk"),
256 * parse the endpoint address from its name. We deliberately use
257 * deprecated simple_strtoul() function here, as the number isn't
258 * followed by '\0' nor '\n'.
259 */
260 if (isdigit(name[2]))
261 return simple_strtoul(&name[2], NULL, 10);
262 /* Otherwise the endpoint is configurable (named as e.g. "ep-a"). */
263 return USB_RAW_EP_ADDR_ANY;
264}
265
252static int gadget_bind(struct usb_gadget *gadget,266static int gadget_bind(struct usb_gadget *gadget,
253 struct usb_gadget_driver *driver)267 struct usb_gadget_driver *driver)
254{268{
255 int ret = 0;269 int ret = 0, i = 0;
256 struct raw_dev *dev = container_of(driver, struct raw_dev, driver);270 struct raw_dev *dev = container_of(driver, struct raw_dev, driver);
257 struct usb_request *req;271 struct usb_request *req;
272 struct usb_ep *ep;
258 unsigned long flags;273 unsigned long flags;
259 274
260 if (strcmp(gadget->name, dev->udc_name) != 0)275 if (strcmp(gadget->name, dev->udc_name) != 0)
@@ -273,6 +288,13 @@ static int gadget_bind(struct usb_gadget *gadget, · 12 unmodified lines
273 dev->req->context = dev;288 dev->req->context = dev;
274 dev->req->complete = gadget_ep0_complete;289 dev->req->complete = gadget_ep0_complete;
275 dev->gadget = gadget;290 dev->gadget = gadget;
291 gadget_for_each_ep(ep, dev->gadget) {
292 dev->eps[i].ep = ep;
293 dev->eps[i].addr = get_ep_addr(ep->name);
294 dev->eps[i].state = STATE_EP_DISABLED;
295 i++;
296 }
297 dev->eps_num = i;
276 spin_unlock_irqrestore(&dev->lock, flags);298 spin_unlock_irqrestore(&dev->lock, flags);
277 299
278 /* Matches kref_put() in gadget_unbind(). */300 /* Matches kref_put() in gadget_unbind(). */
@@ -555,7 +577,7 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr, · 276 unmodified lines
555 577
556 if (copy_from_user(io, ptr, sizeof(*io)))578 if (copy_from_user(io, ptr, sizeof(*io)))
557 return ERR_PTR(-EFAULT);579 return ERR_PTR(-EFAULT);
558 if (io->ep >= USB_RAW_MAX_ENDPOINTS)580 if (io->ep >= USB_RAW_EPS_NUM_MAX)
559 return ERR_PTR(-EINVAL);581 return ERR_PTR(-EINVAL);
560 if (!usb_raw_io_flags_valid(io->flags))582 if (!usb_raw_io_flags_valid(io->flags))
561 return ERR_PTR(-EINVAL);583 return ERR_PTR(-EINVAL);
@@ -682,40 +704,12 @@ free: · 120 unmodified lines
682 return ret;704 return ret;
683}705}
684 706
685static bool check_ep_caps(struct usb_ep *ep,
686 struct usb_endpoint_descriptor *desc)
687{
688 switch (usb_endpoint_type(desc)) {
689 case USB_ENDPOINT_XFER_ISOC:
690 if (!ep->caps.type_iso)
691 return false;
692 break;
693 case USB_ENDPOINT_XFER_BULK:
694 if (!ep->caps.type_bulk)
695 return false;
696 break;
697 case USB_ENDPOINT_XFER_INT:
698 if (!ep->caps.type_int)
699 return false;
700 break;
701 default:
702 return false;
703 }
704
705 if (usb_endpoint_dir_in(desc) && !ep->caps.dir_in)
706 return false;
707 if (usb_endpoint_dir_out(desc) && !ep->caps.dir_out)
708 return false;
709
710 return true;
711}
712
713static int raw_ioctl_ep_enable(struct raw_dev *dev, unsigned long value)707static int raw_ioctl_ep_enable(struct raw_dev *dev, unsigned long value)
714{708{
715 int ret = 0, i;709 int ret = 0, i;
716 unsigned long flags;710 unsigned long flags;
717 struct usb_endpoint_descriptor *desc;711 struct usb_endpoint_descriptor *desc;
718 struct usb_ep *ep = NULL;712 struct raw_ep *ep;
719 713
720 desc = memdup_user((void __user *)value, sizeof(*desc));714 desc = memdup_user((void __user *)value, sizeof(*desc));
721 if (IS_ERR(desc))715 if (IS_ERR(desc))
@@ -743,41 +737,32 @@ static int raw_ioctl_ep_enable(struct raw_dev *dev, unsigned long value) · 21 unmodified lines
743 goto out_free;737 goto out_free;
744 }738 }
745 739
746 for (i = 0; i < USB_RAW_MAX_ENDPOINTS; i++) {740 for (i = 0; i < dev->eps_num; i++) {
747 if (dev->eps[i].state == STATE_EP_ENABLED)741 ep = &dev->eps[i];
742 if (ep->state != STATE_EP_DISABLED)
748 continue;743 continue;
749 break;744 if (ep->addr != usb_endpoint_num(desc) &&
750 }745 ep->addr != USB_RAW_EP_ADDR_ANY)
751 if (i == USB_RAW_MAX_ENDPOINTS) {
752 dev_dbg(&dev->gadget->dev,
753 "fail, no device endpoints available\n");
754 ret = -EBUSY;
755 goto out_free;
756 }
757
758 gadget_for_each_ep(ep, dev->gadget) {
759 if (ep->enabled)
760 continue;746 continue;
761 if (!check_ep_caps(ep, desc))747 if (!usb_gadget_ep_match_desc(dev->gadget, ep->ep, desc, NULL))
762 continue;748 continue;
763 ep->desc = desc;749 ep->ep->desc = desc;
764 ret = usb_ep_enable(ep);750 ret = usb_ep_enable(ep->ep);
765 if (ret < 0) {751 if (ret < 0) {
766 dev_err(&dev->gadget->dev,752 dev_err(&dev->gadget->dev,
767 "fail, usb_ep_enable returned %d\n", ret);753 "fail, usb_ep_enable returned %d\n", ret);
768 goto out_free;754 goto out_free;
769 }755 }
770 dev->eps[i].req = usb_ep_alloc_request(ep, GFP_ATOMIC);756 ep->req = usb_ep_alloc_request(ep->ep, GFP_ATOMIC);
771 if (!dev->eps[i].req) {757 if (!ep->req) {
772 dev_err(&dev->gadget->dev,758 dev_err(&dev->gadget->dev,
773 "fail, usb_ep_alloc_request failed\n");759 "fail, usb_ep_alloc_request failed\n");
774 usb_ep_disable(ep);760 usb_ep_disable(ep->ep);
775 ret = -ENOMEM;761 ret = -ENOMEM;
776 goto out_free;762 goto out_free;
777 }763 }
778 dev->eps[i].ep = ep;764 ep->state = STATE_EP_ENABLED;
779 dev->eps[i].state = STATE_EP_ENABLED;765 ep->ep->driver_data = ep;
780 ep->driver_data = &dev->eps[i];
781 ret = i;766 ret = i;
782 goto out_unlock;767 goto out_unlock;
783 }768 }
@@ -796,10 +781,6 @@ static int raw_ioctl_ep_disable(struct raw_dev *dev, unsigned long value) · 12 unmodified lines
796{781{
797 int ret = 0, i = value;782 int ret = 0, i = value;
798 unsigned long flags;783 unsigned long flags;
799 const void *desc;
800
801 if (i < 0 || i >= USB_RAW_MAX_ENDPOINTS)
802 return -EINVAL;
803 784
804 spin_lock_irqsave(&dev->lock, flags);785 spin_lock_irqsave(&dev->lock, flags);
805 if (dev->state != STATE_DEV_RUNNING) {786 if (dev->state != STATE_DEV_RUNNING) {
@@ -812,6 +793,11 @@ static int raw_ioctl_ep_disable(struct raw_dev *dev, unsigned long value) · 6 unmodified lines
812 ret = -EBUSY;793 ret = -EBUSY;
813 goto out_unlock;794 goto out_unlock;
814 }795 }
796 if (i < 0 || i >= dev->eps_num) {
797 dev_dbg(dev->dev, "fail, invalid endpoint\n");
798 ret = -EBUSY;
799 goto out_unlock;
800 }
815 if (dev->eps[i].state != STATE_EP_ENABLED) {801 if (dev->eps[i].state != STATE_EP_ENABLED) {
816 dev_dbg(&dev->gadget->dev, "fail, endpoint is not enabled\n");802 dev_dbg(&dev->gadget->dev, "fail, endpoint is not enabled\n");
817 ret = -EINVAL;803 ret = -EINVAL;
@@ -836,10 +822,9 @@ static int raw_ioctl_ep_disable(struct raw_dev *dev, unsigned long value) · 18 unmodified lines
836 822
837 spin_lock_irqsave(&dev->lock, flags);823 spin_lock_irqsave(&dev->lock, flags);
838 usb_ep_free_request(dev->eps[i].ep, dev->eps[i].req);824 usb_ep_free_request(dev->eps[i].ep, dev->eps[i].req);
839 desc = dev->eps[i].ep->desc;825 kfree(dev->eps[i].ep->desc);
840 dev->eps[i].ep = NULL;826 dev->eps[i].ep = NULL;
841 dev->eps[i].state = STATE_EP_DISABLED;827 dev->eps[i].state = STATE_EP_DISABLED;
842 kfree(desc);
843 dev->eps[i].disabling = false;828 dev->eps[i].disabling = false;
844 829
845out_unlock:830out_unlock:
@@ -868,7 +853,7 @@ static int raw_process_ep_io(struct raw_dev *dev, struct usb_raw_ep_io *io, · 22 unmodified lines
868{853{
869 int ret = 0;854 int ret = 0;
870 unsigned long flags;855 unsigned long flags;
871 struct raw_ep *ep = &dev->eps[io->ep];856 struct raw_ep *ep;
872 DECLARE_COMPLETION_ONSTACK(done);857 DECLARE_COMPLETION_ONSTACK(done);
873 858
874 spin_lock_irqsave(&dev->lock, flags);859 spin_lock_irqsave(&dev->lock, flags);
@@ -882,6 +867,12 @@ static int raw_process_ep_io(struct raw_dev *dev, struct usb_raw_ep_io *io, · 7 unmodified lines
882 ret = -EBUSY;867 ret = -EBUSY;
883 goto out_unlock;868 goto out_unlock;
884 }869 }
870 if (io->ep >= dev->eps_num) {
871 dev_dbg(&dev->gadget->dev, "fail, invalid endpoint\n");
872 ret = -EINVAL;
873 goto out_unlock;
874 }
875 ep = &dev->eps[io->ep];
885 if (ep->state != STATE_EP_ENABLED) {876 if (ep->state != STATE_EP_ENABLED) {
886 dev_dbg(&dev->gadget->dev, "fail, endpoint is not enabled\n");877 dev_dbg(&dev->gadget->dev, "fail, endpoint is not enabled\n");
887 ret = -EBUSY;878 ret = -EBUSY;
@@ -1027,6 +1018,71 @@ out_unlock: · 139 unmodified lines
1027 return ret;1018 return ret;
1028}1019}
1029 1020
1021static void fill_ep_caps(struct usb_ep_caps *caps,
1022 struct usb_raw_ep_caps *raw_caps)
1023{
1024 raw_caps->type_control = caps->type_control;
1025 raw_caps->type_iso = caps->type_iso;
1026 raw_caps->type_bulk = caps->type_bulk;
1027 raw_caps->type_int = caps->type_int;
1028 raw_caps->dir_in = caps->dir_in;
1029 raw_caps->dir_out = caps->dir_out;
1030}
1031
1032static void fill_ep_limits(struct usb_ep *ep, struct usb_raw_ep_limits *limits)
1033{
1034 limits->maxpacket_limit = ep->maxpacket_limit;
1035 limits->max_streams = ep->max_streams;
1036}
1037
1038static int raw_ioctl_eps_info(struct raw_dev *dev, unsigned long value)
1039{
1040 int ret = 0, i;
1041 unsigned long flags;
1042 struct usb_raw_eps_info *info;
1043 struct raw_ep *ep;
1044
1045 info = kmalloc(sizeof(*info), GFP_KERNEL);
1046 if (!info) {
1047 ret = -ENOMEM;
1048 goto out;
1049 }
1050
1051 spin_lock_irqsave(&dev->lock, flags);
1052 if (dev->state != STATE_DEV_RUNNING) {
1053 dev_dbg(dev->dev, "fail, device is not running\n");
1054 ret = -EINVAL;
1055 spin_unlock_irqrestore(&dev->lock, flags);
1056 goto out_free;
1057 }
1058 if (!dev->gadget) {
1059 dev_dbg(dev->dev, "fail, gadget is not bound\n");
1060 ret = -EBUSY;
1061 spin_unlock_irqrestore(&dev->lock, flags);
1062 goto out_free;
1063 }
1064
1065 memset(info, 0, sizeof(*info));
1066 for (i = 0; i < dev->eps_num; i++) {
1067 ep = &dev->eps[i];
1068 strscpy(&info->eps[i].name[0], ep->ep->name,
1069 USB_RAW_EP_NAME_MAX);
1070 info->eps[i].addr = ep->addr;
1071 fill_ep_caps(&ep->ep->caps, &info->eps[i].caps);
1072 fill_ep_limits(ep->ep, &info->eps[i].limits);
1073 }
1074 ret = dev->eps_num;
1075 spin_unlock_irqrestore(&dev->lock, flags);
1076
1077 if (copy_to_user((void __user *)value, info, sizeof(*info)))
1078 ret = -EFAULT;
1079
1080out_free:
1081 kfree(info);
1082out:
1083 return ret;
1084}
1085
1030static long raw_ioctl(struct file *fd, unsigned int cmd, unsigned long value)1086static long raw_ioctl(struct file *fd, unsigned int cmd, unsigned long value)
1031{1087{
1032 struct raw_dev *dev = fd->private_data;1088 struct raw_dev *dev = fd->private_data;
@@ -1069,6 +1125,9 @@ static long raw_ioctl(struct file *fd, unsigned int cmd, unsigned long value) · 36 unmodified lines
1069 case USB_RAW_IOCTL_VBUS_DRAW:1125 case USB_RAW_IOCTL_VBUS_DRAW:
1070 ret = raw_ioctl_vbus_draw(dev, value);1126 ret = raw_ioctl_vbus_draw(dev, value);
1071 break;1127 break;
1128 case USB_RAW_IOCTL_EPS_INFO:
1129 ret = raw_ioctl_eps_info(dev, value);
1130 break;
1072 default:1131 default:
1073 ret = -EINVAL;1132 ret = -EINVAL;
1074 }1133 }
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 */