[PATCH v4 41/43] usb: gadget: uvc: simplify descriptors generation

From: Robert Baldyga
Date: Wed Feb 03 2016 - 07:43:44 EST


As we don't need distinction between interface descriptors for different
speeds, we can remove some amount of unnecessary code. Additionally we
simplify configfs interface of UVC function.

Signed-off-by: Robert Baldyga <r.baldyga@xxxxxxxxxxx>
---
drivers/usb/gadget/function/f_uvc.c | 60 ++++-------------------
drivers/usb/gadget/function/u_uvc.h | 14 ++----
drivers/usb/gadget/function/uvc.h | 7 +--
drivers/usb/gadget/function/uvc_configfs.c | 79 +++++-------------------------
drivers/usb/gadget/legacy/webcam.c | 43 ++--------------
5 files changed, 32 insertions(+), 171 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
index 29b41b5..0f554c4 100644
--- a/drivers/usb/gadget/function/f_uvc.c
+++ b/drivers/usb/gadget/function/f_uvc.c
@@ -467,26 +467,9 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
unsigned int bytes;
void *mem;

- switch (speed) {
- case USB_SPEED_SUPER:
- uvc_control_desc = uvc->desc.ss_control;
- uvc_streaming_cls = uvc->desc.ss_streaming;
- uvc_streaming_std = uvc_ss_streaming;
- break;
-
- case USB_SPEED_HIGH:
- uvc_control_desc = uvc->desc.fs_control;
- uvc_streaming_cls = uvc->desc.hs_streaming;
- uvc_streaming_std = uvc_hs_streaming;
- break;
-
- case USB_SPEED_FULL:
- default:
- uvc_control_desc = uvc->desc.fs_control;
- uvc_streaming_cls = uvc->desc.fs_streaming;
- uvc_streaming_std = uvc_fs_streaming;
- break;
- }
+ uvc_control_desc = uvc->desc.control;
+ uvc_streaming_cls = uvc->desc.streaming;
+ uvc_streaming_std = uvc_ss_streaming;

if (!uvc_control_desc || !uvc_streaming_cls)
return ERR_PTR(-ENODEV);
@@ -817,24 +800,14 @@ static struct usb_function_instance *uvc_alloc_inst(void)
md->bTransferCharacteristics = 1;
md->bMatrixCoefficients = 4;

- /* Prepare fs control class descriptors for configfs-based gadgets */
- ctl_cls = opts->uvc_fs_control_cls;
- ctl_cls[0] = NULL; /* assigned elsewhere by configfs */
- ctl_cls[1] = (struct uvc_descriptor_header *)cd;
- ctl_cls[2] = (struct uvc_descriptor_header *)pd;
- ctl_cls[3] = (struct uvc_descriptor_header *)od;
- ctl_cls[4] = NULL; /* NULL-terminate */
- opts->fs_control =
- (const struct uvc_descriptor_header * const *)ctl_cls;
-
/* Prepare hs control class descriptors for configfs-based gadgets */
- ctl_cls = opts->uvc_ss_control_cls;
+ ctl_cls = opts->uvc_control_cls;
ctl_cls[0] = NULL; /* assigned elsewhere by configfs */
ctl_cls[1] = (struct uvc_descriptor_header *)cd;
ctl_cls[2] = (struct uvc_descriptor_header *)pd;
ctl_cls[3] = (struct uvc_descriptor_header *)od;
ctl_cls[4] = NULL; /* NULL-terminate */
- opts->ss_control =
+ opts->control =
(const struct uvc_descriptor_header * const *)ctl_cls;

opts->streaming_interval = 1;
@@ -884,27 +857,14 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi)
opts = fi_to_f_uvc_opts(fi);

