[PATCH v2 1/2] media: tw9910: fix failure handling in tw9910_power_on()

2018-12-30 Thread Alexey Khoroshilov
If gpiod_get_optional() fails in tw9910_power_on(), clk is left undisabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
v2: reset pdn_gpio as well as Jacopo Mondi suggested.

 drivers/media/i2c/tw9910.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c
index a54548cc4285..0971f8a34afb 100644
--- a/drivers/media/i2c/tw9910.c
+++ b/drivers/media/i2c/tw9910.c
@@ -610,6 +610,11 @@ static int tw9910_power_on(struct tw9910_priv *priv)
 GPIOD_OUT_LOW);
if (IS_ERR(priv->rstb_gpio)) {
dev_info(&client->dev, "Unable to get GPIO \"rstb\"");
+   clk_disable_unprepare(priv->clk);
+   if (priv->pdn_gpio) {
+   gpiod_set_value(priv->pdn_gpio, 1);
+   usleep_range(500, 1000);
+   }
return PTR_ERR(priv->rstb_gpio);
}
 
-- 
2.7.4



[PATCH v2 2/2] media: tw9910: add helper function for setting gpiod value

2018-12-30 Thread Alexey Khoroshilov
tw9910 driver tries to sleep for the smae period of time
after each gpiod_set_value(). The patch moves duplicated code
to a helper function.

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/i2c/tw9910.c | 30 +-
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c
index 0971f8a34afb..8d1138e13803 100644
--- a/drivers/media/i2c/tw9910.c
+++ b/drivers/media/i2c/tw9910.c
@@ -584,6 +584,14 @@ static int tw9910_s_register(struct v4l2_subdev *sd,
 }
 #endif
 
+static void tw9910_set_gpio_value(struct gpio_desc *desc, int value)
+{
+   if (desc) {
+   gpiod_set_value(desc, value);
+   usleep_range(500, 1000);
+   }
+}
+
 static int tw9910_power_on(struct tw9910_priv *priv)
 {
struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
@@ -595,10 +603,7 @@ static int tw9910_power_on(struct tw9910_priv *priv)
return ret;
}
 
-   if (priv->pdn_gpio) {
-   gpiod_set_value(priv->pdn_gpio, 0);
-   usleep_range(500, 1000);
-   }
+   tw9910_set_gpio_value(priv->pdn_gpio, 0);
 
/*
 * FIXME: The reset signal is connected to a shared GPIO on some
@@ -611,18 +616,13 @@ static int tw9910_power_on(struct tw9910_priv *priv)
if (IS_ERR(priv->rstb_gpio)) {
dev_info(&client->dev, "Unable to get GPIO \"rstb\"");
clk_disable_unprepare(priv->clk);
-   if (priv->pdn_gpio) {
-   gpiod_set_value(priv->pdn_gpio, 1);
-   usleep_range(500, 1000);
-   }
+   tw9910_set_gpio_value(priv->pdn_gpio, 1);
return PTR_ERR(priv->rstb_gpio);
}
 
if (priv->rstb_gpio) {
-   gpiod_set_value(priv->rstb_gpio, 1);
-   usleep_range(500, 1000);
-   gpiod_set_value(priv->rstb_gpio, 0);
-   usleep_range(500, 1000);
+   tw9910_set_gpio_value(priv->rstb_gpio, 1);
+   tw9910_set_gpio_value(priv->rstb_gpio, 0);
 
gpiod_put(priv->rstb_gpio);
}
@@ -633,11 +633,7 @@ static int tw9910_power_on(struct tw9910_priv *priv)
 static int tw9910_power_off(struct tw9910_priv *priv)
 {
clk_disable_unprepare(priv->clk);
-
-   if (priv->pdn_gpio) {
-   gpiod_set_value(priv->pdn_gpio, 1);
-   usleep_range(500, 1000);
-   }
+   tw9910_set_gpio_value(priv->pdn_gpio, 1);
 
return 0;
 }
-- 
2.7.4



Re: [PATCH] media: tw9910: add missed clk_disable_unprepare() on failure path

2018-12-30 Thread Alexey Khoroshilov
Hi Jacopo,

On 30.12.2018 12:49, Jacopo Mondi wrote:
> On Sun, Dec 30, 2018 at 12:35:20AM +0300, Alexey Khoroshilov wrote:
>> If gpiod_get_optional() fails in tw9910_power_on(), clk is left undisabled.
> 
> Correct, thanks for spotting this.
> 
> I think pdn_gpio should also be handled if rstb_gpio fails.
> What's your opinion?

I would agree. I'll send v2.

Thank you,
Alexey

> 
>> Found by Linux Driver Verification project (linuxtesting.org).
>>
>> Signed-off-by: Alexey Khoroshilov 
>> ---
>>  drivers/media/i2c/tw9910.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c
>> index a54548cc4285..109770d678d2 100644
>> --- a/drivers/media/i2c/tw9910.c
>> +++ b/drivers/media/i2c/tw9910.c
>> @@ -610,6 +610,7 @@ static int tw9910_power_on(struct tw9910_priv *priv)
>>   GPIOD_OUT_LOW);
>>  if (IS_ERR(priv->rstb_gpio)) {
>>  dev_info(&client->dev, "Unable to get GPIO \"rstb\"");
>> +clk_disable_unprepare(priv->clk);
>>  return PTR_ERR(priv->rstb_gpio);
>>  }
>>
>> --
>> 2.7.4
>>



[PATCH] media: tw9910: add missed clk_disable_unprepare() on failure path

2018-12-29 Thread Alexey Khoroshilov
If gpiod_get_optional() fails in tw9910_power_on(), clk is left undisabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/i2c/tw9910.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c
index a54548cc4285..109770d678d2 100644
--- a/drivers/media/i2c/tw9910.c
+++ b/drivers/media/i2c/tw9910.c
@@ -610,6 +610,7 @@ static int tw9910_power_on(struct tw9910_priv *priv)
 GPIOD_OUT_LOW);
if (IS_ERR(priv->rstb_gpio)) {
dev_info(&client->dev, "Unable to get GPIO \"rstb\"");
+   clk_disable_unprepare(priv->clk);
return PTR_ERR(priv->rstb_gpio);
}
 
-- 
2.7.4



[PATCH] [media] DaVinci-VPBE: fix error handling in vpbe_initialize()

2018-11-23 Thread Alexey Khoroshilov
If vpbe_set_default_output() or vpbe_set_default_mode() fails,
vpbe_initialize() returns error code without releasing resources.

The patch adds error handling for that case.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/platform/davinci/vpbe.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/davinci/vpbe.c 
b/drivers/media/platform/davinci/vpbe.c
index 18c035ef84cf..df1ae6b5c854 100644
--- a/drivers/media/platform/davinci/vpbe.c
+++ b/drivers/media/platform/davinci/vpbe.c
@@ -740,7 +740,7 @@ static int vpbe_initialize(struct device *dev, struct 
vpbe_device *vpbe_dev)
if (ret) {
v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default output %s",
 def_output);
-   return ret;
+   goto fail_kfree_amp;
}
 
printk(KERN_NOTICE "Setting default mode to %s\n", def_mode);
@@ -748,12 +748,15 @@ static int vpbe_initialize(struct device *dev, struct 
vpbe_device *vpbe_dev)
if (ret) {
v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default mode %s",
 def_mode);
-   return ret;
+   goto fail_kfree_amp;
}
vpbe_dev->initialized = 1;
/* TBD handling of bootargs for default output and mode */
return 0;
 
+fail_kfree_amp:
+   mutex_lock(&vpbe_dev->lock);
+   kfree(vpbe_dev->amp);
 fail_kfree_encoders:
kfree(vpbe_dev->encoders);
 fail_dev_unregister:
-- 
2.7.4



[PATCH] media: mtk-vcodec: Release device nodes in mtk_vcodec_init_enc_pm()

2018-10-20 Thread Alexey Khoroshilov
of_parse_phandle() returns the device node with refcount incremented.
There are two nodes that are used temporary in mtk_vcodec_init_enc_pm(),
but their refcounts are not decremented.

The patch adds one of_node_put() and fixes returning error codes.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 3e73e9db781f..7c025045ea90 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -41,25 +41,27 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
node = of_parse_phandle(dev->of_node, "mediatek,larb", 0);
if (!node) {
mtk_v4l2_err("no mediatek,larb found");
-   return -1;
+   return -ENODEV;
}
pdev = of_find_device_by_node(node);
+   of_node_put(node);
if (!pdev) {
mtk_v4l2_err("no mediatek,larb device found");
-   return -1;
+   return -ENODEV;
}
pm->larbvenc = &pdev->dev;
 
node = of_parse_phandle(dev->of_node, "mediatek,larb", 1);
if (!node) {
mtk_v4l2_err("no mediatek,larb found");
-   return -1;
+   return -ENODEV;
}
 
pdev = of_find_device_by_node(node);
+   of_node_put(node);
if (!pdev) {
mtk_v4l2_err("no mediatek,larb device found");
-   return -1;
+   return -ENODEV;
}
 
pm->larbvenclt = &pdev->dev;
-- 
2.7.4



[PATCH] media: tc358743: release device_node in tc358743_probe_of()

2018-05-25 Thread Alexey Khoroshilov
of_graph_get_next_endpoint() returns device_node with refcnt increased,
but these is no of_node_put() for it.

The patch adds one on error and normal paths.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/i2c/tc358743.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 393baad7..44c41933415a 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -1918,7 +1918,8 @@ static int tc358743_probe_of(struct tc358743_state *state)
endpoint = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep));
if (IS_ERR(endpoint)) {
dev_err(dev, "failed to parse endpoint\n");
-   return PTR_ERR(endpoint);
+   ret = PTR_ERR(endpoint);
+   goto put_node;
}
 
if (endpoint->bus_type != V4L2_MBUS_CSI2 ||
@@ -2013,6 +2014,8 @@ static int tc358743_probe_of(struct tc358743_state *state)
clk_disable_unprepare(refclk);
 free_endpoint:
v4l2_fwnode_endpoint_free(endpoint);
+put_node:
+   of_node_put(ep);
return ret;
 }
 #else
-- 
2.7.4



[PATCH] ir-hix5hd2: fix error handling of clk_prepare_enable()

2018-01-26 Thread Alexey Khoroshilov
Return code of clk_prepare_enable() is ignored in many places.
The patch adds error handling for all of them.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/rc/ir-hix5hd2.c | 35 ---
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c
index 0ce11c41dfae..700ab4c563d0 100644
--- a/drivers/media/rc/ir-hix5hd2.c
+++ b/drivers/media/rc/ir-hix5hd2.c
@@ -71,9 +71,10 @@ struct hix5hd2_ir_priv {
unsigned long   rate;
 };
 
-static void hix5hd2_ir_enable(struct hix5hd2_ir_priv *dev, bool on)
+static int hix5hd2_ir_enable(struct hix5hd2_ir_priv *dev, bool on)
 {
u32 val;
+   int ret = 0;
 
if (dev->regmap) {
regmap_read(dev->regmap, IR_CLK, &val);
@@ -87,10 +88,11 @@ static void hix5hd2_ir_enable(struct hix5hd2_ir_priv *dev, 
bool on)
regmap_write(dev->regmap, IR_CLK, val);
} else {
if (on)
-   clk_prepare_enable(dev->clock);
+   ret = clk_prepare_enable(dev->clock);
else
clk_disable_unprepare(dev->clock);
}
+   return ret;
 }
 
 static int hix5hd2_ir_config(struct hix5hd2_ir_priv *priv)
@@ -127,9 +129,18 @@ static int hix5hd2_ir_config(struct hix5hd2_ir_priv *priv)
 static int hix5hd2_ir_open(struct rc_dev *rdev)
 {
struct hix5hd2_ir_priv *priv = rdev->priv;
+   int ret;
+
+   ret = hix5hd2_ir_enable(priv, true);
+   if (ret)
+   return ret;
 
-   hix5hd2_ir_enable(priv, true);
-   return hix5hd2_ir_config(priv);
+   ret = hix5hd2_ir_config(priv);
+   if (ret) {
+   hix5hd2_ir_enable(priv, false);
+   return ret;
+   }
+   return 0;
 }
 
 static void hix5hd2_ir_close(struct rc_dev *rdev)
@@ -239,7 +250,9 @@ static int hix5hd2_ir_probe(struct platform_device *pdev)
ret = PTR_ERR(priv->clock);
goto err;
}
-   clk_prepare_enable(priv->clock);
+   ret = clk_prepare_enable(priv->clock);
+   if (ret)
+   goto err;
priv->rate = clk_get_rate(priv->clock);
 
rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
@@ -309,9 +322,17 @@ static int hix5hd2_ir_suspend(struct device *dev)
 static int hix5hd2_ir_resume(struct device *dev)
 {
struct hix5hd2_ir_priv *priv = dev_get_drvdata(dev);
+   int ret;
 
-   hix5hd2_ir_enable(priv, true);
-   clk_prepare_enable(priv->clock);
+   ret = hix5hd2_ir_enable(priv, true);
+   if (ret)
+   return ret;
+
+   ret = clk_prepare_enable(priv->clock);
+   if (ret) {
+   hix5hd2_ir_enable(priv, false);
+   return ret;
+   }
 
writel_relaxed(0x01, priv->base + IR_ENABLE);
writel_relaxed(0x00, priv->base + IR_INTM);
-- 
2.7.4



media: tc358743: clk_disable_unprepare(refclk) missed

2018-01-12 Thread Alexey Khoroshilov
Hello,

tc358743_probe_of() enables refclk and disables it on its error paths.
But there is no clk_disable_unprepare(refclk) in tc358743_remove()
and on error paths in tc358743_probe(). Is it a problem?

If we should fix it, is adding struct clk *refclk; to tc358743_state
the reasonable way to keep clk easily available?

Found by Linux Driver Verification project (linuxtesting.org).

--
Alexey Khoroshilov
Linux Verification Center, ISPRAS
web: http://linuxtesting.org



[PATCH] [media] v4l: mt9v032: Disable clock on error paths

2017-11-24 Thread Alexey Khoroshilov
mt9v032_power_on() leaves clk enabled in case of errors,
but it is not expected by its callers.
There is a similar problem in mt9v032_registered().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/i2c/mt9v032.c | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 8a430640c85d..4de63b2df334 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -294,14 +294,22 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032)
/* Reset the chip and stop data read out */
ret = regmap_write(map, MT9V032_RESET, 1);
if (ret < 0)
-   return ret;
+   goto err;
 
