mtd: cfi_cmdset_0001: Support the absence of protection registers
authorJean-Philippe Brucker <jean-philippe@linaro.org>
Fri, 17 Apr 2020 14:23:26 +0000 (16:23 +0200)
committerVignesh Raghavendra <vigneshr@ti.com>
Thu, 30 Apr 2020 18:12:57 +0000 (23:42 +0530)
The flash controller implemented by the Arm Base platform behaves like
the Intel StrataFlash J3 device, but omits several features. In
particular it doesn't implement a protection register, so "Number of
Protection register fields" in the Primary Vendor-Specific Extended
Query, is 0.

The Intel StrataFlash J3 datasheet only lists 1 as a valid value for
NumProtectionFields. It describes the field as:

"Number of Protection register fields in JEDEC ID space.
“00h,” indicates that 256 protection bytes are available"

While a value of 0 may arguably not be architecturally valid, the
driver's current behavior is certainly wrong: if NumProtectionFields is
0, read_pri_intelext() adds a negative value to the unsigned extra_size,
and ends up in an infinite loop.

Fix it by ignoring a NumProtectionFields of 0.

Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Tested-by: Sudeep Holla <sudeep.holla@arm.com>
Tested-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
drivers/mtd/chips/cfi_cmdset_0001.c

index 142c0f9..42001c4 100644 (file)
@@ -420,8 +420,9 @@ read_pri_intelext(struct map_info *map, __u16 adr)
                extra_size = 0;
 
                /* Protection Register info */
-               extra_size += (extp->NumProtectionFields - 1) *
-                             sizeof(struct cfi_intelext_otpinfo);
+               if (extp->NumProtectionFields)
+                       extra_size += (extp->NumProtectionFields - 1) *
+                                     sizeof(struct cfi_intelext_otpinfo);
        }
 
        if (extp->MinorVersion >= '1') {
@@ -695,14 +696,16 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
         */
        if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3'
            && extp->FeatureSupport & (1 << 9)) {
+               int offs = 0;
                struct cfi_private *newcfi;
                struct flchip *chip;
                struct flchip_shared *shared;
-               int offs, numregions, numparts, partshift, numvirtchips, i, j;
+               int numregions, numparts, partshift, numvirtchips, i, j;
 
                /* Protection Register info */
-               offs = (extp->NumProtectionFields - 1) *
-                      sizeof(struct cfi_intelext_otpinfo);
+               if (extp->NumProtectionFields)
+                       offs = (extp->NumProtectionFields - 1) *
+                              sizeof(struct cfi_intelext_otpinfo);
 
                /* Burst Read info */
                offs += extp->extra[offs+1]+2;