diff mbox series

[1/1] media: dvb-core: Enhance shared multi-frontend support

Message ID trinity-22c77578-26b0-4867-9ff7-2668e5d22c64-1642799929896@3c-app-gmx-bap04 (mailing list archive)
State New, archived
Headers show
Series media: dvb-core: Enhance shared multi-frontend support | expand

Commit Message

Robert Schlabbach Jan. 21, 2022, 9:18 p.m. UTC
Drivers for devices with multiple frontends which cannot be used
concurrently due to hardware limitations which enforce that restriction
by setting the mfe_shared field to 1 exhibit rather unfriendly behavior
towards applications: The unavailable frontend devices cannot be opened
at all, not even for read-only access to query information. Even worse,
any open call is blocked for 5 seconds by default.

Allow drivers for such devices to behave like regular busy frontend
devices instead, i.e. still allowing concurrent read access to the
unavailable frontend and denying concurrent write access with -EBUSY
without delay.

This patch does not alter the behavior of any existing driver to avoid
regressions. Driver developers who wish to take advantage of this must
ensure their driver can handle all read-only accesses to the unavailable
frontend, and indicate the capability by setting the mfe_shared field to
2 instead of 1.

Add a check to dvb-usb-init.c when automatically setting the mfe_shared
field that when a driver has already set the field to 2, it is not
overwritten.

Document the additional capability in the code comment about mfe_shared.

Signed-off-by: Robert Schlabbach <robert_s@gmx.net>
Tested-by: Robert Schlabbach <robert_s@gmx.net>
---
 drivers/media/dvb-core/dvb_frontend.c    | 12 +++++++++++-
 drivers/media/usb/dvb-usb/dvb-usb-init.c |  2 +-
 include/media/dvbdev.h                   |  6 +++++-
 3 files changed, 17 insertions(+), 3 deletions(-)

--
2.17.1
diff mbox series

Patch

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 48e735cdbe6b..24c268b20661 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -2754,7 +2754,17 @@  static int dvb_frontend_open(struct inode *inode, struct file *file)
 	if (fe->exit == DVB_FE_DEVICE_REMOVED)
 		return -ENODEV;

-	if (adapter->mfe_shared) {
+	if (adapter->mfe_shared == 2) {
+		mutex_lock(&adapter->mfe_lock);
+		if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+			if (adapter->mfe_dvbdev &&
+			    !adapter->mfe_dvbdev->writers) {
+				mutex_unlock(&adapter->mfe_lock);
+				return -EBUSY;
+			}
+			adapter->mfe_dvbdev = dvbdev;
+		}
+	} else if (adapter->mfe_shared) {
 		mutex_lock(&adapter->mfe_lock);

 		if (!adapter->mfe_dvbdev)
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c
index 61439c8f33ca..341d6c7a6bba 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c
@@ -92,7 +92,7 @@  static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
 			goto frontend_init_err;

 		/* use exclusive FE lock if there is multiple shared FEs */
-		if (adap->fe_adap[1].fe)
+		if (adap->fe_adap[1].fe && adap->dvb_adap.mfe_shared < 1)
 			adap->dvb_adap.mfe_shared = 1;

 		d->num_adapters_initialized++;
diff --git a/include/media/dvbdev.h b/include/media/dvbdev.h
index 2f6b0861322a..6ccff7c6fa6b 100644
--- a/include/media/dvbdev.h
+++ b/include/media/dvbdev.h
@@ -87,7 +87,11 @@  struct dvb_frontend;
  * @device:		pointer to struct device
  * @module:		pointer to struct module
  * @mfe_shared:		indicates mutually exclusive frontends.
- *			Use of this flag is currently deprecated.
+ *			1 = legacy exclusion behavior: blocking any open() call
+ *			2 = enhanced exclusion behavior, emulating the standard
+ *			behavior of busy frontends: allowing read-only sharing
+ *			and otherwise returning immediately with -EBUSY when any
+ *			of the frontends is already opened with write access.
  * @mfe_dvbdev:		Frontend device in use, in the case of MFE
  * @mfe_lock:		Lock to prevent using the other frontends when MFE is
  *			used.