ret = regmap_write(map, MT9V032_RESET, 0);
if (ret < 0)
-   return ret;
+   goto err;
+
+   ret = regmap_write(map, MT9V032_CHIP_CONTROL,
+  MT9V032_CHIP_CONTROL_MASTER_MODE);
+   if (ret < 0)
+   goto err;
+
+   return 0;
 
-   return regmap_write(map, MT9V032_CHIP_CONTROL,
-   MT9V032_CHIP_CONTROL_MASTER_MODE);
+err:
+   clk_disable_unprepare(mt9v032->clk);
+   return ret;
 }
 
 static void mt9v032_power_off(struct mt9v032 *mt9v032)
@@ -876,6 +884,9 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
 
/* Read and check the sensor version */
ret = regmap_read(mt9v032->regmap, MT9V032_CHIP_VERSION, &version);
+
+   mt9v032_power_off(mt9v032);
+
if (ret < 0) {
dev_err(&client->dev, "Failed reading chip version\n");
return ret;
@@ -894,8 +905,6 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
return -ENODEV;
}
 
-   mt9v032_power_off(mt9v032);
-
dev_info(&client->dev, "%s detected at address 0x%02x\n",
 mt9v032->version->name, client->addr);
 
-- 
2.7.4



[PATCH] m2m-deinterlace: don't return zero on failure paths in deinterlace_probe()

2017-04-07 Thread Alexey Khoroshilov
If DMA does not support INTERLEAVE, deinterlace_probe() breaks off
initialization, releases dma channel, but returns zero.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/platform/m2m-deinterlace.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/platform/m2m-deinterlace.c 
b/drivers/media/platform/m2m-deinterlace.c
index bedc7cc4c7d6..980066b8d32a 100644
--- a/drivers/media/platform/m2m-deinterlace.c
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -1017,6 +1017,7 @@ static int deinterlace_probe(struct platform_device *pdev)
 
if (!dma_has_cap(DMA_INTERLEAVE, pcdev->dma_chan->device->cap_mask)) {
dev_err(&pdev->dev, "DMA does not support INTERLEAVE\n");
+   ret = -ENODEV;
goto rel_dma;
}
 
-- 
2.7.4



[media] s5p-cec: strange clk enabling pattern

2017-02-23 Thread Alexey Khoroshilov
The s5p-cec driver has a few places that touch hdmicec clk:

static int s5p_cec_probe(struct platform_device *pdev)
{
...
cec->clk = devm_clk_get(dev, "hdmicec");
if (IS_ERR(cec->clk))
return PTR_ERR(cec->clk);
...
}

static int __maybe_unused s5p_cec_runtime_suspend(struct device *dev)
{
struct s5p_cec_dev *cec = dev_get_drvdata(dev);

clk_disable_unprepare(cec->clk);
return 0;
}

static int __maybe_unused s5p_cec_runtime_resume(struct device *dev)
{
struct s5p_cec_dev *cec = dev_get_drvdata(dev);
int ret;

ret = clk_prepare_enable(cec->clk);
if (ret < 0)
return ret;
return 0;
}

Is it ok to enable/disable clock in rusume/suspend only?
Or have I missed anything?

--
Thank you,
Alexey Khoroshilov
Linux Verification Center, ISPRAS
web: http://linuxtesting.org



[BUG] au0828: dev->lock in au0828_usb_probe()

2016-06-22 Thread Alexey Khoroshilov
It is not quite clear what does mutex_lock(&dev->lock) defend against.

If there is a chance that some other code can try to lock the mutex during 
probe(),
then 
  mutex_unlock(&dev->lock);
  kfree(dev);
looks suspicious, because when that code get control form mutex_lock(dev->lock)
the dev could be already freed.

Otherwise, dev->lock should not be acquired so early.

Another problem is that on the path going via goto done
there is no mutex_unlock(&dev->lock).

Found by Linux Driver Verification project (linuxtesting.org).

--
Alexey Khoroshilov
Linux Verification Center, ISPRAS
web: http://linuxtesting.org

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] radio-maxiradio: fix memory leak when device is removed

2016-06-03 Thread Alexey Khoroshilov
Memory allocated for maxiradio device is not deallocated when
the device is removed.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/radio/radio-maxiradio.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/radio/radio-maxiradio.c 
b/drivers/media/radio/radio-maxiradio.c
index 70fd8e80198a..8253f79d5d75 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -183,6 +183,7 @@ static void maxiradio_remove(struct pci_dev *pdev)
outb(0, dev->io);
v4l2_device_unregister(v4l2_dev);
release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+   kfree(dev);
 }
 
 static struct pci_device_id maxiradio_pci_tbl[] = {
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] au0828: fix double free in au0828_usb_probe()

2016-04-22 Thread Alexey Khoroshilov
In case of failure au0828_v4l2_device_register() deallocates dev
and returns error code to au0828_usb_probe(), which also
calls kfree(dev) on a failure path.

The patch removes duplicated code from au0828_v4l2_device_register().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/usb/au0828/au0828-video.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-video.c 
b/drivers/media/usb/au0828/au0828-video.c
index 32d7db96479c..7d0ec4cb248c 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -679,8 +679,6 @@ int au0828_v4l2_device_register(struct usb_interface 
*interface,
if (retval) {
pr_err("%s() v4l2_device_register failed\n",
   __func__);
-   mutex_unlock(&dev->lock);
-   kfree(dev);
return retval;
}
 
@@ -691,8 +689,6 @@ int au0828_v4l2_device_register(struct usb_interface 
*interface,
if (retval) {
pr_err("%s() v4l2_ctrl_handler_init failed\n",
   __func__);
-   mutex_unlock(&dev->lock);
-   kfree(dev);
return retval;
}
dev->v4l2_dev.ctrl_handler = &dev->v4l2_ctrl_hdl;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] bt8xx: remove needless module refcounting

2016-04-08 Thread Alexey Khoroshilov
It is responsibility of a caller of fops->open(),
to make sure an owner of the fops is available until file is closed.
So, there is no need to lock THIS_MODULE explicitly.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/pci/bt8xx/dst_ca.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c
index da8b414fd824..8681b9143a35 100644
--- a/drivers/media/pci/bt8xx/dst_ca.c
+++ b/drivers/media/pci/bt8xx/dst_ca.c
@@ -655,7 +655,6 @@ static long dst_ca_ioctl(struct file *file, unsigned int 
cmd, unsigned long ioct
 static int dst_ca_open(struct inode *inode, struct file *file)
 {
dprintk(verbose, DST_CA_DEBUG, 1, " Device opened [%p] ", file);
-   try_module_get(THIS_MODULE);
 
return 0;
 }
@@ -663,7 +662,6 @@ static int dst_ca_open(struct inode *inode, struct file 
*file)
 static int dst_ca_release(struct inode *inode, struct file *file)
 {
dprintk(verbose, DST_CA_DEBUG, 1, " Device closed.");
-   module_put(THIS_MODULE);
 
return 0;
 }
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] lirc_imon: do not leave imon_probe() with mutex held

2015-11-14 Thread Alexey Khoroshilov
Commit af8a819a2513 ("[media] lirc_imon: simplify error handling code")
lost mutex_unlock(&context->ctx_lock), so imon_probe() exits with
the context->ctx_lock mutex acquired.

The patch adds mutex_unlock(&context->ctx_lock) back.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
Fixes: af8a819a2513 ("[media] lirc_imon: simplify error handling code")
---
 drivers/staging/media/lirc/lirc_imon.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/staging/media/lirc/lirc_imon.c 
b/drivers/staging/media/lirc/lirc_imon.c
index 534b8103ae80..ff1926ca1f96 100644
--- a/drivers/staging/media/lirc/lirc_imon.c
+++ b/drivers/staging/media/lirc/lirc_imon.c
@@ -885,12 +885,14 @@ static int imon_probe(struct usb_interface *interface,
vendor, product, ifnum, usbdev->bus->busnum, usbdev->devnum);
 
/* Everything went fine. Just unlock and return retval (with is 0) */
+   mutex_unlock(&context->ctx_lock);
goto driver_unlock;
 
 unregister_lirc:
lirc_unregister_driver(driver->minor);
 
 free_tx_urb:
+   mutex_unlock(&context->ctx_lock);
usb_free_urb(tx_urb);
 
 free_rx_urb:
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [media] marvell-ccic: fix memory leak on failure path in cafe_smbus_setup()

2015-04-04 Thread Alexey Khoroshilov
On 04.04.2015 16:36, Jonathan Corbet wrote:
> On Sat,  4 Apr 2015 03:16:01 +0300
> Alexey Khoroshilov  wrote:
> 
>> If i2c_add_adapter() fails, adap is not deallocated.
>>
>> Found by Linux Driver Verification project (linuxtesting.org).
>>
>> Signed-off-by: Alexey Khoroshilov 
> 
> Actually, the worse thing is that it leaves the IRQ enabled...it's good
> you moved that lines down.  Even better, of course, that the failure path
> has probably never been run during the life of this driver...:)

And hopefully it will not, but we will be ready:)

> 
> Should there be some sort of proper reported-by line for the driver
> verification project?

Till now, we used "Found by" line, but we are open to any better way.

> 
> Acked-by: Jonathan Corbet 

--
Alexey
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] marvell-ccic: fix memory leak on failure path in cafe_smbus_setup()

2015-04-03 Thread Alexey Khoroshilov
If i2c_add_adapter() fails, adap is not deallocated.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/platform/marvell-ccic/cafe-driver.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c 
b/drivers/media/platform/marvell-ccic/cafe-driver.c
index 562845361246..9d45505370cd 100644
--- a/drivers/media/platform/marvell-ccic/cafe-driver.c
+++ b/drivers/media/platform/marvell-ccic/cafe-driver.c
@@ -339,17 +339,21 @@ static int cafe_smbus_setup(struct cafe_camera *cam)
adap = kzalloc(sizeof(*adap), GFP_KERNEL);
if (adap == NULL)
return -ENOMEM;
-   cam->mcam.i2c_adapter = adap;
-   cafe_smbus_enable_irq(cam);
adap->owner = THIS_MODULE;
adap->algo = &cafe_smbus_algo;
strcpy(adap->name, "cafe_ccic");
adap->dev.parent = &cam->pdev->dev;
i2c_set_adapdata(adap, cam);
ret = i2c_add_adapter(adap);
-   if (ret)
+   if (ret) {
printk(KERN_ERR "Unable to register cafe i2c adapter\n");
-   return ret;
+   kfree(adap);
+   return ret;
+   }
+
+   cam->mcam.i2c_adapter = adap;
+   cafe_smbus_enable_irq(cam);
+   return 0;
 }
 
 static void cafe_smbus_shutdown(struct cafe_camera *cam)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] usbvision: fix leak of usb_dev on failure paths in usbvision_probe()

