Fixed to stop services of functionfs when gadget is disabled
[platform/core/system/libdevice-node.git] / hw / usb_gadget.h
index 2b96ad6..dc4b539 100644 (file)
  */
 #define USB_GADGET_DEVICE_VERSION      MAKE_VERSION(0,1)
 
-#define _HELPER_Y(x) ((x) & -(x))
-
-/* Count number of trailing zeros using Dean Gaudet's algorithm */
-#define _HELPER_CTZ(mask)                                      \
-       ((_HELPER_Y(mask) ? 0 : 1) +                            \
-        ((_HELPER_Y(mask) & 0x0000FFFF) ? 0 : 16) +            \
-        ((_HELPER_Y(mask) & 0x00FF00FF) ? 0 :  8) +            \
-        ((_HELPER_Y(mask) & 0x0F0F0F0F) ? 0 :  4) +            \
-        ((_HELPER_Y(mask) & 0x33333333) ? 0 :  2) +            \
-        ((_HELPER_Y(mask) & 0x55555555) ? 0 :  1))
-
-/* Function IDX in array is number of trailing zeros */
-#define FUNC_IDX_FROM_MASK(mask) _HELPER_CTZ(mask)
+typedef enum {
+       USB_FUNCTION_IDX_MTP         = 0,
+       USB_FUNCTION_IDX_ACM         = 1,
+       USB_FUNCTION_IDX_SDB         = 2,
+       USB_FUNCTION_IDX_RNDIS       = 3,
+       USB_FUNCTION_IDX_DIAG        = 4,
+       USB_FUNCTION_IDX_CONN_GADGET = 5,
+       USB_FUNCTION_IDX_DM          = 6,
+       USB_FUNCTION_IDX_RMNET       = 7,
+       USB_FUNCTION_IDX_MAX         = USB_FUNCTION_IDX_RMNET + 1
+} usb_function_idx_e;
 
 typedef enum {
-       USB_FUNCTION_GROUP_SIMPLE,
-       USB_FUNCTION_GROUP_WITH_SERVICE,
-} usb_function_group_e;
+       USB_FUNCTION_NONE        = 0,
+       USB_FUNCTION_MTP         = 1 << USB_FUNCTION_IDX_MTP,
+       USB_FUNCTION_ACM         = 1 << USB_FUNCTION_IDX_ACM,
+       USB_FUNCTION_SDB         = 1 << USB_FUNCTION_IDX_SDB,
+       USB_FUNCTION_RNDIS       = 1 << USB_FUNCTION_IDX_RNDIS,
+       USB_FUNCTION_DIAG        = 1 << USB_FUNCTION_IDX_DIAG,
+       USB_FUNCTION_CONN_GADGET = 1 << USB_FUNCTION_IDX_CONN_GADGET,
+       USB_FUNCTION_DM          = 1 << USB_FUNCTION_IDX_DM,
+       USB_FUNCTION_RMNET       = 1 << USB_FUNCTION_IDX_RMNET
+} usb_function_e;
+
 
+/*
+ * legacy enable(usb plug)    : enable gadget -> handler(1) -> ffs_service start -> service start
+ * legacy disable(usb unplug) : service stop -> ffs_service stop -> handler(0) -> disable gadget
+ *
+ * configfs init(booting)       : ffs_service.socket start
+ * configfs enable(usb plug)*   : enable gadget -> handler(1) -> service start
+ * configfs disable(usb unplug) : service stop -> handler(0) -> disable gadget -> ffs_service.service stop
+ * configfs deinit              : ffs_service.socket stop
+ *
+ * Since ffs_service works by socket activation, it will be started automatically when data is enqueued to the usb socket.
+ * So when enabling configfs gadget, it doesn't start ffs_service.
+ */
 struct usb_function {
-       int function_group;
        int id;
        const char *name;
        const char *instance;
 
+       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);
 };
 
