aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorRoger Quadros <roger.quadros@nokia.com>2011-05-09 06:08:06 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-10 17:14:57 -0400
commit1b9ba000177ee47bcc5b44c7c34e48e735f5f9b1 (patch)
tree8faa82465181387e1962786de7805912a8bacb66 /include/linux
parent8eadef1526886db2a471c432d2c3d154de46f5c6 (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>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/usb/composite.h16
1 files changed, 15 insertions, 1 deletions
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 882a084a8411..b78cba466d3d 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -37,6 +37,14 @@
37#include <linux/usb/ch9.h> 37#include <linux/usb/ch9.h>
38#include <linux/usb/gadget.h> 38#include <linux/usb/gadget.h>
39 39
40/*
41 * USB function drivers should return USB_GADGET_DELAYED_STATUS if they
42 * wish to delay the data/status stages of the control transfer till they
43 * are ready. The control transfer will then be kept from completing till
44 * all the function drivers that requested for USB_GADGET_DELAYED_STAUS
45 * invoke usb_composite_setup_continue().
46 */
47#define USB_GADGET_DELAYED_STATUS 0x7fff /* Impossibly large value */
40 48
41struct usb_configuration; 49struct usb_configuration;
42 50
@@ -285,6 +293,7 @@ struct usb_composite_driver {
285extern int usb_composite_probe(struct usb_composite_driver *driver, 293extern int usb_composite_probe(struct usb_composite_driver *driver,
286 int (*bind)(struct usb_composite_dev *cdev)); 294 int (*bind)(struct usb_composite_dev *cdev));
287extern void usb_composite_unregister(struct usb_composite_driver *driver); 295extern void usb_composite_unregister(struct usb_composite_driver *driver);
296extern void usb_composite_setup_continue(struct usb_composite_dev *cdev);
288 297
289 298
290/** 299/**
@@ -342,7 +351,12 @@ struct usb_composite_dev {
342 */ 351 */
343 unsigned deactivations; 352 unsigned deactivations;
344 353
345 /* protects at least deactivation count */ 354 /* the composite driver won't complete the control transfer's
355 * data/status stages till delayed_status is zero.
356 */
357 int delayed_status;
358
359 /* protects deactivations and delayed_status counts*/
346 spinlock_t lock; 360 spinlock_t lock;
347}; 361};
348 362