diff options
author | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-09-04 16:07:03 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2016-01-11 12:18:59 -0200 |
commit | ab232e46bf01db5c540a00f478853a3572b0b88b (patch) | |
tree | 78b0d8e9e70cd8812a21de802b42dc206c76292e | |
parent | 5e5387df0491679fb1210b231173c5279061e9c4 (diff) | |
download | lwn-ab232e46bf01db5c540a00f478853a3572b0b88b.tar.gz lwn-ab232e46bf01db5c540a00f478853a3572b0b88b.zip |
[media] cx231xx: 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>
-rw-r--r-- | drivers/media/usb/cx231xx/cx231xx-cards.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 29cf0c268b19..b842bfc799cc 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1185,8 +1185,6 @@ static void cx231xx_unregister_media_device(struct cx231xx *dev) */ void cx231xx_release_resources(struct cx231xx *dev) { - cx231xx_unregister_media_device(dev); - cx231xx_release_analog_resources(dev); cx231xx_remove_from_devlist(dev); @@ -1199,6 +1197,8 @@ void cx231xx_release_resources(struct cx231xx *dev) /* delete v4l2 device */ v4l2_device_unregister(&dev->v4l2_dev); + cx231xx_unregister_media_device(dev); + usb_put_dev(dev->udev); /* Mark device as unused */ @@ -1237,15 +1237,16 @@ static void cx231xx_media_device_register(struct cx231xx *dev, #endif } -static void cx231xx_create_media_graph(struct cx231xx *dev) +static int cx231xx_create_media_graph(struct cx231xx *dev) { #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev = dev->media_dev; struct media_entity *entity; struct media_entity *tuner = NULL, *decoder = NULL; + int ret; if (!mdev) - return; + return 0; media_device_for_each_entity(entity, mdev) { switch (entity->type) { @@ -1261,16 +1262,24 @@ static void cx231xx_create_media_graph(struct cx231xx *dev) /* Analog setup, using tuner as a link */ if (!decoder) - return; + return 0; - 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); + if (tuner) { + ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0, + MEDIA_LNK_FL_ENABLED); + if (ret < 0) + return ret; + } + ret = media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret < 0) + return ret; + ret = media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret < 0) + return ret; #endif + return 0; } /* @@ -1732,9 +1741,12 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* load other modules required */ request_modules(dev); - cx231xx_create_media_graph(dev); + retval = cx231xx_create_media_graph(dev); + if (retval < 0) { + cx231xx_release_resources(dev); + } - return 0; + return retval; err_video_alt: /* cx231xx_uninit_dev: */ cx231xx_close_extension(dev); |