/*
* YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
*
* Copyright (C) 2002-2011 Aleph One Ltd.
* for Toby Churchill Ltd and Brightstar Engineering
*
* Created by Charles Manning <charles@aleph1.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <stdio.h>
#include "direct/yportenv.h"
#include "yaffs_trace.h"
#include "yaffs_guts.h"
#include "yaffs_getblockinfo.h"
#include "yaffs_tagscompat.h"
#include "yaffs_nand.h"
#include "yaffs_yaffs1.h"
#include "yaffs_yaffs2.h"
#include "yaffs_bitmap.h"
#include "yaffs_verify.h"
#include "yaffs_nand.h"
#include "yaffs_packedtags2.h"
#include "yaffs_nameval.h"
#include "yaffs_allocator.h"
#include "yaffs_attribs.h"
#include "yaffs_summary.h"
/* Note YAFFS_GC_GOOD_ENOUGH must be <= YAFFS_GC_PASSIVE_THRESHOLD */
#define YAFFS_GC_GOOD_ENOUGH 2
#define YAFFS_GC_PASSIVE_THRESHOLD 4
#include "yaffs_ecc.h"
/* Forward declarations */
static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk,
const u8 *buffer, int n_bytes, int use_reserve);
/* Function to calculate chunk and offset */
static inline void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr,
int *chunk_out, u32 *offset_out)
{
int chunk;
u32 offset;
chunk = (u32) (addr >> dev->chunk_shift);
if (dev->chunk_div == 1)
{
/* easy power of 2 case */
offset = (u32) (addr & dev->chunk_mask);
}
else
{
/* Non power-of-2 case */
loff_t chunk_base;
chunk /= dev->chunk_div;
chunk_base = ((loff_t) chunk) * dev->data_bytes_per_chunk;
offset = (u32) (addr - chunk_base);
}
*chunk_out = chunk;
*offset_out = offset;
}
/* Function to return the number of shifts for a power of 2 greater than or
* equal to the given number
* Note we don't try to cater for all possible numbers and this does not have to
* be hellishly efficient.
*/
static inline u32 calc_shifts_ceiling(u32 x)
{
int extra_bits;
int shifts;
shifts = extra_bits = 0;
while (x > 1) {
if (x & 1)
extra_bits++;
x >>= 1;
shifts++;
}
if (extra_bits)
shifts++;
return shifts;
}
/* Function to return the number of shifts to get a 1 in bit 0
*/
static inline u32 calc_shifts(u32 x)
{
u32 shifts;
shifts = 0;
if (!x)
return 0;
while (!(x & 1)) {
x >>= 1;
shifts++;
}
return shifts;
}
/*
* Temporary buffer manipulations.
*/
static int yaffs_init_tmp_buffers(struct yaffs_dev *dev)
{
int i;
u8 *buf = (u8 *) 1;
memset(dev->temp_buffer, 0, sizeof(dev->temp_buffer));
for (i = 0; buf && i < YAFFS_N_TEMP_BUFFERS; i++) {
dev->temp_buffer[i].in_use = 0;
buf = kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS);
dev->temp_buffer[i].buffer = buf;
}
return buf ? YAFFS_OK : YAFFS_FAIL;
}
u8 *yaffs_get_temp_buffer(struct yaffs_dev * dev)
{
int i;
dev->temp_in_use++;
if (dev->temp_in_use > dev->max_temp)
dev->max_temp = dev->temp_in_use;
for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
if (dev->temp_buffer[i].in_use == 0) {
dev->temp_buffer[i].in_use = 1;
return dev->temp_buffer[i].buffer;
}
}
yaffs_trace(YAFFS_TRACE_BUFFERS, "Out of temp buffers");
/*
* If we got here then we have to allocate an unmanaged one
* This is not good.
*/
dev->unmanaged_buffer_allocs++;
return kmalloc(dev->data_bytes_per_chunk, GFP_NOFS);
}
void yaffs_release_temp_buffer(struct yaffs_dev *dev, u8 *buffer)
{
int i;
dev->temp_in_use--;
for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
if (dev->temp_buffer[i].buffer == buffer) {
dev->temp_buffer[i].in_use = 0;
return;
}
}
if (buffer) {
/* assume it is an unmanaged one. */
yaffs_trace(YAFFS_TRACE_BUFFERS, "Releasing unmanaged temp buffer");
kfree(buffer);
dev->unmanaged_buffer_deallocs++;
}
}
/*
* Determine if we have a managed buffer.
*/
int yaffs_is_managed_tmp_buffer(struct yaffs_dev *dev, const u8 *buffer)
{
int i;
for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
if (dev->temp_buffer[i].buffer == buffer)
return 1;
}
for (i = 0; i < dev->param.n_caches; i++) {
if (dev->cache[i].data == buffer)
return 1;
}
if (buffer == dev->checkpt_buffer)
return 1;
yaffs_trace(YAFFS_TRACE_ALWAYS,
"yaffs: unmaged buffer detected.");
return 0;
}
/*
* Functions for robustisizing TODO
*
*/
static void yaffs_handle_chunk_wr_ok(struct yaffs_dev *dev, int nand_chunk,
const u8 *data,
const struct yaffs_ext_tags *tags)
{
/*
dev = dev;
nand_chunk = nand_chunk;
data = data;
tags = tags;
*/
}
static void yaffs_handle_chunk_update(struct yaffs_dev *dev, int nand_chunk,
const struct yaffs_ext_tags *tags)
{
/*
dev = dev;
nand_chunk = nand_chunk;
tags = tags;
*/
}
void yaffs_handle_chunk_error(struct yaffs_dev *dev,
struct yaffs_block_info *bi)
{
if (!bi->gc_prioritise) {
bi->gc_prioritise = 1;
dev->has_pending_prioritised_gc = 1;
bi->chunk_error_strikes++;
if (bi->chunk_error_strikes > 3) {
bi->needs_retiring = 1; /* Too many stikes, so retire */
yaffs_trace(YAFFS_TRACE_ALWAYS,
"yaffs: Block struck out");
}
}
}
static void yaffs_handle_chunk_wr_error(struct yaffs_dev *dev, int nand_chunk,
int erased_ok)
{
int flash_block = nand_chunk / dev->param.chunks_per_block;
struct yaffs_block_info *bi = yaffs_get_block_info(dev, flash_block);
yaffs_handle_chunk_error(dev, bi);
if (erased_ok) {
/* Was an actual write failure,
* so mark the block for retirement.*/
bi->needs_retiring = 1;
yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
"**>> Block %d needs retiring", flash_block);
}
/* Delete the chunk */
yaffs_chunk_del(dev, nand_chunk, 1, __LINE__);
yaffs_skip_rest_of_block(dev);
}
/*
* Verification code
*/
/*
* Simple hash function. Needs to have a reasonable spread
*/
static inline int yaffs_hash_fn(int n)
{
n = abs(n);
return n % YAFFS_NOBJECT_BUCKETS;
}
/*
* Access functions to useful fake objects.
* Note that root might have a presence in NAND if permissions are set.
*/
struct yaffs_obj *yaffs_root(struct yaffs_dev *dev)
{
return dev->root_dir;
}
struct yaffs_obj *yaffs_lost_n_found(struct yaffs_dev *dev)
{
return dev->lost_n_found;
}
/*
* Erased NAND checking functions
*/
int yaffs_check_ff(u8 *buffer, int n_bytes)
{
/* Horrible, slow implementation */
while (n_bytes--) {
if (*buffer != 0xff)
return 0;
buffer++;
}
return 1;
}
static int yaffs_check_chunk_erased(struct yaffs_dev *dev, int nand_chunk)
{
int retval = YAFFS_OK;
u8 *data = yaffs_get_temp_buffer(dev);
struct yaffs_ext_tags tags;
int result;
result = yaffs_rd_chunk_tags_nand(dev, nand_chunk, data, &tags);
if (tags.ecc_result > YAFFS_ECC_RESULT_NO_ERROR)
retval = YAFFS_FAIL;
if (!yaffs_check_ff(data, dev->data_bytes_per_chunk) ||
tags.chunk_used) {
yaffs_trace(YAFFS_TRACE_NANDACCESS,
"Chunk %d not erased", nand_chunk);
retval = YAFFS_FAIL;
}
yaffs_release_temp_buffer(dev, data);
return retval;
}
static int yaffs_verify_chunk_written(struct yaffs_dev *dev,
int nand_chunk,
const u8 *data,
struct yaffs_ext_tags *tags)
{
int retval = YAFFS_OK;
struct yaffs_ext_tags temp_tags;
u8 *buffer = yaffs_get_temp_buffer(dev);
int result;
result = yaffs_rd_chunk_tags_nand(dev, nand_chunk, buffer, &temp_tags);
if (memcmp(buffer, data, dev->data_bytes_per_chunk) ||
temp_tags.obj_id != tags->obj_id ||
temp_tags.chunk_id != tags->chunk_id ||
temp_tags.n_bytes != tags->n_bytes)
retval = YAFFS_FAIL;
yaffs_release_temp_buffer(dev, buffer);
return retval;
}
int yaffs_check_alloc_available(struct yaffs_dev *dev, int n_chunks)
{
int reserved_chunks;
int reserved_blocks = dev->param.n_reserved_blocks;
int checkpt_blocks;
checkpt_blocks = yaffs_calc_checkpt_blocks_required(dev);
reserved_chunks =
(reserved_blocks + checkpt_blocks) * dev->param.chunks_per_block;
return (dev->n
没有合适的资源?快使用搜索试试~ 我知道了~
1B200的rt-thread示例工程
共782个文件
h:199个
d:176个
o:176个
需积分: 0 1 下载量 118 浏览量
2024-04-06
16:19:15
上传
评论
收藏 2.4MB RAR 举报
温馨提示
1B200的rt-thread示例工程
资源推荐
资源详情
资源评论
收起资源包目录
1B200的rt-thread示例工程 (782个子文件)
rtt_newthread.bin 488KB
yaffs_guts.c 120KB
mib2.c 103KB
sockets.c 68KB
yaffsfs.c 66KB
ipc.c 65KB
dhcp.c 63KB
tcp_in.c 59KB
ls1x_gmac.c 59KB
ppp.c 57KB
lcp.c 56KB
tcp.c 52KB
etharp.c 51KB
tcp_out.c 49KB
api_msg.c 45KB
msg_in.c 43KB
pbuf.c 38KB
ipcp.c 38KB
yaffs_yaffs2.c 37KB
ls1x_can.c 37KB
auth.c 35KB
ns16550.c 35KB
simple_gui.c 34KB
udp.c 33KB
cmd.c 33KB
kservice.c 33KB
ppp_oe.c 33KB
finsh_compiler.c 33KB
ip.c 32KB
dns.c 30KB
ls1x_fb_utils.c 30KB
mib_structs.c 29KB
scheduler.c 29KB
ip_frag.c 28KB
igmp.c 26KB
ls1x_nand.c 26KB
finsh_parser.c 26KB
slab.c 25KB
ls1x_rtc.c 25KB
shell.c 24KB
sys_arch.c 24KB
chap.c 24KB
thread.c 24KB
memheap.c 24KB
api_lib.c 23KB
fsm.c 23KB
mem.c 23KB
w25x40.c 23KB
ls1x_fb.c 22KB
netif.c 22KB
touch_utils.c 22KB
msg_out.c 21KB
mem.c 21KB
font_desc.c 20KB
dfs_file.c 19KB
timer.c 19KB
vj.c 18KB
dfs_posix.c 18KB
autoip.c 18KB
ls1x_pwm.c 16KB
asn1_dec.c 16KB
pap.c 16KB
dfs_fs.c 15KB
ls1x_ethernetif.c 15KB
ls1x_yaffs.c 15KB
signal.c 14KB
object.c 14KB
slipif.c 14KB
tcpip.c 14KB
msh.c 14KB
ringblk_buf.c 14KB
asn1_enc.c 14KB
init.c 14KB
memp.c 13KB
rx8010.c 13KB
finsh_token.c 13KB
ls1x_spi_bus.c 13KB
_timers.c 13KB
inet_chksum.c 13KB
yaffs_verify.c 13KB
dfs.c 12KB
device.c 12KB
mempool.c 12KB
ads1015.c 12KB
md5.c 11KB
chpms.c 11KB
icmp.c 11KB
pipe.c 11KB
netdb.c 11KB
raw.c 10KB
workqueue.c 10KB
yaffs_yaffs1.c 10KB
yaffs_checkptrw.c 10KB
yaffs_tagscompat.c 10KB
ls1x_i2c_bus.c 10KB
finsh_ops.c 10KB
ethernetif.c 9KB
pca9557.c 9KB
ringbuffer.c 9KB
dataqueue.c 8KB
共 782 条
- 1
- 2
- 3
- 4
- 5
- 6
- 8
资源评论
leibaer
- 粉丝: 117
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功