From 01573e231f18eb2d99162747186f59511f56b64d Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 08 Dec 2023 10:40:48 +0000
Subject: [PATCH] 移去rt
---
kernel/drivers/usb/gadget/function/uvc_v4l2.c | 78 +++++++++++++++++++++++++++-----------
1 files changed, 55 insertions(+), 23 deletions(-)
diff --git a/kernel/drivers/usb/gadget/function/uvc_v4l2.c b/kernel/drivers/usb/gadget/function/uvc_v4l2.c
index d822456..591411b 100644
--- a/kernel/drivers/usb/gadget/function/uvc_v4l2.c
+++ b/kernel/drivers/usb/gadget/function/uvc_v4l2.c
@@ -75,10 +75,6 @@
strlcpy(cap->card, cdev->gadget->name, sizeof(cap->card));
strlcpy(cap->bus_info, dev_name(&cdev->gadget->dev),
sizeof(cap->bus_info));
-
- cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
- cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-
return 0;
}
@@ -119,8 +115,8 @@
}
if (i == ARRAY_SIZE(uvc_formats)) {
- printk(KERN_INFO "Unsupported format 0x%08x.\n",
- fmt->fmt.pix.pixelformat);
+ uvcg_info(&uvc->func, "Unsupported format 0x%08x.\n",
+ fmt->fmt.pix.pixelformat);
return -EINVAL;
}
@@ -177,7 +173,8 @@
if (ret < 0)
return ret;
- queue_work(video->async_wq, &video->pump);
+ if (uvc->state == UVC_STATE_STREAMING)
+ schedule_work(&video->pump);
return ret;
}
@@ -203,7 +200,7 @@
if (type != video->queue.queue.type)
return -EINVAL;
- if (uvc->state == UVC_STATE_DISCONNECTED)
+ if (uvc->state != UVC_STATE_CONNECTED)
return -ENODEV;
/* Enable UVC video. */
@@ -217,16 +214,15 @@
* settings for zero-bandwidth and full-bandwidth
* cases, but the same is not true for BULK endpoints,
* as they have a single alt-setting.
+ *
+ * For ISOC endpoints, Complete the alternate setting
+ * selection setup phase now that userspace is ready
+ * to provide video frames.
*/
- if (!usb_endpoint_xfer_bulk(video->ep->desc)) {
- /*
- * Complete the alternate setting selection
- * setup phase now that userspace is ready
- * to provide video frames.
- */
+ if (!usb_endpoint_xfer_bulk(video->ep->desc))
uvc_function_setup_continue(uvc);
- uvc->state = UVC_STATE_STREAMING;
- }
+
+ uvc->state = UVC_STATE_STREAMING;
return 0;
}
@@ -248,17 +244,56 @@
uvc_v4l2_subscribe_event(struct v4l2_fh *fh,
const struct v4l2_event_subscription *sub)
{
+ struct uvc_device *uvc = video_get_drvdata(fh->vdev);
+ struct uvc_file_handle *handle = to_uvc_file_handle(fh);
+ int ret;
+
if (sub->type < UVC_EVENT_FIRST || sub->type > UVC_EVENT_LAST)
return -EINVAL;
- return v4l2_event_subscribe(fh, sub, 2, NULL);
+ if (sub->type == UVC_EVENT_SETUP && uvc->func_connected)
+ return -EBUSY;
+
+ ret = v4l2_event_subscribe(fh, sub, 2, NULL);
+ if (ret < 0)
+ return ret;
+
+ if (sub->type == UVC_EVENT_SETUP) {
+ uvc->func_connected = true;
+ handle->is_uvc_app_handle = true;
+ uvc_function_connect(uvc);
+ }
+
+ return 0;
+}
+
+static void uvc_v4l2_disable(struct uvc_device *uvc)
+{
+ uvc_function_disconnect(uvc);
+ uvcg_video_enable(&uvc->video, 0);
+ uvcg_free_buffers(&uvc->video.queue);
+ uvc->func_connected = false;
+ wake_up_interruptible(&uvc->func_connected_queue);
}
static int
uvc_v4l2_unsubscribe_event(struct v4l2_fh *fh,
const struct v4l2_event_subscription *sub)
{
- return v4l2_event_unsubscribe(fh, sub);
+ struct uvc_device *uvc = video_get_drvdata(fh->vdev);
+ struct uvc_file_handle *handle = to_uvc_file_handle(fh);
+ int ret;
+
+ ret = v4l2_event_unsubscribe(fh, sub);
+ if (ret < 0)
+ return ret;
+
+ if (sub->type == UVC_EVENT_SETUP && handle->is_uvc_app_handle) {
+ uvc_v4l2_disable(uvc);
+ handle->is_uvc_app_handle = false;
+ }
+
+ return 0;
}
static long
@@ -313,7 +348,6 @@
handle->device = &uvc->video;
file->private_data = &handle->vfh;
- uvc_function_connect(uvc);
return 0;
}
@@ -325,11 +359,9 @@
struct uvc_file_handle *handle = to_uvc_file_handle(file->private_data);
struct uvc_video *video = handle->device;
- uvc_function_disconnect(uvc);
-
mutex_lock(&video->mutex);
- uvcg_video_enable(video, 0);
- uvcg_free_buffers(&video->queue);
+ if (handle->is_uvc_app_handle)
+ uvc_v4l2_disable(uvc);
mutex_unlock(&video->mutex);
file->private_data = NULL;
--
Gitblit v1.6.2