From: Grant Grundler <grundler@chromium.org>
To: Jonathan Cameron <jic23@cam.ac.uk>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Benson Leung <bleung@chromium.org>,
Bryan Freed <bfreed@chromium.org>,
linux-iio@vger.kernel.org, devel@driverdev.osuosl.org,
linux-kernel@vger.kernel.org,
Grant Grundler <grundler@chromium.org>
Subject: [PATCH] staging:iio:tsl2563 rewrite probe error handling
Date: Mon, 5 Mar 2012 09:15:59 -0800 [thread overview]
Message-ID: <1330967759-18660-1-git-send-email-grundler@chromium.org> (raw)
tsl2563 probe function has two minor issues with it's error handling paths:
1) it is silent (did not report errors to dmesg)
2) did not return failure code (mixed up use of ret and err)
and two major issues:
3) goto fail2 would corrupt a free memory pool ("double free")
4) device registration failure did NOT cancel/flush delayed work.
(and thus dereference a freed data structure later)
The "double free" is subtle and was introduced with this change:
Author: Jonathan Cameron <jic23@cam.ac.uk>
Date: Mon Apr 18 12:58:55 2011 +0100
staging:iio:tsl2563 take advantage of new iio_device_allocate private data.
Originally, chip was allocated seperately. Now it's appended to the
indio_dev by iio_allocate_device(sizeof(*chip)). So we only need one
kfree call as well (in iio_free_device()).
Signed-off-by: Grant Grundler <grundler@chromium.org>
---
Gory details of tracking this down are here:
http://crosbug.com/26819
Despite iio_device_registration failing, system can at least now boot.
Will follow up with a fix to "double register : in_intensity_both_raw"
error that is included in the bug report.
drivers/staging/iio/light/tsl2563.c | 39 +++++++++++++++++++++++-----------
1 files changed, 26 insertions(+), 13 deletions(-)
diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c
index 7e984bc..bf6498b 100644
--- a/drivers/staging/iio/light/tsl2563.c
+++ b/drivers/staging/iio/light/tsl2563.c
@@ -705,7 +705,6 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
struct tsl2563_chip *chip;
struct tsl2563_platform_data *pdata = client->dev.platform_data;
int err = 0;
- int ret;
u8 id = 0;
indio_dev = iio_allocate_device(sizeof(*chip));
@@ -719,13 +718,15 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
err = tsl2563_detect(chip);
if (err) {
- dev_err(&client->dev, "device not found, error %d\n", -err);
+ dev_err(&client->dev, "detect error %d\n", -err);
goto fail1;
}
err = tsl2563_read_id(chip, &id);
- if (err)
+ if (err) {
+ dev_err(&client->dev, "read id error %d\n", -err);
goto fail1;
+ }
mutex_init(&chip->lock);
@@ -748,40 +749,52 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
indio_dev->num_channels = ARRAY_SIZE(tsl2563_channels);
indio_dev->dev.parent = &client->dev;
indio_dev->modes = INDIO_DIRECT_MODE;
+
if (client->irq)
indio_dev->info = &tsl2563_info;
else
indio_dev->info = &tsl2563_info_no_irq;
+
if (client->irq) {
- ret = request_threaded_irq(client->irq,
+ err = request_threaded_irq(client->irq,
NULL,
&tsl2563_event_handler,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"tsl2563_event",
indio_dev);
- if (ret)
- goto fail2;
+ if (err) {
+ dev_err(&client->dev, "irq request error %d\n", -err);
+ goto fail1;
+ }
}
+
err = tsl2563_configure(chip);
- if (err)
- goto fail3;
+ if (err) {
+ dev_err(&client->dev, "configure error %d\n", -err);
+ goto fail2;
+ }
INIT_DELAYED_WORK(&chip->poweroff_work, tsl2563_poweroff_work);
+
/* The interrupt cannot yet be enabled so this is fine without lock */
schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
- ret = iio_device_register(indio_dev);
- if (ret)
+ err = iio_device_register(indio_dev);
+ if (err) {
+ dev_err(&client->dev, "iio registration error %d\n", -err);
goto fail3;
+ }
return 0;
+
fail3:
+ cancel_delayed_work(&chip->poweroff_work);
+ flush_scheduled_work();
+fail2:
if (client->irq)
free_irq(client->irq, indio_dev);
-fail2:
- iio_free_device(indio_dev);
fail1:
- kfree(chip);
+ iio_free_device(indio_dev);
return err;
}
--
1.7.3.4
next reply other threads:[~2012-03-05 17:16 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-05 17:15 Grant Grundler [this message]
2012-03-05 21:27 ` [PATCH] staging:iio:tsl2563 rewrite probe error handling Benson Leung
2012-03-05 22:12 ` Grant Grundler
2012-03-05 21:28 ` Benson Leung
2012-03-05 21:53 ` Bryan Freed
2012-03-05 22:12 ` Grant Grundler
2012-03-05 21:55 ` Bryan Freed
2012-03-07 11:28 ` Jonathan Cameron
2012-03-09 3:51 ` Grant Grundler
2012-03-09 6:23 ` Dan Carpenter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1330967759-18660-1-git-send-email-grundler@chromium.org \
--to=grundler@chromium.org \
--cc=bfreed@chromium.org \
--cc=bleung@chromium.org \
--cc=devel@driverdev.osuosl.org \
--cc=gregkh@linuxfoundation.org \
--cc=jic23@cam.ac.uk \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).