Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 115747
b: refs/heads/master
c: 60beed9
h: refs/heads/master
i:
  115745: e775568
  115743: 73b10d2
v: v3
  • Loading branch information
David Brownell authored and Greg Kroah-Hartman committed Oct 17, 2008
1 parent b77817f commit e769d72
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8066134ff8140ae9d8d15cdad3fc6c60c2a8a4e5
refs/heads/master: 60beed95e38793c0baff7f94433c1f639d8d5efd
64 changes: 64 additions & 0 deletions trunk/drivers/usb/gadget/composite.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,70 @@ int __init usb_add_function(struct usb_configuration *config,
return value;
}

/**
* usb_function_deactivate - prevent function and gadget enumeration
* @function: the function that isn't yet ready to respond
*
* Blocks response of the gadget driver to host enumeration by
* preventing the data line pullup from being activated. This is
* normally called during @bind() processing to change from the
* initial "ready to respond" state, or when a required resource
* becomes available.
*
* For example, drivers that serve as a passthrough to a userspace
* daemon can block enumeration unless that daemon (such as an OBEX,
* MTP, or print server) is ready to handle host requests.
*
* Not all systems support software control of their USB peripheral
* data pullups.
*
* Returns zero on success, else negative errno.
*/
int usb_function_deactivate(struct usb_function *function)
{
struct usb_composite_dev *cdev = function->config->cdev;
int status = 0;

spin_lock(&cdev->lock);

if (cdev->deactivations == 0)
status = usb_gadget_disconnect(cdev->gadget);
if (status == 0)
cdev->deactivations++;

spin_unlock(&cdev->lock);
return status;
}

/**
* usb_function_activate - allow function and gadget enumeration
* @function: function on which usb_function_activate() was called
*
* Reverses effect of usb_function_deactivate(). If no more functions
* are delaying their activation, the gadget driver will respond to
* host enumeration procedures.
*
* Returns zero on success, else negative errno.
*/
int usb_function_activate(struct usb_function *function)
{
struct usb_composite_dev *cdev = function->config->cdev;
int status = 0;

spin_lock(&cdev->lock);

if (WARN_ON(cdev->deactivations == 0))
status = -EINVAL;
else {
cdev->deactivations--;
if (cdev->deactivations == 0)
status = usb_gadget_connect(cdev->gadget);
}

spin_unlock(&cdev->lock);
return status;
}

/**
* usb_interface_id() - allocate an unused interface ID
* @config: configuration associated with the interface
Expand Down
11 changes: 9 additions & 2 deletions trunk/include/linux/usb/composite.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ struct usb_function {

int usb_add_function(struct usb_configuration *, struct usb_function *);

int usb_function_deactivate(struct usb_function *);
int usb_function_activate(struct usb_function *);

int usb_interface_id(struct usb_configuration *, struct usb_function *);

/**
Expand Down Expand Up @@ -316,9 +319,13 @@ struct usb_composite_dev {
struct usb_composite_driver *driver;
u8 next_string_id;

spinlock_t lock;
/* the gadget driver won't enable the data pullup
* while the deactivation count is nonzero.
*/
unsigned deactivations;

/* REVISIT use and existence of lock ... */
/* protects at least deactivation count */
spinlock_t lock;
};

extern int usb_string_id(struct usb_composite_dev *c);
Expand Down

0 comments on commit e769d72

Please sign in to comment.