2015-03-27 Thread Alexey Khoroshilov
There is no usb_put_dev() on failure paths in usbvision_probe().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/usb/usbvision/usbvision-video.c | 24 +---
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/media/usb/usbvision/usbvision-video.c 
b/drivers/media/usb/usbvision/usbvision-video.c
index cd2fbf11e3b4..239d0e0ca087 100644
--- a/drivers/media/usb/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -1525,7 +1525,7 @@ static int usbvision_probe(struct usb_interface *intf,
const struct usb_host_interface *interface;
struct usb_usbvision *usbvision = NULL;
const struct usb_endpoint_descriptor *endpoint;
-   int model, i;
+   int model, i, ret;
 
PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u",
dev->descriptor.idVendor,
@@ -1534,7 +1534,8 @@ static int usbvision_probe(struct usb_interface *intf,
model = devid->driver_info;
if (model < 0 || model >= usbvision_device_data_size) {
PDEBUG(DBG_PROBE, "model out of bounds %d", model);
-   return -ENODEV;
+   ret = -ENODEV;
+   goto err_usb;
}
printk(KERN_INFO "%s: %s found\n", __func__,
usbvision_device_data[model].model_string);
@@ -1549,18 +1550,21 @@ static int usbvision_probe(struct usb_interface *intf,
__func__, ifnum);
dev_err(&intf->dev, "%s: Endpoint attributes %d",
__func__, endpoint->bmAttributes);
-   return -ENODEV;
+   ret = -ENODEV;
+   goto err_usb;
}
if (usb_endpoint_dir_out(endpoint)) {
dev_err(&intf->dev, "%s: interface %d. has ISO OUT endpoint!\n",
__func__, ifnum);
-   return -ENODEV;
+   ret = -ENODEV;
+   goto err_usb;
}
 
usbvision = usbvision_alloc(dev, intf);
if (usbvision == NULL) {
dev_err(&intf->dev, "%s: couldn't allocate USBVision struct\n", 
__func__);
-   return -ENOMEM;
+   ret = -ENOMEM;
+   goto err_usb;
}
 
if (dev->descriptor.bNumConfigurations > 1)
@@ -1579,8 +1583,8 @@ static int usbvision_probe(struct usb_interface *intf,
usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, 
GFP_KERNEL);
if (usbvision->alt_max_pkt_size == NULL) {
dev_err(&intf->dev, "usbvision: out of memory!\n");
-   usbvision_release(usbvision);
-   return -ENOMEM;
+   ret = -ENOMEM;
+   goto err_pkt;
}
 
for (i = 0; i < usbvision->num_alt; i++) {
@@ -1615,6 +1619,12 @@ static int usbvision_probe(struct usb_interface *intf,
 
PDEBUG(DBG_PROBE, "success");
return 0;
+
+err_pkt:
+   usbvision_release(usbvision);
+err_usb:
+   usb_put_dev(dev);
+   return ret;
 }
 
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] sh_vou: fix memory leak on error paths in sh_vou_open()

2015-02-13 Thread Alexey Khoroshilov
Memory allocated for sh_vou_file is not deallocated
on error paths in sh_vou_open().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/platform/sh_vou.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 261f1195b49f..6d1959d1ad02 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -1168,10 +1168,10 @@ static int sh_vou_open(struct file *file)
 
dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
 
-   file->private_data = vou_file;
-
-   if (mutex_lock_interruptible(&vou_dev->fop_lock))
+   if (mutex_lock_interruptible(&vou_dev->fop_lock)) {
+   kfree(vou_file);
return -ERESTARTSYS;
+   }
if (atomic_inc_return(&vou_dev->use_count) == 1) {
int ret;
/* First open */
@@ -1183,6 +1183,7 @@ static int sh_vou_open(struct file *file)
pm_runtime_put(vou_dev->v4l2_dev.dev);
vou_dev->status = SH_VOU_IDLE;
mutex_unlock(&vou_dev->fop_lock);
+   kfree(vou_file);
return ret;
}
}
@@ -1195,6 +1196,8 @@ static int sh_vou_open(struct file *file)
   vou_dev->vdev, &vou_dev->fop_lock);
mutex_unlock(&vou_dev->fop_lock);
 
+   file->private_data = vou_file;
+
return 0;
 }
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] cx231xx: fix usbdev leak on failure paths in cx231xx_usb_probe()

2015-01-16 Thread Alexey Khoroshilov
Commit b7085c086475 ("cx231xx: convert from pr_foo to dev_foo")
moves usb_get_dev(interface_to_usbdev(interface)) to the beginning
of cx231xx_usb_probe() to use udev->dev in dev_err(),
but it does not make sure usbdev is put on all failure paths.

Later dev_err(udev->dev) was replaced by dev_err(d).
So the patch moves usb_get_dev() below (before the first use)
and fixes another failure path.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/usb/cx231xx/cx231xx-cards.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c 
b/drivers/media/usb/cx231xx/cx231xx-cards.c
index ae05d591f228..33c2fa2e7596 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -1403,7 +1403,6 @@ static int cx231xx_usb_probe(struct usb_interface 
*interface,
struct usb_interface_assoc_descriptor *assoc_desc;
 
ifnum = interface->altsetting[0].desc.bInterfaceNumber;
-   udev = usb_get_dev(interface_to_usbdev(interface));
 
/*
 * Interface number 0 - IR interface (handled by mceusb driver)
@@ -1424,11 +1423,13 @@ static int cx231xx_usb_probe(struct usb_interface 
*interface,
}
} while (test_and_set_bit(nr, &cx231xx_devused));
 
+   udev = usb_get_dev(interface_to_usbdev(interface));
+
/* allocate memory for our device state and initialize it */
dev = devm_kzalloc(&udev->dev, sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
-   clear_bit(nr, &cx231xx_devused);
-   return -ENOMEM;
+   retval = -ENOMEM;
+   goto err_if;
}
 
snprintf(dev->name, 29, "cx231xx #%d", nr);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] imon: fix usbdev leaks

2014-09-15 Thread Alexey Khoroshilov
imon_probe() does three usb_get_dev(), but there is no any
usb_put_dev() in the driver.

The patch adds usb_put_dev() to error paths, to imon_disconnect()
and to imon_probe() as far as usbdev is not saved anywhere.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/rc/imon.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 7115e68ba697..06ff61ec3e1e 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -2181,6 +2181,7 @@ idev_setup_failed:
usb_kill_urb(ictx->rx_urb_intf0);
 urb_submit_failed:
 find_endpoint_failed:
+   usb_put_dev(ictx->usbdev_intf0);
mutex_unlock(&ictx->lock);
usb_free_urb(tx_urb);
 tx_urb_alloc_failed:
@@ -2253,6 +2254,7 @@ urb_submit_failed:
input_unregister_device(ictx->touch);
 touch_setup_failed:
 find_endpoint_failed:
+   usb_put_dev(ictx->usbdev_intf1);
mutex_unlock(&ictx->lock);
usb_free_urb(rx_urb);
 rx_urb_alloc_failed:
@@ -2366,11 +2368,13 @@ static int imon_probe(struct usb_interface *interface,
 usbdev->bus->busnum, usbdev->devnum);
 
mutex_unlock(&driver_lock);
+   usb_put_dev(usbdev);
 
return 0;
 
 fail:
mutex_unlock(&driver_lock);
+   usb_put_dev(usbdev);
dev_err(dev, "unable to register, err %d\n", ret);
 
return ret;
@@ -2410,6 +2414,7 @@ static void imon_disconnect(struct usb_interface 
*interface)
if (ifnum == 0) {
ictx->dev_present_intf0 = false;
usb_kill_urb(ictx->rx_urb_intf0);
+   usb_put_dev(ictx->usbdev_intf0);
input_unregister_device(ictx->idev);
rc_unregister_device(ictx->rdev);
if (ictx->display_supported) {
@@ -2421,6 +2426,7 @@ static void imon_disconnect(struct usb_interface 
*interface)
} else {
ictx->dev_present_intf1 = false;
usb_kill_urb(ictx->rx_urb_intf1);
+   usb_put_dev(ictx->usbdev_intf1);
if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
input_unregister_device(ictx->touch);
del_timer_sync(&ictx->ttimer);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [media] mceusb: fix usbdev leak

2014-09-10 Thread Alexey Khoroshilov
On 09.09.2014 14:39, Sean Young wrote:
> On Tue, Sep 09, 2014 at 02:10:43AM +0400, Alexey Khoroshilov wrote:
>> mceusb_init_rc_dev() does usb_get_dev(), but there is no any
>> usb_put_dev() in the driver.
> drivers/media/rc/imon.c suffers from the same problem.
>
> Thanks
> Sean
Yes, our static analyzers show that as well.

We will prepare a patch soon, if nobody has done it yet.

Thanks,
Alexey
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] mceusb: fix usbdev leak

2014-09-08 Thread Alexey Khoroshilov
mceusb_init_rc_dev() does usb_get_dev(), but there is no any
usb_put_dev() in the driver.

The patch tries to straighten logic. It moves usb_get_dev()
directly to mceusb_dev_probe() and adds usb_put_dev() to an error path
and to mceusb_dev_disconnect().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/rc/mceusb.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 45b0894288e5..23e532da0cf7 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -1198,10 +1198,9 @@ static void mceusb_flash_led(struct mceusb_dev *ir)
mce_async_out(ir, FLASH_LED, sizeof(FLASH_LED));
 }
 
-static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir,
-struct usb_interface *intf)
+static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
 {
-   struct usb_device *udev = usb_get_dev(interface_to_usbdev(intf));
+   struct usb_device *udev = ir->usbdev;
struct device *dev = ir->dev;
struct rc_dev *rc;
int ret;
@@ -1341,7 +1340,7 @@ static int mceusb_dev_probe(struct usb_interface *intf,
if (!ir->urb_in)
goto urb_in_alloc_fail;
 
-   ir->usbdev = dev;
+   ir->usbdev = usb_get_dev(dev);
ir->dev = &intf->dev;
ir->len_in = maxp;
ir->flags.microsoft_gen1 = is_microsoft_gen1;
@@ -1362,7 +1361,7 @@ static int mceusb_dev_probe(struct usb_interface *intf,
snprintf(name + strlen(name), sizeof(name) - strlen(name),
 " %s", buf);
 
-   ir->rc = mceusb_init_rc_dev(ir, intf);
+   ir->rc = mceusb_init_rc_dev(ir);
if (!ir->rc)
goto rc_dev_fail;
 
@@ -1408,6 +1407,7 @@ static int mceusb_dev_probe(struct usb_interface *intf,
 
/* Error-handling path */
 rc_dev_fail:
+   usb_put_dev(ir->usbdev);
usb_free_urb(ir->urb_in);
 urb_in_alloc_fail:
usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in);
@@ -1435,6 +1435,7 @@ static void mceusb_dev_disconnect(struct usb_interface 
*intf)
usb_kill_urb(ir->urb_in);
usb_free_urb(ir->urb_in);
usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in);
+   usb_put_dev(dev);
 
kfree(ir);
 }
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] tlg2300: fix leak at failure path in poseidon_probe()

2014-05-30 Thread Alexey Khoroshilov
Error handling code in poseidon_probe() misses usb_put_intf()
and usb_put_dev().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/usb/tlg2300/pd-main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/usb/tlg2300/pd-main.c 
b/drivers/media/usb/tlg2300/pd-main.c
index 3316caa4733b..b31f4791b8ff 100644
--- a/drivers/media/usb/tlg2300/pd-main.c
+++ b/drivers/media/usb/tlg2300/pd-main.c
@@ -476,6 +476,8 @@ err_audio:
 err_video:
v4l2_device_unregister(&pd->v4l2_dev);
 err_v4l2:
+   usb_put_intf(pd->interface);
+   usb_put_dev(pd->udev);
kfree(pd);
return ret;
 }
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] usbtv: fix leak at failure path in usbtv_probe()

2014-05-23 Thread Alexey Khoroshilov
Error handling code in usbtv_probe() misses usb_put_dev().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/usb/usbtv/usbtv-core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/usb/usbtv/usbtv-core.c 
b/drivers/media/usb/usbtv/usbtv-core.c
index 2f87ddfa469f..473fab81b602 100644
--- a/drivers/media/usb/usbtv/usbtv-core.c
+++ b/drivers/media/usb/usbtv/usbtv-core.c
@@ -91,6 +91,8 @@ static int usbtv_probe(struct usb_interface *intf,
return 0;
 
 usbtv_video_fail:
+   usb_set_intfdata(intf, NULL);
+   usb_put_dev(usbtv->udev);
kfree(usbtv);
 
return ret;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] ivtv: avoid GFP_KERNEL in atomic context

2014-04-25 Thread Alexey Khoroshilov
ivtv_yuv_init() is used in atomic context,
so memory allocation should be done keeping that in mind.

Call graph for ivtv_yuv_init() is as follows:
- ivtv_yuv_next_free()
  - ivtv_yuv_prep_frame() [ioctl handler]
  - ivtv_yuv_setup_stream_frame()
- ivtv_irq_dec_data_req() -> ivtv_irq_handler() [ATOMIC CONTEXT]
- ivtv_yuv_udma_stream_frame() [with mutex held]
- ivtv_write() [with mutex held]

The patch adds gfp_t argument and implements its usage according to the context.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/pci/ivtv/ivtv-fileops.c |  2 +-
 drivers/media/pci/ivtv/ivtv-irq.c |  2 +-
 drivers/media/pci/ivtv/ivtv-yuv.c | 16 
 drivers/media/pci/ivtv/ivtv-yuv.h |  2 +-
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/media/pci/ivtv/ivtv-fileops.c 
b/drivers/media/pci/ivtv/ivtv-fileops.c
index 9caffd8aa995..2e8885c245e7 100644
--- a/drivers/media/pci/ivtv/ivtv-fileops.c
+++ b/drivers/media/pci/ivtv/ivtv-fileops.c
@@ -689,7 +689,7 @@ retry:
int got_sig;
 
if (mode == OUT_YUV)
-   ivtv_yuv_setup_stream_frame(itv);
+   ivtv_yuv_setup_stream_frame(itv, GFP_KERNEL);
 
mutex_unlock(&itv->serialize_lock);
prepare_to_wait(&itv->dma_waitq, &wait, 
TASK_INTERRUPTIBLE);
diff --git a/drivers/media/pci/ivtv/ivtv-irq.c 
b/drivers/media/pci/ivtv/ivtv-irq.c
index 19a7c9b990a3..7a44f6b7aed4 100644
--- a/drivers/media/pci/ivtv/ivtv-irq.c
+++ b/drivers/media/pci/ivtv/ivtv-irq.c
@@ -822,7 +822,7 @@ static void ivtv_irq_dec_data_req(struct ivtv *itv)
}
else {
if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
-   ivtv_yuv_setup_stream_frame(itv);
+   ivtv_yuv_setup_stream_frame(itv, GFP_ATOMIC);
clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
ivtv_queue_move(s, &s->q_full, NULL, &s->q_predma, 
itv->dma_data_req_size);
ivtv_dma_stream_dec_prepare(s, itv->dma_data_req_offset + 
IVTV_DECODER_OFFSET, 0);
diff --git a/drivers/media/pci/ivtv/ivtv-yuv.c 
b/drivers/media/pci/ivtv/ivtv-yuv.c
index 2ad65eb29832..9bf47b89f8a0 100644
--- a/drivers/media/pci/ivtv/ivtv-yuv.c
+++ b/drivers/media/pci/ivtv/ivtv-yuv.c
@@ -854,7 +854,7 @@ void ivtv_yuv_work_handler(struct ivtv *itv)
yi->old_frame_info = f;
 }
 
