2 * f_gadgetfs.c -- GadgetFS composite function driver
4 * Copyright (C) 2009 MCCI Corporation
6 * Based on f_acm.c by Al Borchers and David Brownell.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <linux/kernel.h>
25 #include <linux/device.h>
27 #include "u_gadgetfs.h"
28 #include "f_gadgetfs.h"
30 /*-------------------------------------------------------------------------*/
35 * Helper function to find out the f_gagdetfs structure that a give usb_function is wrapped in.
37 static inline struct f_gadgetfs *func_to_gadgetfs(struct usb_function *f)
39 return container_of(f, struct f_gadgetfs, function);
45 * Reconfigures altsettings; function drivers may initialize usb_ep.driver data at this time (when it is used).
46 * Note that setting an interface to its current altsetting resets interface state, and that all interfaces have
49 static void gadgetfs_unbind(struct usb_configuration *c, struct usb_function *f)
51 struct f_gadgetfs *gadgetfs = func_to_gadgetfs(f);
53 /* Free the descriptors that were set up in @gadgetfs_bind */
54 if (gadget_is_dualspeed(c->cdev->gadget))
55 if (f->hs_descriptors)
56 usb_free_descriptors(f->hs_descriptors);
58 usb_free_descriptors(f->descriptors);
66 * The first function to get called when a new configuration is added. It's job is to allocate endpoints and
67 * store that information locally
69 static int __init gadgetfs_bind(struct usb_configuration *c, struct usb_function *f)
71 struct f_gadgetfs *gadgetfs = func_to_gadgetfs(f);
72 struct usb_gadget *gadget = c->cdev->gadget;
76 gadgetfs->ep0 = gadget->ep0;
78 /* Allocate new interface */
79 status = usb_interface_id_specify(c, f, GADGETFS_INTERFACE_ID);
83 gadgetfs->interface_id = status;
84 gadgetfs_control_interface_descriptor.bInterfaceNumber = status;
86 /* Allocate endpoints */
88 gadgetfs->ep_out = usb_ep_autoconfig(gadget, &gadgetfs_full_speed_ep_out_descriptor);
89 if (!gadgetfs->ep_out)
91 gadgetfs->ep_out->driver_data = gadgetfs; // claim the endpoint
94 gadgetfs->ep_in = usb_ep_autoconfig(gadget, &gadgetfs_full_speed_ep_in_descriptor);
97 gadgetfs->ep_in->driver_data = gadgetfs; // claim the endpoint
100 gadgetfs->ep_int = usb_ep_autoconfig(gadget, &gadgetfs_full_speed_status_descriptor);
101 if (!gadgetfs->ep_int)
103 gadgetfs->ep_int->driver_data = gadgetfs; // claim the endpoint
105 /* copy descriptors, so they can be properly reported to the host */
106 f->descriptors = usb_copy_descriptors(gadgetfs_full_speed_function);
110 /* track endpoint copies */
111 gadgetfs->full_speed_descriptor.out = usb_find_endpoint(gadgetfs_full_speed_function, f->descriptors, &gadgetfs_full_speed_ep_out_descriptor);
112 gadgetfs->full_speed_descriptor.in = usb_find_endpoint(gadgetfs_full_speed_function, f->descriptors, &gadgetfs_full_speed_ep_in_descriptor);
113 gadgetfs->full_speed_descriptor.status = usb_find_endpoint(gadgetfs_full_speed_function, f->descriptors, &gadgetfs_full_speed_status_descriptor);
115 if (gadget_is_dualspeed(gadget)) {
116 /* Assume endpoint addresses are the same for both speeds */
117 gadgetfs_high_speed_ep_in_descriptor.bEndpointAddress = gadgetfs_full_speed_ep_in_descriptor.bEndpointAddress;
118 gadgetfs_high_speed_ep_out_descriptor.bEndpointAddress = gadgetfs_full_speed_ep_out_descriptor.bEndpointAddress;
119 gadgetfs_high_speed_status_descriptor.bEndpointAddress = gadgetfs_full_speed_status_descriptor.bEndpointAddress;
121 /* copy descriptors, so they can be properly reported to the host */
122 f->hs_descriptors = usb_copy_descriptors(gadgetfs_high_speed_function);
123 if (!f->hs_descriptors)
126 /* track endpoint copies */
127 gadgetfs->high_speed_descriptor.out = usb_find_endpoint(gadgetfs_high_speed_function, f->descriptors, &gadgetfs_high_speed_ep_out_descriptor);
128 gadgetfs->high_speed_descriptor.in = usb_find_endpoint(gadgetfs_high_speed_function, f->descriptors, &gadgetfs_high_speed_ep_in_descriptor);
129 gadgetfs->high_speed_descriptor.status = usb_find_endpoint(gadgetfs_high_speed_function, f->descriptors, &gadgetfs_high_speed_status_descriptor);
132 /* Create the root inode "(fake ep0)" file (which has the same name as the chip) for the application */
133 status = register_filesystem (&gadgetfs_type);
135 dbg_info ("%s, version %s\n", driver_desc, GADGETFS_DRIVER_VERSION);
136 dbg_info ("ep-in = %s, ep-out = %s, ep-int = %s\n", gadgetfs->ep_in->name, gadgetfs->ep_out->name, gadgetfs->ep_int->name);
144 gadgetfs_unbind(c, f);
151 * Reconfigures altsettings; function drivers may initialize usb_ep.driver data at this time (when it is used).
152 * Note that setting an interface to its current altsetting resets interface state, and that all interfaces have
155 static int gadgetfs_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
157 struct f_gadgetfs *gadgetfs = func_to_gadgetfs(f);
158 //struct usb_composite_dev *cdev = f->config->cdev;
160 /* we know alt == 0, so this is an activation or a reset */
162 if (interface == gadgetfs->interface_id) {
163 // Note that setting an interface to its current altsetting resets interface state
164 // So we should 'reset interface state' now.
173 * Indicates the function should be disabled. Reasons include host resetting or
174 * reconfiguring the gadget, and disconnection.
176 static void gadgetfs_disable(struct usb_function *f)
184 * Notifies functions when the host stops sending USB traffic.
186 static void gadgetfs_suspend(struct usb_function *f)
194 * Handles ep0 requests that the composite.c driver doesn't know what to do with. Ie, interface
195 * specific requests that we have to handle. This is just a wrapper function into u_gadgetfs.
197 static int gadgetfs_setup(struct usb_function *func, const struct usb_ctrlrequest *ctrl)
199 return gfs_setup(func, ctrl);
203 * gadgetfs_bind_config - add a gadgetFS function to a configuration
204 * @c: the configuration to support the gadgetFS instance
205 * Context: single threaded during gadget setup
207 * Returns zero on success, else negative errno.
209 int __init gadgetfs_bind_config(struct usb_composite_dev *c_dev, struct usb_configuration *c)
211 struct f_gadgetfs *gadgetfs;
214 gadgetfs = kzalloc(sizeof *gadgetfs, GFP_KERNEL);
215 if (unlikely(!gadgetfs))
217 the_gadget = gadgetfs;
219 /* allocate string id's */
220 if (gadgetfs_string_defines[GADGETFS_MANUFACTURER_IDX].id == 0) {
221 status = usb_string_id(c_dev);
224 gadgetfs_string_defines[GADGETFS_MANUFACTURER_IDX].id = status;
226 status = usb_string_id(c_dev);
229 gadgetfs_string_defines[GADGETFS_PRODUCT_IDX].id = status;
231 status = usb_string_id(c_dev);
234 gadgetfs_string_defines[GADGETFS_INTERFACE_IDX].id = status;
235 gadgetfs_control_interface_descriptor.iInterface = status;
238 spin_lock_init(&gadgetfs->lock);
240 gadgetfs->cdev = c_dev;
241 gadgetfs->function.name = GADGETFS_DRIVER_DESC;
242 gadgetfs->function.strings = gadgetfs_strings;
243 gadgetfs->function.bind = gadgetfs_bind;
244 gadgetfs->function.unbind = gadgetfs_unbind;
245 gadgetfs->function.set_alt = gadgetfs_set_alt;
246 gadgetfs->function.disable = gadgetfs_disable;
247 gadgetfs->function.suspend = gadgetfs_suspend;
248 gadgetfs->function.setup = gadgetfs_setup;
251 #ifdef CONFIG_USB_G_SAMSUNG_MULTI
252 status = usb_add_function_head(c, &gadgetfs->function);
254 status = usb_add_function(c, &gadgetfs->function);
257 status = usb_add_function(c, &gadgetfs->function);
267 * init_gadgetfs - create device and copy endpoint data
268 * Context: may not sleep
270 * This function gets called after the endpoints have been configured and it's main purpose is to create
271 * a new device in u_gadgetfs and copy of the endpoint data that was set up here. We do the set up in
272 * f_gadgetfs, but most of the work is in u_gadgetfs so this is just a go-between between the two data structures
274 int init_gadgetfs(struct usb_composite_dev *cdev)
276 struct device_data *dev;
277 struct f_gadgetfs *gadgetfs = the_gadget;
281 dbg_err("Whoa. Wait. the_gadget is NULL. How can this be?\n");
285 /* Create a new device structure for use in u_gadgetfs. This was previously done in @gfs_superblock
286 * when a 'mount' happened, but we set it up here now so that we can store the endpoint data there
288 dev = create_device ();
291 the_device = dev; /* set the global device variable in u_gadgetfs */
293 /* Store the endpoint data */
294 dev->ep_in = gadgetfs->ep_in;
295 dev->ep_out = gadgetfs->ep_out;
296 dev->ep_int = gadgetfs->ep_int;
297 dev->ep0 = gadgetfs->ep0;
299 /* Store the real endpoint descriptors */
300 dev->fs_in_desc = gadgetfs->full_speed_descriptor.in;
301 dev->fs_out_desc = gadgetfs->full_speed_descriptor.out;
302 dev->fs_status_desc = gadgetfs->full_speed_descriptor.status;
303 dev->hs_in_desc = gadgetfs->high_speed_descriptor.in;
304 dev->hs_out_desc = gadgetfs->high_speed_descriptor.out;
305 dev->hs_status_desc = gadgetfs->high_speed_descriptor.status;
307 if (gadget_is_dualspeed(cdev->gadget))
308 dev->speed = USB_SPEED_HIGH;
310 dev->speed = USB_SPEED_FULL;
318 * Delete the device_data object in u_gadgetfs
320 void gadgetfs_cleanup(void)
322 /* this used to be done in u_gadgetfs.c/gfs_unmount() */
324 device_decrement(the_device);
328 /* unregister filesystem */