• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 GOODIX.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <sys/mount.h>
16 #include "littlefs.h"
17 #include "los_config.h"
18 #include "hdf_log.h"
19 #include "hdf_device_desc.h"
20 #include "device_resource_if.h"
21 #include "lfs_api.h"
22 
23 #define LFS_CFG_READ_SIZE       16
24 #define LFS_CFG_PROG_SIZE       16
25 #define LFS_CFG_CACHE_SIZE      16
26 #define LFS_CFG_LOOKAHEAD_SIZE  32
27 #define LFS_CFG_BLOCK_CYCLES    500
28 
29 struct fs_cfg {
30     char *mount_point;
31     struct lfs_config lfs_cfg;
32 };
33 
34 static struct fs_cfg fs[LOSCFG_LFS_MAX_MOUNT_SIZE] = {0};
35 
FsGetResource(struct fs_cfg * fs,const struct DeviceResourceNode * resourceNode)36 static uint32_t FsGetResource(struct fs_cfg *fs, const struct DeviceResourceNode *resourceNode)
37 {
38     struct DeviceResourceIface *resource = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
39     if (resource == NULL) {
40         HDF_LOGE("Invalid DeviceResourceIface");
41         return HDF_FAILURE;
42     }
43     int32_t num = resource->GetElemNum(resourceNode, "mount_points");
44     if (num < 0 || num > LOSCFG_LFS_MAX_MOUNT_SIZE) {
45         HDF_LOGE("%s: invalid mount_points num %d", __func__, num);
46         return HDF_FAILURE;
47     }
48     for (int32_t i = 0; i < num; i++) {
49         if (resource->GetStringArrayElem(resourceNode, "mount_points", i, &fs[i].mount_point, NULL) != HDF_SUCCESS) {
50             HDF_LOGE("%s: failed to get mount_points", __func__);
51             return HDF_FAILURE;
52         }
53         if (resource->GetUint32ArrayElem(resourceNode, "partitions", i,
54                                          (uint32_t *)&fs[i].lfs_cfg.context, 0) != HDF_SUCCESS) {
55             HDF_LOGE("%s: failed to get partitions", __func__);
56             return HDF_FAILURE;
57         }
58         if (resource->GetUint32ArrayElem(resourceNode, "block_size", i, &fs[i].lfs_cfg.block_size, 0) != HDF_SUCCESS) {
59             HDF_LOGE("%s: failed to get block_size", __func__);
60             return HDF_FAILURE;
61         }
62         if (resource->GetUint32ArrayElem(resourceNode, "block_count", i,
63                                          &fs[i].lfs_cfg.block_count, 0) != HDF_SUCCESS) {
64             HDF_LOGE("%s: failed to get block_count", __func__);
65             return HDF_FAILURE;
66         }
67         HDF_LOGD("%s: fs[%d] mount_point=%s, partition=%u, block_size=%u, block_count=%u", __func__, i,
68                  fs[i].mount_point, (uint32_t)fs[i].lfs_cfg.context, fs[i].lfs_cfg.block_size,
69                  fs[i].lfs_cfg.block_count);
70     }
71     return HDF_SUCCESS;
72 }
73 
FsDriverInit(struct HdfDeviceObject * object)74 static int32_t FsDriverInit(struct HdfDeviceObject *object)
75 {
76     struct FileOpInfo *fileOpInfo = NULL;
77 
78     if (object == NULL) {
79         return HDF_FAILURE;
80     }
81     if (object->property) {
82         if (FsGetResource(fs, object->property) != HDF_SUCCESS) {
83             HDF_LOGE("%s: FsGetResource failed", __func__);
84             return HDF_FAILURE;
85         }
86     }
87 
88     for (int i = 0; i < sizeof(fs) / sizeof(fs[0]); i++) {
89         if (fs[i].mount_point == NULL) {
90             continue;
91         }
92         fs[i].lfs_cfg.read  = littlefs_block_read;
93         fs[i].lfs_cfg.prog  = littlefs_block_write;
94         fs[i].lfs_cfg.erase = littlefs_block_erase;
95         fs[i].lfs_cfg.sync  = littlefs_block_sync;
96 
97         fs[i].lfs_cfg.read_size = LFS_CFG_READ_SIZE;
98         fs[i].lfs_cfg.prog_size = LFS_CFG_PROG_SIZE;
99         fs[i].lfs_cfg.cache_size = LFS_CFG_CACHE_SIZE;
100         fs[i].lfs_cfg.lookahead_size = LFS_CFG_LOOKAHEAD_SIZE;
101         fs[i].lfs_cfg.block_cycles = LFS_CFG_BLOCK_CYCLES;
102 
103         SetDefaultMountPath(i, fs[i].mount_point);
104         littlefs_flash_init(&fs[i].lfs_cfg);
105 
106         int ret = mount(NULL, fs[i].mount_point, "littlefs", 0, &fs[i].lfs_cfg);
107         HDF_LOGI("%s: mount fs on '%s' %s\n", __func__, fs[i].mount_point, (ret == 0) ? "succeed" : "failed");
108         if (CheckPathIsMounted(fs[i].mount_point, &fileOpInfo) == TRUE) {
109             int lfs_ret = lfs_mkdir(&fileOpInfo->lfsInfo, fs[i].mount_point);
110             if (lfs_ret == LFS_ERR_OK) {
111                 HDF_LOGI("create root dir success.");
112             } else if (lfs_ret == LFS_ERR_EXIST) {
113                 HDF_LOGI("root dir exist.");
114             } else {
115                 HDF_LOGI("create root dir failed.");
116             }
117         }
118     }
119 
120     return HDF_SUCCESS;
121 }
122 
FsDriverBind(struct HdfDeviceObject * device)123 static int32_t FsDriverBind(struct HdfDeviceObject *device)
124 {
125     (void)device;
126     return HDF_SUCCESS;
127 }
128 
FsDriverRelease(struct HdfDeviceObject * device)129 static void FsDriverRelease(struct HdfDeviceObject *device)
130 {
131     (void)device;
132 }
133 
134 static struct HdfDriverEntry g_fsDriverEntry = {
135     .moduleVersion = 1,
136     .moduleName = "HDF_FS_LITTLEFS",
137     .Bind = FsDriverBind,
138     .Init = FsDriverInit,
139     .Release = FsDriverRelease,
140 };
141 
142 HDF_INIT(g_fsDriverEntry);
143