Lines Matching refs:part

151 static int scan_header(partition_t *part)
157 part->header.FormattedSize = 0;
158 max_offset = (0x100000<part->mbd.mtd->size)?0x100000:part->mbd.mtd->size;
162 offset += part->mbd.mtd->erasesize ? : 0x2000) {
164 err = mtd_read(part->mbd.mtd, offset, sizeof(header), &ret,
183 if ((1 << header.EraseUnitSize) != part->mbd.mtd->erasesize) {
185 1 << header.EraseUnitSize,part->mbd.mtd->erasesize);
188 part->header = header;
192 static int build_maps(partition_t *part)
202 part->DataUnits = le16_to_cpu(part->header.NumEraseUnits) -
203 part->header.NumTransferUnits;
204 part->EUNInfo = kmalloc_array(part->DataUnits, sizeof(struct eun_info_t),
206 if (!part->EUNInfo)
208 for (i = 0; i < part->DataUnits; i++)
209 part->EUNInfo[i].Offset = 0xffffffff;
210 part->XferInfo =
211 kmalloc_array(part->header.NumTransferUnits,
214 if (!part->XferInfo)
218 for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) {
219 offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN))
220 << part->header.EraseUnitSize);
221 ret = mtd_read(part->mbd.mtd, offset, sizeof(header), &retval,
230 if (hdr_ok && (le16_to_cpu(header.LogicalEUN) < part->DataUnits) &&
231 (part->EUNInfo[le16_to_cpu(header.LogicalEUN)].Offset == 0xffffffff)) {
232 part->EUNInfo[le16_to_cpu(header.LogicalEUN)].Offset = offset;
233 part->EUNInfo[le16_to_cpu(header.LogicalEUN)].EraseCount =
237 if (xtrans == part->header.NumTransferUnits) {
243 part->XferInfo[xtrans].state = XFER_PREPARED;
244 part->XferInfo[xtrans].EraseCount = le32_to_cpu(header.EraseCount);
246 part->XferInfo[xtrans].state = XFER_UNKNOWN;
248 part->XferInfo[xtrans].EraseCount =
249 le32_to_cpu(part->header.EraseCount);
251 part->XferInfo[xtrans].Offset = offset;
256 header = part->header;
266 part->VirtualBlockMap = vmalloc(array_size(blocks, sizeof(uint32_t)));
267 if (!part->VirtualBlockMap)
270 memset(part->VirtualBlockMap, 0xff, blocks * sizeof(uint32_t));
271 part->BlocksPerUnit = (1 << header.EraseUnitSize) >> header.BlockSize;
273 part->bam_cache = kmalloc_array(part->BlocksPerUnit, sizeof(uint32_t),
275 if (!part->bam_cache)
278 part->bam_index = 0xffff;
279 part->FreeTotal = 0;
281 for (i = 0; i < part->DataUnits; i++) {
282 part->EUNInfo[i].Free = 0;
283 part->EUNInfo[i].Deleted = 0;
284 offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset);
286 ret = mtd_read(part->mbd.mtd, offset,
287 part->BlocksPerUnit * sizeof(uint32_t), &retval,
288 (unsigned char *)part->bam_cache);
293 for (j = 0; j < part->BlocksPerUnit; j++) {
294 if (BLOCK_FREE(le32_to_cpu(part->bam_cache[j]))) {
295 part->EUNInfo[i].Free++;
296 part->FreeTotal++;
297 } else if ((BLOCK_TYPE(le32_to_cpu(part->bam_cache[j])) == BLOCK_DATA) &&
298 (BLOCK_NUMBER(le32_to_cpu(part->bam_cache[j])) < blocks))
299 part->VirtualBlockMap[BLOCK_NUMBER(le32_to_cpu(part->bam_cache[j]))] =
301 else if (BLOCK_DELETED(le32_to_cpu(part->bam_cache[j])))
302 part->EUNInfo[i].Deleted++;
310 kfree(part->bam_cache);
312 vfree(part->VirtualBlockMap);
314 kfree(part->XferInfo);
316 kfree(part->EUNInfo);
328 static int erase_xfer(partition_t *part,
335 xfer = &part->XferInfo[xfernum];
347 erase->len = 1 << part->header.EraseUnitSize;
349 ret = mtd_erase(part->mbd.mtd, erase);
370 static int prepare_xfer(partition_t *part, int i)
379 xfer = &part->XferInfo[i];
385 header = part->header;
389 ret = mtd_write(part->mbd.mtd, xfer->Offset, sizeof(header), &retlen,
397 nbam = DIV_ROUND_UP(part->BlocksPerUnit * sizeof(uint32_t) +
398 le32_to_cpu(part->header.BAMOffset), SECTOR_SIZE);
400 offset = xfer->Offset + le32_to_cpu(part->header.BAMOffset);
405 ret = mtd_write(part->mbd.mtd, offset, sizeof(uint32_t), &retlen,
428 static int copy_erase_unit(partition_t *part, uint16_t srcunit,
441 eun = &part->EUNInfo[srcunit];
442 xfer = &part->XferInfo[xferunit];
448 if (part->bam_index != srcunit) {
450 offset = eun->Offset + le32_to_cpu(part->header.BAMOffset);
452 ret = mtd_read(part->mbd.mtd, offset,
453 part->BlocksPerUnit * sizeof(uint32_t), &retlen,
454 (u_char *)(part->bam_cache));
457 part->bam_index = 0xffff;
470 ret = mtd_write(part->mbd.mtd, offset, sizeof(uint16_t), &retlen,
483 for (i = 0; i < part->BlocksPerUnit; i++) {
484 switch (BLOCK_TYPE(le32_to_cpu(part->bam_cache[i]))) {
490 ret = mtd_read(part->mbd.mtd, src, SECTOR_SIZE, &retlen,
498 ret = mtd_write(part->mbd.mtd, dest, SECTOR_SIZE, &retlen,
508 part->bam_cache[i] = cpu_to_le32(0xffffffff);
517 ret = mtd_write(part->mbd.mtd,
518 xfer->Offset + le32_to_cpu(part->header.BAMOffset),
519 part->BlocksPerUnit * sizeof(int32_t),
521 (u_char *)part->bam_cache);
529 ret = mtd_write(part->mbd.mtd, xfer->Offset + 20, sizeof(uint16_t),
541 part->FreeTotal -= eun->Free;
542 part->FreeTotal += free;
547 part->bam_index = srcunit;
568 static int reclaim_block(partition_t *part)
575 pr_debug("NumTransferUnits == %x\n", part->header.NumTransferUnits);
580 for (i = 0; i < part->header.NumTransferUnits; i++) {
582 if (part->XferInfo[i].state == XFER_UNKNOWN) {
585 erase_xfer(part, i);
587 if (part->XferInfo[i].state == XFER_ERASING) {
592 else if (part->XferInfo[i].state == XFER_ERASED) {
595 prepare_xfer(part, i);
597 if (part->XferInfo[i].state == XFER_PREPARED) {
600 if (part->XferInfo[i].EraseCount <= best) {
601 best = part->XferInfo[i].EraseCount;
606 pr_debug("XferInfo[%d].state == %x\n",i, part->XferInfo[i].state);
613 mtd_sync(part->mbd.mtd);
632 for (i = 0; i < part->DataUnits; i++)
633 if (part->EUNInfo[i].EraseCount <= best) {
634 best = part->EUNInfo[i].EraseCount;
639 for (i = 0; i < part->DataUnits; i++)
640 if (part->EUNInfo[i].Deleted >= best) {
641 best = part->EUNInfo[i].Deleted;
656 ret = copy_erase_unit(part, eun, xfer);
658 erase_xfer(part, xfer);
675 static void dump_lists(partition_t *part)
678 printk(KERN_DEBUG "ftl_cs: Free total = %d\n", part->FreeTotal);
679 for (i = 0; i < part->DataUnits; i++)
682 part->EUNInfo[i].Offset >> part->header.EraseUnitSize,
683 part->EUNInfo[i].Free, part->EUNInfo[i].Deleted);
687 static uint32_t find_free(partition_t *part)
695 stop = (part->bam_index == 0xffff) ? 0 : part->bam_index;
698 if (part->EUNInfo[eun].Free != 0) break;
700 if (++eun == part->DataUnits) eun = 0;
703 if (part->EUNInfo[eun].Free == 0)
707 if (eun != part->bam_index) {
709 part->bam_index = 0xffff;
711 ret = mtd_read(part->mbd.mtd,
712 part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset),
713 part->BlocksPerUnit * sizeof(uint32_t),
715 (u_char *)(part->bam_cache));
721 part->bam_index = eun;
725 for (blk = 0; blk < part->BlocksPerUnit; blk++)
726 if (BLOCK_FREE(le32_to_cpu(part->bam_cache[blk]))) break;
727 if (blk == part->BlocksPerUnit) {
731 dump_lists(part);
748 static int ftl_read(partition_t *part, caddr_t buffer,
757 part, sector, nblocks);
758 if (!(part->state & FTL_FORMATTED)) {
762 bsize = 1 << part->header.EraseUnitSize;
765 if (((sector+i) * SECTOR_SIZE) >= le32_to_cpu(part->header.FormattedSize)) {
769 log_addr = part->VirtualBlockMap[sector+i];
773 offset = (part->EUNInfo[log_addr / bsize].Offset
775 ret = mtd_read(part->mbd.mtd, offset, SECTOR_SIZE, &retlen,
794 static int set_bam_entry(partition_t *part, uint32_t log_addr,
806 part, log_addr, virt_addr);
807 bsize = 1 << part->header.EraseUnitSize;
810 offset = (part->EUNInfo[eun].Offset + blk * sizeof(uint32_t) +
811 le32_to_cpu(part->header.BAMOffset));
814 ret = mtd_read(part->mbd.mtd, offset, sizeof(uint32_t), &retlen,
835 if (part->bam_index == eun) {
837 if (le32_to_cpu(part->bam_cache[blk]) != old_addr) {
844 le32_to_cpu(part->bam_cache[blk]), old_addr);
849 part->bam_cache[blk] = le_virt_addr;
851 ret = mtd_write(part->mbd.mtd, offset, sizeof(uint32_t), &retlen,
862 static int ftl_write(partition_t *part, caddr_t buffer,
871 part, sector, nblocks);
872 if (!(part->state & FTL_FORMATTED)) {
877 while (part->FreeTotal < nblocks) {
878 ret = reclaim_block(part);
883 bsize = 1 << part->header.EraseUnitSize;
887 if (virt_addr >= le32_to_cpu(part->header.FormattedSize)) {
893 blk = find_free(part);
903 log_addr = part->bam_index * bsize + blk * SECTOR_SIZE;
904 part->EUNInfo[part->bam_index].Free--;
905 part->FreeTotal--;
906 if (set_bam_entry(part, log_addr, 0xfffffffe))
908 part->EUNInfo[part->bam_index].Deleted++;
909 offset = (part->EUNInfo[part->bam_index].Offset +
911 ret = mtd_write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen, buffer);
922 old_addr = part->VirtualBlockMap[sector+i];
924 part->VirtualBlockMap[sector+i] = 0xffffffff;
925 part->EUNInfo[old_addr/bsize].Deleted++;
926 if (set_bam_entry(part, old_addr, 0))
931 if (set_bam_entry(part, log_addr, virt_addr))
933 part->VirtualBlockMap[sector+i] = log_addr;
934 part->EUNInfo[part->bam_index].Deleted--;
944 partition_t *part = container_of(dev, struct partition_t, mbd);
948 sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE;
972 partition_t *part = container_of(dev, struct partition_t, mbd);
973 uint32_t bsize = 1 << part->header.EraseUnitSize;
979 uint32_t old_addr = part->VirtualBlockMap[sector];
981 part->VirtualBlockMap[sector] = 0xffffffff;
982 part->EUNInfo[old_addr/bsize].Deleted++;
983 if (set_bam_entry(part, old_addr, 0))
994 static void ftl_freepart(partition_t *part)
996 vfree(part->VirtualBlockMap);
997 part->VirtualBlockMap = NULL;
998 kfree(part->EUNInfo);
999 part->EUNInfo = NULL;
1000 kfree(part->XferInfo);
1001 part->XferInfo = NULL;
1002 kfree(part->bam_cache);
1003 part->bam_cache = NULL;