ia64/linux-2.6.18-xen.hg

annotate drivers/mtd/chips/jedec_probe.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
rev   line source
ian@0 1 /*
ian@0 2 Common Flash Interface probe code.
ian@0 3 (C) 2000 Red Hat. GPL'd.
ian@0 4 $Id: jedec_probe.c,v 1.66 2005/11/07 11:14:23 gleixner Exp $
ian@0 5 See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
ian@0 6 for the standard this probe goes back to.
ian@0 7
ian@0 8 Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
ian@0 9 */
ian@0 10
ian@0 11 #include <linux/module.h>
ian@0 12 #include <linux/init.h>
ian@0 13 #include <linux/types.h>
ian@0 14 #include <linux/kernel.h>
ian@0 15 #include <asm/io.h>
ian@0 16 #include <asm/byteorder.h>
ian@0 17 #include <linux/errno.h>
ian@0 18 #include <linux/slab.h>
ian@0 19 #include <linux/interrupt.h>
ian@0 20 #include <linux/init.h>
ian@0 21
ian@0 22 #include <linux/mtd/mtd.h>
ian@0 23 #include <linux/mtd/map.h>
ian@0 24 #include <linux/mtd/cfi.h>
ian@0 25 #include <linux/mtd/gen_probe.h>
ian@0 26
ian@0 27 /* Manufacturers */
ian@0 28 #define MANUFACTURER_AMD 0x0001
ian@0 29 #define MANUFACTURER_ATMEL 0x001f
ian@0 30 #define MANUFACTURER_FUJITSU 0x0004
ian@0 31 #define MANUFACTURER_HYUNDAI 0x00AD
ian@0 32 #define MANUFACTURER_INTEL 0x0089
ian@0 33 #define MANUFACTURER_MACRONIX 0x00C2
ian@0 34 #define MANUFACTURER_NEC 0x0010
ian@0 35 #define MANUFACTURER_PMC 0x009D
ian@0 36 #define MANUFACTURER_SHARP 0x00b0
ian@0 37 #define MANUFACTURER_SST 0x00BF
ian@0 38 #define MANUFACTURER_ST 0x0020
ian@0 39 #define MANUFACTURER_TOSHIBA 0x0098
ian@0 40 #define MANUFACTURER_WINBOND 0x00da
ian@0 41
ian@0 42
ian@0 43 /* AMD */
ian@0 44 #define AM29DL800BB 0x22C8
ian@0 45 #define AM29DL800BT 0x224A
ian@0 46
ian@0 47 #define AM29F800BB 0x2258
ian@0 48 #define AM29F800BT 0x22D6
ian@0 49 #define AM29LV400BB 0x22BA
ian@0 50 #define AM29LV400BT 0x22B9
ian@0 51 #define AM29LV800BB 0x225B
ian@0 52 #define AM29LV800BT 0x22DA
ian@0 53 #define AM29LV160DT 0x22C4
ian@0 54 #define AM29LV160DB 0x2249
ian@0 55 #define AM29F017D 0x003D
ian@0 56 #define AM29F016D 0x00AD
ian@0 57 #define AM29F080 0x00D5
ian@0 58 #define AM29F040 0x00A4
ian@0 59 #define AM29LV040B 0x004F
ian@0 60 #define AM29F032B 0x0041
ian@0 61 #define AM29F002T 0x00B0
ian@0 62
ian@0 63 /* Atmel */
ian@0 64 #define AT49BV512 0x0003
ian@0 65 #define AT29LV512 0x003d
ian@0 66 #define AT49BV16X 0x00C0
ian@0 67 #define AT49BV16XT 0x00C2
ian@0 68 #define AT49BV32X 0x00C8
ian@0 69 #define AT49BV32XT 0x00C9
ian@0 70
ian@0 71 /* Fujitsu */
ian@0 72 #define MBM29F040C 0x00A4
ian@0 73 #define MBM29LV650UE 0x22D7
ian@0 74 #define MBM29LV320TE 0x22F6
ian@0 75 #define MBM29LV320BE 0x22F9
ian@0 76 #define MBM29LV160TE 0x22C4
ian@0 77 #define MBM29LV160BE 0x2249
ian@0 78 #define MBM29LV800BA 0x225B
ian@0 79 #define MBM29LV800TA 0x22DA
ian@0 80 #define MBM29LV400TC 0x22B9
ian@0 81 #define MBM29LV400BC 0x22BA
ian@0 82
ian@0 83 /* Hyundai */
ian@0 84 #define HY29F002T 0x00B0
ian@0 85
ian@0 86 /* Intel */
ian@0 87 #define I28F004B3T 0x00d4
ian@0 88 #define I28F004B3B 0x00d5
ian@0 89 #define I28F400B3T 0x8894
ian@0 90 #define I28F400B3B 0x8895
ian@0 91 #define I28F008S5 0x00a6
ian@0 92 #define I28F016S5 0x00a0
ian@0 93 #define I28F008SA 0x00a2
ian@0 94 #define I28F008B3T 0x00d2
ian@0 95 #define I28F008B3B 0x00d3
ian@0 96 #define I28F800B3T 0x8892
ian@0 97 #define I28F800B3B 0x8893
ian@0 98 #define I28F016S3 0x00aa
ian@0 99 #define I28F016B3T 0x00d0
ian@0 100 #define I28F016B3B 0x00d1
ian@0 101 #define I28F160B3T 0x8890
ian@0 102 #define I28F160B3B 0x8891
ian@0 103 #define I28F320B3T 0x8896
ian@0 104 #define I28F320B3B 0x8897
ian@0 105 #define I28F640B3T 0x8898
ian@0 106 #define I28F640B3B 0x8899
ian@0 107 #define I82802AB 0x00ad
ian@0 108 #define I82802AC 0x00ac
ian@0 109
ian@0 110 /* Macronix */
ian@0 111 #define MX29LV040C 0x004F
ian@0 112 #define MX29LV160T 0x22C4
ian@0 113 #define MX29LV160B 0x2249
ian@0 114 #define MX29F040 0x00A4
ian@0 115 #define MX29F016 0x00AD
ian@0 116 #define MX29F002T 0x00B0
ian@0 117 #define MX29F004T 0x0045
ian@0 118 #define MX29F004B 0x0046
ian@0 119
ian@0 120 /* NEC */
ian@0 121 #define UPD29F064115 0x221C
ian@0 122
ian@0 123 /* PMC */
ian@0 124 #define PM49FL002 0x006D
ian@0 125 #define PM49FL004 0x006E
ian@0 126 #define PM49FL008 0x006A
ian@0 127
ian@0 128 /* Sharp */
ian@0 129 #define LH28F640BF 0x00b0
ian@0 130
ian@0 131 /* ST - www.st.com */
ian@0 132 #define M29W800DT 0x00D7
ian@0 133 #define M29W800DB 0x005B
ian@0 134 #define M29W160DT 0x22C4
ian@0 135 #define M29W160DB 0x2249
ian@0 136 #define M29W040B 0x00E3
ian@0 137 #define M50FW040 0x002C
ian@0 138 #define M50FW080 0x002D
ian@0 139 #define M50FW016 0x002E
ian@0 140 #define M50LPW080 0x002F
ian@0 141
ian@0 142 /* SST */
ian@0 143 #define SST29EE020 0x0010
ian@0 144 #define SST29LE020 0x0012
ian@0 145 #define SST29EE512 0x005d
ian@0 146 #define SST29LE512 0x003d
ian@0 147 #define SST39LF800 0x2781
ian@0 148 #define SST39LF160 0x2782
ian@0 149 #define SST39VF1601 0x234b
ian@0 150 #define SST39LF512 0x00D4
ian@0 151 #define SST39LF010 0x00D5
ian@0 152 #define SST39LF020 0x00D6
ian@0 153 #define SST39LF040 0x00D7
ian@0 154 #define SST39SF010A 0x00B5
ian@0 155 #define SST39SF020A 0x00B6
ian@0 156 #define SST49LF004B 0x0060
ian@0 157 #define SST49LF008A 0x005a
ian@0 158 #define SST49LF030A 0x001C
ian@0 159 #define SST49LF040A 0x0051
ian@0 160 #define SST49LF080A 0x005B
ian@0 161
ian@0 162 /* Toshiba */
ian@0 163 #define TC58FVT160 0x00C2
ian@0 164 #define TC58FVB160 0x0043
ian@0 165 #define TC58FVT321 0x009A
ian@0 166 #define TC58FVB321 0x009C
ian@0 167 #define TC58FVT641 0x0093
ian@0 168 #define TC58FVB641 0x0095
ian@0 169
ian@0 170 /* Winbond */
ian@0 171 #define W49V002A 0x00b0
ian@0 172
ian@0 173
ian@0 174 /*
ian@0 175 * Unlock address sets for AMD command sets.
ian@0 176 * Intel command sets use the MTD_UADDR_UNNECESSARY.
ian@0 177 * Each identifier, except MTD_UADDR_UNNECESSARY, and
ian@0 178 * MTD_UADDR_NO_SUPPORT must be defined below in unlock_addrs[].
ian@0 179 * MTD_UADDR_NOT_SUPPORTED must be 0 so that structure
ian@0 180 * initialization need not require initializing all of the
ian@0 181 * unlock addresses for all bit widths.
ian@0 182 */
ian@0 183 enum uaddr {
ian@0 184 MTD_UADDR_NOT_SUPPORTED = 0, /* data width not supported */
ian@0 185 MTD_UADDR_0x0555_0x02AA,
ian@0 186 MTD_UADDR_0x0555_0x0AAA,
ian@0 187 MTD_UADDR_0x5555_0x2AAA,
ian@0 188 MTD_UADDR_0x0AAA_0x0555,
ian@0 189 MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */
ian@0 190 MTD_UADDR_UNNECESSARY, /* Does not require any address */
ian@0 191 };
ian@0 192
ian@0 193
ian@0 194 struct unlock_addr {
ian@0 195 u32 addr1;
ian@0 196 u32 addr2;
ian@0 197 };
ian@0 198
ian@0 199
ian@0 200 /*
ian@0 201 * I don't like the fact that the first entry in unlock_addrs[]
ian@0 202 * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore,
ian@0 203 * should not be used. The problem is that structures with
ian@0 204 * initializers have extra fields initialized to 0. It is _very_
ian@0 205 * desireable to have the unlock address entries for unsupported
ian@0 206 * data widths automatically initialized - that means that
ian@0 207 * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here
ian@0 208 * must go unused.
ian@0 209 */
ian@0 210 static const struct unlock_addr unlock_addrs[] = {
ian@0 211 [MTD_UADDR_NOT_SUPPORTED] = {
ian@0 212 .addr1 = 0xffff,
ian@0 213 .addr2 = 0xffff
ian@0 214 },
ian@0 215
ian@0 216 [MTD_UADDR_0x0555_0x02AA] = {
ian@0 217 .addr1 = 0x0555,
ian@0 218 .addr2 = 0x02aa
ian@0 219 },
ian@0 220
ian@0 221 [MTD_UADDR_0x0555_0x0AAA] = {
ian@0 222 .addr1 = 0x0555,
ian@0 223 .addr2 = 0x0aaa
ian@0 224 },
ian@0 225
ian@0 226 [MTD_UADDR_0x5555_0x2AAA] = {
ian@0 227 .addr1 = 0x5555,
ian@0 228 .addr2 = 0x2aaa
ian@0 229 },
ian@0 230
ian@0 231 [MTD_UADDR_0x0AAA_0x0555] = {
ian@0 232 .addr1 = 0x0AAA,
ian@0 233 .addr2 = 0x0555
ian@0 234 },
ian@0 235
ian@0 236 [MTD_UADDR_DONT_CARE] = {
ian@0 237 .addr1 = 0x0000, /* Doesn't matter which address */
ian@0 238 .addr2 = 0x0000 /* is used - must be last entry */
ian@0 239 },
ian@0 240
ian@0 241 [MTD_UADDR_UNNECESSARY] = {
ian@0 242 .addr1 = 0x0000,
ian@0 243 .addr2 = 0x0000
ian@0 244 }
ian@0 245 };
ian@0 246
ian@0 247
ian@0 248 struct amd_flash_info {
ian@0 249 const __u16 mfr_id;
ian@0 250 const __u16 dev_id;
ian@0 251 const char *name;
ian@0 252 const int DevSize;
ian@0 253 const int NumEraseRegions;
ian@0 254 const int CmdSet;
ian@0 255 const __u8 uaddr[4]; /* unlock addrs for 8, 16, 32, 64 */
ian@0 256 const ulong regions[6];
ian@0 257 };
ian@0 258
ian@0 259 #define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
ian@0 260
ian@0 261 #define SIZE_64KiB 16
ian@0 262 #define SIZE_128KiB 17
ian@0 263 #define SIZE_256KiB 18
ian@0 264 #define SIZE_512KiB 19
ian@0 265 #define SIZE_1MiB 20
ian@0 266 #define SIZE_2MiB 21
ian@0 267 #define SIZE_4MiB 22
ian@0 268 #define SIZE_8MiB 23
ian@0 269
ian@0 270
ian@0 271 /*
ian@0 272 * Please keep this list ordered by manufacturer!
ian@0 273 * Fortunately, the list isn't searched often and so a
ian@0 274 * slow, linear search isn't so bad.
ian@0 275 */
ian@0 276 static const struct amd_flash_info jedec_table[] = {
ian@0 277 {
ian@0 278 .mfr_id = MANUFACTURER_AMD,
ian@0 279 .dev_id = AM29F032B,
ian@0 280 .name = "AMD AM29F032B",
ian@0 281 .uaddr = {
ian@0 282 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
ian@0 283 },
ian@0 284 .DevSize = SIZE_4MiB,
ian@0 285 .CmdSet = P_ID_AMD_STD,
ian@0 286 .NumEraseRegions= 1,
ian@0 287 .regions = {
ian@0 288 ERASEINFO(0x10000,64)
ian@0 289 }
ian@0 290 }, {
ian@0 291 .mfr_id = MANUFACTURER_AMD,
ian@0 292 .dev_id = AM29LV160DT,
ian@0 293 .name = "AMD AM29LV160DT",
ian@0 294 .uaddr = {
ian@0 295 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 296 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
ian@0 297 },
ian@0 298 .DevSize = SIZE_2MiB,
ian@0 299 .CmdSet = P_ID_AMD_STD,
ian@0 300 .NumEraseRegions= 4,
ian@0 301 .regions = {
ian@0 302 ERASEINFO(0x10000,31),
ian@0 303 ERASEINFO(0x08000,1),
ian@0 304 ERASEINFO(0x02000,2),
ian@0 305 ERASEINFO(0x04000,1)
ian@0 306 }
ian@0 307 }, {
ian@0 308 .mfr_id = MANUFACTURER_AMD,
ian@0 309 .dev_id = AM29LV160DB,
ian@0 310 .name = "AMD AM29LV160DB",
ian@0 311 .uaddr = {
ian@0 312 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 313 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
ian@0 314 },
ian@0 315 .DevSize = SIZE_2MiB,
ian@0 316 .CmdSet = P_ID_AMD_STD,
ian@0 317 .NumEraseRegions= 4,
ian@0 318 .regions = {
ian@0 319 ERASEINFO(0x04000,1),
ian@0 320 ERASEINFO(0x02000,2),
ian@0 321 ERASEINFO(0x08000,1),
ian@0 322 ERASEINFO(0x10000,31)
ian@0 323 }
ian@0 324 }, {
ian@0 325 .mfr_id = MANUFACTURER_AMD,
ian@0 326 .dev_id = AM29LV400BB,
ian@0 327 .name = "AMD AM29LV400BB",
ian@0 328 .uaddr = {
ian@0 329 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 330 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 331 },
ian@0 332 .DevSize = SIZE_512KiB,
ian@0 333 .CmdSet = P_ID_AMD_STD,
ian@0 334 .NumEraseRegions= 4,
ian@0 335 .regions = {
ian@0 336 ERASEINFO(0x04000,1),
ian@0 337 ERASEINFO(0x02000,2),
ian@0 338 ERASEINFO(0x08000,1),
ian@0 339 ERASEINFO(0x10000,7)
ian@0 340 }
ian@0 341 }, {
ian@0 342 .mfr_id = MANUFACTURER_AMD,
ian@0 343 .dev_id = AM29LV400BT,
ian@0 344 .name = "AMD AM29LV400BT",
ian@0 345 .uaddr = {
ian@0 346 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 347 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 348 },
ian@0 349 .DevSize = SIZE_512KiB,
ian@0 350 .CmdSet = P_ID_AMD_STD,
ian@0 351 .NumEraseRegions= 4,
ian@0 352 .regions = {
ian@0 353 ERASEINFO(0x10000,7),
ian@0 354 ERASEINFO(0x08000,1),
ian@0 355 ERASEINFO(0x02000,2),
ian@0 356 ERASEINFO(0x04000,1)
ian@0 357 }
ian@0 358 }, {
ian@0 359 .mfr_id = MANUFACTURER_AMD,
ian@0 360 .dev_id = AM29LV800BB,
ian@0 361 .name = "AMD AM29LV800BB",
ian@0 362 .uaddr = {
ian@0 363 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 364 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 365 },
ian@0 366 .DevSize = SIZE_1MiB,
ian@0 367 .CmdSet = P_ID_AMD_STD,
ian@0 368 .NumEraseRegions= 4,
ian@0 369 .regions = {
ian@0 370 ERASEINFO(0x04000,1),
ian@0 371 ERASEINFO(0x02000,2),
ian@0 372 ERASEINFO(0x08000,1),
ian@0 373 ERASEINFO(0x10000,15),
ian@0 374 }
ian@0 375 }, {
ian@0 376 /* add DL */
ian@0 377 .mfr_id = MANUFACTURER_AMD,
ian@0 378 .dev_id = AM29DL800BB,
ian@0 379 .name = "AMD AM29DL800BB",
ian@0 380 .uaddr = {
ian@0 381 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 382 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 383 },
ian@0 384 .DevSize = SIZE_1MiB,
ian@0 385 .CmdSet = P_ID_AMD_STD,
ian@0 386 .NumEraseRegions= 6,
ian@0 387 .regions = {
ian@0 388 ERASEINFO(0x04000,1),
ian@0 389 ERASEINFO(0x08000,1),
ian@0 390 ERASEINFO(0x02000,4),
ian@0 391 ERASEINFO(0x08000,1),
ian@0 392 ERASEINFO(0x04000,1),
ian@0 393 ERASEINFO(0x10000,14)
ian@0 394 }
ian@0 395 }, {
ian@0 396 .mfr_id = MANUFACTURER_AMD,
ian@0 397 .dev_id = AM29DL800BT,
ian@0 398 .name = "AMD AM29DL800BT",
ian@0 399 .uaddr = {
ian@0 400 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 401 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 402 },
ian@0 403 .DevSize = SIZE_1MiB,
ian@0 404 .CmdSet = P_ID_AMD_STD,
ian@0 405 .NumEraseRegions= 6,
ian@0 406 .regions = {
ian@0 407 ERASEINFO(0x10000,14),
ian@0 408 ERASEINFO(0x04000,1),
ian@0 409 ERASEINFO(0x08000,1),
ian@0 410 ERASEINFO(0x02000,4),
ian@0 411 ERASEINFO(0x08000,1),
ian@0 412 ERASEINFO(0x04000,1)
ian@0 413 }
ian@0 414 }, {
ian@0 415 .mfr_id = MANUFACTURER_AMD,
ian@0 416 .dev_id = AM29F800BB,
ian@0 417 .name = "AMD AM29F800BB",
ian@0 418 .uaddr = {
ian@0 419 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 420 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 421 },
ian@0 422 .DevSize = SIZE_1MiB,
ian@0 423 .CmdSet = P_ID_AMD_STD,
ian@0 424 .NumEraseRegions= 4,
ian@0 425 .regions = {
ian@0 426 ERASEINFO(0x04000,1),
ian@0 427 ERASEINFO(0x02000,2),
ian@0 428 ERASEINFO(0x08000,1),
ian@0 429 ERASEINFO(0x10000,15),
ian@0 430 }
ian@0 431 }, {
ian@0 432 .mfr_id = MANUFACTURER_AMD,
ian@0 433 .dev_id = AM29LV800BT,
ian@0 434 .name = "AMD AM29LV800BT",
ian@0 435 .uaddr = {
ian@0 436 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 437 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 438 },
ian@0 439 .DevSize = SIZE_1MiB,
ian@0 440 .CmdSet = P_ID_AMD_STD,
ian@0 441 .NumEraseRegions= 4,
ian@0 442 .regions = {
ian@0 443 ERASEINFO(0x10000,15),
ian@0 444 ERASEINFO(0x08000,1),
ian@0 445 ERASEINFO(0x02000,2),
ian@0 446 ERASEINFO(0x04000,1)
ian@0 447 }
ian@0 448 }, {
ian@0 449 .mfr_id = MANUFACTURER_AMD,
ian@0 450 .dev_id = AM29F800BT,
ian@0 451 .name = "AMD AM29F800BT",
ian@0 452 .uaddr = {
ian@0 453 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 454 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 455 },
ian@0 456 .DevSize = SIZE_1MiB,
ian@0 457 .CmdSet = P_ID_AMD_STD,
ian@0 458 .NumEraseRegions= 4,
ian@0 459 .regions = {
ian@0 460 ERASEINFO(0x10000,15),
ian@0 461 ERASEINFO(0x08000,1),
ian@0 462 ERASEINFO(0x02000,2),
ian@0 463 ERASEINFO(0x04000,1)
ian@0 464 }
ian@0 465 }, {
ian@0 466 .mfr_id = MANUFACTURER_AMD,
ian@0 467 .dev_id = AM29F017D,
ian@0 468 .name = "AMD AM29F017D",
ian@0 469 .uaddr = {
ian@0 470 [0] = MTD_UADDR_DONT_CARE /* x8 */
ian@0 471 },
ian@0 472 .DevSize = SIZE_2MiB,
ian@0 473 .CmdSet = P_ID_AMD_STD,
ian@0 474 .NumEraseRegions= 1,
ian@0 475 .regions = {
ian@0 476 ERASEINFO(0x10000,32),
ian@0 477 }
ian@0 478 }, {
ian@0 479 .mfr_id = MANUFACTURER_AMD,
ian@0 480 .dev_id = AM29F016D,
ian@0 481 .name = "AMD AM29F016D",
ian@0 482 .uaddr = {
ian@0 483 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
ian@0 484 },
ian@0 485 .DevSize = SIZE_2MiB,
ian@0 486 .CmdSet = P_ID_AMD_STD,
ian@0 487 .NumEraseRegions= 1,
ian@0 488 .regions = {
ian@0 489 ERASEINFO(0x10000,32),
ian@0 490 }
ian@0 491 }, {
ian@0 492 .mfr_id = MANUFACTURER_AMD,
ian@0 493 .dev_id = AM29F080,
ian@0 494 .name = "AMD AM29F080",
ian@0 495 .uaddr = {
ian@0 496 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
ian@0 497 },
ian@0 498 .DevSize = SIZE_1MiB,
ian@0 499 .CmdSet = P_ID_AMD_STD,
ian@0 500 .NumEraseRegions= 1,
ian@0 501 .regions = {
ian@0 502 ERASEINFO(0x10000,16),
ian@0 503 }
ian@0 504 }, {
ian@0 505 .mfr_id = MANUFACTURER_AMD,
ian@0 506 .dev_id = AM29F040,
ian@0 507 .name = "AMD AM29F040",
ian@0 508 .uaddr = {
ian@0 509 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
ian@0 510 },
ian@0 511 .DevSize = SIZE_512KiB,
ian@0 512 .CmdSet = P_ID_AMD_STD,
ian@0 513 .NumEraseRegions= 1,
ian@0 514 .regions = {
ian@0 515 ERASEINFO(0x10000,8),
ian@0 516 }
ian@0 517 }, {
ian@0 518 .mfr_id = MANUFACTURER_AMD,
ian@0 519 .dev_id = AM29LV040B,
ian@0 520 .name = "AMD AM29LV040B",
ian@0 521 .uaddr = {
ian@0 522 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
ian@0 523 },
ian@0 524 .DevSize = SIZE_512KiB,
ian@0 525 .CmdSet = P_ID_AMD_STD,
ian@0 526 .NumEraseRegions= 1,
ian@0 527 .regions = {
ian@0 528 ERASEINFO(0x10000,8),
ian@0 529 }
ian@0 530 }, {
ian@0 531 .mfr_id = MANUFACTURER_AMD,
ian@0 532 .dev_id = AM29F002T,
ian@0 533 .name = "AMD AM29F002T",
ian@0 534 .uaddr = {
ian@0 535 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
ian@0 536 },
ian@0 537 .DevSize = SIZE_256KiB,
ian@0 538 .CmdSet = P_ID_AMD_STD,
ian@0 539 .NumEraseRegions= 4,
ian@0 540 .regions = {
ian@0 541 ERASEINFO(0x10000,3),
ian@0 542 ERASEINFO(0x08000,1),
ian@0 543 ERASEINFO(0x02000,2),
ian@0 544 ERASEINFO(0x04000,1),
ian@0 545 }
ian@0 546 }, {
ian@0 547 .mfr_id = MANUFACTURER_ATMEL,
ian@0 548 .dev_id = AT49BV512,
ian@0 549 .name = "Atmel AT49BV512",
ian@0 550 .uaddr = {
ian@0 551 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 552 },
ian@0 553 .DevSize = SIZE_64KiB,
ian@0 554 .CmdSet = P_ID_AMD_STD,
ian@0 555 .NumEraseRegions= 1,
ian@0 556 .regions = {
ian@0 557 ERASEINFO(0x10000,1)
ian@0 558 }
ian@0 559 }, {
ian@0 560 .mfr_id = MANUFACTURER_ATMEL,
ian@0 561 .dev_id = AT29LV512,
ian@0 562 .name = "Atmel AT29LV512",
ian@0 563 .uaddr = {
ian@0 564 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 565 },
ian@0 566 .DevSize = SIZE_64KiB,
ian@0 567 .CmdSet = P_ID_AMD_STD,
ian@0 568 .NumEraseRegions= 1,
ian@0 569 .regions = {
ian@0 570 ERASEINFO(0x80,256),
ian@0 571 ERASEINFO(0x80,256)
ian@0 572 }
ian@0 573 }, {
ian@0 574 .mfr_id = MANUFACTURER_ATMEL,
ian@0 575 .dev_id = AT49BV16X,
ian@0 576 .name = "Atmel AT49BV16X",
ian@0 577 .uaddr = {
ian@0 578 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
ian@0 579 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
ian@0 580 },
ian@0 581 .DevSize = SIZE_2MiB,
ian@0 582 .CmdSet = P_ID_AMD_STD,
ian@0 583 .NumEraseRegions= 2,
ian@0 584 .regions = {
ian@0 585 ERASEINFO(0x02000,8),
ian@0 586 ERASEINFO(0x10000,31)
ian@0 587 }
ian@0 588 }, {
ian@0 589 .mfr_id = MANUFACTURER_ATMEL,
ian@0 590 .dev_id = AT49BV16XT,
ian@0 591 .name = "Atmel AT49BV16XT",
ian@0 592 .uaddr = {
ian@0 593 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
ian@0 594 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
ian@0 595 },
ian@0 596 .DevSize = SIZE_2MiB,
ian@0 597 .CmdSet = P_ID_AMD_STD,
ian@0 598 .NumEraseRegions= 2,
ian@0 599 .regions = {
ian@0 600 ERASEINFO(0x10000,31),
ian@0 601 ERASEINFO(0x02000,8)
ian@0 602 }
ian@0 603 }, {
ian@0 604 .mfr_id = MANUFACTURER_ATMEL,
ian@0 605 .dev_id = AT49BV32X,
ian@0 606 .name = "Atmel AT49BV32X",
ian@0 607 .uaddr = {
ian@0 608 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
ian@0 609 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
ian@0 610 },
ian@0 611 .DevSize = SIZE_4MiB,
ian@0 612 .CmdSet = P_ID_AMD_STD,
ian@0 613 .NumEraseRegions= 2,
ian@0 614 .regions = {
ian@0 615 ERASEINFO(0x02000,8),
ian@0 616 ERASEINFO(0x10000,63)
ian@0 617 }
ian@0 618 }, {
ian@0 619 .mfr_id = MANUFACTURER_ATMEL,
ian@0 620 .dev_id = AT49BV32XT,
ian@0 621 .name = "Atmel AT49BV32XT",
ian@0 622 .uaddr = {
ian@0 623 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
ian@0 624 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
ian@0 625 },
ian@0 626 .DevSize = SIZE_4MiB,
ian@0 627 .CmdSet = P_ID_AMD_STD,
ian@0 628 .NumEraseRegions= 2,
ian@0 629 .regions = {
ian@0 630 ERASEINFO(0x10000,63),
ian@0 631 ERASEINFO(0x02000,8)
ian@0 632 }
ian@0 633 }, {
ian@0 634 .mfr_id = MANUFACTURER_FUJITSU,
ian@0 635 .dev_id = MBM29F040C,
ian@0 636 .name = "Fujitsu MBM29F040C",
ian@0 637 .uaddr = {
ian@0 638 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 639 },
ian@0 640 .DevSize = SIZE_512KiB,
ian@0 641 .CmdSet = P_ID_AMD_STD,
ian@0 642 .NumEraseRegions= 1,
ian@0 643 .regions = {
ian@0 644 ERASEINFO(0x10000,8)
ian@0 645 }
ian@0 646 }, {
ian@0 647 .mfr_id = MANUFACTURER_FUJITSU,
ian@0 648 .dev_id = MBM29LV650UE,
ian@0 649 .name = "Fujitsu MBM29LV650UE",
ian@0 650 .uaddr = {
ian@0 651 [0] = MTD_UADDR_DONT_CARE /* x16 */
ian@0 652 },
ian@0 653 .DevSize = SIZE_8MiB,
ian@0 654 .CmdSet = P_ID_AMD_STD,
ian@0 655 .NumEraseRegions= 1,
ian@0 656 .regions = {
ian@0 657 ERASEINFO(0x10000,128)
ian@0 658 }
ian@0 659 }, {
ian@0 660 .mfr_id = MANUFACTURER_FUJITSU,
ian@0 661 .dev_id = MBM29LV320TE,
ian@0 662 .name = "Fujitsu MBM29LV320TE",
ian@0 663 .uaddr = {
ian@0 664 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 665 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 666 },
ian@0 667 .DevSize = SIZE_4MiB,
ian@0 668 .CmdSet = P_ID_AMD_STD,
ian@0 669 .NumEraseRegions= 2,
ian@0 670 .regions = {
ian@0 671 ERASEINFO(0x10000,63),
ian@0 672 ERASEINFO(0x02000,8)
ian@0 673 }
ian@0 674 }, {
ian@0 675 .mfr_id = MANUFACTURER_FUJITSU,
ian@0 676 .dev_id = MBM29LV320BE,
ian@0 677 .name = "Fujitsu MBM29LV320BE",
ian@0 678 .uaddr = {
ian@0 679 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 680 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 681 },
ian@0 682 .DevSize = SIZE_4MiB,
ian@0 683 .CmdSet = P_ID_AMD_STD,
ian@0 684 .NumEraseRegions= 2,
ian@0 685 .regions = {
ian@0 686 ERASEINFO(0x02000,8),
ian@0 687 ERASEINFO(0x10000,63)
ian@0 688 }
ian@0 689 }, {
ian@0 690 .mfr_id = MANUFACTURER_FUJITSU,
ian@0 691 .dev_id = MBM29LV160TE,
ian@0 692 .name = "Fujitsu MBM29LV160TE",
ian@0 693 .uaddr = {
ian@0 694 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 695 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 696 },
ian@0 697 .DevSize = SIZE_2MiB,
ian@0 698 .CmdSet = P_ID_AMD_STD,
ian@0 699 .NumEraseRegions= 4,
ian@0 700 .regions = {
ian@0 701 ERASEINFO(0x10000,31),
ian@0 702 ERASEINFO(0x08000,1),
ian@0 703 ERASEINFO(0x02000,2),
ian@0 704 ERASEINFO(0x04000,1)
ian@0 705 }
ian@0 706 }, {
ian@0 707 .mfr_id = MANUFACTURER_FUJITSU,
ian@0 708 .dev_id = MBM29LV160BE,
ian@0 709 .name = "Fujitsu MBM29LV160BE",
ian@0 710 .uaddr = {
ian@0 711 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 712 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 713 },
ian@0 714 .DevSize = SIZE_2MiB,
ian@0 715 .CmdSet = P_ID_AMD_STD,
ian@0 716 .NumEraseRegions= 4,
ian@0 717 .regions = {
ian@0 718 ERASEINFO(0x04000,1),
ian@0 719 ERASEINFO(0x02000,2),
ian@0 720 ERASEINFO(0x08000,1),
ian@0 721 ERASEINFO(0x10000,31)
ian@0 722 }
ian@0 723 }, {
ian@0 724 .mfr_id = MANUFACTURER_FUJITSU,
ian@0 725 .dev_id = MBM29LV800BA,
ian@0 726 .name = "Fujitsu MBM29LV800BA",
ian@0 727 .uaddr = {
ian@0 728 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 729 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 730 },
ian@0 731 .DevSize = SIZE_1MiB,
ian@0 732 .CmdSet = P_ID_AMD_STD,
ian@0 733 .NumEraseRegions= 4,
ian@0 734 .regions = {
ian@0 735 ERASEINFO(0x04000,1),
ian@0 736 ERASEINFO(0x02000,2),
ian@0 737 ERASEINFO(0x08000,1),
ian@0 738 ERASEINFO(0x10000,15)
ian@0 739 }
ian@0 740 }, {
ian@0 741 .mfr_id = MANUFACTURER_FUJITSU,
ian@0 742 .dev_id = MBM29LV800TA,
ian@0 743 .name = "Fujitsu MBM29LV800TA",
ian@0 744 .uaddr = {
ian@0 745 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 746 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 747 },
ian@0 748 .DevSize = SIZE_1MiB,
ian@0 749 .CmdSet = P_ID_AMD_STD,
ian@0 750 .NumEraseRegions= 4,
ian@0 751 .regions = {
ian@0 752 ERASEINFO(0x10000,15),
ian@0 753 ERASEINFO(0x08000,1),
ian@0 754 ERASEINFO(0x02000,2),
ian@0 755 ERASEINFO(0x04000,1)
ian@0 756 }
ian@0 757 }, {
ian@0 758 .mfr_id = MANUFACTURER_FUJITSU,
ian@0 759 .dev_id = MBM29LV400BC,
ian@0 760 .name = "Fujitsu MBM29LV400BC",
ian@0 761 .uaddr = {
ian@0 762 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 763 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 764 },
ian@0 765 .DevSize = SIZE_512KiB,
ian@0 766 .CmdSet = P_ID_AMD_STD,
ian@0 767 .NumEraseRegions= 4,
ian@0 768 .regions = {
ian@0 769 ERASEINFO(0x04000,1),
ian@0 770 ERASEINFO(0x02000,2),
ian@0 771 ERASEINFO(0x08000,1),
ian@0 772 ERASEINFO(0x10000,7)
ian@0 773 }
ian@0 774 }, {
ian@0 775 .mfr_id = MANUFACTURER_FUJITSU,
ian@0 776 .dev_id = MBM29LV400TC,
ian@0 777 .name = "Fujitsu MBM29LV400TC",
ian@0 778 .uaddr = {
ian@0 779 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 780 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 781 },
ian@0 782 .DevSize = SIZE_512KiB,
ian@0 783 .CmdSet = P_ID_AMD_STD,
ian@0 784 .NumEraseRegions= 4,
ian@0 785 .regions = {
ian@0 786 ERASEINFO(0x10000,7),
ian@0 787 ERASEINFO(0x08000,1),
ian@0 788 ERASEINFO(0x02000,2),
ian@0 789 ERASEINFO(0x04000,1)
ian@0 790 }
ian@0 791 }, {
ian@0 792 .mfr_id = MANUFACTURER_HYUNDAI,
ian@0 793 .dev_id = HY29F002T,
ian@0 794 .name = "Hyundai HY29F002T",
ian@0 795 .uaddr = {
ian@0 796 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
ian@0 797 },
ian@0 798 .DevSize = SIZE_256KiB,
ian@0 799 .CmdSet = P_ID_AMD_STD,
ian@0 800 .NumEraseRegions= 4,
ian@0 801 .regions = {
ian@0 802 ERASEINFO(0x10000,3),
ian@0 803 ERASEINFO(0x08000,1),
ian@0 804 ERASEINFO(0x02000,2),
ian@0 805 ERASEINFO(0x04000,1),
ian@0 806 }
ian@0 807 }, {
ian@0 808 .mfr_id = MANUFACTURER_INTEL,
ian@0 809 .dev_id = I28F004B3B,
ian@0 810 .name = "Intel 28F004B3B",
ian@0 811 .uaddr = {
ian@0 812 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 813 },
ian@0 814 .DevSize = SIZE_512KiB,
ian@0 815 .CmdSet = P_ID_INTEL_STD,
ian@0 816 .NumEraseRegions= 2,
ian@0 817 .regions = {
ian@0 818 ERASEINFO(0x02000, 8),
ian@0 819 ERASEINFO(0x10000, 7),
ian@0 820 }
ian@0 821 }, {
ian@0 822 .mfr_id = MANUFACTURER_INTEL,
ian@0 823 .dev_id = I28F004B3T,
ian@0 824 .name = "Intel 28F004B3T",
ian@0 825 .uaddr = {
ian@0 826 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 827 },
ian@0 828 .DevSize = SIZE_512KiB,
ian@0 829 .CmdSet = P_ID_INTEL_STD,
ian@0 830 .NumEraseRegions= 2,
ian@0 831 .regions = {
ian@0 832 ERASEINFO(0x10000, 7),
ian@0 833 ERASEINFO(0x02000, 8),
ian@0 834 }
ian@0 835 }, {
ian@0 836 .mfr_id = MANUFACTURER_INTEL,
ian@0 837 .dev_id = I28F400B3B,
ian@0 838 .name = "Intel 28F400B3B",
ian@0 839 .uaddr = {
ian@0 840 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 841 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
ian@0 842 },
ian@0 843 .DevSize = SIZE_512KiB,
ian@0 844 .CmdSet = P_ID_INTEL_STD,
ian@0 845 .NumEraseRegions= 2,
ian@0 846 .regions = {
ian@0 847 ERASEINFO(0x02000, 8),
ian@0 848 ERASEINFO(0x10000, 7),
ian@0 849 }
ian@0 850 }, {
ian@0 851 .mfr_id = MANUFACTURER_INTEL,
ian@0 852 .dev_id = I28F400B3T,
ian@0 853 .name = "Intel 28F400B3T",
ian@0 854 .uaddr = {
ian@0 855 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 856 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
ian@0 857 },
ian@0 858 .DevSize = SIZE_512KiB,
ian@0 859 .CmdSet = P_ID_INTEL_STD,
ian@0 860 .NumEraseRegions= 2,
ian@0 861 .regions = {
ian@0 862 ERASEINFO(0x10000, 7),
ian@0 863 ERASEINFO(0x02000, 8),
ian@0 864 }
ian@0 865 }, {
ian@0 866 .mfr_id = MANUFACTURER_INTEL,
ian@0 867 .dev_id = I28F008B3B,
ian@0 868 .name = "Intel 28F008B3B",
ian@0 869 .uaddr = {
ian@0 870 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 871 },
ian@0 872 .DevSize = SIZE_1MiB,
ian@0 873 .CmdSet = P_ID_INTEL_STD,
ian@0 874 .NumEraseRegions= 2,
ian@0 875 .regions = {
ian@0 876 ERASEINFO(0x02000, 8),
ian@0 877 ERASEINFO(0x10000, 15),
ian@0 878 }
ian@0 879 }, {
ian@0 880 .mfr_id = MANUFACTURER_INTEL,
ian@0 881 .dev_id = I28F008B3T,
ian@0 882 .name = "Intel 28F008B3T",
ian@0 883 .uaddr = {
ian@0 884 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 885 },
ian@0 886 .DevSize = SIZE_1MiB,
ian@0 887 .CmdSet = P_ID_INTEL_STD,
ian@0 888 .NumEraseRegions= 2,
ian@0 889 .regions = {
ian@0 890 ERASEINFO(0x10000, 15),
ian@0 891 ERASEINFO(0x02000, 8),
ian@0 892 }
ian@0 893 }, {
ian@0 894 .mfr_id = MANUFACTURER_INTEL,
ian@0 895 .dev_id = I28F008S5,
ian@0 896 .name = "Intel 28F008S5",
ian@0 897 .uaddr = {
ian@0 898 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 899 },
ian@0 900 .DevSize = SIZE_1MiB,
ian@0 901 .CmdSet = P_ID_INTEL_EXT,
ian@0 902 .NumEraseRegions= 1,
ian@0 903 .regions = {
ian@0 904 ERASEINFO(0x10000,16),
ian@0 905 }
ian@0 906 }, {
ian@0 907 .mfr_id = MANUFACTURER_INTEL,
ian@0 908 .dev_id = I28F016S5,
ian@0 909 .name = "Intel 28F016S5",
ian@0 910 .uaddr = {
ian@0 911 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 912 },
ian@0 913 .DevSize = SIZE_2MiB,
ian@0 914 .CmdSet = P_ID_INTEL_EXT,
ian@0 915 .NumEraseRegions= 1,
ian@0 916 .regions = {
ian@0 917 ERASEINFO(0x10000,32),
ian@0 918 }
ian@0 919 }, {
ian@0 920 .mfr_id = MANUFACTURER_INTEL,
ian@0 921 .dev_id = I28F008SA,
ian@0 922 .name = "Intel 28F008SA",
ian@0 923 .uaddr = {
ian@0 924 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 925 },
ian@0 926 .DevSize = SIZE_1MiB,
ian@0 927 .CmdSet = P_ID_INTEL_STD,
ian@0 928 .NumEraseRegions= 1,
ian@0 929 .regions = {
ian@0 930 ERASEINFO(0x10000, 16),
ian@0 931 }
ian@0 932 }, {
ian@0 933 .mfr_id = MANUFACTURER_INTEL,
ian@0 934 .dev_id = I28F800B3B,
ian@0 935 .name = "Intel 28F800B3B",
ian@0 936 .uaddr = {
ian@0 937 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
ian@0 938 },
ian@0 939 .DevSize = SIZE_1MiB,
ian@0 940 .CmdSet = P_ID_INTEL_STD,
ian@0 941 .NumEraseRegions= 2,
ian@0 942 .regions = {
ian@0 943 ERASEINFO(0x02000, 8),
ian@0 944 ERASEINFO(0x10000, 15),
ian@0 945 }
ian@0 946 }, {
ian@0 947 .mfr_id = MANUFACTURER_INTEL,
ian@0 948 .dev_id = I28F800B3T,
ian@0 949 .name = "Intel 28F800B3T",
ian@0 950 .uaddr = {
ian@0 951 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
ian@0 952 },
ian@0 953 .DevSize = SIZE_1MiB,
ian@0 954 .CmdSet = P_ID_INTEL_STD,
ian@0 955 .NumEraseRegions= 2,
ian@0 956 .regions = {
ian@0 957 ERASEINFO(0x10000, 15),
ian@0 958 ERASEINFO(0x02000, 8),
ian@0 959 }
ian@0 960 }, {
ian@0 961 .mfr_id = MANUFACTURER_INTEL,
ian@0 962 .dev_id = I28F016B3B,
ian@0 963 .name = "Intel 28F016B3B",
ian@0 964 .uaddr = {
ian@0 965 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 966 },
ian@0 967 .DevSize = SIZE_2MiB,
ian@0 968 .CmdSet = P_ID_INTEL_STD,
ian@0 969 .NumEraseRegions= 2,
ian@0 970 .regions = {
ian@0 971 ERASEINFO(0x02000, 8),
ian@0 972 ERASEINFO(0x10000, 31),
ian@0 973 }
ian@0 974 }, {
ian@0 975 .mfr_id = MANUFACTURER_INTEL,
ian@0 976 .dev_id = I28F016S3,
ian@0 977 .name = "Intel I28F016S3",
ian@0 978 .uaddr = {
ian@0 979 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 980 },
ian@0 981 .DevSize = SIZE_2MiB,
ian@0 982 .CmdSet = P_ID_INTEL_STD,
ian@0 983 .NumEraseRegions= 1,
ian@0 984 .regions = {
ian@0 985 ERASEINFO(0x10000, 32),
ian@0 986 }
ian@0 987 }, {
ian@0 988 .mfr_id = MANUFACTURER_INTEL,
ian@0 989 .dev_id = I28F016B3T,
ian@0 990 .name = "Intel 28F016B3T",
ian@0 991 .uaddr = {
ian@0 992 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 993 },
ian@0 994 .DevSize = SIZE_2MiB,
ian@0 995 .CmdSet = P_ID_INTEL_STD,
ian@0 996 .NumEraseRegions= 2,
ian@0 997 .regions = {
ian@0 998 ERASEINFO(0x10000, 31),
ian@0 999 ERASEINFO(0x02000, 8),
ian@0 1000 }
ian@0 1001 }, {
ian@0 1002 .mfr_id = MANUFACTURER_INTEL,
ian@0 1003 .dev_id = I28F160B3B,
ian@0 1004 .name = "Intel 28F160B3B",
ian@0 1005 .uaddr = {
ian@0 1006 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
ian@0 1007 },
ian@0 1008 .DevSize = SIZE_2MiB,
ian@0 1009 .CmdSet = P_ID_INTEL_STD,
ian@0 1010 .NumEraseRegions= 2,
ian@0 1011 .regions = {
ian@0 1012 ERASEINFO(0x02000, 8),
ian@0 1013 ERASEINFO(0x10000, 31),
ian@0 1014 }
ian@0 1015 }, {
ian@0 1016 .mfr_id = MANUFACTURER_INTEL,
ian@0 1017 .dev_id = I28F160B3T,
ian@0 1018 .name = "Intel 28F160B3T",
ian@0 1019 .uaddr = {
ian@0 1020 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
ian@0 1021 },
ian@0 1022 .DevSize = SIZE_2MiB,
ian@0 1023 .CmdSet = P_ID_INTEL_STD,
ian@0 1024 .NumEraseRegions= 2,
ian@0 1025 .regions = {
ian@0 1026 ERASEINFO(0x10000, 31),
ian@0 1027 ERASEINFO(0x02000, 8),
ian@0 1028 }
ian@0 1029 }, {
ian@0 1030 .mfr_id = MANUFACTURER_INTEL,
ian@0 1031 .dev_id = I28F320B3B,
ian@0 1032 .name = "Intel 28F320B3B",
ian@0 1033 .uaddr = {
ian@0 1034 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
ian@0 1035 },
ian@0 1036 .DevSize = SIZE_4MiB,
ian@0 1037 .CmdSet = P_ID_INTEL_STD,
ian@0 1038 .NumEraseRegions= 2,
ian@0 1039 .regions = {
ian@0 1040 ERASEINFO(0x02000, 8),
ian@0 1041 ERASEINFO(0x10000, 63),
ian@0 1042 }
ian@0 1043 }, {
ian@0 1044 .mfr_id = MANUFACTURER_INTEL,
ian@0 1045 .dev_id = I28F320B3T,
ian@0 1046 .name = "Intel 28F320B3T",
ian@0 1047 .uaddr = {
ian@0 1048 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
ian@0 1049 },
ian@0 1050 .DevSize = SIZE_4MiB,
ian@0 1051 .CmdSet = P_ID_INTEL_STD,
ian@0 1052 .NumEraseRegions= 2,
ian@0 1053 .regions = {
ian@0 1054 ERASEINFO(0x10000, 63),
ian@0 1055 ERASEINFO(0x02000, 8),
ian@0 1056 }
ian@0 1057 }, {
ian@0 1058 .mfr_id = MANUFACTURER_INTEL,
ian@0 1059 .dev_id = I28F640B3B,
ian@0 1060 .name = "Intel 28F640B3B",
ian@0 1061 .uaddr = {
ian@0 1062 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
ian@0 1063 },
ian@0 1064 .DevSize = SIZE_8MiB,
ian@0 1065 .CmdSet = P_ID_INTEL_STD,
ian@0 1066 .NumEraseRegions= 2,
ian@0 1067 .regions = {
ian@0 1068 ERASEINFO(0x02000, 8),
ian@0 1069 ERASEINFO(0x10000, 127),
ian@0 1070 }
ian@0 1071 }, {
ian@0 1072 .mfr_id = MANUFACTURER_INTEL,
ian@0 1073 .dev_id = I28F640B3T,
ian@0 1074 .name = "Intel 28F640B3T",
ian@0 1075 .uaddr = {
ian@0 1076 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
ian@0 1077 },
ian@0 1078 .DevSize = SIZE_8MiB,
ian@0 1079 .CmdSet = P_ID_INTEL_STD,
ian@0 1080 .NumEraseRegions= 2,
ian@0 1081 .regions = {
ian@0 1082 ERASEINFO(0x10000, 127),
ian@0 1083 ERASEINFO(0x02000, 8),
ian@0 1084 }
ian@0 1085 }, {
ian@0 1086 .mfr_id = MANUFACTURER_INTEL,
ian@0 1087 .dev_id = I82802AB,
ian@0 1088 .name = "Intel 82802AB",
ian@0 1089 .uaddr = {
ian@0 1090 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 1091 },
ian@0 1092 .DevSize = SIZE_512KiB,
ian@0 1093 .CmdSet = P_ID_INTEL_EXT,
ian@0 1094 .NumEraseRegions= 1,
ian@0 1095 .regions = {
ian@0 1096 ERASEINFO(0x10000,8),
ian@0 1097 }
ian@0 1098 }, {
ian@0 1099 .mfr_id = MANUFACTURER_INTEL,
ian@0 1100 .dev_id = I82802AC,
ian@0 1101 .name = "Intel 82802AC",
ian@0 1102 .uaddr = {
ian@0 1103 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 1104 },
ian@0 1105 .DevSize = SIZE_1MiB,
ian@0 1106 .CmdSet = P_ID_INTEL_EXT,
ian@0 1107 .NumEraseRegions= 1,
ian@0 1108 .regions = {
ian@0 1109 ERASEINFO(0x10000,16),
ian@0 1110 }
ian@0 1111 }, {
ian@0 1112 .mfr_id = MANUFACTURER_MACRONIX,
ian@0 1113 .dev_id = MX29LV040C,
ian@0 1114 .name = "Macronix MX29LV040C",
ian@0 1115 .uaddr = {
ian@0 1116 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
ian@0 1117 },
ian@0 1118 .DevSize = SIZE_512KiB,
ian@0 1119 .CmdSet = P_ID_AMD_STD,
ian@0 1120 .NumEraseRegions= 1,
ian@0 1121 .regions = {
ian@0 1122 ERASEINFO(0x10000,8),
ian@0 1123 }
ian@0 1124 }, {
ian@0 1125 .mfr_id = MANUFACTURER_MACRONIX,
ian@0 1126 .dev_id = MX29LV160T,
ian@0 1127 .name = "MXIC MX29LV160T",
ian@0 1128 .uaddr = {
ian@0 1129 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 1130 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 1131 },
ian@0 1132 .DevSize = SIZE_2MiB,
ian@0 1133 .CmdSet = P_ID_AMD_STD,
ian@0 1134 .NumEraseRegions= 4,
ian@0 1135 .regions = {
ian@0 1136 ERASEINFO(0x10000,31),
ian@0 1137 ERASEINFO(0x08000,1),
ian@0 1138 ERASEINFO(0x02000,2),
ian@0 1139 ERASEINFO(0x04000,1)
ian@0 1140 }
ian@0 1141 }, {
ian@0 1142 .mfr_id = MANUFACTURER_NEC,
ian@0 1143 .dev_id = UPD29F064115,
ian@0 1144 .name = "NEC uPD29F064115",
ian@0 1145 .uaddr = {
ian@0 1146 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
ian@0 1147 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 1148 },
ian@0 1149 .DevSize = SIZE_8MiB,
ian@0 1150 .CmdSet = P_ID_AMD_STD,
ian@0 1151 .NumEraseRegions= 3,
ian@0 1152 .regions = {
ian@0 1153 ERASEINFO(0x2000,8),
ian@0 1154 ERASEINFO(0x10000,126),
ian@0 1155 ERASEINFO(0x2000,8),
ian@0 1156 }
ian@0 1157 }, {
ian@0 1158 .mfr_id = MANUFACTURER_MACRONIX,
ian@0 1159 .dev_id = MX29LV160B,
ian@0 1160 .name = "MXIC MX29LV160B",
ian@0 1161 .uaddr = {
ian@0 1162 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 1163 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 1164 },
ian@0 1165 .DevSize = SIZE_2MiB,
ian@0 1166 .CmdSet = P_ID_AMD_STD,
ian@0 1167 .NumEraseRegions= 4,
ian@0 1168 .regions = {
ian@0 1169 ERASEINFO(0x04000,1),
ian@0 1170 ERASEINFO(0x02000,2),
ian@0 1171 ERASEINFO(0x08000,1),
ian@0 1172 ERASEINFO(0x10000,31)
ian@0 1173 }
ian@0 1174 }, {
ian@0 1175 .mfr_id = MANUFACTURER_MACRONIX,
ian@0 1176 .dev_id = MX29F040,
ian@0 1177 .name = "Macronix MX29F040",
ian@0 1178 .uaddr = {
ian@0 1179 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
ian@0 1180 },
ian@0 1181 .DevSize = SIZE_512KiB,
ian@0 1182 .CmdSet = P_ID_AMD_STD,
ian@0 1183 .NumEraseRegions= 1,
ian@0 1184 .regions = {
ian@0 1185 ERASEINFO(0x10000,8),
ian@0 1186 }
ian@0 1187 }, {
ian@0 1188 .mfr_id = MANUFACTURER_MACRONIX,
ian@0 1189 .dev_id = MX29F016,
ian@0 1190 .name = "Macronix MX29F016",
ian@0 1191 .uaddr = {
ian@0 1192 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
ian@0 1193 },
ian@0 1194 .DevSize = SIZE_2MiB,
ian@0 1195 .CmdSet = P_ID_AMD_STD,
ian@0 1196 .NumEraseRegions= 1,
ian@0 1197 .regions = {
ian@0 1198 ERASEINFO(0x10000,32),
ian@0 1199 }
ian@0 1200 }, {
ian@0 1201 .mfr_id = MANUFACTURER_MACRONIX,
ian@0 1202 .dev_id = MX29F004T,
ian@0 1203 .name = "Macronix MX29F004T",
ian@0 1204 .uaddr = {
ian@0 1205 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
ian@0 1206 },
ian@0 1207 .DevSize = SIZE_512KiB,
ian@0 1208 .CmdSet = P_ID_AMD_STD,
ian@0 1209 .NumEraseRegions= 4,
ian@0 1210 .regions = {
ian@0 1211 ERASEINFO(0x10000,7),
ian@0 1212 ERASEINFO(0x08000,1),
ian@0 1213 ERASEINFO(0x02000,2),
ian@0 1214 ERASEINFO(0x04000,1),
ian@0 1215 }
ian@0 1216 }, {
ian@0 1217 .mfr_id = MANUFACTURER_MACRONIX,
ian@0 1218 .dev_id = MX29F004B,
ian@0 1219 .name = "Macronix MX29F004B",
ian@0 1220 .uaddr = {
ian@0 1221 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
ian@0 1222 },
ian@0 1223 .DevSize = SIZE_512KiB,
ian@0 1224 .CmdSet = P_ID_AMD_STD,
ian@0 1225 .NumEraseRegions= 4,
ian@0 1226 .regions = {
ian@0 1227 ERASEINFO(0x04000,1),
ian@0 1228 ERASEINFO(0x02000,2),
ian@0 1229 ERASEINFO(0x08000,1),
ian@0 1230 ERASEINFO(0x10000,7),
ian@0 1231 }
ian@0 1232 }, {
ian@0 1233 .mfr_id = MANUFACTURER_MACRONIX,
ian@0 1234 .dev_id = MX29F002T,
ian@0 1235 .name = "Macronix MX29F002T",
ian@0 1236 .uaddr = {
ian@0 1237 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
ian@0 1238 },
ian@0 1239 .DevSize = SIZE_256KiB,
ian@0 1240 .CmdSet = P_ID_AMD_STD,
ian@0 1241 .NumEraseRegions= 4,
ian@0 1242 .regions = {
ian@0 1243 ERASEINFO(0x10000,3),
ian@0 1244 ERASEINFO(0x08000,1),
ian@0 1245 ERASEINFO(0x02000,2),
ian@0 1246 ERASEINFO(0x04000,1),
ian@0 1247 }
ian@0 1248 }, {
ian@0 1249 .mfr_id = MANUFACTURER_PMC,
ian@0 1250 .dev_id = PM49FL002,
ian@0 1251 .name = "PMC Pm49FL002",
ian@0 1252 .uaddr = {
ian@0 1253 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1254 },
ian@0 1255 .DevSize = SIZE_256KiB,
ian@0 1256 .CmdSet = P_ID_AMD_STD,
ian@0 1257 .NumEraseRegions= 1,
ian@0 1258 .regions = {
ian@0 1259 ERASEINFO( 0x01000, 64 )
ian@0 1260 }
ian@0 1261 }, {
ian@0 1262 .mfr_id = MANUFACTURER_PMC,
ian@0 1263 .dev_id = PM49FL004,
ian@0 1264 .name = "PMC Pm49FL004",
ian@0 1265 .uaddr = {
ian@0 1266 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1267 },
ian@0 1268 .DevSize = SIZE_512KiB,
ian@0 1269 .CmdSet = P_ID_AMD_STD,
ian@0 1270 .NumEraseRegions= 1,
ian@0 1271 .regions = {
ian@0 1272 ERASEINFO( 0x01000, 128 )
ian@0 1273 }
ian@0 1274 }, {
ian@0 1275 .mfr_id = MANUFACTURER_PMC,
ian@0 1276 .dev_id = PM49FL008,
ian@0 1277 .name = "PMC Pm49FL008",
ian@0 1278 .uaddr = {
ian@0 1279 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1280 },
ian@0 1281 .DevSize = SIZE_1MiB,
ian@0 1282 .CmdSet = P_ID_AMD_STD,
ian@0 1283 .NumEraseRegions= 1,
ian@0 1284 .regions = {
ian@0 1285 ERASEINFO( 0x01000, 256 )
ian@0 1286 }
ian@0 1287 }, {
ian@0 1288 .mfr_id = MANUFACTURER_SHARP,
ian@0 1289 .dev_id = LH28F640BF,
ian@0 1290 .name = "LH28F640BF",
ian@0 1291 .uaddr = {
ian@0 1292 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 1293 },
ian@0 1294 .DevSize = SIZE_4MiB,
ian@0 1295 .CmdSet = P_ID_INTEL_STD,
ian@0 1296 .NumEraseRegions= 1,
ian@0 1297 .regions = {
ian@0 1298 ERASEINFO(0x40000,16),
ian@0 1299 }
ian@0 1300 }, {
ian@0 1301 .mfr_id = MANUFACTURER_SST,
ian@0 1302 .dev_id = SST39LF512,
ian@0 1303 .name = "SST 39LF512",
ian@0 1304 .uaddr = {
ian@0 1305 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1306 },
ian@0 1307 .DevSize = SIZE_64KiB,
ian@0 1308 .CmdSet = P_ID_AMD_STD,
ian@0 1309 .NumEraseRegions= 1,
ian@0 1310 .regions = {
ian@0 1311 ERASEINFO(0x01000,16),
ian@0 1312 }
ian@0 1313 }, {
ian@0 1314 .mfr_id = MANUFACTURER_SST,
ian@0 1315 .dev_id = SST39LF010,
ian@0 1316 .name = "SST 39LF010",
ian@0 1317 .uaddr = {
ian@0 1318 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1319 },
ian@0 1320 .DevSize = SIZE_128KiB,
ian@0 1321 .CmdSet = P_ID_AMD_STD,
ian@0 1322 .NumEraseRegions= 1,
ian@0 1323 .regions = {
ian@0 1324 ERASEINFO(0x01000,32),
ian@0 1325 }
ian@0 1326 }, {
ian@0 1327 .mfr_id = MANUFACTURER_SST,
ian@0 1328 .dev_id = SST29EE020,
ian@0 1329 .name = "SST 29EE020",
ian@0 1330 .uaddr = {
ian@0 1331 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1332 },
ian@0 1333 .DevSize = SIZE_256KiB,
ian@0 1334 .CmdSet = P_ID_SST_PAGE,
ian@0 1335 .NumEraseRegions= 1,
ian@0 1336 .regions = {ERASEINFO(0x01000,64),
ian@0 1337 }
ian@0 1338 }, {
ian@0 1339 .mfr_id = MANUFACTURER_SST,
ian@0 1340 .dev_id = SST29LE020,
ian@0 1341 .name = "SST 29LE020",
ian@0 1342 .uaddr = {
ian@0 1343 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1344 },
ian@0 1345 .DevSize = SIZE_256KiB,
ian@0 1346 .CmdSet = P_ID_SST_PAGE,
ian@0 1347 .NumEraseRegions= 1,
ian@0 1348 .regions = {ERASEINFO(0x01000,64),
ian@0 1349 }
ian@0 1350 }, {
ian@0 1351 .mfr_id = MANUFACTURER_SST,
ian@0 1352 .dev_id = SST39LF020,
ian@0 1353 .name = "SST 39LF020",
ian@0 1354 .uaddr = {
ian@0 1355 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1356 },
ian@0 1357 .DevSize = SIZE_256KiB,
ian@0 1358 .CmdSet = P_ID_AMD_STD,
ian@0 1359 .NumEraseRegions= 1,
ian@0 1360 .regions = {
ian@0 1361 ERASEINFO(0x01000,64),
ian@0 1362 }
ian@0 1363 }, {
ian@0 1364 .mfr_id = MANUFACTURER_SST,
ian@0 1365 .dev_id = SST39LF040,
ian@0 1366 .name = "SST 39LF040",
ian@0 1367 .uaddr = {
ian@0 1368 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1369 },
ian@0 1370 .DevSize = SIZE_512KiB,
ian@0 1371 .CmdSet = P_ID_AMD_STD,
ian@0 1372 .NumEraseRegions= 1,
ian@0 1373 .regions = {
ian@0 1374 ERASEINFO(0x01000,128),
ian@0 1375 }
ian@0 1376 }, {
ian@0 1377 .mfr_id = MANUFACTURER_SST,
ian@0 1378 .dev_id = SST39SF010A,
ian@0 1379 .name = "SST 39SF010A",
ian@0 1380 .uaddr = {
ian@0 1381 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1382 },
ian@0 1383 .DevSize = SIZE_128KiB,
ian@0 1384 .CmdSet = P_ID_AMD_STD,
ian@0 1385 .NumEraseRegions= 1,
ian@0 1386 .regions = {
ian@0 1387 ERASEINFO(0x01000,32),
ian@0 1388 }
ian@0 1389 }, {
ian@0 1390 .mfr_id = MANUFACTURER_SST,
ian@0 1391 .dev_id = SST39SF020A,
ian@0 1392 .name = "SST 39SF020A",
ian@0 1393 .uaddr = {
ian@0 1394 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1395 },
ian@0 1396 .DevSize = SIZE_256KiB,
ian@0 1397 .CmdSet = P_ID_AMD_STD,
ian@0 1398 .NumEraseRegions= 1,
ian@0 1399 .regions = {
ian@0 1400 ERASEINFO(0x01000,64),
ian@0 1401 }
ian@0 1402 }, {
ian@0 1403 .mfr_id = MANUFACTURER_SST,
ian@0 1404 .dev_id = SST49LF004B,
ian@0 1405 .name = "SST 49LF004B",
ian@0 1406 .uaddr = {
ian@0 1407 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1408 },
ian@0 1409 .DevSize = SIZE_512KiB,
ian@0 1410 .CmdSet = P_ID_AMD_STD,
ian@0 1411 .NumEraseRegions= 1,
ian@0 1412 .regions = {
ian@0 1413 ERASEINFO(0x01000,128),
ian@0 1414 }
ian@0 1415 }, {
ian@0 1416 .mfr_id = MANUFACTURER_SST,
ian@0 1417 .dev_id = SST49LF008A,
ian@0 1418 .name = "SST 49LF008A",
ian@0 1419 .uaddr = {
ian@0 1420 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1421 },
ian@0 1422 .DevSize = SIZE_1MiB,
ian@0 1423 .CmdSet = P_ID_AMD_STD,
ian@0 1424 .NumEraseRegions= 1,
ian@0 1425 .regions = {
ian@0 1426 ERASEINFO(0x01000,256),
ian@0 1427 }
ian@0 1428 }, {
ian@0 1429 .mfr_id = MANUFACTURER_SST,
ian@0 1430 .dev_id = SST49LF030A,
ian@0 1431 .name = "SST 49LF030A",
ian@0 1432 .uaddr = {
ian@0 1433 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1434 },
ian@0 1435 .DevSize = SIZE_512KiB,
ian@0 1436 .CmdSet = P_ID_AMD_STD,
ian@0 1437 .NumEraseRegions= 1,
ian@0 1438 .regions = {
ian@0 1439 ERASEINFO(0x01000,96),
ian@0 1440 }
ian@0 1441 }, {
ian@0 1442 .mfr_id = MANUFACTURER_SST,
ian@0 1443 .dev_id = SST49LF040A,
ian@0 1444 .name = "SST 49LF040A",
ian@0 1445 .uaddr = {
ian@0 1446 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1447 },
ian@0 1448 .DevSize = SIZE_512KiB,
ian@0 1449 .CmdSet = P_ID_AMD_STD,
ian@0 1450 .NumEraseRegions= 1,
ian@0 1451 .regions = {
ian@0 1452 ERASEINFO(0x01000,128),
ian@0 1453 }
ian@0 1454 }, {
ian@0 1455 .mfr_id = MANUFACTURER_SST,
ian@0 1456 .dev_id = SST49LF080A,
ian@0 1457 .name = "SST 49LF080A",
ian@0 1458 .uaddr = {
ian@0 1459 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1460 },
ian@0 1461 .DevSize = SIZE_1MiB,
ian@0 1462 .CmdSet = P_ID_AMD_STD,
ian@0 1463 .NumEraseRegions= 1,
ian@0 1464 .regions = {
ian@0 1465 ERASEINFO(0x01000,256),
ian@0 1466 }
ian@0 1467 }, {
ian@0 1468 .mfr_id = MANUFACTURER_SST, /* should be CFI */
ian@0 1469 .dev_id = SST39LF160,
ian@0 1470 .name = "SST 39LF160",
ian@0 1471 .uaddr = {
ian@0 1472 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
ian@0 1473 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
ian@0 1474 },
ian@0 1475 .DevSize = SIZE_2MiB,
ian@0 1476 .CmdSet = P_ID_AMD_STD,
ian@0 1477 .NumEraseRegions= 2,
ian@0 1478 .regions = {
ian@0 1479 ERASEINFO(0x1000,256),
ian@0 1480 ERASEINFO(0x1000,256)
ian@0 1481 }
ian@0 1482 }, {
ian@0 1483 .mfr_id = MANUFACTURER_SST, /* should be CFI */
ian@0 1484 .dev_id = SST39VF1601,
ian@0 1485 .name = "SST 39VF1601",
ian@0 1486 .uaddr = {
ian@0 1487 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
ian@0 1488 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
ian@0 1489 },
ian@0 1490 .DevSize = SIZE_2MiB,
ian@0 1491 .CmdSet = P_ID_AMD_STD,
ian@0 1492 .NumEraseRegions= 2,
ian@0 1493 .regions = {
ian@0 1494 ERASEINFO(0x1000,256),
ian@0 1495 ERASEINFO(0x1000,256)
ian@0 1496 }
ian@0 1497
ian@0 1498 }, {
ian@0 1499 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
ian@0 1500 .dev_id = M29W800DT,
ian@0 1501 .name = "ST M29W800DT",
ian@0 1502 .uaddr = {
ian@0 1503 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
ian@0 1504 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
ian@0 1505 },
ian@0 1506 .DevSize = SIZE_1MiB,
ian@0 1507 .CmdSet = P_ID_AMD_STD,
ian@0 1508 .NumEraseRegions= 4,
ian@0 1509 .regions = {
ian@0 1510 ERASEINFO(0x10000,15),
ian@0 1511 ERASEINFO(0x08000,1),
ian@0 1512 ERASEINFO(0x02000,2),
ian@0 1513 ERASEINFO(0x04000,1)
ian@0 1514 }
ian@0 1515 }, {
ian@0 1516 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
ian@0 1517 .dev_id = M29W800DB,
ian@0 1518 .name = "ST M29W800DB",
ian@0 1519 .uaddr = {
ian@0 1520 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
ian@0 1521 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
ian@0 1522 },
ian@0 1523 .DevSize = SIZE_1MiB,
ian@0 1524 .CmdSet = P_ID_AMD_STD,
ian@0 1525 .NumEraseRegions= 4,
ian@0 1526 .regions = {
ian@0 1527 ERASEINFO(0x04000,1),
ian@0 1528 ERASEINFO(0x02000,2),
ian@0 1529 ERASEINFO(0x08000,1),
ian@0 1530 ERASEINFO(0x10000,15)
ian@0 1531 }
ian@0 1532 }, {
ian@0 1533 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
ian@0 1534 .dev_id = M29W160DT,
ian@0 1535 .name = "ST M29W160DT",
ian@0 1536 .uaddr = {
ian@0 1537 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
ian@0 1538 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 1539 },
ian@0 1540 .DevSize = SIZE_2MiB,
ian@0 1541 .CmdSet = P_ID_AMD_STD,
ian@0 1542 .NumEraseRegions= 4,
ian@0 1543 .regions = {
ian@0 1544 ERASEINFO(0x10000,31),
ian@0 1545 ERASEINFO(0x08000,1),
ian@0 1546 ERASEINFO(0x02000,2),
ian@0 1547 ERASEINFO(0x04000,1)
ian@0 1548 }
ian@0 1549 }, {
ian@0 1550 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
ian@0 1551 .dev_id = M29W160DB,
ian@0 1552 .name = "ST M29W160DB",
ian@0 1553 .uaddr = {
ian@0 1554 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
ian@0 1555 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 1556 },
ian@0 1557 .DevSize = SIZE_2MiB,
ian@0 1558 .CmdSet = P_ID_AMD_STD,
ian@0 1559 .NumEraseRegions= 4,
ian@0 1560 .regions = {
ian@0 1561 ERASEINFO(0x04000,1),
ian@0 1562 ERASEINFO(0x02000,2),
ian@0 1563 ERASEINFO(0x08000,1),
ian@0 1564 ERASEINFO(0x10000,31)
ian@0 1565 }
ian@0 1566 }, {
ian@0 1567 .mfr_id = MANUFACTURER_ST,
ian@0 1568 .dev_id = M29W040B,
ian@0 1569 .name = "ST M29W040B",
ian@0 1570 .uaddr = {
ian@0 1571 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
ian@0 1572 },
ian@0 1573 .DevSize = SIZE_512KiB,
ian@0 1574 .CmdSet = P_ID_AMD_STD,
ian@0 1575 .NumEraseRegions= 1,
ian@0 1576 .regions = {
ian@0 1577 ERASEINFO(0x10000,8),
ian@0 1578 }
ian@0 1579 }, {
ian@0 1580 .mfr_id = MANUFACTURER_ST,
ian@0 1581 .dev_id = M50FW040,
ian@0 1582 .name = "ST M50FW040",
ian@0 1583 .uaddr = {
ian@0 1584 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 1585 },
ian@0 1586 .DevSize = SIZE_512KiB,
ian@0 1587 .CmdSet = P_ID_INTEL_EXT,
ian@0 1588 .NumEraseRegions= 1,
ian@0 1589 .regions = {
ian@0 1590 ERASEINFO(0x10000,8),
ian@0 1591 }
ian@0 1592 }, {
ian@0 1593 .mfr_id = MANUFACTURER_ST,
ian@0 1594 .dev_id = M50FW080,
ian@0 1595 .name = "ST M50FW080",
ian@0 1596 .uaddr = {
ian@0 1597 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 1598 },
ian@0 1599 .DevSize = SIZE_1MiB,
ian@0 1600 .CmdSet = P_ID_INTEL_EXT,
ian@0 1601 .NumEraseRegions= 1,
ian@0 1602 .regions = {
ian@0 1603 ERASEINFO(0x10000,16),
ian@0 1604 }
ian@0 1605 }, {
ian@0 1606 .mfr_id = MANUFACTURER_ST,
ian@0 1607 .dev_id = M50FW016,
ian@0 1608 .name = "ST M50FW016",
ian@0 1609 .uaddr = {
ian@0 1610 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 1611 },
ian@0 1612 .DevSize = SIZE_2MiB,
ian@0 1613 .CmdSet = P_ID_INTEL_EXT,
ian@0 1614 .NumEraseRegions= 1,
ian@0 1615 .regions = {
ian@0 1616 ERASEINFO(0x10000,32),
ian@0 1617 }
ian@0 1618 }, {
ian@0 1619 .mfr_id = MANUFACTURER_ST,
ian@0 1620 .dev_id = M50LPW080,
ian@0 1621 .name = "ST M50LPW080",
ian@0 1622 .uaddr = {
ian@0 1623 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
ian@0 1624 },
ian@0 1625 .DevSize = SIZE_1MiB,
ian@0 1626 .CmdSet = P_ID_INTEL_EXT,
ian@0 1627 .NumEraseRegions= 1,
ian@0 1628 .regions = {
ian@0 1629 ERASEINFO(0x10000,16),
ian@0 1630 }
ian@0 1631 }, {
ian@0 1632 .mfr_id = MANUFACTURER_TOSHIBA,
ian@0 1633 .dev_id = TC58FVT160,
ian@0 1634 .name = "Toshiba TC58FVT160",
ian@0 1635 .uaddr = {
ian@0 1636 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 1637 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
ian@0 1638 },
ian@0 1639 .DevSize = SIZE_2MiB,
ian@0 1640 .CmdSet = P_ID_AMD_STD,
ian@0 1641 .NumEraseRegions= 4,
ian@0 1642 .regions = {
ian@0 1643 ERASEINFO(0x10000,31),
ian@0 1644 ERASEINFO(0x08000,1),
ian@0 1645 ERASEINFO(0x02000,2),
ian@0 1646 ERASEINFO(0x04000,1)
ian@0 1647 }
ian@0 1648 }, {
ian@0 1649 .mfr_id = MANUFACTURER_TOSHIBA,
ian@0 1650 .dev_id = TC58FVB160,
ian@0 1651 .name = "Toshiba TC58FVB160",
ian@0 1652 .uaddr = {
ian@0 1653 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 1654 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
ian@0 1655 },
ian@0 1656 .DevSize = SIZE_2MiB,
ian@0 1657 .CmdSet = P_ID_AMD_STD,
ian@0 1658 .NumEraseRegions= 4,
ian@0 1659 .regions = {
ian@0 1660 ERASEINFO(0x04000,1),
ian@0 1661 ERASEINFO(0x02000,2),
ian@0 1662 ERASEINFO(0x08000,1),
ian@0 1663 ERASEINFO(0x10000,31)
ian@0 1664 }
ian@0 1665 }, {
ian@0 1666 .mfr_id = MANUFACTURER_TOSHIBA,
ian@0 1667 .dev_id = TC58FVB321,
ian@0 1668 .name = "Toshiba TC58FVB321",
ian@0 1669 .uaddr = {
ian@0 1670 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 1671 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
ian@0 1672 },
ian@0 1673 .DevSize = SIZE_4MiB,
ian@0 1674 .CmdSet = P_ID_AMD_STD,
ian@0 1675 .NumEraseRegions= 2,
ian@0 1676 .regions = {
ian@0 1677 ERASEINFO(0x02000,8),
ian@0 1678 ERASEINFO(0x10000,63)
ian@0 1679 }
ian@0 1680 }, {
ian@0 1681 .mfr_id = MANUFACTURER_TOSHIBA,
ian@0 1682 .dev_id = TC58FVT321,
ian@0 1683 .name = "Toshiba TC58FVT321",
ian@0 1684 .uaddr = {
ian@0 1685 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 1686 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
ian@0 1687 },
ian@0 1688 .DevSize = SIZE_4MiB,
ian@0 1689 .CmdSet = P_ID_AMD_STD,
ian@0 1690 .NumEraseRegions= 2,
ian@0 1691 .regions = {
ian@0 1692 ERASEINFO(0x10000,63),
ian@0 1693 ERASEINFO(0x02000,8)
ian@0 1694 }
ian@0 1695 }, {
ian@0 1696 .mfr_id = MANUFACTURER_TOSHIBA,
ian@0 1697 .dev_id = TC58FVB641,
ian@0 1698 .name = "Toshiba TC58FVB641",
ian@0 1699 .uaddr = {
ian@0 1700 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 1701 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 1702 },
ian@0 1703 .DevSize = SIZE_8MiB,
ian@0 1704 .CmdSet = P_ID_AMD_STD,
ian@0 1705 .NumEraseRegions= 2,
ian@0 1706 .regions = {
ian@0 1707 ERASEINFO(0x02000,8),
ian@0 1708 ERASEINFO(0x10000,127)
ian@0 1709 }
ian@0 1710 }, {
ian@0 1711 .mfr_id = MANUFACTURER_TOSHIBA,
ian@0 1712 .dev_id = TC58FVT641,
ian@0 1713 .name = "Toshiba TC58FVT641",
ian@0 1714 .uaddr = {
ian@0 1715 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
ian@0 1716 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
ian@0 1717 },
ian@0 1718 .DevSize = SIZE_8MiB,
ian@0 1719 .CmdSet = P_ID_AMD_STD,
ian@0 1720 .NumEraseRegions= 2,
ian@0 1721 .regions = {
ian@0 1722 ERASEINFO(0x10000,127),
ian@0 1723 ERASEINFO(0x02000,8)
ian@0 1724 }
ian@0 1725 }, {
ian@0 1726 .mfr_id = MANUFACTURER_WINBOND,
ian@0 1727 .dev_id = W49V002A,
ian@0 1728 .name = "Winbond W49V002A",
ian@0 1729 .uaddr = {
ian@0 1730 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
ian@0 1731 },
ian@0 1732 .DevSize = SIZE_256KiB,
ian@0 1733 .CmdSet = P_ID_AMD_STD,
ian@0 1734 .NumEraseRegions= 4,
ian@0 1735 .regions = {
ian@0 1736 ERASEINFO(0x10000, 3),
ian@0 1737 ERASEINFO(0x08000, 1),
ian@0 1738 ERASEINFO(0x02000, 2),
ian@0 1739 ERASEINFO(0x04000, 1),
ian@0 1740 }
ian@0 1741 }
ian@0 1742 };
ian@0 1743
ian@0 1744
ian@0 1745 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index);
ian@0 1746
ian@0 1747 static int jedec_probe_chip(struct map_info *map, __u32 base,
ian@0 1748 unsigned long *chip_map, struct cfi_private *cfi);
ian@0 1749
ian@0 1750 static struct mtd_info *jedec_probe(struct map_info *map);
ian@0 1751
ian@0 1752 static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
ian@0 1753 struct cfi_private *cfi)
ian@0 1754 {
ian@0 1755 map_word result;
ian@0 1756 unsigned long mask;
ian@0 1757 u32 ofs = cfi_build_cmd_addr(0, cfi_interleave(cfi), cfi->device_type);
ian@0 1758 mask = (1 << (cfi->device_type * 8)) -1;
ian@0 1759 result = map_read(map, base + ofs);
ian@0 1760 return result.x[0] & mask;
ian@0 1761 }
ian@0 1762
ian@0 1763 static inline u32 jedec_read_id(struct map_info *map, __u32 base,
ian@0 1764 struct cfi_private *cfi)
ian@0 1765 {
ian@0 1766 map_word result;
ian@0 1767 unsigned long mask;
ian@0 1768 u32 ofs = cfi_build_cmd_addr(1, cfi_interleave(cfi), cfi->device_type);
ian@0 1769 mask = (1 << (cfi->device_type * 8)) -1;
ian@0 1770 result = map_read(map, base + ofs);
ian@0 1771 return result.x[0] & mask;
ian@0 1772 }
ian@0 1773
ian@0 1774 static inline void jedec_reset(u32 base, struct map_info *map,
ian@0 1775 struct cfi_private *cfi)
ian@0 1776 {
ian@0 1777 /* Reset */
ian@0 1778
ian@0 1779 /* after checking the datasheets for SST, MACRONIX and ATMEL
ian@0 1780 * (oh and incidentaly the jedec spec - 3.5.3.3) the reset
ian@0 1781 * sequence is *supposed* to be 0xaa at 0x5555, 0x55 at
ian@0 1782 * 0x2aaa, 0xF0 at 0x5555 this will not affect the AMD chips
ian@0 1783 * as they will ignore the writes and dont care what address
ian@0 1784 * the F0 is written to */
ian@0 1785 if(cfi->addr_unlock1) {
ian@0 1786 DEBUG( MTD_DEBUG_LEVEL3,
ian@0 1787 "reset unlock called %x %x \n",
ian@0 1788 cfi->addr_unlock1,cfi->addr_unlock2);
ian@0 1789 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
ian@0 1790 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
ian@0 1791 }
ian@0 1792
ian@0 1793 cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
ian@0 1794 /* Some misdesigned intel chips do not respond for 0xF0 for a reset,
ian@0 1795 * so ensure we're in read mode. Send both the Intel and the AMD command
ian@0 1796 * for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so
ian@0 1797 * this should be safe.
ian@0 1798 */
ian@0 1799 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
ian@0 1800 /* FIXME - should have reset delay before continuing */
ian@0 1801 }
ian@0 1802
ian@0 1803
ian@0 1804 static inline __u8 finfo_uaddr(const struct amd_flash_info *finfo, int device_type)
ian@0 1805 {
ian@0 1806 int uaddr_idx;
ian@0 1807 __u8 uaddr = MTD_UADDR_NOT_SUPPORTED;
ian@0 1808
ian@0 1809 switch ( device_type ) {
ian@0 1810 case CFI_DEVICETYPE_X8: uaddr_idx = 0; break;
ian@0 1811 case CFI_DEVICETYPE_X16: uaddr_idx = 1; break;
ian@0 1812 case CFI_DEVICETYPE_X32: uaddr_idx = 2; break;
ian@0 1813 default:
ian@0 1814 printk(KERN_NOTICE "MTD: %s(): unknown device_type %d\n",
ian@0 1815 __func__, device_type);
ian@0 1816 goto uaddr_done;
ian@0 1817 }
ian@0 1818
ian@0 1819 uaddr = finfo->uaddr[uaddr_idx];
ian@0 1820
ian@0 1821 if (uaddr != MTD_UADDR_NOT_SUPPORTED ) {
ian@0 1822 /* ASSERT("The unlock addresses for non-8-bit mode
ian@0 1823 are bollocks. We don't really need an array."); */
ian@0 1824 uaddr = finfo->uaddr[0];
ian@0 1825 }
ian@0 1826
ian@0 1827 uaddr_done:
ian@0 1828 return uaddr;
ian@0 1829 }
ian@0 1830
ian@0 1831
ian@0 1832 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
ian@0 1833 {
ian@0 1834 int i,num_erase_regions;
ian@0 1835 __u8 uaddr;
ian@0 1836
ian@0 1837 printk("Found: %s\n",jedec_table[index].name);
ian@0 1838
ian@0 1839 num_erase_regions = jedec_table[index].NumEraseRegions;
ian@0 1840
ian@0 1841 p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
ian@0 1842 if (!p_cfi->cfiq) {
ian@0 1843 //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
ian@0 1844 return 0;
ian@0 1845 }
ian@0 1846
ian@0 1847 memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));
ian@0 1848
ian@0 1849 p_cfi->cfiq->P_ID = jedec_table[index].CmdSet;
ian@0 1850 p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
ian@0 1851 p_cfi->cfiq->DevSize = jedec_table[index].DevSize;
ian@0 1852 p_cfi->cfi_mode = CFI_MODE_JEDEC;
ian@0 1853
ian@0 1854 for (i=0; i<num_erase_regions; i++){
ian@0 1855 p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
ian@0 1856 }
ian@0 1857 p_cfi->cmdset_priv = NULL;
ian@0 1858
ian@0 1859 /* This may be redundant for some cases, but it doesn't hurt */
ian@0 1860 p_cfi->mfr = jedec_table[index].mfr_id;
ian@0 1861 p_cfi->id = jedec_table[index].dev_id;
ian@0 1862
ian@0 1863 uaddr = finfo_uaddr(&jedec_table[index], p_cfi->device_type);
ian@0 1864 if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) {
ian@0 1865 kfree( p_cfi->cfiq );
ian@0 1866 return 0;
ian@0 1867 }
ian@0 1868
ian@0 1869 p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1;
ian@0 1870 p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2;
ian@0 1871
ian@0 1872 return 1; /* ok */
ian@0 1873 }
ian@0 1874
ian@0 1875
ian@0 1876 /*
ian@0 1877 * There is a BIG problem properly ID'ing the JEDEC devic and guaranteeing
ian@0 1878 * the mapped address, unlock addresses, and proper chip ID. This function
ian@0 1879 * attempts to minimize errors. It is doubtfull that this probe will ever
ian@0 1880 * be perfect - consequently there should be some module parameters that
ian@0 1881 * could be manually specified to force the chip info.
ian@0 1882 */
ian@0 1883 static inline int jedec_match( __u32 base,
ian@0 1884 struct map_info *map,
ian@0 1885 struct cfi_private *cfi,
ian@0 1886 const struct amd_flash_info *finfo )
ian@0 1887 {
ian@0 1888 int rc = 0; /* failure until all tests pass */
ian@0 1889 u32 mfr, id;
ian@0 1890 __u8 uaddr;
ian@0 1891
ian@0 1892 /*
ian@0 1893 * The IDs must match. For X16 and X32 devices operating in
ian@0 1894 * a lower width ( X8 or X16 ), the device ID's are usually just
ian@0 1895 * the lower byte(s) of the larger device ID for wider mode. If
ian@0 1896 * a part is found that doesn't fit this assumption (device id for
ian@0 1897 * smaller width mode is completely unrealated to full-width mode)
ian@0 1898 * then the jedec_table[] will have to be augmented with the IDs
ian@0 1899 * for different widths.
ian@0 1900 */
ian@0 1901 switch (cfi->device_type) {
ian@0 1902 case CFI_DEVICETYPE_X8:
ian@0 1903 mfr = (__u8)finfo->mfr_id;
ian@0 1904 id = (__u8)finfo->dev_id;
ian@0 1905
ian@0 1906 /* bjd: it seems that if we do this, we can end up
ian@0 1907 * detecting 16bit flashes as an 8bit device, even though
ian@0 1908 * there aren't.
ian@0 1909 */
ian@0 1910 if (finfo->dev_id > 0xff) {
ian@0 1911 DEBUG( MTD_DEBUG_LEVEL3, "%s(): ID is not 8bit\n",
ian@0 1912 __func__);
ian@0 1913 goto match_done;
ian@0 1914 }
ian@0 1915 break;
ian@0 1916 case CFI_DEVICETYPE_X16:
ian@0 1917 mfr = (__u16)finfo->mfr_id;
ian@0 1918 id = (__u16)finfo->dev_id;
ian@0 1919 break;
ian@0 1920 case CFI_DEVICETYPE_X32:
ian@0 1921 mfr = (__u16)finfo->mfr_id;
ian@0 1922 id = (__u32)finfo->dev_id;
ian@0 1923 break;
ian@0 1924 default:
ian@0 1925 printk(KERN_WARNING
ian@0 1926 "MTD %s(): Unsupported device type %d\n",
ian@0 1927 __func__, cfi->device_type);
ian@0 1928 goto match_done;
ian@0 1929 }
ian@0 1930 if ( cfi->mfr != mfr || cfi->id != id ) {
ian@0 1931 goto match_done;
ian@0 1932 }
ian@0 1933
ian@0 1934 /* the part size must fit in the memory window */
ian@0 1935 DEBUG( MTD_DEBUG_LEVEL3,
ian@0 1936 "MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
ian@0 1937 __func__, base, 1 << finfo->DevSize, base + (1 << finfo->DevSize) );
ian@0 1938 if ( base + cfi_interleave(cfi) * ( 1 << finfo->DevSize ) > map->size ) {
ian@0 1939 DEBUG( MTD_DEBUG_LEVEL3,
ian@0 1940 "MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
ian@0 1941 __func__, finfo->mfr_id, finfo->dev_id,
ian@0 1942 1 << finfo->DevSize );
ian@0 1943 goto match_done;
ian@0 1944 }
ian@0 1945
ian@0 1946 uaddr = finfo_uaddr(finfo, cfi->device_type);
ian@0 1947 if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) {
ian@0 1948 goto match_done;
ian@0 1949 }
ian@0 1950
ian@0 1951 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
ian@0 1952 __func__, cfi->addr_unlock1, cfi->addr_unlock2 );
ian@0 1953 if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr
ian@0 1954 && ( unlock_addrs[uaddr].addr1 != cfi->addr_unlock1 ||
ian@0 1955 unlock_addrs[uaddr].addr2 != cfi->addr_unlock2 ) ) {
ian@0 1956 DEBUG( MTD_DEBUG_LEVEL3,
ian@0 1957 "MTD %s(): 0x%.4x 0x%.4x did not match\n",
ian@0 1958 __func__,
ian@0 1959 unlock_addrs[uaddr].addr1,
ian@0 1960 unlock_addrs[uaddr].addr2);
ian@0 1961 goto match_done;
ian@0 1962 }
ian@0 1963
ian@0 1964 /*
ian@0 1965 * Make sure the ID's dissappear when the device is taken out of
ian@0 1966 * ID mode. The only time this should fail when it should succeed
ian@0 1967 * is when the ID's are written as data to the same
ian@0 1968 * addresses. For this rare and unfortunate case the chip
ian@0 1969 * cannot be probed correctly.
ian@0 1970 * FIXME - write a driver that takes all of the chip info as
ian@0 1971 * module parameters, doesn't probe but forces a load.
ian@0 1972 */
ian@0 1973 DEBUG( MTD_DEBUG_LEVEL3,
ian@0 1974 "MTD %s(): check ID's disappear when not in ID mode\n",
ian@0 1975 __func__ );
ian@0 1976 jedec_reset( base, map, cfi );
ian@0 1977 mfr = jedec_read_mfr( map, base, cfi );
ian@0 1978 id = jedec_read_id( map, base, cfi );
ian@0 1979 if ( mfr == cfi->mfr && id == cfi->id ) {
ian@0 1980 DEBUG( MTD_DEBUG_LEVEL3,
ian@0 1981 "MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
ian@0 1982 "You might need to manually specify JEDEC parameters.\n",
ian@0 1983 __func__, cfi->mfr, cfi->id );
ian@0 1984 goto match_done;
ian@0 1985 }
ian@0 1986
ian@0 1987 /* all tests passed - mark as success */
ian@0 1988 rc = 1;
ian@0 1989
ian@0 1990 /*
ian@0 1991 * Put the device back in ID mode - only need to do this if we
ian@0 1992 * were truly frobbing a real device.
ian@0 1993 */
ian@0 1994 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ );
ian@0 1995 if(cfi->addr_unlock1) {
ian@0 1996 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
ian@0 1997 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
ian@0 1998 }
ian@0 1999 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
ian@0 2000 /* FIXME - should have a delay before continuing */
ian@0 2001
ian@0 2002 match_done:
ian@0 2003 return rc;
ian@0 2004 }
ian@0 2005
ian@0 2006
ian@0 2007 static int jedec_probe_chip(struct map_info *map, __u32 base,
ian@0 2008 unsigned long *chip_map, struct cfi_private *cfi)
ian@0 2009 {
ian@0 2010 int i;
ian@0 2011 enum uaddr uaddr_idx = MTD_UADDR_NOT_SUPPORTED;
ian@0 2012 u32 probe_offset1, probe_offset2;
ian@0 2013
ian@0 2014 retry:
ian@0 2015 if (!cfi->numchips) {
ian@0 2016 uaddr_idx++;
ian@0 2017
ian@0 2018 if (MTD_UADDR_UNNECESSARY == uaddr_idx)
ian@0 2019 return 0;
ian@0 2020
ian@0 2021 cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1;
ian@0 2022 cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2;
ian@0 2023 }
ian@0 2024
ian@0 2025 /* Make certain we aren't probing past the end of map */
ian@0 2026 if (base >= map->size) {
ian@0 2027 printk(KERN_NOTICE
ian@0 2028 "Probe at base(0x%08x) past the end of the map(0x%08lx)\n",
ian@0 2029 base, map->size -1);
ian@0 2030 return 0;
ian@0 2031
ian@0 2032 }
ian@0 2033 /* Ensure the unlock addresses we try stay inside the map */
ian@0 2034 probe_offset1 = cfi_build_cmd_addr(
ian@0 2035 cfi->addr_unlock1,
ian@0 2036 cfi_interleave(cfi),
ian@0 2037 cfi->device_type);
ian@0 2038 probe_offset2 = cfi_build_cmd_addr(
ian@0 2039 cfi->addr_unlock1,
ian@0 2040 cfi_interleave(cfi),
ian@0 2041 cfi->device_type);
ian@0 2042 if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) ||
ian@0 2043 ((base + probe_offset2 + map_bankwidth(map)) >= map->size))
ian@0 2044 {
ian@0 2045 goto retry;
ian@0 2046 }
ian@0 2047
ian@0 2048 /* Reset */
ian@0 2049 jedec_reset(base, map, cfi);
ian@0 2050
ian@0 2051 /* Autoselect Mode */
ian@0 2052 if(cfi->addr_unlock1) {
ian@0 2053 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
ian@0 2054 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
ian@0 2055 }
ian@0 2056 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
ian@0 2057 /* FIXME - should have a delay before continuing */
ian@0 2058
ian@0 2059 if (!cfi->numchips) {
ian@0 2060 /* This is the first time we're called. Set up the CFI
ian@0 2061 stuff accordingly and return */
ian@0 2062
ian@0 2063 cfi->mfr = jedec_read_mfr(map, base, cfi);
ian@0 2064 cfi->id = jedec_read_id(map, base, cfi);
ian@0 2065 DEBUG(MTD_DEBUG_LEVEL3,
ian@0 2066 "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
ian@0 2067 cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type);
ian@0 2068 for (i = 0; i < ARRAY_SIZE(jedec_table); i++) {
ian@0 2069 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
ian@0 2070 DEBUG( MTD_DEBUG_LEVEL3,
ian@0 2071 "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
ian@0 2072 __func__, cfi->mfr, cfi->id,
ian@0 2073 cfi->addr_unlock1, cfi->addr_unlock2 );
ian@0 2074 if (!cfi_jedec_setup(cfi, i))
ian@0 2075 return 0;
ian@0 2076 goto ok_out;
ian@0 2077 }
ian@0 2078 }
ian@0 2079 goto retry;
ian@0 2080 } else {
ian@0 2081 __u16 mfr;
ian@0 2082 __u16 id;
ian@0 2083
ian@0 2084 /* Make sure it is a chip of the same manufacturer and id */
ian@0 2085 mfr = jedec_read_mfr(map, base, cfi);
ian@0 2086 id = jedec_read_id(map, base, cfi);
ian@0 2087
ian@0 2088 if ((mfr != cfi->mfr) || (id != cfi->id)) {
ian@0 2089 printk(KERN_DEBUG "%s: Found different chip or no chip at all (mfr 0x%x, id 0x%x) at 0x%x\n",
ian@0 2090 map->name, mfr, id, base);
ian@0 2091 jedec_reset(base, map, cfi);
ian@0 2092 return 0;
ian@0 2093 }
ian@0 2094 }
ian@0 2095
ian@0 2096 /* Check each previous chip locations to see if it's an alias */
ian@0 2097 for (i=0; i < (base >> cfi->chipshift); i++) {
ian@0 2098 unsigned long start;
ian@0 2099 if(!test_bit(i, chip_map)) {
ian@0 2100 continue; /* Skip location; no valid chip at this address */
ian@0 2101 }
ian@0 2102 start = i << cfi->chipshift;
ian@0 2103 if (jedec_read_mfr(map, start, cfi) == cfi->mfr &&
ian@0 2104 jedec_read_id(map, start, cfi) == cfi->id) {
ian@0 2105 /* Eep. This chip also looks like it's in autoselect mode.
ian@0 2106 Is it an alias for the new one? */
ian@0 2107 jedec_reset(start, map, cfi);
ian@0 2108
ian@0 2109 /* If the device IDs go away, it's an alias */
ian@0 2110 if (jedec_read_mfr(map, base, cfi) != cfi->mfr ||
ian@0 2111 jedec_read_id(map, base, cfi) != cfi->id) {
ian@0 2112 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
ian@0 2113 map->name, base, start);
ian@0 2114 return 0;
ian@0 2115 }
ian@0 2116
ian@0 2117 /* Yes, it's actually got the device IDs as data. Most
ian@0 2118 * unfortunate. Stick the new chip in read mode
ian@0 2119 * too and if it's the same, assume it's an alias. */
ian@0 2120 /* FIXME: Use other modes to do a proper check */
ian@0 2121 jedec_reset(base, map, cfi);
ian@0 2122 if (jedec_read_mfr(map, base, cfi) == cfi->mfr &&
ian@0 2123 jedec_read_id(map, base, cfi) == cfi->id) {
ian@0 2124 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
ian@0 2125 map->name, base, start);
ian@0 2126 return 0;
ian@0 2127 }
ian@0 2128 }
ian@0 2129 }
ian@0 2130
ian@0 2131 /* OK, if we got to here, then none of the previous chips appear to
ian@0 2132 be aliases for the current one. */
ian@0 2133 set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
ian@0 2134 cfi->numchips++;
ian@0 2135
ian@0 2136 ok_out:
ian@0 2137 /* Put it back into Read Mode */
ian@0 2138 jedec_reset(base, map, cfi);
ian@0 2139
ian@0 2140 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
ian@0 2141 map->name, cfi_interleave(cfi), cfi->device_type*8, base,
ian@0 2142 map->bankwidth*8);
ian@0 2143
ian@0 2144 return 1;
ian@0 2145 }
ian@0 2146
ian@0 2147 static struct chip_probe jedec_chip_probe = {
ian@0 2148 .name = "JEDEC",
ian@0 2149 .probe_chip = jedec_probe_chip
ian@0 2150 };
ian@0 2151
ian@0 2152 static struct mtd_info *jedec_probe(struct map_info *map)
ian@0 2153 {
ian@0 2154 /*
ian@0 2155 * Just use the generic probe stuff to call our CFI-specific
ian@0 2156 * chip_probe routine in all the possible permutations, etc.
ian@0 2157 */
ian@0 2158 return mtd_do_chip_probe(map, &jedec_chip_probe);
ian@0 2159 }
ian@0 2160
ian@0 2161 static struct mtd_chip_driver jedec_chipdrv = {
ian@0 2162 .probe = jedec_probe,
ian@0 2163 .name = "jedec_probe",
ian@0 2164 .module = THIS_MODULE
ian@0 2165 };
ian@0 2166
ian@0 2167 static int __init jedec_probe_init(void)
ian@0 2168 {
ian@0 2169 register_mtd_chip_driver(&jedec_chipdrv);
ian@0 2170 return 0;
ian@0 2171 }
ian@0 2172
ian@0 2173 static void __exit jedec_probe_exit(void)
ian@0 2174 {
ian@0 2175 unregister_mtd_chip_driver(&jedec_chipdrv);
ian@0 2176 }
ian@0 2177
ian@0 2178 module_init(jedec_probe_init);
ian@0 2179 module_exit(jedec_probe_exit);
ian@0 2180
ian@0 2181 MODULE_LICENSE("GPL");
ian@0 2182 MODULE_AUTHOR("Erwin Authried <eauth@softsys.co.at> et al.");
ian@0 2183 MODULE_DESCRIPTION("Probe code for JEDEC-compliant flash chips");