aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2008-08-18 20:38:22 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-10-17 17:40:53 -0400
commit60beed95e38793c0baff7f94433c1f639d8d5efd (patch)
treef35e277cdd32267772854b481843299564e4f3e8 /drivers/usb/gadget
parent8066134ff8140ae9d8d15cdad3fc6c60c2a8a4e5 (diff)
usb gadget: function activation/deactivation
Add a new mechanism to the composite gadget framework, letting functions deactivate (and reactivate) themselves. Think of it as a refcounted wrapper for the software pullup control. A key example of why to use this mechanism involves functions that require a userspace daemon. Those functions shuld use this new mechanism to prevent the gadget from enumerating until those daemons are activated. Without this mechanism, hosts would see devices that malfunction until the relevant daemons start. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/composite.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 85c876c1f15..f79fdb839cb 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -128,6 +128,70 @@ done:
128} 128}
129 129
130/** 130/**
131 * usb_function_deactivate - prevent function and gadget enumeration
132 * @function: the function that isn't yet ready to respond
133 *
134 * Blocks response of the gadget driver to host enumeration by
135 * preventing the data line pullup from being activated. This is
136 * normally called during @bind() processing to change from the
137 * initial "ready to respond" state, or when a required resource
138 * becomes available.
139 *
140 * For example, drivers that serve as a passthrough to a userspace
141 * daemon can block enumeration unless that daemon (such as an OBEX,
142 * MTP, or print server) is ready to handle host requests.
143 *
144 * Not all systems support software control of their USB peripheral
145 * data pullups.
146 *
147 * Returns zero on success, else negative errno.
148 */
149int usb_function_deactivate(struct usb_function *function)
150{
151 struct usb_composite_dev *cdev = function->config->cdev;
152 int status = 0;
153
154 spin_lock(&cdev->lock);
155
156 if (cdev->deactivations == 0)
157 status = usb_gadget_disconnect(cdev->gadget);
158 if (status == 0)
159 cdev->deactivations++;
160
161 spin_unlock(&cdev->lock);
162 return status;
163}
164
165/**
166 * usb_function_activate - allow function and gadget enumeration
167 * @function: function on which usb_function_activate() was called
168 *
169 * Reverses effect of usb_function_deactivate(). If no more functions
170 * are delaying their activation, the gadget driver will respond to
171 * host enumeration procedures.
172 *
173 * Returns zero on success, else negative errno.
174 */
175int usb_function_activate(struct usb_function *function)
176{
177 struct usb_composite_dev *cdev = function->config->cdev;
178 int status = 0;
179
180 spin_lock(&cdev->lock);
181
182 if (WARN_ON(cdev->deactivations == 0))
183 status = -EINVAL;
184 else {
185 cdev->deactivations--;
186 if (cdev->deactivations == 0)
187 status = usb_gadget_connect(cdev->gadget);
188 }
189
190 spin_unlock(&cdev->lock);
191 return status;
192}
193
194/**
131 * usb_interface_id() - allocate an unused interface ID 195 * usb_interface_id() - allocate an unused interface ID
132 * @config: configuration associated with the interface 196 * @config: configuration associated with the interface
133 * @function: function handling the interface 197 * @function: function handling the interface