Add API trace_usb_configfs_link_group() and trace_usb_configfs_unlink_group() to trace user link/unlink a function to gadget configuration, if a specific function need link/unlink, it also can be used. Signed-off-by: Linyu Yuan <quic_linyyuan@xxxxxxxxxxx> --- drivers/usb/gadget/configfs.c | 50 ++++++++++++++++++++++++++++++ drivers/usb/gadget/function/uvc_configfs.c | 12 +++++++ include/linux/usb/composite.h | 6 ++++ 3 files changed, 68 insertions(+) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index be9e70a..0f85290 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -425,6 +425,8 @@ static int config_usb_cfg_link( struct usb_function *f; int ret; + trace_usb_configfs_link_group(usb_cfg_ci, usb_func_ci); + mutex_lock(&gi->lock); /* * Make sure this function is from within our _this_ gadget and not @@ -474,6 +476,8 @@ static void config_usb_cfg_unlink( to_usb_function_instance(usb_func_ci); struct usb_function *f; + trace_usb_configfs_unlink_group(usb_cfg_ci, usb_func_ci); + /* * ideally I would like to forbid to unlink functions while a gadget is * bound to an UDC. Since this isn't possible at the moment, we simply @@ -896,6 +900,8 @@ static int os_desc_link(struct config_item *os_desc_ci, struct usb_configuration *c = NULL, *iter; int ret; + trace_usb_configfs_link_group(os_desc_ci, usb_cfg_ci); + mutex_lock(&gi->lock); list_for_each_entry(iter, &cdev->configs, list) { if (iter != &c_target->c) @@ -927,6 +933,8 @@ static void os_desc_unlink(struct config_item *os_desc_ci, struct gadget_info *gi = os_desc_item_to_gadget_info(os_desc_ci); struct usb_composite_dev *cdev = &gi->cdev; + trace_usb_configfs_unlink_group(os_desc_ci, usb_cfg_ci); + mutex_lock(&gi->lock); if (gi->composite.gadget_driver.udc_name) unregister_gadget(gi); @@ -1756,6 +1764,48 @@ void trace_usb_configfs_drop_group(struct config_item *pitem, trace_usb_configfs_make_drop_group(pitem, item, "rmdir"); } EXPORT_SYMBOL(trace_usb_configfs_drop_group); + +static void trace_usb_configfs_link_unlink_group(struct config_item *dest, + struct config_item *src, char *link_unlink) +{ + char *group = kzalloc(4 * GROUP_LEN, GFP_KERNEL); + char *group1, *group2; + int ret; + + if (!group) + goto out; + + group1 = group + 2 * GROUP_LEN; + ret = gadget_configfs_group(group1, dest); + if (ret) + goto out; + + group2 = group + 3 * GROUP_LEN; + ret = gadget_configfs_group(group2, src); + if (ret) + goto out; + + snprintf(group, 2 * GROUP_LEN, "%s %s %s", link_unlink, group1, group2); + + trace_gadget_configfs(group); + +out: + kfree(group); +} + +void trace_usb_configfs_link_group(struct config_item *dest, + struct config_item *src) +{ + trace_usb_configfs_link_unlink_group(dest, src, "link"); +} +EXPORT_SYMBOL(trace_usb_configfs_link_group); + +void trace_usb_configfs_unlink_group(struct config_item *dest, + struct config_item *src) +{ + trace_usb_configfs_link_unlink_group(dest, src, "unlink"); +} +EXPORT_SYMBOL(trace_usb_configfs_unlink_group); #endif static int __init gadget_cfs_init(void) diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c index cc0f2eb..fc139f3 100644 --- a/drivers/usb/gadget/function/uvc_configfs.c +++ b/drivers/usb/gadget/function/uvc_configfs.c @@ -598,6 +598,8 @@ static int uvcg_control_class_allow_link(struct config_item *src, struct uvcg_control_header *target_hdr; int ret = -EINVAL; + trace_usb_configfs_link_group(src, target); + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ control = src->ci_parent->ci_parent; @@ -639,6 +641,8 @@ static void uvcg_control_class_drop_link(struct config_item *src, struct uvc_descriptor_header **class_array; struct uvcg_control_header *target_hdr; + trace_usb_configfs_unlink_group(src, target); + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ control = src->ci_parent->ci_parent; @@ -883,6 +887,8 @@ static int uvcg_streaming_header_allow_link(struct config_item *src, struct uvcg_format_ptr *format_ptr; int i, ret = -EINVAL; + trace_usb_configfs_link_group(src, target); + src_hdr = to_uvcg_streaming_header(src); mutex_lock(su_mutex); /* for navigating configfs hierarchy */ @@ -946,6 +952,8 @@ static void uvcg_streaming_header_drop_link(struct config_item *src, struct uvcg_format *target_fmt = NULL; struct uvcg_format_ptr *format_ptr, *tmp; + trace_usb_configfs_unlink_group(src, target); + src_hdr = to_uvcg_streaming_header(src); mutex_lock(su_mutex); /* for navigating configfs hierarchy */ @@ -2171,6 +2179,8 @@ static int uvcg_streaming_class_allow_link(struct config_item *src, size_t size = 0, count = 0; int ret = -EINVAL; + trace_usb_configfs_link_group(src, target); + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ streaming = src->ci_parent->ci_parent; @@ -2242,6 +2252,8 @@ static void uvcg_streaming_class_drop_link(struct config_item *src, struct uvc_descriptor_header ***class_array; struct uvcg_streaming_header *target_hdr; + trace_usb_configfs_unlink_group(src, target); + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ streaming = src->ci_parent->ci_parent; diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 611029d..a90e626 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -608,9 +608,15 @@ void trace_usb_configfs_make_group(struct config_item *pitem, struct config_item *item); void trace_usb_configfs_drop_group(struct config_item *pitem, struct config_item *item); +void trace_usb_configfs_link_group(struct config_item *pitem, + struct config_item *item); +void trace_usb_configfs_unlink_group(struct config_item *pitem, + struct config_item *item); #else #define trace_usb_configfs_make_group(pitem, item) do {} while(0) #define trace_usb_configfs_drop_group(pitem, item) do {} while(0) +#define trace_usb_configfs_link_group(pitem, item) do {} while(0) +#define trace_usb_configfs_unlink_group(pitem, item) do {} while(0) #endif struct usb_configuration *usb_get_config(struct usb_composite_dev *cdev, -- 2.7.4