• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  *    conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *    of conditions and the following disclaimer in the documentation and/or other materials
12  *    provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15  *    to endorse or promote products derived from this software without specific prior written
16  *    permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "mtd_legacy_lite.h"
32 #include "hdf_log.h"
33 #include "mtd_core.h"
34 #include "mtd_list.h"
35 #include "osal_mem.h"
36 #include "string.h"
37 
38 struct MtdDevNode {
39     char *type;
40     int status;
41     struct MtdDev *mtdDev;
42     struct MtdDevNode *next;
43 };
44 
45 static struct MtdDevNode g_mtdHead;
46 
GetMtd(const char * type)47 void *GetMtd(const char *type)
48 {
49     struct MtdDevNode *p = NULL;
50 
51     if (type == NULL) {
52         return NULL;
53     }
54 
55     for (p = g_mtdHead.next; p != NULL; p = p->next) {
56         if (strcmp(type, p->type) == 0) {
57             p->status++;
58             return p->mtdDev;
59         }
60     }
61     return NULL;
62 }
63 
GetMtdInfo(const char * type)64 int GetMtdInfo(const char *type)
65 {
66     struct MtdDevNode *p = NULL;
67 
68     if (type == NULL) {
69         return -1;
70     }
71 
72     for (p = g_mtdHead.next; p != NULL; p = p->next) {
73         if (strcmp(type, p->type) == 0) {
74             return 0;
75         }
76     }
77     return -1;
78 }
79 
FreeMtd(struct MtdDev * mtdDev)80 int FreeMtd(struct MtdDev *mtdDev)
81 {
82     struct MtdDevNode *p = NULL;
83 
84     if (mtdDev == NULL) {
85         return -1;
86     }
87 
88     for (p = g_mtdHead.next; p != NULL; p = p->next) {
89         if (p->mtdDev == mtdDev) {
90             p->status--;
91             return 0;
92         }
93     }
94 
95     return -1;
96 }
97 
DelMtdList(struct MtdDev * mtdDev)98 int DelMtdList(struct MtdDev *mtdDev)
99 {
100     struct MtdDevNode *p = NULL;
101     struct MtdDevNode *q = NULL;
102 
103     if (mtdDev == NULL) {
104         return -1;
105     }
106 
107     for (p = g_mtdHead.next, q = &g_mtdHead; p != NULL; q = p, p = p->next) {
108         if (p->mtdDev == mtdDev) {
109             if (p->status == 0) {
110                 q->next = p->next;
111                 free(p);
112                 return 0;
113             }
114             return -1;
115         }
116     }
117     return -1;
118 }
119 
AddMtdList(char * type,struct MtdDev * mtdDev)120 void AddMtdList(char *type, struct MtdDev *mtdDev)
121 {
122     struct MtdDevNode *p = NULL;
123     struct MtdDevNode *q = NULL;
124 
125     if (type == NULL || mtdDev == NULL) {
126         return;
127     }
128 
129     p = g_mtdHead.next;
130     q = (struct MtdDevNode *)OsalMemCalloc(sizeof(*q));
131     if (q == NULL) {
132         return;
133     }
134 
135     q->type = type;
136     q->mtdDev = mtdDev;
137     q->status = 0;
138     g_mtdHead.next = q;
139     q->next = p;
140 }
141 
142 MtdInfoLegacy g_mtdInfo;
143 MtdInfoLegacy *nand_mtd;
144 struct MtdDevice *g_nandMtd;
145 /************** compatibale of old hisi interfaces ***************************/
146 // from device/hisilicon/drivers/xxxx/mtd/nand/src/common/nand.c
nand_init(void)147 int nand_init(void)
148 {
149     HDF_LOGI("%s: this is a stub cause new mtd drivers has been used", __func__);
150     return 0;
151 }
152 
153 // form device/hisilicon/drivers/xxxx/mtd/nand/src/common/nand_utils.c
hinand_read(void * memaddr,unsigned long start,unsigned long size)154 int hinand_read(void *memaddr, unsigned long start, unsigned long size)
155 {
156     int32_t ret;
157 
158     if (g_nandMtd == NULL) {
159         HDF_LOGE("%s: g_nandMtd is null", __func__);
160         return -ENODEV;
161     }
162     ret = MtdDeviceRead(g_nandMtd, (off_t)start, (size_t)size, (uint8_t *)memaddr);
163     if ((unsigned long)ret != size) {
164         HDF_LOGE("%s: ret=%d, size=%lu", __func__, ret, size);
165     }
166     return ((unsigned long)ret == size) ? HDF_SUCCESS : ret;
167 }
168 
hinand_write(void * memaddr,unsigned long start,unsigned long size)169 int hinand_write(void *memaddr, unsigned long start, unsigned long size)
170 {
171     int32_t ret;
172 
173     if (g_nandMtd == NULL) {
174         HDF_LOGE("%s: g_nandMtd is null", __func__);
175         return -ENODEV;
176     }
177     ret = MtdDeviceWrite(g_nandMtd, (off_t)start, (size_t)size, (const uint8_t *)memaddr);
178     if ((unsigned long)ret != size) {
179         HDF_LOGE("%s: ret=%d, size=%lu", __func__, ret, size);
180     }
181     return ((unsigned long)ret == size) ? HDF_SUCCESS : ret;
182 }
183 
hinand_erase(unsigned long start,unsigned long size)184 int hinand_erase(unsigned long start, unsigned long size)
185 {
186     int ret;
187     off_t failAddr;
188 
189     if (g_nandMtd == NULL) {
190         HDF_LOGE("%s: g_nandMtd is null", __func__);
191         return -ENODEV;
192     }
193     ret = MtdDeviceErase(g_nandMtd, (off_t)start, (size_t)size, &failAddr);
194     if (ret != 0) {
195         HDF_LOGE("%s: MtdDeviceErase failed, ret=%d", __func__, ret);
196     }
197     return ret;
198 }
199 
hinand_yaffs_read(void * memaddr,unsigned long start,unsigned long size)200 int hinand_yaffs_read(void *memaddr, unsigned long start, unsigned long size)
201 {
202     int32_t ret;
203 
204     if (g_nandMtd == NULL) {
205         HDF_LOGE("%s: g_nandMtd is null", __func__);
206         return -ENODEV;
207     }
208     ret = MtdDeviceReadWithOob(g_nandMtd, (off_t)start, (size_t)size, (uint8_t *)memaddr);
209     if ((unsigned long)ret != size) {
210         HDF_LOGE("%s: ret=%d, size=%lu", __func__, ret, size);
211     }
212     return ((unsigned long)ret == size) ? HDF_SUCCESS : ret;
213 }
214 
hinand_yaffs_write(void * memaddr,unsigned long start,unsigned long size)215 int hinand_yaffs_write(void *memaddr, unsigned long start, unsigned long size)
216 {
217     int32_t ret;
218 
219     if (g_nandMtd == NULL) {
220         HDF_LOGE("%s: g_nandMtd is null", __func__);
221         return -ENODEV;
222     }
223     ret = MtdDeviceWriteWithOob(g_nandMtd, (off_t)start, (size_t)size, (uint8_t *)memaddr);
224     if ((unsigned long)ret != size) {
225         HDF_LOGE("%s: ret=%d, size=%lu", __func__, ret, size);
226     }
227     return ((unsigned long)ret == size) ? HDF_SUCCESS : ret;
228 }
229 
hinand_yaffs_nand_block_isbad(loff_t ofs)230 int hinand_yaffs_nand_block_isbad(loff_t ofs)
231 {
232     return MtdDeviceIsBadBlock(g_nandMtd, ofs);
233 }
234 
hinand_yaffs_nand_block_markbad(loff_t ofs)235 int hinand_yaffs_nand_block_markbad(loff_t ofs)
236 {
237     return MtdDeviceMarkBadBlock(g_nandMtd, ofs);
238 }
239 
spinor_init(void)240 int spinor_init(void)
241 {
242     HDF_LOGI("%s: this function has been hacked ...", __func__);
243     return HDF_SUCCESS;
244 }
245 
MtdDeviceLegacyNandErase(MtdInfoLegacy * mtd,EraseInfoLegacy * ops)246 static int MtdDeviceLegacyNandErase(MtdInfoLegacy *mtd, EraseInfoLegacy *ops)
247 {
248     int ret;
249     off_t failAddr;
250 
251     if (mtd == NULL || ops == NULL) {
252         return -EINVAL;
253     }
254     ops->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
255 
256     ret = MtdDeviceErase((struct MtdDevice *)mtd->priv, (off_t)ops->addr, (size_t)ops->len, &failAddr);
257     if (ret != HDF_SUCCESS) {
258         ops->fail_addr = failAddr;
259     }
260     return ret;
261 }
262 
MtdDeviceLegacyNandRead(MtdInfoLegacy * mtd,off_t addr,size_t len,size_t * retlen,char * buf)263 static int MtdDeviceLegacyNandRead(MtdInfoLegacy *mtd, off_t addr, size_t len, size_t *retlen, char *buf)
264 {
265     int ret;
266 
267     if (mtd == NULL) {
268         return -EINVAL;
269     }
270 
271     ret = MtdDeviceRead((struct MtdDevice *)mtd->priv, addr, len, (uint8_t *)buf);
272     *retlen = (ret == HDF_SUCCESS) ? len : 0;
273     return ret;
274 }
275 
MtdDeviceLegacyNandWrite(MtdInfoLegacy * mtd,off_t addr,size_t len,size_t * retlen,const char * buf)276 static int MtdDeviceLegacyNandWrite(MtdInfoLegacy *mtd, off_t addr, size_t len, size_t *retlen, const char *buf)
277 {
278     int ret;
279 
280     if (mtd == NULL) {
281         return -EINVAL;
282     }
283 
284     ret = MtdDeviceWrite((struct MtdDevice *)mtd->priv, addr, len, (const uint8_t *)buf);
285     *retlen = (ret == HDF_SUCCESS) ? len : 0;
286     return ret;
287 }
288 
MtdDeviceLegacyNandReadOob(MtdInfoLegacy * mtd,off_t addr,size_t len,size_t * retlen,char * buf)289 static int MtdDeviceLegacyNandReadOob(MtdInfoLegacy *mtd, off_t addr, size_t len, size_t *retlen, char *buf)
290 {
291     int ret;
292 
293     if (mtd == NULL) {
294         return -EINVAL;
295     }
296 
297     ret = MtdDeviceReadWithOob((struct MtdDevice *)mtd->priv, addr, len, (uint8_t *)buf);
298     *retlen = (ret == HDF_SUCCESS) ? len : 0;
299     return ret;
300 }
301 
MtdDeviceLegacyNandWriteOob(MtdInfoLegacy * mtd,off_t addr,size_t len,size_t * retlen,const char * buf)302 static int MtdDeviceLegacyNandWriteOob(MtdInfoLegacy *mtd, off_t addr, size_t len, size_t *retlen, const char *buf)
303 {
304     int ret;
305 
306     if (mtd == NULL) {
307         return -EINVAL;
308     }
309 
310     ret = MtdDeviceWriteWithOob((struct MtdDevice *)mtd->priv, addr, len, (const uint8_t *)buf);
311     *retlen = (ret == HDF_SUCCESS) ? len : 0;
312     return ret;
313 }
314 
MtdDeviceLegacyBlockIsBad(MtdInfoLegacy * mtd,off_t ofs)315 static int MtdDeviceLegacyBlockIsBad(MtdInfoLegacy *mtd, off_t ofs)
316 {
317     if (mtd == NULL) {
318         return -EINVAL;
319     }
320 
321     return (int)MtdDeviceIsBadBlock((struct MtdDevice *)mtd->priv, ofs);
322 }
323 
MtdDeviceLegacyBlockMarkBad(MtdInfoLegacy * mtd,off_t ofs)324 static int MtdDeviceLegacyBlockMarkBad(MtdInfoLegacy *mtd, off_t ofs)
325 {
326     if (mtd == NULL) {
327         return -EINVAL;
328     }
329 
330     return (int)MtdDeviceMarkBadBlock((struct MtdDevice *)mtd->priv, ofs);
331 }
332 
MtdDeviceLegacyFillMtdInfo(struct MtdDevice * mtdDevice)333 void MtdDeviceLegacyFillMtdInfo(struct MtdDevice *mtdDevice)
334 {
335     if (mtdDevice == NULL) {
336         return;
337     }
338     nand_mtd = &g_mtdInfo;
339 
340     nand_mtd->size = mtdDevice->capacity;
341     nand_mtd->erasesize = mtdDevice->eraseSize;
342     nand_mtd->writesize = mtdDevice->writeSize;
343     nand_mtd->oobsize = mtdDevice->oobSize;
344     nand_mtd->name = "nand";
345     nand_mtd->type = MTD_NANDFLASH;
346     nand_mtd->flags = MTD_CAP_NANDFLASH;
347 
348     nand_mtd->erase = MtdDeviceLegacyNandErase;
349     nand_mtd->read = MtdDeviceLegacyNandRead;
350     nand_mtd->write = MtdDeviceLegacyNandWrite;
351     nand_mtd->read_oob = MtdDeviceLegacyNandReadOob;
352     nand_mtd->write_oob = MtdDeviceLegacyNandWriteOob;
353     nand_mtd->block_isbad = MtdDeviceLegacyBlockIsBad;
354     nand_mtd->block_markbad = MtdDeviceLegacyBlockMarkBad;
355     nand_mtd->priv = mtdDevice;
356 
357     g_nandMtd = mtdDevice;
358 }
359