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 <sallam@qualcomm.com>

Signed-off-by: Mike Lockwood <lockwood@android.com>

USB: gadget: android: Allow functions to handle setup requests.

Signed-off-by: Mike Lockwood <lockwood@android.com>

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 <lockwood@android.com>
This commit is contained in:
Krishna, Vamsi
2009-02-11 21:07:20 +05:30
committed by Arve Hjønnevåg
parent 11d0a9ece7
commit dd5acba95d
11 changed files with 351 additions and 286 deletions

View File

@@ -781,13 +781,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)"

View File

@@ -41,7 +41,6 @@ gadgetfs-objs := inode.o
g_file_storage-objs := file_storage.o
g_printer-objs := printer.o
g_cdc-objs := cdc2.o
g_android-objs := android.o f_adb.o f_mass_storage.o
obj-$(CONFIG_USB_ZERO) += g_zero.o
obj-$(CONFIG_USB_AUDIO) += g_audio.o
@@ -52,5 +51,8 @@ obj-$(CONFIG_USB_G_SERIAL) += g_serial.o
obj-$(CONFIG_USB_G_PRINTER) += g_printer.o
obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o
obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.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.o

View File

@@ -25,17 +25,13 @@
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/utsname.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/usb/android.h>
#include <linux/usb/android_composite.h>
#include <linux/usb/ch9.h>
#include <linux/usb/composite.h>
#include <linux/usb/gadget.h>
#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");
ret = mass_storage_function_add(dev->cdev, c, dev->nluns);
if (ret)
return ret;
return adb_function_add(dev->cdev, c);
printk(KERN_DEBUG "android_bind_config\n");
dev->config = 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;

View File

@@ -17,6 +17,7 @@
#include "u_serial.h"
#include "gadget_chips.h"
#include "linux/usb/android_composite.h"
/*
@@ -762,11 +763,22 @@ int __init 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);

View File

@@ -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 */

View File

@@ -30,11 +30,7 @@
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/usb/ch9.h>
#include <linux/usb/composite.h>
#include <linux/usb/gadget.h>
#include "f_adb.h"
#include <linux/usb/android_composite.h>
#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)
static struct android_usb_function adb_function = {
.name = "adb",
.bind_config = adb_bind_config,
};
static int __init init(void)
{
struct adb_dev *dev = _adb_dev;
if (dev) {
DBG(dev->cdev, "adb_function_enable(%s)\n",
enable ? "true" : "false");
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;
}
}
printk(KERN_INFO "f_adb init\n");
android_register_function(&adb_function);
return 0;
}
module_init(init);

View File

@@ -1,25 +0,0 @@
/*
* Gadget Driver for Android ADB
*
* Copyright (C) 2008 Google, Inc.
* Author: Mike Lockwood <lockwood@android.com>
*
* 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 */

View File

@@ -73,9 +73,8 @@
#include <linux/usb/ch9.h>
#include <linux/usb/composite.h>
#include <linux/usb/gadget.h>
#include <linux/usb/android.h>
#include <linux/usb/android_composite.h>
#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);

View File

@@ -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 <lockwood@android.com>
*
* 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 */

View File

@@ -1,50 +0,0 @@
/*
* Platform data for Android USB
*
* Copyright (C) 2008 Google, Inc.
* Author: Mike Lockwood <lockwood@android.com>
*
* 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 */

View File

@@ -0,0 +1,90 @@
/*
* Platform data for Android USB
*
* Copyright (C) 2008 Google, Inc.
* Author: Mike Lockwood <lockwood@android.com>
*
* 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 <linux/usb/composite.h>
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 */