mutex_lock(&opts->lock);
- if (opts->uvc_fs_streaming_cls) {
- strm_cls = opts->uvc_fs_streaming_cls;
- opts->fs_streaming =
- (const struct uvc_descriptor_header * const *)strm_cls;
- }
- if (opts->uvc_hs_streaming_cls) {
- strm_cls = opts->uvc_hs_streaming_cls;
- opts->hs_streaming =
- (const struct uvc_descriptor_header * const *)strm_cls;
- }
- if (opts->uvc_ss_streaming_cls) {
- strm_cls = opts->uvc_ss_streaming_cls;
- opts->ss_streaming =
+ if (opts->uvc_streaming_cls) {
+ strm_cls = opts->uvc_streaming_cls;
+ opts->streaming =
(const struct uvc_descriptor_header * const *)strm_cls;
}

- uvc->desc.fs_control = opts->fs_control;
- uvc->desc.ss_control = opts->ss_control;
- uvc->desc.fs_streaming = opts->fs_streaming;
- uvc->desc.hs_streaming = opts->hs_streaming;
- uvc->desc.ss_streaming = opts->ss_streaming;
+ uvc->desc.control = opts->control;
+ uvc->desc.streaming = opts->streaming;
++opts->refcnt;
mutex_unlock(&opts->lock);

diff --git a/drivers/usb/gadget/function/u_uvc.h b/drivers/usb/gadget/function/u_uvc.h
index 4676b60..0068203 100644
--- a/drivers/usb/gadget/function/u_uvc.h
+++ b/drivers/usb/gadget/function/u_uvc.h
@@ -34,8 +34,7 @@ struct f_uvc_opts {
* uvc_ss_control_cls arrays respectively. Legacy gadgets must
* override them in their gadget bind callback.
*/
- const struct uvc_descriptor_header * const *fs_control;
- const struct uvc_descriptor_header * const *ss_control;
+ const struct uvc_descriptor_header * const *control;

/*
* Streaming descriptors array pointers for full-speed, high-speed and
@@ -43,9 +42,7 @@ struct f_uvc_opts {
* for configfs-based gadgets. Legacy gadgets must initialize them in
* their gadget bind callback.
*/
- const struct uvc_descriptor_header * const *fs_streaming;
- const struct uvc_descriptor_header * const *hs_streaming;
- const struct uvc_descriptor_header * const *ss_streaming;
+ const struct uvc_descriptor_header * const *streaming;

/* Default control descriptors for configfs-based gadgets. */
struct uvc_camera_terminal_descriptor uvc_camera_terminal;
@@ -60,8 +57,7 @@ struct f_uvc_opts {
* descriptors. Used by configfs only, must not be touched by legacy
* gadgets.
*/
- struct uvc_descriptor_header *uvc_fs_control_cls[5];
- struct uvc_descriptor_header *uvc_ss_control_cls[5];
+ struct uvc_descriptor_header *uvc_control_cls[5];

/*
* Streaming descriptors for full-speed, high-speed and super-speed.
@@ -69,9 +65,7 @@ struct f_uvc_opts {
* arrays are allocated at runtime as the number of descriptors isn't
* known in advance.
*/
- struct uvc_descriptor_header **uvc_fs_streaming_cls;
- struct uvc_descriptor_header **uvc_hs_streaming_cls;
- struct uvc_descriptor_header **uvc_ss_streaming_cls;
+ struct uvc_descriptor_header **uvc_streaming_cls;

/*
* Read/write access to configfs attributes is handled by configfs.
diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h
index 7d3bb62..bccdda2 100644
--- a/drivers/usb/gadget/function/uvc.h
+++ b/drivers/usb/gadget/function/uvc.h
@@ -151,11 +151,8 @@ struct uvc_device

/* Descriptors */
struct {
- const struct uvc_descriptor_header * const *fs_control;
- const struct uvc_descriptor_header * const *ss_control;
- const struct uvc_descriptor_header * const *fs_streaming;
- const struct uvc_descriptor_header * const *hs_streaming;
- const struct uvc_descriptor_header * const *ss_streaming;
+ const struct uvc_descriptor_header * const *control;
+ const struct uvc_descriptor_header * const *streaming;
} desc;

unsigned int control_intf;
diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c
index 56ab61e..7d8e588 100644
--- a/drivers/usb/gadget/function/uvc_configfs.c
+++ b/drivers/usb/gadget/function/uvc_configfs.c
@@ -509,7 +509,7 @@ static struct config_item_type uvcg_terminal_grp_type = {
/* control/class/{fs} */
static struct uvcg_control_class {
struct config_group group;
-} uvcg_control_class_fs, uvcg_control_class_ss;
+} uvcg_control_class;


static inline struct uvc_descriptor_header
@@ -518,11 +518,8 @@ static inline struct uvc_descriptor_header
struct uvcg_control_class *cl = container_of(to_config_group(i),
struct uvcg_control_class, group);

- if (cl == &uvcg_control_class_fs)
- return o->uvc_fs_control_cls;
-
- if (cl == &uvcg_control_class_ss)
- return o->uvc_ss_control_cls;
+ if (cl == &uvcg_control_class)
+ return o->uvc_control_cls;

return NULL;
}
@@ -619,26 +616,12 @@ static struct config_item_type uvcg_control_class_type = {
.ct_owner = THIS_MODULE,
};

-static struct config_group *uvcg_control_class_default_groups[] = {
- &uvcg_control_class_fs.group,
- &uvcg_control_class_ss.group,
- NULL,
-};
-
/* control/class */
-static struct uvcg_control_class_grp {
- struct config_group group;
-} uvcg_control_class_grp;
-
-static struct config_item_type uvcg_control_class_grp_type = {
- .ct_owner = THIS_MODULE,
-};
-
static struct config_group *uvcg_control_default_groups[] = {
&uvcg_control_header_grp.group,
&uvcg_processing_grp.group,
&uvcg_terminal_grp.group,
- &uvcg_control_class_grp.group,
+ &uvcg_control_class.group,
NULL,
};

@@ -1797,7 +1780,7 @@ static struct config_item_type uvcg_color_matching_grp_type = {
/* streaming/class/{fs|hs|ss} */
static struct uvcg_streaming_class {
struct config_group group;
-} uvcg_streaming_class_fs, uvcg_streaming_class_hs, uvcg_streaming_class_ss;
+} uvcg_streaming_class;


static inline struct uvc_descriptor_header
@@ -1806,14 +1789,8 @@ static inline struct uvc_descriptor_header
struct uvcg_streaming_class *cl = container_of(to_config_group(i),
struct uvcg_streaming_class, group);

- if (cl == &uvcg_streaming_class_fs)
- return &o->uvc_fs_streaming_cls;
-
- if (cl == &uvcg_streaming_class_hs)
- return &o->uvc_hs_streaming_cls;
-
- if (cl == &uvcg_streaming_class_ss)
- return &o->uvc_ss_streaming_cls;
+ if (cl == &uvcg_streaming_class)
+ return &o->uvc_streaming_cls;

return NULL;
}
@@ -2145,28 +2122,13 @@ static struct config_item_type uvcg_streaming_class_type = {
.ct_owner = THIS_MODULE,
};

-static struct config_group *uvcg_streaming_class_default_groups[] = {
- &uvcg_streaming_class_fs.group,
- &uvcg_streaming_class_hs.group,
- &uvcg_streaming_class_ss.group,
- NULL,
-};
-
/* streaming/class */
-static struct uvcg_streaming_class_grp {
- struct config_group group;
-} uvcg_streaming_class_grp;
-
-static struct config_item_type uvcg_streaming_class_grp_type = {
- .ct_owner = THIS_MODULE,
-};
-
static struct config_group *uvcg_streaming_default_groups[] = {
&uvcg_streaming_header_grp.group,
&uvcg_uncompressed_grp.group,
&uvcg_mjpeg_grp.group,
&uvcg_color_matching_grp.group,
- &uvcg_streaming_class_grp.group,
+ &uvcg_streaming_class.group,
NULL,
};

@@ -2312,16 +2274,9 @@ int uvcg_attach_configfs(struct f_uvc_opts *opts)
uvcg_terminal_default_groups,
"terminal",
&uvcg_terminal_grp_type);
- config_group_init_type_name(&uvcg_control_class_fs.group,
- "fs",
- &uvcg_control_class_type);
- config_group_init_type_name(&uvcg_control_class_ss.group,
- "ss",
+ config_group_init_type_name(&uvcg_control_class.group,
+ "desc",
&uvcg_control_class_type);
- uvcg_init_group(&uvcg_control_class_grp.group,
- uvcg_control_class_default_groups,
- "class",
- &uvcg_control_class_grp_type);
uvcg_init_group(&uvcg_control_grp.group,
uvcg_control_default_groups,
"control",
@@ -2342,19 +2297,9 @@ int uvcg_attach_configfs(struct f_uvc_opts *opts)
uvcg_color_matching_default_groups,
"color_matching",
&uvcg_color_matching_grp_type);
- config_group_init_type_name(&uvcg_streaming_class_fs.group,
- "fs",
- &uvcg_streaming_class_type);
- config_group_init_type_name(&uvcg_streaming_class_hs.group,
- "hs",
- &uvcg_streaming_class_type);
- config_group_init_type_name(&uvcg_streaming_class_ss.group,
- "ss",
+ config_group_init_type_name(&uvcg_streaming_class.group,
+ "desc",
&uvcg_streaming_class_type);
- uvcg_init_group(&uvcg_streaming_class_grp.group,
- uvcg_streaming_class_default_groups,
- "class",
- &uvcg_streaming_class_grp_type);
uvcg_init_group(&uvcg_streaming_grp.group,
uvcg_streaming_default_groups,
"streaming",
diff --git a/drivers/usb/gadget/legacy/webcam.c b/drivers/usb/gadget/legacy/webcam.c
index f9661cd..ffe5ef4 100644
--- a/drivers/usb/gadget/legacy/webcam.c
+++ b/drivers/usb/gadget/legacy/webcam.c
@@ -278,7 +278,7 @@ static const struct uvc_color_matching_descriptor uvc_color_matching = {
.bMatrixCoefficients = 4,
};

-static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = {
+static const struct uvc_descriptor_header * const uvc_control_cls[] = {
(const struct uvc_descriptor_header *) &uvc_control_header,
(const struct uvc_descriptor_header *) &uvc_camera_terminal,
(const struct uvc_descriptor_header *) &uvc_processing,
@@ -286,39 +286,7 @@ static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = {
NULL,
};

-static const struct uvc_descriptor_header * const uvc_ss_control_cls[] = {
- (const struct uvc_descriptor_header *) &uvc_control_header,
- (const struct uvc_descriptor_header *) &uvc_camera_terminal,
- (const struct uvc_descriptor_header *) &uvc_processing,
- (const struct uvc_descriptor_header *) &uvc_output_terminal,
- NULL,
-};
-
-static const struct uvc_descriptor_header * const uvc_fs_streaming_cls[] = {
- (const struct uvc_descriptor_header *) &uvc_input_header,
- (const struct uvc_descriptor_header *) &uvc_format_yuv,
- (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
- (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
- (const struct uvc_descriptor_header *) &uvc_format_mjpg,
- (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
- (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
- (const struct uvc_descriptor_header *) &uvc_color_matching,
- NULL,
-};
-
-static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = {
- (const struct uvc_descriptor_header *) &uvc_input_header,
- (const struct uvc_descriptor_header *) &uvc_format_yuv,
- (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
- (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
- (const struct uvc_descriptor_header *) &uvc_format_mjpg,
- (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
- (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
- (const struct uvc_descriptor_header *) &uvc_color_matching,
- NULL,
-};
-
-static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = {
+static const struct uvc_descriptor_header * const uvc_streaming_cls[] = {
(const struct uvc_descriptor_header *) &uvc_input_header,
(const struct uvc_descriptor_header *) &uvc_format_yuv,
(const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
@@ -385,11 +353,8 @@ webcam_bind(struct usb_composite_dev *cdev)
uvc_opts->streaming_maxburst = streaming_maxburst;
uvc_set_trace_param(trace);

- uvc_opts->fs_control = uvc_fs_control_cls;
- uvc_opts->ss_control = uvc_ss_control_cls;
- uvc_opts->fs_streaming = uvc_fs_streaming_cls;
- uvc_opts->hs_streaming = uvc_hs_streaming_cls;
- uvc_opts->ss_streaming = uvc_ss_streaming_cls;
+ uvc_opts->control = uvc_control_cls;
+ uvc_opts->streaming = uvc_streaming_cls;

/* Allocate string descriptor numbers ... note that string contents
* can be overridden by the composite_dev glue.
--
1.9.1