From: Tatyana Brokhman <tlinder-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
To: greg-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
balbi-l0cyMroinI0@public.gmane.org,
ablay-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
Tatyana Brokhman
<tlinder-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>,
open list <linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Subject: [PATCH v9 6/7] usb:gadget: Introduce usb_generate_ss_descriptors()
Date: Sun, 8 May 2011 14:16:47 +0300 [thread overview]
Message-ID: <1304853414-10234-7-git-send-email-tlinder@codeaurora.org> (raw)
In-Reply-To: <1304853414-10234-1-git-send-email-tlinder-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
This patch implements the usb_generate_ss_descriptors() function that is
used to automatically generate SuperSpeed descriptors for gadget drivers
that didn't provide any of their own. If a gadget driver wishes to have
the SuperSpeed descriptors generated for it, it should set the
function->generate_ss_desc flag to 1.
This patch is not to be mainlined since in the long run we want all gadget
drivers that wish to operate in SuperSpeed connection to provide their own
SupeSpeed descriptors. The purpose of this patch is to assist developers
in the early stages of their work.
Signed-off-by: Tatyana Brokhman <tlinder-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
---
drivers/usb/gadget/composite.c | 137 +++++++++++++++++++++++++++++++++++++++-
include/linux/usb/composite.h | 4 +
2 files changed, 140 insertions(+), 1 deletions(-)
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index a622af5..546c0b3 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -74,6 +74,127 @@ MODULE_PARM_DESC(iSerialNumber, "SerialNumber string");
static char composite_manufacturer[50];
+/*
+ * Default endpoint companion descriptor:
+ * Bursting is not supported
+ * Streaming is not supported
+ */
+static struct usb_ss_ep_comp_descriptor default_ep_comp_desc = {
+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
+ .bLength = USB_DT_SS_EP_COMP_SIZE,
+ .bMaxBurst = 0,
+ .bmAttributes = 0,
+ .wBytesPerInterval = 0,
+};
+
+/**
+ * usb_generate_ss_descriptors() - Generate SuperSpeed
+ * descriptors with default values
+ * @f: pointer to usb_function to generate the descriptors for
+ *
+ * This function receives a pointer to usb_function and adds
+ * missing super speed descriptors in the ss_descriptor field
+ * according to its hs_descriptors field.
+ *
+ * This function copies f->hs_descriptors while updating the
+ * endpoint descriptor and adding endpoint companion descriptor.
+ */
+static void usb_generate_ss_descriptors(struct usb_function *f)
+{
+
+ struct usb_ss_ep_comp_descriptor *ep_comp_desc;
+ struct usb_endpoint_descriptor *ep_desc ;
+ struct usb_descriptor_header **tmp;
+ struct usb_descriptor_header **src = f->hs_descriptors;
+ unsigned bytes;
+ unsigned n_desc;
+ void *mem;
+
+ if (!f->hs_descriptors)
+ return;
+
+ /*
+ * Count number of EPs (in order to know how many SS_EP_COMPANION
+ * descriptors to add), the total number of descriptors and the sum of
+ * each descriptor bLength field in order to know how much memory to
+ * allocate.
+ */
+ for (bytes = 0, n_desc = 0, tmp = src; *tmp; tmp++, n_desc++) {
+ if ((*tmp)->bDescriptorType == USB_DT_ENDPOINT) {
+ bytes += default_ep_comp_desc.bLength;
+ n_desc++;
+ }
+ bytes += (*tmp)->bLength;
+ }
+
+ bytes += (n_desc + 1) * sizeof(*tmp);
+ mem = kmalloc(bytes, GFP_KERNEL);
+ if (!mem)
+ return;
+
+ /*
+ * Fill in pointers starting at "tmp", to descriptors copied starting
+ * at "mem" and return "ret"
+ */
+ tmp = mem;
+ f->ss_descriptors = mem;
+ mem += (n_desc + 1) * sizeof(*tmp);
+ while (*src) {
+ /* Copy the original descriptor */
+ memcpy(mem, *src, (*src)->bLength);
+ switch ((*src)->bDescriptorType) {
+ case USB_DT_ENDPOINT:
+ /* update ep descriptor */
+ ep_desc = (struct usb_endpoint_descriptor *)mem;
+ switch (ep_desc->bmAttributes &
+ USB_ENDPOINT_XFERTYPE_MASK) {
+ case USB_ENDPOINT_XFER_CONTROL:
+ ep_desc->wMaxPacketSize = cpu_to_le16(512);
+ ep_desc->bInterval = 0;
+ break;
+ case USB_ENDPOINT_XFER_BULK:
+ ep_desc->wMaxPacketSize = cpu_to_le16(1024);
+ ep_desc->bInterval = 0;
+ break;
+ case USB_ENDPOINT_XFER_INT:
+ case USB_ENDPOINT_XFER_ISOC:
+ break;
+ }
+ *tmp = mem;
+ tmp++;
+ mem += (*src)->bLength;
+ /* add ep companion descriptor */
+ memcpy(mem, &default_ep_comp_desc,
+ default_ep_comp_desc.bLength);
+ *tmp = mem;
+ tmp++;
+ /* Update wBytesPerInterval for periodic endpoints */
+ ep_comp_desc = mem;
+ switch (ep_desc->bmAttributes &
+ USB_ENDPOINT_XFERTYPE_MASK) {
+ case USB_ENDPOINT_XFER_INT:
+ case USB_ENDPOINT_XFER_ISOC:
+ ep_comp_desc->wBytesPerInterval =
+ ep_desc->wMaxPacketSize;
+ break;
+ }
+ mem += default_ep_comp_desc.bLength;
+ break;
+ default:
+ *tmp = mem;
+ tmp++;
+ mem += (*src)->bLength;
+ break;
+ }
+ src++;
+ }
+ /*
+ * The last (struct usb_descriptor_header *) in the descriptors
+ * vector is NULL
+ */
+ *tmp = NULL;
+}
+
/*-------------------------------------------------------------------------*/
/**
* next_ep_desc() - advance to the next EP descriptor
@@ -231,6 +352,14 @@ int usb_add_function(struct usb_configuration *config,
list_del(&function->list);
function->config = NULL;
}
+ /*
+ * Add SS descriptors if there aren't any. This has to be done
+ * after the bind since we need the hs_descriptors to be set in
+ * usb_function and some of the FDs does it in the bind.
+ */
+ if ((gadget_is_superspeed(config->cdev->gadget)) &&
+ (function->generate_ss_desc) && (!function->ss_descriptors))
+ usb_generate_ss_descriptors(function);
} else
value = 0;
@@ -1314,12 +1443,18 @@ composite_unbind(struct usb_gadget *gadget)
f = list_first_entry(&c->functions,
struct usb_function, list);
list_del(&f->list);
+ /*
+ * Free memory for SS descriptors if they were
+ * automaticaly generated
+ */
+ if (f->generate_ss_desc)
+ usb_free_descriptors(f->ss_descriptors);
if (f->unbind) {
DBG(cdev, "unbind function '%s'/%p\n",
f->name, f);
f->unbind(c, f);
- /* may free memory for "f" */
}
+ /* may free memory for "f" */
}
list_del(&c->list);
if (c->unbind) {
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 274c084..ae385da 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -57,6 +57,8 @@ struct usb_configuration;
* default values while working in superspeed mode. If this
* pointer is null after initiation, the function will not
* be available at super speed.
+ * @generate_ss_desc: This flag is used by the FD to indicate that it wishes
+ * SS descriptors to be automatically generated for it.
* @config: assigned when @usb_add_function() is called; this is the
* configuration with which this function is associated.
* @bind: Before the gadget can register, all of its functions bind() to the
@@ -110,6 +112,8 @@ struct usb_function {
struct usb_descriptor_header **hs_descriptors;
struct usb_descriptor_header **ss_descriptors;
+ unsigned generate_ss_desc:1;
+
struct usb_configuration *config;
/* REVISIT: bind() functions can be marked __init, which
--
1.7.3.3
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2011-05-08 11:16 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-08 11:16 [PATCH v9 0/7] usb gadget: Add SuperSpeed support to the Gadget Framework Tatyana Brokhman
2011-05-08 11:16 ` [PATCH v9 1/7] usb: Add usb_endpoint_descriptor to be part of the struct usb_ep Tatyana Brokhman
2011-05-08 11:16 ` [PATCH v9 2/7] usb: Configure endpoint according to gadget speed Tatyana Brokhman
2011-05-08 11:16 ` [PATCH v9 3/7] usb: Modify existing gadget drivers to use config_ep_by_speed() instead of ep_choose Tatyana Brokhman
2011-05-08 11:16 ` [PATCH v9 4/7] usb:gadget: Add SuperSpeed support to the Gadget Framework Tatyana Brokhman
2011-05-09 9:19 ` Felipe Balbi
2011-05-11 13:00 ` Tanya Brokhman
[not found] ` <1304853414-10234-1-git-send-email-tlinder-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2011-05-08 11:16 ` [PATCH v9 5/7] usb: Add streams support to the gadget framework Tatyana Brokhman
2011-05-09 9:25 ` Felipe Balbi
2011-05-11 13:29 ` Tanya Brokhman
2011-05-11 20:54 ` Felipe Balbi
2011-05-08 11:16 ` Tatyana Brokhman [this message]
2011-05-08 11:16 ` [PATCH v9 7/7] usb: Adding SuperSpeed support to dummy_hcd Tatyana Brokhman
2011-05-09 17:49 ` Sebastian Andrzej Siewior
2011-05-10 11:24 ` Sergei Shtylyov
2011-05-12 5:19 ` Tanya Brokhman
2011-05-12 14:45 ` Alan Stern
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1304853414-10234-7-git-send-email-tlinder@codeaurora.org \
--to=tlinder-sgv2jx0feol9jmxxk+q4oq@public.gmane.org \
--cc=ablay-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
--cc=balbi-l0cyMroinI0@public.gmane.org \
--cc=greg-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org \
--cc=linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).