*/
if (strs->manufacturer) {
- ret = sys_set_str(LEGACY_IMANUFACTURER_PATH,
- strs->manufacturer);
+ ret = sys_set_str(LEGACY_IMANUFACTURER_PATH, strs->manufacturer);
if (ret)
return ret;
}
if (strs->product) {
- ret = sys_set_str(LEGACY_IPRODUCT_PATH,
- strs->product);
+ ret = sys_set_str(LEGACY_IPRODUCT_PATH, strs->product);
if (ret)
return ret;
}
static int legacy_enable(struct usb_client *usb)
{
- int ret;
int i;
+ int ret;
struct usb_gadget *gadget;
struct usb_function *func;
- ret = sys_set_str(LEGACY_ENABLE_PATH,
- LEGACY_ENABLE);
+ ret = sys_set_str(LEGACY_ENABLE_PATH, LEGACY_ENABLE);
if (ret < 0)
return ret;
for (i = 0; gadget->funcs[i]; ++i) {
func = gadget->funcs[i];
+ if (func->handler)
+ func->handler(1);
+
/*
* Reuse configfs data structure to simplify design.
* Configfs has a special service for functionfs. (E.g. sdbd and mtp-responder)
static int legacy_disable(struct usb_client *usb)
{
- int ret;
int i;
+ int ret;
struct usb_gadget *gadget;
struct usb_function *func;
if (func->ffs_service)
(void)systemd_stop_unit_wait_stopped(func->ffs_service, ".service", -1);
+
+ if (func->handler)
+ func->handler(0);
}
ret = sys_set_str(LEGACY_ENABLE_PATH, LEGACY_DISABLE);
/* Function IDX in array is number of trailing zeros */
#define FUNC_IDX_FROM_MASK(mask) _HELPER_CTZ(mask)
+/*
+ * legacy enable : enable gadget -> handler(1) -> ffs_service start -> service start
+ * legacy disable : service stop -> ffs_service stop -> handler(0) -> disable gadget
+ *
+ * configfs enable : ffs_service start -> enable gadget -> handler(1) -> service start
+ * configfs disable : service stop -> handler(0) -> disable gadget (ffs_service is never stopped until changing usb mode)
+ */
struct usb_function {
int id;
const char *name;
const char *ffs_service; /* only used in configfs */
const char *service;
+ void (*handler)(int enable);
+
int (*clone)(struct usb_function *func, struct usb_function **_clone);
void (*free_func)(struct usb_function *func);
};
return -ENOMEM;
}
-#define DEFINE_USB_FUNCTION(_id, _name, _ffs_service, _service) \
- static struct usb_function _##_name##_function = { \
- .id = _id, \
- .name = #_name, \
- .instance = "default", \
- .ffs_service = _ffs_service, \
- .service = _service, \
- .clone = clone_simple_func, \
- .free_func = free_simple_func, \
+#define DEFINE_USB_FUNCTION(_id, _name, _ffs_service, _service, _handler) \
+ static struct usb_function _##_name##_function = { \
+ .id = _id, \
+ .name = #_name, \
+ .instance = "default", \
+ .ffs_service = _ffs_service, \
+ .service = _service, \
+ .handler = _handler, \
+ .clone = clone_simple_func, \
+ .free_func = free_simple_func, \
}
-DEFINE_USB_FUNCTION(USB_FUNCTION_DIAG, diag, NULL, NULL);
-DEFINE_USB_FUNCTION(USB_FUNCTION_RMNET, rmnet, NULL, NULL);
-DEFINE_USB_FUNCTION(USB_FUNCTION_DM, dm, NULL, NULL);
-DEFINE_USB_FUNCTION(USB_FUNCTION_CONN_GADGET, conn_gadget, NULL, NULL);
-DEFINE_USB_FUNCTION(USB_FUNCTION_SDB, sdb, "sdbd", NULL);
-DEFINE_USB_FUNCTION(USB_FUNCTION_MTP, mtp, "mtp-responder", NULL);
-DEFINE_USB_FUNCTION(USB_FUNCTION_ACM, acm, NULL, "data-router");
-DEFINE_USB_FUNCTION(USB_FUNCTION_RNDIS, rndis, NULL, "rndis");
+DEFINE_USB_FUNCTION(USB_FUNCTION_DIAG, diag, NULL, NULL, NULL);
+DEFINE_USB_FUNCTION(USB_FUNCTION_RMNET, rmnet, NULL, NULL, NULL);
+DEFINE_USB_FUNCTION(USB_FUNCTION_DM, dm, NULL, NULL, NULL);
+DEFINE_USB_FUNCTION(USB_FUNCTION_CONN_GADGET, conn_gadget, NULL, NULL, NULL);
+DEFINE_USB_FUNCTION(USB_FUNCTION_SDB, sdb, "sdbd", NULL, NULL);
+DEFINE_USB_FUNCTION(USB_FUNCTION_MTP, mtp, "mtp-responder", NULL, NULL);
+DEFINE_USB_FUNCTION(USB_FUNCTION_ACM, acm, NULL, "data-router", NULL);
+DEFINE_USB_FUNCTION(USB_FUNCTION_RNDIS, rndis, NULL, "rndis", NULL);
#undef DEFINE_USB_FUNCTION
#define MAKE_FUNC_AVAILABLE(_name, _vname) \