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_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,
|
||||||
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 @@
|
||||||
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 {
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
|
|
||||||
/* 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)
|
||||||
|
|
||||||
/* 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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
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,
|
||||||
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,
|
||||||
|
|
||||||
/* 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,
|
||||||
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);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче