mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
usb: gadget: uvc: add a new attribute uvc_num_request
This patch adds a new uvc attribute "uvc_num_request" to set the number of uvc requests. And the maximum limit is set to UVC_MAX_NUM_REQUESTS (8), the default value of uvc_num_request is set to UVC_NUM_REQUESTS (4). Change-Id: I69d6a4d6547a81b67ce447f271c7a5103671767e Signed-off-by: William Wu <william.wu@rock-chips.com>
This commit is contained in:
@@ -1111,6 +1111,7 @@ static struct usb_function_instance *uvc_alloc_inst(void)
|
||||
|
||||
opts->streaming_interval = 1;
|
||||
opts->streaming_maxpacket = 1024;
|
||||
opts->uvc_num_request = UVC_NUM_REQUESTS;
|
||||
|
||||
ret = uvcg_attach_configfs(opts);
|
||||
if (ret < 0) {
|
||||
|
||||
@@ -29,6 +29,7 @@ struct f_uvc_opts {
|
||||
|
||||
unsigned int control_interface;
|
||||
unsigned int streaming_interface;
|
||||
unsigned int uvc_num_request;
|
||||
|
||||
/*
|
||||
* Control descriptors array pointers for full-/high-speed and
|
||||
|
||||
@@ -67,6 +67,7 @@ extern unsigned int uvc_gadget_trace_param;
|
||||
#define UVC_NUM_REQUESTS 4
|
||||
#define UVC_MAX_REQUEST_SIZE 64
|
||||
#define UVC_MAX_EVENTS 4
|
||||
#define UVC_MAX_NUM_REQUESTS 8
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* Structures
|
||||
@@ -85,8 +86,8 @@ struct uvc_video {
|
||||
|
||||
/* Requests */
|
||||
unsigned int req_size;
|
||||
struct usb_request *req[UVC_NUM_REQUESTS];
|
||||
__u8 *req_buffer[UVC_NUM_REQUESTS];
|
||||
struct usb_request *req[UVC_MAX_NUM_REQUESTS];
|
||||
__u8 *req_buffer[UVC_MAX_NUM_REQUESTS];
|
||||
struct list_head req_free;
|
||||
spinlock_t req_lock;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <linux/sort.h>
|
||||
|
||||
#include "uvc.h"
|
||||
#include "u_uvc.h"
|
||||
#include "uvc_configfs.h"
|
||||
|
||||
@@ -2773,6 +2774,7 @@ UVCG_OPTS_ATTR(streaming_bulk, streaming_bulk, 1);
|
||||
UVCG_OPTS_ATTR(streaming_interval, streaming_interval, 16);
|
||||
UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, 3072);
|
||||
UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, 15);
|
||||
UVCG_OPTS_ATTR(uvc_num_request, uvc_num_request, UVC_MAX_NUM_REQUESTS);
|
||||
|
||||
#undef UVCG_OPTS_ATTR
|
||||
|
||||
@@ -2781,6 +2783,7 @@ static struct configfs_attribute *uvc_attrs[] = {
|
||||
&f_uvc_opts_attr_streaming_interval,
|
||||
&f_uvc_opts_attr_streaming_maxpacket,
|
||||
&f_uvc_opts_attr_streaming_maxburst,
|
||||
&f_uvc_opts_attr_uvc_num_request,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "uvc.h"
|
||||
#include "uvc_queue.h"
|
||||
#include "uvc_video.h"
|
||||
#include "u_uvc.h"
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* Video codecs
|
||||
@@ -224,8 +225,13 @@ static int
|
||||
uvc_video_free_requests(struct uvc_video *video)
|
||||
{
|
||||
unsigned int i;
|
||||
struct uvc_device *uvc;
|
||||
struct f_uvc_opts *opts;
|
||||
|
||||
for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
|
||||
uvc = container_of(video, struct uvc_device, video);
|
||||
opts = fi_to_f_uvc_opts(uvc->func.fi);
|
||||
|
||||
for (i = 0; i < opts->uvc_num_request; ++i) {
|
||||
if (video->req[i]) {
|
||||
usb_ep_free_request(video->ep, video->req[i]);
|
||||
video->req[i] = NULL;
|
||||
@@ -248,6 +254,11 @@ uvc_video_alloc_requests(struct uvc_video *video)
|
||||
unsigned int req_size;
|
||||
unsigned int i;
|
||||
int ret = -ENOMEM;
|
||||
struct uvc_device *uvc;
|
||||
struct f_uvc_opts *opts;
|
||||
|
||||
uvc = container_of(video, struct uvc_device, video);
|
||||
opts = fi_to_f_uvc_opts(uvc->func.fi);
|
||||
|
||||
BUG_ON(video->req_size);
|
||||
|
||||
@@ -260,7 +271,7 @@ uvc_video_alloc_requests(struct uvc_video *video)
|
||||
* max_t(unsigned int, video->ep->maxburst, 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
|
||||
for (i = 0; i < opts->uvc_num_request; ++i) {
|
||||
video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL);
|
||||
if (video->req_buffer[i] == NULL)
|
||||
goto error;
|
||||
@@ -357,6 +368,8 @@ int uvcg_video_enable(struct uvc_video *video, int enable)
|
||||
{
|
||||
unsigned int i;
|
||||
int ret;
|
||||
struct uvc_device *uvc;
|
||||
struct f_uvc_opts *opts;
|
||||
|
||||
if (video->ep == NULL) {
|
||||
printk(KERN_INFO "Video enable failed, device is "
|
||||
@@ -364,8 +377,11 @@ int uvcg_video_enable(struct uvc_video *video, int enable)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
uvc = container_of(video, struct uvc_device, video);
|
||||
opts = fi_to_f_uvc_opts(uvc->func.fi);
|
||||
|
||||
if (!enable) {
|
||||
for (i = 0; i < UVC_NUM_REQUESTS; ++i)
|
||||
for (i = 0; i < opts->uvc_num_request; ++i)
|
||||
if (video->req[i])
|
||||
usb_ep_dequeue(video->ep, video->req[i]);
|
||||
|
||||
|
||||
@@ -382,6 +382,7 @@ webcam_bind(struct usb_composite_dev *cdev)
|
||||
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->uvc_num_request = UVC_NUM_REQUESTS;
|
||||
|
||||
/* Allocate string descriptor numbers ... note that string contents
|
||||
* can be overridden by the composite_dev glue.
|
||||
|
||||
Reference in New Issue
Block a user