source: trunk/kernel/fs/devfs/devfs_file.c@ 9

Last change on this file since 9 was 9, checked in by alain, 9 years ago

Bloup

File size: 5.5 KB
Line 
1/*
2 * devfs/devfs_file.c - devfs file related operations
3 *
4 * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
5 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
6 *
7 * This file is part of ALMOS-kernel.
8 *
9 * ALMOS-kernel is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2.0 of the License.
12 *
13 * ALMOS-kernel is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with ALMOS-kernel; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <config.h>
24#include <chdev.h>
25#include <driver.h>
26#include <kmem.h>
27#include <string.h>
28#include <vfs.h>
29#include <errno.h>
30#include <metafs.h>
31#include <thread.h>
32
33#include <devfs.h>
34#include <devfs-private.h>
35
36
37KMEM_OBJATTR_INIT(devfs_kmem_file_init)
38{
39 attr->type = KMEM_DEVFS_FILE;
40 attr->name = "KCM DevFs File";
41 attr->size = sizeof(struct devfs_file_s);
42 attr->aligne = 0;
43 attr->min = CONFIG_DEVFS_FILE_MIN;
44 attr->max = CONFIG_DEVFS_FILE_MAX;
45 attr->ctor = NULL;
46 attr->dtor = NULL;
47 return 0;
48}
49
50VFS_OPEN_FILE(devfs_open)
51{
52 register error_t err;
53 register struct devfs_context_s *ctx;
54 register struct devfs_file_s *info;
55 register struct device_s *dev;
56 struct vfs_inode_s *inode;
57 dev_request_t rq;
58 kmem_req_t req;
59
60 inode = file->fr_inode;
61
62 info = file->fr_pv;
63 ctx = (struct devfs_context_s *)&inode->i_ctx->ctx_devfs;
64
65 if(!(inode->i_attr & VFS_DIR))
66 {
67 dev = (struct device_s*)inode->i_pv;
68
69 if(dev->type == DEV_INTERNAL)
70 return EPERM;
71
72 if(dev->type == DEV_BLK)
73 VFS_SET(inode->i_attr,VFS_DEV_BLK);
74 else
75 VFS_SET(inode->i_attr,VFS_DEV_CHR);
76
77 if(dev->op.dev.open != NULL)
78 {
79 rq.fremote = file;
80 if((err=dev->op.dev.open(dev, &rq)))
81 return err;
82 }
83
84 priv->dev = (void*)dev;
85
86 return 0;
87 }
88
89 if(info == NULL)
90 {
91 req.type = KMEM_DEVFS_FILE;
92 req.size = sizeof(*info);
93 req.flags = AF_KERNEL;
94 info = kmem_alloc(&req);
95 }
96
97 if(info == NULL) return ENOMEM;
98
99 metafs_iter_init(&devfs_db.root, &info->iter);
100 info->ctx = ctx;
101 file->fr_pv = info;
102
103 metafs_print(&devfs_db.root);
104 return 0;
105}
106
107#define TMP_BUFF_SZ 512
108//FIXME:
109//add a "while" loop for the case where the
110//buffer TMP_BUFF_SZ is smaller than
111//buffer->size
112VFS_READ_FILE(devfs_read)
113{
114 register struct device_s *dev;
115 dev_request_t rq;
116 uint_t count;
117 uint8_t buff[TMP_BUFF_SZ];
118
119 dev = (struct device_s*)file->f_private.dev;
120
121 rq.dst = &buff[0];
122 rq.count = TMP_BUFF_SZ;
123 rq.flags = 0;
124 rq.file = file;
125
126 if((count = dev->op.dev.read(dev, &rq)) < 0)
127 return count;
128
129 buffer->scpy_to_buff(buffer, &buff[0], count);
130 return count;
131}
132
133//FIXME: To improve this an avoid the extra copy,
134//we could set along with the buffer(src and dest)
135//the functions to manipulate them, such as in
136//do_exec.c
137VFS_WRITE_FILE(devfs_write)
138{
139 register struct device_s *dev;
140 uint8_t buff[TMP_BUFF_SZ];
141 dev_request_t rq;
142
143 dev = (struct device_s*)file->f_private.dev;
144
145 //FIXME avoid the extra copy ?
146 buffer->scpy_from_buff(buffer, (void*)&buff[0], TMP_BUFF_SZ);
147 rq.src = (void*)&buff[0];
148 rq.count = buffer->size;
149 rq.flags = 0;
150 rq.file = file;
151
152 return dev->op.dev.write(dev, &rq);
153}
154
155VFS_LSEEK_FILE(devfs_lseek)
156{
157 register struct device_s *dev;
158 dev_request_t rq;
159
160 dev = (struct device_s*)file->fr_inode->i_pv;
161
162 if(dev->op.dev.lseek == NULL)
163 return VFS_ENOTUSED;
164
165 rq.fremote = file;
166 return dev->op.dev.lseek(dev, &rq);
167}
168
169VFS_CLOSE_FILE(devfs_close)
170{
171 register struct device_s *dev;
172 dev_request_t rq;
173
174 if(file->fr_inode->i_attr & VFS_DIR)
175 return 0;
176
177 dev = (struct device_s*)file->fr_inode->i_pv;
178
179 if(dev->op.dev.close == NULL)
180 return 0;
181
182 rq.fremote = file;
183 return dev->op.dev.close(dev, &rq);
184}
185
186VFS_RELEASE_FILE(devfs_release)
187{
188 kmem_req_t req;
189
190 if(file->fr_pv == NULL)
191 return 0;
192
193 req.type = KMEM_DEVFS_FILE;
194 req.ptr = file->fr_pv;
195 kmem_free(&req);
196
197 file->fr_pv = NULL;
198 return 0;
199}
200
201VFS_READ_DIR(devfs_readdir)
202{
203 register struct devfs_file_s *info;
204 register struct metafs_s *current;
205 register struct device_s *current_dev;
206
207 info = file->fr_pv;
208
209 if(file->fr_pv == NULL)
210 return ENOTDIR;
211
212 if((current = metafs_lookup_next(&devfs_db.root, &info->iter)) == NULL)
213 return EEODIR;
214
215 current_dev = metafs_container(current, struct device_s, node);
216 dirent->u_attr = (current_dev->type == DEV_BLK) ? VFS_DEV_BLK : VFS_DEV_CHR;
217
218 strcpy((char*)dirent->u_name, metafs_get_name(current));
219
220 dirent->u_ino = (uint_t) current_dev->base_paddr;
221
222 return 0;
223}
224
225VFS_MMAP_FILE(devfs_mmap)
226{
227 register struct device_s *dev;
228 dev_request_t rq;
229
230 dev = (struct device_s*)file->f_private.dev;
231
232 if(dev->op.dev.mmap == NULL)
233 return ENODEV;
234
235 rq.flags = 0;
236 rq.file = file;
237 rq.region = region;
238
239 return dev->op.dev.mmap(dev, &rq);
240}
241
242VFS_MMAP_FILE(devfs_munmap)
243{
244 register struct device_s *dev;
245 dev_request_t rq;
246
247 dev = (struct device_s*)file->f_private.dev;
248
249 if(dev->op.dev.munmap == NULL)
250 return ENODEV;
251
252 rq.flags = 0;
253 rq.file = file;
254 rq.region = region;
255
256 return dev->op.dev.munmap(dev, &rq);
257}
258
259
260const struct vfs_file_op_s devfs_f_op =
261{
262 .open = devfs_open,
263 .read = devfs_read,
264 .write = devfs_write,
265 .lseek = devfs_lseek,
266 .mmap = devfs_mmap,
267 .munmap = devfs_munmap,
268 .readdir = devfs_readdir,
269 .close = devfs_close,
270 .release = devfs_release
271};
Note: See TracBrowser for help on using the repository browser.