Commit 08ddd71b authored by Daniel Scally's avatar Daniel Scally Committed by Greg Kroah-Hartman
Browse files

usb: gadget: uvc: Allow linking XUs to string descriptors



Add .allow_link() and .drop_link() callbacks to allow users to link
an extension unit descriptor to a string descriptor.

Signed-off-by: default avatarDaniel Scally <dan.scally@ideasonboard.com>
Link: https://lore.kernel.org/r/20230206161802.892954-9-dan.scally@ideasonboard.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c0335632
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -1064,8 +1064,60 @@ static void uvcg_extension_release(struct config_item *item)
	kfree(xu);
}

static int uvcg_extension_allow_link(struct config_item *src, struct config_item *tgt)
{
	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
	struct uvcg_extension *xu = to_uvcg_extension(src);
	struct config_item *gadget_item;
	struct gadget_string *string;
	struct config_item *strings;
	int ret = 0;

	mutex_lock(su_mutex); /* for navigating configfs hierarchy */

	/* Validate that the target of the link is an entry in strings/<langid> */
	gadget_item = src->ci_parent->ci_parent->ci_parent->ci_parent->ci_parent;
	strings = config_group_find_item(to_config_group(gadget_item), "strings");
	if (!strings || tgt->ci_parent->ci_parent != strings) {
		ret = -EINVAL;
		goto put_strings;
	}

	string = to_gadget_string(tgt);
	xu->string_descriptor_index = string->usb_string.id;

put_strings:
	config_item_put(strings);
	mutex_unlock(su_mutex);

	return ret;
}

static void uvcg_extension_drop_link(struct config_item *src, struct config_item *tgt)
{
	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
	struct uvcg_extension *xu = to_uvcg_extension(src);
	struct config_item *opts_item;
	struct f_uvc_opts *opts;

	mutex_lock(su_mutex); /* for navigating configfs hierarchy */

	opts_item = src->ci_parent->ci_parent->ci_parent;
	opts = to_f_uvc_opts(opts_item);

	mutex_lock(&opts->lock);

	xu->string_descriptor_index = 0;

	mutex_unlock(&opts->lock);

	mutex_unlock(su_mutex);
}

static struct configfs_item_operations uvcg_extension_item_ops = {
	.release	= uvcg_extension_release,
	.allow_link	= uvcg_extension_allow_link,
	.drop_link	= uvcg_extension_drop_link,
};

static const struct config_item_type uvcg_extension_type = {
+1 −0
Original line number Diff line number Diff line
@@ -163,6 +163,7 @@ struct uvcg_extension_unit_descriptor {
struct uvcg_extension {
	struct config_item item;
	struct list_head list;
	u8 string_descriptor_index;
	struct uvcg_extension_unit_descriptor desc;
};