Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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