📄 jedec_probe.c
字号:
/* Common Flash Interface probe code. (C) 2000 Red Hat. GPL'd. See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5) for the standard this probe goes back to. Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com*/#include <linux/module.h>#include <linux/init.h>#include <linux/types.h>#include <linux/kernel.h>#include <asm/io.h>#include <asm/byteorder.h>#include <linux/errno.h>#include <linux/slab.h>#include <linux/interrupt.h>#include <linux/mtd/mtd.h>#include <linux/mtd/map.h>#include <linux/mtd/cfi.h>#include <linux/mtd/gen_probe.h>/* Manufacturers */#define MANUFACTURER_AMD 0x0001#define MANUFACTURER_ATMEL 0x001f#define MANUFACTURER_EON 0x001c#define MANUFACTURER_FUJITSU 0x0004#define MANUFACTURER_HYUNDAI 0x00AD#define MANUFACTURER_INTEL 0x0089#define MANUFACTURER_MACRONIX 0x00C2#define MANUFACTURER_NEC 0x0010#define MANUFACTURER_PMC 0x009D#define MANUFACTURER_SHARP 0x00b0#define MANUFACTURER_SST 0x00BF#define MANUFACTURER_ST 0x0020#define MANUFACTURER_TOSHIBA 0x0098#define MANUFACTURER_WINBOND 0x00da#define CONTINUATION_CODE 0x007f/* AMD */#define AM29DL800BB 0x22CB#define AM29DL800BT 0x224A#define AM29F800BB 0x2258#define AM29F800BT 0x22D6#define AM29LV400BB 0x22BA#define AM29LV400BT 0x22B9#define AM29LV800BB 0x225B#define AM29LV800BT 0x22DA#define AM29LV160DT 0x22C4#define AM29LV160DB 0x2249#define AM29F017D 0x003D#define AM29F016D 0x00AD#define AM29F080 0x00D5#define AM29F040 0x00A4#define AM29LV040B 0x004F#define AM29F032B 0x0041#define AM29F002T 0x00B0#define AM29SL800DB 0x226B#define AM29SL800DT 0x22EA/* Atmel */#define AT49BV512 0x0003#define AT29LV512 0x003d#define AT49BV16X 0x00C0#define AT49BV16XT 0x00C2#define AT49BV32X 0x00C8#define AT49BV32XT 0x00C9/* Eon */#define EN29SL800BB 0x226B#define EN29SL800BT 0x22EA/* Fujitsu */#define MBM29F040C 0x00A4#define MBM29F800BA 0x2258#define MBM29LV650UE 0x22D7#define MBM29LV320TE 0x22F6#define MBM29LV320BE 0x22F9#define MBM29LV160TE 0x22C4#define MBM29LV160BE 0x2249#define MBM29LV800BA 0x225B#define MBM29LV800TA 0x22DA#define MBM29LV400TC 0x22B9#define MBM29LV400BC 0x22BA/* Hyundai */#define HY29F002T 0x00B0/* Intel */#define I28F004B3T 0x00d4#define I28F004B3B 0x00d5#define I28F400B3T 0x8894#define I28F400B3B 0x8895#define I28F008S5 0x00a6#define I28F016S5 0x00a0#define I28F008SA 0x00a2#define I28F008B3T 0x00d2#define I28F008B3B 0x00d3#define I28F800B3T 0x8892#define I28F800B3B 0x8893#define I28F016S3 0x00aa#define I28F016B3T 0x00d0#define I28F016B3B 0x00d1#define I28F160B3T 0x8890#define I28F160B3B 0x8891#define I28F320B3T 0x8896#define I28F320B3B 0x8897#define I28F640B3T 0x8898#define I28F640B3B 0x8899#define I82802AB 0x00ad#define I82802AC 0x00ac/* Macronix */#define MX29LV040C 0x004F#define MX29LV160T 0x22C4#define MX29LV160B 0x2249#define MX29F040 0x00A4#define MX29F016 0x00AD#define MX29F002T 0x00B0#define MX29F004T 0x0045#define MX29F004B 0x0046/* NEC */#define UPD29F064115 0x221C/* PMC */#define PM49FL002 0x006D#define PM49FL004 0x006E#define PM49FL008 0x006A/* Sharp */#define LH28F640BF 0x00b0/* ST - www.st.com */#define M29F800AB 0x0058#define M29W800DT 0x00D7#define M29W800DB 0x005B#define M29W400DT 0x00EE#define M29W400DB 0x00EF#define M29W160DT 0x22C4#define M29W160DB 0x2249#define M29W040B 0x00E3#define M50FW040 0x002C#define M50FW080 0x002D#define M50FW016 0x002E#define M50LPW080 0x002F#define M50FLW080A 0x0080#define M50FLW080B 0x0081/* SST */#define SST29EE020 0x0010#define SST29LE020 0x0012#define SST29EE512 0x005d#define SST29LE512 0x003d#define SST39LF800 0x2781#define SST39LF160 0x2782#define SST39VF1601 0x234b#define SST39LF512 0x00D4#define SST39LF010 0x00D5#define SST39LF020 0x00D6#define SST39LF040 0x00D7#define SST39SF010A 0x00B5#define SST39SF020A 0x00B6#define SST49LF004B 0x0060#define SST49LF040B 0x0050#define SST49LF008A 0x005a#define SST49LF030A 0x001C#define SST49LF040A 0x0051#define SST49LF080A 0x005B#define SST36VF3203 0x7354/* Toshiba */#define TC58FVT160 0x00C2#define TC58FVB160 0x0043#define TC58FVT321 0x009A#define TC58FVB321 0x009C#define TC58FVT641 0x0093#define TC58FVB641 0x0095/* Winbond */#define W49V002A 0x00b0/* * Unlock address sets for AMD command sets. * Intel command sets use the MTD_UADDR_UNNECESSARY. * Each identifier, except MTD_UADDR_UNNECESSARY, and * MTD_UADDR_NO_SUPPORT must be defined below in unlock_addrs[]. * MTD_UADDR_NOT_SUPPORTED must be 0 so that structure * initialization need not require initializing all of the * unlock addresses for all bit widths. */enum uaddr { MTD_UADDR_NOT_SUPPORTED = 0, /* data width not supported */ MTD_UADDR_0x0555_0x02AA, MTD_UADDR_0x0555_0x0AAA, MTD_UADDR_0x5555_0x2AAA, MTD_UADDR_0x0AAA_0x0555, MTD_UADDR_0xAAAA_0x5555, MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */ MTD_UADDR_UNNECESSARY, /* Does not require any address */};struct unlock_addr { uint32_t addr1; uint32_t addr2;};/* * I don't like the fact that the first entry in unlock_addrs[] * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore, * should not be used. The problem is that structures with * initializers have extra fields initialized to 0. It is _very_ * desireable to have the unlock address entries for unsupported * data widths automatically initialized - that means that * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here * must go unused. */static const struct unlock_addr unlock_addrs[] = { [MTD_UADDR_NOT_SUPPORTED] = { .addr1 = 0xffff, .addr2 = 0xffff }, [MTD_UADDR_0x0555_0x02AA] = { .addr1 = 0x0555, .addr2 = 0x02aa }, [MTD_UADDR_0x0555_0x0AAA] = { .addr1 = 0x0555, .addr2 = 0x0aaa }, [MTD_UADDR_0x5555_0x2AAA] = { .addr1 = 0x5555, .addr2 = 0x2aaa }, [MTD_UADDR_0x0AAA_0x0555] = { .addr1 = 0x0AAA, .addr2 = 0x0555 }, [MTD_UADDR_0xAAAA_0x5555] = { .addr1 = 0xaaaa, .addr2 = 0x5555 }, [MTD_UADDR_DONT_CARE] = { .addr1 = 0x0000, /* Doesn't matter which address */ .addr2 = 0x0000 /* is used - must be last entry */ }, [MTD_UADDR_UNNECESSARY] = { .addr1 = 0x0000, .addr2 = 0x0000 }};struct amd_flash_info { const char *name; const uint16_t mfr_id; const uint16_t dev_id; const uint8_t dev_size; const uint8_t nr_regions; const uint16_t cmd_set; const uint32_t regions[6]; const uint8_t devtypes; /* Bitmask for x8, x16 etc. */ const uint8_t uaddr; /* unlock addrs for 8, 16, 32, 64 */};#define ERASEINFO(size,blocks) (size<<8)|(blocks-1)#define SIZE_64KiB 16#define SIZE_128KiB 17#define SIZE_256KiB 18#define SIZE_512KiB 19#define SIZE_1MiB 20#define SIZE_2MiB 21#define SIZE_4MiB 22#define SIZE_8MiB 23/* * Please keep this list ordered by manufacturer! * Fortunately, the list isn't searched often and so a * slow, linear search isn't so bad. */static const struct amd_flash_info jedec_table[] = { { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29F032B, .name = "AMD AM29F032B", .uaddr = MTD_UADDR_0x0555_0x02AA, .devtypes = CFI_DEVICETYPE_X8, .dev_size = SIZE_4MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 1, .regions = { ERASEINFO(0x10000,64) } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29LV160DT, .name = "AMD AM29LV160DT", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_2MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 4, .regions = { ERASEINFO(0x10000,31), ERASEINFO(0x08000,1), ERASEINFO(0x02000,2), ERASEINFO(0x04000,1) } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29LV160DB, .name = "AMD AM29LV160DB", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_2MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 4, .regions = { ERASEINFO(0x04000,1), ERASEINFO(0x02000,2), ERASEINFO(0x08000,1), ERASEINFO(0x10000,31) } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29LV400BB, .name = "AMD AM29LV400BB", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_512KiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 4, .regions = { ERASEINFO(0x04000,1), ERASEINFO(0x02000,2), ERASEINFO(0x08000,1), ERASEINFO(0x10000,7) } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29LV400BT, .name = "AMD AM29LV400BT", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_512KiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 4, .regions = { ERASEINFO(0x10000,7), ERASEINFO(0x08000,1), ERASEINFO(0x02000,2), ERASEINFO(0x04000,1) } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29LV800BB, .name = "AMD AM29LV800BB", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_1MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 4, .regions = { ERASEINFO(0x04000,1), ERASEINFO(0x02000,2), ERASEINFO(0x08000,1), ERASEINFO(0x10000,15), } }, {/* add DL */ .mfr_id = MANUFACTURER_AMD, .dev_id = AM29DL800BB, .name = "AMD AM29DL800BB", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_1MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 6, .regions = { ERASEINFO(0x04000,1), ERASEINFO(0x08000,1), ERASEINFO(0x02000,4), ERASEINFO(0x08000,1), ERASEINFO(0x04000,1), ERASEINFO(0x10000,14) } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29DL800BT, .name = "AMD AM29DL800BT", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_1MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 6, .regions = { ERASEINFO(0x10000,14), ERASEINFO(0x04000,1), ERASEINFO(0x08000,1), ERASEINFO(0x02000,4), ERASEINFO(0x08000,1), ERASEINFO(0x04000,1) } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29F800BB, .name = "AMD AM29F800BB", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_1MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 4, .regions = { ERASEINFO(0x04000,1), ERASEINFO(0x02000,2), ERASEINFO(0x08000,1), ERASEINFO(0x10000,15), } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29LV800BT, .name = "AMD AM29LV800BT", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_1MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 4, .regions = { ERASEINFO(0x10000,15), ERASEINFO(0x08000,1), ERASEINFO(0x02000,2), ERASEINFO(0x04000,1) } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29F800BT, .name = "AMD AM29F800BT", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_1MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 4, .regions = { ERASEINFO(0x10000,15), ERASEINFO(0x08000,1), ERASEINFO(0x02000,2), ERASEINFO(0x04000,1) } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29F017D, .name = "AMD AM29F017D", .devtypes = CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_DONT_CARE, .dev_size = SIZE_2MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 1, .regions = { ERASEINFO(0x10000,32), } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29F016D, .name = "AMD AM29F016D", .devtypes = CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0555_0x02AA, .dev_size = SIZE_2MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 1, .regions = { ERASEINFO(0x10000,32), } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29F080, .name = "AMD AM29F080", .devtypes = CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0555_0x02AA, .dev_size = SIZE_1MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 1, .regions = { ERASEINFO(0x10000,16), } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29F040, .name = "AMD AM29F040", .devtypes = CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0555_0x02AA, .dev_size = SIZE_512KiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 1, .regions = { ERASEINFO(0x10000,8), } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29LV040B, .name = "AMD AM29LV040B", .devtypes = CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0555_0x02AA, .dev_size = SIZE_512KiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 1, .regions = { ERASEINFO(0x10000,8), } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29F002T, .name = "AMD AM29F002T", .devtypes = CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0555_0x02AA, .dev_size = SIZE_256KiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 4, .regions = { ERASEINFO(0x10000,3), ERASEINFO(0x08000,1), ERASEINFO(0x02000,2), ERASEINFO(0x04000,1), } }, { .mfr_id = MANUFACTURER_AMD, .dev_id = AM29SL800DT, .name = "AMD AM29SL800DT", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_1MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 4, .regions = { ERASEINFO(0x10000,15), ERASEINFO(0x08000,1), ERASEINFO(0x02000,2), ERASEINFO(0x04000,1), }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -