Commit 2a6003c2 authored by Michael Krufky's avatar Michael Krufky Committed by Mauro Carvalho Chehab

V4L/DVB (8950): xc5000: prevent an OOPS if analog driver is unloaded while digital is in use

Prevent an OOPS if xc5000_attach was called by tuner.ko before being called by
the DVB adapter driver. The OOPS occurs when a digital tune request is made
after tuner.ko is unloaded.

When tuner.ko is unloaded, it takes the xc5000_config structure with it.

Rather than storing a pointer to the xc5000_config structure, just store the
if_khz and tuner_callback inside the xc5000_priv internal state structure.
Signed-off-by: default avatarMichael Krufky <mkrufky@linuxtv.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 89fd2854
...@@ -50,17 +50,17 @@ static LIST_HEAD(hybrid_tuner_instance_list); ...@@ -50,17 +50,17 @@ static LIST_HEAD(hybrid_tuner_instance_list);
#define XC5000_DEFAULT_FIRMWARE_SIZE 12332 #define XC5000_DEFAULT_FIRMWARE_SIZE 12332
struct xc5000_priv { struct xc5000_priv {
struct xc5000_config *cfg;
struct tuner_i2c_props i2c_props; struct tuner_i2c_props i2c_props;
struct list_head hybrid_tuner_instance_list; struct list_head hybrid_tuner_instance_list;
u32 if_khz;
u32 freq_hz; u32 freq_hz;
u32 bandwidth; u32 bandwidth;
u8 video_standard; u8 video_standard;
u8 rf_mode; u8 rf_mode;
void *devptr; void *devptr;
int (*tuner_callback) (void *priv, int command, int arg);
}; };
/* Misc Defines */ /* Misc Defines */
...@@ -233,9 +233,8 @@ static void xc5000_TunerReset(struct dvb_frontend *fe) ...@@ -233,9 +233,8 @@ static void xc5000_TunerReset(struct dvb_frontend *fe)
dprintk(1, "%s()\n", __func__); dprintk(1, "%s()\n", __func__);
if (priv->cfg->tuner_callback) { if (priv->tuner_callback) {
ret = priv->cfg->tuner_callback(priv->devptr, ret = priv->tuner_callback(priv->devptr, XC5000_TUNER_RESET, 0);
XC5000_TUNER_RESET, 0);
if (ret) if (ret)
printk(KERN_ERR "xc5000: reset failed\n"); printk(KERN_ERR "xc5000: reset failed\n");
} else } else
...@@ -692,10 +691,10 @@ static int xc5000_set_params(struct dvb_frontend *fe, ...@@ -692,10 +691,10 @@ static int xc5000_set_params(struct dvb_frontend *fe,
return -EREMOTEIO; return -EREMOTEIO;
} }
ret = xc_set_IF_frequency(priv, priv->cfg->if_khz); ret = xc_set_IF_frequency(priv, priv->if_khz);
if (ret != XC_RESULT_SUCCESS) { if (ret != XC_RESULT_SUCCESS) {
printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n", printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n",
priv->cfg->if_khz); priv->if_khz);
return -EIO; return -EIO;
} }
...@@ -972,9 +971,10 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, ...@@ -972,9 +971,10 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
break; break;
case 1: case 1:
/* new tuner instance */ /* new tuner instance */
priv->cfg = cfg;
priv->bandwidth = BANDWIDTH_6_MHZ; priv->bandwidth = BANDWIDTH_6_MHZ;
priv->devptr = devptr; priv->devptr = devptr;
priv->if_khz = cfg->if_khz;
priv->tuner_callback = cfg->tuner_callback;
fe->tuner_priv = priv; fe->tuner_priv = priv;
break; break;
......
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