diff options
Diffstat (limited to 'drivers/usb/gadget/f_sourcesink.c')
-rw-r--r-- | drivers/usb/gadget/f_sourcesink.c | 71 |
1 files changed, 64 insertions, 7 deletions
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index e403a534dd55..e18b4f520951 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c | |||
@@ -131,6 +131,49 @@ static struct usb_descriptor_header *hs_source_sink_descs[] = { | |||
131 | NULL, | 131 | NULL, |
132 | }; | 132 | }; |
133 | 133 | ||
134 | /* super speed support: */ | ||
135 | |||
136 | static struct usb_endpoint_descriptor ss_source_desc = { | ||
137 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
138 | .bDescriptorType = USB_DT_ENDPOINT, | ||
139 | |||
140 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
141 | .wMaxPacketSize = cpu_to_le16(1024), | ||
142 | }; | ||
143 | |||
144 | struct usb_ss_ep_comp_descriptor ss_source_comp_desc = { | ||
145 | .bLength = USB_DT_SS_EP_COMP_SIZE, | ||
146 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
147 | .bMaxBurst = 0, | ||
148 | .bmAttributes = 0, | ||
149 | .wBytesPerInterval = 0, | ||
150 | }; | ||
151 | |||
152 | static struct usb_endpoint_descriptor ss_sink_desc = { | ||
153 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
154 | .bDescriptorType = USB_DT_ENDPOINT, | ||
155 | |||
156 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
157 | .wMaxPacketSize = cpu_to_le16(1024), | ||
158 | }; | ||
159 | |||
160 | struct usb_ss_ep_comp_descriptor ss_sink_comp_desc = { | ||
161 | .bLength = USB_DT_SS_EP_COMP_SIZE, | ||
162 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
163 | .bMaxBurst = 0, | ||
164 | .bmAttributes = 0, | ||
165 | .wBytesPerInterval = 0, | ||
166 | }; | ||
167 | |||
168 | static struct usb_descriptor_header *ss_source_sink_descs[] = { | ||
169 | (struct usb_descriptor_header *) &source_sink_intf, | ||
170 | (struct usb_descriptor_header *) &ss_source_desc, | ||
171 | (struct usb_descriptor_header *) &ss_source_comp_desc, | ||
172 | (struct usb_descriptor_header *) &ss_sink_desc, | ||
173 | (struct usb_descriptor_header *) &ss_sink_comp_desc, | ||
174 | NULL, | ||
175 | }; | ||
176 | |||
134 | /* function-specific strings: */ | 177 | /* function-specific strings: */ |
135 | 178 | ||
136 | static struct usb_string strings_sourcesink[] = { | 179 | static struct usb_string strings_sourcesink[] = { |
@@ -187,8 +230,18 @@ autoconf_fail: | |||
187 | f->hs_descriptors = hs_source_sink_descs; | 230 | f->hs_descriptors = hs_source_sink_descs; |
188 | } | 231 | } |
189 | 232 | ||
233 | /* support super speed hardware */ | ||
234 | if (gadget_is_superspeed(c->cdev->gadget)) { | ||
235 | ss_source_desc.bEndpointAddress = | ||
236 | fs_source_desc.bEndpointAddress; | ||
237 | ss_sink_desc.bEndpointAddress = | ||
238 | fs_sink_desc.bEndpointAddress; | ||
239 | f->ss_descriptors = ss_source_sink_descs; | ||
240 | } | ||
241 | |||
190 | DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", | 242 | DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", |
191 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | 243 | (gadget_is_superspeed(c->cdev->gadget) ? "super" : |
244 | (gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")), | ||
192 | f->name, ss->in_ep->name, ss->out_ep->name); | 245 | f->name, ss->in_ep->name, ss->out_ep->name); |
193 | return 0; | 246 | return 0; |
194 | } | 247 | } |
@@ -343,15 +396,14 @@ static int | |||
343 | enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss) | 396 | enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss) |
344 | { | 397 | { |
345 | int result = 0; | 398 | int result = 0; |
346 | const struct usb_endpoint_descriptor *src, *sink; | ||
347 | struct usb_ep *ep; | 399 | struct usb_ep *ep; |
348 | 400 | ||
349 | src = ep_choose(cdev->gadget, &hs_source_desc, &fs_source_desc); | ||
350 | sink = ep_choose(cdev->gadget, &hs_sink_desc, &fs_sink_desc); | ||
351 | |||
352 | /* one endpoint writes (sources) zeroes IN (to the host) */ | 401 | /* one endpoint writes (sources) zeroes IN (to the host) */ |
353 | ep = ss->in_ep; | 402 | ep = ss->in_ep; |
354 | result = usb_ep_enable(ep, src); | 403 | result = config_ep_by_speed(cdev->gadget, &(ss->function), ep); |
404 | if (result) | ||
405 | return result; | ||
406 | result = usb_ep_enable(ep); | ||
355 | if (result < 0) | 407 | if (result < 0) |
356 | return result; | 408 | return result; |
357 | ep->driver_data = ss; | 409 | ep->driver_data = ss; |
@@ -367,7 +419,10 @@ fail: | |||
367 | 419 | ||
368 | /* one endpoint reads (sinks) anything OUT (from the host) */ | 420 | /* one endpoint reads (sinks) anything OUT (from the host) */ |
369 | ep = ss->out_ep; | 421 | ep = ss->out_ep; |
370 | result = usb_ep_enable(ep, sink); | 422 | result = config_ep_by_speed(cdev->gadget, &(ss->function), ep); |
423 | if (result) | ||
424 | goto fail; | ||
425 | result = usb_ep_enable(ep); | ||
371 | if (result < 0) | 426 | if (result < 0) |
372 | goto fail; | 427 | goto fail; |
373 | ep->driver_data = ss; | 428 | ep->driver_data = ss; |
@@ -435,6 +490,8 @@ static int sourcesink_setup(struct usb_configuration *c, | |||
435 | u16 w_value = le16_to_cpu(ctrl->wValue); | 490 | u16 w_value = le16_to_cpu(ctrl->wValue); |
436 | u16 w_length = le16_to_cpu(ctrl->wLength); | 491 | u16 w_length = le16_to_cpu(ctrl->wLength); |
437 | 492 | ||
493 | req->length = USB_BUFSIZ; | ||
494 | |||
438 | /* composite driver infrastructure handles everything except | 495 | /* composite driver infrastructure handles everything except |
439 | * the two control test requests. | 496 | * the two control test requests. |
440 | */ | 497 | */ |