Loading...
Searching...
No Matches
gadget-ffs.c

This is an example of how to create gadget with FunctionFS based functions in two ways. After executing this program gadget will not be enabled because ffs instances should be mounted and both descriptors and strings should be written to ep0. For more details about FunctionFS please refer to FunctionFS documentation in linux kernel repository.

/*
* Copyright (C) 2014 Samsung Electronics
*
* Krzysztof Opasiak <k.opasiak@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <errno.h>
#include <stdio.h>
#include <linux/usb/ch9.h>
#include <usbg/usbg.h>
#define VENDOR 0x1d6b
#define PRODUCT 0x0104
int main(void)
{
usbg_state *s;
usbg_gadget *g;
usbg_config *c;
usbg_function *f_ffs1, *f_ffs2;
int ret = -EINVAL;
int usbg_ret;
struct usbg_gadget_attrs g_attrs = {
.bcdUSB = 0x0200,
.bDeviceClass = USB_CLASS_PER_INTERFACE,
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00,
.bMaxPacketSize0 = 64, /* Max allowed ep0 packet size */
.idVendor = VENDOR,
.idProduct = PRODUCT,
.bcdDevice = 0x0001, /* Verson of device */
};
struct usbg_gadget_strs g_strs = {
.serial = "0123456789", /* Serial number */
.manufacturer = "Foo Inc.", /* Manufacturer */
.product = "Bar Gadget" /* Product string */
};
struct usbg_config_strs c_strs = {
.configuration = "2xFFS"
};
usbg_ret = usbg_init("/sys/kernel/config", &s);
if (usbg_ret != USBG_SUCCESS) {
fprintf(stderr, "Error on USB gadget init\n");
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
usbg_strerror(usbg_ret));
goto out1;
}
usbg_ret = usbg_create_gadget(s, "g1", &g_attrs, &g_strs, &g);
if (usbg_ret != USBG_SUCCESS) {
fprintf(stderr, "Error on create gadget\n");
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
usbg_strerror(usbg_ret));
goto out2;
}
usbg_ret = usbg_create_function(g, USBG_F_FFS, "my_dev_name", NULL, &f_ffs1);
if (usbg_ret != USBG_SUCCESS) {
fprintf(stderr, "Error creating ffs1 function\n");
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
usbg_strerror(usbg_ret));
goto out2;
}
usbg_ret = usbg_create_function(g, USBG_F_FFS, "my_other_dev_name",
NULL, &f_ffs2);
if (usbg_ret != USBG_SUCCESS) {
fprintf(stderr, "Error creating ffs2 function\n");
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
usbg_strerror(usbg_ret));
goto out2;
}
/* NULL can be passed to use kernel defaults */
usbg_ret = usbg_create_config(g, 1, "The only one", NULL, &c_strs, &c);
if (usbg_ret != USBG_SUCCESS) {
fprintf(stderr, "Error creating config\n");
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
usbg_strerror(usbg_ret));
goto out2;
}
usbg_ret = usbg_add_config_function(c, "some_name_here", f_ffs1);
if (usbg_ret != USBG_SUCCESS) {
fprintf(stderr, "Error adding ffs1\n");
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
usbg_strerror(usbg_ret));
goto out2;
}
usbg_ret = usbg_add_config_function(c, "some_name_here_too", f_ffs2);
if (usbg_ret != USBG_SUCCESS) {
fprintf(stderr, "Error adding ffs2\n");
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
usbg_strerror(usbg_ret));
goto out2;
}
fprintf(stdout, "2xFFS gadget has been created.\n"
"Enable it after preparing your functions.\n");
/*
* Here we end up with two created ffs instances but they are not
* fully operational. Now we have to do step by step:
* 1) Mount both instances:
* $ mount my_dev_name -t functionfs /path/to/mount/dir1
* $ mount my_awesome_dev_name -t functionfs /path/to/mount/dir2
*
* 2) Run ffs daemons for both instances:
* $ my-ffs-daemon /path/to/mount/dir1
* $ my-ffs-daemon /path/to/mount/dir2
*
* 3) Enable your gadget:
* $ echo "my_udc_name" > /sys/kernel/config/usb_gadget/g1/UDC
*/
ret = 0;
out2:
usbg_cleanup(s);
out1:
return ret;
}
usbg_create_gadget
int usbg_create_gadget(usbg_state *s, const char *name, const struct usbg_gadget_attrs *g_attrs, const struct usbg_gadget_strs *g_strs, usbg_gadget **g)
Create a new USB gadget device and set given attributes and strings.
Definition usbg.c:1532
usbg_strerror
const char * usbg_strerror(usbg_error e)
Get the short description of error.
Definition usbg_error.c:123
usbg_add_config_function
int usbg_add_config_function(usbg_config *c, const char *name, usbg_function *f)
Add a function to a configuration.
Definition usbg.c:2368
usbg_create_config
int usbg_create_config(usbg_gadget *g, int id, const char *label, const struct usbg_config_attrs *c_attrs, const struct usbg_config_strs *c_strs, usbg_config **c)
Create a new USB gadget configuration.
Definition usbg.c:2179
usbg_init
int usbg_init(const char *configfs_path, usbg_state **state)
Initialize the libusbgx library state.
Definition usbg.c:1091
usbg_cleanup
void usbg_cleanup(usbg_state *s)
Clean up the libusbgx library state.
Definition usbg.c:1136
usbg_create_function
int usbg_create_function(usbg_gadget *g, usbg_function_type type, const char *instance, void *f_attrs, usbg_function **f)
Create a new USB gadget function and set its attributes.
Definition usbg.c:2051
usbg_error_name
const char * usbg_error_name(usbg_error e)
Get the error name as a constant string.
Definition usbg_error.c:62
usbg_config_strs
USB configuration strings.
Definition usbg.h:199
usbg_gadget_attrs
USB gadget device attributes.
Definition usbg.h:135
usbg_gadget_strs
USB gadget device strings.
Definition usbg.h:158
usbg_config
Definition usbg_internal.h:117
usbg_function
Definition usbg_internal.h:129
usbg_gadget
Definition usbg_internal.h:103
usbg_state
Definition usbg_internal.h:93
usbg.h