V4L/DVB (9618): tvaudio: add additional logic to avoid OOPS
authorMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 13 Nov 2008 17:01:15 +0000 (14:01 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Fri, 14 Nov 2008 16:24:44 +0000 (14:24 -0200)
This patch checks for volume, bass, treble, set mode and get mode
callbacks before actually enabling the code that would use them.

Instead of aborting the driver for load, this patch will allow it to
load with a reduced number of functionatities.

This prevents OOPS if some board entry is missing a needed callback.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/tvaudio.c

index 1387c54b7f02478a384b53f347f4269d8e0819d7..6c920bf74973ad2b9ebb7dd37507084c27ff1e32 100644 (file)
@@ -1511,20 +1511,49 @@ static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id)
                chip_cmd(chip,"init",&desc->init);
 
        if (desc->flags & CHIP_HAS_VOLUME) {
-               chip->left   = desc->leftinit   ? desc->leftinit   : 65535;
-               chip->right  = desc->rightinit  ? desc->rightinit  : 65535;
-               chip_write(chip,desc->leftreg,desc->volfunc(chip->left));
-               chip_write(chip,desc->rightreg,desc->volfunc(chip->right));
+               if (!desc->volfunc) {
+                       /* This shouldn't be happen. Warn user, but keep working
+                          without volume controls
+                        */
+                       v4l_info(chip->c, "volume callback undefined!\n");
+                       desc->flags &= ~CHIP_HAS_VOLUME;
+               } else {
+                       chip->left  = desc->leftinit  ? desc->leftinit  : 65535;
+                       chip->right = desc->rightinit ? desc->rightinit : 65535;
+                       chip_write(chip, desc->leftreg,
+                                  desc->volfunc(chip->left));
+                       chip_write(chip, desc->rightreg,
+                                  desc->volfunc(chip->right));
+               }
        }
        if (desc->flags & CHIP_HAS_BASSTREBLE) {
-               chip->treble = desc->trebleinit ? desc->trebleinit : 32768;
-               chip->bass   = desc->bassinit   ? desc->bassinit   : 32768;
-               chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
-               chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
+               if (!desc->bassfunc || !desc->treblefunc) {
+                       /* This shouldn't be happen. Warn user, but keep working
+                          without bass/treble controls
+                        */
+                       v4l_info(chip->c, "bass/treble callbacks undefined!\n");
+                       desc->flags &= ~CHIP_HAS_BASSTREBLE;
+               } else {
+                       chip->treble = desc->trebleinit ?
+                                               desc->trebleinit : 32768;
+                       chip->bass   = desc->bassinit   ?
+                                               desc->bassinit   : 32768;
+                       chip_write(chip, desc->bassreg,
+                                  desc->bassfunc(chip->bass));
+                       chip_write(chip, desc->treblereg,
+                                  desc->treblefunc(chip->treble));
+               }
        }
 
        chip->thread = NULL;
        if (desc->flags & CHIP_NEED_CHECKMODE) {
+               if (!desc->getmode || !desc->setmode) {
+                       /* This shouldn't be happen. Warn user, but keep working
+                          without kthread
+                        */
+                       v4l_info(chip->c, "set/get mode callbacks undefined!\n");
+                       return 0;
+               }
                /* start async thread */
                init_timer(&chip->wt);
                chip->wt.function = chip_thread_wake;