Commit a2673d57 authored by Michael Grzeschik's avatar Michael Grzeschik Committed by Greg Kroah-Hartman
Browse files

usb: gadget: uvc: track frames in format entries



Just like the header is tracking the formats in a linked list, in this
patch we track the frames in a linked list of the formats. It
simplifies the parsing of the configfs structure.

Signed-off-by: default avatarMichael Grzeschik <m.grzeschik@pengutronix.de>

Link: https://lore.kernel.org/r/20220421211427.3400834-6-m.grzeschik@pengutronix.de


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e2fa7b36
Loading
Loading
Loading
Loading
+24 −1
Original line number Diff line number Diff line
@@ -1262,6 +1262,7 @@ static struct config_item *uvcg_frame_make(struct config_group *group,
	struct uvcg_format *fmt;
	struct f_uvc_opts *opts;
	struct config_item *opts_item;
	struct uvcg_frame_ptr *frame_ptr;

	h = kzalloc(sizeof(*h), GFP_KERNEL);
	if (!h)
@@ -1292,6 +1293,16 @@ static struct config_item *uvcg_frame_make(struct config_group *group,
		kfree(h);
		return ERR_PTR(-EINVAL);
	}

	frame_ptr = kzalloc(sizeof(*frame_ptr), GFP_KERNEL);
	if (!frame_ptr) {
		mutex_unlock(&opts->lock);
		kfree(h);
		return ERR_PTR(-ENOMEM);
	}

	frame_ptr->frm = h;
	list_add_tail(&frame_ptr->entry, &fmt->frames);
	++fmt->num_frames;
	mutex_unlock(&opts->lock);

@@ -1305,13 +1316,23 @@ static void uvcg_frame_drop(struct config_group *group, struct config_item *item
	struct uvcg_format *fmt;
	struct f_uvc_opts *opts;
	struct config_item *opts_item;
	struct uvcg_frame *target_frm = NULL;
	struct uvcg_frame_ptr *frame_ptr, *tmp;

	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
	opts = to_f_uvc_opts(opts_item);

	mutex_lock(&opts->lock);
	target_frm = container_of(item, struct uvcg_frame, item);
	fmt = to_uvcg_format(&group->cg_item);

	list_for_each_entry_safe(frame_ptr, tmp, &fmt->frames, entry)
		if (frame_ptr->frm == target_frm) {
			list_del(&frame_ptr->entry);
			kfree(frame_ptr);
			--fmt->num_frames;
			break;
		}
	mutex_unlock(&opts->lock);

	config_item_put(item);
@@ -1556,6 +1577,7 @@ static struct config_group *uvcg_uncompressed_make(struct config_group *group,
	h->desc.bmInterfaceFlags	= 0;
	h->desc.bCopyProtect		= 0;

	INIT_LIST_HEAD(&h->fmt.frames);
	h->fmt.type = UVCG_UNCOMPRESSED;
	config_group_init_type_name(&h->fmt.group, name,
				    &uvcg_uncompressed_type);
@@ -1736,6 +1758,7 @@ static struct config_group *uvcg_mjpeg_make(struct config_group *group,
	h->desc.bmInterfaceFlags	= 0;
	h->desc.bCopyProtect		= 0;

	INIT_LIST_HEAD(&h->fmt.frames);
	h->fmt.type = UVCG_MJPEG;
	config_group_init_type_name(&h->fmt.group, name,
				    &uvcg_mjpeg_type);
+6 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ struct uvcg_format {
	struct config_group	group;
	enum uvcg_format_type	type;
	unsigned		linked;
	struct list_head	frames;
	unsigned		num_frames;
	__u8			bmaControls[UVCG_STREAMING_CONTROL_SIZE];
};
@@ -73,6 +74,11 @@ static inline struct uvcg_streaming_header *to_uvcg_streaming_header(struct conf
	return container_of(item, struct uvcg_streaming_header, item);
}

struct uvcg_frame_ptr {
	struct uvcg_frame	*frm;
	struct list_head	entry;
};

struct uvcg_frame {
	struct config_item	item;
	enum uvcg_format_type	fmt_type;