Commit 9133aee0 authored by Michael Krufky's avatar Michael Krufky Committed by Mauro Carvalho Chehab

V4L/DVB (13103): create a standard method for dvb adapter drivers to override frontend ioctls

Signed-off-by: default avatarMichael Krufky <mkrufky@kernellabs.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent dbda8f70
...@@ -1712,7 +1712,18 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *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_device *dvbdev = file->private_data;
struct dvb_frontend *fe = dvbdev->priv; struct dvb_frontend *fe = dvbdev->priv;
struct dvb_frontend_private *fepriv = fe->frontend_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) { switch (cmd) {
case FE_GET_INFO: { case FE_GET_INFO: {
...@@ -1978,6 +1989,13 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, ...@@ -1978,6 +1989,13 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
break; 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; return err;
} }
......
...@@ -54,6 +54,8 @@ ...@@ -54,6 +54,8 @@
module_param_array(adapter_nr, short, NULL, 0444); \ module_param_array(adapter_nr, short, NULL, 0444); \
MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers") MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers")
struct dvb_frontend;
struct dvb_adapter { struct dvb_adapter {
int num; int num;
struct list_head list_head; struct list_head list_head;
...@@ -69,6 +71,32 @@ struct dvb_adapter { ...@@ -69,6 +71,32 @@ struct dvb_adapter {
int mfe_shared; /* indicates mutually exclusive frontends */ int mfe_shared; /* indicates mutually exclusive frontends */
struct dvb_device *mfe_dvbdev; /* frontend device in use */ struct dvb_device *mfe_dvbdev; /* frontend device in use */
struct mutex mfe_lock; /* access lock for thread creation */ 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) ...@@ -904,7 +904,7 @@ static int dvb_register(struct cx23885_tsport *port)
/* register everything */ /* register everything */
ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, 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 */ /* init CI & MAC */
switch (dev->board) { switch (dev->board) {
......
...@@ -1174,7 +1174,7 @@ static int dvb_register(struct cx8802_dev *dev) ...@@ -1174,7 +1174,7 @@ static int dvb_register(struct cx8802_dev *dev)
/* register everything */ /* register everything */
return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, 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: frontend_detach:
core->gate_ctrl = NULL; core->gate_ctrl = NULL;
......
...@@ -1574,7 +1574,7 @@ static int dvb_init(struct saa7134_dev *dev) ...@@ -1574,7 +1574,7 @@ static int dvb_init(struct saa7134_dev *dev)
/* register everything else */ /* register everything else */
ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, 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 /* this sequence is necessary to make the tda1004x load its firmware
* and to enter analog mode of hybrid boards * and to enter analog mode of hybrid boards
......
...@@ -139,7 +139,9 @@ static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe, ...@@ -139,7 +139,9 @@ static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
struct device *device, struct device *device,
char *adapter_name, char *adapter_name,
short *adapter_nr, short *adapter_nr,
int mfe_shared) int mfe_shared,
int (*fe_ioctl_override)(struct dvb_frontend *,
unsigned int, void *, unsigned int))
{ {
int result; int result;
...@@ -154,6 +156,7 @@ static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe, ...@@ -154,6 +156,7 @@ static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
} }
fe->adapter.priv = adapter_priv; fe->adapter.priv = adapter_priv;
fe->adapter.mfe_shared = mfe_shared; fe->adapter.mfe_shared = mfe_shared;
fe->adapter.fe_ioctl_override = fe_ioctl_override;
return result; return result;
} }
...@@ -253,7 +256,9 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f, ...@@ -253,7 +256,9 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
void *adapter_priv, void *adapter_priv,
struct device *device, struct device *device,
short *adapter_nr, 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 list_head *list, *q;
struct videobuf_dvb_frontend *fe; struct videobuf_dvb_frontend *fe;
...@@ -267,7 +272,7 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f, ...@@ -267,7 +272,7 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
/* Bring up the adapter */ /* Bring up the adapter */
res = videobuf_dvb_register_adapter(f, module, adapter_priv, device, 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) { if (res < 0) {
printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res); printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res);
return res; return res;
......
...@@ -42,7 +42,9 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f, ...@@ -42,7 +42,9 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
void *adapter_priv, void *adapter_priv,
struct device *device, struct device *device,
short *adapter_nr, 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); void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment