source: trunk/kernel/fs/devfs.c@ 642

Last change on this file since 642 was 637, checked in by alain, 7 years ago

Introduce the non-standard pthread_parallel_create() system call
and re-write the <fft> and <sort> applications to improve the
intrinsic paralelism in applications.

File size: 27.6 KB
Line 
1/*
2 * devfs.c - DEVFS File system API implementation.
3 *
4 * Author Mohamed Lamine Karaoui (2014,2015)
5 * Alain Greiner (2016,2017,2018,2019)
6 *
7 * Copyright (c) Sorbonne Universites
8 *
9 * This file is part of ALMOS-MKH.
10 *
11 * ALMOS-MKH is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2.0 of the License.
14 *
15 * ALMOS-MKH is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25#include <hal_kernel_types.h>
26#include <hal_special.h>
27#include <hal_uspace.h>
28#include <printk.h>
29#include <string.h>
30#include <chdev.h>
31#include <thread.h>
32#include <dev_txt.h>
33#include <cluster.h>
34#include <vfs.h>
35#include <kmem.h>
36#include <devfs.h>
37
38/////////////////////////////////////////////////////////////////////////////////////////
39// Extern variables
40/////////////////////////////////////////////////////////////////////////////////////////
41
42extern vfs_ctx_t fs_context[]; // allocated in kernel_init.c
43extern chdev_directory_t chdev_dir; // allocated in kernel_init.c
44
45#if (DEBUG_SYS_READ & 1)
46extern uint32_t enter_devfs_read;
47extern uint32_t exit_devfs_read;
48#endif
49
50#if (DEBUG_SYS_WRITE & 1)
51extern uint32_t enter_devfs_write;
52extern uint32_t exit_devfs_write;
53#endif
54
55/////////////////////////////////////
56devfs_ctx_t * devfs_ctx_alloc( void )
57{
58 kmem_req_t req;
59
60 req.type = KMEM_KCM;
61 req.order = bits_log2( sizeof(devfs_ctx_t) );
62 req.flags = AF_KERNEL | AF_ZERO;
63
64 return kmem_alloc( &req );
65}
66
67/////////////////////////////////////////////
68void devfs_ctx_init( devfs_ctx_t * devfs_ctx,
69 xptr_t devfs_dev_inode_xp,
70 xptr_t devfs_external_inode_xp )
71{
72 devfs_ctx->dev_inode_xp = devfs_dev_inode_xp;
73 devfs_ctx->external_inode_xp = devfs_external_inode_xp;
74
75 fs_context[FS_TYPE_DEVFS].extend = devfs_ctx;
76}
77
78/////////////////////////////////////////////////
79void devfs_ctx_destroy( devfs_ctx_t * devfs_ctx )
80{
81 kmem_req_t req;
82
83 req.type = KMEM_KCM;
84 req.ptr = devfs_ctx;
85 kmem_free( &req );
86}
87
88/////////////////////////////////////////////////
89void devfs_global_init( xptr_t root_inode_xp,
90 xptr_t * devfs_dev_inode_xp,
91 xptr_t * devfs_external_inode_xp )
92{
93 error_t error;
94 xptr_t unused_xp; // required by vfs_add_child_in_parent()
95 vfs_inode_t * inode;
96
97 // create DEVFS "dev" inode in cluster 0
98 error = vfs_add_child_in_parent( 0, // cxy
99 FS_TYPE_DEVFS,
100 root_inode_xp,
101 "dev",
102 &unused_xp,
103 devfs_dev_inode_xp );
104
105 // update inode "type" field
106 inode = GET_PTR( *devfs_dev_inode_xp );
107 inode->type = INODE_TYPE_DIR;
108
109 // create dentries <.> and <..> in <dev>
110 error |= vfs_add_special_dentries( *devfs_dev_inode_xp,
111 root_inode_xp );
112
113 if( error )
114 {
115 printk("\n[PANIC] in %s : cannot create <dev> directory\n", __FUNCTION__ );
116 hal_core_sleep();
117 }
118
119#if DEBUG_DEVFS_GLOBAL_INIT
120uint32_t cycle = (uint32_t)hal_get_cycles();
121thread_t * this = CURRENT_THREAD;
122if( DEBUG_DEVFS_GLOBAL_INIT < cycle )
123printk("\n[%s] thread[%x,%x] created <dev> inode / cycle %d\n",
124__FUNCTION__, this->process->pid, this->trdid, cycle );
125#endif
126
127 // create DEVFS "external" inode in cluster 0
128 error = vfs_add_child_in_parent( 0, // cxy
129 FS_TYPE_DEVFS,
130 *devfs_dev_inode_xp,
131 "external",
132 &unused_xp,
133 devfs_external_inode_xp );
134
135 // update inode "type" field
136 inode = GET_PTR( *devfs_external_inode_xp );
137 inode->type = INODE_TYPE_DIR;
138
139 // create dentries <.> and <..> in <external>
140 error |= vfs_add_special_dentries( *devfs_external_inode_xp,
141 *devfs_dev_inode_xp );
142
143 if( error )
144 {
145 printk("\n[PANIC] in %s : cannot create <external> directory\n", __FUNCTION__ );
146 hal_core_sleep();
147 }
148
149#if DEBUG_DEVFS_GLOBAL_INIT
150cycle = (uint32_t)hal_get_cycles();
151if( DEBUG_DEVFS_GLOBAL_INIT < cycle )
152printk("\n[%s] thread[%x,%x] created <external> inode / cycle %d\n",
153__FUNCTION__, this->process->pid, this->trdid, cycle );
154#endif
155
156} // end devfs_global_init()
157
158///////////////////////////////////////////////////
159void devfs_local_init( xptr_t devfs_dev_inode_xp,
160 xptr_t devfs_external_inode_xp,
161 xptr_t * devfs_internal_inode_xp )
162{
163 char node_name[16];
164 xptr_t chdev_xp;
165 cxy_t chdev_cxy;
166 chdev_t * chdev_ptr;
167 xptr_t inode_xp;
168 vfs_inode_t * inode_ptr;
169 uint32_t channel;
170 xptr_t unused_xp; // required by add_child_in_parent()
171 error_t error;
172
173#if DEBUG_DEVFS_LOCAL_INIT
174uint32_t cycle = (uint32_t)hal_get_cycles();
175thread_t * this = CURRENT_THREAD;
176if( DEBUG_DEVFS_LOCAL_INIT < cycle )
177printk("\n[%s] thread[%x,%x] enter / cycle %d\n",
178__FUNCTION__, this->process->pid, this->trdid, cycle );
179#endif
180
181 // create "internal" directory
182 snprintf( node_name , 16 , "internal_%x" , local_cxy );
183
184 error = vfs_add_child_in_parent( local_cxy,
185 FS_TYPE_DEVFS,
186 devfs_dev_inode_xp,
187 node_name,
188 &unused_xp,
189 devfs_internal_inode_xp );
190
191 // set inode "type" field
192 inode_ptr = GET_PTR( *devfs_internal_inode_xp );
193 inode_ptr->type = INODE_TYPE_DEV;
194
195 // create dentries <.> and <..> in <internal>
196 error |= vfs_add_special_dentries( *devfs_internal_inode_xp,
197 devfs_dev_inode_xp );
198
199 if( error )
200 {
201 printk("\n[PANIC] in %s : cannot create <internal> directory\n", __FUNCTION__ );
202 hal_core_sleep();
203 }
204
205#if DEBUG_DEVFS_LOCAL_INIT
206cycle = (uint32_t)hal_get_cycles();
207if( DEBUG_DEVFS_LOCAL_INIT < cycle )
208printk("\n[%s] thread[%x,%x] created <%s> inode in cluster %x / cycle %d\n",
209__FUNCTION__, this->process->pid, this->trdid, node_name, local_cxy, cycle );
210#endif
211
212 // create MMC chdev inode
213 chdev_xp = chdev_dir.mmc[local_cxy];
214 if( chdev_xp != XPTR_NULL)
215 {
216 chdev_ptr = GET_PTR( chdev_xp );
217 chdev_cxy = GET_CXY( chdev_xp );
218
219 if( chdev_cxy != local_cxy )
220 {
221 printk("\n[PANIC] in %s : illegal MMC chdev in cluster %x\n",
222 __FUNCTION__, local_cxy );
223 hal_core_sleep();
224 }
225
226 error = vfs_add_child_in_parent( local_cxy,
227 FS_TYPE_DEVFS,
228 *devfs_internal_inode_xp,
229 chdev_ptr->name,
230 &unused_xp,
231 &inode_xp );
232
233 if( error )
234 {
235 printk("\n[PANIC] in %s : cannot create MMC inode in cluster %x\n",
236 __FUNCTION__, local_cxy );
237 hal_core_sleep();
238 }
239
240 // update child inode "extend" and "type" fields
241 inode_ptr = GET_PTR( inode_xp );
242 inode_ptr->extend = chdev_ptr;
243 inode_ptr->type = INODE_TYPE_DEV;
244
245#if DEBUG_DEVFS_LOCAL_INIT
246cycle = (uint32_t)hal_get_cycles();
247if( DEBUG_DEVFS_LOCAL_INIT < cycle )
248printk("\n[%s] thread[%x,%x] created <mmc> inode in cluster %x\n",
249__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
250#endif
251
252 }
253
254 // create DMA chdev inodes (one DMA channel per core)
255 for( channel = 0 ; channel < LOCAL_CLUSTER->cores_nr ; channel++ )
256 {
257 chdev_xp = chdev_dir.dma[channel];
258 if( chdev_xp != XPTR_NULL)
259 {
260 chdev_ptr = GET_PTR( chdev_xp );
261 chdev_cxy = GET_CXY( chdev_xp );
262
263 if( chdev_cxy != local_cxy )
264 {
265 printk("\n[PANIC] in %s : illegal DMA chdev in cluster %x\n",
266 __FUNCTION__, local_cxy );
267 hal_core_sleep();
268 }
269
270 error = vfs_add_child_in_parent( local_cxy,
271 FS_TYPE_DEVFS,
272 *devfs_internal_inode_xp,
273 chdev_ptr->name,
274 &unused_xp,
275 &inode_xp );
276 if( error )
277 {
278 printk("\n[PANIC] in %s : cannot create DMA inode in cluster %x\n",
279 __FUNCTION__, local_cxy );
280 hal_core_sleep();
281 }
282
283 // update child inode "extend" and "type" fields
284 inode_ptr = GET_PTR( inode_xp );
285 inode_ptr->extend = chdev_ptr;
286 inode_ptr->type = INODE_TYPE_DEV;
287
288#if DEBUG_DEVFS_LOCAL_INIT
289cycle = (uint32_t)hal_get_cycles();
290if( DEBUG_DEVFS_LOCAL_INIT < cycle )
291printk("\n[%s] thread [%x,%x] created <dma[%d]> inode in cluster %x\n",
292__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
293#endif
294 }
295 }
296
297 // create an IOB inode in cluster containing IOB chdev
298 chdev_xp = chdev_dir.iob;
299 if( chdev_xp != XPTR_NULL )
300 {
301 chdev_cxy = GET_CXY( chdev_xp );
302 chdev_ptr = GET_PTR( chdev_xp );
303
304 if( chdev_cxy == local_cxy )
305 {
306 error = vfs_add_child_in_parent( local_cxy,
307 FS_TYPE_DEVFS,
308 devfs_external_inode_xp,
309 chdev_ptr->name,
310 &unused_xp,
311 &inode_xp );
312 if( error )
313 {
314 printk("\n[PANIC] in %s : cannot create IOB inode in cluster %x\n",
315 __FUNCTION__, local_cxy );
316 hal_core_sleep();
317 }
318
319 // update child inode "extend" and "type" fields
320 inode_ptr = GET_PTR( inode_xp );
321 inode_ptr->extend = chdev_ptr;
322 inode_ptr->type = INODE_TYPE_DEV;
323
324#if DEBUG_DEVFS_LOCAL_INIT
325cycle = (uint32_t)hal_get_cycles();
326if( DEBUG_DEVFS_LOCAL_INIT < cycle )
327printk("\n[%s] thread[%x,%x] created <iob> inode in cluster %x\n",
328__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
329#endif
330 }
331 }
332
333 // create a PIC inode in cluster containing PIC chdev
334 chdev_xp = chdev_dir.pic;
335 if( chdev_xp != XPTR_NULL )
336 {
337 chdev_cxy = GET_CXY( chdev_xp );
338 chdev_ptr = GET_PTR( chdev_xp );
339
340 if( chdev_cxy == local_cxy )
341 {
342 error = vfs_add_child_in_parent( local_cxy,
343 FS_TYPE_DEVFS,
344 devfs_external_inode_xp,
345 chdev_ptr->name,
346 &unused_xp,
347 &inode_xp );
348
349 if( error )
350 {
351 printk("\n[PANIC] in %s : cannot create PIC inode in cluster %x\n",
352 __FUNCTION__, local_cxy );
353 hal_core_sleep();
354 }
355
356 // update child inode "extend" field
357 inode_ptr = GET_PTR( inode_xp );
358 inode_ptr->extend = chdev_ptr;
359 inode_ptr->type = INODE_TYPE_DEV;
360
361#if DEBUG_DEVFS_LOCAL_INIT
362cycle = (uint32_t)hal_get_cycles();
363if( DEBUG_DEVFS_LOCAL_INIT < cycle )
364printk("\n[%s] thread[%x,%x] created <pic> inode in cluster %x\n",
365__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
366#endif
367 }
368 }
369
370 // create a TXT_RX inode in each cluster containing a TXT_RX chdev
371 for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
372 {
373 chdev_xp = chdev_dir.txt_rx[channel];
374 if( chdev_xp != XPTR_NULL )
375 {
376 chdev_cxy = GET_CXY( chdev_xp );
377 chdev_ptr = GET_PTR( chdev_xp );
378
379 if( chdev_cxy == local_cxy )
380 {
381 error = vfs_add_child_in_parent( local_cxy,
382 FS_TYPE_DEVFS,
383 devfs_external_inode_xp,
384 chdev_ptr->name,
385 &unused_xp,
386 &inode_xp );
387
388 if( error )
389 {
390 printk("\n[PANIC] in %s : cannot create TXT_RX inode in cluster %x\n",
391 __FUNCTION__, local_cxy );
392 hal_core_sleep();
393 }
394
395 // update child inode "extend" and "type" fields
396 inode_ptr = GET_PTR( inode_xp );
397 inode_ptr->extend = chdev_ptr;
398 inode_ptr->type = INODE_TYPE_DEV;
399
400#if DEBUG_DEVFS_LOCAL_INIT
401cycle = (uint32_t)hal_get_cycles();
402if( DEBUG_DEVFS_LOCAL_INIT < cycle )
403printk("\n[%s] thread[%x,%x] created <txt_rx[%d]> inode in cluster %x\n",
404__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
405#endif
406 }
407 }
408 }
409
410 // create a TXT_TX inode in each cluster containing a TXT_TX chdev
411 for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
412 {
413 chdev_xp = chdev_dir.txt_tx[channel];
414 if( chdev_xp != XPTR_NULL )
415 {
416 chdev_cxy = GET_CXY( chdev_xp );
417 chdev_ptr = GET_PTR( chdev_xp );
418
419 if( chdev_cxy == local_cxy )
420 {
421 error = vfs_add_child_in_parent( local_cxy,
422 FS_TYPE_DEVFS,
423 devfs_external_inode_xp,
424 chdev_ptr->name,
425 &unused_xp,
426 &inode_xp );
427 if( error )
428 {
429 printk("\n[PANIC] in %s : cannot create TXT_TX inode in cluster %x\n",
430 __FUNCTION__, local_cxy );
431 hal_core_sleep();
432 }
433
434 // update child inode "extend" and "type" fields
435 inode_ptr = GET_PTR( inode_xp );
436 inode_ptr->extend = chdev_ptr;
437 inode_ptr->type = INODE_TYPE_DEV;
438
439#if DEBUG_DEVFS_LOCAL_INIT
440cycle = (uint32_t)hal_get_cycles();
441if( DEBUG_DEVFS_LOCAL_INIT < cycle )
442printk("\n[%s] thread[%x,%x] created <txt_tx[%d]> inode in cluster %x\n",
443__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
444#endif
445 }
446 }
447 }
448
449 // create an IOC inode in each cluster containing an IOC chdev
450 for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
451 {
452 chdev_xp = chdev_dir.ioc[channel];
453 if( chdev_xp != XPTR_NULL )
454 {
455 chdev_cxy = GET_CXY( chdev_xp );
456 chdev_ptr = GET_PTR( chdev_xp );
457
458 if( chdev_cxy == local_cxy )
459 {
460 error = vfs_add_child_in_parent( local_cxy,
461 FS_TYPE_DEVFS,
462 devfs_external_inode_xp,
463 chdev_ptr->name,
464 &unused_xp,
465 &inode_xp );
466 if( error )
467 {
468 printk("\n[PANIC] in %s : cannot create IOC inode in cluster %x\n",
469 __FUNCTION__, local_cxy );
470 hal_core_sleep();
471 }
472
473 // update child inode "extend" and "type" fields
474 inode_ptr = GET_PTR( inode_xp );
475 inode_ptr->extend = chdev_ptr;
476 inode_ptr->type = INODE_TYPE_DEV;
477
478#if DEBUG_DEVFS_LOCAL_INIT
479cycle = (uint32_t)hal_get_cycles();
480if( DEBUG_DEVFS_LOCAL_INIT < cycle )
481printk("\n[%s] thread[%x,%x] created <ioc[%d]> inode in cluster %x\n",
482__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
483#endif
484 }
485 }
486 }
487
488 // create a FBF inode in each cluster containing a FBF chdev
489 for( channel = 0 ; channel < CONFIG_MAX_FBF_CHANNELS ; channel++ )
490 {
491 chdev_xp = chdev_dir.fbf[channel];
492 if( chdev_xp != XPTR_NULL )
493 {
494 chdev_cxy = GET_CXY( chdev_xp );
495 chdev_ptr = GET_PTR( chdev_xp );
496
497 if( chdev_cxy == local_cxy )
498 {
499 error = vfs_add_child_in_parent( local_cxy,
500 FS_TYPE_DEVFS,
501 devfs_external_inode_xp,
502 chdev_ptr->name,
503 &unused_xp,
504 &inode_xp );
505 if( error )
506 {
507 printk("\n[PANIC] in %s : cannot create FBF inode in cluster %x\n",
508 __FUNCTION__, local_cxy );
509 hal_core_sleep();
510 }
511
512 // update child inode "extend" and "type" fields
513 inode_ptr = GET_PTR( inode_xp );
514 inode_ptr->extend = chdev_ptr;
515 inode_ptr->type = INODE_TYPE_DEV;
516
517#if DEBUG_DEVFS_LOCAL_INIT
518cycle = (uint32_t)hal_get_cycles();
519if( DEBUG_DEVFS_LOCAL_INIT < cycle )
520printk("\n[%s] thread[%x,%x] created <fbf[%d]> inode in cluster %x\n",
521__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
522#endif
523 }
524 }
525 }
526
527 // create a NIC_RX inode in each cluster containing a NIC_RX chdev
528 for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
529 {
530 chdev_xp = chdev_dir.nic_rx[channel];
531 if( chdev_xp != XPTR_NULL )
532 {
533 chdev_cxy = GET_CXY( chdev_xp );
534 chdev_ptr = GET_PTR( chdev_xp );
535
536 if( chdev_cxy == local_cxy )
537 {
538 error = vfs_add_child_in_parent( local_cxy,
539 FS_TYPE_DEVFS,
540 devfs_external_inode_xp,
541 chdev_ptr->name,
542 &unused_xp,
543 &inode_xp );
544 if( error )
545 {
546 printk("\n[PANIC] in %s : cannot create NIC_RX inode in cluster %x\n",
547 __FUNCTION__, local_cxy );
548 hal_core_sleep();
549 }
550
551 // update child inode "extend" and "type" fields
552 inode_ptr = GET_PTR( inode_xp );
553 inode_ptr->extend = chdev_ptr;
554 inode_ptr->type = INODE_TYPE_DEV;
555
556#if DEBUG_DEVFS_LOCAL_INIT
557cycle = (uint32_t)hal_get_cycles();
558if( DEBUG_DEVFS_LOCAL_INIT < cycle )
559printk("\n[%s] thread[%x,%x] created <nic_rx[%d]> inode in cluster %x\n",
560__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
561#endif
562 }
563 }
564 }
565
566 // create a NIC_TX inode in each cluster containing a NIC_TX chdev
567 for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
568 {
569 chdev_xp = chdev_dir.nic_tx[channel];
570 if( chdev_xp != XPTR_NULL )
571 {
572 chdev_cxy = GET_CXY( chdev_xp );
573 chdev_ptr = GET_PTR( chdev_xp );
574
575 if( chdev_cxy == local_cxy )
576 {
577 error = vfs_add_child_in_parent( local_cxy,
578 FS_TYPE_DEVFS,
579 devfs_external_inode_xp,
580 chdev_ptr->name,
581 &unused_xp,
582 &inode_xp );
583 if( error )
584 {
585 printk("\n[PANIC] in %s : cannot create NIC_TX inode in cluster %x\n",
586 __FUNCTION__, local_cxy );
587 hal_core_sleep();
588 }
589
590 // update child inode "extend" and "type" fields
591 inode_ptr = GET_PTR( inode_xp );
592 inode_ptr->extend = chdev_ptr;
593 inode_ptr->type = INODE_TYPE_DEV;
594
595#if DEBUG_DEVFS_LOCAL_INIT
596cycle = (uint32_t)hal_get_cycles();
597if( DEBUG_DEVFS_LOCAL_INIT < cycle )
598printk("\n[%s] thread[%x,%x] created <nic_tx[%d]> inode in cluster %x\n",
599__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
600#endif
601 }
602 }
603 }
604} // end devfs_local_init()
605
606//////////////////////////////////////////
607int devfs_user_move( bool_t to_buffer,
608 xptr_t file_xp,
609 char * u_buf,
610 uint32_t size )
611{
612 xptr_t chdev_xp;
613 cxy_t chdev_cxy;
614 chdev_t * chdev_ptr; // associated chdev type
615 uint32_t func; // chdev functionnal type
616 uint32_t channel; // chdev channel index
617 uint32_t burst; // number of bytes in a burst
618 uint32_t todo; // number of bytes not yet moved
619 error_t error;
620 uint32_t i;
621
622 char k_buf[CONFIG_TXT_KBUF_SIZE]; // local kernel buffer
623
624assert( ( file_xp != XPTR_NULL ) , "file_xp == XPTR_NULL" );
625
626#if (DEBUG_SYS_READ & 1)
627enter_devfs_read = hal_time_stamp();
628#endif
629
630#if (DEBUG_SYS_WRITE & 1)
631enter_devfs_write = hal_time_stamp();
632#endif
633
634#if DEBUG_DEVFS_MOVE
635uint32_t cycle = (uint32_t)hal_get_cycles();
636thread_t * this = CURRENT_THREAD;
637if( DEBUG_DEVFS_MOVE < cycle )
638printk("\n[%s] thread[%x,%x] enter / to_mem %d / cycle %d\n",
639__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
640#endif
641
642 // get extended pointer on chdev_xp
643 chdev_xp = chdev_from_file( file_xp );
644
645 // get cluster and local pointer on chdev
646 chdev_cxy = GET_CXY( chdev_xp );
647 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
648
649 // get chdev functionnal type and channel
650 func = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->func ) );
651 channel = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->channel ) );
652
653// Only TXT devices are associated to a pseudo-file
654assert( ( func == DEV_FUNC_TXT ) , __FUNCTION__, "illegal device func_type");
655
656 // initialise number of bytes to move
657 todo = size;
658
659 /////////////// TXT read
660 if( to_buffer )
661 {
662 while( todo )
663 {
664 // set burst size
665 if( todo > CONFIG_TXT_KBUF_SIZE ) burst = CONFIG_TXT_KBUF_SIZE;
666 else burst = todo;
667
668 // read burst bytes from TXT device to kernel buffer
669 for( i = 0 ; i < burst ; i++ )
670 {
671 error = dev_txt_read( channel , &k_buf[i] );
672
673 if( error ) return -1;
674 }
675
676 // move burst bytes from k_buf to u_buf
677 hal_strcpy_to_uspace( u_buf,
678 XPTR( local_cxy , k_buf ),
679 burst );
680
681 // update loop variables
682 todo -= burst;
683 u_buf += burst;
684 }
685
686#if DEBUG_DEVFS_MOVE
687cycle = (uint32_t)hal_get_cycles();
688if( DEBUG_DEVFS_MOVE < cycle )
689printk("\n[%s] thread[%x,%x] exit / to_mem %d / cycle %d\n",
690__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
691#endif
692
693#if (DEBUG_SYS_READ & 1)
694exit_devfs_read = hal_time_stamp();
695#endif
696 return size;
697 }
698 ///////////// TXT write
699 else
700 {
701 while( todo )
702 {
703 // set burst size
704 if( todo > CONFIG_TXT_KBUF_SIZE ) burst = CONFIG_TXT_KBUF_SIZE;
705 else burst = todo;
706
707 // move burst bytes from u_buf to k_buf
708 hal_strcpy_from_uspace( XPTR( local_cxy , k_buf ) , u_buf , burst );
709
710 // write burst bytes from kernel buffer to TXT device
711 error = dev_txt_write( channel , k_buf , burst );
712
713 if( error ) return -1;
714
715 // update loop variables
716 todo -= burst;
717 u_buf += burst;
718 }
719
720#if DEBUG_DEVFS_MOVE
721cycle = (uint32_t)hal_get_cycles();
722if( DEBUG_DEVFS_MOVE < cycle )
723printk("\n[%s] thread[%x,%x] exit / to_mem %d / cycle %d\n",
724__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
725#endif
726
727#if (DEBUG_SYS_WRITE & 1)
728exit_devfs_write = hal_time_stamp();
729#endif
730 return size;
731 }
732
733} // end devfs_user_move()
734
735///////////////////////////////////////////////////////
736error_t devfs_get_user_dir( struct vfs_inode_s * inode,
737 struct dirent * array,
738 uint32_t max_dirent,
739 uint32_t min_dentry,
740 bool_t detailed,
741 uint32_t * entries,
742 bool_t * done )
743{
744 xptr_t xhtab_xp; // extended pointer on inode xhtab (children dentries)
745 xptr_t dentry_xp; // extended pointer on current dentry
746 vfs_dentry_t * dentry_ptr; // local pointer on current dentry
747 uint32_t dentry_id; // dentry index in set of children dentry
748 uint32_t dirent_id; // dirent index in array of dirent
749
750// detailed argument unused
751assert( (detailed == false) , "detailed argument not supported\n");
752
753 // One loop to scan the target inode xhtab containing the set of dentries
754 // exit loop if no more dentries, or dirent array full
755
756#if DEBUG_DEVFS_GET_USER_DIR
757char inode_name[CONFIG_VFS_MAX_NAME_LENGTH];
758uint32_t cycle = (uint32_t)hal_get_cycles();
759thread_t * this = CURRENT_THREAD;
760vfs_inode_get_name( XPTR( local_cxy , inode ) , inode_name );
761if( DEBUG_DEVFS_GET_USER_DIR < cycle )
762printk("\n[%s] thread[%x,%x] enter for inode <%s> / cycle %d\n",
763__FUNCTION__, this->process->pid, this->trdid, inode_name , cycle );
764#endif
765
766 // get extended pointer on inode xhtab
767 xhtab_xp = XPTR( local_cxy , &inode->children );
768
769 // initialize loop variables
770 dentry_xp = xhtab_get_first( xhtab_xp );
771 dentry_id = 0;
772 dirent_id = 0;
773
774 while( (dentry_xp != XPTR_NULL ) && (dirent_id < max_dirent) )
775 {
776 if( dentry_id >= min_dentry )
777 {
778 // copy name into dirent array
779 dentry_ptr = GET_PTR( dentry_xp );
780 strcpy( array[dirent_id].d_name , dentry_ptr->name );
781
782 // increment dirent_id
783 dirent_id++;
784 }
785
786 // update loop variables
787 dentry_xp = xhtab_get_next( xhtab_xp );
788 dentry_id++;
789 }
790
791 // return results of scan
792 *done = (dentry_xp == XPTR_NULL);
793 *entries = dirent_id;
794
795#if DEBUG_DEVFS_GET_USER_DIR
796cycle = (uint32_t)hal_get_cycles();
797if( DEBUG_DEVFS_GET_USER_DIR < cycle )
798printk("\n[%s] thread[%x,%x] exit for inode <%s> / %d entries / cycle %d\n",
799__FUNCTION__, this->process->pid, this->trdid, inode_name, entries, cycle );
800#endif
801
802 return 0;
803
804} // en devfs_get_user_dir()
805
Note: See TracBrowser for help on using the repository browser.