-static void ivtv_yuv_init(struct ivtv *itv)
+static void ivtv_yuv_init(struct ivtv *itv, gfp_t gfp)
 {
struct yuv_playback_info *yi = &itv->yuv_info;
 
@@ -936,7 +936,7 @@ static void ivtv_yuv_init(struct ivtv *itv)
}
 
/* We need a buffer for blanking when Y plane is offset - non-fatal if 
we can't get one */
-   yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
+   yi->blanking_ptr = kzalloc(720 * 16, gfp|__GFP_NOWARN);
if (yi->blanking_ptr) {
yi->blanking_dmaptr = pci_map_single(itv->pdev, 
yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
} else {
@@ -952,13 +952,13 @@ static void ivtv_yuv_init(struct ivtv *itv)
 }
 
 /* Get next available yuv buffer on PVR350 */
-static void ivtv_yuv_next_free(struct ivtv *itv)
+static void ivtv_yuv_next_free(struct ivtv *itv, gfp_t gfp)
 {
int draw, display;
struct yuv_playback_info *yi = &itv->yuv_info;
 
if (atomic_read(&yi->next_dma_frame) == -1)
-   ivtv_yuv_init(itv);
+   ivtv_yuv_init(itv, gfp);
 
draw = atomic_read(&yi->next_fill_frame);
display = atomic_read(&yi->next_dma_frame);
@@ -1119,12 +1119,12 @@ static int ivtv_yuv_udma_frame(struct ivtv *itv, struct 
ivtv_dma_frame *args)
 }
 
 /* Setup frame according to V4L2 parameters */
-void ivtv_yuv_setup_stream_frame(struct ivtv *itv)
+void ivtv_yuv_setup_stream_frame(struct ivtv *itv, gfp_t gfp)
 {
struct yuv_playback_info *yi = &itv->yuv_info;
struct ivtv_dma_frame dma_args;
 
-   ivtv_yuv_next_free(itv);
+   ivtv_yuv_next_free(itv, gfp);
 
/* Copy V4L2 parameters to an ivtv_dma_frame struct... */
dma_args.y_source = NULL;
@@ -1151,7 +1151,7 @@ int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void 
__user *src)
struct ivtv_dma_frame dma_args;
int res;
 
-   ivtv_yuv_setup_stream_frame(itv);
+   ivtv_yuv_setup_stream_frame(itv, GFP_KERNEL);
 
/* We only need to supply source addresses for this */
dma_args.y_source = src;
@@ -1171,7 +1171,7 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct 
ivtv_dma_frame *args)
int res;
 
 /* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */
-   ivtv_yuv_next_free(itv);
+   ivtv_yuv_next_free(itv, GFP_KERNEL);
ivtv_yuv_setup_frame(itv, 

[PATCH] [media] adv7180: free an interrupt on failure paths in init_device()

2014-03-14 Thread Alexey Khoroshilov
There is request_irq() in init_device(), but the interrupt is not removed
on failure paths. The patch adds proper error handling.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/i2c/adv7180.c | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index d7d99f1c69e4..e462392ba043 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -541,40 +541,44 @@ static int init_device(struct i2c_client *client, struct 
adv7180_state *state)
ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
ADV7180_ADI_CTRL_IRQ_SPACE);
if (ret < 0)
-   return ret;
+   goto err;
 
/* config the Interrupt pin to be active low */
ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI,
ADV7180_ICONF1_ACTIVE_LOW |
ADV7180_ICONF1_PSYNC_ONLY);
if (ret < 0)
-   return ret;
+   goto err;
 
ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0);
if (ret < 0)
-   return ret;
+   goto err;
 
ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0);
if (ret < 0)
-   return ret;
+   goto err;
 
/* enable AD change interrupts interrupts */
ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI,
ADV7180_IRQ3_AD_CHANGE);
if (ret < 0)
-   return ret;
+   goto err;
 
ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0);
if (ret < 0)
-   return ret;
+   goto err;
 
ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
0);
if (ret < 0)
-   return ret;
+   goto err;
}
 
return 0;
+
+err:
+   free_irq(state->irq, state);
+   return ret;
 }
 
 static int adv7180_probe(struct i2c_client *client,
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] as102: fix leaks at failure paths in as102_usb_probe()

2013-12-27 Thread Alexey Khoroshilov
Failure handling is incomplete in as102_usb_probe().
The patch implements proper resource deallocations.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/staging/media/as102/as102_usb_drv.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/as102/as102_usb_drv.c 
b/drivers/staging/media/as102/as102_usb_drv.c
index 9f275f020150..c1c6152d1ab4 100644
--- a/drivers/staging/media/as102/as102_usb_drv.c
+++ b/drivers/staging/media/as102/as102_usb_drv.c
@@ -419,15 +419,22 @@ static int as102_usb_probe(struct usb_interface *intf,
/* request buffer allocation for streaming */
ret = as102_alloc_usb_stream_buffer(as102_dev);
if (ret != 0)
-   goto failed;
+   goto failed_stream;
 
/* register dvb layer */
ret = as102_dvb_register(as102_dev);
+   if (ret != 0)
+   goto failed_dvb;
 
LEAVE();
return ret;
 
+failed_dvb:
+   as102_free_usb_stream_buffer(as102_dev);
+failed_stream:
+   usb_deregister_dev(intf, &as102_usb_class_driver);
 failed:
+   usb_put_dev(as102_dev->bus_adap.usb_dev);
usb_set_intfdata(intf, NULL);
kfree(as102_dev);
return ret;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] go7007-loader: fix usb_dev leak

2013-12-20 Thread Alexey Khoroshilov
There is usb_get_dev() in go7007_loader_probe(),
but there is no usb_put_dev() anywhere.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/staging/media/go7007/go7007-loader.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/go7007/go7007-loader.c 
b/drivers/staging/media/go7007/go7007-loader.c
index f846ad5819dc..2b15952e4c18 100644
--- a/drivers/staging/media/go7007/go7007-loader.c
+++ b/drivers/staging/media/go7007/go7007-loader.c
@@ -60,7 +60,7 @@ static int go7007_loader_probe(struct usb_interface 
*interface,
 
if (usbdev->descriptor.bNumConfigurations != 1) {
dev_err(&interface->dev, "can't handle multiple config\n");
-   return -ENODEV;
+   goto failed2;
}
 
vendor = le16_to_cpu(usbdev->descriptor.idVendor);
@@ -109,6 +109,7 @@ static int go7007_loader_probe(struct usb_interface 
*interface,
return 0;
 
 failed2:
+   usb_put_dev(usbdev);
dev_err(&interface->dev, "probe failed\n");
return -ENODEV;
 }
@@ -116,6 +117,7 @@ failed2:
 static void go7007_loader_disconnect(struct usb_interface *interface)
 {
dev_info(&interface->dev, "disconnect\n");
+   usb_put_dev(interface_to_usbdev(interface));
usb_set_intfdata(interface, NULL);
 }
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] cxusb: fix mismatch in mutex lock-unlock in cxusb_i2c_xfer()

2013-11-29 Thread Alexey Khoroshilov
There are several failure paths in cxusb_i2c_xfer(), where
d->i2c_mutex is left held. The patch fixes them.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/usb/dvb-usb/cxusb.c | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/cxusb.c 
b/drivers/media/usb/dvb-usb/cxusb.c
index 20e345d9fe8f..00b42984f1dd 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -149,7 +149,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msg[],
  int num)
 {
struct dvb_usb_device *d = i2c_get_adapdata(adap);
-   int i;
+   int i, ret;
 
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
@@ -173,7 +173,8 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msg[],
if (1 + msg[i].len > sizeof(ibuf)) {
warn("i2c rd: len=%d is too big!\n",
 msg[i].len);
-   return -EOPNOTSUPP;
+   ret = -EOPNOTSUPP;
+   goto unlock;
}
obuf[0] = 0;
obuf[1] = msg[i].len;
@@ -193,12 +194,14 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, 
struct i2c_msg msg[],
if (3 + msg[i].len > sizeof(obuf)) {
warn("i2c wr: len=%d is too big!\n",
 msg[i].len);
-   return -EOPNOTSUPP;
+   ret = -EOPNOTSUPP;
+   goto unlock;
}
if (1 + msg[i + 1].len > sizeof(ibuf)) {
warn("i2c rd: len=%d is too big!\n",
 msg[i + 1].len);
-   return -EOPNOTSUPP;
+   ret = -EOPNOTSUPP;
+   goto unlock;
}
obuf[0] = msg[i].len;
obuf[1] = msg[i+1].len;
@@ -223,7 +226,8 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msg[],
if (2 + msg[i].len > sizeof(obuf)) {
warn("i2c wr: len=%d is too big!\n",
 msg[i].len);
-   return -EOPNOTSUPP;
+   ret = -EOPNOTSUPP;
+   goto unlock;
}
obuf[0] = msg[i].addr;
obuf[1] = msg[i].len;
@@ -236,9 +240,10 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msg[],
deb_i2c("i2c write may have failed\n");
}
}
-
+   ret = (i == num) ? num : -EREMOTEIO;
+unlock:
mutex_unlock(&d->i2c_mutex);
-   return i == num ? num : -EREMOTEIO;
+   return ret;
 }
 
 static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] cx231xx: fix double free and leaks on failure path in cx231xx_usb_probe()

2013-10-07 Thread Alexey Khoroshilov
There are numerous issues in error handling code of cx231xx initialization.
Double free (when cx231xx_init_dev() calls kfree(dev) via 
cx231xx_release_resources()
and then cx231xx_usb_probe() does the same) and memory leaks
(e.g. usb_get_dev() before (ifnum != 1) check in cx231xx_usb_probe())
are just a few of them.

The patch fixes the issues in cx231xx_usb_probe() and cx231xx_init_dev()
by moving usb_get_dev(interface_to_usbdev(interface)) below in code and
implementing proper error handling.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/usb/cx231xx/cx231xx-cards.c | 110 --
 1 file changed, 57 insertions(+), 53 deletions(-)

diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c 
b/drivers/media/usb/cx231xx/cx231xx-cards.c
index a384f80..e9d017b 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -978,7 +978,6 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct 
usb_device *udev,
int minor)
 {
int retval = -ENOMEM;
-   int errCode;
unsigned int maxh, maxw;
 
dev->udev = udev;
@@ -1014,8 +1013,8 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct 
usb_device *udev,
/* Cx231xx pre card setup */
cx231xx_pre_card_setup(dev);
 
-   errCode = cx231xx_config(dev);
-   if (errCode) {
+   retval = cx231xx_config(dev);
+   if (retval) {
cx231xx_errdev("error configuring device\n");
return -ENOMEM;
}
@@ -1024,12 +1023,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct 
usb_device *udev,
dev->norm = dev->board.norm;
 
/* register i2c bus */
-   errCode = cx231xx_dev_init(dev);
-   if (errCode < 0) {
-   cx231xx_dev_uninit(dev);
+   retval = cx231xx_dev_init(dev);
+   if (retval) {
cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n",
-  __func__, errCode);
-   return errCode;
+  __func__, retval);
+   goto err_dev_init;
}
 
/* Do board specific init */
@@ -1047,11 +1045,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct 
usb_device *udev,
dev->interlaced = 0;
dev->video_input = 0;
 
-   errCode = cx231xx_config(dev);
-   if (errCode < 0) {
+   retval = cx231xx_config(dev);
+   if (retval) {
cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n",
-  __func__, errCode);
-   return errCode;
+  __func__, retval);
+   goto err_dev_init;
}
 
/* init video dma queues */
@@ -1075,9 +1073,9 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct 
usb_device *udev,
}
 
retval = cx231xx_register_analog_devices(dev);
-   if (retval < 0) {
-   cx231xx_release_resources(dev);
-   return retval;
+   if (retval) {
+   cx231xx_release_analog_resources(dev);
+   goto err_analog;
}
 
cx231xx_ir_init(dev);
@@ -1085,6 +1083,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct 
usb_device *udev,
cx231xx_init_extension(dev);
 
return 0;
+err_analog:
+   cx231xx_remove_from_devlist(dev);
+err_dev_init:
+   cx231xx_dev_uninit(dev);
+   return retval;
 }
 
 #if defined(CONFIG_MODULES) && defined(MODULE)
