/* Modify the unlock address if we are in compatibility mode. *For16bitdeviceson8bitbusses *and32bitdeviceson16bitbusses *setthelowbitofthealternatingbitsequenceoftheaddress.
*/ if (((type * interleave) > bankwidth) && ((cmd_ofs & 0xff) == 0xaa))
addr |= (type >> 1)*interleave;
return addr;
}
EXPORT_SYMBOL(cfi_build_cmd_addr);
/* *TransformstheCFIcommandforthegivengeometry(buswidth&interleave). *Itlookstoolongtobeinline,butinthecommoncaseitshouldalmostall *getoptimisedaway.
*/
map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi)
{
map_word val = { {0} }; int wordwidth, words_per_bus, chip_mode, chips_per_word; unsignedlong onecmd; int i;
/* We do it this way to give the compiler a fighting chance ofoptimisingawayallthecrapfor'bankwidth'largerthan anunsignedlong,inthecommoncasewherethatsupportis
disabled */ if (map_bankwidth_is_large(map)) {
wordwidth = sizeof(unsignedlong);
words_per_bus = (map_bankwidth(map)) / wordwidth; // i.e. normally 1
} else {
wordwidth = map_bankwidth(map);
words_per_bus = 1;
}
/* First, determine what the bit-pattern should be for a single
device, according to chip mode and endianness... */ switch (chip_mode) { default: BUG(); case1:
onecmd = cmd; break; case2:
onecmd = cpu_to_cfi16(map, cmd); break; case4:
onecmd = cpu_to_cfi32(map, cmd); break;
}
/* Now replicate it across the size of an unsigned long, or
just to the bus width as appropriate */ switch (chips_per_word) { default: BUG(); #if BITS_PER_LONG >= 64 case8:
onecmd |= (onecmd << (chip_mode * 32));
fallthrough; #endif case4:
onecmd |= (onecmd << (chip_mode * 16));
fallthrough; case2:
onecmd |= (onecmd << (chip_mode * 8));
fallthrough; case1:
;
}
/* And finally, for the multi-word case, replicate it
in all words in the structure */ for (i=0; i < words_per_bus; i++) {
val.x[i] = onecmd;
}
return val;
}
EXPORT_SYMBOL(cfi_build_cmd);
unsignedlong cfi_merge_status(map_word val, struct map_info *map, struct cfi_private *cfi)
{ int wordwidth, words_per_bus, chip_mode, chips_per_word; unsignedlong onestat, res = 0; int i;
/* We do it this way to give the compiler a fighting chance ofoptimisingawayallthecrapfor'bankwidth'largerthan anunsignedlong,inthecommoncasewherethatsupportis
disabled */ if (map_bankwidth_is_large(map)) {
wordwidth = sizeof(unsignedlong);
words_per_bus = (map_bankwidth(map)) / wordwidth; // i.e. normally 1
} else {
wordwidth = map_bankwidth(map);
words_per_bus = 1;
}
/* Last, determine what the bit-pattern should be for a single
device, according to chip mode and endianness... */ switch (chip_mode) { case1: break; case2:
res = cfi16_to_cpu(map, res); break; case4:
res = cfi32_to_cpu(map, res); break; default: BUG();
} return res;
}
EXPORT_SYMBOL(cfi_merge_status);
int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
loff_t ofs, size_t len, void *thunk)
{ struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; unsignedlong adr; int chipnum, ret = 0; int i, first; struct mtd_erase_region_info *regions = mtd->eraseregions;
/* Check that both start and end of the requested erase are *alignedwiththeerasesizeattheappropriateaddresses.
*/
i = 0;
/* Skip all erase regions which are ended before the start of therequestederase.Actually,tosaveonthecalculations, weskiptothefirsteraseregionwhichstartsafterthe startoftherequestederase,andthengobackone.
*/
while (i < mtd->numeraseregions && ofs >= regions[i].offset)
i++;
i--;
/* OK, now i is pointing at the erase region in which this eraserequeststarts.Checkthestartoftherequested eraserangeisalignedwiththeerasesizewhichisin effecthere.
*/
if (ofs & (regions[i].erasesize-1)) return -EINVAL;
/* Remember the erase region we start on */
first = i;
/* Next, check that the end of the requested erase is aligned *withtheeraseregionatthataddress.
*/
while (i<mtd->numeraseregions && (ofs + len) >= regions[i].offset)
i++;
/* As before, drop back one to point at the region in which theaddressactuallyfalls
*/
i--;
if ((ofs + len) & (regions[i].erasesize-1)) return -EINVAL;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.