Mercurial > flash_v2
diff packages/devs/disk/synth/current/src/synthdisk.c @ 1476:f2453fae08d4
Added support for FAT filesystem. Several packages, see the individual
ChangeLogs for details.
| author | nickg |
|---|---|
| date | Mon, 19 Jan 2004 14:35:01 +0000 |
| parents | |
| children | 3cd6f4cd3db2 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/devs/disk/synth/current/src/synthdisk.c @@ -0,0 +1,299 @@ +//========================================================================== +// +// synthdisk.c +// +// Disk device driver for the synthetic target +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2003 Savin Zlobec. +// +// eCos 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 or (at your option) any later version. +// +// eCos 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 eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): savin +// Contributors: +// Date: 2003-06-18 +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include <pkgconf/devs_disk_ecosynth.h> + +#include <cyg/infra/cyg_type.h> +#include <cyg/infra/cyg_ass.h> +#include <cyg/infra/diag.h> +#include <cyg/hal/hal_arch.h> +#include <cyg/hal/hal_io.h> +#include <cyg/hal/drv_api.h> +#include <cyg/io/io.h> +#include <cyg/io/devtab.h> +#include <cyg/io/disk.h> + +#include <stdio.h> // sprintf + +// ---------------------------------------------------------------------------- + +//#define DEBUG 1 + +// ---------------------------------------------------------------------------- + +typedef struct { + int num; + cyg_uint32 cylinders_num; + cyg_uint32 heads_num; + cyg_uint32 sectors_num; + cyg_uint32 size; + int filefd; + char *filename; +} synth_disk_info_t; + +// ---------------------------------------------------------------------------- + +static cyg_bool synth_disk_init(struct cyg_devtab_entry *tab); + +static Cyg_ErrNo synth_disk_read(disk_channel *chan, + void *buf, + cyg_uint32 len, + cyg_uint32 block_num); + +static Cyg_ErrNo synth_disk_write(disk_channel *chan, + const void *buf, + cyg_uint32 len, + cyg_uint32 block_num); + +static Cyg_ErrNo synth_disk_get_config(disk_channel *chan, + cyg_uint32 key, + const void *xbuf, + cyg_uint32 *len); + +static Cyg_ErrNo synth_disk_set_config(disk_channel *chan, + cyg_uint32 key, + const void *xbuf, + cyg_uint32 *len); + +static Cyg_ErrNo synth_disk_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name); + +static DISK_FUNS(synth_disk_funs, + synth_disk_read, + synth_disk_write, + synth_disk_get_config, + synth_disk_set_config +); + +// ---------------------------------------------------------------------------- + +#define SYNTH_DISK_INSTANCE(_number_,_mbr_supp_, _cyl_,_hpt_,_spt_) \ +static synth_disk_info_t synth_disk_info##_number_ = { \ + num: _number_, \ + cylinders_num: _cyl_, \ + heads_num: _hpt_, \ + sectors_num: _spt_, \ + size: CYGNUM_IO_DISK_ECOSYNTH_DISK##_number_##_SIZE, \ + filefd: -1, \ + filename: CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_FILENAME \ +}; \ +static DISK_CHANNEL(synth_disk_channel##_number_, \ + synth_disk_funs, \ + synth_disk_info##_number_, \ + _mbr_supp_ \ +); \ +BLOCK_DEVTAB_ENTRY(synth_disk_io##_number_, \ + CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_NAME, \ + 0, \ + &cyg_io_disk_devio, \ + synth_disk_init, \ + synth_disk_lookup, \ + &synth_disk_channel##_number_ \ +); + +// ---------------------------------------------------------------------------- + +#ifdef CYGVAR_DEVS_DISK_ECOSYNTH_DISK0 +# ifndef CYGIMP_IO_DISK_ECOSYNTH_DISK0_MBR +SYNTH_DISK_INSTANCE(0, false, 0, 0, 0); +# else +SYNTH_DISK_INSTANCE(0, true, CYGIMP_IO_DISK_ECOSYNTH_DISK0_CYLINDERS, + CYGIMP_IO_DISK_ECOSYNTH_DISK0_HEADS, + CYGIMP_IO_DISK_ECOSYNTH_DISK0_SECTORS); +# endif +#endif + +// ---------------------------------------------------------------------------- + +static cyg_bool +synth_disk_init(struct cyg_devtab_entry *tab) +{ + disk_channel *chan = (disk_channel *) tab->priv; + synth_disk_info_t *synth_info = (synth_disk_info_t *) chan->dev_priv; + bool result = true; + + if (chan->init) + return true; + +#ifdef DEBUG + diag_printf("synth disk %d init size=%d\n", + synth_info->num, synth_info->size); +#endif + + synth_info->filefd = cyg_hal_sys_open(synth_info->filename, + CYG_HAL_SYS_O_RDWR, + CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO); + + if (-ENOENT == synth_info->filefd) + { + synth_info->filefd = cyg_hal_sys_open(synth_info->filename, + CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT, 0644); + + if (synth_info->filefd >= 0) + { + unsigned char b = 0x00; + int i; + + for (i = 0; i < synth_info->size; i++) + cyg_hal_sys_write(synth_info->filefd, &b, 1); + } + } + + if (synth_info->filefd < 0) + { + CYG_ASSERT(false, "Can't open/create disk image file"); + return false; + } + + if (result) + { + cyg_disk_identify_t ident; + + ident.serial[0] = '\0'; + ident.firmware_rev[0] = '\0'; + ident.model_num[0] = '\0'; + ident.lba_sectors_num = synth_info->size / 512; + ident.cylinders_num = synth_info->cylinders_num; + ident.heads_num = synth_info->heads_num; + ident.sectors_num = synth_info->sectors_num; + + if (!(chan->callbacks->disk_init)(tab)) + return false; + if (ENOERR != (chan->callbacks->disk_connected)(tab, &ident)) + return false; + } + return result; +} + +static Cyg_ErrNo +synth_disk_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name) +{ + disk_channel *chan = (disk_channel *) (*tab)->priv; + return (chan->callbacks->disk_lookup(tab, sub_tab, name)); +} + +static Cyg_ErrNo +synth_disk_read(disk_channel *chan, + void *buf, + cyg_uint32 len, + cyg_uint32 block_num) +{ + synth_disk_info_t *synth_info = (synth_disk_info_t *)chan->dev_priv; + +#ifdef DEBUG + diag_printf("synth disk read block %d\n", block_num); +#endif + + if (synth_info->filefd >= 0) + { + cyg_hal_sys_lseek(synth_info->filefd, + block_num * chan->info->block_size, + CYG_HAL_SYS_SEEK_SET); + cyg_hal_sys_read(synth_info->filefd, buf, len); + return ENOERR; + } + return -EIO; +} + +static Cyg_ErrNo +synth_disk_write(disk_channel *chan, + const void *buf, + cyg_uint32 len, + cyg_uint32 block_num) +{ + synth_disk_info_t *synth_info = (synth_disk_info_t *)chan->dev_priv; + +#ifdef DEBUG + diag_printf("synth disk write block %d\n", block_num); +#endif + + if (synth_info->filefd >= 0) + { + cyg_hal_sys_lseek(synth_info->filefd, + block_num * chan->info->block_size, + CYG_HAL_SYS_SEEK_SET); + cyg_hal_sys_write(synth_info->filefd, buf, len); +// cyg_hal_sys_fdatasync(synth_info->filefd); + return ENOERR; + } + return -EIO; +} + +static Cyg_ErrNo +synth_disk_get_config(disk_channel *chan, + cyg_uint32 key, + const void *xbuf, + cyg_uint32 *len) +{ + +#ifdef DEBUG + diag_printf("synth disk get config\n"); +#endif + + return -EINVAL; +} + +static Cyg_ErrNo +synth_disk_set_config(disk_channel *chan, + cyg_uint32 key, + const void *xbuf, + cyg_uint32 *len) +{ + +#ifdef DEBUG + diag_printf("synth disk set config\n"); +#endif + + return -EINVAL; +} + +// ---------------------------------------------------------------------------- +// EOF synthdisk.c
