Fail to access 4 x8 bit CFI compliance NOR chip
Chi-Ho Sung
chsung at nortel.com
Fri Dec 14 10:08:02 EST 2007
Hi all,
Does the CFI driver support the 8/16 bit flash in 8 bit mode ?
I have 4 Spansion S29GL01GP (8/16 bit) chips on the board. They are in 8
bit mode and are connected 4 x8 bit interleave to a 32 bits local bus. I
can see the partition defined in /proc/mtd, but when I try to access it
(i.e. cat /dev/mtd1), I got "Oops: kernel access of bad area".
I noticed that the kernel see "MTD: Physically mapped S29GL01GP flash:
Found 4 x16 devices at 0x0 in 32-bit bank ". Is this normal ? Does it
mean the cfi_probe_chip does not support 16 bit device in 8 bit mode ?
Looking at the codes which print out this message:
printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit
bank\n",
map->name, cfi->interleave, cfi->device_type*8, base,
map->bankwidth*8);
The 4 (cfi->interleave) is from the kernel config option.
The 32-bit (map->bankwidth*8) is also from config option.
But, the 16 (cfi->device_type*8) is detected by the "genprobe_new_chip"
from the kernel. The genprobe_new_chip calls cfi_probe_chip to check for
the QRY pattern.
In "genprobe_new_chip", there is a FOR loop.
Case 1:
If (cfi->device_type = 1)
cfi_probe_chip(map, 0, NULL, cfi) --> return false.
Case 2:
If (cfi->device_type = 2)
cfi_probe_chip(map, 0, NULL, cfi) --> return TRUE.
Therefore, cfi_probe assigns 2 to cfi->device_type.
The reason cfi_probe_chip failed in case 1, is because
"qry_present(map,base,cfi)" failed. "qry_present" fail, when 0x98 is
sent to hard coded offset 0x55, but it did not receive back "QRY".
mtd/chips/cfi_probe.c - Note the hardcoded offset "0x55".
-----------------------
static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
unsigned long *chip_map, struct
cfi_private *cfi)
{
...
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type,
NULL);
cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type,
NULL);
cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type,
NULL);
if (!qry_present(map,base,cfi)) {
xip_enable(base, map, cfi);
return 0;
}
...
}
For your information, below is my configuration.
==============================================
struct map_info nt_cb_cp_map = {
.name = "Physically mapped S29GL01GP flash",
.size = WINDOW_SIZE,
.phys = WINDOW_ADDR,
.bankwidth = 4,
};
CONFIG_MTD=y
CONFIG_MTD_DEBUG=y
CONFIG_MTD_DEBUG_VERBOSE=3
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_GEN_PROBE=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_NOSWAP=y
CONFIG_MTD_CFI_GEOMETRY=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
CONFIG_MTD_CFI_I4=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_CFI_AMDSTD_RETRY=0
CONFIG_MTD_CFI_UTIL=y
Below is the "Oops":
=====================
root at localhost:/dev> cat /dev/mtd1
Oops: kernel access of bad area, sig: 11 [#1]
NIP: C001E6AC LR: C001E73C SP: E1A9FDF0 REGS: e1a9fd40 TRAP: 0300 Not
tainted
MSR: 00021000 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 00
DAR: 00000000, DSISR: 00000000
TASK = cee444a0[341] 'cat' THREAD: e1a9e000
Last syscall: 3
GPR00: C001E73C E1A9FDF0 CEE444A0 CEE61B34 00000003 00000001 00000000
00000000
GPR08: FFFFFFFF 03F80000 C0261C6C 00000000 C02DD530 1001C140 00000220
00000000
GPR16: 00001000 E1A9FE6C 00000000 E1A9FEC8 CEE61AE0 E1994000 00000000
CEE61AE0
GPR24: 03F80000 00000003 00000000 00000000 00000001 00029000 CEE61B34
CEE61B18
NIP [c001e6ac] __wake_up_common+0x2c/0x94
LR [c001e73c] __wake_up+0x28/0x40
Call trace:
[c001e73c] __wake_up+0x28/0x40
[c017eab4] put_chip+0x5c/0x1ac
[c017ef18] cfi_amdstd_read+0x1b4/0x220
[c0176990] part_read+0xd4/0xf4
[c01797d0] mtd_read+0xe4/0x214
[c00664a4] vfs_read+0x18c/0x1a8
[c00667ec] sys_read+0x4c/0x90
[c0002330] ret_from_syscall+0x0/0x48
MTD_close
Oops: kernel access of bad area, sig: 11 [#2]
NIP: C001E6AC LR: C001E73C SP: E1A9FB90 REGS: e1a9fae0 TRAP: 0300 Not
tainted
MSR: 00021000 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 00
DAR: 00000000, DSISR: 00000000
TASK = cee444a0[341] 'cat' THREAD: e1a9e000
Last syscall: 3
GPR00: C001E73C E1A9FB90 CEE444A0 CEE61B34 00000003 00000001 00000000
00000000
GPR08: C0250000 C001E678 00000000 00000000 24004428 1001C140 00000220
00000000
GPR16: 00001000 E1A9FE6C 00000000 E1A9FEC8 CEE61AE0 E1994000 00000000
CEE61AE0
GPR24: 03F80000 00000003 00000000 00000000 00000001 00029000 CEE61B34
CEE61B4C
NIP [c001e6ac] __wake_up_common+0x2c/0x94
LR [c001e73c] __wake_up+0x28/0x40
Call trace:
[c001e73c] __wake_up+0x28/0x40
[c0181998] cfi_amdstd_sync+0x100/0x11c
[c0177488] part_sync+0x20/0x30
[c01796cc] mtd_close+0x60/0x80
[c006773c] __fput+0x188/0x1a0
[c0065a40] filp_close+0x54/0xac
[c0023ab0] put_files_struct+0xb0/0x100
[c00242fc] do_exit+0xe8/0xae4
[c0002ff4] _exception+0x0/0x11c
[c000c1dc] bad_page_fault+0x94/0xc4
[c0002894] handle_page_fault+0x7c/0x80
[c0057d94] do_no_page+0x250/0xb18
[c001e73c] __wake_up+0x28/0x40
[c017eab4] put_chip+0x5c/0x1ac
[c017ef18] cfi_amdstd_read+0x1b4/0x220
Fixing recursive fault but reboot is needed!
Thanks,
Ben
More information about the linux-mtd
mailing list