@@ -1132,7 +1135,6 @@ static int cx231xx_usb_probe(struct usb_interface 
*interface,
char *speed;
struct usb_interface_assoc_descriptor *assoc_desc;
 
-   udev = usb_get_dev(interface_to_usbdev(interface));
ifnum = interface->altsetting[0].desc.bInterfaceNumber;
 
/*
@@ -1161,6 +1163,8 @@ static int cx231xx_usb_probe(struct usb_interface 
*interface,
return -ENOMEM;
}
 
+   udev = usb_get_dev(interface_to_usbdev(interface));
+
snprintf(dev->name, 29, "cx231xx #%d", nr);
dev->devno = nr;
dev->model = id->driver_info;
@@ -1223,10 +1227,8 @@ static int cx231xx_usb_probe(struct usb_interface 
*interface,
if (assoc_desc->bFirstInterface != ifnum) {
cx231xx_err(DRIVER_NAME ": Not found "
"matching IAD interface\n");
-   clear_bit(dev->devno, &cx231xx_devused);
-   kfree(dev);
-   dev = NULL;
-   return -ENODEV;
+   retval = -ENODEV;
+   goto err_if;
}
 
cx231xx_info("registering interface %d\n", ifnum);
@@ -1242,22 +1244,13 @@ static int cx231xx_usb_probe(struct usb_interface 
*interface,
retval = v4l2_device_register(&interface->dev, &d

[PATCH v2] [media] dvb_demux: fix deadlock in dmx_section_feed_release_filter()

2013-10-07 Thread Alexey Khoroshilov
dmx_section_feed_release_filter() locks dvbdmx->mutex and
if the feed is still filtering, it calls feed->stop_filtering(feed).
stop_filtering() is implemented by dmx_section_feed_stop_filtering()
that first of all try to lock the same mutex: dvbdmx->mutex.
That leads to a deadlock.

It does not happen often in practice because all callers of
release_filter() stop filtering by themselves.
So the problem can happen in case of race condition only.

The patch releases dvbdmx->mutex before call to feed->stop_filtering(feed)
and reacquires the mutex after that.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/dvb-core/dvb_demux.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-core/dvb_demux.c 
b/drivers/media/dvb-core/dvb_demux.c
index 3485655..6de3bd0 100644
--- a/drivers/media/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb-core/dvb_demux.c
@@ -1027,8 +1027,13 @@ static int dmx_section_feed_release_filter(struct 
dmx_section_feed *feed,
return -EINVAL;
}
 
-   if (feed->is_filtering)
+   if (feed->is_filtering) {
+   /* release dvbdmx->mutex as far as 
+  it is acquired by stop_filtering() itself */
+   mutex_unlock(&dvbdmx->mutex);
feed->stop_filtering(feed);
+   mutex_lock(&dvbdmx->mutex);
+   }
 
spin_lock_irq(&dvbdmx->lock);
f = dvbdmxfeed->filter;
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] dvb_demux: fix deadlock in dmx_section_feed_release_filter()

2013-08-17 Thread Alexey Khoroshilov
dmx_section_feed_release_filter() locks dvbdmx->mutex and
if the feed is still filtering, it calls feed->stop_filtering(feed).
stop_filtering() is implemented by dmx_section_feed_stop_filtering()
that first of all try to lock the same mutex: dvbdmx->mutex.
That leads to a deadlock.

It does not happen often in practice because all callers of
release_filter() stop filtering by themselves.
So the problem can happen in case of race condition only.

The patch proposes to unlock dvbdmx->mutex before call 
feed->stop_filtering(feed)
and recheck feed->is_filtering after reacquiring mutex.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/dvb-core/dvb_demux.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-core/dvb_demux.c 
b/drivers/media/dvb-core/dvb_demux.c
index 3485655..9d517af 100644
--- a/drivers/media/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb-core/dvb_demux.c
@@ -1027,8 +1027,11 @@ static int dmx_section_feed_release_filter(struct 
dmx_section_feed *feed,
return -EINVAL;
}
 
-   if (feed->is_filtering)
+   while (feed->is_filtering) {
+   mutex_unlock(&dvbdmx->mutex);
feed->stop_filtering(feed);
+   mutex_lock(&dvbdmx->mutex);
+   }
 
spin_lock_irq(&dvbdmx->lock);
f = dvbdmxfeed->filter;
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] gspca: fix dev_open() error path

2013-08-05 Thread Alexey Khoroshilov
If v4l2_fh_open() fails in dev_open(), gspca_dev->module left locked.
The patch adds module_put(gspca_dev->module) on this path.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/usb/gspca/gspca.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
index b7ae872..048507b 100644
--- a/drivers/media/usb/gspca/gspca.c
+++ b/drivers/media/usb/gspca/gspca.c
@@ -1266,6 +1266,7 @@ static void gspca_release(struct v4l2_device *v4l2_device)
 static int dev_open(struct file *file)
 {
struct gspca_dev *gspca_dev = video_drvdata(file);
+   int ret;
 
PDEBUG(D_STREAM, "[%s] open", current->comm);
 
@@ -1273,7 +1274,10 @@ static int dev_open(struct file *file)
if (!try_module_get(gspca_dev->module))
return -ENODEV;
 
-   return v4l2_fh_open(file);
+   ret = v4l2_fh_open(file);
+   if (ret)
+   module_put(gspca_dev->module);
+   return ret;
 }
 
 static int dev_close(struct file *file)
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] dvb-usb: fix error handling in ttusb_dec_probe()

2013-07-13 Thread Alexey Khoroshilov
There is an asymmetry in ttusb_dec_init_usb()-ttusb_init_rc()
and ttusb_dec_exit_usb()-ttusb_dec_exit_rc() in terms of resources
allocated-deallocated. irq_urb and irq_buffer are allocated in
ttusb_dec_init_usb(), while they are deallocated in ttusb_dec_exit_rc().
As a result there is a leak of them in ttusb_dec_probe().

The patch fixes the asymmetry and a leak on a failure path in 
ttusb_dec_init_usb().
By the way, it
- removes usage of -1 as a custom error code,
- replaces GFP_ATOMIC by GFP_KERNEL in usb_alloc_coherent() in 
ttusb_dec_init_usb()
  as soon as all other memory allocation done with GFP_KERNEL;
- refactors ttusb_dec_boot_dsp() in an equivalent way except for returning 0
  instead of 1 if ttusb_dec_boot_dsp() succeed in (!mode) branch.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/usb/ttusb-dec/ttusb_dec.c | 152 +---
 1 file changed, 82 insertions(+), 70 deletions(-)

diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c 
b/drivers/media/usb/ttusb-dec/ttusb_dec.c
index e52c3b9..29724af 100644
--- a/drivers/media/usb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c
@@ -366,7 +366,7 @@ static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, 
unsigned int *mode,
}
return 0;
} else {
-   return -1;
+   return -ENOENT;
}
 }
 
@@ -1241,6 +1241,8 @@ static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
 
 static int ttusb_dec_init_usb(struct ttusb_dec *dec)
 {
+   int result;
+
dprintk("%s\n", __func__);
 
mutex_init(&dec->usb_mutex);
@@ -1258,7 +1260,7 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec)
return -ENOMEM;
}
dec->irq_buffer = usb_alloc_coherent(dec->udev,IRQ_PACKET_SIZE,
-   GFP_ATOMIC, &dec->irq_dma_handle);
+   GFP_KERNEL, &dec->irq_dma_handle);
if(!dec->irq_buffer) {
usb_free_urb(dec->irq_urb);
return -ENOMEM;
@@ -1270,7 +1272,13 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec)
dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
}
 
-   return ttusb_dec_alloc_iso_urbs(dec);
+   result = ttusb_dec_alloc_iso_urbs(dec);
+   if (result) {
+   usb_free_urb(dec->irq_urb);
+   usb_free_coherent(dec->udev, IRQ_PACKET_SIZE,
+ dec->irq_buffer, dec->irq_dma_handle);
+   }
+   return result;
 }
 
 static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
@@ -1293,10 +1301,11 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
 
dprintk("%s\n", __func__);
 
-   if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) {
+   result = request_firmware(&fw_entry, dec->firmware_name, 
&dec->udev->dev);
+   if (result) {
printk(KERN_ERR "%s: Firmware (%s) unavailable.\n",
   __func__, dec->firmware_name);
-   return 1;
+   return result;
}
 
firmware = fw_entry->data;
@@ -1306,7 +1315,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
printk("%s: firmware size too small for DSP code (%zu < 60).\n",
__func__, firmware_size);
release_firmware(fw_entry);
-   return -1;
+   return -ENOENT;
}
 
/* a 32 bit checksum over the first 56 bytes of the DSP Code is stored
@@ -1320,7 +1329,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
   "0x%08x != 0x%08x in file), file invalid.\n",
__func__, crc32_csum, crc32_check);
release_firmware(fw_entry);
-   return -1;
+   return -ENOENT;
}
memcpy(idstring, &firmware[36], 20);
idstring[20] = '\0';
@@ -1389,55 +1398,48 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec)
dprintk("%s\n", __func__);
 
result = ttusb_dec_get_stb_state(dec, &mode, &model, &version);
+   if (result)
+   return result;
 
-   if (!result) {
-   if (!mode) {
-   if (version == 0xABCDEFAB)
-   printk(KERN_INFO "ttusb_dec: no version "
-  "info in Firmware\n");
-   else
-   printk(KERN_INFO "ttusb_dec: Firmware "
-  "%x.%02x%c%c\n",
-  version >> 24, (version >> 

[PATCH] [media] hdpvr: fix iteration over uninitialized lists in hdpvr_probe()

2013-07-03 Thread Alexey Khoroshilov
free_buff_list and rec_buff_list are initialized in the middle of hdpvr_probe(),
but if something bad happens before that, error handling code calls 
hdpvr_delete(),
which contains iteration over the lists (via hdpvr_free_buffers()).

The patch moves the lists initialization to the beginning and by the way fixes
goto label in error handling of registering videodev.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/usb/hdpvr/hdpvr-core.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c 
b/drivers/media/usb/hdpvr/hdpvr-core.c
index 8247c19..77d7b7f 100644
--- a/drivers/media/usb/hdpvr/hdpvr-core.c
+++ b/drivers/media/usb/hdpvr/hdpvr-core.c
@@ -311,6 +311,11 @@ static int hdpvr_probe(struct usb_interface *interface,
 
dev->workqueue = 0;
 
+   /* init video transfer queues first of all */
+   /* to prevent oops in hdpvr_delete() on error paths */
+   INIT_LIST_HEAD(&dev->free_buff_list);
+   INIT_LIST_HEAD(&dev->rec_buff_list);
+
/* register v4l2_device early so it can be used for printks */
if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
dev_err(&interface->dev, "v4l2_device_register failed\n");
@@ -333,10 +338,6 @@ static int hdpvr_probe(struct usb_interface *interface,
if (!dev->workqueue)
goto error;
 
-   /* init video transfer queues */
-   INIT_LIST_HEAD(&dev->free_buff_list);
-   INIT_LIST_HEAD(&dev->rec_buff_list);
-
dev->options = hdpvr_default_options;
 
if (default_video_input < HDPVR_VIDEO_INPUTS)
@@ -413,7 +414,7 @@ static int hdpvr_probe(struct usb_interface *interface,
video_nr[atomic_inc_return(&dev_nr)]);
if (retval < 0) {
v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
-   goto error;
+   goto reg_fail;
}
 
/* let the user know what node this device is now attached to */
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] [media] tlg2300: fix checking firmware in poseidon_probe()

2013-06-24 Thread Alexey Khoroshilov
check_firmware() makes sure firmware is in a device.
It returns zero on success and error code otherwise.
Also it sets down_firmware flag to 1 if downloading occurs.

The only caller poseidon_probe() checks down_firmware flag and
returns 0 without any initialization if it is set.

That looks very strange, so the patch removes down_firmware argument
of check_firmware() and returns error code if check_firmware() fails
in poseidon_probe().

Not tested on real hardware.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/usb/tlg2300/pd-main.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/media/usb/tlg2300/pd-main.c 
b/drivers/media/usb/tlg2300/pd-main.c
index ca5e1bc..95f94e5 100644
--- a/drivers/media/usb/tlg2300/pd-main.c
+++ b/drivers/media/usb/tlg2300/pd-main.c
@@ -375,7 +375,7 @@ static inline void set_map_flags(struct poseidon *pd, 
struct usb_device *udev)
 }
 #endif
 
-static int check_firmware(struct usb_device *udev, int *down_firmware)
+static int check_firmware(struct usb_device *udev)
 {
void *buf;
int ret;
@@ -395,10 +395,8 @@ static int check_firmware(struct usb_device *udev, int 
*down_firmware)
 USB_CTRL_GET_TIMEOUT);
kfree(buf);
 
-   if (ret < 0) {
-   *down_firmware = 1;
+   if (ret < 0)
return firmware_download(udev);
-   }
return 0;
 }
 
@@ -411,9 +409,9 @@ static int poseidon_probe(struct usb_interface *interface,
int new_one = 0;
 
/* download firmware */
-   check_firmware(udev, &ret);
+   ret = check_firmware(udev);
if (ret)
-   return 0;
+   return ret;
 
/* Do I recovery from the hibernate ? */
pd = find_old_poseidon(udev);
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] [media] tlg2300: implement error handling in poseidon_probe()

2013-06-24 Thread Alexey Khoroshilov
All poseidon init functions properly return error codes,
but they are ignored by poseidon_probe(). The patch implements
handling of error cases.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/usb/tlg2300/pd-main.c | 27 ---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/media/usb/tlg2300/pd-main.c 
b/drivers/media/usb/tlg2300/pd-main.c
index e07e4c6..ca5e1bc 100644
--- a/drivers/media/usb/tlg2300/pd-main.c
+++ b/drivers/media/usb/tlg2300/pd-main.c
@@ -436,12 +436,22 @@ static int poseidon_probe(struct usb_interface *interface,
 
/* register v4l2 device */
ret = v4l2_device_register(&interface->dev, &pd->v4l2_dev);
+   if (ret)
+   goto err_v4l2;
 
/* register devices in directory /dev */
ret = pd_video_init(pd);
-   poseidon_audio_init(pd);
-   poseidon_fm_init(pd);
-   pd_dvb_usb_device_init(pd);
+   if (ret)
+   goto err_video;
+   ret = poseidon_audio_init(pd);
+   if (ret)
+   goto err_audio;
+   ret = poseidon_fm_init(pd);
+   if (ret)
+   goto err_fm;
+   ret = pd_dvb_usb_device_init(pd);
+   if (ret)
+   goto err_dvb;
 
INIT_LIST_HEAD(&pd->device_list);
list_add_tail(&pd->device_list, &pd_device_list);
@@ -459,6 +469,17 @@ static int poseidon_probe(struct usb_interface *interface,
}
 #endif
return 0;
+err_dvb:
+   poseidon_fm_exit(pd);
+err_fm:
+   poseidon_audio_free(pd);
+err_audio:
+   pd_video_exit(pd);
+err_video:
+   v4l2_device_unregister(&pd->v4l2_dev);
+err_v4l2:
+   kfree(pd);
+   return ret;
 }
 
 static void poseidon_disconnect(struct usb_interface *interface)
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] go7007: fix return 0 for unsupported devices in go7007_usb_probe()

