struct mtd_info *amd_flash_probe(struct map_info *map)<br />{<br /> /* Keep this table on the stack so that it gets deallocated after the<br /> * probe is done.<br /> */<br /> const struct amd_flash_info table[] = {<br /> {<br /> mfr_id: MANUFACTURER_AMD,<br /> dev_id: AM29LV160DT,<br /> name: "AMD AM29LV160DT",<br /> size: 0x00200000,<br /> numeraseregions: 4,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },<br /> { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 },<br /> { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 },<br /> { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_AMD,<br /> dev_id: AM29LV160DB,<br /> name: "AMD AM29LV160DB",<br /> size: 0x00200000,<br /> numeraseregions: 4,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },<br /> { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },<br /> { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },<br /> { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_TOSHIBA,<br /> dev_id: TC58FVT160,<br /> name: "Toshiba TC58FVT160",<br /> size: 0x00200000,<br /> numeraseregions: 4,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },<br /> { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 },<br /> { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 },<br /> { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_FUJITSU,<br /> dev_id: MBM29LV160TE,<br /> name: "Fujitsu MBM29LV160TE",<br /> size: 0x00200000,<br /> numeraseregions: 4,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },<br /> { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 },<br /> { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 },<br /> { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_TOSHIBA,<br /> dev_id: TC58FVB160,<br /> name: "Toshiba TC58FVB160",<br /> size: 0x00200000,<br /> numeraseregions: 4,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },<br /> { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },<br /> { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },<br /> { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_FUJITSU,<br /> dev_id: MBM29LV160BE,<br /> name: "Fujitsu MBM29LV160BE",<br /> size: 0x00200000,<br /> numeraseregions: 4,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },<br /> { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },<br /> { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },<br /> { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_AMD,<br /> dev_id: AM29LV800BB,<br /> name: "AMD AM29LV800BB",<br /> size: 0x00100000,<br /> numeraseregions: 4,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },<br /> { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },<br /> { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },<br /> { offset: 0x010000, erasesize: 0x10000, numblocks: 15 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_AMD,<br /> dev_id: AM29F800BB,<br /> name: "AMD AM29F800BB",<br /> size: 0x00100000,<br /> numeraseregions: 4,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },<br /> { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },<br /> { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },<br /> { offset: 0x010000, erasesize: 0x10000, numblocks: 15 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_AMD,<br /> dev_id: AM29LV800BT,<br /> name: "AMD AM29LV800BT",<br /> size: 0x00100000,<br /> numeraseregions: 4,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },<br /> { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 },<br /> { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 },<br /> { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_AMD,<br /> dev_id: AM29F800BT,<br /> name: "AMD AM29F800BT",<br /> size: 0x00100000,<br /> numeraseregions: 4,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },<br /> { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 },<br /> { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 },<br /> { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_AMD,<br /> dev_id: AM29LV800BB,<br /> name: "AMD AM29LV800BB",<br /> size: 0x00100000,<br /> numeraseregions: 4,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },<br /> { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 },<br /> { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 },<br /> { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_ST,<br /> dev_id: M29W800T,<br /> name: "ST M29W800T",<br /> size: 0x00100000,<br /> numeraseregions: 4,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },<br /> { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 },<br /> { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 },<br /> { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_ST,<br /> dev_id: M29W160DT,<br /> name: "ST M29W160DT",<br /> size: 0x00200000,<br /> numeraseregions: 4,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },<br /> { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 },<br /> { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 },<br /> { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_ST,<br /> dev_id: M29W160DB,<br /> name: "ST M29W160DB",<br /> size: 0x00200000,<br /> numeraseregions: 4,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },<br /> { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },<br /> { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },<br /> { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_AMD,<br /> dev_id: AM29BDS323D,<br /> name: "AMD AM29BDS323D",<br /> size: 0x00400000,<br /> numeraseregions: 3,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x10000, numblocks: 48 },<br /> { offset: 0x300000, erasesize: 0x10000, numblocks: 15 },<br /> { offset: 0x3f0000, erasesize: 0x02000, numblocks: 8 },<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_AMD,<br /> dev_id: AM29BDS643D,<br /> name: "AMD AM29BDS643D",<br /> size: 0x00800000,<br /> numeraseregions: 3,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x10000, numblocks: 96 },<br /> { offset: 0x600000, erasesize: 0x10000, numblocks: 31 },<br /> { offset: 0x7f0000, erasesize: 0x02000, numblocks: 8 },<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_ATMEL,<br /> dev_id: AT49xV16x,<br /> name: "Atmel AT49xV16x",<br /> size: 0x00200000,<br /> numeraseregions: 2,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x02000, numblocks: 8 },<br /> { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }<br /> }<br /> }, {<br /> mfr_id: MANUFACTURER_ATMEL,<br /> dev_id: AT49xV16xT,<br /> name: "Atmel AT49xV16xT",<br /> size: 0x00200000,<br /> numeraseregions: 2,<br /> regions: {<br /> { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },<br /> { offset: 0x1F0000, erasesize: 0x02000, numblocks: 8 }<br /> }<br /> } <br /> };<br /><br /> struct mtd_info *mtd;<br /> struct flchip chips[MAX_AMD_CHIPS];<br /> int table_pos[MAX_AMD_CHIPS];<br /> struct amd_flash_private temp;<br /> struct amd_flash_private *private;<br /> u_long size;<br /> unsigned long base;<br /> int i;<br /> int reg_idx;<br /> int offset;<br /><br /> mtd = (struct mtd_info*)mmalloc(sizeof(*mtd));<br /> if (!mtd) {<br /> printk("%s: malloc failed for info structure
", map->name);<br /> return NULL;<br /> }<br /> memset(mtd, 0, sizeof(*mtd));<br /> mtd->priv = map;<br /><br /> memset(&temp, 0, sizeof(temp));<br /><br /> printk("%s: Probing for AMD compatible flash...
", map->name);<br /><br /> if ((table_pos[0] = probe_new_chip(mtd, 0, NULL, &temp, table,<br /> sizeof(table)/sizeof(table[0])))<br /> == -1) {<br /> printk("%s: Found no AMD compatible device at location zero
",<br /> map->name);<br /> mfree(mtd);<br /><br /> return NULL;<br /> }<br /><br /> chips[0].start = 0;<br /> temp.numchips = 1;<br /><br /> for (size = mtd->size; size > 1; size >>= 1) {<br /> temp.chipshift++;<br /> }<br /> switch (temp.interleave) {<br /> case 2:<br /> temp.chipshift += 1;<br /> break;<br /> case 4:<br /> temp.chipshift += 2;<br /> break;<br /> }<br /><br /> /* Find out if there are any more chips in the map. */<br /> for (base = (1 << temp.chipshift);<br /> base < map->size;<br /> base += (1 << temp.chipshift)) {<br /> int numchips = temp.numchips;<br /> table_pos[numchips] = probe_new_chip(mtd, base, chips,<br /> &temp, table, sizeof(table)/sizeof(table[0]));<br /> }<br /><br /> mtd->eraseregions = mmalloc(sizeof(struct mtd_erase_region_info) *<br /> mtd->numeraseregions);<br /> if (!mtd->eraseregions) { <br /> printk("%s: Failed to allocate "<br /> "memory for MTD erase region info
", map->name);<br /> mfree(mtd);<br /> map->fldrv_priv = NULL;<br /> return 0;<br /> }<br /><br /> reg_idx = 0;<br /> offset = 0;<br /> for (i = 0; i < temp.numchips; i++) {<br /> int dev_size;<br /> int j;<br /><br /> dev_size = 0;<br /> for (j = 0; j < table[table_pos]].numeraseregions; j++) {<br /> mtd->eraseregions[reg_idx].offset = offset +<br /> (table[table_pos]].regions[j].offset *<br /> temp.interleave);<br /> mtd->eraseregions[reg_idx].erasesize =<br /> table[table_pos]].regions[j].erasesize *<br /> temp.interleave;<br /> mtd->eraseregions[reg_idx].numblocks =<br /> table[table_pos]].regions[j].numblocks;<br /> if (mtd->erasesize <<br /> mtd->eraseregions[reg_idx].erasesize) {<br /> mtd->erasesize =<br /> mtd->eraseregions[reg_idx].erasesize;<br /> }<br /> dev_size += mtd->eraseregions[reg_idx].erasesize *<br /> mtd->eraseregions[reg_idx].numblocks;<br /> reg_idx++;<br /> }<br /> offset += dev_size;<br /> }<br /> mtd->type = MTD_NORFLASH;<br /> mtd->flags = MTD_CAP_NORFLASH;<br /> mtd->name = map->name;<br /> mtd->erase = amd_flash_erase; <br /> mtd->write = amd_flash_write; <br /> mtd->lock = amd_flash_lock;<br /> mtd->unlock = amd_flash_unlock;<br /><br /> private = mmalloc(sizeof(*private) + (sizeof(struct flchip) *<br /> temp.numchips));<br /> if (!private) {<br /> printk("%s: kmalloc failed for private structure
", map->name);<br /> mfree(mtd);<br /> map->fldrv_priv = NULL;<br /> return NULL;<br /> }<br /> memcpy(private, &temp, sizeof(temp));<br /> memcpy(private->chips, chips,<br /> sizeof(struct flchip) * private->numchips);<br /><br /> map->fldrv_priv = private;<br /> /* map->fldrv = &amd_flash_chipdrv; */<br /><br /> return mtd;<br />}<br />
|