Skip to content

Commit 3131f16

Browse files
committedMar 28, 2016
Add functionfs support to usb gadget
1 parent 5459f77 commit 3131f16

File tree

2 files changed

+195
-7
lines changed

2 files changed

+195
-7
lines changed
 

‎drivers/usb/gadget/android.c

+194-7
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
#include "f_uac1.c"
9595
#endif
9696
#include "f_ncm.c"
97+
#include "f_fs.c"
9798

9899
MODULE_AUTHOR("Mike Lockwood");
99100
MODULE_DESCRIPTION("Android Composite USB Driver");
@@ -207,6 +208,8 @@ struct android_dev {
207208
struct pm_qos_request pm_qos_req_dma;
208209
struct work_struct work;
209210

211+
char ffs_aliases[256];
212+
210213
/* A list of struct android_configuration */
211214
struct list_head configs;
212215
int configs_num;
@@ -235,6 +238,7 @@ struct android_configuration {
235238

236239
struct dload_struct __iomem *diag_dload;
237240
static struct class *android_class;
241+
static struct android_dev *_android_dev;
238242
static struct list_head android_dev_list;
239243
static int android_dev_count;
240244
static int android_bind_config(struct usb_configuration *c);
@@ -2159,6 +2163,162 @@ static struct android_usb_function usbnet_function = {
21592163
.ctrlrequest = usbnet_function_ctrlrequest,
21602164
};
21612165

2166+
/* functionfs */
2167+
struct functionfs_config {
2168+
bool opened;
2169+
bool enabled;
2170+
struct ffs_data *data;
2171+
};
2172+
2173+
static int functionfs_check_dev_callback(const char *dev_name)
2174+
{
2175+
return 0;
2176+
}
2177+
2178+
static int ffs_function_init(struct android_usb_function *f,
2179+
struct usb_composite_dev *cdev)
2180+
{
2181+
if(!_android_dev)
2182+
_android_dev = cdev_to_android_dev(cdev);
2183+
2184+
f->config = kzalloc(sizeof(struct functionfs_config), GFP_KERNEL);
2185+
if (!f->config)
2186+
return -ENOMEM;
2187+
2188+
return functionfs_init();
2189+
}
2190+
2191+
static void ffs_function_cleanup(struct android_usb_function *f)
2192+
{
2193+
functionfs_cleanup();
2194+
kfree(f->config);
2195+
_android_dev = NULL;
2196+
}
2197+
2198+
static void ffs_function_enable(struct android_usb_function *f)
2199+
{
2200+
struct android_dev *dev = _android_dev;
2201+
struct functionfs_config *config = f->config;
2202+
2203+
config->enabled = true;
2204+
2205+
/* Disable the gadget until the function is ready */
2206+
if (!config->opened)
2207+
android_disable(dev);
2208+
}
2209+
2210+
static void ffs_function_disable(struct android_usb_function *f)
2211+
{
2212+
struct android_dev *dev = _android_dev;
2213+
struct functionfs_config *config = f->config;
2214+
2215+
config->enabled = false;
2216+
2217+
/* Balance the disable that was called in closed_callback */
2218+
if (!config->opened)
2219+
android_enable(dev);
2220+
}
2221+
2222+
static int ffs_function_bind_config(struct android_usb_function *f,
2223+
struct usb_configuration *c)
2224+
{
2225+
struct functionfs_config *config = f->config;
2226+
return functionfs_bind_config(c->cdev, c, config->data);
2227+
}
2228+
2229+
static ssize_t
2230+
ffs_aliases_show(struct device *pdev, struct device_attribute *attr, char *buf)
2231+
{
2232+
struct android_dev *dev = _android_dev;
2233+
int ret;
2234+
2235+
mutex_lock(&dev->mutex);
2236+
ret = sprintf(buf, "%s\n", dev->ffs_aliases);
2237+
mutex_unlock(&dev->mutex);
2238+
2239+
return ret;
2240+
}
2241+
2242+
static ssize_t
2243+
ffs_aliases_store(struct device *pdev, struct device_attribute *attr,
2244+
const char *buf, size_t size)
2245+
{
2246+
struct android_dev *dev = _android_dev;
2247+
char buff[256];
2248+
2249+
mutex_lock(&dev->mutex);
2250+
2251+
if (dev->enabled) {
2252+
mutex_unlock(&dev->mutex);
2253+
return -EBUSY;
2254+
}
2255+
2256+
strlcpy(buff, buf, sizeof(buff));
2257+
strlcpy(dev->ffs_aliases, strim(buff), sizeof(dev->ffs_aliases));
2258+
2259+
mutex_unlock(&dev->mutex);
2260+
2261+
return size;
2262+
}
2263+
2264+
static DEVICE_ATTR(aliases, S_IRUGO | S_IWUSR, ffs_aliases_show,
2265+
ffs_aliases_store);
2266+
static struct device_attribute *ffs_function_attributes[] = {
2267+
&dev_attr_aliases,
2268+
NULL
2269+
};
2270+
2271+
static struct android_usb_function ffs_function = {
2272+
.name = "ffs",
2273+
.init = ffs_function_init,
2274+
.enable = ffs_function_enable,
2275+
.disable = ffs_function_disable,
2276+
.cleanup = ffs_function_cleanup,
2277+
.bind_config = ffs_function_bind_config,
2278+
.attributes = ffs_function_attributes,
2279+
};
2280+
2281+
static int functionfs_ready_callback(struct ffs_data *ffs)
2282+
{
2283+
struct android_dev *dev = _android_dev;
2284+
struct functionfs_config *config = ffs_function.config;
2285+
int ret = 0;
2286+
2287+
mutex_lock(&dev->mutex);
2288+
2289+
ret = functionfs_bind(ffs, dev->cdev);
2290+
if (ret)
2291+
goto err;
2292+
2293+
config->data = ffs;
2294+
config->opened = true;
2295+
2296+
if (config->enabled)
2297+
android_enable(dev);
2298+
2299+
err:
2300+
mutex_unlock(&dev->mutex);
2301+
return ret;
2302+
}
2303+
2304+
static void functionfs_closed_callback(struct ffs_data *ffs)
2305+
{
2306+
struct android_dev *dev =_android_dev;
2307+
struct functionfs_config *config = ffs_function.config;
2308+
2309+
mutex_lock(&dev->mutex);
2310+
2311+
if (config->enabled)
2312+
android_disable(dev);
2313+
2314+
config->opened = false;
2315+
config->data = NULL;
2316+
2317+
functionfs_unbind(ffs);
2318+
2319+
mutex_unlock(&dev->mutex);
2320+
}
2321+
21622322
static struct android_usb_function *supported_functions[] = {
21632323
&mbim_function,
21642324
&ecm_qc_function,
@@ -2189,6 +2349,7 @@ static struct android_usb_function *supported_functions[] = {
21892349
#endif
21902350
&uasp_function,
21912351
&usbnet_function,
2352+
&ffs_function,
21922353
NULL
21932354
};
21942355

@@ -2465,9 +2626,12 @@ functions_store(struct device *pdev, struct device_attribute *attr,
24652626
struct android_configuration *conf;
24662627
char *conf_str;
24672628
struct android_usb_function_holder *f_holder;
2468-
char *name;
2629+
char *name = NULL;
2630+
char aliases[256], *a;
24692631
char buf[256], *b;
24702632
int err;
2633+
int is_ffs;
2634+
int ffs_enabled = 0;
24712635

24722636
mutex_lock(&dev->mutex);
24732637

@@ -2510,12 +2674,35 @@ functions_store(struct device *pdev, struct device_attribute *attr,
25102674

25112675
while (conf_str) {
25122676
name = strsep(&conf_str, ",");
2513-
if (name) {
2514-
err = android_enable_function(dev, conf, name);
2515-
if (err)
2516-
pr_err("android_usb: Cannot enable %s",
2517-
name);
2518-
}
2677+
if (!name)
2678+
continue;
2679+
2680+
is_ffs = 0;
2681+
strlcpy(aliases, dev->ffs_aliases, sizeof(aliases));
2682+
a = aliases;
2683+
2684+
while (a) {
2685+
char *alias = strsep(&a, ",");
2686+
if (alias && !strcmp(name, alias)) {
2687+
is_ffs = 1;
2688+
break;
2689+
}
2690+
}
2691+
2692+
if (is_ffs) {
2693+
if (ffs_enabled)
2694+
continue;
2695+
err = android_enable_function(dev, conf, "ffs");
2696+
if (err)
2697+
pr_err("android_usb: Cannot enable ffs (%d)", err);
2698+
else
2699+
ffs_enabled = 1;
2700+
continue;
2701+
}
2702+
2703+
err = android_enable_function(dev, conf, name);
2704+
if (err)
2705+
pr_err("android_usb: Cannot enable %s (%d)", name, err);
25192706
}
25202707
}
25212708

‎drivers/usb/gadget/f_fs.c

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
# define ffs_dump_mem(prefix, ptr, len) \
3838
print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len)
3939
#else
40+
#undef pr_vdebug
4041
# define pr_vdebug(...) do { } while (0)
4142
# define ffs_dump_mem(prefix, ptr, len) do { } while (0)
4243
#endif /* VERBOSE_DEBUG */

0 commit comments

Comments
 (0)
Please sign in to comment.