• Home
  • History
  • Annotate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/src/linux/linux-2.6/drivers/mtd/

Lines Matching refs:part

135 void ftl_freepart(partition_t *part);
161 static int scan_header(partition_t *part)
167 part->header.FormattedSize = 0;
168 max_offset = (0x100000<part->mbd.mtd->size)?0x100000:part->mbd.mtd->size;
172 offset += part->mbd.mtd->erasesize ? : 0x2000) {
174 err = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret,
193 if ((1 << header.EraseUnitSize) != part->mbd.mtd->erasesize) {
195 1 << header.EraseUnitSize,part->mbd.mtd->erasesize);
198 part->header = header;
202 static int build_maps(partition_t *part)
212 part->DataUnits = le16_to_cpu(part->header.NumEraseUnits) -
213 part->header.NumTransferUnits;
214 part->EUNInfo = kmalloc(part->DataUnits * sizeof(struct eun_info_t),
216 if (!part->EUNInfo)
218 for (i = 0; i < part->DataUnits; i++)
219 part->EUNInfo[i].Offset = 0xffffffff;
220 part->XferInfo =
221 kmalloc(part->header.NumTransferUnits * sizeof(struct xfer_info_t),
223 if (!part->XferInfo)
227 for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) {
228 offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN))
229 << part->header.EraseUnitSize);
230 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval,
239 if (hdr_ok && (le16_to_cpu(header.LogicalEUN) < part->DataUnits) &&
240 (part->EUNInfo[le16_to_cpu(header.LogicalEUN)].Offset == 0xffffffff)) {
241 part->EUNInfo[le16_to_cpu(header.LogicalEUN)].Offset = offset;
242 part->EUNInfo[le16_to_cpu(header.LogicalEUN)].EraseCount =
246 if (xtrans == part->header.NumTransferUnits) {
252 part->XferInfo[xtrans].state = XFER_PREPARED;
253 part->XferInfo[xtrans].EraseCount = le32_to_cpu(header.EraseCount);
255 part->XferInfo[xtrans].state = XFER_UNKNOWN;
257 part->XferInfo[xtrans].EraseCount =
258 le32_to_cpu(part->header.EraseCount);
260 part->XferInfo[xtrans].Offset = offset;
265 header = part->header;
275 part->VirtualBlockMap = vmalloc(blocks * sizeof(u_int32_t));
276 if (!part->VirtualBlockMap)
279 memset(part->VirtualBlockMap, 0xff, blocks * sizeof(u_int32_t));
280 part->BlocksPerUnit = (1 << header.EraseUnitSize) >> header.BlockSize;
282 part->bam_cache = kmalloc(part->BlocksPerUnit * sizeof(u_int32_t),
284 if (!part->bam_cache)
287 part->bam_index = 0xffff;
288 part->FreeTotal = 0;
290 for (i = 0; i < part->DataUnits; i++) {
291 part->EUNInfo[i].Free = 0;
292 part->EUNInfo[i].Deleted = 0;
293 offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset);
295 ret = part->mbd.mtd->read(part->mbd.mtd, offset,
296 part->BlocksPerUnit * sizeof(u_int32_t), &retval,
297 (unsigned char *)part->bam_cache);
302 for (j = 0; j < part->BlocksPerUnit; j++) {
303 if (BLOCK_FREE(le32_to_cpu(part->bam_cache[j]))) {
304 part->EUNInfo[i].Free++;
305 part->FreeTotal++;
306 } else if ((BLOCK_TYPE(le32_to_cpu(part->bam_cache[j])) == BLOCK_DATA) &&
307 (BLOCK_NUMBER(le32_to_cpu(part->bam_cache[j])) < blocks))
308 part->VirtualBlockMap[BLOCK_NUMBER(le32_to_cpu(part->bam_cache[j]))] =
310 else if (BLOCK_DELETED(le32_to_cpu(part->bam_cache[j])))
311 part->EUNInfo[i].Deleted++;
319 kfree(part->bam_cache);
321 vfree(part->VirtualBlockMap);
323 kfree(part->XferInfo);
325 kfree(part->EUNInfo);
337 static int erase_xfer(partition_t *part,
344 xfer = &part->XferInfo[xfernum];
355 erase->mtd = part->mbd.mtd;
358 erase->len = 1 << part->header.EraseUnitSize;
359 erase->priv = (u_long)part;
361 ret = part->mbd.mtd->erase(part->mbd.mtd, erase);
380 partition_t *part;
385 part = (partition_t *)(erase->priv);
387 for (i = 0; i < part->header.NumTransferUnits; i++)
388 if (part->XferInfo[i].Offset == erase->addr) break;
390 if (i == part->header.NumTransferUnits) {
396 xfer = &part->XferInfo[i];
409 static int prepare_xfer(partition_t *part, int i)
418 xfer = &part->XferInfo[i];
424 header = part->header;
428 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset, sizeof(header),
436 nbam = (part->BlocksPerUnit * sizeof(u_int32_t) +
437 le32_to_cpu(part->header.BAMOffset) + SECTOR_SIZE - 1) / SECTOR_SIZE;
439 offset = xfer->Offset + le32_to_cpu(part->header.BAMOffset);
444 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
467 static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
480 eun = &part->EUNInfo[srcunit];
481 xfer = &part->XferInfo[xferunit];
487 if (part->bam_index != srcunit) {
489 offset = eun->Offset + le32_to_cpu(part->header.BAMOffset);
491 ret = part->mbd.mtd->read(part->mbd.mtd, offset,
492 part->BlocksPerUnit * sizeof(u_int32_t),
493 &retlen, (u_char *) (part->bam_cache));
496 part->bam_index = 0xffff;
509 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int16_t),
522 for (i = 0; i < part->BlocksPerUnit; i++) {
523 switch (BLOCK_TYPE(le32_to_cpu(part->bam_cache[i]))) {
529 ret = part->mbd.mtd->read(part->mbd.mtd, src, SECTOR_SIZE,
537 ret = part->mbd.mtd->write(part->mbd.mtd, dest, SECTOR_SIZE,
547 part->bam_cache[i] = cpu_to_le32(0xffffffff);
556 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset),
557 part->BlocksPerUnit * sizeof(int32_t), &retlen,
558 (u_char *)part->bam_cache);
566 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(u_int16_t),
582 part->FreeTotal -= eun->Free;
583 part->FreeTotal += free;
588 part->bam_index = srcunit;
609 static int reclaim_block(partition_t *part)
616 DEBUG(3, "NumTransferUnits == %x\n", part->header.NumTransferUnits);
621 for (i = 0; i < part->header.NumTransferUnits; i++) {
623 if (part->XferInfo[i].state == XFER_UNKNOWN) {
626 erase_xfer(part, i);
628 if (part->XferInfo[i].state == XFER_ERASING) {
633 else if (part->XferInfo[i].state == XFER_ERASED) {
636 prepare_xfer(part, i);
638 if (part->XferInfo[i].state == XFER_PREPARED) {
641 if (part->XferInfo[i].EraseCount <= best) {
642 best = part->XferInfo[i].EraseCount;
647 DEBUG(3,"XferInfo[%d].state == %x\n",i, part->XferInfo[i].state);
654 if (part->mbd.mtd->sync)
655 part->mbd.mtd->sync(part->mbd.mtd);
674 for (i = 0; i < part->DataUnits; i++)
675 if (part->EUNInfo[i].EraseCount <= best) {
676 best = part->EUNInfo[i].EraseCount;
681 for (i = 0; i < part->DataUnits; i++)
682 if (part->EUNInfo[i].Deleted >= best) {
683 best = part->EUNInfo[i].Deleted;
698 ret = copy_erase_unit(part, eun, xfer);
700 erase_xfer(part, xfer);
717 static void dump_lists(partition_t *part)
720 printk(KERN_DEBUG "ftl_cs: Free total = %d\n", part->FreeTotal);
721 for (i = 0; i < part->DataUnits; i++)
724 part->EUNInfo[i].Offset >> part->header.EraseUnitSize,
725 part->EUNInfo[i].Free, part->EUNInfo[i].Deleted);
729 static u_int32_t find_free(partition_t *part)
737 stop = (part->bam_index == 0xffff) ? 0 : part->bam_index;
740 if (part->EUNInfo[eun].Free != 0) break;
742 if (++eun == part->DataUnits) eun = 0;
745 if (part->EUNInfo[eun].Free == 0)
749 if (eun != part->bam_index) {
751 part->bam_index = 0xffff;
753 ret = part->mbd.mtd->read(part->mbd.mtd,
754 part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset),
755 part->BlocksPerUnit * sizeof(u_int32_t),
756 &retlen, (u_char *) (part->bam_cache));
762 part->bam_index = eun;
766 for (blk = 0; blk < part->BlocksPerUnit; blk++)
767 if (BLOCK_FREE(le32_to_cpu(part->bam_cache[blk]))) break;
768 if (blk == part->BlocksPerUnit) {
772 dump_lists(part);
789 static int ftl_read(partition_t *part, caddr_t buffer,
798 part, sector, nblocks);
799 if (!(part->state & FTL_FORMATTED)) {
803 bsize = 1 << part->header.EraseUnitSize;
806 if (((sector+i) * SECTOR_SIZE) >= le32_to_cpu(part->header.FormattedSize)) {
810 log_addr = part->VirtualBlockMap[sector+i];
814 offset = (part->EUNInfo[log_addr / bsize].Offset
816 ret = part->mbd.mtd->read(part->mbd.mtd, offset, SECTOR_SIZE,
835 static int set_bam_entry(partition_t *part, u_int32_t log_addr,
847 part, log_addr, virt_addr);
848 bsize = 1 << part->header.EraseUnitSize;
851 offset = (part->EUNInfo[eun].Offset + blk * sizeof(u_int32_t) +
852 le32_to_cpu(part->header.BAMOffset));
855 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(u_int32_t),
876 if (part->bam_index == eun) {
878 if (le32_to_cpu(part->bam_cache[blk]) != old_addr) {
885 le32_to_cpu(part->bam_cache[blk]), old_addr);
890 part->bam_cache[blk] = le_virt_addr;
892 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
903 static int ftl_write(partition_t *part, caddr_t buffer,
912 part, sector, nblocks);
913 if (!(part->state & FTL_FORMATTED)) {
918 while (part->FreeTotal < nblocks) {
919 ret = reclaim_block(part);
924 bsize = 1 << part->header.EraseUnitSize;
928 if (virt_addr >= le32_to_cpu(part->header.FormattedSize)) {
934 blk = find_free(part);
944 log_addr = part->bam_index * bsize + blk * SECTOR_SIZE;
945 part->EUNInfo[part->bam_index].Free--;
946 part->FreeTotal--;
947 if (set_bam_entry(part, log_addr, 0xfffffffe))
949 part->EUNInfo[part->bam_index].Deleted++;
950 offset = (part->EUNInfo[part->bam_index].Offset +
952 ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen,
964 old_addr = part->VirtualBlockMap[sector+i];
966 part->VirtualBlockMap[sector+i] = 0xffffffff;
967 part->EUNInfo[old_addr/bsize].Deleted++;
968 if (set_bam_entry(part, old_addr, 0))
973 if (set_bam_entry(part, log_addr, virt_addr))
975 part->VirtualBlockMap[sector+i] = log_addr;
976 part->EUNInfo[part->bam_index].Deleted--;
986 partition_t *part = (void *)dev;
990 sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE;
1013 void ftl_freepart(partition_t *part)
1015 vfree(part->VirtualBlockMap);
1016 part->VirtualBlockMap = NULL;
1017 kfree(part->VirtualPageMap);
1018 part->VirtualPageMap = NULL;
1019 kfree(part->EUNInfo);
1020 part->EUNInfo = NULL;
1021 kfree(part->XferInfo);
1022 part->XferInfo = NULL;
1023 kfree(part->bam_cache);
1024 part->bam_cache = NULL;