1 /*
2 * Copyright (C) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include <linux/fs.h>
20 #include <asm/uaccess.h>
21 #include "hi_osal.h"
22 #include "securec.h"
23
24 char *g_klib_store_path = NULL;
25
klib_fopen(const char * filename,int flags,int mode)26 struct file *klib_fopen(const char *filename, int flags, int mode)
27 {
28 struct file *filp = filp_open(filename, flags, mode);
29 return (IS_ERR(filp)) ? NULL : filp;
30 }
31
klib_fclose(struct file * filp)32 void klib_fclose(struct file *filp)
33 {
34 if (filp != NULL) {
35 filp_close(filp, NULL);
36 }
37 return;
38 }
39
klib_fwrite(const char * buf,unsigned long size,struct file * filp)40 int klib_fwrite(const char *buf, unsigned long size, struct file *filp)
41 {
42 int writelen;
43
44 if (filp == NULL) {
45 return -ENOENT;
46 }
47
48 writelen = __kernel_write(filp, buf, size, &filp->f_pos);
49 return writelen;
50 }
51
klib_fread(char * buf,unsigned long size,struct file * filp)52 int klib_fread(char *buf, unsigned long size, struct file *filp)
53 {
54 mm_segment_t old_fs;
55 int readlen;
56
57 if (filp == NULL) {
58 return -ENOENT;
59 }
60
61 old_fs = get_fs();
62 set_fs(KERNEL_DS);
63 /* The cast to a user pointer is valid due to the set_fs() */
64 readlen = vfs_read(filp, (void __user *)buf, size, &filp->f_pos);
65 set_fs(old_fs);
66 return readlen;
67 }
68
osal_klib_fopen(const char * filename,int flags,int mode)69 void *osal_klib_fopen(const char *filename, int flags, int mode)
70 {
71 if (filename == NULL) {
72 osal_printk("%s - filename NULL\n", __FUNCTION__);
73 return NULL;
74 }
75
76 return (void *)klib_fopen(filename, flags, mode);
77 }
78 EXPORT_SYMBOL(osal_klib_fopen);
79
osal_klib_fclose(void * filp)80 void osal_klib_fclose(void *filp)
81 {
82 if (filp == NULL) {
83 osal_printk("%s - filp NULL\n", __FUNCTION__);
84 return;
85 }
86
87 klib_fclose((struct file *)filp);
88 }
89 EXPORT_SYMBOL(osal_klib_fclose);
90
osal_klib_fwrite(const char * buf,unsigned long size,void * filp)91 int osal_klib_fwrite(const char *buf, unsigned long size, void *filp)
92 {
93 if ((buf == NULL) || (filp == NULL)) {
94 osal_printk("%s - buf&filp NULL\n", __FUNCTION__);
95 return -1;
96 }
97
98 return klib_fwrite(buf, size, (struct file *)filp);
99 }
100 EXPORT_SYMBOL(osal_klib_fwrite);
101
osal_klib_fread(char * buf,unsigned long size,void * filp)102 int osal_klib_fread(char *buf, unsigned long size, void *filp)
103 {
104 if ((buf == NULL) || (filp == NULL)) {
105 osal_printk("%s - buf&filp NULL\n", __FUNCTION__);
106 return -1;
107 }
108
109 return klib_fread(buf, size, (struct file *)filp);
110 }
111 EXPORT_SYMBOL(osal_klib_fread);
112
osal_klib_user_fread(char * buf,unsigned long size,void * filp)113 int osal_klib_user_fread(char *buf, unsigned long size, void *filp)
114 {
115 int len;
116 mm_segment_t st_old_fs = {0};
117
118 if (filp == NULL || buf == NULL) {
119 osal_printk("%s - buf&filp NULL\n", __FUNCTION__);
120 return -1; /* no such file or directory */
121 }
122
123 if (((((struct file *)filp)->f_flags & O_ACCMODE) & (O_RDONLY | O_RDWR)) != 0) {
124 return -1; /* permission denied */
125 }
126
127 /* saved the original file space */
128 st_old_fs = get_fs();
129
130 /* extend to the kernel data space */
131 set_fs(USER_DS);
132
133 len = vfs_read((struct file *)filp, buf, size, &(((struct file *)filp)->f_pos));
134
135 /* restore the original file space */
136 set_fs(st_old_fs);
137
138 return len;
139 }
140 EXPORT_SYMBOL(osal_klib_user_fread);
141
osal_klib_user_fwrite(const char * buf,unsigned long size,void * filp)142 int osal_klib_user_fwrite(const char *buf, unsigned long size, void *filp)
143 {
144 int len;
145 mm_segment_t st_old_fs = {0};
146
147 if (filp == NULL || buf == NULL) {
148 osal_printk("%s - buf&filp NULL\n", __FUNCTION__);
149 return -1; /* no such file or directory */
150 }
151
152 if (((((struct file *)filp)->f_flags & O_ACCMODE) & (O_WRONLY | O_RDWR)) == 0) {
153 return -1; /* permission denied */
154 }
155
156 st_old_fs = get_fs();
157 set_fs(USER_DS);
158
159 len = vfs_write((struct file *)filp, buf, size, &(((struct file *)filp)->f_pos));
160
161 set_fs(st_old_fs);
162
163 return len;
164 }
165 EXPORT_SYMBOL(osal_klib_user_fwrite);
166
osal_klib_fseek(long long offset,int whence,void * filp)167 int osal_klib_fseek(long long offset, int whence, void *filp)
168 {
169 int ret;
170 loff_t res;
171
172 if (filp == NULL) {
173 osal_printk("%s - filp NULL\n", __FUNCTION__);
174 return -1;
175 }
176
177 res = vfs_llseek(filp, offset, whence);
178 ret = res;
179 if (res != (loff_t)ret) {
180 ret = -EOVERFLOW;
181 }
182
183 return ret;
184 }
185 EXPORT_SYMBOL(osal_klib_fseek);
186
osal_klib_fsync(void * filp)187 void osal_klib_fsync(void *filp)
188 {
189 if (filp == NULL) {
190 osal_printk("%s - filp NULL\n", __FUNCTION__);
191 return;
192 }
193
194 vfs_fsync(filp, 0);
195 }
196 EXPORT_SYMBOL(osal_klib_fsync);
197
osal_klib_set_store_path(char * path)198 void osal_klib_set_store_path(char *path)
199 {
200 g_klib_store_path = path;
201 }
202 EXPORT_SYMBOL(osal_klib_set_store_path);
203
osal_klib_get_store_path(char * path,unsigned int path_size)204 int osal_klib_get_store_path(char *path, unsigned int path_size)
205 {
206 int len;
207
208 #if defined (CONFIG_CLOSE_UART0)
209 /* not support log when uart close or user version */
210 if (osal_get_buildvariant() != OSAL_BUILDVARIANT_ENG) {
211 return 0;
212 }
213 #endif
214
215 if ((path == NULL) || (g_klib_store_path == NULL)) {
216 osal_printk("%s - path Or g_klib_store_path NULL\n", __FUNCTION__);
217 return -1;
218 }
219
220 len = strlen(g_klib_store_path) + 1;
221 if (len > path_size || path_size <= 1) {
222 osal_printk("%s - path_size(%u) unvaild\n", __FUNCTION__, path_size);
223 return -1;
224 }
225
226 return memcpy_s(path, path_size, g_klib_store_path, len);
227 }
228 EXPORT_SYMBOL(osal_klib_get_store_path);
229