summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorRakesh Bodla <rbodla@nvidia.com>2011-06-22 10:58:40 +0530
committerVarun Colbert <vcolbert@nvidia.com>2011-07-08 22:50:43 -0700
commit8be6f0a64aa65c70648982a541d97c066d07ff96 (patch)
tree31dd7d2b1677b7842b1a00a585587bdcd68d3d49 /include/linux
parenta290e4bcf8a798cf0acb1ee8828f1828779089f5 (diff)
usb: gadget: composite: Allow function drivers to pause control transfers
Some USB function drivers (e.g. f_mass_storage.c) need to delay or defer the data/status stages of standard control requests like SET_CONFIGURATION or SET_INTERFACE till they are done with their bookkeeping and are actually ready for accepting new commands to their interface. They can now achieve this functionality by returning USB_GADGET_DELAYED_STATUS in their setup handlers (e.g. set_alt()). The composite framework will then defer completion of the control transfer by not completing the data/status stages. This ensures that the host does not send new packets to the interface till the function driver is ready to take them. When the function driver that requested for USB_GADGET_DELAYED_STATUS is done with its bookkeeping, it should signal the composite framework to continue with the data/status stages of the control transfer. It can do so by invoking the new API usb_composite_setup_continue(). This is where the control transfer's data/status stages are completed and host can initiate new transfers. The DELAYED_STATUS mechanism is currently only supported if the expected data phase is 0 bytes (i.e. w_length == 0). Since SET_CONFIGURATION and SET_INTERFACE are the only cases that will use this mechanism, this is not a limitation. Signed-off-by: Roger Quadros <roger.quadros@nokia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> (cherry picked from commit 1b9ba000177ee47bcc5b44c7c34e48e735f5f9b1 kernel.org, linux-2.6 tree) Change-Id: I9d7082042f33c10110070febf36c95d61a292f82 Reviewed-on: http://git-master/r/37788 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/usb/composite.h17
1 files changed, 15 insertions, 2 deletions
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index cb28d4302781..26b30db9770c 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -38,6 +38,14 @@
#include <linux/usb/gadget.h>
#include <linux/switch.h>
+/*
+ * USB function drivers should return USB_GADGET_DELAYED_STATUS if they
+ * wish to delay the data/status stages of the control transfer till they
+ * are ready. The control transfer will then be kept from completing till
+ * all the function drivers that requested for USB_GADGET_DELAYED_STAUS
+ * invoke usb_composite_setup_continue().
+ */
+#define USB_GADGET_DELAYED_STATUS 0x7fff /* Impossibly large value */
struct usb_composite_dev;
struct usb_configuration;
@@ -300,7 +308,7 @@ struct usb_composite_driver {
extern int usb_composite_register(struct usb_composite_driver *);
extern void usb_composite_unregister(struct usb_composite_driver *);
-
+extern void usb_composite_setup_continue(struct usb_composite_dev *cdev);
/**
* struct usb_composite_device - represents one composite usb gadget
@@ -354,7 +362,12 @@ struct usb_composite_dev {
*/
unsigned deactivations;
- /* protects at least deactivation count */
+ /* the composite driver won't complete the control transfer's
+ * data/status stages till delayed_status is zero.
+ */
+ int delayed_status;
+
+ /* protects deactivations and delayed_status counts*/
spinlock_t lock;
/* switch indicating connected/disconnected state */