This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / mtd / chips / jedec_probe.c
index 3e232fd..8fb85f0 100644 (file)
@@ -1,7 +1,7 @@
 /* 
    Common Flash Interface probe code.
    (C) 2000 Red Hat. GPL'd.
-   $Id: jedec_probe.c,v 1.58 2004/11/16 18:29:00 dwmw2 Exp $
+   $Id: jedec_probe.c,v 1.51 2004/07/14 14:44:30 thayne Exp $
    See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
    for the standard this probe goes back to.
 
 #define I82802AC       0x00ac
 
 /* Macronix */
-#define MX29LV040C     0x004F
 #define MX29LV160T     0x22C4
 #define MX29LV160B     0x2249
 #define MX29F016       0x00AD
 #define M50FW040       0x002C
 #define M50FW080       0x002D
 #define M50FW016       0x002E
-#define M50LPW080       0x002F
 
 /* SST */
 #define SST29EE020     0x0010
@@ -183,8 +181,8 @@ enum uaddr {
 
 
 struct unlock_addr {
-       u32 addr1;
-       u32 addr2;
+       int addr1;
+       int addr2;
 };
 
 
@@ -514,12 +512,12 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,8),
                }
        }, {
-               mfr_id: MANUFACTURER_AMD,
-               dev_id: AM29F002T,
-               name: "AMD AM29F002T",
-               DevSize: SIZE_256KiB,
-               NumEraseRegions: 4,
-               regions: {ERASEINFO(0x10000,3),
+               .mfr_id = MANUFACTURER_AMD,
+               .dev_id = AM29F002T,
+               .name = "AMD AM29F002T",
+               .DevSize = SIZE_256KiB,
+               .NumEraseRegions = 4,
+               .regions = {ERASEINFO(0x10000,3),
                          ERASEINFO(0x08000,1),
                          ERASEINFO(0x02000,2),
                          ERASEINFO(0x04000,1)
@@ -770,12 +768,12 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1)
                }
        }, {
-               mfr_id: MANUFACTURER_HYUNDAI,
-               dev_id: HY29F002T,
-               name: "Hyundai HY29F002T",
-               DevSize: SIZE_256KiB,
-               NumEraseRegions: 4,
-               regions: {ERASEINFO(0x10000,3),
+               .mfr_id = MANUFACTURER_HYUNDAI,
+               .dev_id = HY29F002T,
+               .name = "Hyundai HY29F002T",
+               .DevSize = SIZE_256KiB,
+               .NumEraseRegions = 4,
+               .regions = {ERASEINFO(0x10000,3),
                          ERASEINFO(0x08000,1),
                          ERASEINFO(0x02000,2),
                          ERASEINFO(0x04000,1)
@@ -1084,19 +1082,6 @@ static const struct amd_flash_info jedec_table[] = {
                .regions        = {
                        ERASEINFO(0x10000,16),
                }
-       }, {
-               .mfr_id         = MANUFACTURER_MACRONIX,
-               .dev_id         = MX29LV040C,
-               .name           = "Macronix MX29LV040C",
-               .uaddr          = {
-                       [0] = MTD_UADDR_0x0555_0x02AA,  /* x8 */
-               },
-               .DevSize        = SIZE_512KiB,
-               .CmdSet         = P_ID_AMD_STD,
-               .NumEraseRegions= 1,
-               .regions        = {
-                       ERASEINFO(0x10000,8),
-               }
        }, {
                .mfr_id         = MANUFACTURER_MACRONIX,
                .dev_id         = MX29LV160T,
@@ -1177,12 +1162,12 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,7),
                }
        }, {
-               mfr_id: MANUFACTURER_MACRONIX,
-               dev_id: MX29F002T,
-               name: "Macronix MX29F002T",
-               DevSize: SIZE_256KiB,
-               NumEraseRegions: 4,
-               regions: {ERASEINFO(0x10000,3),
+               .mfr_id = MANUFACTURER_MACRONIX,
+               .dev_id = MX29F002T,
+               .name = "Macronix MX29F002T",
+               .DevSize = SIZE_256KiB,
+               .NumEraseRegions = 4,
+               .regions = {ERASEINFO(0x10000,3),
                          ERASEINFO(0x08000,1),
                          ERASEINFO(0x02000,2),
                          ERASEINFO(0x04000,1)
@@ -1262,7 +1247,7 @@ static const struct amd_flash_info jedec_table[] = {
                .DevSize        = SIZE_256KiB,
                .CmdSet         = P_ID_SST_PAGE,
                .NumEraseRegions= 1,
-               regions: {ERASEINFO(0x01000,64),
+               .regions = {ERASEINFO(0x01000,64),
                }
          }, {
                .mfr_id         = MANUFACTURER_SST,
@@ -1274,7 +1259,7 @@ static const struct amd_flash_info jedec_table[] = {
                .DevSize        = SIZE_256KiB,
                .CmdSet         = P_ID_SST_PAGE,
                .NumEraseRegions= 1,
-               regions: {ERASEINFO(0x01000,64),
+               .regions = {ERASEINFO(0x01000,64),
                }
        }, {
                .mfr_id         = MANUFACTURER_SST,
@@ -1394,22 +1379,6 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x01000,256),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,     /* should be CFI */
-               .dev_id         = SST39LF160,
-               .name           = "SST 39LF160",
-               .uaddr          = {
-                       [0] = MTD_UADDR_0x5555_0x2AAA,  /* x8 */
-                       [1] = MTD_UADDR_0x5555_0x2AAA   /* x16 */
-               },
-               .DevSize        = SIZE_2MiB,
-               .CmdSet         = P_ID_AMD_STD,
-               .NumEraseRegions= 2,
-               .regions        = {
-                       ERASEINFO(0x1000,256),
-                       ERASEINFO(0x1000,256)
-               }
-
-       }, {
                .mfr_id         = MANUFACTURER_ST,      /* FIXME - CFI device? */
                .dev_id         = M29W800DT,
                .name           = "ST M29W800DT",
@@ -1529,19 +1498,6 @@ static const struct amd_flash_info jedec_table[] = {
                .regions        = {
                        ERASEINFO(0x10000,32),
                }
-       }, {
-               .mfr_id         = MANUFACTURER_ST,
-               .dev_id         = M50LPW080,
-               .name           = "ST M50LPW080",
-               .uaddr          = {
-                       [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
-               },
-               .DevSize        = SIZE_1MiB,
-               .CmdSet         = P_ID_INTEL_EXT,
-               .NumEraseRegions= 1,
-               .regions        = {
-                       ERASEINFO(0x10000,16),
-               }
        }, {
                .mfr_id         = MANUFACTURER_TOSHIBA,
                .dev_id         = TC58FVT160,
@@ -1661,27 +1617,27 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index);
 static int jedec_probe_chip(struct map_info *map, __u32 base,
                            unsigned long *chip_map, struct cfi_private *cfi);
 
-static struct mtd_info *jedec_probe(struct map_info *map);
+struct mtd_info *jedec_probe(struct map_info *map);
 
 static inline u32 jedec_read_mfr(struct map_info *map, __u32 base, 
        struct cfi_private *cfi)
 {
        map_word result;
        unsigned long mask;
-       u32 ofs = cfi_build_cmd_addr(0, cfi_interleave(cfi), cfi->device_type);
        mask = (1 << (cfi->device_type * 8)) -1;
-       result = map_read(map, base + ofs);
+       result = map_read(map, base);
        return result.x[0] & mask;
 }
 
 static inline u32 jedec_read_id(struct map_info *map, __u32 base, 
        struct cfi_private *cfi)
 {
+       int osf;
        map_word result;
        unsigned long mask;
-       u32 ofs = cfi_build_cmd_addr(1, cfi_interleave(cfi), cfi->device_type);
+       osf = cfi->interleave *cfi->device_type;
        mask = (1 << (cfi->device_type * 8)) -1;
-       result = map_read(map, base + ofs);
+       result = map_read(map, base + osf);
        return result.x[0] & mask;
 }
 
@@ -1697,11 +1653,9 @@ static inline void jedec_reset(u32 base, struct map_info *map,
         * as they will ignore the writes and dont care what address
         * the F0 is written to */
        if(cfi->addr_unlock1) {
-               DEBUG( MTD_DEBUG_LEVEL3,
-                      "reset unlock called %x %x \n",
-                      cfi->addr_unlock1,cfi->addr_unlock2);
-               cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
-               cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
+               /*printk("reset unlock called %x %x \n",cfi->addr_unlock1,cfi->addr_unlock2);*/
+               cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+               cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
        }
 
        cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
@@ -1746,6 +1700,7 @@ static inline __u8 finfo_uaddr(const struct amd_flash_info *finfo, int device_ty
 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
 {
        int i,num_erase_regions;
+       unsigned long mask;
        __u8 uaddr;
 
        printk("Found: %s\n",jedec_table[index].name);
@@ -1781,8 +1736,9 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
        }
 
        /* Mask out address bits which are smaller than the device type */
-       p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1;
-       p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2;
+       mask = ~(p_cfi->device_type-1);
+       p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1 & mask;
+       p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2 & mask;
 
        return 1;       /* ok */
 }
@@ -1803,6 +1759,7 @@ static inline int jedec_match( __u32 base,
        int rc = 0;           /* failure until all tests pass */
        u32 mfr, id;
        __u8 uaddr;
+       unsigned long mask;
 
        /*
         * The IDs must match.  For X16 and X32 devices operating in
@@ -1840,7 +1797,7 @@ static inline int jedec_match( __u32 base,
        DEBUG( MTD_DEBUG_LEVEL3,
               "MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
               __func__, base, 1 << finfo->DevSize, base + (1 << finfo->DevSize) );
-       if ( base + cfi_interleave(cfi) * ( 1 << finfo->DevSize ) > map->size ) {
+       if ( base + cfi->interleave * ( 1 << finfo->DevSize ) > map->size ) {
                DEBUG( MTD_DEBUG_LEVEL3,
                       "MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
                       __func__, finfo->mfr_id, finfo->dev_id,
@@ -1853,16 +1810,18 @@ static inline int jedec_match( __u32 base,
                goto match_done;
        }
 
+       mask = ~(cfi->device_type-1);
+
        DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
               __func__, cfi->addr_unlock1, cfi->addr_unlock2 );
        if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr
-            && ( unlock_addrs[uaddr].addr1 != cfi->addr_unlock1 ||
-                 unlock_addrs[uaddr].addr2 != cfi->addr_unlock2 ) ) {
+            && ( (unlock_addrs[uaddr].addr1 & mask) != cfi->addr_unlock1 ||
+                 (unlock_addrs[uaddr].addr2 & mask) != cfi->addr_unlock2 ) ) {
                DEBUG( MTD_DEBUG_LEVEL3,
-                       "MTD %s(): 0x%.4x 0x%.4x did not match\n",
-                       __func__,
-                       unlock_addrs[uaddr].addr1,
-                       unlock_addrs[uaddr].addr2);
+                      "MTD %s(): 0x%.4lx 0x%.4lx did not match\n",
+                      __func__,
+                      unlock_addrs[uaddr].addr1 & mask,
+                      unlock_addrs[uaddr].addr2 & mask);
                goto match_done;
        }
 
@@ -1898,10 +1857,10 @@ static inline int jedec_match( __u32 base,
         */
        DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ );
        if(cfi->addr_unlock1) {
-               cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
-               cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
+               cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+               cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
        }
-       cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
+       cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
        /* FIXME - should have a delay before continuing */
 
  match_done:   
@@ -1914,18 +1873,19 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
 {
        int i;
        enum uaddr uaddr_idx = MTD_UADDR_NOT_SUPPORTED;
-       u32 probe_offset1, probe_offset2;
 
  retry:
        if (!cfi->numchips) {
+               unsigned long mask = ~(cfi->device_type-1);
+
                uaddr_idx++;
 
                if (MTD_UADDR_UNNECESSARY == uaddr_idx)
                        return 0;
 
                /* Mask out address bits which are smaller than the device type */
-               cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1;
-               cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2;
+               cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1 & mask;
+               cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2 & mask;
        }
 
        /* Make certain we aren't probing past the end of map */
@@ -1936,30 +1896,30 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
                return 0;
                
        }
-       /* Ensure the unlock addresses we try stay inside the map */
-       probe_offset1 = cfi_build_cmd_addr(
-               cfi->addr_unlock1, 
-               cfi_interleave(cfi), 
-               cfi->device_type);
-       probe_offset2 = cfi_build_cmd_addr(
-               cfi->addr_unlock1, 
-               cfi_interleave(cfi), 
-               cfi->device_type);
-       if (    ((base + probe_offset1 + map_bankwidth(map)) >= map->size) ||
-               ((base + probe_offset2 + map_bankwidth(map)) >= map->size))
-       {
-               goto retry;
+       if ((base + cfi->addr_unlock1) >= map->size) {
+               printk(KERN_NOTICE
+                       "Probe at addr_unlock1(0x%08x + 0x%08x) past the end of the map(0x%08lx)\n",
+                       base, cfi->addr_unlock1, map->size -1);
+
+               return 0;
        }
+       if ((base + cfi->addr_unlock2) >= map->size) {
+               printk(KERN_NOTICE
+                       "Probe at addr_unlock2(0x%08x + 0x%08x) past the end of the map(0x%08lx)\n",
+                       base, cfi->addr_unlock2, map->size -1);
+               return 0;
                
+       }
+
        /* Reset */
        jedec_reset(base, map, cfi);
 
        /* Autoselect Mode */
        if(cfi->addr_unlock1) {
-               cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
-               cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
+               cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+               cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
        }
-       cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
+       cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
        /* FIXME - should have a delay before continuing */
 
        if (!cfi->numchips) {
@@ -1970,7 +1930,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
                cfi->id = jedec_read_id(map, base, cfi);
                DEBUG(MTD_DEBUG_LEVEL3,
                      "Search for id:(%02x %02x) interleave(%d) type(%d)\n", 
-                       cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type);
+                       cfi->mfr, cfi->id, cfi->interleave, cfi->device_type);
                for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
                        if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
                                DEBUG( MTD_DEBUG_LEVEL3,
@@ -2044,7 +2004,7 @@ ok_out:
        jedec_reset(base, map, cfi);
 
        printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
-              map->name, cfi_interleave(cfi), cfi->device_type*8, base, 
+              map->name, cfi->interleave, cfi->device_type*8, base, 
               map->bankwidth*8);
        
        return 1;
@@ -2055,7 +2015,7 @@ static struct chip_probe jedec_chip_probe = {
        .probe_chip = jedec_probe_chip
 };
 
-static struct mtd_info *jedec_probe(struct map_info *map)
+struct mtd_info *jedec_probe(struct map_info *map)
 {
        /*
         * Just use the generic probe stuff to call our CFI-specific
@@ -2070,7 +2030,7 @@ static struct mtd_chip_driver jedec_chipdrv = {
        .module = THIS_MODULE
 };
 
-static int __init jedec_probe_init(void)
+int __init jedec_probe_init(void)
 {
        register_mtd_chip_driver(&jedec_chipdrv);
        return 0;