summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_sourcesink.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-25 23:08:32 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-25 23:08:32 -0700
commitf549953c15deab4c54708b39af86d4edecc6cddc (patch)
treef0412f989b77cdceab34c18aa85a8a25d5942a1f /drivers/usb/gadget/f_sourcesink.c
parentf0deb97ab13ad1f89cd0993f7339655d59788405 (diff)
parente04f5f7e423018bcec84c11af2058cdce87816f3 (diff)
downloadtalos-obmc-linux-f549953c15deab4c54708b39af86d4edecc6cddc.tar.gz
talos-obmc-linux-f549953c15deab4c54708b39af86d4edecc6cddc.zip
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (115 commits) EHCI: fix direction handling for interrupt data toggles USB: serial: add IDs for WinChipHead USB->RS232 adapter USB: OHCI: fix another regression for NVIDIA controllers usb: gadget: m66592-udc: add pullup function usb: gadget: m66592-udc: add function for external controller usb: gadget: r8a66597-udc: add pullup function usb: renesas_usbhs: support multi driver usb: renesas_usbhs: inaccessible pipe is not an error usb: renesas_usbhs: care buff alignment when dma handler USB: PL2303: correctly handle baudrates above 115200 usb: r8a66597-hcd: fixup USB_PORT_STAT_C_SUSPEND shift usb: renesas_usbhs: compile/config are rescued usb: renesas_usbhs: fixup comment-out usb: update email address in ohci-sh and r8a66597-hcd usb: r8a66597-hcd: add function for external controller EHCI: only power off port if over-current is active USB: mon: Allow to use usbmon without debugfs USB: EHCI: go back to using the system clock for QH unlinks ehci: add pci quirk for Ordissimo and RM Slate 100 too ehci: refactor pci quirk to use standard dmi_check_system method ... Fix up trivial conflicts in Documentation/feature-removal-schedule.txt
Diffstat (limited to 'drivers/usb/gadget/f_sourcesink.c')
-rw-r--r--drivers/usb/gadget/f_sourcesink.c71
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[] = {
NULL,
};
+/* super speed support: */
+
+static struct usb_endpoint_descriptor ss_source_desc = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = cpu_to_le16(1024),
+};
+
+struct usb_ss_ep_comp_descriptor ss_source_comp_desc = {
+ .bLength = USB_DT_SS_EP_COMP_SIZE,
+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
+ .bMaxBurst = 0,
+ .bmAttributes = 0,
+ .wBytesPerInterval = 0,
+};
+
+static struct usb_endpoint_descriptor ss_sink_desc = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = cpu_to_le16(1024),
+};
+
+struct usb_ss_ep_comp_descriptor ss_sink_comp_desc = {
+ .bLength = USB_DT_SS_EP_COMP_SIZE,
+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
+ .bMaxBurst = 0,
+ .bmAttributes = 0,
+ .wBytesPerInterval = 0,
+};
+
+static struct usb_descriptor_header *ss_source_sink_descs[] = {
+ (struct usb_descriptor_header *) &source_sink_intf,
+ (struct usb_descriptor_header *) &ss_source_desc,
+ (struct usb_descriptor_header *) &ss_source_comp_desc,
+ (struct usb_descriptor_header *) &ss_sink_desc,
+ (struct usb_descriptor_header *) &ss_sink_comp_desc,
+ NULL,
+};
+
/* function-specific strings: */
static struct usb_string strings_sourcesink[] = {
@@ -187,8 +230,18 @@ autoconf_fail:
f->hs_descriptors = hs_source_sink_descs;
}
+ /* support super speed hardware */
+ if (gadget_is_superspeed(c->cdev->gadget)) {
+ ss_source_desc.bEndpointAddress =
+ fs_source_desc.bEndpointAddress;
+ ss_sink_desc.bEndpointAddress =
+ fs_sink_desc.bEndpointAddress;
+ f->ss_descriptors = ss_source_sink_descs;
+ }
+
DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
- gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
+ (gadget_is_superspeed(c->cdev->gadget) ? "super" :
+ (gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")),
f->name, ss->in_ep->name, ss->out_ep->name);
return 0;
}
@@ -343,15 +396,14 @@ static int
enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss)
{
int result = 0;
- const struct usb_endpoint_descriptor *src, *sink;
struct usb_ep *ep;
- src = ep_choose(cdev->gadget, &hs_source_desc, &fs_source_desc);
- sink = ep_choose(cdev->gadget, &hs_sink_desc, &fs_sink_desc);
-
/* one endpoint writes (sources) zeroes IN (to the host) */
ep = ss->in_ep;
- result = usb_ep_enable(ep, src);
+ result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
+ if (result)
+ return result;
+ result = usb_ep_enable(ep);
if (result < 0)
return result;
ep->driver_data = ss;
@@ -367,7 +419,10 @@ fail:
/* one endpoint reads (sinks) anything OUT (from the host) */
ep = ss->out_ep;
- result = usb_ep_enable(ep, sink);
+ result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
+ if (result)
+ goto fail;
+ result = usb_ep_enable(ep);
if (result < 0)
goto fail;
ep->driver_data = ss;
@@ -435,6 +490,8 @@ static int sourcesink_setup(struct usb_configuration *c,
u16 w_value = le16_to_cpu(ctrl->wValue);
u16 w_length = le16_to_cpu(ctrl->wLength);
+ req->length = USB_BUFSIZ;
+
/* composite driver infrastructure handles everything except
* the two control test requests.
*/
OpenPOWER on IntegriCloud