aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/composite.c
diff options
context:
space:
mode:
authorTatyana Brokhman <tlinder@codeaurora.org>2011-06-28 09:33:49 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-28 14:14:36 -0400
commit48767a4e8263620c347c3fa17812c943dd0fc2fa (patch)
tree2859b92667049c57cae1c6ca02fd7897d6f3534f /drivers/usb/gadget/composite.c
parent72c973dd2b01b212a159faa330a2bc641a3ed809 (diff)
usb: gadget: configure endpoint according to gadget speed
Add config_ep_by_speed() to configure the endpoint according to the gadget speed. Using this function will spare the FDs from handling the endpoint chosen descriptor. Signed-off-by: Tatyana Brokhman <tlinder@codeaurora.org> Signed-off-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/composite.c')
-rw-r--r--drivers/usb/gadget/composite.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 5cbb1a41c223..1c6bd666150a 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -74,6 +74,91 @@ MODULE_PARM_DESC(iSerialNumber, "SerialNumber string");
74static char composite_manufacturer[50]; 74static char composite_manufacturer[50];
75 75
76/*-------------------------------------------------------------------------*/ 76/*-------------------------------------------------------------------------*/
77/**
78 * next_ep_desc() - advance to the next EP descriptor
79 * @t: currect pointer within descriptor array
80 *
81 * Return: next EP descriptor or NULL
82 *
83 * Iterate over @t until either EP descriptor found or
84 * NULL (that indicates end of list) encountered
85 */
86static struct usb_descriptor_header**
87next_ep_desc(struct usb_descriptor_header **t)
88{
89 for (; *t; t++) {
90 if ((*t)->bDescriptorType == USB_DT_ENDPOINT)
91 return t;
92 }
93 return NULL;
94}
95
96/*
97 * for_each_ep_desc()- iterate over endpoint descriptors in the
98 * descriptors list
99 * @start: pointer within descriptor array.
100 * @ep_desc: endpoint descriptor to use as the loop cursor
101 */
102#define for_each_ep_desc(start, ep_desc) \
103 for (ep_desc = next_ep_desc(start); \
104 ep_desc; ep_desc = next_ep_desc(ep_desc+1))
105
106/**
107 * config_ep_by_speed() - configures the given endpoint
108 * according to gadget speed.
109 * @g: pointer to the gadget
110 * @f: usb function
111 * @_ep: the endpoint to configure
112 *
113 * Return: error code, 0 on success
114 *
115 * This function chooses the right descriptors for a given
116 * endpoint according to gadget speed and saves it in the
117 * endpoint desc field. If the endpoint already has a descriptor
118 * assigned to it - overwrites it with currently corresponding
119 * descriptor. The endpoint maxpacket field is updated according
120 * to the chosen descriptor.
121 * Note: the supplied function should hold all the descriptors
122 * for supported speeds
123 */
124int config_ep_by_speed(struct usb_gadget *g,
125 struct usb_function *f,
126 struct usb_ep *_ep)
127{
128 struct usb_endpoint_descriptor *chosen_desc = NULL;
129 struct usb_descriptor_header **speed_desc = NULL;
130
131 struct usb_descriptor_header **d_spd; /* cursor for speed desc */
132
133 if (!g || !f || !_ep)
134 return -EIO;
135
136 /* select desired speed */
137 switch (g->speed) {
138 case USB_SPEED_HIGH:
139 if (gadget_is_dualspeed(g)) {
140 speed_desc = f->hs_descriptors;
141 break;
142 }
143 /* else: fall through */
144 default:
145 speed_desc = f->descriptors;
146 }
147 /* find descriptors */
148 for_each_ep_desc(speed_desc, d_spd) {
149 chosen_desc = (struct usb_endpoint_descriptor *)*d_spd;
150 if (chosen_desc->bEndpointAddress == _ep->address)
151 goto ep_found;
152 }
153 return -EIO;
154
155ep_found:
156 /* commit results */
157 _ep->maxpacket = le16_to_cpu(chosen_desc->wMaxPacketSize);
158 _ep->desc = chosen_desc;
159
160 return 0;
161}
77 162
78/** 163/**
79 * usb_add_function() - add a function to a configuration 164 * usb_add_function() - add a function to a configuration