1 //==========================================================================
5 // Fileio device filesystem
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // Copyright (C) 2003 Gary Thomas
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
45 // Contributors: nickg, gthomas
47 // Purpose: Fileio device filesystem
48 // Description: This file implements a simple filesystem that interfaces
49 // to the existing device IO subsystem.
54 //####DESCRIPTIONEND####
56 //==========================================================================
58 #include <pkgconf/hal.h>
59 #include <pkgconf/io_fileio.h>
61 #include <cyg/infra/cyg_trac.h> // tracing macros
62 #include <cyg/infra/cyg_ass.h> // assertion macros
64 #include "fio.h" // Private header
66 #include <cyg/io/devtab.h> // device subsystem
67 #include <cyg/io/config_keys.h> // CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
69 //==========================================================================
70 // Forward definitions
72 // Filesystem operations
73 static int dev_mount ( cyg_fstab_entry *fste, cyg_mtab_entry *mte );
74 static int dev_umount ( cyg_mtab_entry *mte );
75 static int dev_open ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
76 int mode, cyg_file *fte );
77 static int dev_unlink ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );
78 static int dev_mkdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );
79 static int dev_rmdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );
80 static int dev_rename ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,
81 cyg_dir dir2, const char *name2 );
82 static int dev_link ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,
83 cyg_dir dir2, const char *name2, int type );
84 static int dev_opendir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
86 static int dev_chdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
88 static int dev_stat ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
90 static int dev_getinfo ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
91 int key, void *buf, int len );
92 static int dev_setinfo ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
93 int key, void *buf, int len );
96 static int dev_fo_read (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
97 static int dev_fo_write (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
98 static int dev_fo_lseek (struct CYG_FILE_TAG *fp, off_t *pos, int whence );
99 static int dev_fo_ioctl (struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,
101 static cyg_bool dev_fo_select (struct CYG_FILE_TAG *fp, int which, CYG_ADDRWORD info);
102 static int dev_fo_fsync (struct CYG_FILE_TAG *fp, int mode );
103 static int dev_fo_close (struct CYG_FILE_TAG *fp);
104 static int dev_fo_fstat (struct CYG_FILE_TAG *fp, struct stat *buf );
105 static int dev_fo_getinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len );
106 static int dev_fo_setinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len );
109 //==========================================================================
110 // Filesystem table entries
112 FSTAB_ENTRY( dev_fste, "devfs", 0,
113 CYG_SYNCMODE_NONE, // dev system has its own sync mechanism
134 static cyg_fileops dev_fileops =
148 //==========================================================================
149 // Filesystem operations
151 // -------------------------------------------------------------------------
153 static int dev_mount ( cyg_fstab_entry *fste, cyg_mtab_entry *mte )
155 // Nothing to do here. The device IO subsystem has already initialized
156 // iteslf, and the fileio infrastructure will do the rest.
161 // -------------------------------------------------------------------------
163 static int dev_umount ( cyg_mtab_entry *mte )
165 // Nothing to do here.
170 // -------------------------------------------------------------------------
172 static int dev_open ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
173 int mode, cyg_file *file )
176 cyg_io_handle_t handle;
178 // The name we are passed will point to the first character after
179 // "/dev/". We know that the full string contains the prefix string,
180 // so we back the pointer up by 5 chars.
181 // A better approach would be for the device table entries to only
182 // contain the part of the string after the prefix.
186 err = cyg_io_lookup( name, &handle );
191 // If we want non-blocking mode, configure the device for it.
192 if( (mode & (O_NONBLOCK|O_RDONLY)) == (O_NONBLOCK|O_RDONLY) )
195 cyg_uint32 fsize = sizeof(f);
196 err = cyg_io_set_config( handle, CYG_IO_SET_CONFIG_READ_BLOCKING,
202 if( (mode & (O_NONBLOCK|O_WRONLY)) == (O_NONBLOCK|O_WRONLY) )
205 cyg_uint32 fsize = sizeof(f);
206 err = cyg_io_set_config( handle, CYG_IO_SET_CONFIG_WRITE_BLOCKING,
212 // Initialize the file object
214 file->f_flag |= mode & CYG_FILE_MODE_MASK;
215 file->f_type = CYG_FILE_TYPE_FILE;
216 file->f_ops = &dev_fileops;
218 file->f_data = (CYG_ADDRWORD)handle;
224 // -------------------------------------------------------------------------
226 static int dev_unlink ( cyg_mtab_entry *mte, cyg_dir dir, const char *name )
231 // -------------------------------------------------------------------------
233 static int dev_mkdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name )
238 // -------------------------------------------------------------------------
240 static int dev_rmdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name )
245 // -------------------------------------------------------------------------
247 static int dev_rename ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,
248 cyg_dir dir2, const char *name2 )
253 // -------------------------------------------------------------------------
255 static int dev_link ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,
256 cyg_dir dir2, const char *name2, int type )
261 // -------------------------------------------------------------------------
263 static int dev_opendir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
269 // -------------------------------------------------------------------------
271 static int dev_chdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
277 // -------------------------------------------------------------------------
279 static int dev_stat ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
283 cyg_io_handle_t handle;
284 cyg_devtab_entry_t *dev;
286 name -= 5; // See comment in dev_open()
288 err = cyg_io_lookup( name, &handle );
293 // Just fill in the stat buffer with some constant values.
294 dev = (cyg_devtab_entry_t *)handle;
296 if (dev->status & CYG_DEVTAB_STATUS_BLOCK)
297 buf->st_mode = __stat_mode_BLK;
299 buf->st_mode = __stat_mode_CHR;
301 buf->st_ino = (ino_t)handle; // map dev handle to inode
302 buf->st_dev = 0; // (dev_t)handle; // same with dev id
314 // -------------------------------------------------------------------------
316 static int dev_getinfo ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
317 int key, void *buf, int len )
322 // -------------------------------------------------------------------------
324 static int dev_setinfo ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
325 int key, void *buf, int len )
330 //==========================================================================
334 // -------------------------------------------------------------------------
336 static int dev_fo_read (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
341 // Now loop over the iovecs until they are all done, or
343 for( i = 0; i < uio->uio_iovcnt; i++ )
345 cyg_iovec *iov = &uio->uio_iov[i];
346 cyg_uint32 len = iov->iov_len;
347 cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)fp->f_data;
349 if (t->status & CYG_DEVTAB_STATUS_BLOCK)
350 err = cyg_io_bread( (cyg_io_handle_t)t,
354 err = cyg_io_read( (cyg_io_handle_t)t,
360 uio->uio_resid -= len;
366 // -------------------------------------------------------------------------
368 static int dev_fo_write (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
373 // Now loop over the iovecs until they are all done, or
375 for( i = 0; i < uio->uio_iovcnt; i++ )
377 cyg_iovec *iov = &uio->uio_iov[i];
378 cyg_uint32 len = iov->iov_len;
379 cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)fp->f_data;
381 if (t->status & CYG_DEVTAB_STATUS_BLOCK)
382 err = cyg_io_bwrite( (cyg_io_handle_t)t,
386 err = cyg_io_write( (cyg_io_handle_t)t,
392 uio->uio_resid -= len;
398 // -------------------------------------------------------------------------
400 static int dev_fo_lseek (struct CYG_FILE_TAG *fp, off_t *pos, int whence )
402 // All current devices have no notion of position. Just return zero
403 // as the new position.
410 // -------------------------------------------------------------------------
412 static int dev_fo_ioctl (struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,
418 // -------------------------------------------------------------------------
420 static cyg_bool dev_fo_select (struct CYG_FILE_TAG *fp, int which, CYG_ADDRWORD info)
422 return cyg_io_select( (cyg_io_handle_t)fp->f_data,
427 // -------------------------------------------------------------------------
429 static int dev_fo_fsync (struct CYG_FILE_TAG *fp, int mode )
433 err = cyg_io_get_config((cyg_io_handle_t)fp->f_data,
434 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN,
440 // -------------------------------------------------------------------------
442 static int dev_fo_close (struct CYG_FILE_TAG *fp)
447 // -------------------------------------------------------------------------
449 static int dev_fo_fstat (struct CYG_FILE_TAG *fp, struct stat *buf )
451 cyg_devtab_entry_t *dev = (cyg_devtab_entry_t *)fp->f_data;
453 // Just fill in the stat buffer with some constant values.
454 if (dev->status & CYG_DEVTAB_STATUS_BLOCK)
455 buf->st_mode = __stat_mode_BLK;
457 buf->st_mode = __stat_mode_CHR;
459 buf->st_ino = (ino_t)fp->f_data; // map dev handle to inode
460 buf->st_dev = 0; //(dev_t)fp->f_data; // same with dev id
472 // -------------------------------------------------------------------------
474 static int dev_fo_getinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len )
479 err = cyg_io_get_config( (cyg_io_handle_t)fp->f_data, key, buf, &ll );
484 // -------------------------------------------------------------------------
486 static int dev_fo_setinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len )
491 err = cyg_io_set_config( (cyg_io_handle_t)fp->f_data, key, buf, &ll );
496 // -------------------------------------------------------------------------