• Wang Haitao's avatar
    mtd: map: fixed bug in 64-bit systems · eba485ec
    Wang Haitao authored
    commit a4d62bab upstream.
    
    Hardware:
    	CPU: XLP832,the 64-bit OS
    	NOR Flash:S29GL128S 128M
    Software:
    	Kernel:2.6.32.41
    	Filesystem:JFFS2
    When writing files, errors appear:
    	Write len 182  but return retlen 180
    	Write of 182 bytes at 0x072c815c failed. returned -5, retlen 180
    	Write len 186  but return retlen 184
    	Write of 186 bytes at 0x072caff4 failed. returned -5, retlen 184
    These errors exist only in 64-bit systems,not in 32-bit systems. After analysis, we
    found that the left shift operation is wrong in map_word_load_partial. For instance:
    	unsigned char buf[3] ={0x9e,0x3a,0xea};
    	map_bankwidth(map) is 4;
    	for (i=0; i < 3; i++) {
    		int bitpos;
    		bitpos = (map_bankwidth(map)-1-i)*8;
    		orig.x[0] &= ~(0xff << bitpos);
    		orig.x[0] |= buf[i] << bitpos;
    	}
    
    The value of orig.x[0] is expected to be 0x9e3aeaff, but in this situation(64-bit
    System) we'll get the wrong value of 0xffffffff9e3aeaff due to the 64-bit sign
    extension:
    buf[i] is defined as "unsigned char" and the left-shift operation will convert it
    to the type of "signed int", so when left-shift buf[i] by 24 bits, the final result
    will get the wrong value: 0xffffffff9e3aeaff.
    
    If the left-shift bits are less than 24, then sign extension will not occur. Whereas
    the bankwidth of the nor flash we used is 4, therefore this BUG emerges.
    Signed-off-by: default avatarPang Xunlei <pang.xunlei@zte.com.cn>
    Signed-off-by: default avatarZhang Yi <zhang.yi20@zte.com.cn>
    Signed-off-by: default avatarLu Zhongjun <lu.zhongjun@zte.com.cn>
    Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
    Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
    eba485ec
map.h 12.8 KB