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: Daniel Scally <dan.scally@ideasonboard.com>
Link: https://lore.kernel.org/r/20230206161802.892954-9-dan.scally@ideasonboard.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Daniel Scally 2023-02-06 16:17:59 +00:00 committed by Greg Kroah-Hartman
parent c033563220
commit 08ddd71bf0
2 changed files with 53 additions and 0 deletions

View File

@ -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 = {

View File

@ -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;
};