2013-06-19 Thread Alexey Khoroshilov
probe() should not return 0 for unsupported devices, but go7007_usb_probe() 
does.
The patch fixes it to return -ENODEV.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/staging/media/go7007/go7007-usb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-usb.c 
b/drivers/staging/media/go7007/go7007-usb.c
index 50066e0..46ed832 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -1124,7 +1124,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
case GO7007_BOARDID_LIFEVIEW_LR192:
printk(KERN_ERR "go7007-usb: The Lifeview TV Walker Ultra "
"is not supported.  Sorry!\n");
-   return 0;
+   return -ENODEV;
name = "Lifeview TV Walker Ultra";
board = &board_lifeview_lr192;
break;
@@ -1140,7 +1140,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
default:
printk(KERN_ERR "go7007-usb: unknown board ID %d!\n",
(unsigned int)id->driver_info);
-   return 0;
+   return -ENODEV;
}
 
go = go7007_alloc(&board->main_info, &intf->dev);
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] usbvision-video: fix memory leak of alt_max_pkt_size

2013-06-10 Thread Alexey Khoroshilov
1. usbvision->alt_max_pkt_size is not deallocated anywhere.
2. if allocation of usbvision->alt_max_pkt_size fails,
there is no proper deallocation of already acquired resources.

The patch adds kfree(usbvision->alt_max_pkt_size) to
usbvision_release() as soon as other deallocations happen there.
It calls usbvision_release() if allocation of
usbvision->alt_max_pkt_size fails as soon as usbvision_release()
is safe to work with incompletely initialized usbvision structure.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/usb/usbvision/usbvision-video.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/usb/usbvision/usbvision-video.c 
b/drivers/media/usb/usbvision/usbvision-video.c
index d34c2af..443e783 100644
--- a/drivers/media/usb/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -1459,6 +1459,7 @@ static void usbvision_release(struct usb_usbvision 
*usbvision)
 
usbvision_remove_sysfs(usbvision->vdev);
usbvision_unregister_video(usbvision);
+   kfree(usbvision->alt_max_pkt_size);
 
usb_free_urb(usbvision->ctrl_urb);
 
@@ -1574,6 +1575,7 @@ static int usbvision_probe(struct usb_interface *intf,
usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, 
GFP_KERNEL);
if (usbvision->alt_max_pkt_size == NULL) {
dev_err(&intf->dev, "usbvision: out of memory!\n");
+   usbvision_release(usbvision);
return -ENOMEM;
}
 
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] ttusb-budget: fix memory leak in ttusb_probe()

2013-06-10 Thread Alexey Khoroshilov
If something goes wrong starting from i2c_add_adapter(),
ttusb->iso_urb[] and ttusb itself are not deallocated.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c 
b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
index 21b9049..f8a60c1 100644
--- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
@@ -1768,6 +1768,8 @@ err_i2c_del_adapter:
i2c_del_adapter(&ttusb->i2c_adap);
 err_unregister_adapter:
dvb_unregister_adapter (&ttusb->adapter);
+   ttusb_free_iso_urbs(ttusb);
+   kfree(ttusb);
return result;
 }
 
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] staging/media: lirc_imon: fix leaks in imon_probe()

2013-06-02 Thread Alexey Khoroshilov
Error handling of usb_submit_urb() is not as all others in imon_probe().
It just unlocks mutexes and returns nonzero leaving all already
allocated resources unfreed.

The patch makes sure all the resources are deallocated.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/staging/media/lirc/lirc_imon.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/media/lirc/lirc_imon.c 
b/drivers/staging/media/lirc/lirc_imon.c
index 0a2c45d..4afa7da 100644
--- a/drivers/staging/media/lirc/lirc_imon.c
+++ b/drivers/staging/media/lirc/lirc_imon.c
@@ -911,8 +911,8 @@ static int imon_probe(struct usb_interface *interface,
if (retval) {
dev_err(dev, "%s: usb_submit_urb failed for intf0 (%d)\n",
__func__, retval);
-   mutex_unlock(&context->ctx_lock);
-   goto exit;
+   alloc_status = 8;
+   goto unlock;
}
 
usb_set_intfdata(interface, context);
@@ -937,6 +937,8 @@ unlock:
 alloc_status_switch:
 
switch (alloc_status) {
+   case 8:
+   lirc_unregister_driver(driver->minor);
case 7:
usb_free_urb(tx_urb);
case 6:
@@ -959,7 +961,6 @@ alloc_status_switch:
retval = 0;
}
 
-exit:
mutex_unlock(&driver_lock);
 
return retval;
-- 
1.8.1.2
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] wl128x: do not call copy_to_user() while holding spinlocks

2013-05-07 Thread Alexey Khoroshilov
copy_to_user() must not be called with spinlocks held, but it is in
fmc_transfer_rds_from_internal_buff().
The patch copies data to tmpbuf, releases spinlock and then passes it to 
userspace.

By the way there is a small unification: replace a couple of hardcoded 
constants by a macro.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/radio/wl128x/fmdrv_common.c |   24 ++--
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/media/radio/wl128x/fmdrv_common.c 
b/drivers/media/radio/wl128x/fmdrv_common.c
index a002234..253f307 100644
--- a/drivers/media/radio/wl128x/fmdrv_common.c
+++ b/drivers/media/radio/wl128x/fmdrv_common.c
@@ -715,7 +715,7 @@ static void fm_irq_handle_rdsdata_getcmd_resp(struct fmdev 
*fmdev)
struct fm_rdsdata_format rds_fmt;
struct fm_rds *rds = &fmdev->rx.rds;
unsigned long group_idx, flags;
-   u8 *rds_data, meta_data, tmpbuf[3];
+   u8 *rds_data, meta_data, tmpbuf[FM_RDS_BLK_SIZE];
u8 type, blk_idx;
u16 cur_picode;
u32 rds_len;
@@ -1073,6 +1073,7 @@ int fmc_transfer_rds_from_internal_buff(struct fmdev 
*fmdev, struct file *file,
u8 __user *buf, size_t count)
 {
u32 block_count;
+   u8 tmpbuf[FM_RDS_BLK_SIZE];
unsigned long flags;
int ret;
 
@@ -1087,29 +1088,32 @@ int fmc_transfer_rds_from_internal_buff(struct fmdev 
*fmdev, struct file *file,
}
 
/* Calculate block count from byte count */
-   count /= 3;
+   count /= FM_RDS_BLK_SIZE;
block_count = 0;
ret = 0;
 
-   spin_lock_irqsave(&fmdev->rds_buff_lock, flags);
-
while (block_count < count) {
-   if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx)
-   break;
+   spin_lock_irqsave(&fmdev->rds_buff_lock, flags);
 
-   if (copy_to_user(buf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx],
-   FM_RDS_BLK_SIZE))
+   if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx) {
+   spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
break;
-
+   }
+   memcpy(tmpbuf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx],
+   FM_RDS_BLK_SIZE);
fmdev->rx.rds.rd_idx += FM_RDS_BLK_SIZE;
if (fmdev->rx.rds.rd_idx >= fmdev->rx.rds.buf_size)
fmdev->rx.rds.rd_idx = 0;
 
+   spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
+
+   if (copy_to_user(buf, tmpbuf, FM_RDS_BLK_SIZE))
+   break;
+
block_count++;
buf += FM_RDS_BLK_SIZE;
ret += FM_RDS_BLK_SIZE;
}
-   spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
return ret;
 }
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] cx88: Fix unsafe locking in suspend-resume

2013-04-13 Thread Alexey Khoroshilov
Legacy PCI suspend-resume handlers are called with interrupts enabled.
But cx8800_suspend/cx8800_resume and cx8802_suspend_common/cx8802_resume_common
use spin_lock/spin_unlock functions to acquire dev->slock, while the same lock 
is acquired in
the corresponding irq-handlers: cx8800_irq and cx8802_irq.
That means a deadlock is possible if an interrupt happens while suspend or 
resume owns the lock.

The patch replaces spin_lock/spin_unlock with 
spin_lock_irqsave/spin_unlock_irqrestore.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/pci/cx88/cx88-mpeg.c  |   10 ++
 drivers/media/pci/cx88/cx88-video.c |   10 ++
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/media/pci/cx88/cx88-mpeg.c 
b/drivers/media/pci/cx88/cx88-mpeg.c
index c9d3182..c6cdbdb 100644
--- a/drivers/media/pci/cx88/cx88-mpeg.c
+++ b/drivers/media/pci/cx88/cx88-mpeg.c
@@ -532,16 +532,17 @@ static int cx8802_suspend_common(struct pci_dev *pci_dev, 
pm_message_t state)
 {
struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
struct cx88_core *core = dev->core;
+   unsigned long flags;
 
/* stop mpeg dma */
-   spin_lock(&dev->slock);
+   spin_lock_irqsave(&dev->slock,flags);
if (!list_empty(&dev->mpegq.active)) {
dprintk( 2, "suspend\n" );
printk("%s: suspend mpeg\n", core->name);
cx8802_stop_dma(dev);
del_timer(&dev->mpegq.timeout);
}
-   spin_unlock(&dev->slock);
+   spin_unlock_irqrestore(&dev->slock,flags);
 
/* FIXME -- shutdown device */
cx88_shutdown(dev->core);
@@ -558,6 +559,7 @@ static int cx8802_resume_common(struct pci_dev *pci_dev)
 {
struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
struct cx88_core *core = dev->core;
+   unsigned long flags;
int err;
 
if (dev->state.disabled) {
@@ -584,12 +586,12 @@ static int cx8802_resume_common(struct pci_dev *pci_dev)
cx88_reset(dev->core);
 
/* restart video+vbi capture */
-   spin_lock(&dev->slock);
+   spin_lock_irqsave(&dev->slock,flags);
if (!list_empty(&dev->mpegq.active)) {
printk("%s: resume mpeg\n", core->name);
cx8802_restart_queue(dev,&dev->mpegq);
}
-   spin_unlock(&dev->slock);
+   spin_unlock_irqrestore(&dev->slock,flags);
 
return 0;
 }
diff --git a/drivers/media/pci/cx88/cx88-video.c 
b/drivers/media/pci/cx88/cx88-video.c
index bc78354..d72b403 100644
--- a/drivers/media/pci/cx88/cx88-video.c
+++ b/drivers/media/pci/cx88/cx88-video.c
@@ -1957,9 +1957,10 @@ static int cx8800_suspend(struct pci_dev *pci_dev, 
pm_message_t state)
 {
struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
struct cx88_core *core = dev->core;
+   unsigned long flags;
 
/* stop video+vbi capture */
-   spin_lock(&dev->slock);
+   spin_lock_irqsave(&dev->slock,flags);
if (!list_empty(&dev->vidq.active)) {
printk("%s/0: suspend video\n", core->name);
stop_video_dma(dev);
@@ -1970,7 +1971,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, 
pm_message_t state)
cx8800_stop_vbi_dma(dev);
del_timer(&dev->vbiq.timeout);
}
-   spin_unlock(&dev->slock);
+   spin_unlock_irqrestore(&dev->slock,flags);
 
if (core->ir)
cx88_ir_stop(core);
@@ -1989,6 +1990,7 @@ static int cx8800_resume(struct pci_dev *pci_dev)
 {
struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
struct cx88_core *core = dev->core;
+   unsigned long flags;
int err;
 
if (dev->state.disabled) {
@@ -2019,7 +2021,7 @@ static int cx8800_resume(struct pci_dev *pci_dev)
cx_set(MO_PCI_INTMSK, core->pci_irqmask);
 
/* restart video+vbi capture */
-   spin_lock(&dev->slock);
+   spin_lock_irqsave(&dev->slock,flags);
if (!list_empty(&dev->vidq.active)) {
printk("%s/0: resume video\n", core->name);
restart_video_queue(dev,&dev->vidq);
@@ -2028,7 +2030,7 @@ static int cx8800_resume(struct pci_dev *pci_dev)
printk("%s/0: resume vbi\n", core->name);
cx8800_restart_vbi_queue(dev,&dev->vbiq);
}
-   spin_unlock(&dev->slock);
+   spin_unlock_irqrestore(&dev->slock,flags);
 
return 0;
 }
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [media] stv090x: do not unlock unheld mutex in stv090x_sleep()

2013-02-20 Thread Alexey Khoroshilov
On 02/20/2013 10:58 AM, Manu Abraham wrote:
> Hi,
>
> On Wed, Feb 20, 2013 at 12:28 AM, Alexey Khoroshilov
>  wrote:
>> goto err and goto err_gateoff before mutex_lock(&state->internal->demod_lock)
>> lead to unlock of unheld mutex in stv090x_sleep().
> Out of curiosity, what happens when you try to unlock an unlocked mutex ?
>
> Regards,
> Manu
>
Bad things can happen if someone else holds the mutex and it becomes
unexpectedly unlocked.
Also it can result that the next lock() operation leaves the mutex in
unlocked state.
The both cases can lead to data races with unpredictable consequences.

--
Alexey Khoroshilov
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] stv090x: do not unlock unheld mutex in stv090x_sleep()

2013-02-19 Thread Alexey Khoroshilov
goto err and goto err_gateoff before mutex_lock(&state->internal->demod_lock)
lead to unlock of unheld mutex in stv090x_sleep().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/dvb-frontends/stv090x.c |   22 --
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/media/dvb-frontends/stv090x.c 
b/drivers/media/dvb-frontends/stv090x.c
index 13caec0..4f600ac 100644
--- a/drivers/media/dvb-frontends/stv090x.c
+++ b/drivers/media/dvb-frontends/stv090x.c
@@ -3906,12 +3906,12 @@ static int stv090x_sleep(struct dvb_frontend *fe)
reg = stv090x_read_reg(state, STV090x_TSTTNR1);
STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0);
if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
-   goto err;
+   goto err_unlock;
/* power off DiSEqC 1 */
reg = stv090x_read_reg(state, STV090x_TSTTNR2);
STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0);
if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
-   goto err;
+   goto err_unlock;
 
