[U-Boot-Users] Bug in cfi_flash.c

Hello,
there is a bug in cfi_flash.c in function flash_get_size(). The problem appears if the board specific CFG_MAX_FLASH_SECT macro is smaller than the real number of sectors.
In this case i use a 32 MiB Spansion flash (S29GL256), but we only want respectivly can use 16 MiB of the flash because of the broken A24 line on the AT91RM9200. Therefore i defined CFG_MAX_FLASH_SECT to 128, but the real value is 256. The structure allocation of flash_info_t in flash.h defines the size of the protect array to CFG_MAX_FLASH_SECT (in my case 128). The for-loop in flash_get_size() initialises this array, but it does it for all sectors (erase_region_count) which is 256 in my case. This will cause the info->portwidth variable (and of course all following too) to be overwritten.
flash.h **************************************** typedef struct { ulong size; /* total bank size in bytes */ ushort sector_count; /* number of erase units */ ulong flash_id; /* combined device & manufacturer code */ ulong start[CFG_MAX_FLASH_SECT]; /* physical sector start addresses */ uchar protect[CFG_MAX_FLASH_SECT]; /* sector protection status */ #ifdef CFG_FLASH_CFI uchar portwidth; /* the width of the port */ uchar chipwidth; /* the width of the chip */ ushort buffer_size; /* # of bytes in write buffer */ ulong erase_blk_tout; /* maximum block erase timeout */ ulong write_tout; /* maximum write timeout */ ulong buffer_write_tout; /* maximum buffer write timeout */ ushort vendor; /* the primary vendor id */ ushort cmd_reset; /* Vendor specific reset command */ ushort interface; /* used for x8/x16 adjustments */ ushort legacy_unlock; /* support Intel legacy (un)locking */ #endif } flash_info_t; ****************************************
cfi_flash.c, flash_get_size() **************************************** debug ("erase_region_count = %d erase_region_size = %d\n", erase_region_count, erase_region_size); for (j = 0; j < erase_region_count; j++) { info->start[sect_cnt] = sector; sector += (erase_region_size * size_ratio);
/* * Only read protection status from supported devices (intel...) */ switch (info->vendor) { case CFI_CMDSET_INTEL_EXTENDED: case CFI_CMDSET_INTEL_STANDARD: info->protect[sect_cnt] = flash_isset (info, sect_cnt, FLASH_OFFSET_PROTECT, FLASH_STATUS_PROTECT); break; default: info->protect[sect_cnt] = 0; /* default: not protected */ }
sect_cnt++; } } ******************************************
regards
Mirco

In message 444F81AF.32040.10275B0@fuchs.ftz-leipzig.de you wrote:
there is a bug in cfi_flash.c in function flash_get_size(). The problem appears if the board specific CFG_MAX_FLASH_SECT macro is smaller than the real number of sectors.
That's not a bug in the driver, but in your configuration then.
In this case i use a 32 MiB Spansion flash (S29GL256), but we only want respectivly can use 16 MiB of the flash because of the broken A24 line on the AT91RM9200. Therefore i defined CFG_MAX_FLASH_SECT to 128, but the real value is 256. The structure allocation of
This is not correct. You should not lie to the driver. Don't complain if he refuses to work for you.
flash_info_t in flash.h defines the size of the protect array to CFG_MAX_FLASH_SECT (in my case 128). The for-loop in flash_get_size() initialises this array, but it does it for all sectors (erase_region_count) which is 256 in my case. This will cause the info->portwidth variable (and of course all following too) to be overwritten.
This should be fixed. It should complain about the misconfiguration and die.
Please submit a patch.
--Alt-Boundary-8434.16938416 Content-type: text/html; charset=US-ASCII Content-transfer-encoding: 7BIT Content-description: Mail message body
And never post HTML here!
Best regards,
Wolfgang Denk
participants (2)
-
Mirco Fuchs
-
Wolfgang Denk