diff options
author | John Stultz <john.stultz@linaro.org> | 2014-03-28 16:32:33 -0700 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2014-03-28 17:05:53 -0700 |
commit | 47f51bdd492879ef89b9016ad2b288faf0a70bcc (patch) | |
tree | 911ccf3332545cdf1d07b856dda0ba4678b4b811 | |
parent | e2ef3735b676024a6771497a15bf4b45f0cf4f68 (diff) |
gadget: Numerous build fixestracking-linaro-android-3.14-llct-20140331.0
Here are some of the build fixes we're using at Linaro.
I suspect much of this is incorrect, but wanted to submit it
as a starting place to get things fixed.
Change-Id: Id471d3004eef2aa2a6317950f434ad2b549b9dfc
Signed-off-by: John Stultz <john.stultz@linaro.org>
-rw-r--r-- | drivers/usb/gadget/Kconfig | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/android.c | 101 | ||||
-rw-r--r-- | drivers/usb/gadget/f_fs.c | 90 | ||||
-rw-r--r-- | drivers/usb/gadget/f_rndis.c | 56 |
4 files changed, 219 insertions, 30 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index e272b648d329..d8e4660faf47 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -1024,6 +1024,8 @@ config USB_G_ANDROID select USB_F_ACM select USB_LIBCOMPOSITE select USB_U_SERIAL + select USB_F_MASS_STORAGE + select SND_PCM 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 a74ae6b26ea9..91f0efdabc8a 100644 --- a/drivers/usb/gadget/android.c +++ b/drivers/usb/gadget/android.c @@ -32,7 +32,6 @@ #include "f_fs.c" #include "f_audio_source.c" -#include "f_mass_storage.c" #include "f_mtp.c" #include "f_accessory.c" #define USB_ETH_RNDIS y @@ -40,6 +39,8 @@ #include "rndis.c" #include "u_ether.c" +USB_ETHERNET_MODULE_PARAMETERS(); + MODULE_AUTHOR("Mike Lockwood"); MODULE_DESCRIPTION("Android Composite USB Driver"); MODULE_LICENSE("GPL"); @@ -596,7 +597,7 @@ 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]); - dev = gether_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis"); + dev = gether_setup_name(c->cdev->gadget,dev_addr, host_addr, rndis->ethaddr, qmult, "rndis"); if (IS_ERR(dev)) { ret = PTR_ERR(dev); pr_err("%s: gether_setup failed\n", __func__); @@ -746,47 +747,58 @@ static struct android_usb_function rndis_function = { }; +#define MAX_MS_INSTANCES 1 struct mass_storage_function_config { - struct fsg_config fsg; - struct fsg_common *common; + int instances; + int instances_on; + struct usb_function *f_ms[MAX_MS_INSTANCES]; + struct usb_function_instance *f_ms_inst[MAX_MS_INSTANCES]; }; static int mass_storage_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) { struct mass_storage_function_config *config; - struct fsg_common *common; - int err; + int i; + int ret; config = kzalloc(sizeof(struct mass_storage_function_config), GFP_KERNEL); if (!config) return -ENOMEM; + f->config = config; - config->fsg.nluns = 1; - config->fsg.luns[0].removable = 1; - - common = fsg_common_init(NULL, cdev, &config->fsg); - if (IS_ERR(common)) { - kfree(config); - return PTR_ERR(common); - } - - err = sysfs_create_link(&f->dev->kobj, - &common->luns[0].dev.kobj, - "lun"); - if (err) { - kfree(config); - return err; + for (i = 0; i < MAX_MS_INSTANCES; i++) { + config->f_ms_inst[i] = usb_get_function_instance("mass_storage"); + if (IS_ERR(config->f_ms_inst[i])) { + ret = PTR_ERR(config->f_ms_inst[i]); + goto err_usb_get_function_instance; + } + config->f_ms[i] = usb_get_function(config->f_ms_inst[i]); + if (IS_ERR(config->f_ms[i])) { + ret = PTR_ERR(config->f_ms[i]); + goto err_usb_get_function; + } } - - config->common = common; - f->config = config; return 0; +err_usb_get_function_instance: + while (i-- > 0) { + usb_put_function(config->f_ms[i]); +err_usb_get_function: + usb_put_function_instance(config->f_ms_inst[i]); + } + return ret; } static void mass_storage_function_cleanup(struct android_usb_function *f) { + struct mass_storage_function_config *config = f->config; + int i; + + for (i = 0; i < MAX_MS_INSTANCES; i++) { + usb_put_function(config->f_ms[i]); + usb_put_function_instance(config->f_ms_inst[i]); + } kfree(f->config); f->config = NULL; } @@ -795,7 +807,34 @@ static int mass_storage_function_bind_config(struct android_usb_function *f, struct usb_configuration *c) { struct mass_storage_function_config *config = f->config; - return fsg_bind_config(c->cdev, c, config->common); + int ret = 0; + int i; + + config->instances_on = config->instances; + for (i = 0; i < config->instances_on; i++) { + ret = usb_add_function(c, config->f_ms[i]); + if (ret) { + pr_err("Could not bind ms%u config\n", i); + goto err_usb_add_function; + } + } + + return 0; + +err_usb_add_function: + while (i-- > 0) + usb_remove_function(c, config->f_ms[i]); + return ret; +} + +static void mass_storage_function_unbind_config(struct android_usb_function *f, + struct usb_configuration *c) +{ + int i; + struct mass_storage_function_config *config = f->config; + + for (i = 0; i < config->instances_on; i++) + usb_remove_function(c, config->f_ms[i]); } static ssize_t mass_storage_inquiry_show(struct device *dev, @@ -803,7 +842,7 @@ static ssize_t mass_storage_inquiry_show(struct device *dev, { struct android_usb_function *f = dev_get_drvdata(dev); struct mass_storage_function_config *config = f->config; - return sprintf(buf, "%s\n", config->common->inquiry_string); + return sprintf(buf, "%d\n", config->instances); } static ssize_t mass_storage_inquiry_store(struct device *dev, @@ -811,10 +850,12 @@ static ssize_t mass_storage_inquiry_store(struct device *dev, { struct android_usb_function *f = dev_get_drvdata(dev); struct mass_storage_function_config *config = f->config; - if (size >= sizeof(config->common->inquiry_string)) - return -EINVAL; - if (sscanf(buf, "%s", config->common->inquiry_string) != 1) - return -EINVAL; + int value; + + sscanf(buf, "%d", &value); + if (value > MAX_MS_INSTANCES) + value = MAX_MS_INSTANCES; + config->instances = value; return size; } diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 663078c0dafe..ebbae4667b11 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -98,12 +98,15 @@ static struct ffs_function *ffs_func_from_usb(struct usb_function *f) return container_of(f, struct ffs_function, function); } +static void ffs_func_free(struct ffs_function *func); static void ffs_func_eps_disable(struct ffs_function *func); static int __must_check ffs_func_eps_enable(struct ffs_function *func); static int ffs_func_bind(struct usb_configuration *, struct usb_function *); +static void old_ffs_func_unbind(struct usb_configuration *, + struct usb_function *); static int ffs_func_set_alt(struct usb_function *, unsigned, unsigned); static void ffs_func_disable(struct usb_function *); static int ffs_func_setup(struct usb_function *, @@ -1302,6 +1305,73 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count) } +static int functionfs_bind_config(struct usb_composite_dev *cdev, + struct usb_configuration *c, + struct ffs_data *ffs) +{ + struct ffs_function *func; + int ret; + + ENTER(); + + func = kzalloc(sizeof *func, GFP_KERNEL); + if (unlikely(!func)) + return -ENOMEM; + + func->function.name = "Function FS Gadget"; + func->function.strings = ffs->stringtabs; + + func->function.bind = ffs_func_bind; + func->function.unbind = old_ffs_func_unbind; + func->function.set_alt = ffs_func_set_alt; + func->function.disable = ffs_func_disable; + func->function.setup = ffs_func_setup; + func->function.suspend = ffs_func_suspend; + func->function.resume = ffs_func_resume; + + func->conf = c; + func->gadget = cdev->gadget; + func->ffs = ffs; + ffs_data_get(ffs); + + ret = usb_add_function(c, &func->function); + if (unlikely(ret)) + ffs_func_free(func); + + return ret; +} + +static void ffs_func_free(struct ffs_function *func) +{ + struct ffs_ep *ep = func->eps; + unsigned count = func->ffs->eps_count; + unsigned long flags; + + ENTER(); + + /* cleanup after autoconfig */ + spin_lock_irqsave(&func->ffs->eps_lock, flags); + do { + if (ep->ep && ep->req) + usb_ep_free_request(ep->ep, ep->req); + ep->req = NULL; + ++ep; + } while (--count); + spin_unlock_irqrestore(&func->ffs->eps_lock, flags); + + ffs_data_put(func->ffs); + + kfree(func->eps); + /* + * eps and interfaces_nums are allocated in the same chunk so + * only one free is required. Descriptors are also allocated + * in the same chunk. + */ + + kfree(func); +} + + static void ffs_func_eps_disable(struct ffs_function *func) { struct ffs_ep *ep = func->eps; @@ -2133,6 +2203,26 @@ static int ffs_func_bind(struct usb_configuration *c, /* Other USB function hooks *************************************************/ + +static void old_ffs_func_unbind(struct usb_configuration *c, + struct usb_function *f) +{ + struct ffs_function *func = ffs_func_from_usb(f); + struct ffs_data *ffs = func->ffs; + + ENTER(); + + if (ffs->func == func) { + ffs_func_eps_disable(func); + ffs->func = NULL; + } + + ffs_event_add(ffs, FUNCTIONFS_UNBIND); + + ffs_func_free(func); +} + + static int ffs_func_set_alt(struct usb_function *f, unsigned interface, unsigned alt) { diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index c11761ce5113..a3a220890b58 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -822,6 +822,62 @@ fail: return status; } +static void +rndis_old_unbind(struct usb_configuration *c, struct usb_function *f) +{ + struct f_rndis *rndis = func_to_rndis(f); + + rndis_deregister(rndis->config); + + usb_free_all_descriptors(f); + + kfree(rndis->notify_req->buf); + usb_ep_free_request(rndis->notify, rndis->notify_req); + + kfree(rndis); +} + +int +rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], + u32 vendorID, const char *manufacturer, struct eth_dev *dev) +{ + struct f_rndis *rndis; + int status; + + /* allocate and initialize one new instance */ + status = -ENOMEM; + rndis = kzalloc(sizeof *rndis, GFP_KERNEL); + if (!rndis) + goto fail; + + memcpy(rndis->ethaddr, ethaddr, ETH_ALEN); + rndis->vendorID = vendorID; + rndis->manufacturer = manufacturer; + + rndis->port.ioport = dev; + /* RNDIS activates when the host changes this filter */ + rndis->port.cdc_filter = 0; + + /* RNDIS has special (and complex) framing */ + rndis->port.header_len = sizeof(struct rndis_packet_msg_type); + rndis->port.wrap = rndis_add_header; + rndis->port.unwrap = rndis_rm_hdr; + + rndis->port.func.name = "rndis"; + /* descriptors are per-instance copies */ + rndis->port.func.bind = rndis_bind; + rndis->port.func.unbind = rndis_old_unbind; + rndis->port.func.set_alt = rndis_set_alt; + rndis->port.func.setup = rndis_setup; + rndis->port.func.disable = rndis_disable; + + status = usb_add_function(c, &rndis->port.func); + if (status) + kfree(rndis); +fail: + return status; +} + void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net) { struct f_rndis_opts *opts; |