/* check whether path 2 is already sleeping, that is when
   ADC2 is off */
@@ -3930,7 +3930,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
if (full_standby)
STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
-   goto err;
+   goto err_unlock;
reg = stv090x_read_reg(state, STV090x_STOPCLK2);
/* sampling 1 clock */
STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1);
@@ -3941,7 +3941,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
if (full_standby)
STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
-   goto err;
+   goto err_unlock;
break;
 
case STV090x_DEMODULATOR_1:
@@ -3949,12 +3949,12 @@ static int stv090x_sleep(struct dvb_frontend *fe)
reg = stv090x_read_reg(state, STV090x_TSTTNR3);
STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0);
if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
-   goto err;
+   goto err_unlock;
/* power off DiSEqC 2 */
reg = stv090x_read_reg(state, STV090x_TSTTNR4);
STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0);
if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
-   goto err;
+   goto err_unlock;
 
/* check whether path 1 is already sleeping, that is when
   ADC1 is off */
@@ -3973,7 +3973,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
if (full_standby)
STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
-   goto err;
+   goto err_unlock;
reg = stv090x_read_reg(state, STV090x_STOPCLK2);
/* sampling 2 clock */
STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1);
@@ -3984,7 +3984,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
if (full_standby)
STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
-   goto err;
+   goto err_unlock;
break;
 
default:
@@ -3997,7 +3997,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
-   goto err;
+   goto err_unlock;
}
 
mutex_unlock(&state->internal->demod_lock);
@@ -4005,8 +4005,10 @@ static int stv090x_sleep(struct dvb_frontend *fe)
 
 err_gateoff:
stv090x_i2c_gate_ctrl(state, 0);
-err:
+   goto err;
+err_unlock:
mutex_unlock(&state->internal->demod_lock);
+err:
dprintk(FE_ERROR, 1, "I/O error");
return -1;
 }
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] ddbridge: fix error handling in module_init_ddbridge()

2012-08-16 Thread Alexey Khoroshilov
If pci_register_driver() failed, resources allocated in
ddb_class_create() are leaked. The patch fixes it
as well as it replaces -1 with correct error code
in ddb_class_create().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/dvb/ddbridge/ddbridge-core.c |   15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/media/dvb/ddbridge/ddbridge-core.c 
b/drivers/media/dvb/ddbridge/ddbridge-core.c
index ebf3f05..feff57e 100644
--- a/drivers/media/dvb/ddbridge/ddbridge-core.c
+++ b/drivers/media/dvb/ddbridge/ddbridge-core.c
@@ -1497,7 +1497,7 @@ static int ddb_class_create(void)
ddb_class = class_create(THIS_MODULE, DDB_NAME);
if (IS_ERR(ddb_class)) {
unregister_chrdev(ddb_major, DDB_NAME);
-   return -1;
+   return PTR_ERR(ddb_class);
}
ddb_class->devnode = ddb_devnode;
return 0;
@@ -1701,11 +1701,18 @@ static struct pci_driver ddb_pci_driver = {
 
 static __init int module_init_ddbridge(void)
 {
+   int ret;
+
printk(KERN_INFO "Digital Devices PCIE bridge driver, "
   "Copyright (C) 2010-11 Digital Devices GmbH\n");
-   if (ddb_class_create())
-   return -1;
-   return pci_register_driver(&ddb_pci_driver);
+
+   ret = ddb_class_create();
+   if (ret < 0)
+   return ret;
+   ret = pci_register_driver(&ddb_pci_driver);
+   if (ret < 0)
+   ddb_class_destroy();
+   return ret;
 }
 
 static __exit void module_exit_ddbridge(void)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] ddbridge: fix error handling in module_init_ddbridge()

2012-08-15 Thread Alexey Khoroshilov
If pci_register_driver() failed, resources allocated in
ddb_class_create() are leaked. The patch fixes it.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/dvb/ddbridge/ddbridge-core.c |6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb/ddbridge/ddbridge-core.c 
b/drivers/media/dvb/ddbridge/ddbridge-core.c
index ebf3f05..36aa4e4 100644
--- a/drivers/media/dvb/ddbridge/ddbridge-core.c
+++ b/drivers/media/dvb/ddbridge/ddbridge-core.c
@@ -1705,7 +1705,11 @@ static __init int module_init_ddbridge(void)
   "Copyright (C) 2010-11 Digital Devices GmbH\n");
if (ddb_class_create())
return -1;
-   return pci_register_driver(&ddb_pci_driver);
+   if (pci_register_driver(&ddb_pci_driver) < 0) {
+   ddb_class_destroy();
+   return -1;
+   }
+   return 0;
 }
 
 static __exit void module_exit_ddbridge(void)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] drxk: Does not unlock mutex if sanity check failed in scu_command()

2012-04-05 Thread Alexey Khoroshilov
If sanity check fails in scu_command(), goto error leads to unlock of
an unheld mutex. The check should not fail in reality, but it nevertheless
worth fixing.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/dvb/frontends/drxk_hard.c |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/dvb/frontends/drxk_hard.c 
b/drivers/media/dvb/frontends/drxk_hard.c
index 6980ed7..3cce362 100644
--- a/drivers/media/dvb/frontends/drxk_hard.c
+++ b/drivers/media/dvb/frontends/drxk_hard.c
@@ -1525,8 +1525,10 @@ static int scu_command(struct drxk_state *state,
dprintk(1, "\n");
 
if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
-   ((resultLen > 0) && (result == NULL)))
-   goto error;
+   ((resultLen > 0) && (result == NULL))) {
+   printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+   return status;
+   }
 
mutex_lock(&state->mutex);
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] dib9000: get rid of Dib*Lock macros

2012-03-19 Thread Alexey Khoroshilov
The patch replaces Dib*Lock macros with direct calls to mutex functions
as soon as they just make the driver code harder to review
(per request of Mauro).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/dvb/frontends/dib9000.c |  128 +++--
 1 files changed, 58 insertions(+), 70 deletions(-)

diff --git a/drivers/media/dvb/frontends/dib9000.c 
b/drivers/media/dvb/frontends/dib9000.c
index 80848b4..953102f 100644
--- a/drivers/media/dvb/frontends/dib9000.c
+++ b/drivers/media/dvb/frontends/dib9000.c
@@ -31,13 +31,6 @@ struct i2c_device {
u8 *i2c_write_buffer;
 };
 
