summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRobert Schlabbach <robert_s@gmx.net>2022-01-21 21:18:49 +0000
committerMauro Carvalho Chehab <mchehab@kernel.org>2022-11-25 09:59:09 +0000
commite704b44b550fbc9a4af15bc848fdbac5ff2eec47 (patch)
treea60f107adc9ed3c529027fb994beec01501fe9d5 /drivers
parent6508a50fe84f9858e8b59b53dce3847aaeeab744 (diff)
downloadlinux-stable-e704b44b550fbc9a4af15bc848fdbac5ff2eec47.tar.gz
linux-stable-e704b44b550fbc9a4af15bc848fdbac5ff2eec47.tar.bz2
linux-stable-e704b44b550fbc9a4af15bc848fdbac5ff2eec47.zip
media: dvb-core: Enhance shared multi-frontend support
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. Link: https://lore.kernel.org/linux-media/trinity-22c77578-26b0-4867-9ff7-2668e5d22c64-1642799929896@3c-app-gmx-bap04 Signed-off-by: Robert Schlabbach <robert_s@gmx.net> Tested-by: Robert Schlabbach <robert_s@gmx.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/dvb-core/dvb_frontend.c12
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-init.c2
2 files changed, 12 insertions, 2 deletions
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index d0955e0c86f7..2a98082c605e 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -2765,7 +2765,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++;