mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-27 16:01:27 +00:00
fw_setenv: lock the flash only if it was locked before
With current implementation of fw_setenv, it is always locks u-boot-env region if lock interface is implemented for such mtd device. You can not control lock of this region with fw_setenv, there is no option for it in config or in application itself. Because of this situation may happen problems like in this thread on xilinx forum: https://forums.xilinx.com/t5/Embedded-Linux/Flash-be-locked-after-use-fw-setenv-from-user-space /td-p/1027851 A short summary of that link is: some person has issue with some spi chip which has lock interface but doesn't locks properly which leads to lock of whole flash memory on lock of u-boot-env region. As resulted solution hack was added into spi-nor.c driver for this chip with lock disablement. Instead fix this problem by adding logic to fw_setenv only lock the flash if it was already locked when we attempted to use it. Signed-off-by: Ivan Mikhaylov <fr0st61te@gmail.com>
This commit is contained in:
parent
d045cbacf2
commit
db82015929
1 changed files with 19 additions and 5 deletions
16
tools/env/fw_env.c
vendored
16
tools/env/fw_env.c
vendored
|
@ -995,6 +995,7 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count)
|
||||||
of the data */
|
of the data */
|
||||||
loff_t blockstart; /* running start of the current block -
|
loff_t blockstart; /* running start of the current block -
|
||||||
MEMGETBADBLOCK needs 64 bits */
|
MEMGETBADBLOCK needs 64 bits */
|
||||||
|
int was_locked; /* flash lock flag */
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1080,6 +1081,12 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count)
|
||||||
}
|
}
|
||||||
|
|
||||||
erase.length = erasesize;
|
erase.length = erasesize;
|
||||||
|
if (DEVTYPE(dev) != MTD_ABSENT) {
|
||||||
|
was_locked = ioctl(fd, MEMISLOCKED, &erase);
|
||||||
|
/* treat any errors as unlocked flash */
|
||||||
|
if (was_locked < 0)
|
||||||
|
was_locked = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* This only runs once on NOR flash and SPI-dataflash */
|
/* This only runs once on NOR flash and SPI-dataflash */
|
||||||
while (processed < write_total) {
|
while (processed < write_total) {
|
||||||
|
@ -1099,6 +1106,7 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count)
|
||||||
|
|
||||||
if (DEVTYPE(dev) != MTD_ABSENT) {
|
if (DEVTYPE(dev) != MTD_ABSENT) {
|
||||||
erase.start = blockstart;
|
erase.start = blockstart;
|
||||||
|
if (was_locked)
|
||||||
ioctl(fd, MEMUNLOCK, &erase);
|
ioctl(fd, MEMUNLOCK, &erase);
|
||||||
/* These do not need an explicit erase cycle */
|
/* These do not need an explicit erase cycle */
|
||||||
if (DEVTYPE(dev) != MTD_DATAFLASH)
|
if (DEVTYPE(dev) != MTD_DATAFLASH)
|
||||||
|
@ -1127,8 +1135,10 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DEVTYPE(dev) != MTD_ABSENT)
|
if (DEVTYPE(dev) != MTD_ABSENT) {
|
||||||
|
if (was_locked)
|
||||||
ioctl(fd, MEMLOCK, &erase);
|
ioctl(fd, MEMLOCK, &erase);
|
||||||
|
}
|
||||||
|
|
||||||
processed += erasesize;
|
processed += erasesize;
|
||||||
block_seek = 0;
|
block_seek = 0;
|
||||||
|
@ -1149,7 +1159,9 @@ static int flash_flag_obsolete(int dev, int fd, off_t offset)
|
||||||
int rc;
|
int rc;
|
||||||
struct erase_info_user erase;
|
struct erase_info_user erase;
|
||||||
char tmp = ENV_REDUND_OBSOLETE;
|
char tmp = ENV_REDUND_OBSOLETE;
|
||||||
|
int was_locked; /* flash lock flag */
|
||||||
|
|
||||||
|
was_locked = ioctl(fd, MEMISLOCKED, &erase);
|
||||||
erase.start = DEVOFFSET(dev);
|
erase.start = DEVOFFSET(dev);
|
||||||
erase.length = DEVESIZE(dev);
|
erase.length = DEVESIZE(dev);
|
||||||
/* This relies on the fact, that ENV_REDUND_OBSOLETE == 0 */
|
/* This relies on the fact, that ENV_REDUND_OBSOLETE == 0 */
|
||||||
|
@ -1159,8 +1171,10 @@ static int flash_flag_obsolete(int dev, int fd, off_t offset)
|
||||||
DEVNAME(dev));
|
DEVNAME(dev));
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
if (was_locked)
|
||||||
ioctl(fd, MEMUNLOCK, &erase);
|
ioctl(fd, MEMUNLOCK, &erase);
|
||||||
rc = write(fd, &tmp, sizeof(tmp));
|
rc = write(fd, &tmp, sizeof(tmp));
|
||||||
|
if (was_locked)
|
||||||
ioctl(fd, MEMLOCK, &erase);
|
ioctl(fd, MEMLOCK, &erase);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
perror("Could not set obsolete flag");
|
perror("Could not set obsolete flag");
|
||||||
|
|
Loading…
Add table
Reference in a new issue