40#include "mtd/mtd_legacy_lite.h"
42#ifdef LOSCFG_PLATFORM_QEMU_ARM_VIRT_CA7
47#define DRIVER_NAME_ADD_SIZE 3
65static VOID YaffsLockDeinit(VOID)
__attribute__((weakref(
"yaffsfs_OsDestroy")));
67static VOID Jffs2LockDeinit(VOID)
__attribute__((weakref(
"Jffs2MutexDelete")));
78 return g_nandPartParam;
83 return g_spinorPartParam;
88 return g_spinorPartitionHead;
101 nandParam->
char_ops = GetMtdCharFops();
110 if (YaffsLockDeinit != NULL) {
118 if (nandMtd == NULL) {
121 if (nandParam == NULL) {
126 if (nandParam == NULL) {
131 if (g_nandPartitionHead == NULL) {
151#ifndef LOSCFG_PLATFORM_QEMU_ARM_VIRT_CA7
152 spinorParam->
flash_ops = GetDevSpinorOps();
153 spinorParam->
char_ops = GetMtdCharFops();
155 spinorParam->
charname = SPICHR_NAME;
168 if (Jffs2LockDeinit != NULL) {
175#ifndef LOSCFG_PLATFORM_QEMU_ARM_VIRT_CA7
178 struct MtdDev *spinorMtd = GetCfiMtdDev();
180 if (spinorMtd == NULL) {
183 if (spinorParam == NULL) {
184 if (Jffs2LockInit != NULL) {
185 if (Jffs2LockInit() != 0) {
190 if (spinorParam == NULL) {
191 PRINT_ERR(
"%s, partition_param malloc failed\n", __FUNCTION__);
196 if (g_spinorPartitionHead == NULL) {
197 PRINT_ERR(
"%s, mtd_partition malloc failed\n", __FUNCTION__);
212 if (strcmp(
type,
"nand") == 0) {
214 *fsparParam = g_nandPartParam;
215 }
else if (strcmp(
type,
"spinor") == 0 || strcmp(
type,
"cfi-flash") == 0) {
217 *fsparParam = g_spinorPartParam;
222 if ((*fsparParam == NULL) || ((VOID *)((*fsparParam)->flash_mtd) == NULL)) {
232 if (strcmp(
type,
"nand") == 0) {
234 g_nandPartParam = NULL;
235 }
else if (strcmp(
type,
"spinor") == 0 || strcmp(
type,
"cfi-flash") == 0) {
237 g_spinorPartParam = NULL;
256 if ((length == 0) || (length < param->block_size) ||
261 ALIGN_ASSIGN(length, startAddr, startBlk, endBlk, param->
block_size);
263 if (startBlk > endBlk) {
270 if ((startBlk > node->
end_block) || (endBlk < node->start_block)) {
284 size_t driverNameSize;
287 driverNameSize = strlen(param->
blockname) + DRIVER_NAME_ADD_SIZE;
294 driverNameSize - 1,
"%s%u", param->
blockname, partitionNum);
298 return -ENAMETOOLONG;
306 PRINT_ERR(
"register blkdev partition error\n");
320 size_t driverNameSize;
323 driverNameSize = strlen(param->
charname) + DRIVER_NAME_ADD_SIZE;
330 driverNameSize - 1,
"%s%u", param->
charname, partitionNum);
334 return -ENAMETOOLONG;
339 PRINT_ERR(
"register chardev partition error\n");
357 PRINT_ERR(
"unregister blkdev partition error:%d\n", ret);
373 PRINT_ERR(
"unregister chardev partition error:%d\n", ret);
401 if ((partitionNum >= CONFIG_MTD_PATTITION_NUM) || (
type == NULL)) {
407 PRINT_ERR(
"%s %d, mutex lock failed, error:%d\n", __FUNCTION__, __LINE__, ret);
421 if (newNode == NULL) {
426 PAR_ASSIGNMENT(newNode, length, startAddr, partitionNum, param->
flash_mtd, param->
block_size);
443 PRINT_ERR(
"%s %d, mutex unlock failed, error:%d\n", __FUNCTION__, __LINE__, ret);
460 if (strcmp(
type,
"nand") == 0) {
461 *param = g_nandPartParam;
462 }
else if (strcmp(
type,
"spinor") == 0 || strcmp(
type,
"cfi-flash") == 0) {
463 *param = g_spinorPartParam;
465 PRINT_ERR(
"type error \n");
469 if ((partitionNum >= CONFIG_MTD_PATTITION_NUM) ||
470 ((*param) == NULL) || ((*param)->flash_mtd == NULL)) {
496 if ((*node)->patitionnum == partitionNum) {
500 if ((*node == NULL) || ((*node)->patitionnum != partitionNum) ||
501 ((*node)->mountpoint_name != NULL)) {
539 PRINT_ERR(
"%s %d, mutex lock failed, error:%d\n", __FUNCTION__, __LINE__, ret);
544 PRINT_ERR(
"delete_mtd_partition param invalid\n");
549 ret =
OsNodeGet(&node, partitionNum, param);
557 PRINT_ERR(
"DeletePartitionUnregister error:%d\n", ret);
564 PRINT_ERR(
"DeletePartitionUnregister error:%d\n", ret);
571 PRINT_ERR(
"%s %d, mutex unlock failed, error:%d\n", __FUNCTION__, __LINE__, ret);
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a node to the tail of a doubly linked list.
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
Identify whether a specified doubly linked list is empty. | 判断链表是否为空
LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr)
初始化互斥锁
LITE_OS_SEC_TEXT UINT32 LOS_MuxDestroy(LosMux *mutex)
销毁互斥锁
INT32 add_mtd_partition(const CHAR *type, UINT32 startAddr, UINT32 length, UINT32 partitionNum)
Add a partition.
INT32 delete_mtd_partition(UINT32 partitionNum, const CHAR *type)
删除MTD分区
__attribute__((aligned(MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS)))
void * zalloc(size_t size)
void * malloc(size_t size)
动态分配内存块大小
void free(void *ptr)
释放ptr所指向的内存空间
void * GetMtd(const char *type)
int FreeMtd(struct MtdDev *mtd)
static VOID YaffsLockInit(VOID)
static VOID MtdDeinitSpinorParam(VOID)
static partition_param * MtdInitSpinorParam(partition_param *spinorParam)
spi nor flash 参数初始化
static INT32 BlockDriverUnregister(mtd_partition *node)
注销块设备驱动
static INT32 DeleteParamCheck(UINT32 partitionNum, const CHAR *type, partition_param **param)
检查分区参数
static INT32 AddParamCheck(UINT32 startAddr, const partition_param *param, UINT32 partitionNum, UINT32 length)
增加MTD分区参数检查
static VOID MtdNandParamAssign(partition_param *nandParam, const struct MtdDev *nandMtd)
static INT32 DeletePartitionUnregister(mtd_partition *node)
删除分区驱动程序,注意每个分区的文件系统都可以不一样,驱动程序也都不同
mtd_partition * GetSpinorPartitionHead(VOID)
static VOID MtdNorParamAssign(partition_param *spinorParam, const struct MtdDev *spinorMtd)
nor flash 初始化,本函数只会被调用一次
static partition_param * MtdInitNandParam(partition_param *nandParam)
nand flash 初始化
pthread_mutex_t g_mtdPartitionLock
static INT32 BlockDriverRegisterOperate(mtd_partition *newNode, const partition_param *param, UINT32 partitionNum)
注册块设备,此函数之后设备将支持VFS访问
static VOID MtdDeinitNandParam(VOID)
反初始化
static INT32 OsResourceRelease(mtd_partition *node, const CHAR *type, partition_param *param)
释放分区链表节点所占内存 sizeof(mtd_partition)
static INT32 CharDriverUnregister(mtd_partition *node)
注销字符设备驱动
partition_param * GetSpinorPartParam(VOID)
static INT32 MtdInitFsparParam(const CHAR *type, partition_param **fsparParam)
根据 flash-type 来初始化分区的参数, Fspar 是不是 flash partition 的意思? 这名字取得有点费解 @note_thinking
static INT32 OsNodeGet(mtd_partition **node, UINT32 partitionNum, const partition_param *param)
获取分区链表节点
static INT32 MtdDeinitFsparParam(const CHAR *type)
根据flash-type 去初始化 分区的参数。
static INT32 CharDriverRegisterOperate(mtd_partition *newNode, const partition_param *param, UINT32 partitionNum)
注册字符设备,此函数之后设备将支持VFS访问
partition_param * GetNandPartParam(VOID)
struct mtd_node mtd_partition
通过mknod在/dev子目录下建立MTD块设备节点(主设备号为31)和MTD字符设备节点(主设备号为90)
int pthread_mutex_lock(pthread_mutex_t *mutex)
互斥锁加锁操作
int pthread_mutex_unlock(pthread_mutex_t *mutex)
解锁互斥锁
UINT32 eraseSize
4K, 跟PAGE_CACHE_SIZE对应
通过mknod在/dev子目录下建立MTD块设备节点(主设备号为31)和MTD字符设备节点(主设备号为90)
CHAR * blockdriver_name
块设备驱动名称 例如: /dev/spinorblk0p0
CHAR * chardriver_name
字符设备驱动名称 例如: /dev/nandchr0p2
LOS_DL_LIST node_info
双循环节点,挂在首个分区节点上
分区参数描述符,一个分区既可支持按块访问也可以支持按字符访问,只要有驱动程序就阔以
const struct file_operations_vfs * char_ops
字符方式的操作数据
mtd_partition * partition_head
首个分区,其他分区都挂在.node_info节点上
const struct block_operations * flash_ops
块方式的操作数据
struct MtdDev * flash_mtd
flash设备描述符,属于硬件驱动层
UINT32 block_size
块单位(4K),对文件系统而言是按块读取数据,方便和内存页置换