lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220920-resend-powersave-v2-8-5135d1bb1c38@chromium.org>
Date:   Tue, 25 Oct 2022 16:34:29 +0200
From:   Ricardo Ribalda <ribalda@...omium.org>
To:     Mauro Carvalho Chehab <mchehab@...nel.org>
Cc:     Laurent Pinchart <laurent.pinchart@...asonboard.com>,
        Guenter Roeck <linux@...ck-us.net>,
        Max Staudt <mstaudt@...gle.com>, linux-media@...r.kernel.org,
        Tomasz Figa <tfiga@...omium.org>, linux-kernel@...r.kernel.org,
        Alan Stern <stern@...land.harvard.edu>,
        Ricardo Ribalda <ribalda@...omium.org>,
        Hans Verkuil <hverkuil-cisco@...all.nl>
Subject: [PATCH v2 8/8] media: uvcvideo: Only call status ep if hw supports it

Instead of calling uvc_status_* regardless if the hw supports it or not,
make all the calls conditional.

This simplifies the locking during suspend/resume.

Signed-off-by: Ricardo Ribalda <ribalda@...omium.org>

diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index f15fbdbcd8bb..d2841f0d9132 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1847,7 +1847,8 @@ static void uvc_delete(struct kref *kref)
 	struct uvc_device *dev = container_of(kref, struct uvc_device, ref);
 	struct list_head *p, *n;
 
-	uvc_status_cleanup(dev);
+	if (dev->int_ep)
+		uvc_status_cleanup(dev);
 	uvc_ctrl_cleanup_device(dev);
 
 	usb_put_intf(dev->intf);
@@ -1918,7 +1919,8 @@ static void uvc_unregister_video(struct uvc_device *dev)
 		mutex_unlock(&stream->mutex);
 	}
 
-	uvc_status_unregister(dev);
+	if (dev->int_ep)
+		uvc_status_unregister(dev);
 	uvc_ctrl_stop_device(dev);
 
 	if (dev->vdev.dev)
@@ -2222,7 +2224,9 @@ static int uvc_probe(struct usb_interface *intf,
 	usb_set_intfdata(intf, dev);
 
 	/* Initialize the interrupt URB. */
-	if ((ret = uvc_status_init(dev)) < 0) {
+	if (dev->int_ep)
+		ret = uvc_status_init(dev);
+	if (ret < 0) {
 		dev_info(&dev->udev->dev,
 			 "Unable to initialize the status endpoint (%d), status interrupt will not be supported.\n",
 			 ret);
@@ -2274,6 +2278,8 @@ static int uvc_suspend(struct usb_interface *intf, pm_message_t message)
 	/* Controls are cached on the fly so they don't need to be saved. */
 	if (intf->cur_altsetting->desc.bInterfaceSubClass ==
 	    UVC_SC_VIDEOCONTROL) {
+		if (!dev->int_ep)
+			return 0;
 		mutex_lock(&dev->lock);
 		if (dev->users)
 			uvc_status_stop(dev);
@@ -2308,6 +2314,9 @@ static int __uvc_resume(struct usb_interface *intf, int reset)
 				return ret;
 		}
 
+		if (!dev->int_ep)
+			return ret;
+
 		mutex_lock(&dev->lock);
 		if (dev->users)
 			ret = uvc_status_start(dev, GFP_NOIO);
diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c
index cb90aff344bc..627cf11066e7 100644
--- a/drivers/media/usb/uvc/uvc_status.c
+++ b/drivers/media/usb/uvc/uvc_status.c
@@ -277,7 +277,7 @@ int uvc_status_init(struct uvc_device *dev)
 	unsigned int pipe;
 	int interval;
 
-	if (ep == NULL)
+	if (WARN_ON(!ep))
 		return 0;
 
 	uvc_input_init(dev);
@@ -312,19 +312,23 @@ int uvc_status_init(struct uvc_device *dev)
 
 void uvc_status_unregister(struct uvc_device *dev)
 {
+	if (WARN_ON(!dev->int_ep))
+		return;
 	usb_kill_urb(dev->int_urb);
 	uvc_input_unregister(dev);
 }
 
 void uvc_status_cleanup(struct uvc_device *dev)
 {
+	if (WARN_ON(!dev->int_ep))
+		return;
 	usb_free_urb(dev->int_urb);
 	kfree(dev->status);
 }
 
 int uvc_status_start(struct uvc_device *dev, gfp_t flags)
 {
-	if (dev->int_urb == NULL)
+	if (WARN_ON(!dev->int_ep) || !dev->int_urb)
 		return 0;
 
 	return usb_submit_urb(dev->int_urb, flags);
@@ -332,5 +336,8 @@ int uvc_status_start(struct uvc_device *dev, gfp_t flags)
 
 void uvc_status_stop(struct uvc_device *dev)
 {
+	if (WARN_ON(!dev->int_ep) || !dev->int_urb)
+		return;
+
 	usb_kill_urb(dev->int_urb);
 }
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index c250b628fc4f..2861ab122beb 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -44,7 +44,7 @@ static int uvc_pm_get(struct uvc_streaming *stream)
 		goto done;
 	}
 
-	if (!stream->dev->users)
+	if (!stream->dev->users && stream->dev->int_ep)
 		ret = uvc_status_start(stream->dev, GFP_KERNEL);
 	if (!ret)
 		stream->dev->users++;
@@ -66,7 +66,7 @@ static void uvc_pm_put(struct uvc_streaming *stream)
 		return;
 	}
 	stream->dev->users--;
-	if (!stream->dev->users)
+	if (!stream->dev->users && stream->dev->int_ep)
 		uvc_status_stop(stream->dev);
 	mutex_unlock(&stream->dev->lock);
 

-- 
b4 0.11.0-dev-d93f8

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