
the sst26_process_bpr function is supposed to check whether a particular protection bit is set (write-lock active). the caller always returns with EACCES when sst26_process_bpr returns true. the previous implementation (double negation) causes the caller to abort checking protection bits when the first bit expected to be set is set.
in order to check whether a particular region is (completely) write-protected, all bits enabling write-protection for all relevant blocks (blocks within the region) must be set. checking for bits can be aborted if a required bit is NOT set, i.e., if sst26_process_bpr returns true. the test whether the region is locked then fails, indicated by (positive) return value EACCES. checking for bits must continue while the required bits are found to be set. only if all expected bits were found to be set, return value 0 indicates that no error occurred and all relevant bits are set.
Signed-off-by: Bernhard Kirchen bernhard.kirchen@mbconnectline.com ---
drivers/mtd/spi/spi-nor-core.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index b3873aaf6e..0b48e068be 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -982,6 +982,9 @@ enum lock_ctl { SST26_CTL_CHECK };
+/* + * returns false for "no error" and true for "expected protection bit is NOT set" + */ static bool sst26_process_bpr(u32 bpr_size, u8 *cmd, u32 bit, enum lock_ctl ctl) { switch (ctl) { @@ -992,7 +995,7 @@ static bool sst26_process_bpr(u32 bpr_size, u8 *cmd, u32 bit, enum lock_ctl ctl) cmd[bpr_size - (bit / 8) - 1] &= ~BIT(bit % 8); break; case SST26_CTL_CHECK: - return !!(cmd[bpr_size - (bit / 8) - 1] & BIT(bit % 8)); + return !(cmd[bpr_size - (bit / 8) - 1] & BIT(bit % 8)); }
return false; @@ -1071,6 +1074,11 @@ static int sst26_hardware_write_protection(struct spi_nor *nor, bool lock) /* * Lock, unlock or check lock status of the flash region of the flash (depending * on the lock_ctl value) + * + * if lock_ctl == SST26_CTL_CHECK, returns EACCES (positive value) if region is + * NOT locked, 0 if region is locked, and negative on errors. + * + * otherwise returns 0 on success, negative value on error. */ static int sst26_lock_ctl(struct spi_nor *nor, loff_t ofs, uint64_t len, enum lock_ctl ctl) { @@ -1200,10 +1208,6 @@ static int sst26_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) return sst26_lock_ctl(nor, ofs, len, SST26_CTL_LOCK); }
-/* - * Returns EACCES (positive value) if region is locked, 0 if region is unlocked, - * and negative on errors. - */ static int sst26_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) { /*