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