Fixed to stop services of functionfs when gadget is disabled
[platform/core/system/libdevice-node.git] / hw / usb_gadget.h
index 629504a..dc4b539 100644 (file)
  */
 #define USB_GADGET_DEVICE_VERSION      MAKE_VERSION(0,1)
 
-#define _HELPER_Y(x) ((x) & -(x))
+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;
 
-/* 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))
+typedef enum {
+       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;
 
-/* Function IDX in array is number of trailing zeros */
-#define FUNC_IDX_FROM_MASK(mask) _HELPER_CTZ(mask)
 
+/*
+ * 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 id;
        const char *name;
@@ -58,6 +81,8 @@ struct usb_function {
        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);
 };
@@ -101,97 +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(struct usb_function *func)
-{
-       if (func) {
-               free((void *)func->name);
-               free((void *)func->instance);
-               free((void *)func->service);
-               free(func);
-       }
-}
-
-static int clone_simple_func(struct usb_function *func,
-                             struct usb_function **clone)
-{
-       struct usb_function *other;
-
-       if (!func || !clone)
-               return -EINVAL;
-
-       other = (struct usb_function *)calloc(1, sizeof(struct usb_function));
-       if (!other)
-               return -ENOMEM;
-
-       *other = *func;
-
-       other->name = strdup(func->name);
-       other->instance = strdup(func->instance);
-       if (!other->name || !other->instance)
-               goto out_nomem;
-
-       if (func->service) {
-               other->service = strdup(func->service);
-               if (!other->service)
-                       goto out_nomem;
-       }
-
-       *clone = other;
-       return 0;
-
-out_nomem:
-       free_simple_func(other);
-       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_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");
-#undef DEFINE_USB_FUNCTION
-
-#define MAKE_FUNC_AVAILABLE(_name, _vname)  \
-       [FUNC_IDX_FROM_MASK(USB_FUNCTION_##_name)] = &_##_vname##_function
-
-static struct usb_function *_available_funcs[] = {
-       MAKE_FUNC_AVAILABLE(MTP, mtp),
-       MAKE_FUNC_AVAILABLE(ACM, acm),
-       MAKE_FUNC_AVAILABLE(SDB, sdb),
-       MAKE_FUNC_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;
 };
@@ -209,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