From: Gerlando Falauto <gerlando.falauto@keymile.com>
To: Austin Boyle <Austin.Boyle@aviatnet.com>
Cc: David Woodhouse <dwmw2@infradead.org>,
linux-mtd@lists.infradead.org,
Artem Bityutskiy <artem.bityutskiy@linux.intel.com>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] mtd: m25p80: Flash protection support for STmicro chips
Date: Thu, 27 Feb 2014 15:34:06 +0100 [thread overview]
Message-ID: <530F4CDE.7010205@keymile.com> (raw)
In-Reply-To: <528D15B6.2030800@keymile.com>
Hi,
it's me again.
In my opinion (and experience) this introduces a pretty serious bug (not
to mention the compatibility issues), yet I haven't heard a single word
or found a patch applied about it in three months.
Am I the only one having this issue? Or maybe I'm just "seeing things"?
Thank you,
Gerlando
P.S. FWIW, the original author of the patch seem to have disappeared.
On 11/20/2013 09:04 PM, Gerlando Falauto wrote:
> Hi,
>
> On 01/04/2013 01:02 AM, Austin Boyle wrote:
>> This patch adds generic support for flash protection on STmicro chips.
>> On chips with less than 3 protection bits, the unused bits are don't
>> cares
>> and so can be written anyway.
>
> I have two remarks:
>
> 1) I believe this introduces incompatibilities with existing bootloaders
> which do not support this feature.
> Namely, u-boot is not able (to the best of my knowledge) to treat these
> bits properly. So as soon as you write something to your SPI nor flash
> from within linux, u-boot is not able to erase/rewrite those blocks
> anymore.
>
> Wouldn't it make more sense to selectively enable this feature, only if
> explicity configured to do so (e.g. through its device tree node)?
> Like what was used for the Spansion's PPB, see:
>
> http://lists.infradead.org/pipermail/linux-mtd/2013-January/045536.html
>
> > The lock function will only change the
>> protection bits if it would not unlock other areas. Similarly, the unlock
>> function will not lock currently unlocked areas. Tested on the m25p64.
> >
>> From: Austin Boyle <Austin.Boyle@aviatnet.com>
>> Signed-off-by: Austin Boyle <Austin.Boyle@aviatnet.com>
>> ---
>> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
>> index 4eeeb2d..069e34f 100644
>> --- a/drivers/mtd/devices/m25p80.c
>> +++ b/drivers/mtd/devices/m25p80.c
>> @@ -565,6 +565,96 @@ time_out:
>> return ret;
>> }
>>
>> +static int m25p80_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>> +{
>> + struct m25p *flash = mtd_to_m25p(mtd);
>> + uint32_t offset = ofs;
>> + uint8_t status_old, status_new;
>> + int res = 0;
>> +
>> + mutex_lock(&flash->lock);
>> + /* Wait until finished previous command */
>> + if (wait_till_ready(flash)) {
>> + res = 1;
>> + goto err;
>> + }
>> +
>> + status_old = read_sr(flash);
>> +
>> + if (offset < flash->mtd.size-(flash->mtd.size/2))
>> + status_new = status_old | SR_BP2 | SR_BP1 | SR_BP0;
>> + else if (offset < flash->mtd.size-(flash->mtd.size/4))
>> + status_new = (status_old & ~SR_BP0) | SR_BP2 | SR_BP1;
>> + else if (offset < flash->mtd.size-(flash->mtd.size/8))
>> + status_new = (status_old & ~SR_BP1) | SR_BP2 | SR_BP0;
>> + else if (offset < flash->mtd.size-(flash->mtd.size/16))
>> + status_new = (status_old & ~(SR_BP0|SR_BP1)) | SR_BP2;
>> + else if (offset < flash->mtd.size-(flash->mtd.size/32))
>> + status_new = (status_old & ~SR_BP2) | SR_BP1 | SR_BP0;
>> + else if (offset < flash->mtd.size-(flash->mtd.size/64))
>> + status_new = (status_old & ~(SR_BP2|SR_BP0)) | SR_BP1;
>> + else
>> + status_new = (status_old & ~(SR_BP2|SR_BP1)) | SR_BP0;
>
> 2) While I believe this might work on m25p32, m25p64 and m25p128 (i.e.
> flashes with 64 blocks or more), it looks incorrect for smaller chips
> (namely our m25p80, with just 16 blocks). There, the 1/64 logic scales
> down to 1/16, e.g.
> - 000 means protect nothing
> - 001 means protect 1/16th (=1 blocks) [m25p64 => 1/64th]
> - 010 means protect 1/8th (=2 blocks) [m25p64 => 1/32th]
> - ...
> - 100 means protect 1/2nd (=8 blocks)
> - 101,110, 111 mean protect everything
>
> and I assume the same goes for chips with fewer sectors.
>
> Any comments?
>
> Thanks,
> Gerlando
>
>> +
>> + /* Only modify protection if it will not unlock other areas */
>> + if ((status_new&(SR_BP2|SR_BP1|SR_BP0)) >
>> + (status_old&(SR_BP2|SR_BP1|SR_BP0))) {
>> + write_enable(flash);
>> + if (write_sr(flash, status_new) < 0) {
>> + res = 1;
>> + goto err;
>> + }
>> + }
>> +
>> +err: mutex_unlock(&flash->lock);
>> + return res;
>> +}
>> +
>> +static int m25p80_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>> +{
>> + struct m25p *flash = mtd_to_m25p(mtd);
>> + uint32_t offset = ofs;
>> + uint8_t status_old, status_new;
>> + int res = 0;
>> +
>> + mutex_lock(&flash->lock);
>> + /* Wait until finished previous command */
>> + if (wait_till_ready(flash)) {
>> + res = 1;
>> + goto err;
>> + }
>> +
>> + status_old = read_sr(flash);
>> +
>> + if (offset+len > flash->mtd.size-(flash->mtd.size/64))
>> + status_new = status_old & ~(SR_BP2|SR_BP1|SR_BP0);
>> + else if (offset+len > flash->mtd.size-(flash->mtd.size/32))
>> + status_new = (status_old & ~(SR_BP2|SR_BP1)) | SR_BP0;
>> + else if (offset+len > flash->mtd.size-(flash->mtd.size/16))
>> + status_new = (status_old & ~(SR_BP2|SR_BP0)) | SR_BP1;
>> + else if (offset+len > flash->mtd.size-(flash->mtd.size/8))
>> + status_new = (status_old & ~SR_BP2) | SR_BP1 | SR_BP0;
>> + else if (offset+len > flash->mtd.size-(flash->mtd.size/4))
>> + status_new = (status_old & ~(SR_BP0|SR_BP1)) | SR_BP2;
>> + else if (offset+len > flash->mtd.size-(flash->mtd.size/2))
>> + status_new = (status_old & ~SR_BP1) | SR_BP2 | SR_BP0;
>> + else
>> + status_new = (status_old & ~SR_BP0) | SR_BP2 | SR_BP1;
>> +
>> + /* Only modify protection if it will not lock other areas */
>> + if ((status_new&(SR_BP2|SR_BP1|SR_BP0)) <
>> + (status_old&(SR_BP2|SR_BP1|SR_BP0))) {
>> + write_enable(flash);
>> + if (write_sr(flash, status_new) < 0) {
>> + res = 1;
>> + goto err;
>> + }
>> + }
>> +
>> +err: mutex_unlock(&flash->lock);
>> + return res;
>> +}
>> +
>>
>> /****************************************************************************/
>>
>>
>> /*
>> @@ -899,6 +989,12 @@ static int m25p_probe(struct spi_device *spi)
>> flash->mtd._erase = m25p80_erase;
>> flash->mtd._read = m25p80_read;
>>
>> + /* flash protection support for STmicro chips */
>> + if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ST) {
>> + flash->mtd._lock = m25p80_lock;
>> + flash->mtd._unlock = m25p80_unlock;
>> + }
>> +
>> /* sst flash chips use AAI word program */
>> if (JEDEC_MFR(info->jedec_id) == CFI_MFR_SST)
>> flash->mtd._write = sst_write;
>>
>>
>> ______________________________________________________
>> Linux MTD discussion mailing list
>> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>>
>
>
next prev parent reply other threads:[~2014-02-27 14:34 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-04 0:02 [PATCH] mtd: m25p80: Flash protection support for STmicro chips Austin Boyle
2013-01-17 10:41 ` Artem Bityutskiy
2013-11-20 20:04 ` Gerlando Falauto
2014-02-27 14:34 ` Gerlando Falauto [this message]
2014-03-05 8:10 ` Brian Norris
2014-03-05 8:31 ` Brian Norris
2014-03-08 15:26 ` Austin Boyle
[not found] ` <CADnxWiqfaaRoaL+B_WQxx38-gpSDmdFQPLN-bs-moGRECXeJxg@mail.gmail.com>
2014-03-10 9:06 ` Gerlando Falauto
2014-03-13 12:57 ` Austin Boyle
2014-03-13 13:46 ` Gerlando Falauto
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=530F4CDE.7010205@keymile.com \
--to=gerlando.falauto@keymile.com \
--cc=Austin.Boyle@aviatnet.com \
--cc=artem.bityutskiy@linux.intel.com \
--cc=dwmw2@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.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