• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-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 "osal_firmware.h"
32 #include <limits.h>
33 #include <sys/stat.h>
34 #include <unistd.h>
35 #include "fs/file.h"
36 #include "hdf_log.h"
37 #include "osal_mem.h"
38 
39 #define HDF_LOG_TAG osal_fw
40 #define HDF_FW_BLOCK_SIZE 64
41 
42 struct OsalFwDesc {
43     int32_t fd;
44     uint8_t *buff;
45     uint32_t offset;
46     bool openFlag;
47 };
48 
OsalRequestFirmware(struct OsalFirmware * fwPara,const char * fwName,void * device)49 int32_t OsalRequestFirmware(struct OsalFirmware *fwPara, const char *fwName, void *device)
50 {
51     struct OsalFwDesc *fw = NULL;
52     uint8_t *base = NULL;
53     struct stat fwStat;
54     char path[PATH_MAX + 1] = {0};
55     int32_t fd = -1;
56 
57     (void)device;
58     if (fwPara == NULL || fwName == NULL) {
59         HDF_LOGE("%s invalid param", __func__);
60         return HDF_ERR_INVALID_PARAM;
61     }
62 
63     fwPara->fwSize = 0;
64     fwPara->para = NULL;
65 
66     if (realpath(fwName, path) == NULL) {
67         HDF_LOGE("%s file name is invalid\n", __func__);
68         return HDF_FAILURE;
69     }
70 
71     fd = open(path, O_RDONLY, S_IREAD);
72     if (fd == -1) {
73         HDF_LOGE("%s open file fail %d", __func__, errno);
74         return HDF_FAILURE;
75     }
76 
77     if (fstat(fd, &fwStat) == -1) {
78         HDF_LOGE("%s fstat file fail %d", __func__, errno);
79         close(fd);
80         return HDF_FAILURE;
81     }
82 
83     base = (uint8_t *)OsalMemCalloc(sizeof(*fw) + HDF_FW_BLOCK_SIZE);
84     if (base == NULL) {
85         HDF_LOGE("%s malloc fail", __func__);
86         close(fd);
87         return HDF_ERR_MALLOC_FAIL;
88     }
89 
90     fw = (struct OsalFwDesc *)base;
91     fw->fd = fd;
92     fwPara->fwSize = (uint32_t)fwStat.st_size;
93 
94     fw->openFlag = true;
95     fw->buff = base + sizeof(*fw);
96     fw->offset = 0;
97 
98     fwPara->para = (void *)fw;
99 
100     return HDF_SUCCESS;
101 }
102 
OsalSeekFirmware(struct OsalFirmware * fwPara,uint32_t offset)103 int32_t OsalSeekFirmware(struct OsalFirmware *fwPara, uint32_t offset)
104 {
105     struct OsalFwDesc *fw = NULL;
106 
107     if (fwPara == NULL || offset >= fwPara->fwSize || fwPara->para == NULL) {
108         HDF_LOGE("%s invalid param", __func__);
109         return HDF_ERR_INVALID_PARAM;
110     }
111 
112     fw = (struct OsalFwDesc *)fwPara->para;
113     fw->offset = offset;
114 
115     return HDF_SUCCESS;
116 }
117 
OsalReadFirmware(struct OsalFirmware * fwPara,struct OsalFwBlock * block)118 int32_t OsalReadFirmware(struct OsalFirmware *fwPara, struct OsalFwBlock *block)
119 {
120     uint32_t readOffset;
121     uint32_t readSize;
122     struct OsalFwDesc *fw = NULL;
123 
124     if (fwPara == NULL || fwPara->para == NULL || block == NULL) {
125         HDF_LOGE("%s invalid param",  __func__);
126         return HDF_ERR_INVALID_PARAM;
127     }
128 
129     fw = (struct OsalFwDesc *)fwPara->para;
130     if (fw->openFlag == false) {
131         HDF_LOGE("%s file do not open",  __func__);
132         return HDF_ERR_INVALID_PARAM;
133     }
134 
135     block->data = fw->buff;
136     block->endFlag = false;
137     block->dataSize = HDF_FW_BLOCK_SIZE;
138 
139     if (fw->offset >= fwPara->fwSize) {
140         HDF_LOGE("%s file offset invalid %d %d", __func__, fw->offset, fwPara->fwSize);
141         return HDF_ERR_INVALID_PARAM;
142     }
143 
144     if (fw->offset + block->dataSize >= fwPara->fwSize) {
145         block->dataSize = fwPara->fwSize - fw->offset;
146         block->endFlag = true;
147     }
148 
149     if (fw->fd == -1) {
150         HDF_LOGE("%s invalid file id",  __func__);
151         return HDF_ERR_INVALID_PARAM;
152     }
153 
154     readOffset = (uint32_t)lseek(fw->fd, fw->offset, SEEK_SET);
155     if (readOffset != fw->offset) {
156         HDF_LOGE("%s seek offset fail %d %d", __func__, readOffset, fw->offset);
157         return HDF_FAILURE;
158     }
159     readSize = (uint32_t)read(fw->fd, block->data, block->dataSize);
160     if (readSize != block->dataSize) {
161         HDF_LOGE("%s read file fail %d %d", __func__, readSize, block->dataSize);
162         return HDF_FAILURE;
163     }
164 
165     block->curOffset = fw->offset;
166     fw->offset += block->dataSize;
167 
168     return HDF_SUCCESS;
169 }
170 
OsalReleaseFirmware(struct OsalFirmware * fwPara)171 int32_t OsalReleaseFirmware(struct OsalFirmware *fwPara)
172 {
173     struct OsalFwDesc *fw = NULL;
174 
175     if (fwPara == NULL || fwPara->para == NULL) {
176         HDF_LOGE("%s invalid param", __func__);
177         return HDF_ERR_INVALID_PARAM;
178     }
179 
180     fw = (struct OsalFwDesc *)fwPara->para;
181     if (fw->fd == -1) {
182         HDF_LOGE("%s invalid file id",  __func__);
183         return HDF_ERR_INVALID_PARAM;
184     }
185 
186     if (close(fw->fd) != 0) {
187         HDF_LOGE("%s close fail %d",  __func__, errno);
188         return HDF_FAILURE;
189     }
190     OsalMemFree(fwPara->para);
191     fwPara->para = NULL;
192 
193     return HDF_SUCCESS;
194 }
195 
196