diff options
author | Arve Hjønnevåg <arve@android.com> | 2013-05-16 20:27:45 -0700 |
---|---|---|
committer | Paul Kocialkowski <contact@paulk.fr> | 2014-05-02 20:52:58 +0200 |
commit | 455985996072d8fc49f9540cf07cde609b05aedd (patch) | |
tree | 55b7e8029786999a4ea6195b6e9e1c7baa7c0cef | |
parent | 609fc33db8e07d216033c1dc4600134ae15f3c5b (diff) | |
download | kernel_goldelico_gta04-455985996072d8fc49f9540cf07cde609b05aedd.zip kernel_goldelico_gta04-455985996072d8fc49f9540cf07cde609b05aedd.tar.gz kernel_goldelico_gta04-455985996072d8fc49f9540cf07cde609b05aedd.tar.bz2 |
usb: gadget: android: 3.10 fixes
Signed-off-by: Arve Hjønnevåg <arve@android.com>
-rw-r--r-- | drivers/usb/gadget/Kconfig | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/android.c | 73 | ||||
-rw-r--r-- | drivers/usb/gadget/u_serial.c | 4 |
3 files changed, 58 insertions, 21 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 93e8fdb..c0f7898 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -959,7 +959,9 @@ config USB_G_PRINTER config USB_G_ANDROID boolean "Android Composite Gadget" + select USB_F_ACM select USB_LIBCOMPOSITE + select USB_U_SERIAL help The Android Composite Gadget supports multiple USB functions: adb, acm, mass storage, mtp, accessory diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c index f5b00c1..d0ec54b 100644 --- a/drivers/usb/gadget/android.c +++ b/drivers/usb/gadget/android.c @@ -33,9 +33,6 @@ #include "f_fs.c" #include "f_audio_source.c" #include "f_mass_storage.c" -#include "u_serial.c" -#define USB_FACM_INCLUDED -#include "f_acm.c" #include "f_mtp.c" #include "f_accessory.c" #define USB_ETH_RNDIS y @@ -367,7 +364,9 @@ static void functionfs_release_dev_callback(struct ffs_data *ffs_data) #define MAX_ACM_INSTANCES 4 struct acm_function_config { int instances; - unsigned char port_num[MAX_ACM_INSTANCES]; + int instances_on; + struct usb_function *f_acm[MAX_ACM_INSTANCES]; + struct usb_function_instance *f_acm_inst[MAX_ACM_INSTANCES]; }; static int @@ -384,14 +383,24 @@ acm_function_init(struct android_usb_function *f, f->config = config; for (i = 0; i < MAX_ACM_INSTANCES; i++) { - ret = gserial_alloc_line(&config->port_num[i]); - if (ret) - goto err_alloc_line; + config->f_acm_inst[i] = usb_get_function_instance("acm"); + if (IS_ERR(config->f_acm_inst[i])) { + ret = PTR_ERR(config->f_acm_inst[i]); + goto err_usb_get_function_instance; + } + config->f_acm[i] = usb_get_function(config->f_acm_inst[i]); + if (IS_ERR(config->f_acm[i])) { + ret = PTR_ERR(config->f_acm[i]); + goto err_usb_get_function; + } } return 0; -err_alloc_line: - while (i-- > 0) - gserial_free_line(config->port_num[i]); +err_usb_get_function_instance: + while (i-- > 0) { + usb_put_function(config->f_acm[i]); +err_usb_get_function: + usb_put_function_instance(config->f_acm_inst[i]); + } return ret; } @@ -400,8 +409,10 @@ static void acm_function_cleanup(struct android_usb_function *f) int i; struct acm_function_config *config = f->config; - for (i = 0; i < MAX_ACM_INSTANCES; i++) - gserial_free_line(config->port_num[i]); + for (i = 0; i < MAX_ACM_INSTANCES; i++) { + usb_put_function(config->f_acm[i]); + usb_put_function_instance(config->f_acm_inst[i]); + } kfree(f->config); f->config = NULL; } @@ -414,17 +425,33 @@ acm_function_bind_config(struct android_usb_function *f, int ret = 0; struct acm_function_config *config = f->config; - for (i = 0; i < config->instances; i++) { - ret = acm_bind_config(c, i); + config->instances_on = config->instances; + for (i = 0; i < config->instances_on; i++) { + ret = usb_add_function(c, config->f_acm[i]); if (ret) { pr_err("Could not bind acm%u config\n", i); - break; + goto err_usb_add_function; } } + return 0; + +err_usb_add_function: + while (i-- > 0) + usb_remove_function(c, config->f_acm[i]); return ret; } +static void acm_function_unbind_config(struct android_usb_function *f, + struct usb_configuration *c) +{ + int i; + struct acm_function_config *config = f->config; + + for (i = 0; i < config->instances_on; i++) + usb_remove_function(c, config->f_acm[i]); +} + static ssize_t acm_instances_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -459,6 +486,7 @@ static struct android_usb_function acm_function = { .init = acm_function_init, .cleanup = acm_function_cleanup, .bind_config = acm_function_bind_config, + .unbind_config = acm_function_unbind_config, .attributes = acm_function_attributes, }; @@ -532,6 +560,7 @@ struct rndis_function_config { char manufacturer[256]; /* "Wireless" RNDIS; auto-detected by Windows */ bool wceis; + struct eth_dev *dev; }; static int @@ -555,6 +584,7 @@ rndis_function_bind_config(struct android_usb_function *f, struct usb_configuration *c) { int ret; + struct eth_dev *dev; struct rndis_function_config *rndis = f->config; if (!rndis) { @@ -566,11 +596,13 @@ rndis_function_bind_config(struct android_usb_function *f, rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2], rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]); - ret = gether_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis"); - if (ret) { + dev = gether_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis"); + if (IS_ERR(dev)) { + ret = PTR_ERR(dev); pr_err("%s: gether_setup failed\n", __func__); return ret; } + rndis->dev = dev; if (rndis->wceis) { /* "Wireless" RNDIS; auto-detected by Windows */ @@ -585,13 +617,14 @@ rndis_function_bind_config(struct android_usb_function *f, } return rndis_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID, - rndis->manufacturer); + rndis->manufacturer, rndis->dev); } static void rndis_function_unbind_config(struct android_usb_function *f, struct usb_configuration *c) { - gether_cleanup(); + struct rndis_function_config *rndis = f->config; + gether_cleanup(rndis->dev); } static ssize_t rndis_manufacturer_show(struct device *dev, @@ -881,7 +914,7 @@ static ssize_t audio_source_pcm_show(struct device *dev, return sprintf(buf, "%d %d\n", config->card, config->device); } -static DEVICE_ATTR(pcm, S_IRUGO | S_IWUSR, audio_source_pcm_show, NULL); +static DEVICE_ATTR(pcm, S_IRUGO, audio_source_pcm_show, NULL); static struct device_attribute *audio_source_function_attributes[] = { &dev_attr_pcm, diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 5946eb4..7206808 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -1124,7 +1124,9 @@ int gserial_alloc_line(unsigned char *line_num) /* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */ - tty_dev = tty_register_device(gs_tty_driver, port_num, NULL); + tty_dev = tty_port_register_device(&ports[port_num].port->port, + gs_tty_driver, port_num, NULL); + if (IS_ERR(tty_dev)) { struct gs_port *port; pr_err("%s: failed to register tty for port %d, err %ld\n", |