-/* lock */
-#define DIB_LOCK struct mutex
-#define DibAcquireLock(lock) mutex_lock_interruptible(lock)
-#define DibReleaseLock(lock) mutex_unlock(lock)
-#define DibInitLock(lock) mutex_init(lock)
-#define DibFreeLock(lock)
-
 struct dib9000_pid_ctrl {
 #define DIB9000_PID_FILTER_CTRL 0
 #define DIB9000_PID_FILTER  1
@@ -82,11 +75,11 @@ struct dib9000_state {
} fe_mm[18];
u8 memcmd;
 
-   DIB_LOCK mbx_if_lock;   /* to protect read/write 
operations */
-   DIB_LOCK mbx_lock;  /* to protect the whole mailbox 
handling */
+   struct mutex mbx_if_lock;   /* to protect 
read/write operations */
+   struct mutex mbx_lock;  /* to protect the whole mailbox 
handling */
 
-   DIB_LOCK mem_lock;  /* to protect the memory 
accesses */
-   DIB_LOCK mem_mbx_lock;  /* to protect the memory-based 
mailbox */
+   struct mutex mem_lock;  /* to protect the memory 
accesses */
+   struct mutex mem_mbx_lock;  /* to protect the 
memory-based mailbox */
 
 #define MBX_MAX_WORDS (256 - 200 - 2)
 #define DIB9000_MSG_CACHE_SIZE 2
@@ -108,7 +101,7 @@ struct dib9000_state {
struct i2c_msg msg[2];
u8 i2c_write_buffer[255];
u8 i2c_read_buffer[255];
-   DIB_LOCK demod_lock;
+   struct mutex demod_lock;
u8 get_frontend_internal;
struct dib9000_pid_ctrl pid_ctrl[10];
s8 pid_ctrl_index; /* -1: empty list; -2: do not use the list */
@@ -446,13 +439,13 @@ static int dib9000_risc_mem_read(struct dib9000_state 
*state, u8 cmd, u8 * b, u1
if (!state->platform.risc.fw_is_running)
return -EIO;
 
-   if (DibAcquireLock(&state->platform.risc.mem_lock) < 0) {
+   if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) {
dprintk("could not get the lock");
return -EINTR;
}
dib9000_risc_mem_setup(state, cmd | 0x80);
dib9000_risc_mem_read_chunks(state, b, len);
-   DibReleaseLock(&state->platform.risc.mem_lock);
+   mutex_unlock(&state->platform.risc.mem_lock);
return 0;
 }
 
@@ -462,13 +455,13 @@ static int dib9000_risc_mem_write(struct dib9000_state 
*state, u8 cmd, const u8
if (!state->platform.risc.fw_is_running)
return -EIO;
 
-   if (DibAcquireLock(&state->platform.risc.mem_lock) < 0) {
+   if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) {
dprintk("could not get the lock");
return -EINTR;
}
dib9000_risc_mem_setup(state, cmd);
dib9000_risc_mem_write_chunks(state, b, m->size);
-   DibReleaseLock(&state->platform.risc.mem_lock);
+   mutex_unlock(&state->platform.risc.mem_lock);
return 0;
 }
 
@@ -537,7 +530,7 @@ static int dib9000_mbx_send_attr(struct dib9000_state 
*state, u8 id, u16 * data,
if (!state->platform.risc.fw_is_running)
return -EINVAL;
 
-   if (DibAcquireLock(&state->platform.risc.mbx_if_lock) < 0) {
+   if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) {
dprintk("could not get the lock");
return -EINTR;
}
@@ -584,7 +577,7 @@ static int dib9000_mbx_send_attr(struct dib9000_state 
*state, u8 id, u16 * data,
ret = (u8) dib9000_write_word_attr(state, 1043, 1 << 14, attr);
 
 out:
-   DibReleaseLock(&state->platform.risc.mbx_if_lock);
+   mutex_unlock(&state->platform.risc.mbx_if_lock);
 
return ret;
 }
@@ -602,7 +595,7 @@ static u8 dib9000_mbx_read(struct dib9000_state *state, u16 
* data, u8 risc_id,
if (!state->platform.risc.fw_is_running)
return 0;
 
-   if (DibAcquireLock(&state->platform.risc.mbx_if_lock) < 0) {
+   if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) {
dprintk("could not get the lock");
return 0;
}
@@ -643,7 +636,7 @@ static u8 dib9000_mbx_read(struct dib9000_state *state, u16 
* data, u8 risc_id,
/* Update r

Re: [PATCH] [media] dib0700: unlock mutexes on error paths

2012-03-19 Thread Alexey Khoroshilov
On Mon, 19 Mar 2012 14:47:54 -0300, Mauro Carvalho Chehab 
 wrote:

Em 07-03-2012 16:21, Alexey Khoroshilov escreveu:
dib0700_i2c_xfer [_new and _legacy] leave i2c_mutex locked on error 
paths.

The patch adds appropriate unlocks.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/dvb/dvb-usb/dib0700_core.c |9 ++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c 
b/drivers/media/dvb/dvb-usb/dib0700_core.c

index 070e82a..8ec22c4 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -228,7 +228,7 @@ static int dib0700_i2c_xfer_new(struct 
i2c_adapter *adap, struct i2c_msg *msg,

/* Write request */
if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
err("could not acquire lock");
-   return 0;
+   break;


A break here doesn't sound the right thing to do.



I am sorry, but I did not catch the issue.
The break is almost equivalent to another one a few lines below that 
happens when usb_control_msg() fails.


Could you please clarify the problem?

--
Alexey


--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] dib0700: unlock mutexes on error paths

2012-03-07 Thread Alexey Khoroshilov
dib0700_i2c_xfer [_new and _legacy] leave i2c_mutex locked on error paths.
The patch adds appropriate unlocks.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/dvb/dvb-usb/dib0700_core.c |9 ++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c 
b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 070e82a..8ec22c4 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -228,7 +228,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, 
struct i2c_msg *msg,
/* Write request */
if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
err("could not acquire lock");
-   return 0;
+   break;
}
st->buf[0] = REQUEST_NEW_I2C_WRITE;
st->buf[1] = msg[i].addr << 1;
@@ -270,11 +270,14 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter 
*adap,
struct dib0700_state *st = d->priv;
int i,len;
 
-   if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+   if (mutex_lock_interruptible(&d->i2c_mutex) < 0) {
+   err("could not acquire lock");
return -EAGAIN;
+   }
if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
+   mutex_unlock(&d->i2c_mutex);
err("could not acquire lock");
-   return 0;
+   return -EAGAIN;
}
 
for (i = 0; i < num; i++) {
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] [media] dib9000: implement error handling for DibAcquireLock

2012-03-06 Thread Alexey Khoroshilov
DibAcquireLock() is implemented as mutex_lock_interruptible() 
but the driver does not handle unsuccessful locking.
As a result it may lead to unlock of an unheld mutex.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/dvb/frontends/dib9000.c |  115 ++---
 1 files changed, 91 insertions(+), 24 deletions(-)

diff --git a/drivers/media/dvb/frontends/dib9000.c 
b/drivers/media/dvb/frontends/dib9000.c
index d96b6a1..80848b4 100644
--- a/drivers/media/dvb/frontends/dib9000.c
+++ b/drivers/media/dvb/frontends/dib9000.c
@@ -33,7 +33,7 @@ struct i2c_device {
 
 /* lock */
 #define DIB_LOCK struct mutex
-#define DibAcquireLock(lock) do { if (mutex_lock_interruptible(lock) < 0) 
dprintk("could not get the lock"); } while (0)
+#define DibAcquireLock(lock) mutex_lock_interruptible(lock)
 #define DibReleaseLock(lock) mutex_unlock(lock)
 #define DibInitLock(lock) mutex_init(lock)
 #define DibFreeLock(lock)
@@ -446,7 +446,10 @@ static int dib9000_risc_mem_read(struct dib9000_state 
*state, u8 cmd, u8 * b, u1
if (!state->platform.risc.fw_is_running)
return -EIO;
 
-   DibAcquireLock(&state->platform.risc.mem_lock);
+   if (DibAcquireLock(&state->platform.risc.mem_lock) < 0) {
+   dprintk("could not get the lock");
+   return -EINTR;
+   }
dib9000_risc_mem_setup(state, cmd | 0x80);
dib9000_risc_mem_read_chunks(state, b, len);
DibReleaseLock(&state->platform.risc.mem_lock);
@@ -459,7 +462,10 @@ static int dib9000_risc_mem_write(struct dib9000_state 
*state, u8 cmd, const u8
if (!state->platform.risc.fw_is_running)
return -EIO;
 
-   DibAcquireLock(&state->platform.risc.mem_lock);
+   if (DibAcquireLock(&state->platform.risc.mem_lock) < 0) {
+   dprintk("could not get the lock");
+   return -EINTR;
+   }
dib9000_risc_mem_setup(state, cmd);
dib9000_risc_mem_write_chunks(state, b, m->size);
DibReleaseLock(&state->platform.risc.mem_lock);
@@ -531,7 +537,10 @@ static int dib9000_mbx_send_attr(struct dib9000_state 
*state, u8 id, u16 * data,
if (!state->platform.risc.fw_is_running)
return -EINVAL;
 
-   DibAcquireLock(&state->platform.risc.mbx_if_lock);
+   if (DibAcquireLock(&state->platform.risc.mbx_if_lock) < 0) {
+   dprintk("could not get the lock");
+   return -EINTR;
+   }
tmp = MAX_MAILBOX_TRY;
do {
size = dib9000_read_word_attr(state, 1043, attr) & 0xff;
@@ -593,7 +602,10 @@ static u8 dib9000_mbx_read(struct dib9000_state *state, 
u16 * data, u8 risc_id,
if (!state->platform.risc.fw_is_running)
return 0;
 
-   DibAcquireLock(&state->platform.risc.mbx_if_lock);
+   if (DibAcquireLock(&state->platform.risc.mbx_if_lock) < 0) {
+   dprintk("could not get the lock");
+   return 0;
+   }
if (risc_id == 1)
mc_base = 16;
else
@@ -701,7 +713,10 @@ static int dib9000_mbx_process(struct dib9000_state 
*state, u16 attr)
if (!state->platform.risc.fw_is_running)
return -1;
 
-   DibAcquireLock(&state->platform.risc.mbx_lock);
+   if (DibAcquireLock(&state->platform.risc.mbx_lock) < 0) {
+   dprintk("could not get the lock");
+   return -1;
+   }
 
if (dib9000_mbx_count(state, 1, attr))  /* 1=RiscB */
ret = dib9000_mbx_fetch_to_cache(state, attr);
@@ -1178,7 +1193,10 @@ static int dib9000_fw_get_channel(struct dvb_frontend 
*fe)
struct dibDVBTChannel *ch;
int ret = 0;
 
-   DibAcquireLock(&state->platform.risc.mem_mbx_lock);
+   if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) {
+   dprintk("could not get the lock");
+   return -EINTR;
+   }
if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
ret = -EIO;
goto error;
@@ -1660,7 +1678,10 @@ static int dib9000_fw_component_bus_xfer(struct 
i2c_adapter *i2c_adap, struct i2
p[12] = 0;
}
 
-   DibAcquireLock(&state->platform.risc.mem_mbx_lock);
+   if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) {
+   dprintk("could not get the lock");
+   return 0;
+   }
 
dib9000_risc_mem_write(state, FE_MM_W_COMPONENT_ACCESS, p);
 
@@ -1768,7 +1789,10 @@ int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, 
u8 onoff)
return 0;
}
 
-   DibAcquireLock(&state->demod_lock);
+   if (DibAcquireLock(&state->demod_

[PATCH 1/2] [media] dib9000: fix explicit lock mismatches

2012-03-06 Thread Alexey Khoroshilov
There are several error paths, where &state->platform.risc.mem_mbx_lock
is not unlocked. The patch fixes it.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/dvb/frontends/dib9000.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/media/dvb/frontends/dib9000.c 
b/drivers/media/dvb/frontends/dib9000.c
index 863ef3c..d96b6a1 100644
--- a/drivers/media/dvb/frontends/dib9000.c
+++ b/drivers/media/dvb/frontends/dib9000.c
@@ -2208,6 +2208,7 @@ static int dib9000_read_signal_strength(struct 
dvb_frontend *fe, u16 * strength)
 
DibAcquireLock(&state->platform.risc.mem_mbx_lock);
if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
+   DibReleaseLock(&state->platform.risc.mem_mbx_lock);
ret = -EIO;
goto error;
}
@@ -2233,8 +2234,10 @@ static u32 dib9000_get_snr(struct dvb_frontend *fe)
u16 val;
 
DibAcquireLock(&state->platform.risc.mem_mbx_lock);
-   if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
+   if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
+   DibReleaseLock(&state->platform.risc.mem_mbx_lock);
return -EIO;
+   }
dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
DibReleaseLock(&state->platform.risc.mem_mbx_lock);
 
@@ -2291,6 +2294,7 @@ static int dib9000_read_unc_blocks(struct dvb_frontend 
*fe, u32 * unc)
DibAcquireLock(&state->demod_lock);
DibAcquireLock(&state->platform.risc.mem_mbx_lock);
if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
+   DibReleaseLock(&state->platform.risc.mem_mbx_lock);
ret = -EIO;
goto error;
}
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] staging: go7007: fix mismatch in mutex lock-unlock in [read|write]_reg_fp

2012-02-13 Thread Alexey Khoroshilov
If go7007_usb_vendor_request() fails in write_reg_fp()
or in read_reg_fp(), the usb->i2c_lock mutex left locked.

The patch moves mutex_unlock(&usb->i2c_lock) before check
for go7007_usb_vendor_request() returned value.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/staging/media/go7007/s2250-board.c |   16 ++--
 1 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/media/go7007/s2250-board.c 
b/drivers/staging/media/go7007/s2250-board.c
index e7736a9..014d384 100644
--- a/drivers/staging/media/go7007/s2250-board.c
+++ b/drivers/staging/media/go7007/s2250-board.c
@@ -192,6 +192,7 @@ static int write_reg_fp(struct i2c_client *client, u16 
addr, u16 val)
 {
struct go7007 *go = i2c_get_adapdata(client->adapter);
struct go7007_usb *usb;
+   int rc;
u8 *buf;
struct s2250 *dec = i2c_get_clientdata(client);
 
@@ -216,12 +217,13 @@ static int write_reg_fp(struct i2c_client *client, u16 
addr, u16 val)
kfree(buf);
return -EINTR;
}
-   if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0) {
+   rc = go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1);
+   mutex_unlock(&usb->i2c_lock);
+   if (rc < 0) {
kfree(buf);
-   return -EFAULT;
+   return rc;
}
 
-   mutex_unlock(&usb->i2c_lock);
if (buf[0] == 0) {
unsigned int subaddr, val_read;
 
@@ -254,6 +256,7 @@ static int read_reg_fp(struct i2c_client *client, u16 addr, 
u16 *val)
 {
struct go7007 *go = i2c_get_adapdata(client->adapter);
struct go7007_usb *usb;
+   int rc;
u8 *buf;
 
if (go == NULL)
@@ -276,11 +279,12 @@ static int read_reg_fp(struct i2c_client *client, u16 
addr, u16 *val)
kfree(buf);
return -EINTR;
}
-   if (go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1) < 0) {
+   rc = go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1);
+   mutex_unlock(&usb->i2c_lock);
+   if (rc < 0) {
kfree(buf);
-   return -EFAULT;
+   return rc;
}
-   mutex_unlock(&usb->i2c_lock);
 
*val = (buf[0] << 8) | buf[1];
kfree(buf);
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] hdpvr: fix null pointer dereference on error path in hdpvr_probe()

2011-09-16 Thread Alexey Khoroshilov
dev->free_buff_list and dev->rec_buff_list are zero initialized after
kzalloc of dev. If something goes wrong before INIT_LIST_HEAD for them,
goto error leads to call hdpvr_delete() and then to hdpvr_free_buffers(),
where the lists are dereferenced.

The patch moves INIT_LIST_HEAD before the first possible fail.

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/video/hdpvr/hdpvr-core.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/media/video/hdpvr/hdpvr-core.c 
b/drivers/media/video/hdpvr/hdpvr-core.c
index 441dacf..fe0a088 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -295,6 +295,10 @@ static int hdpvr_probe(struct usb_interface *interface,
goto error;
}
 
+   /* init video transfer queues */
+   INIT_LIST_HEAD(&dev->free_buff_list);
+   INIT_LIST_HEAD(&dev->rec_buff_list);
+
dev->workqueue = 0;
 
/* register v4l2_device early so it can be used for printks */
@@ -319,10 +323,6 @@ static int hdpvr_probe(struct usb_interface *interface,
if (!dev->workqueue)
goto error;
 
-   /* init video transfer queues */
-   INIT_LIST_HEAD(&dev->free_buff_list);
-   INIT_LIST_HEAD(&dev->rec_buff_list);
-
dev->options = hdpvr_default_options;
 
if (default_video_input < HDPVR_VIDEO_INPUTS)
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] V4L/DVB: radio-si470x: fix memory leak in si470x_usb_driver_probe()

2011-05-31 Thread Alexey Khoroshilov
radio->int_in_urb is not deallocated on error paths in 
si470x_usb_driver_probe().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/radio/si470x/radio-si470x-usb.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c 
b/drivers/media/radio/si470x/radio-si470x-usb.c
index 392e84f..ccefdae 100644
--- a/drivers/media/radio/si470x/radio-si470x-usb.c
+++ b/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -699,7 +699,7 @@ static int si470x_usb_driver_probe(struct usb_interface 
*intf,
radio->videodev = video_device_alloc();
if (!radio->videodev) {
retval = -ENOMEM;
-   goto err_intbuffer;
+   goto err_urb;
}
memcpy(radio->videodev, &si470x_viddev_template,
sizeof(si470x_viddev_template));
@@ -790,6 +790,8 @@ err_all:
kfree(radio->buffer);
 err_video:
video_device_release(radio->videodev);
+err_urb:
+   usb_free_urb(radio->int_in_urb);
 err_intbuffer:
kfree(radio->int_in_buffer);
 err_radio:
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] lmedm04: Do not unlock mutex if mutex_lock_interruptible failed

2011-04-15 Thread Alexey Khoroshilov
There are a couple of places where mutex_unlock() is called even 
if mutex_lock_interruptible() failed. The patch fixes the issue.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/dvb/dvb-usb/lmedm04.c |   12 +++-
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c 
b/drivers/media/dvb/dvb-usb/lmedm04.c
index f2db012..40907df 100644
--- a/drivers/media/dvb/dvb-usb/lmedm04.c
+++ b/drivers/media/dvb/dvb-usb/lmedm04.c
@@ -591,9 +591,10 @@ static int lme2510_streaming_ctrl(struct dvb_usb_adapter 
*adap, int onoff)
else {
deb_info(1, "STM Steam Off");
/* mutex is here only to avoid collision with I2C */
-   ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
+   if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
+   return -EAGAIN;
 
-   ret |= lme2510_usb_talk(adap->dev, clear_reg_3,
+   ret = lme2510_usb_talk(adap->dev, clear_reg_3,
sizeof(clear_reg_3), rbuf, rlen);
st->stream_on = 0;
st->i2c_talk_onoff = 1;
@@ -1017,12 +1018,13 @@ static int lme2510_powerup(struct dvb_usb_device *d, 
int onoff)
static u8 rbuf[1];
int ret, len = 3, rlen = 1;
 
-   ret = mutex_lock_interruptible(&d->i2c_mutex);
+   if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+   return -EAGAIN;
 
if (onoff)
-   ret |= lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
+   ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
else
-   ret |= lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
+   ret = lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
 
st->i2c_talk_onoff = 1;
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html