mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
Merge remote branch 'common/android-2.6.32' into develop
Conflicts: drivers/usb/gadget/f_adb.c
This commit is contained in:
@@ -208,7 +208,7 @@ 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)
|
||||
if (product_has_function(p, f) == !!f->disabled)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -323,8 +323,8 @@ void android_enable_function(struct usb_function *f, int enable)
|
||||
int disable = !enable;
|
||||
int product_id;
|
||||
|
||||
if (!!f->hidden != disable) {
|
||||
f->hidden = disable;
|
||||
if (!!f->disabled != disable) {
|
||||
usb_function_set_enabled(f, !disable);
|
||||
|
||||
#ifdef CONFIG_USB_ANDROID_RNDIS
|
||||
if (!strcmp(f->name, "rndis")) {
|
||||
@@ -347,7 +347,7 @@ void android_enable_function(struct usb_function *f, int enable)
|
||||
*/
|
||||
list_for_each_entry(func, &android_config_driver.functions, list) {
|
||||
if (!strcmp(func->name, "usb_mass_storage")) {
|
||||
func->hidden = enable;
|
||||
usb_function_set_enabled(func, !enable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -358,14 +358,7 @@ void android_enable_function(struct usb_function *f, int enable)
|
||||
device_desc.idProduct = __constant_cpu_to_le16(product_id);
|
||||
if (dev->cdev)
|
||||
dev->cdev->desc.idProduct = device_desc.idProduct;
|
||||
|
||||
/* force reenumeration */
|
||||
if (dev->cdev && dev->cdev->gadget &&
|
||||
dev->cdev->gadget->speed != USB_SPEED_UNKNOWN) {
|
||||
usb_gadget_disconnect(dev->cdev->gadget);
|
||||
msleep(10);
|
||||
usb_gadget_connect(dev->cdev->gadget);
|
||||
}
|
||||
usb_composite_force_reset(dev->cdev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct usb_function *f = dev_get_drvdata(dev);
|
||||
return sprintf(buf, "%d\n", !f->hidden);
|
||||
return sprintf(buf, "%d\n", !f->disabled);
|
||||
}
|
||||
|
||||
static ssize_t enable_store(
|
||||
@@ -90,13 +90,39 @@ static ssize_t enable_store(
|
||||
if (driver->enable_function)
|
||||
driver->enable_function(f, value);
|
||||
else
|
||||
f->hidden = !value;
|
||||
usb_function_set_enabled(f, value);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
|
||||
|
||||
void usb_function_set_enabled(struct usb_function *f, int enabled)
|
||||
{
|
||||
f->disabled = !enabled;
|
||||
kobject_uevent(&f->dev->kobj, KOBJ_CHANGE);
|
||||
}
|
||||
|
||||
|
||||
void usb_composite_force_reset(struct usb_composite_dev *cdev)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&cdev->lock, flags);
|
||||
/* force reenumeration */
|
||||
if (cdev && cdev->gadget &&
|
||||
cdev->gadget->speed != USB_SPEED_UNKNOWN) {
|
||||
/* avoid sending a disconnect switch event until after we disconnect */
|
||||
cdev->mute_switch = 1;
|
||||
spin_unlock_irqrestore(&cdev->lock, flags);
|
||||
|
||||
usb_gadget_disconnect(cdev->gadget);
|
||||
msleep(10);
|
||||
usb_gadget_connect(cdev->gadget);
|
||||
} else {
|
||||
spin_unlock_irqrestore(&cdev->lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_add_function() - add a function to a configuration
|
||||
@@ -310,7 +336,7 @@ static int config_buf(struct usb_configuration *config,
|
||||
descriptors = f->hs_descriptors;
|
||||
else
|
||||
descriptors = f->descriptors;
|
||||
if (f->hidden || !descriptors || descriptors[0] == NULL)
|
||||
if (f->disabled || !descriptors || descriptors[0] == NULL)
|
||||
continue;
|
||||
status = usb_descriptor_fillbuf(next, len,
|
||||
(const struct usb_descriptor_header **) descriptors);
|
||||
@@ -481,7 +507,7 @@ static int set_config(struct usb_composite_dev *cdev,
|
||||
|
||||
if (!f)
|
||||
break;
|
||||
if (f->hidden)
|
||||
if (f->disabled)
|
||||
continue;
|
||||
|
||||
result = f->set_alt(f, tmp, 0);
|
||||
@@ -498,6 +524,8 @@ static int set_config(struct usb_composite_dev *cdev,
|
||||
power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW;
|
||||
done:
|
||||
usb_gadget_vbus_draw(gadget, power);
|
||||
|
||||
schedule_work(&cdev->switch_work);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -939,6 +967,11 @@ static void composite_disconnect(struct usb_gadget *gadget)
|
||||
spin_lock_irqsave(&cdev->lock, flags);
|
||||
if (cdev->config)
|
||||
reset_config(cdev);
|
||||
|
||||
if (cdev->mute_switch)
|
||||
cdev->mute_switch = 0;
|
||||
else
|
||||
schedule_work(&cdev->switch_work);
|
||||
spin_unlock_irqrestore(&cdev->lock, flags);
|
||||
}
|
||||
|
||||
@@ -988,6 +1021,8 @@ composite_unbind(struct usb_gadget *gadget)
|
||||
kfree(cdev->req->buf);
|
||||
usb_ep_free_request(gadget->ep0, cdev->req);
|
||||
}
|
||||
|
||||
switch_dev_unregister(&cdev->sdev);
|
||||
kfree(cdev);
|
||||
set_gadget_data(gadget, NULL);
|
||||
composite = NULL;
|
||||
@@ -1015,6 +1050,19 @@ string_override(struct usb_gadget_strings **tab, u8 id, const char *s)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
composite_switch_work(struct work_struct *data)
|
||||
{
|
||||
struct usb_composite_dev *cdev =
|
||||
container_of(data, struct usb_composite_dev, switch_work);
|
||||
struct usb_configuration *config = cdev->config;
|
||||
|
||||
if (config)
|
||||
switch_set_state(&cdev->sdev, config->bConfigurationValue);
|
||||
else
|
||||
switch_set_state(&cdev->sdev, 0);
|
||||
}
|
||||
|
||||
static int __init composite_bind(struct usb_gadget *gadget)
|
||||
{
|
||||
struct usb_composite_dev *cdev;
|
||||
@@ -1058,6 +1106,12 @@ static int __init composite_bind(struct usb_gadget *gadget)
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
|
||||
cdev->sdev.name = "usb_configuration";
|
||||
status = switch_dev_register(&cdev->sdev);
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
INIT_WORK(&cdev->switch_work, composite_switch_work);
|
||||
|
||||
cdev->desc = *composite->dev;
|
||||
cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
|
||||
|
||||
@@ -1132,6 +1186,23 @@ composite_resume(struct usb_gadget *gadget)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
composite_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct usb_function *f = dev_get_drvdata(dev);
|
||||
|
||||
if (!f) {
|
||||
/* this happens when the device is first created */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (add_uevent_var(env, "FUNCTION=%s", f->name))
|
||||
return -ENOMEM;
|
||||
if (add_uevent_var(env, "ENABLED=%d", !f->disabled))
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static struct usb_gadget_driver composite_driver = {
|
||||
@@ -1180,6 +1251,7 @@ int __init usb_composite_register(struct usb_composite_driver *driver)
|
||||
driver->class = class_create(THIS_MODULE, "usb_composite");
|
||||
if (IS_ERR(driver->class))
|
||||
return PTR_ERR(driver->class);
|
||||
driver->class->dev_uevent = composite_uevent;
|
||||
|
||||
return usb_gadget_register_driver(&composite_driver);
|
||||
}
|
||||
|
||||
@@ -612,7 +612,7 @@ static int adb_bind_config(struct usb_configuration *c)
|
||||
dev->function.disable = adb_function_disable;
|
||||
|
||||
/* start disabled */
|
||||
dev->function.hidden = 0;
|
||||
dev->function.disabled = 1;
|
||||
|
||||
/* _adb_dev must be set before calling usb_gadget_register_driver */
|
||||
_adb_dev = dev;
|
||||
|
||||
@@ -840,7 +840,7 @@ int __init rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
|
||||
|
||||
#ifdef CONFIG_USB_ANDROID_RNDIS
|
||||
/* start disabled */
|
||||
rndis->port.func.hidden = 1;
|
||||
rndis->port.func.disabled = 1;
|
||||
#endif
|
||||
|
||||
status = usb_add_function(c, &rndis->port.func);
|
||||
|
||||
@@ -36,8 +36,10 @@
|
||||
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
#include <linux/switch.h>
|
||||
|
||||
|
||||
struct usb_composite_dev;
|
||||
struct usb_configuration;
|
||||
|
||||
/**
|
||||
@@ -100,7 +102,9 @@ struct usb_function {
|
||||
struct usb_descriptor_header **hs_descriptors;
|
||||
|
||||
struct usb_configuration *config;
|
||||
int hidden;
|
||||
|
||||
/* disabled is zero if the function is enabled */
|
||||
int disabled;
|
||||
|
||||
/* REVISIT: bind() functions can be marked __init, which
|
||||
* makes trouble for section mismatch analysis. See if
|
||||
@@ -138,6 +142,9 @@ int usb_function_activate(struct usb_function *);
|
||||
|
||||
int usb_interface_id(struct usb_configuration *, struct usb_function *);
|
||||
|
||||
void usb_function_set_enabled(struct usb_function *, int);
|
||||
void usb_composite_force_reset(struct usb_composite_dev *);
|
||||
|
||||
/**
|
||||
* ep_choose - select descriptor endpoint at current device speed
|
||||
* @g: gadget, connected and running at some speed
|
||||
@@ -344,6 +351,11 @@ struct usb_composite_dev {
|
||||
|
||||
/* protects at least deactivation count */
|
||||
spinlock_t lock;
|
||||
|
||||
struct switch_dev sdev;
|
||||
/* used by usb_composite_force_reset to avoid signalling switch changes */
|
||||
bool mute_switch;
|
||||
struct work_struct switch_work;
|
||||
};
|
||||
|
||||
extern int usb_string_id(struct usb_composite_dev *c);
|
||||
|
||||
Reference in New Issue
Block a user