V4L/DVB: budget: Oops: "BUG: unable to handle kernel NULL pointer dereference"
authorBjørn Mork <bjorn@mork.no>
Wed, 24 Mar 2010 13:30:15 +0000 (10:30 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Wed, 19 May 2010 15:57:17 +0000 (12:57 -0300)
Never call dvb_frontend_detach if we failed to attach a frontend. This fixes
the following oops:

[    8.172997] DVB: registering new adapter (TT-Budget S2-1600 PCI)
[    8.209018] adapter has MAC addr = 00:d0:5c:cc:a7:29
[    8.328665] Intel ICH 0000:00:1f.5: PCI INT B -> GSI 17 (level, low) -> IRQ 17
[    8.328753] Intel ICH 0000:00:1f.5: setting latency timer to 64
[    8.562047] DVB: Unable to find symbol stv090x_attach()
[    8.562117] BUG: unable to handle kernel NULL pointer dereference at 000000ac
[    8.562239] IP: [<e08b04a3>] dvb_frontend_detach+0x4/0x67 [dvb_core]

Ref http://bugs.debian.org/575207

Also clean up if we are unable to register the tuner and LNB drivers

[mchehab@redhat.com: add printk log level, to calm down chechpatch.pl]
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Reported-by: Fladischer Michael <FladischerMichael@fladi.at>
Acked-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/dvb/ttpci/budget.c

index f5db13d..874a10a 100644 (file)
@@ -628,29 +628,36 @@ static void frontend_init(struct budget *budget)
                                                 &tt1600_stv6110x_config,
                                                 &budget->i2c_adap);
 
-                               tt1600_stv090x_config.tuner_init          = ctl->tuner_init;
-                               tt1600_stv090x_config.tuner_sleep         = ctl->tuner_sleep;
-                               tt1600_stv090x_config.tuner_set_mode      = ctl->tuner_set_mode;
-                               tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
-                               tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
-                               tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
-                               tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
-                               tt1600_stv090x_config.tuner_set_bbgain    = ctl->tuner_set_bbgain;
-                               tt1600_stv090x_config.tuner_get_bbgain    = ctl->tuner_get_bbgain;
-                               tt1600_stv090x_config.tuner_set_refclk    = ctl->tuner_set_refclk;
-                               tt1600_stv090x_config.tuner_get_status    = ctl->tuner_get_status;
-
-                               /* call the init function once to initialize
-                                  tuner's clock output divider and demod's
-                                  master clock */
-                               if (budget->dvb_frontend->ops.init)
-                                       budget->dvb_frontend->ops.init(budget->dvb_frontend);
-
-                               dvb_attach(isl6423_attach,
-                                       budget->dvb_frontend,
-                                       &budget->i2c_adap,
-                                       &tt1600_isl6423_config);
-
+                               if (ctl) {
+                                       tt1600_stv090x_config.tuner_init          = ctl->tuner_init;
+                                       tt1600_stv090x_config.tuner_sleep         = ctl->tuner_sleep;
+                                       tt1600_stv090x_config.tuner_set_mode      = ctl->tuner_set_mode;
+                                       tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
+                                       tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
+                                       tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
+                                       tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
+                                       tt1600_stv090x_config.tuner_set_bbgain    = ctl->tuner_set_bbgain;
+                                       tt1600_stv090x_config.tuner_get_bbgain    = ctl->tuner_get_bbgain;
+                                       tt1600_stv090x_config.tuner_set_refclk    = ctl->tuner_set_refclk;
+                                       tt1600_stv090x_config.tuner_get_status    = ctl->tuner_get_status;
+
+                                       /* call the init function once to initialize
+                                          tuner's clock output divider and demod's
+                                          master clock */
+                                       if (budget->dvb_frontend->ops.init)
+                                               budget->dvb_frontend->ops.init(budget->dvb_frontend);
+
+                                       if (dvb_attach(isl6423_attach,
+                                                      budget->dvb_frontend,
+                                                      &budget->i2c_adap,
+                                                      &tt1600_isl6423_config) == NULL) {
+                                               printk(KERN_ERR "%s: No Intersil ISL6423 found!\n", __func__);
+                                               goto error_out;
+                                       }
+                               } else {
+                                       printk(KERN_ERR "%s: No STV6110(A) Silicon Tuner found!\n", __func__);
+                                       goto error_out;
+                               }
                        }
                }
                break;