diff options
author | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-09-04 16:08:02 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2016-01-11 12:19:00 -0200 |
commit | 4e26f3abafa9d0f635e105c8b9021f3b5bae6702 (patch) | |
tree | f6ceebd633e06f2673c4a7bdabcde561950ec550 /drivers/media/usb | |
parent | ab232e46bf01db5c540a00f478853a3572b0b88b (diff) |
[media] au0828: enforce check for graph creation
If the graph creation fails, don't register the device.
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/usb')
-rw-r--r-- | drivers/media/usb/au0828/au0828-core.c | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 0d77e9cc303b..27679e5cdca1 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -172,9 +172,9 @@ static void au0828_usb_v4l2_release(struct v4l2_device *v4l2_dev) struct au0828_dev *dev = container_of(v4l2_dev, struct au0828_dev, v4l2_dev); - au0828_usb_v4l2_media_release(dev); v4l2_ctrl_handler_free(&dev->v4l2_ctrl_hdl); v4l2_device_unregister(&dev->v4l2_dev); + au0828_usb_v4l2_media_release(dev); au0828_usb_release(dev); } #endif @@ -253,16 +253,16 @@ static void au0828_media_device_register(struct au0828_dev *dev, } -static void au0828_create_media_graph(struct au0828_dev *dev) +static int au0828_create_media_graph(struct au0828_dev *dev) { #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev = dev->media_dev; struct media_entity *entity; struct media_entity *tuner = NULL, *decoder = NULL; - int i; + int i, ret; if (!mdev) - return; + return 0; media_device_for_each_entity(entity, mdev) { switch (entity->type) { @@ -279,15 +279,23 @@ static void au0828_create_media_graph(struct au0828_dev *dev) /* Something bad happened! */ if (!decoder) - return; - - if (tuner) - media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0, - MEDIA_LNK_FL_ENABLED); - media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, - MEDIA_LNK_FL_ENABLED); - media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, - MEDIA_LNK_FL_ENABLED); + return -EINVAL; + + if (tuner) { + ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, + decoder, 0, + MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; + } + ret = media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; + ret = media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; for (i = 0; i < AU0828_MAX_INPUT; i++) { struct media_entity *ent = &dev->input_ent[i]; @@ -299,20 +307,27 @@ static void au0828_create_media_graph(struct au0828_dev *dev) case AU0828_VMUX_CABLE: case AU0828_VMUX_TELEVISION: case AU0828_VMUX_DVB: - if (tuner) - media_create_pad_link(ent, 0, tuner, - TUNER_PAD_RF_INPUT, - MEDIA_LNK_FL_ENABLED); + if (!tuner) + break; + + ret = media_create_pad_link(ent, 0, tuner, + TUNER_PAD_RF_INPUT, + MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; break; case AU0828_VMUX_COMPOSITE: case AU0828_VMUX_SVIDEO: default: /* AU0828_VMUX_DEBUG */ /* FIXME: fix the decoder PAD */ - media_create_pad_link(ent, 0, decoder, 0, 0); + ret = media_create_pad_link(ent, 0, decoder, 0, 0); + if (ret) + return ret; break; } } #endif + return 0; } static int au0828_usb_probe(struct usb_interface *interface, @@ -427,7 +442,12 @@ static int au0828_usb_probe(struct usb_interface *interface, mutex_unlock(&dev->lock); - au0828_create_media_graph(dev); + retval = au0828_create_media_graph(dev); + if (retval) { + pr_err("%s() au0282_dev_register failed to create graph\n", + __func__); + au0828_usb_disconnect(interface); + } return retval; } |