diff options
author | Sakethram Bommisetti <sakethram.bommisetti@stericsson.com> | 2011-09-06 19:16:35 +0530 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@stericsson.com> | 2011-09-19 16:07:23 +0200 |
commit | 66f9d0923890085da40fa908b8619e029fe824af (patch) | |
tree | 70ae36a7acdf283fc567131c00ed0af032f8776b /drivers/usb | |
parent | 6b1cb7c41d42f2dd1089203951c19590f5e89fca (diff) |
USB:Composite Driver Patch
Added code for ECM.
Mass Storage supports 2 luns by default.
ST-Ericsson ID: 259958
Signed-off-by: Sakethram Bommisetti <sakethram.bommisetti@stericsson.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/android.c | 147 |
1 files changed, 146 insertions, 1 deletions
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c index 8cb5aae5994..15977c311db 100644 --- a/drivers/usb/gadget/android.c +++ b/drivers/usb/gadget/android.c @@ -54,6 +54,7 @@ #define USB_ETH_RNDIS y #include "f_rndis.c" #include "rndis.c" +#include "f_ecm.c" #include "u_ether.c" MODULE_AUTHOR("Mike Lockwood"); @@ -336,6 +337,148 @@ static struct android_usb_function ptp_function = { .bind_config = ptp_function_bind_config, }; +struct ecm_function_config { + u8 ethaddr[ETH_ALEN]; + u32 vendorID; + char manufacturer[256];; +}; +static int ecm_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) +{ + f->config = kzalloc(sizeof(struct ecm_function_config), GFP_KERNEL); + if (!f->config) + return -ENOMEM; + return 0; +} + +static void ecm_function_cleanup(struct android_usb_function *f) +{ + kfree(f->config); + f->config = NULL; +} + +static int ecm_function_bind_config(struct android_usb_function *f, struct usb_configuration *c) +{ + int ret = 0; + struct ecm_function_config *ecm = f->config; + + if (!ecm) { + pr_err("%s: ecm_pdata\n", __func__); + return -1; + } + + + pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__, + ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2], + ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]); + + ret = gether_setup(c->cdev->gadget, ecm->ethaddr); + + if (ret) { + pr_err("%s: gether_setup failed\n", __func__); + return ret; + } + + return ecm_bind_config(c, ecm->ethaddr); +} + +static void ecm_function_unbind_config(struct android_usb_function *f, + struct usb_configuration *c) +{ + gether_cleanup(); +} + +static ssize_t ecm_manufacturer_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct android_usb_function *f = dev_get_drvdata(dev); + struct ecm_function_config *config = f->config; + return sprintf(buf, "%s\n", config->manufacturer); +} + +static ssize_t ecm_manufacturer_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct android_usb_function *f = dev_get_drvdata(dev); + struct ecm_function_config *config = f->config; + + if (size >= sizeof(config->manufacturer)) + return -EINVAL; + if (sscanf(buf, "%s", config->manufacturer) == 1) + return size; + return -1; +} + +static DEVICE_ATTR(manufactur, S_IRUGO | S_IWUSR, ecm_manufacturer_show, + ecm_manufacturer_store); + +static ssize_t ecm_ethaddr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct android_usb_function *f = dev_get_drvdata(dev); + struct ecm_function_config *ecm = f->config; + return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2], + ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]); +} + +static ssize_t ecm_ethaddr_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct android_usb_function *f = dev_get_drvdata(dev); + struct ecm_function_config *ecm = f->config; + + if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + (int *)&ecm->ethaddr[0], (int *)&ecm->ethaddr[1], + (int *)&ecm->ethaddr[2], (int *)&ecm->ethaddr[3], + (int *)&ecm->ethaddr[4], (int *)&ecm->ethaddr[5]) == 6) + return size; + return -EINVAL; +} + +static DEVICE_ATTR(ethadd, S_IRUGO | S_IWUSR, ecm_ethaddr_show, + ecm_ethaddr_store); + +static ssize_t ecm_vendorID_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct android_usb_function *f = dev_get_drvdata(dev); + struct ecm_function_config *config = f->config; + return sprintf(buf, "%04x\n", config->vendorID); +} + +static ssize_t ecm_vendorID_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct android_usb_function *f = dev_get_drvdata(dev); + struct ecm_function_config *config = f->config; + int value; + + if (sscanf(buf, "%04x", &value) == 1) { + config->vendorID = value; + return size; + } + return -EINVAL; +} + +static DEVICE_ATTR(vendor, S_IRUGO | S_IWUSR, ecm_vendorID_show, + ecm_vendorID_store); + +static struct device_attribute *ecm_function_attributes[] = { + &dev_attr_ethadd, + &dev_attr_vendor, + &dev_attr_manufactur, + NULL +}; + +static struct android_usb_function ecm_function = { + .name = "ecm", + .init = ecm_function_init, + .cleanup = ecm_function_cleanup, + .bind_config = ecm_function_bind_config, + .unbind_config = ecm_function_unbind_config, + .attributes = ecm_function_attributes, +}; + struct rndis_function_config { u8 ethaddr[ETH_ALEN]; @@ -537,8 +680,9 @@ static int mass_storage_function_init(struct android_usb_function *f, if (!config) return -ENOMEM; - config->fsg.nluns = 1; + config->fsg.nluns = 2; config->fsg.luns[0].removable = 1; + config->fsg.luns[1].removable = 1; common = fsg_common_init(NULL, cdev, &config->fsg); if (IS_ERR(common)) { @@ -651,6 +795,7 @@ static struct android_usb_function *supported_functions[] = { &rndis_function, &mass_storage_function, &accessory_function, + &ecm_function, NULL }; |