V4L/DVB (13103): create a standard method for dvb adapter drivers to override frontend ioctls
Signed-off-by: Michael Krufky <mkrufky@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Родитель
dbda8f701a
Коммит
9133aee09e
|
@ -1712,7 +1712,18 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
|
|||
struct dvb_device *dvbdev = file->private_data;
|
||||
struct dvb_frontend *fe = dvbdev->priv;
|
||||
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
||||
int err = -EOPNOTSUPP;
|
||||
int cb_err, err = -EOPNOTSUPP;
|
||||
|
||||
if (fe->dvb->fe_ioctl_override) {
|
||||
cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg,
|
||||
DVB_FE_IOCTL_PRE);
|
||||
if (cb_err < 0)
|
||||
return cb_err;
|
||||
if (cb_err > 0)
|
||||
return 0;
|
||||
/* fe_ioctl_override returning 0 allows
|
||||
* dvb-core to continue handling the ioctl */
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case FE_GET_INFO: {
|
||||
|
@ -1978,6 +1989,13 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
|
|||
break;
|
||||
};
|
||||
|
||||
if (fe->dvb->fe_ioctl_override) {
|
||||
cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg,
|
||||
DVB_FE_IOCTL_POST);
|
||||
if (cb_err < 0)
|
||||
return cb_err;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
module_param_array(adapter_nr, short, NULL, 0444); \
|
||||
MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers")
|
||||
|
||||
struct dvb_frontend;
|
||||
|
||||
struct dvb_adapter {
|
||||
int num;
|
||||
struct list_head list_head;
|
||||
|
@ -69,6 +71,32 @@ struct dvb_adapter {
|
|||
int mfe_shared; /* indicates mutually exclusive frontends */
|
||||
struct dvb_device *mfe_dvbdev; /* frontend device in use */
|
||||
struct mutex mfe_lock; /* access lock for thread creation */
|
||||
|
||||
/* Allow the adapter/bridge driver to perform an action before and/or
|
||||
* after the core handles an ioctl:
|
||||
*
|
||||
* DVB_FE_IOCTL_PRE indicates that the ioctl has not yet been handled.
|
||||
* DVB_FE_IOCTL_POST indicates that the ioctl has been handled.
|
||||
*
|
||||
* When DVB_FE_IOCTL_PRE is passed to the callback as the stage arg:
|
||||
*
|
||||
* return 0 to allow dvb-core to handle the ioctl.
|
||||
* return a positive int to prevent dvb-core from handling the ioctl,
|
||||
* and exit without error.
|
||||
* return a negative int to prevent dvb-core from handling the ioctl,
|
||||
* and return that value as an error.
|
||||
*
|
||||
* When DVB_FE_IOCTL_POST is passed to the callback as the stage arg:
|
||||
*
|
||||
* return 0 to allow the dvb_frontend ioctl handler to exit normally.
|
||||
* return a negative int to cause the dvb_frontend ioctl handler to
|
||||
* return that value as an error.
|
||||
*/
|
||||
#define DVB_FE_IOCTL_PRE 0
|
||||
#define DVB_FE_IOCTL_POST 1
|
||||
int (*fe_ioctl_override)(struct dvb_frontend *fe,
|
||||
unsigned int cmd, void *parg,
|
||||
unsigned int stage);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -904,7 +904,7 @@ static int dvb_register(struct cx23885_tsport *port)
|
|||
|
||||
/* register everything */
|
||||
ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
|
||||
&dev->pci->dev, adapter_nr, 0);
|
||||
&dev->pci->dev, adapter_nr, 0, NULL);
|
||||
|
||||
/* init CI & MAC */
|
||||
switch (dev->board) {
|
||||
|
|
|
@ -1174,7 +1174,7 @@ static int dvb_register(struct cx8802_dev *dev)
|
|||
|
||||
/* register everything */
|
||||
return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
|
||||
&dev->pci->dev, adapter_nr, mfe_shared);
|
||||
&dev->pci->dev, adapter_nr, mfe_shared, NULL);
|
||||
|
||||
frontend_detach:
|
||||
core->gate_ctrl = NULL;
|
||||
|
|
|
@ -1574,7 +1574,7 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
|
||||
/* register everything else */
|
||||
ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
|
||||
&dev->pci->dev, adapter_nr, 0);
|
||||
&dev->pci->dev, adapter_nr, 0, NULL);
|
||||
|
||||
/* this sequence is necessary to make the tda1004x load its firmware
|
||||
* and to enter analog mode of hybrid boards
|
||||
|
|
|
@ -139,7 +139,9 @@ static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
|
|||
struct device *device,
|
||||
char *adapter_name,
|
||||
short *adapter_nr,
|
||||
int mfe_shared)
|
||||
int mfe_shared,
|
||||
int (*fe_ioctl_override)(struct dvb_frontend *,
|
||||
unsigned int, void *, unsigned int))
|
||||
{
|
||||
int result;
|
||||
|
||||
|
@ -154,6 +156,7 @@ static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
|
|||
}
|
||||
fe->adapter.priv = adapter_priv;
|
||||
fe->adapter.mfe_shared = mfe_shared;
|
||||
fe->adapter.fe_ioctl_override = fe_ioctl_override;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -253,7 +256,9 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
|
|||
void *adapter_priv,
|
||||
struct device *device,
|
||||
short *adapter_nr,
|
||||
int mfe_shared)
|
||||
int mfe_shared,
|
||||
int (*fe_ioctl_override)(struct dvb_frontend *,
|
||||
unsigned int, void *, unsigned int))
|
||||
{
|
||||
struct list_head *list, *q;
|
||||
struct videobuf_dvb_frontend *fe;
|
||||
|
@ -267,7 +272,7 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
|
|||
|
||||
/* Bring up the adapter */
|
||||
res = videobuf_dvb_register_adapter(f, module, adapter_priv, device,
|
||||
fe->dvb.name, adapter_nr, mfe_shared);
|
||||
fe->dvb.name, adapter_nr, mfe_shared, fe_ioctl_override);
|
||||
if (res < 0) {
|
||||
printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res);
|
||||
return res;
|
||||
|
|
|
@ -42,7 +42,9 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
|
|||
void *adapter_priv,
|
||||
struct device *device,
|
||||
short *adapter_nr,
|
||||
int mfe_shared);
|
||||
int mfe_shared,
|
||||
int (*fe_ioctl_override)(struct dvb_frontend *,
|
||||
unsigned int, void *, unsigned int));
|
||||
|
||||
void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче