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:
Michael Krufky 2009-05-23 18:00:59 -03:00 committed by Mauro Carvalho Chehab
parent dbda8f701a
commit 9133aee09e
7 changed files with 61 additions and 8 deletions

View file

@ -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;
}

View file

@ -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);
};

View file

@ -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) {

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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);