public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Stephen Warren <swarren@wwwdotorg.org>
To: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] regmap: core: Split out in place value parsing
Date: Wed, 20 Mar 2013 16:19:22 -0600	[thread overview]
Message-ID: <514A35EA.2090001@wwwdotorg.org> (raw)
In-Reply-To: <20130319165007.GA22168@opensource.wolfsonmicro.com>

On 03/19/2013 10:50 AM, Mark Brown wrote:
> On Mon, Mar 18, 2013 at 05:41:49PM -0600, Stephen Warren wrote:
> 
>> It took a very quick look at the patch and couldn't see anything 
>> actively wrong. I wonder if one of the existing unconverted users
>> of .parse_val() relies on the in-place modification of the buffer
>> as well as getting the result back, and so should have been
>> converted to calling both .parse_inplace() and then
>> .parse_val()?
> 
> Possibly, though you'd have thought that if it were just that one
> of the other users would have noticed - my primary development
> board uses regmap extensively for example.  Does seem the most
> likely option though.  Can't test anything again until Friday
> sadly.
> 
> Might also be some unusual code path WM8903 exercises, though again
> it's pretty simple.

I haven't thought through why the patch in question causes/exposes the
issue yet, but I have found out what the problem is.

_regmap_bus_raw_write() formats the value into work_buf + reg_bytes +
pad_bytes, i.e. work_buf + 1.

For the first regmap_write() that the WM8903 driver does, work_buf is
now xx 89 03.

_regmap_raw_write() then memcpy()s from val (i.e. work_buf + 1) to
workbuf, and parses the value to send to the caching code:

> if (!map->cache_bypass && map->format.parse_val) { unsigned int
> ival; int val_bytes = map->format.val_bytes; for (i = 0; i <
> val_len / val_bytes; i++) { memcpy(map->work_buf, val + (i *
> val_bytes), val_bytes); ival =
> map->format.parse_val(map->work_buf);

This corrupts that value at work_buf + 1 since it overlaps the copy
destination at work_buf. work_buf is now 89 03 03.

_regmap_raw_write() then formats the register address into work_buf,
yielding 00 03 03.

That data stream is then sent over I2C, causing a write to register 0
(correct) of value 03 03 (rather than 89 03).

If I comment out the memcpy, and instead pass the value address
directly to .parse_val(), everything works again.

  parent reply	other threads:[~2013-03-20 22:19 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-04  1:14 [PATCH 1/2] regmap: core: Split out in place value parsing Mark Brown
2013-03-04  1:14 ` [PATCH 2/2] regmap: cache: Store caches in native register format where possible Mark Brown
2013-03-18 23:41 ` [PATCH 1/2] regmap: core: Split out in place value parsing Stephen Warren
     [not found]   ` <20130319165007.GA22168@opensource.wolfsonmicro.com>
2013-03-20 22:19     ` Stephen Warren [this message]
2013-03-20 22:33       ` Stephen Warren

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=514A35EA.2090001@wwwdotorg.org \
    --to=swarren@wwwdotorg.org \
    --cc=broonie@opensource.wolfsonmicro.com \
    --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