uromfs.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2003 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00034 /*
00035  * $Log: uromfs.c,v $
00036  * Revision 1.8  2008/04/18 13:22:27  haraldkipp
00037  * Added type casts to fix ICCAVR V7.16 compile errors.
00038  *
00039  * Revision 1.7  2006/03/02 19:57:34  haraldkipp
00040  * ICCARM insists on a (void *) typecast for the second parameter of memcpy().
00041  *
00042  * Revision 1.6  2006/01/05 16:45:20  haraldkipp
00043  * Dynamic NUTFILE allocation for detached block device.
00044  *
00045  * Revision 1.5  2005/08/05 11:29:07  olereinhardt
00046  * Added IOCTL function with support for seek
00047  *
00048  * Revision 1.4  2004/03/18 11:37:06  haraldkipp
00049  * Deprecated functions removed
00050  *
00051  * Revision 1.3  2004/03/16 16:48:27  haraldkipp
00052  * Added Jan Dubiec's H8/300 port.
00053  *
00054  * Revision 1.2  2003/07/20 19:27:59  haraldkipp
00055  * Patch by Alessandro Zummo. Moves the urom filesystem filenames to
00056  * AVR's flash memory.
00057  *
00058  * Revision 1.1.1.1  2003/05/09 14:41:02  haraldkipp
00059  * Initial using 3.2.1
00060  *
00061  * Revision 1.12  2003/04/21 16:58:20  harald
00062  * Make use of predefined eof
00063  *
00064  * Revision 1.11  2003/02/04 17:57:14  harald
00065  * Version 3 released
00066  *
00067  * Revision 1.10  2002/11/02 15:16:09  harald
00068  * Compiler warning avoided
00069  *
00070  * Revision 1.9  2002/06/26 17:29:13  harald
00071  * First pre-release with 2.4 stack
00072  *
00073  */
00074 
00075 #include <string.h>
00076 #include <errno.h>
00077 #include <stdio.h>
00078 
00079 #include <sys/heap.h>
00080 #include <sys/file.h>
00081 #include <sys/device.h>
00082 
00083 #include <fs/fs.h>
00084 #include <dev/urom.h>
00085 #include <fs/uromfs.h>
00086 
00087 /*
00088 static int UromRead(NUTFILE * fp, void *buffer, int size);
00089 static int UromWrite(NUTFILE * fp, CONST void *buffer, int len);
00090 #ifdef __HARVARD_ARCH__
00091 static int UromWrite_P(NUTFILE * fp, PGM_P buffer, int len);
00092 #endif
00093 static NUTFILE *UromOpen(NUTDEVICE * dev, CONST char *name, int mode,
00094                          int acc);
00095 static int UromClose(NUTFILE * fp);
00096 static long UromSize(NUTFILE * fp);
00097 */
00102 
00103 static int UromSeek(NUTFILE * fp, long *pos, int whence)
00104 {
00105     ROMFILE *romf = fp->nf_fcb;
00106     ROMENTRY *rome = romf->romf_entry;
00107 
00108     int rc = 0;
00109     long npos = *pos;
00110 
00111     switch (whence) {
00112     case SEEK_CUR:
00113         npos += romf->romf_pos;
00114         break;
00115     case SEEK_END:
00116         npos += rome->rome_size;
00117         break;
00118     }
00119 
00120     if (npos < 0 || npos > rome->rome_size) {
00121         rc = EINVAL;
00122     } else {
00123         romf->romf_pos = npos;
00124         *pos = npos;
00125     }
00126     return rc;
00127 }
00128 
00132 static int UromRead(NUTFILE * fp, void *buffer, int size)
00133 {
00134     ROMFILE *romf = fp->nf_fcb;
00135     ROMENTRY *rome = romf->romf_entry;
00136 
00137     if ((u_int) size > rome->rome_size - romf->romf_pos)
00138         size = rome->rome_size - romf->romf_pos;
00139     if (size) {
00140         memcpy_P(buffer, (PGM_P)(rome->rome_data + romf->romf_pos), size);
00141         romf->romf_pos += size;
00142     }
00143     return size;
00144 }
00145 
00151 static int UromWrite(NUTFILE * fp, CONST void *buffer, int len)
00152 {
00153     return -1;
00154 }
00155 
00161 #ifdef __HARVARD_ARCH__
00162 static int UromWrite_P(NUTFILE * fp, PGM_P buffer, int len)
00163 {
00164     return -1;
00165 }
00166 #endif
00167 
00168 
00172 static NUTFILE *UromOpen(NUTDEVICE * dev, CONST char *name, int mode,
00173                          int acc)
00174 {
00175     NUTFILE *fp = NutHeapAlloc(sizeof(NUTFILE));
00176     ROMENTRY *rome;
00177     ROMFILE *romf = 0;
00178 
00179     if (fp == 0) {
00180         errno = ENOMEM;
00181         return NUTFILE_EOF;
00182     }
00183 
00184     for (rome = romEntryList; rome; rome = rome->rome_next) {
00185         if (strcmp_P(name, rome->rome_name) == 0)
00186             break;
00187     }
00188     if (rome) {
00189         if ((romf = NutHeapAllocClear(sizeof(ROMFILE))) != 0)
00190             romf->romf_entry = rome;
00191         else
00192             errno = ENOMEM;
00193     } else
00194         errno = ENOENT;
00195 
00196     if (romf) {
00197         fp->nf_next = 0;
00198         fp->nf_dev = dev;
00199         fp->nf_fcb = romf;
00200     } else {
00201         NutHeapFree(fp);
00202         fp = NUTFILE_EOF;
00203     }
00204 
00205     return fp;
00206 }
00207 
00211 static int UromClose(NUTFILE * fp)
00212 {
00213     if (fp && fp != NUTFILE_EOF) {
00214         if (fp->nf_fcb)
00215             NutHeapFree(fp->nf_fcb);
00216         NutHeapFree(fp);
00217     }
00218     return 0;
00219 }
00220 
00224 static long UromSize(NUTFILE * fp)
00225 {
00226     ROMFILE *romf = fp->nf_fcb;
00227     ROMENTRY *rome = romf->romf_entry;
00228 
00229     return (long) rome->rome_size;
00230 }
00231 
00235 int UromIOCtl(NUTDEVICE * dev, int req, void *conf)
00236 {
00237     int rc = -1;
00238 
00239     switch (req) {
00240     case FS_FILE_SEEK:
00241         UromSeek((NUTFILE *) ((IOCTL_ARG3 *) conf)->arg1,      /* */
00242                      (long *) ((IOCTL_ARG3 *) conf)->arg2,      /* */
00243                      (int) ((IOCTL_ARG3 *) conf)->arg3);
00244         break;
00245     }
00246     return rc;
00247 }
00248 
00249 
00256 NUTDEVICE devUrom = {
00257     0,                          
00258     {'U', 'R', 'O', 'M', 0, 0, 0, 0, 0},        
00259     IFTYP_ROM,                  
00260     0,                          
00261     0,                          
00262     0,                          
00263     0,                          
00264     0,                          
00265     UromIOCtl,                  
00266     UromRead,                   
00267     UromWrite,                  
00268 #ifdef __HARVARD_ARCH__
00269     UromWrite_P,                
00270 #endif
00271     UromOpen,                   
00272     UromClose,                  
00273     UromSize                    
00274 };
00275 

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/