From 83814ea997cb03a65c7baf1c41699963724af932 Mon Sep 17 00:00:00 2001 From: "Krishna, Vamsi" Date: Wed, 11 Feb 2009 21:07:20 +0530 Subject: [PATCH] USB: gadget: android: android USB gadget improvements: USB: android gadget: add remote wakeup attribute to android function Add remote wakeup attribute to configuration descriptor of android function to advertise remote wakeup capability to host Acked-by: Allam, Suresh Reddy Signed-off-by: Mike Lockwood USB: gadget: android: Allow functions to handle setup requests. Signed-off-by: Mike Lockwood Support for specifying the list of USB functions from platform data. The main android.c gadget driver no longer has hard coded references to the mass_storage and adb functions. Support for computing the product ID based on tables in platform data and the currently enabled functions. Moved the adb enable/disable logic from android.c to f_adb.c. Change-Id: I6259d3fb1473ed973f700e55d17744956f3527bb Signed-off-by: Mike Lockwood --- drivers/usb/gadget/Kconfig | 25 ++- drivers/usb/gadget/Makefile | 6 +- drivers/usb/gadget/android.c | 224 +++++++++++++++--------- drivers/usb/gadget/f_acm.c | 16 +- drivers/usb/gadget/f_acm.h | 24 --- drivers/usb/gadget/f_adb.c | 97 ++++++---- drivers/usb/gadget/f_adb.h | 25 --- drivers/usb/gadget/f_mass_storage.h | 52 ------ drivers/usb/gadget/f_mass_storage_tmp.c | 26 ++- include/linux/usb/android.h | 50 ------ include/linux/usb/android_composite.h | 90 ++++++++++ 11 files changed, 350 insertions(+), 285 deletions(-) delete mode 100644 drivers/usb/gadget/f_acm.h delete mode 100644 drivers/usb/gadget/f_adb.h delete mode 100644 drivers/usb/gadget/f_mass_storage.h delete mode 100644 include/linux/usb/android.h create mode 100644 include/linux/usb/android_composite.h diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 43c9015b5d4f..e1e5af52a1c9 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -936,13 +936,30 @@ config USB_G_PRINTER which includes sample code for accessing the device file. config USB_ANDROID - tristate "Android Gadget" + boolean "Android Gadget" depends on SWITCH help - The Android gadget provides mass storage and adb transport. + The Android gadget driver supports multiple USB functions. + The functions can be configured via a board file and may be + enabled and disabled dynamically. - Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "g_android". +config USB_ANDROID_ACM + boolean "Android gadget ACM function" + depends on USB_ANDROID + help + Provides adb function for adb gadget driver. + +config USB_ANDROID_ADB + boolean "Android gadget adb function" + depends on USB_ANDROID + help + Provides adb function for adb gadget driver. + +config USB_ANDROID_MASS_STORAGE + boolean "Android gadget mass storage function" + depends on USB_ANDROID && SWITCH + help + Provides USB mass storage function for adb gadget driver. config USB_CDC_COMPOSITE tristate "CDC Composite Device (Ethernet and ACM)" diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index dc9fcf98d55e..321e1c8f667e 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -49,7 +49,6 @@ g_dbgp-y := dbgp.o g_nokia-y := nokia.o g_webcam-y := webcam.o g_ncm-y := ncm.o -g_android-y := android.o f_adb.o f_mass_storage_tmp.o obj-$(CONFIG_USB_ZERO) += g_zero.o obj-$(CONFIG_USB_AUDIO) += g_audio.o @@ -68,4 +67,7 @@ obj-$(CONFIG_USB_G_MULTI) += g_multi.o obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o obj-$(CONFIG_USB_G_NCM) += g_ncm.o -obj-$(CONFIG_USB_ANDROID) += g_android.o +obj-$(CONFIG_USB_ANDROID) += android.o +obj-$(CONFIG_USB_ANDROID_ACM) += f_acm.o u_serial.o +obj-$(CONFIG_USB_ANDROID_ADB) += f_adb.o +obj-$(CONFIG_USB_ANDROID_MASS_STORAGE) += f_mass_storage_tmp.o diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c index d3c028d45cbc..d10568ef8940 100644 --- a/drivers/usb/gadget/android.c +++ b/drivers/usb/gadget/android.c @@ -25,17 +25,13 @@ #include #include #include -#include #include -#include +#include #include #include #include -#include "f_mass_storage.h" -#include "f_adb.h" - #include "gadget_chips.h" /* @@ -60,20 +56,19 @@ static const char longname[] = "Gadget Android"; /* Default vendor and product IDs, overridden by platform data */ #define VENDOR_ID 0x18D1 #define PRODUCT_ID 0x0001 -#define ADB_PRODUCT_ID 0x0002 struct android_dev { struct usb_composite_dev *cdev; + struct usb_configuration *config; + int num_products; + struct android_usb_product *products; + int num_functions; + char **functions; int product_id; - int adb_product_id; int version; - - int adb_enabled; - int nluns; }; -static atomic_t adb_enable_excl; static struct android_dev *_android_dev; /* string IDs are assigned dynamically */ @@ -112,6 +107,9 @@ static struct usb_device_descriptor device_desc = { .bNumConfigurations = 1, }; +static struct list_head _functions = LIST_HEAD_INIT(_functions); +static int _registered_function_count = 0; + void android_usb_set_connected(int connected) { if (_android_dev && _android_dev->cdev && _android_dev->cdev->gadget) { @@ -122,33 +120,121 @@ void android_usb_set_connected(int connected) } } +static struct android_usb_function *get_function(const char *name) +{ + struct android_usb_function *f; + list_for_each_entry(f, &_functions, list) { + if (!strcmp(name, f->name)) + return f; + } + return 0; +} + +static void bind_functions(struct android_dev *dev) +{ + struct android_usb_function *f; + char **functions = dev->functions; + int i; + + for (i = 0; i < dev->num_functions; i++) { + char *name = *functions++; + f = get_function(name); + if (f) + f->bind_config(dev->config); + else + printk(KERN_ERR "function %s not found in bind_functions\n", name); + } +} + static int __init android_bind_config(struct usb_configuration *c) { struct android_dev *dev = _android_dev; - int ret; + printk(KERN_DEBUG "android_bind_config\n"); + dev->config = c; - ret = mass_storage_function_add(dev->cdev, c, dev->nluns); - if (ret) - return ret; - return adb_function_add(dev->cdev, c); + /* bind our functions if they have all registered */ + if (_registered_function_count == dev->num_functions) + bind_functions(dev); + + return 0; } +static int android_setup_config(struct usb_configuration *c, + const struct usb_ctrlrequest *ctrl); + static struct usb_configuration android_config_driver = { .label = "android", .bind = android_bind_config, + .setup = android_setup_config, .bConfigurationValue = 1, .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, .bMaxPower = 0xFA, /* 500ma */ }; +static int android_setup_config(struct usb_configuration *c, + const struct usb_ctrlrequest *ctrl) +{ + int i; + int ret = -EOPNOTSUPP; + + for (i = 0; i < android_config_driver.next_interface_id; i++) { + if (android_config_driver.interface[i]->setup) { + ret = android_config_driver.interface[i]->setup( + android_config_driver.interface[i], ctrl); + if (ret >= 0) + return ret; + } + } + return ret; +} + +static int product_has_function(struct android_usb_product *p, + struct usb_function *f) +{ + char **functions = p->functions; + int count = p->num_functions; + const char *name = f->name; + int i; + + for (i = 0; i < count; i++) { + if (!strcmp(name, *functions++)) + return 1; + } + return 0; +} + +static int product_matches_functions(struct android_usb_product *p) +{ + struct usb_function *f; + list_for_each_entry(f, &android_config_driver.functions, list) { + if (product_has_function(p, f) == !!f->hidden) + return 0; + } + return 1; +} + +static int get_product_id(struct android_dev *dev) +{ + struct android_usb_product *p = dev->products; + int count = dev->num_products; + int i; + + if (p) { + for (i = 0; i < count; i++, p++) { + if (product_matches_functions(p)) + return p->product_id; + } + } + /* use default product ID */ + return dev->product_id; +} + static int __init android_bind(struct usb_composite_dev *cdev) { struct android_dev *dev = _android_dev; struct usb_gadget *gadget = cdev->gadget; - int gcnum; - int id; - int ret; + int gcnum, id, product_id, ret; printk(KERN_INFO "android_bind\n"); @@ -173,6 +259,9 @@ static int __init android_bind(struct usb_composite_dev *cdev) strings_dev[STRING_SERIAL_IDX].id = id; device_desc.iSerialNumber = id; + if (gadget->ops->wakeup) + android_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + /* register our configuration */ ret = usb_add_config(cdev, &android_config_driver); if (ret) { @@ -198,6 +287,9 @@ static int __init android_bind(struct usb_composite_dev *cdev) usb_gadget_set_selfpowered(gadget); dev->cdev = cdev; + product_id = get_product_id(dev); + device_desc.idProduct = __constant_cpu_to_le16(product_id); + cdev->desc.idProduct = device_desc.idProduct; return 0; } @@ -209,19 +301,31 @@ static struct usb_composite_driver android_usb_driver = { .bind = android_bind, }; -static void enable_adb(struct android_dev *dev, int enable) +void android_register_function(struct android_usb_function *f) { - if (enable != dev->adb_enabled) { - dev->adb_enabled = enable; - adb_function_enable(enable); + struct android_dev *dev = _android_dev; - /* set product ID to the appropriate value */ - if (enable) - device_desc.idProduct = - __constant_cpu_to_le16(dev->adb_product_id); - else - device_desc.idProduct = - __constant_cpu_to_le16(dev->product_id); + printk(KERN_INFO "android_register_function\n"); + list_add_tail(&f->list, &_functions); + _registered_function_count++; + + /* bind our functions if they have all registered + * and the main driver has bound. + */ + if (dev->config && _registered_function_count == dev->num_functions) + bind_functions(dev); +} + +void android_enable_function(struct usb_function *f, int enable) +{ + struct android_dev *dev = _android_dev; + int disable = !enable; + int product_id; + + if (!!f->hidden != disable) { + f->hidden = disable; + product_id = get_product_id(dev); + device_desc.idProduct = __constant_cpu_to_le16(product_id); if (dev->cdev) dev->cdev->desc.idProduct = device_desc.idProduct; @@ -235,39 +339,6 @@ static void enable_adb(struct android_dev *dev, int enable) } } -static int adb_enable_open(struct inode *ip, struct file *fp) -{ - if (atomic_inc_return(&adb_enable_excl) != 1) { - atomic_dec(&adb_enable_excl); - return -EBUSY; - } - - printk(KERN_INFO "enabling adb\n"); - enable_adb(_android_dev, 1); - - return 0; -} - -static int adb_enable_release(struct inode *ip, struct file *fp) -{ - printk(KERN_INFO "disabling adb\n"); - enable_adb(_android_dev, 0); - atomic_dec(&adb_enable_excl); - return 0; -} - -static const struct file_operations adb_enable_fops = { - .owner = THIS_MODULE, - .open = adb_enable_open, - .release = adb_enable_release, -}; - -static struct miscdevice adb_enable_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "android_adb_enable", - .fops = &adb_enable_fops, -}; - static int __init android_probe(struct platform_device *pdev) { struct android_usb_platform_data *pdata = pdev->dev.platform_data; @@ -276,6 +347,10 @@ static int __init android_probe(struct platform_device *pdev) printk(KERN_INFO "android_probe pdata: %p\n", pdata); if (pdata) { + dev->products = pdata->products; + dev->num_products = pdata->num_products; + dev->functions = pdata->functions; + dev->num_functions = pdata->num_functions; if (pdata->vendor_id) device_desc.idVendor = __constant_cpu_to_le16(pdata->vendor_id); @@ -284,8 +359,6 @@ static int __init android_probe(struct platform_device *pdev) device_desc.idProduct = __constant_cpu_to_le16(pdata->product_id); } - if (pdata->adb_product_id) - dev->adb_product_id = pdata->adb_product_id; if (pdata->version) dev->version = pdata->version; @@ -296,10 +369,9 @@ static int __init android_probe(struct platform_device *pdev) pdata->manufacturer_name; if (pdata->serial_number) strings_dev[STRING_SERIAL_IDX].s = pdata->serial_number; - dev->nluns = pdata->nluns; } - return 0; + return usb_composite_register(&android_usb_driver); } static struct platform_driver android_platform_driver = { @@ -310,7 +382,6 @@ static struct platform_driver android_platform_driver = { static int __init init(void) { struct android_dev *dev; - int ret; printk(KERN_INFO "android init\n"); @@ -320,30 +391,15 @@ static int __init init(void) /* set default values, which should be overridden by platform data */ dev->product_id = PRODUCT_ID; - dev->adb_product_id = ADB_PRODUCT_ID; _android_dev = dev; - ret = platform_driver_register(&android_platform_driver); - if (ret) - return ret; - ret = misc_register(&adb_enable_device); - if (ret) { - platform_driver_unregister(&android_platform_driver); - return ret; - } - ret = usb_composite_register(&android_usb_driver); - if (ret) { - misc_deregister(&adb_enable_device); - platform_driver_unregister(&android_platform_driver); - } - return ret; + return platform_driver_register(&android_platform_driver); } module_init(init); static void __exit cleanup(void) { usb_composite_unregister(&android_usb_driver); - misc_deregister(&adb_enable_device); platform_driver_unregister(&android_platform_driver); kfree(_android_dev); _android_dev = NULL; diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 39363bfa39e7..b6fb4cfe79ec 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -20,6 +20,7 @@ #include "u_serial.h" #include "gadget_chips.h" +#include "linux/usb/android_composite.h" /* @@ -783,11 +784,22 @@ int acm_bind_config(struct usb_configuration *c, u8 port_num) return status; } -int __init acm_function_add(struct usb_composite_dev *cdev, - struct usb_configuration *c) +int acm_function_bind_config(struct usb_configuration *c) { int ret = acm_bind_config(c, 0); if (ret == 0) gserial_setup(c->cdev->gadget, 1); return ret; } + +static struct android_usb_function acm_function = { + .name = "acm", + .bind_config = acm_function_bind_config, +}; + +static int __init init(void) +{ + android_register_function(&acm_function); + return 0; +} +module_init(init); diff --git a/drivers/usb/gadget/f_acm.h b/drivers/usb/gadget/f_acm.h deleted file mode 100644 index 8e27b3440635..000000000000 --- a/drivers/usb/gadget/f_acm.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Gadget Driver for Android ACM - * - * Copyright (C) 2009 Motorola, Inc. - * Author: - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __F_ACM_H -#define __F_ACM_H - -int acm_function_add(struct usb_composite_dev *cdev, - struct usb_configuration *c); - -#endif /* __F_ACM_H */ diff --git a/drivers/usb/gadget/f_adb.c b/drivers/usb/gadget/f_adb.c index 2eaaadaab925..04dd45139406 100644 --- a/drivers/usb/gadget/f_adb.c +++ b/drivers/usb/gadget/f_adb.c @@ -30,11 +30,7 @@ #include #include -#include -#include -#include - -#include "f_adb.h" +#include #define BULK_BUFFER_SIZE 4096 @@ -126,15 +122,12 @@ static struct usb_descriptor_header *hs_adb_descs[] = { NULL, }; -/* used when adb function is disabled */ -static struct usb_descriptor_header *null_adb_descs[] = { - NULL, -}; - /* temporary variable used between adb_open() and adb_gadget_bind() */ static struct adb_dev *_adb_dev; +static atomic_t adb_enable_excl; + static inline struct adb_dev *func_to_dev(struct usb_function *f) { return container_of(f, struct adb_dev, function); @@ -489,7 +482,40 @@ static struct miscdevice adb_device = { .fops = &adb_fops, }; -static int __init +static int adb_enable_open(struct inode *ip, struct file *fp) +{ + if (atomic_inc_return(&adb_enable_excl) != 1) { + atomic_dec(&adb_enable_excl); + return -EBUSY; + } + + printk(KERN_INFO "enabling adb\n"); + android_enable_function(&_adb_dev->function, 1); + + return 0; +} + +static int adb_enable_release(struct inode *ip, struct file *fp) +{ + printk(KERN_INFO "disabling adb\n"); + android_enable_function(&_adb_dev->function, 0); + atomic_dec(&adb_enable_excl); + return 0; +} + +static const struct file_operations adb_enable_fops = { + .owner = THIS_MODULE, + .open = adb_enable_open, + .release = adb_enable_release, +}; + +static struct miscdevice adb_enable_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = "android_adb_enable", + .fops = &adb_enable_fops, +}; + +static int adb_function_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; @@ -544,6 +570,7 @@ adb_function_unbind(struct usb_configuration *c, struct usb_function *f) spin_unlock_irq(&dev->lock); misc_deregister(&adb_device); + misc_deregister(&adb_enable_device); kfree(_adb_dev); _adb_dev = NULL; } @@ -594,13 +621,12 @@ static void adb_function_disable(struct usb_function *f) VDBG(cdev, "%s disabled\n", dev->function.name); } -int __init adb_function_add(struct usb_composite_dev *cdev, - struct usb_configuration *c) +static int adb_bind_config(struct usb_configuration *c) { struct adb_dev *dev; int ret; - printk(KERN_INFO "adb_function_add\n"); + printk(KERN_INFO "adb_bind_config\n"); dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) @@ -619,27 +645,36 @@ int __init adb_function_add(struct usb_composite_dev *cdev, INIT_LIST_HEAD(&dev->rx_done); INIT_LIST_HEAD(&dev->tx_idle); - dev->cdev = cdev; + dev->cdev = c->cdev; dev->function.name = "adb"; - dev->function.descriptors = null_adb_descs; - dev->function.hs_descriptors = null_adb_descs; + dev->function.descriptors = fs_adb_descs; + dev->function.hs_descriptors = hs_adb_descs; dev->function.bind = adb_function_bind; dev->function.unbind = adb_function_unbind; dev->function.set_alt = adb_function_set_alt; dev->function.disable = adb_function_disable; + /* start disabled */ + dev->function.hidden = 1; + /* _adb_dev must be set before calling usb_gadget_register_driver */ _adb_dev = dev; ret = misc_register(&adb_device); if (ret) goto err1; - ret = usb_add_function(c, &dev->function); + ret = misc_register(&adb_enable_device); if (ret) goto err2; + ret = usb_add_function(c, &dev->function); + if (ret) + goto err3; + return 0; +err3: + misc_deregister(&adb_enable_device); err2: misc_deregister(&adb_device); err1: @@ -648,21 +683,15 @@ err1: return ret; } -void adb_function_enable(int enable) -{ - struct adb_dev *dev = _adb_dev; - - if (dev) { - DBG(dev->cdev, "adb_function_enable(%s)\n", - enable ? "true" : "false"); +static struct android_usb_function adb_function = { + .name = "adb", + .bind_config = adb_bind_config, +}; - if (enable) { - dev->function.descriptors = fs_adb_descs; - dev->function.hs_descriptors = hs_adb_descs; - } else { - dev->function.descriptors = null_adb_descs; - dev->function.hs_descriptors = null_adb_descs; - } - } +static int __init init(void) +{ + printk(KERN_INFO "f_adb init\n"); + android_register_function(&adb_function); + return 0; } - +module_init(init); diff --git a/drivers/usb/gadget/f_adb.h b/drivers/usb/gadget/f_adb.h deleted file mode 100644 index 4854ff629797..000000000000 --- a/drivers/usb/gadget/f_adb.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Gadget Driver for Android ADB - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __F_ADB_H -#define __F_ADB_H - -int adb_function_add(struct usb_composite_dev *cdev, - struct usb_configuration *c); -void adb_function_enable(int enable); - -#endif /* __F_ADB_H */ diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h deleted file mode 100644 index 8e63ac0cbe93..000000000000 --- a/drivers/usb/gadget/f_mass_storage.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * drivers/usb/gadget/f_mass_storage.h - * - * Function Driver for USB Mass Storage - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * Based heavily on the file_storage gadget driver in - * drivers/usb/gadget/file_storage.c and licensed under the same terms: - * - * Copyright (C) 2003-2007 Alan Stern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The names of the above-listed copyright holders may not be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __F_MASS_STORAGE_H -#define __F_MASS_STORAGE_H - -int mass_storage_function_add(struct usb_composite_dev *cdev, - struct usb_configuration *c, int nluns); - -#endif /* __F_MASS_STORAGE_H */ diff --git a/drivers/usb/gadget/f_mass_storage_tmp.c b/drivers/usb/gadget/f_mass_storage_tmp.c index a0f7f9ce7be7..79044f72652c 100644 --- a/drivers/usb/gadget/f_mass_storage_tmp.c +++ b/drivers/usb/gadget/f_mass_storage_tmp.c @@ -73,9 +73,8 @@ #include #include #include -#include +#include -#include "f_mass_storage.h" #include "gadget_chips.h" @@ -2711,7 +2710,7 @@ fsg_function_unbind(struct usb_configuration *c, struct usb_function *f) switch_dev_unregister(&fsg->sdev); } -static int __init +static int fsg_function_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; @@ -2902,6 +2901,7 @@ static int __init fsg_probe(struct platform_device *pdev) if (pdata->release) fsg->release = pdata->release; + fsg->nluns = pdata->nluns; } return 0; @@ -2912,18 +2912,16 @@ static struct platform_driver fsg_platform_driver = { .probe = fsg_probe, }; -int __init mass_storage_function_add(struct usb_composite_dev *cdev, - struct usb_configuration *c, int nluns) +int mass_storage_bind_config(struct usb_configuration *c) { int rc; struct fsg_dev *fsg; - printk(KERN_INFO "mass_storage_function_add\n"); + printk(KERN_INFO "mass_storage_bind_config\n"); rc = fsg_alloc(); if (rc) return rc; fsg = the_fsg; - fsg->nluns = nluns; spin_lock_init(&fsg->lock); init_rwsem(&fsg->filesem); @@ -2945,7 +2943,7 @@ int __init mass_storage_function_add(struct usb_composite_dev *cdev, wake_lock_init(&the_fsg->wake_lock, WAKE_LOCK_SUSPEND, "usb_mass_storage"); - fsg->cdev = cdev; + fsg->cdev = c->cdev; fsg->function.name = shortname; fsg->function.descriptors = fs_function; fsg->function.bind = fsg_function_bind; @@ -2972,4 +2970,16 @@ err_switch_dev_register: return rc; } +static struct android_usb_function mass_storage_function = { + .name = "usb_mass_storage", + .bind_config = mass_storage_bind_config, +}; + +static int __init init(void) +{ + printk(KERN_INFO "f_mass_storage init\n"); + android_register_function(&mass_storage_function); + return 0; +} +module_init(init); diff --git a/include/linux/usb/android.h b/include/linux/usb/android.h deleted file mode 100644 index 4e7f419149d8..000000000000 --- a/include/linux/usb/android.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Platform data for Android USB - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __LINUX_USB_ANDROID_H -#define __LINUX_USB_ANDROID_H - -struct android_usb_platform_data { - /* USB device descriptor fields */ - __u16 vendor_id; - - /* Default product ID. */ - __u16 product_id; - - /* Product ID when adb is enabled. */ - __u16 adb_product_id; - - __u16 version; - - char *product_name; - char *manufacturer_name; - char *serial_number; - - /* number of LUNS for mass storage function */ - int nluns; -}; - -/* Platform data for "usb_mass_storage" driver. - * Contains values for the SC_INQUIRY SCSI command. */ -struct usb_mass_storage_platform_data { - char *vendor; - char *product; - int release; -}; - -extern void android_usb_set_connected(int on); - -#endif /* __LINUX_USB_ANDROID_H */ diff --git a/include/linux/usb/android_composite.h b/include/linux/usb/android_composite.h new file mode 100644 index 000000000000..328016813dd5 --- /dev/null +++ b/include/linux/usb/android_composite.h @@ -0,0 +1,90 @@ +/* + * Platform data for Android USB + * + * Copyright (C) 2008 Google, Inc. + * Author: Mike Lockwood + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __LINUX_USB_ANDROID_H +#define __LINUX_USB_ANDROID_H + +#include + +struct android_usb_function { + struct list_head list; + char *name; + int (*bind_config)(struct usb_configuration *c); +}; + +struct android_usb_product { + /* Default product ID. */ + __u16 product_id; + + /* List of function names associated with this product. + * This is used to compute the USB product ID dynamically + * based on which functions are enabled. + */ + int num_functions; + char **functions; +}; + +struct android_usb_platform_data { + /* USB device descriptor fields */ + __u16 vendor_id; + + /* Default product ID. */ + __u16 product_id; + + __u16 version; + + char *product_name; + char *manufacturer_name; + char *serial_number; + + /* List of available USB products. + * This is used to compute the USB product ID dynamically + * based on which functions are enabled. + * if num_products is zero or no match can be found, + * we use the default product ID + */ + int num_products; + struct android_usb_product *products; + + /* List of all supported USB functions. + * This list is used to define the order in which + * the functions appear in the configuration's list of USB interfaces. + * This is necessary to avoid depending upon the order in which + * the individual function drivers are initialized. + */ + int num_functions; + char **functions; +}; + +/* Platform data for "usb_mass_storage" driver. */ +struct usb_mass_storage_platform_data { + /* Contains values for the SC_INQUIRY SCSI command. */ + char *vendor; + char *product; + int release; + + /* number of LUNS */ + int nluns; +}; + +extern void android_usb_set_connected(int on); + +extern void android_register_function(struct android_usb_function *f); + +extern void android_enable_function(struct usb_function *f, int enable); + + +#endif /* __LINUX_USB_ANDROID_H */ -- 2.34.1