• Home
  • History
  • Annotate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/mtd/

Lines Matching refs:part

158 static int scan_header(partition_t *part)
164 part->header.FormattedSize = 0;
165 max_offset = (0x100000<part->mbd.mtd->size)?0x100000:part->mbd.mtd->size;
169 offset += part->mbd.mtd->erasesize ? : 0x2000) {
171 err = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret,
190 if ((1 << header.EraseUnitSize) != part->mbd.mtd->erasesize) {
192 1 << header.EraseUnitSize,part->mbd.mtd->erasesize);
195 part->header = header;
199 static int build_maps(partition_t *part)
209 part->DataUnits = le16_to_cpu(part->header.NumEraseUnits) -
210 part->header.NumTransferUnits;
211 part->EUNInfo = kmalloc(part->DataUnits * sizeof(struct eun_info_t),
213 if (!part->EUNInfo)
215 for (i = 0; i < part->DataUnits; i++)
216 part->EUNInfo[i].Offset = 0xffffffff;
217 part->XferInfo =
218 kmalloc(part->header.NumTransferUnits * sizeof(struct xfer_info_t),
220 if (!part->XferInfo)
224 for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) {
225 offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN))
226 << part->header.EraseUnitSize);
227 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval,
236 if (hdr_ok && (le16_to_cpu(header.LogicalEUN) < part->DataUnits) &&
237 (part->EUNInfo[le16_to_cpu(header.LogicalEUN)].Offset == 0xffffffff)) {
238 part->EUNInfo[le16_to_cpu(header.LogicalEUN)].Offset = offset;
239 part->EUNInfo[le16_to_cpu(header.LogicalEUN)].EraseCount =
243 if (xtrans == part->header.NumTransferUnits) {
249 part->XferInfo[xtrans].state = XFER_PREPARED;
250 part->XferInfo[xtrans].EraseCount = le32_to_cpu(header.EraseCount);
252 part->XferInfo[xtrans].state = XFER_UNKNOWN;
254 part->XferInfo[xtrans].EraseCount =
255 le32_to_cpu(part->header.EraseCount);
257 part->XferInfo[xtrans].Offset = offset;
262 header = part->header;
272 part->VirtualBlockMap = vmalloc(blocks * sizeof(uint32_t));
273 if (!part->VirtualBlockMap)
276 memset(part->VirtualBlockMap, 0xff, blocks * sizeof(uint32_t));
277 part->BlocksPerUnit = (1 << header.EraseUnitSize) >> header.BlockSize;
279 part->bam_cache = kmalloc(part->BlocksPerUnit * sizeof(uint32_t),
281 if (!part->bam_cache)
284 part->bam_index = 0xffff;
285 part->FreeTotal = 0;
287 for (i = 0; i < part->DataUnits; i++) {
288 part->EUNInfo[i].Free = 0;
289 part->EUNInfo[i].Deleted = 0;
290 offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset);
292 ret = part->mbd.mtd->read(part->mbd.mtd, offset,
293 part->BlocksPerUnit * sizeof(uint32_t), &retval,
294 (unsigned char *)part->bam_cache);
299 for (j = 0; j < part->BlocksPerUnit; j++) {
300 if (BLOCK_FREE(le32_to_cpu(part->bam_cache[j]))) {
301 part->EUNInfo[i].Free++;
302 part->FreeTotal++;
303 } else if ((BLOCK_TYPE(le32_to_cpu(part->bam_cache[j])) == BLOCK_DATA) &&
304 (BLOCK_NUMBER(le32_to_cpu(part->bam_cache[j])) < blocks))
305 part->VirtualBlockMap[BLOCK_NUMBER(le32_to_cpu(part->bam_cache[j]))] =
307 else if (BLOCK_DELETED(le32_to_cpu(part->bam_cache[j])))
308 part->EUNInfo[i].Deleted++;
316 kfree(part->bam_cache);
318 vfree(part->VirtualBlockMap);
320 kfree(part->XferInfo);
322 kfree(part->EUNInfo);
334 static int erase_xfer(partition_t *part,
341 xfer = &part->XferInfo[xfernum];
352 erase->mtd = part->mbd.mtd;
355 erase->len = 1 << part->header.EraseUnitSize;
356 erase->priv = (u_long)part;
358 ret = part->mbd.mtd->erase(part->mbd.mtd, erase);
377 partition_t *part;
382 part = (partition_t *)(erase->priv);
384 for (i = 0; i < part->header.NumTransferUnits; i++)
385 if (part->XferInfo[i].Offset == erase->addr) break;
387 if (i == part->header.NumTransferUnits) {
393 xfer = &part->XferInfo[i];
406 static int prepare_xfer(partition_t *part, int i)
415 xfer = &part->XferInfo[i];
421 header = part->header;
425 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset, sizeof(header),
433 nbam = (part->BlocksPerUnit * sizeof(uint32_t) +
434 le32_to_cpu(part->header.BAMOffset) + SECTOR_SIZE - 1) / SECTOR_SIZE;
436 offset = xfer->Offset + le32_to_cpu(part->header.BAMOffset);
441 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(uint32_t),
464 static int copy_erase_unit(partition_t *part, uint16_t srcunit,
477 eun = &part->EUNInfo[srcunit];
478 xfer = &part->XferInfo[xferunit];
484 if (part->bam_index != srcunit) {
486 offset = eun->Offset + le32_to_cpu(part->header.BAMOffset);
488 ret = part->mbd.mtd->read(part->mbd.mtd, offset,
489 part->BlocksPerUnit * sizeof(uint32_t),
490 &retlen, (u_char *) (part->bam_cache));
493 part->bam_index = 0xffff;
506 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(uint16_t),
519 for (i = 0; i < part->BlocksPerUnit; i++) {
520 switch (BLOCK_TYPE(le32_to_cpu(part->bam_cache[i]))) {
526 ret = part->mbd.mtd->read(part->mbd.mtd, src, SECTOR_SIZE,
534 ret = part->mbd.mtd->write(part->mbd.mtd, dest, SECTOR_SIZE,
544 part->bam_cache[i] = cpu_to_le32(0xffffffff);
553 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset),
554 part->BlocksPerUnit * sizeof(int32_t), &retlen,
555 (u_char *)part->bam_cache);
563 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(uint16_t),
579 part->FreeTotal -= eun->Free;
580 part->FreeTotal += free;
585 part->bam_index = srcunit;
606 static int reclaim_block(partition_t *part)
613 DEBUG(3, "NumTransferUnits == %x\n", part->header.NumTransferUnits);
618 for (i = 0; i < part->header.NumTransferUnits; i++) {
620 if (part->XferInfo[i].state == XFER_UNKNOWN) {
623 erase_xfer(part, i);
625 if (part->XferInfo[i].state == XFER_ERASING) {
630 else if (part->XferInfo[i].state == XFER_ERASED) {
633 prepare_xfer(part, i);
635 if (part->XferInfo[i].state == XFER_PREPARED) {
638 if (part->XferInfo[i].EraseCount <= best) {
639 best = part->XferInfo[i].EraseCount;
644 DEBUG(3,"XferInfo[%d].state == %x\n",i, part->XferInfo[i].state);
651 if (part->mbd.mtd->sync)
652 part->mbd.mtd->sync(part->mbd.mtd);
671 for (i = 0; i < part->DataUnits; i++)
672 if (part->EUNInfo[i].EraseCount <= best) {
673 best = part->EUNInfo[i].EraseCount;
678 for (i = 0; i < part->DataUnits; i++)
679 if (part->EUNInfo[i].Deleted >= best) {
680 best = part->EUNInfo[i].Deleted;
695 ret = copy_erase_unit(part, eun, xfer);
697 erase_xfer(part, xfer);
714 static void dump_lists(partition_t *part)
717 printk(KERN_DEBUG "ftl_cs: Free total = %d\n", part->FreeTotal);
718 for (i = 0; i < part->DataUnits; i++)
721 part->EUNInfo[i].Offset >> part->header.EraseUnitSize,
722 part->EUNInfo[i].Free, part->EUNInfo[i].Deleted);
726 static uint32_t find_free(partition_t *part)
734 stop = (part->bam_index == 0xffff) ? 0 : part->bam_index;
737 if (part->EUNInfo[eun].Free != 0) break;
739 if (++eun == part->DataUnits) eun = 0;
742 if (part->EUNInfo[eun].Free == 0)
746 if (eun != part->bam_index) {
748 part->bam_index = 0xffff;
750 ret = part->mbd.mtd->read(part->mbd.mtd,
751 part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset),
752 part->BlocksPerUnit * sizeof(uint32_t),
753 &retlen, (u_char *) (part->bam_cache));
759 part->bam_index = eun;
763 for (blk = 0; blk < part->BlocksPerUnit; blk++)
764 if (BLOCK_FREE(le32_to_cpu(part->bam_cache[blk]))) break;
765 if (blk == part->BlocksPerUnit) {
769 dump_lists(part);
786 static int ftl_read(partition_t *part, caddr_t buffer,
795 part, sector, nblocks);
796 if (!(part->state & FTL_FORMATTED)) {
800 bsize = 1 << part->header.EraseUnitSize;
803 if (((sector+i) * SECTOR_SIZE) >= le32_to_cpu(part->header.FormattedSize)) {
807 log_addr = part->VirtualBlockMap[sector+i];
811 offset = (part->EUNInfo[log_addr / bsize].Offset
813 ret = part->mbd.mtd->read(part->mbd.mtd, offset, SECTOR_SIZE,
832 static int set_bam_entry(partition_t *part, uint32_t log_addr,
844 part, log_addr, virt_addr);
845 bsize = 1 << part->header.EraseUnitSize;
848 offset = (part->EUNInfo[eun].Offset + blk * sizeof(uint32_t) +
849 le32_to_cpu(part->header.BAMOffset));
852 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(uint32_t),
873 if (part->bam_index == eun) {
875 if (le32_to_cpu(part->bam_cache[blk]) != old_addr) {
882 le32_to_cpu(part->bam_cache[blk]), old_addr);
887 part->bam_cache[blk] = le_virt_addr;
889 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(uint32_t),
900 static int ftl_write(partition_t *part, caddr_t buffer,
909 part, sector, nblocks);
910 if (!(part->state & FTL_FORMATTED)) {
915 while (part->FreeTotal < nblocks) {
916 ret = reclaim_block(part);
921 bsize = 1 << part->header.EraseUnitSize;
925 if (virt_addr >= le32_to_cpu(part->header.FormattedSize)) {
931 blk = find_free(part);
941 log_addr = part->bam_index * bsize + blk * SECTOR_SIZE;
942 part->EUNInfo[part->bam_index].Free--;
943 part->FreeTotal--;
944 if (set_bam_entry(part, log_addr, 0xfffffffe))
946 part->EUNInfo[part->bam_index].Deleted++;
947 offset = (part->EUNInfo[part->bam_index].Offset +
949 ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen,
961 old_addr = part->VirtualBlockMap[sector+i];
963 part->VirtualBlockMap[sector+i] = 0xffffffff;
964 part->EUNInfo[old_addr/bsize].Deleted++;
965 if (set_bam_entry(part, old_addr, 0))
970 if (set_bam_entry(part, log_addr, virt_addr))
972 part->VirtualBlockMap[sector+i] = log_addr;
973 part->EUNInfo[part->bam_index].Deleted--;
983 partition_t *part = (void *)dev;
987 sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE;
1011 partition_t *part = (void *)dev;
1012 uint32_t bsize = 1 << part->header.EraseUnitSize;
1018 uint32_t old_addr = part->VirtualBlockMap[sector];
1020 part->VirtualBlockMap[sector] = 0xffffffff;
1021 part->EUNInfo[old_addr/bsize].Deleted++;
1022 if (set_bam_entry(part, old_addr, 0))
1033 static void ftl_freepart(partition_t *part)
1035 vfree(part->VirtualBlockMap);
1036 part->VirtualBlockMap = NULL;
1037 kfree(part->VirtualPageMap);
1038 part->VirtualPageMap = NULL;
1039 kfree(part->EUNInfo);
1040 part->EUNInfo = NULL;
1041 kfree(part->XferInfo);
1042 part->XferInfo = NULL;
1043 kfree(part->bam_cache);
1044 part->bam_cache = NULL;