diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uvc b/Documentation/ABI/testing/configfs-usb-gadget-uvc
index 9281e2aa38df..bee6ab72e6b1 100644
--- a/Documentation/ABI/testing/configfs-usb-gadget-uvc
+++ b/Documentation/ABI/testing/configfs-usb-gadget-uvc
@@ -177,6 +177,10 @@ Date: Dec 2014
KernelVersion: 4.0
Description: Specific MJPEG frame descriptors
+ bFrameIndex - unique id for this framedescriptor;
+ only defined after parent format is
+ linked into the streaming header;
+ read-only
dwFrameInterval - indicates how frame interval can be
programmed; a number of values
separated by newline can be specified
@@ -224,6 +228,10 @@ Date: Dec 2014
KernelVersion: 4.0
Description: Specific uncompressed frame descriptors
+ bFrameIndex - unique id for this framedescriptor;
+ only defined after parent format is
+ linked into the streaming header;
+ read-only
dwFrameInterval - indicates how frame interval can be
programmed; a number of values
separated by newline can be specified
diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c
index 1122659ccfe6..1645be415933 100644
--- a/drivers/usb/gadget/function/uvc_configfs.c
+++ b/drivers/usb/gadget/function/uvc_configfs.c
@@ -1155,6 +1155,8 @@ UVC_ATTR(uvcg_frame_, cname, aname);
#define noop_conversion(x) (x)
+UVCG_FRAME_ATTR_RO(b_frame_index, bFrameIndex, noop_conversion,
+ noop_conversion, 8);
UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, noop_conversion,
noop_conversion, 8);
UVCG_FRAME_ATTR(w_width, wWidth, le16_to_cpu, cpu_to_le16, 16);
@@ -1301,6 +1303,7 @@ static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item,
UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval);
static struct configfs_attribute *uvcg_frame_attrs[] = {
+ &uvcg_frame_attr_b_frame_index,
&uvcg_frame_attr_bm_capabilities,
&uvcg_frame_attr_w_width,
&uvcg_frame_attr_w_height,@@ -2133,12 +2136,15 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
sizeof(*frm->dw_frame_interval);
memcpy(*dest, frm->dw_frame_interval, sz);
*dest += sz;
- if (frm->fmt_type == UVCG_UNCOMPRESSED)
+ if (frm->fmt_type == UVCG_UNCOMPRESSED) {
h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(
frm->frame.b_frame_interval_type);
- else if (frm->fmt_type == UVCG_MJPEG)
+ frm->frame.b_frame_index = n + 1;
+ } else if (frm->fmt_type == UVCG_MJPEG) {
h->bLength = UVC_DT_FRAME_MJPEG_SIZE(
frm->frame.b_frame_interval_type);
+ frm->frame.b_frame_index = n + 1;
+ }
}
break;
}