-struct usb_function_with_service {
-       struct usb_function func;
-       const char *service;
-};
-
 struct usb_configuration_attributes {
        uint8_t bmAttributs;
        int MaxPower;
@@ -109,174 +126,6 @@ struct usb_gadget {
        struct usb_configuration **configs;
 };
 
-typedef enum {
-       USB_FUNCTION_NONE               = 0,
-       USB_FUNCTION_MTP                = 1 << 0,
-       USB_FUNCTION_ACM                = 1 << 1,
-       USB_FUNCTION_SDB                = 1 << 2,
-       USB_FUNCTION_RNDIS              = 1 << 3,
-       USB_FUNCTION_DIAG               = 1 << 4,
-       USB_FUNCTION_CONN_GADGET        = 1 << 5,
-       USB_FUNCTION_DM                 = 1 << 6,
-       USB_FUNCTION_RMNET              = 1 << 7,
-} usb_function_e;
-
-static void free_simple_func_content(struct usb_function *func)
-{
-       free((void *)func->name);
-       free((void *)func->instance);
-}
-
-static void free_simple_func(struct usb_function *func)
-{
-       free_simple_func_content(func);
-       free(func);
-}
-
-static int clone_simple_func_to(struct usb_function *func,
-                             struct usb_function *other)
-{
-       *other = *func;
-       other->name = strdup(func->name);
-       other->instance = strdup(func->instance);
-
-       if (!other->name || !other->instance)
-               goto free_strs;
-
-       return 0;
-free_strs:
-       free((void *)other->name);
-       free((void *)other->instance);
-       return -ENOMEM;
-}
-
-static int clone_simple_func(struct usb_function *func,
-                             struct usb_function **clone)
-{
-       struct usb_function *other;
-       int ret;
-
-       if (!func || !clone)
-               return -EINVAL;
-
-       other = (struct usb_function *)malloc(sizeof(*other));
-       if (!other)
-               goto out;
-
-       ret = clone_simple_func_to(func, other);
-       if (ret)
-               goto free_other;
-
-       *clone = other;
-       return 0;
-free_other:
-       free(other);
-out:
-       return -ENOMEM;
-}
-
-#define DEFINE_SIMPLE_USB_FUNCTION(_id, _name)                      \
-       static struct usb_function _##_name##_function = {           \
-               .function_group = USB_FUNCTION_GROUP_SIMPLE,         \
-               .id = _id,                                           \
-               .name = #_name,                                      \
-               .instance = "default",                               \
-               .clone = clone_simple_func,                      \
-               .free_func = free_simple_func,                       \
-       }
-
-DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_DIAG, diag);
-DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_RMNET, rmnet);
-DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_DM, dm);
-DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_CONN_GADGET, conn_gadget);
-
-#undef DEFINE_SIMPLE_USB_FUNCTION
-
-static void free_func_with_service(struct usb_function *func)
-{
-       struct usb_function_with_service *fws;
-
-       fws = container_of(func, struct usb_function_with_service, func);
-
-       free_simple_func_content(func);
-       free((void *)fws->service);
-       free(fws);
-}
-
-static int clone_func_with_service(struct usb_function *func,
-                                  struct usb_function **clone)
-{
-       struct usb_function_with_service *fws;
-       struct usb_function_with_service *other;
-       int ret;
-
-       if (!func || !clone)
-               return -EINVAL;
-
-       other = (struct usb_function_with_service *)malloc(sizeof(*other));
-       if (!other)
-               goto out;
-
-       ret = clone_simple_func_to(func, &other->func);
-       if (ret)
-               goto free_other;
-
-       fws = container_of(func, struct usb_function_with_service, func);
-       if (fws->service) {
-               other->service = strdup(fws->service);
-               if (!other->service)
-                       goto free_content;
-       } else {
-               other->service = NULL;
-       }
-
-       *clone = &other->func;
-       return 0;
-free_content:
-       free_simple_func_content(&other->func);
-free_other:
-       free(other);
-out:
-       return -ENOMEM;
-}
-
-#define DEFINE_USB_FUNCTION_WITH_SERVICE(_id, _name, _service)         \
-       static struct usb_function_with_service _##_name##_function = { \
-               .func = {                                               \
-                       .function_group = USB_FUNCTION_GROUP_WITH_SERVICE, \
-                       .id = _id,                                      \
-                       .name = #_name,                                 \
-                       .instance = "default",                          \
-                       .clone = clone_func_with_service,               \
-                       .free_func = free_func_with_service,            \
-               },                                                      \
-               .service = _service,                                    \
-       }
-
-DEFINE_USB_FUNCTION_WITH_SERVICE(USB_FUNCTION_ACM, acm, "data-router");
-DEFINE_USB_FUNCTION_WITH_SERVICE(USB_FUNCTION_SDB, sdb, "sdbd");
-DEFINE_USB_FUNCTION_WITH_SERVICE(USB_FUNCTION_MTP, mtp, "mtp-responder");
-DEFINE_USB_FUNCTION_WITH_SERVICE(USB_FUNCTION_RNDIS, rndis, "rndis");
-
-#define MAKE_FUNC_AVAILABLE(_name, _vname)                             \
-       [FUNC_IDX_FROM_MASK(USB_FUNCTION_##_name)] = &_##_vname##_function
-
-#define MAKE_FUNC_WS_AVAILABLE(_name, _vname)                          \
-       [FUNC_IDX_FROM_MASK(USB_FUNCTION_##_name)] = &_##_vname##_function.func
-
-static struct usb_function *_available_funcs[] = {
-       MAKE_FUNC_WS_AVAILABLE(MTP, mtp),
-       MAKE_FUNC_WS_AVAILABLE(ACM, acm),
-       MAKE_FUNC_WS_AVAILABLE(SDB, sdb),
-       MAKE_FUNC_WS_AVAILABLE(RNDIS, rndis),
-       MAKE_FUNC_AVAILABLE(DIAG, diag),
-       MAKE_FUNC_AVAILABLE(CONN_GADGET, conn_gadget),
-       MAKE_FUNC_AVAILABLE(DM, dm),
-       MAKE_FUNC_AVAILABLE(RMNET, rmnet),
-};
-
-#undef MAKE_FUNC_AVAILABLE
-
 struct usb_gadget_id {
        unsigned int function_mask;
 };
@@ -294,4 +143,6 @@ int simple_translator_open(struct hw_info *info,
                const char *id, struct hw_common **common);
 int simple_translator_close(struct hw_common *common);
 
+extern struct usb_function *_available_funcs[];
+
 #endif