From: Stefan E. <se...@us...> - 2002-05-02 15:22:10
|
Update of /cvsroot/blob/blob/src/lib In directory usw-pr-cvs1:/tmp/cvs-serv13320a Added Files: generic_io.c Log Message: - generic io framework - this tries to add a generic io framework. io "drivers" for a memory pool included. Why do i need this? Well, i want to have CF, Flash, Memory, filesystem and tar file access separated from each other. Please have a look at generic_io.h, system3.c::iotest(), and tar.c (now also using the generic io framework) --- NEW FILE: generic_io.c --- /********************************************************************** * generic_io.c * * generic io abstraction * * Copyright (C) 2002, Stefan Eletzhofer <ste...@el...> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: generic_io.c,v 1.1 2002/05/02 15:22:07 seletz Exp $ * * $Log: generic_io.c,v $ * Revision 1.1 2002/05/02 15:22:07 seletz * - generic io framework * - this tries to add a generic io framework. io "drivers" for * a memory pool included. * Why do i need this? Well, i want to have CF, Flash, Memory, filesystem * and tar file access separated from each other. Please have a look at * generic_io.h, * system3.c::iotest(), * and tar.c (now also using the generic io framework) * * Revision 1.4 2002/04/27 04:59:59 timriker * turn on ide and pcmcia again, fix pcmcia compiles (but not features) for non sa1111 systems * * Revision 1.3 2002/04/26 09:22:05 seletz * - added original copyright from Brad Parker * - corrected EMAIL addr * * Revision 1.2 2002/04/24 14:27:08 seletz * - first round of bugfixing. Now at last one can read 512 byte sectors * of a CF in true-ide mode. See system3.c::pcmciatest(). * * Still WIP. YMMV, and so on.... * * Revision 1.1 2002/04/18 19:52:49 seletz * - Added PCMCIA and IDE framework. Based on Brad Parker's code. * NOTE NOTE NOTE: * This is all Work-In-Progress (you have been warned) * */ /********************************************************************** * Includes */ #ifdef HAVE_CONFIG_H # include <blob/config.h> #endif #include <blob/types.h> #include <blob/errno.h> #include <blob/util.h> #include <blob/command.h> #include <blob/time.h> #include <blob/serial.h> #include <blob/arch.h> #include <blob/init.h> #include <blob/generic_io.h> /********************************************************************** * Defines / Makros */ #define IO_MODULE_TEST 1 #define IO_DEBUG 1 #ifdef IO_DEBUG # define DBG( x, args... ) if ( io_dbg>x ) printf( args ) #else # define DBG( x, args... ) #endif /********************************************************************** * Typen */ /********************************************************************** * Programmglobale Variable */ /********************************************************************** * Modulglobale Variable */ static char *module_version = "$Id: generic_io.c,v 1.1 2002/05/02 15:22:07 seletz Exp $"; #ifdef IO_DEBUG static int io_dbg = 1; #else static int io_dbg = 0; #endif static io_driver_t *drivers[IO_MAX_DRIVER]; /********************************************************************** * Prototypen */ static int ram_io_read( unsigned char *dest, unsigned char *src, size_t amount, io_driver_t *io ); static int ram_io_write( unsigned char *dest, unsigned char *src, size_t amount, io_driver_t *io ); /********************************************************************** * Exported functions */ void io_dbg_set( int lvl ) { io_dbg = lvl; } void io_init( void ) { int i; for ( i=0; i<IO_MAX_DRIVER;i++) drivers[i] = NULL; return; } __initlist(io_init, INIT_LEVEL_OTHER_STUFF + 1); int io_register( io_driver_t *io, char *name ) { int i; if ( !io || !name ) return -EINVAL; for ( i=0; i<IO_MAX_DRIVER;i++) { if (!drivers[i]) break; } if ( i==IO_MAX_DRIVER) return -EINVAL; drivers[i]=io; strncpy( io->name, name, IO_NAME_LEN ); DBG( 1, "%s: driver '%s' registered #%d.\n", __FUNCTION__, name, i ); return 0; } int io_configure( io_driver_t *io, void *conf_data ) { if ( !io ) return -EINVAL; if (io->conf ) return io->conf( io, conf_data ); return 0; } io_driver_t *io_get_byname( char *name ) { int i; if ( !name ) return NULL; for ( i=0; i<IO_MAX_DRIVER;i++) { if (drivers[i]) { DBG( 1, "%s: #%d '%s'\n", __FUNCTION__, i, io_get_name( drivers[i] ) ); if ( strncmp( io_get_name( drivers[i] ), name, IO_NAME_LEN ) == 0 ) return drivers[i]; } } return NULL; } int io_chain_driver( char *parent, char *new_child ) { io_driver_t *p, *c; if ( !parent || !new_child ) return -EINVAL; p = io_get_byname( parent ); if ( !p ) return -EINVAL; c = io_get_byname( new_child ); if ( !c ) return -EINVAL; DBG( 1, "%s: chained Parent '%s' -> child '%s'.\n", __FUNCTION__, io_get_name( p ), io_get_name( c ) ); p->child_io = c; return 0; } int io_read( unsigned char *dest, unsigned char *src, size_t amount, io_driver_t *rd ) { if ( !rd || !rd->read ) return -EINVAL; /* FIXME: check bounds */ return rd->read( dest, src, amount, rd ); } int io_write( unsigned char *dest, unsigned char *src, size_t amount, io_driver_t *rd ) { if ( !rd|| !rd->write ) return -EINVAL; /* FIXME: check bounds */ return rd->write( dest, src, amount, rd ); } int io_copy( io_driver_t *dest, io_driver_t *src, size_t amount ) { static unsigned char buffer[512]; int ret = 0; int blocks, block, to_copy; unsigned char *adr = NULL; if ( !dest || !src ) return -EINVAL; blocks = amount / 512 + (amount%512?1:0); DBG( 1, "%s: %d blocks (%d bytes) to copy.\n", __FUNCTION__, blocks, amount ); for ( block=0; block<blocks; block++ ) { if ( amount > 512 ) { to_copy = 512; } else { to_copy = amount; } DBG( 1, "%s: block %d/%d (%d bytes)\n", __FUNCTION__, block, blocks, to_copy ); /* read from source */ ret = io_read( buffer, adr, to_copy, src ); if ( ret ) { DBG( 1, "%s: read failed at block %d (adr %p).\n", __FUNCTION__, block, adr ); return -EINVAL; } /* write to dest */ ret = io_write( adr, buffer, to_copy, dest ); if ( ret ) { DBG( 1, "%s: write failed at block %d (adr %p).\n", __FUNCTION__, block, adr ); return -EINVAL; } amount -= to_copy; adr += to_copy; } return 0; } /********************************************************************** * A simple RAM driver */ void init_ram_default_io( void ) { int ret; static ram_io_t ram0, ram1; static io_driver_t io_ram0, io_ram1; ram0.start=0xd0000000; ram0.len=8*1024*1024; ram0.pos=0; ram1.start=0xd0800000; ram1.len=8*1024*1024; ram1.pos=0; ret = ram_io_init( &io_ram0, &ram0 ); if ( ret ) return; ret = ram_io_init( &io_ram1, &ram1 ); if ( ret ) return; ret = io_register( &io_ram0, "RAM0" ); if ( ret ) return; ret = io_register( &io_ram1, "RAM1" ); if ( ret ) return; } __initlist(init_ram_default_io, INIT_LEVEL_OTHER_STUFF + 2); int ram_io_init( io_driver_t *io, ram_io_t *ram ) { if ( !io || !ram ) return -EINVAL; io->private_data = (void *)ram; io->io_size = ram->len - ram->pos; io->conf = ram_io_conf; io->read = ram_io_read; io->write = ram_io_write; io->child_io = NULL; return 0; } int ram_io_conf( io_driver_t * io, void *conf ) { ram_io_t *ram; if ( !io || !conf ) return -EINVAL; ram = (ram_io_t*)io->private_data; if ( !ram ) return -EINVAL; if ( (u32)conf >= ram->len ) return -EINVAL; ram->pos = (u32)conf; io->io_size = ram->len - (u32)ram->pos; return 0; } static int ram_io_read( unsigned char *dest, unsigned char *src, size_t amount, io_driver_t *io ) { u32 offset; ram_io_t *ram; DBG( 1, "%s: dest=%p, src=%p, amount=%d, io=%p\n", __FUNCTION__, dest, src, amount, io ); if ( !io || !dest ) return -EINVAL; ram = (ram_io_t*)io->private_data; if ( !ram ) return -EINVAL; offset = ram->start + (u32)ram->pos; DBG( 1, "%s: dest=%p, src=%p(=%p), amount=%d, io=%p\n", __FUNCTION__, dest, src, (void*)(src +offset), amount, io ); memcpy( dest, (void *)(offset + (u32)src), amount); return 0; } static int ram_io_write( unsigned char *dest, unsigned char *src, size_t amount, io_driver_t *io ) { u32 offset; ram_io_t *ram; if ( !io || !src ) return -EINVAL; ram = (ram_io_t*)io->private_data; if ( !ram ) return -EINVAL; offset = ram->start + (u32)ram->pos; DBG( 1, "%s: dest=%p(=%p), src=%p, amount=%d, io=%p\n", __FUNCTION__, dest, (void*)(dest +offset), src, amount, io ); memcpy((void *)(offset + (u32)dest), src, amount); return 0; } #if defined(IO_MODULE_TEST) /********************************************************************** * module test function */ int io_test( void ) { int ret = 0; io_driver_t *io0, *io1; DBG( 1, "%s: version %s\n", __FUNCTION__, module_version ); io0 = io_get_byname( "RAM0" ); if ( ret ) return -EINVAL; io1 = io_get_byname( "RAM1" ); if ( ret ) return -EINVAL; ret = io_copy( io1, io0, 768 ); if ( ret ) return -EINVAL; return 0; } #endif |