Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: spi-nor: Check that BP bits are set properly

Previously, the lock and unlock functions returned success even if the
BP bits were not actually updated in the status register due to
hardware write protection. Introduce write_sr_and_check() to write and
read back the status register to ensure the desired BP bits are
actually set as requested.

Signed-off-by: Joe Schultz <jschultz@xes-inc.com>
Signed-off-by: Aaron Sierra <asierra@xes-inc.com>
Signed-off-by: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>

authored by

Aaron Sierra and committed by
Cyrille Pitchen
2666067f 20ccb993

+23 -12
+23 -12
drivers/mtd/spi-nor/spi-nor.c
··· 566 566 return ret; 567 567 } 568 568 569 + /* Write status register and ensure bits in mask match written values */ 570 + static int write_sr_and_check(struct spi_nor *nor, u8 status_new, u8 mask) 571 + { 572 + int ret; 573 + 574 + write_enable(nor); 575 + ret = write_sr(nor, status_new); 576 + if (ret) 577 + return ret; 578 + 579 + ret = spi_nor_wait_till_ready(nor); 580 + if (ret) 581 + return ret; 582 + 583 + ret = read_sr(nor); 584 + if (ret < 0) 585 + return ret; 586 + 587 + return ((ret & mask) != (status_new & mask)) ? -EIO : 0; 588 + } 589 + 569 590 static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, 570 591 uint64_t *len) 571 592 { ··· 685 664 loff_t lock_len; 686 665 bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB; 687 666 bool use_top; 688 - int ret; 689 667 690 668 status_old = read_sr(nor); 691 669 if (status_old < 0) ··· 748 728 if ((status_new & mask) < (status_old & mask)) 749 729 return -EINVAL; 750 730 751 - write_enable(nor); 752 - ret = write_sr(nor, status_new); 753 - if (ret) 754 - return ret; 755 - return spi_nor_wait_till_ready(nor); 731 + return write_sr_and_check(nor, status_new, mask); 756 732 } 757 733 758 734 /* ··· 765 749 loff_t lock_len; 766 750 bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB; 767 751 bool use_top; 768 - int ret; 769 752 770 753 status_old = read_sr(nor); 771 754 if (status_old < 0) ··· 831 816 if ((status_new & mask) > (status_old & mask)) 832 817 return -EINVAL; 833 818 834 - write_enable(nor); 835 - ret = write_sr(nor, status_new); 836 - if (ret) 837 - return ret; 838 - return spi_nor_wait_till_ready(nor); 819 + return write_sr_and_check(nor, status_new, mask); 839 820 } 840 821 841 822 /*