Lines Matching +full:1 +full:- +full:512

1 // SPDX-License-Identifier: GPL-2.0-or-later
6 * Copyright © 1999-2010 David Woodhouse <[email protected]>
40 if (!mtd_type_is_nand(mtd) || mtd->size > UINT_MAX) in nftl_add_mtd()
43 if (memcmp(mtd->name, "DiskOnChip", 10)) in nftl_add_mtd()
46 pr_debug("NFTL: add_mtd for %s\n", mtd->name); in nftl_add_mtd()
53 nftl->mbd.mtd = mtd; in nftl_add_mtd()
54 nftl->mbd.devnum = -1; in nftl_add_mtd()
56 nftl->mbd.tr = tr; in nftl_add_mtd()
67 nftl->cylinders = 1024; in nftl_add_mtd()
68 nftl->heads = 16; in nftl_add_mtd()
70 temp = nftl->cylinders * nftl->heads; in nftl_add_mtd()
71 nftl->sectors = nftl->mbd.size / temp; in nftl_add_mtd()
72 if (nftl->mbd.size % temp) { in nftl_add_mtd()
73 nftl->sectors++; in nftl_add_mtd()
74 temp = nftl->cylinders * nftl->sectors; in nftl_add_mtd()
75 nftl->heads = nftl->mbd.size / temp; in nftl_add_mtd()
77 if (nftl->mbd.size % temp) { in nftl_add_mtd()
78 nftl->heads++; in nftl_add_mtd()
79 temp = nftl->heads * nftl->sectors; in nftl_add_mtd()
80 nftl->cylinders = nftl->mbd.size / temp; in nftl_add_mtd()
84 if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) { in nftl_add_mtd()
90 "match size of 0x%lx.\n", nftl->mbd.size); in nftl_add_mtd()
93 nftl->cylinders, nftl->heads , nftl->sectors, in nftl_add_mtd()
94 (long)nftl->cylinders * (long)nftl->heads * in nftl_add_mtd()
95 (long)nftl->sectors ); in nftl_add_mtd()
98 if (add_mtd_blktrans_dev(&nftl->mbd)) { in nftl_add_mtd()
99 kfree(nftl->ReplUnitTable); in nftl_add_mtd()
100 kfree(nftl->EUNtable); in nftl_add_mtd()
105 printk(KERN_INFO "NFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a'); in nftl_add_mtd()
113 pr_debug("NFTL: remove_dev (i=%d)\n", dev->devnum); in nftl_remove_dev()
116 kfree(nftl->ReplUnitTable); in nftl_remove_dev()
117 kfree(nftl->EUNtable); in nftl_remove_dev()
126 loff_t mask = mtd->writesize - 1; in nftl_read_oob()
147 loff_t mask = mtd->writesize - 1; in nftl_write_oob()
170 loff_t mask = mtd->writesize - 1; in nftl_write()
176 ops.ooblen = mtd->oobsize; in nftl_write()
196 u16 pot = nftl->LastFreeEUN; in NFTL_findfreeblock()
197 int silly = nftl->nb_blocks; in NFTL_findfreeblock()
200 if (!desperate && nftl->numfreeEUNs < 2) { in NFTL_findfreeblock()
207 if (nftl->ReplUnitTable[pot] == BLOCK_FREE) { in NFTL_findfreeblock()
208 nftl->LastFreeEUN = pot; in NFTL_findfreeblock()
209 nftl->numfreeEUNs--; in NFTL_findfreeblock()
217 if (++pot > nftl->lastEUN) in NFTL_findfreeblock()
218 pot = le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN); in NFTL_findfreeblock()
220 if (!silly--) { in NFTL_findfreeblock()
222 "FirstEUN = %d\n", nftl->LastFreeEUN, in NFTL_findfreeblock()
223 le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN)); in NFTL_findfreeblock()
226 } while (pot != nftl->LastFreeEUN); in NFTL_findfreeblock()
233 struct mtd_info *mtd = nftl->mbd.mtd; in NFTL_foldchain()
242 int inplace = 1; in NFTL_foldchain()
248 thisEUN = nftl->EUNtable[thisVUC]; in NFTL_foldchain()
251 printk(KERN_WARNING "Trying to fold non-existent " in NFTL_foldchain()
257 512-byte block within the Chain. in NFTL_foldchain()
261 while (thisEUN <= nftl->lastEUN ) { in NFTL_foldchain()
265 for (block = 0; block < nftl->EraseSize / 512; block ++) { in NFTL_foldchain()
266 nftl_read_oob(mtd, (thisEUN * nftl->EraseSize) + in NFTL_foldchain()
267 (block * 512), 16 , &retlen, in NFTL_foldchain()
278 inplace = 1; in NFTL_foldchain()
286 BlockFreeFound[block] = 1; in NFTL_foldchain()
316 if (!silly--) { in NFTL_foldchain()
322 thisEUN = nftl->ReplUnitTable[thisEUN]; in NFTL_foldchain()
326 /* We're being asked to be a fold-in-place. Check in NFTL_foldchain()
330 block. If not, we're going to have to fold out-of-place in NFTL_foldchain()
333 for (block = 0; block < nftl->EraseSize / 512 ; block++) { in NFTL_foldchain()
349 if (pendingblock >= (thisVUC * (nftl->EraseSize / 512)) && in NFTL_foldchain()
350 pendingblock < ((thisVUC + 1)* (nftl->EraseSize / 512)) && in NFTL_foldchain()
351 BlockLastState[pendingblock - (thisVUC * (nftl->EraseSize / 512))] != in NFTL_foldchain()
361 "Trying out-of-place\n", thisVUC); in NFTL_foldchain()
363 targetEUN = NFTL_findfreeblock(nftl, 1); in NFTL_foldchain()
366 fold-in-place of another chain to make room in NFTL_foldchain()
382 nftl_write_oob(mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8, in NFTL_foldchain()
391 for (block = 0; block < nftl->EraseSize / 512 ; block++) { in NFTL_foldchain()
392 unsigned char movebuf[512]; in NFTL_foldchain()
397 (pendingblock == (thisVUC * (nftl->EraseSize / 512) + block))) { in NFTL_foldchain()
407 (nftl->EraseSize * BlockMap[block]) + (block * 512), in NFTL_foldchain()
408 512, in NFTL_foldchain()
413 (nftl->EraseSize * BlockMap[block]) + (block * 512), in NFTL_foldchain()
414 512, in NFTL_foldchain()
417 if (ret != -EIO) in NFTL_foldchain()
423 nftl_write(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + in NFTL_foldchain()
424 (block * 512), 512, &retlen, movebuf, (char *)&oob); in NFTL_foldchain()
431 nftl_write_oob(mtd, (nftl->EraseSize * targetEUN) + 8, in NFTL_foldchain()
441 thisEUN = nftl->EUNtable[thisVUC]; in NFTL_foldchain()
446 while (thisEUN <= nftl->lastEUN && thisEUN != targetEUN) { in NFTL_foldchain()
449 EUNtmp = nftl->ReplUnitTable[thisEUN]; in NFTL_foldchain()
454 nftl->ReplUnitTable[thisEUN] = BLOCK_RESERVED; in NFTL_foldchain()
457 nftl->ReplUnitTable[thisEUN] = BLOCK_FREE; in NFTL_foldchain()
458 nftl->numfreeEUNs++; in NFTL_foldchain()
464 nftl->ReplUnitTable[targetEUN] = BLOCK_NIL; in NFTL_foldchain()
465 nftl->EUNtable[thisVUC] = targetEUN; in NFTL_foldchain()
475 Wear-levelling and other clever stuff needs to be implemented in NFTL_makefreeblock()
477 the system loses power half-way through the routine. in NFTL_makefreeblock()
483 for (chain = 0; chain < le32_to_cpu(nftl->MediaHdr.FormattedSize) / nftl->EraseSize; chain++) { in NFTL_makefreeblock()
484 EUN = nftl->EUNtable[chain]; in NFTL_makefreeblock()
487 while (EUN <= nftl->lastEUN) { in NFTL_makefreeblock()
490 EUN = nftl->ReplUnitTable[EUN] & 0x7fff; in NFTL_makefreeblock()
525 u16 thisVUC = block / (nftl->EraseSize / 512); in NFTL_findwriteunit()
526 struct mtd_info *mtd = nftl->mbd.mtd; in NFTL_findwriteunit()
528 unsigned long blockofs = (block * 512) & (nftl->EraseSize -1); in NFTL_findwriteunit()
539 being a sanity check for past-end-of-media access in NFTL_findwriteunit()
542 writeEUN = nftl->EUNtable[thisVUC]; in NFTL_findwriteunit()
544 while (writeEUN <= nftl->lastEUN) { in NFTL_findwriteunit()
552 (writeEUN * nftl->EraseSize) + blockofs, in NFTL_findwriteunit()
572 if (!silly--) { in NFTL_findwriteunit()
580 writeEUN = nftl->ReplUnitTable[writeEUN]; in NFTL_findwriteunit()
586 /* Try to find an already-free block */ in NFTL_findwriteunit()
590 /* That didn't work - there were no free blocks just in NFTL_findwriteunit()
596 //u16 startEUN = nftl->EUNtable[thisVUC]; in NFTL_findwriteunit()
603 lying - there may have been free blocks in NFTL_findwriteunit()
608 pr_debug("Using desperate==1 to find free EUN to accommodate write to VUC %d\n", thisVUC); in NFTL_findwriteunit()
609 writeEUN = NFTL_findfreeblock(nftl, 1); in NFTL_findwriteunit()
612 /* Ouch. This should never happen - we should in NFTL_findwriteunit()
631 nftl->EUNtable[thisVUC] = writeEUN; in NFTL_findwriteunit()
636 nftl->ReplUnitTable[writeEUN] = BLOCK_NIL; in NFTL_findwriteunit()
639 nftl_read_oob(mtd, writeEUN * nftl->EraseSize + 8, 8, in NFTL_findwriteunit()
644 nftl_write_oob(mtd, writeEUN * nftl->EraseSize + 8, 8, in NFTL_findwriteunit()
652 nftl->ReplUnitTable[lastEUN] = writeEUN; in NFTL_findwriteunit()
654 nftl_read_oob(mtd, (lastEUN * nftl->EraseSize) + 8, in NFTL_findwriteunit()
660 nftl_write_oob(mtd, (lastEUN * nftl->EraseSize) + 8, in NFTL_findwriteunit()
666 } while (silly2--); in NFTL_findwriteunit()
678 unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1); in nftl_writeblock()
688 return 1; in nftl_writeblock()
694 nftl_write(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs, in nftl_writeblock()
695 512, &retlen, (char *)buffer, (char *)&oob); in nftl_writeblock()
704 struct mtd_info *mtd = nftl->mbd.mtd; in nftl_readblock()
706 u16 thisEUN = nftl->EUNtable[block / (nftl->EraseSize / 512)]; in nftl_readblock()
707 unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1); in nftl_readblock()
716 while (thisEUN < nftl->nb_blocks) { in nftl_readblock()
717 if (nftl_read_oob(mtd, (thisEUN * nftl->EraseSize) + in nftl_readblock()
742 if (!silly--) { in nftl_readblock()
744 block / (nftl->EraseSize / 512)); in nftl_readblock()
745 return 1; in nftl_readblock()
747 thisEUN = nftl->ReplUnitTable[thisEUN]; in nftl_readblock()
754 memset(buffer, 0, 512); in nftl_readblock()
756 loff_t ptr = (lastgoodEUN * nftl->EraseSize) + blockofs; in nftl_readblock()
758 int res = mtd_read(mtd, ptr, 512, &retlen, buffer); in nftl_readblock()
761 return -EIO; in nftl_readblock()
770 geo->heads = nftl->heads; in nftl_getgeo()
771 geo->sectors = nftl->sectors; in nftl_getgeo()
772 geo->cylinders = nftl->cylinders; in nftl_getgeo()
788 .blksize = 512,
803 MODULE_DESCRIPTION("Support code for NAND Flash Translation Layer, used on M-Systems DiskOnChip 200…