Mercurial > ecos
diff packages/io/disk/current/include/disk.h @ 2300:654c837cc618
* include/disk.h (DISK_CHANNEL): No need for extra _part_dev
slot intended for entire disk's own devtab.
* src/disk.c (disk_lookup): Just access pdevs_dev directly
with no adjusted offset.
(disk_init): No longer set entry 0 from device devtab.
It's unnecessary.
* include/disk.h: Merge eCosCentric CVS with public eCos CVS.
This merges (and therefore changes) the API. ChangeLog
entries have been incorporated in the correct places below.
* include/diskio.h: Also merged.
* cdl/io_disk.cdl: Also merged.
* src/disk.c: Also merged.
* src/disk.c (read_partition): Switched to favour LBA partition
information in partition tables. This also means we don't now rely
on the driver reporting a correct CHS size for the disk.
(disk_bread, disk_bwrite): API changed to take length in sectors
rather than bytes. Also call hardware driver to transfer in
(up to) max_transfer sized chunks, rather than a sector at a
time. Call in to driver now made with DSR lock claimed, to avoid a
race condition between the DSR and the calling thread.
(disk_get_config): Added phys_block_size to channel info.
* include/diskio.h (struct cyg_disk_identify_t): Added
phys_block_size and max_transfer fields. These must be filled in
by the driver.
* include/disk.h (DISK_CHANNEL_INIT): New macro. Allows a
DISK_CHANNEL to be defined dynamically.
* src/disk.c (disk_bread, disk_bwrite): Made calls to
cyg_thread_yield() dependent on presence ok kernel.
* src/disk.c (disk_bwrite): Uncomment the cyg_thread_yield() at
the end to prevent thread starvation between threads at the same
priority.
(disk_bread): Ditto.
* src/disk.c (read_partition): Changed to account for very large
disks which report bogus CHS geometry. We can only use the LBA
partition parameters in such disks.
(disk_set_config): Added some extra debug output.
* src/disk.c:
Various changes to support disconnect/reconnect of changeable
media.
* include/diskio.h: Added mount counter to disk_info structure.
* include/disk.h: Changed disk_disconnected() function to take a
pointer to a struct disk_channel rather than a struct
cyg_devtab_entry. Added mount count to disk_channel structure.
Moved include of diskio.h to end to fix declaration problems.
* src/disk.c: Fixed bug in write routine where controller result
field was not being initialized. Added signals on controller queue
condition variable after setting controller busy flag to false.
* include/disk.h: Made controller result and busy fields
volatile. Just in case.
* include/disk.h:
* src/disk.c:
Many changes. Added additional disk_controller data structure to
better reflect hardware structure. Added support for serialization
of multithreaded accesses to a single controller. Added support
for asynchronous, interrupt driven, IO operations. Various
tidies.
| author | jlarmour |
|---|---|
| date | Thu, 21 Sep 2006 16:38:38 +0000 |
| parents | b1d2762b2eec |
| children | 21a641579915 |
line wrap: on
line diff
--- a/packages/io/disk/current/include/disk.h +++ b/packages/io/disk/current/include/disk.h @@ -11,7 +11,8 @@ // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -// Copyright (C) 2003 Savin Zlobec +// Copyright (C) 2003 Savin Zlobec +// Copyright (C) 2004, 2005 eCosCentric Limited // // 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 @@ -59,12 +60,22 @@ #include <pkgconf/io_disk.h> #include <cyg/infra/cyg_type.h> +#include <cyg/io/devtab.h> #include <cyg/io/io.h> -#include <cyg/io/diskio.h> #include <cyg/hal/drv_api.h> +#include <string.h> /* memset() */ -typedef struct disk_channel disk_channel; -typedef struct disk_funs disk_funs; +// --------------------------------------------------------------------------- + +typedef struct cyg_disk_partition_t cyg_disk_partition_t; +typedef struct cyg_disk_info_t cyg_disk_info_t; +typedef struct cyg_disk_identify_t cyg_disk_identify_t; + +typedef struct disk_channel disk_channel; +typedef struct disk_controller disk_controller; +typedef struct disk_funs disk_funs; + +// --------------------------------------------------------------------------- // Pointers into upper-level driver typedef struct { @@ -77,33 +88,62 @@ typedef struct { cyg_disk_identify_t *ident); // Disk device has been disconnected - Cyg_ErrNo (*disk_disconnected)(struct cyg_devtab_entry *tab); + Cyg_ErrNo (*disk_disconnected)(struct disk_channel *chan); // Lookup disk device Cyg_ErrNo (*disk_lookup)(struct cyg_devtab_entry **tab, struct cyg_devtab_entry *sub_tab, const char *name); + + // Asynchronous block transfer done + void (*disk_transfer_done)(struct disk_channel *chan, Cyg_ErrNo res); + } disk_callbacks_t; -#define DISK_CALLBACKS(_l, \ - _init, \ - _connected, \ - _disconnected, \ - _lookup) \ -disk_callbacks_t _l = { \ - _init, \ - _connected, \ - _disconnected, \ - _lookup \ +#define DISK_CALLBACKS(_l, \ + _init, \ + _connected, \ + _disconnected, \ + _lookup, \ + _transfer_done) \ +disk_callbacks_t _l = { \ + _init, \ + _connected, \ + _disconnected, \ + _lookup, \ + _transfer_done \ }; extern disk_callbacks_t cyg_io_disk_callbacks; +// --------------------------------------------------------------------------- +// Private data which describes a disk controller + +struct disk_controller { + cyg_drv_mutex_t lock; // Per-controller lock + cyg_drv_cond_t queue; // Access wait list + cyg_drv_cond_t async; // Async transfer waits here + void *priv; // Private data + volatile Cyg_ErrNo result; // Last operation result + cyg_bool init; // Initialized? + volatile cyg_bool busy; // Busy? +}; + +#define DISK_CONTROLLER(_l, _priv) \ +static disk_controller _l = { \ + priv: &_priv, \ + init: false, \ + busy: false \ +}; + +// --------------------------------------------------------------------------- // Private data which describes this channel + struct disk_channel { disk_funs *funs; disk_callbacks_t *callbacks; void *dev_priv; // device private data + disk_controller *controller; // pointer to controller cyg_disk_info_t *info; // disk info cyg_disk_partition_t *partition; // partition data struct cyg_devtab_entry *pdevs_dev; // partition devs devtab ents @@ -111,12 +151,14 @@ struct disk_channel { cyg_bool mbr_support; // true if disk has MBR cyg_bool valid; // true if device valid cyg_bool init; // true if initialized + cyg_ucount16 mounts; // count of number of mounts }; // Initialization macro for disk channel #define DISK_CHANNEL(_l, \ _funs, \ _dev_priv, \ + _controller, \ _mbr_supp, \ _max_part_num) \ static struct cyg_devtab_entry _l##_part_dev[_max_part_num]; \ @@ -130,16 +172,49 @@ static disk_channel _l = { &(_funs), \ &cyg_io_disk_callbacks, \ &(_dev_priv), \ + &(_controller), \ &(_l##_disk_info), \ NULL, \ _l##_part_dev, \ _l##_part_chan, \ _mbr_supp, \ false, \ - false \ + false, \ + 0 \ }; +// Initialization macro for disk channel allocated elsewhere. +#define DISK_CHANNEL_INIT(_dc, \ + _funs, \ + _dev_priv, \ + _controller, \ + _disk_info, \ + _part_dev, \ + _part_chan, \ + _part_tab, \ + _mbr_supp, \ + _max_part_num) \ + CYG_MACRO_START \ + memset((_disk_info), 0, sizeof(cyg_disk_info_t)); \ + (_dc).funs = &(_funs); \ + (_dc).callbacks = &cyg_io_disk_callbacks; \ + (_dc).dev_priv = (_dev_priv); \ + (_dc).controller = &(_controller); \ + (_dc).info = &(_disk_info); \ + (_dc).info->partitions = (_part_tab); \ + (_dc).pdevs_dev = (_part_dev); \ + (_dc).pdevs_chan = (_part_chan); \ + (_dc).partition = NULL; \ + (_dc).mbr_support = (_mbr_supp); \ + (_dc).valid = false; \ + (_dc).init = false; \ + (_dc).mounts = 0; \ + (_dc).info->partitions_num = (_max_part_num); \ + CYG_MACRO_END + +// --------------------------------------------------------------------------- // Low level interface functions + struct disk_funs { // Read block data into buf @@ -168,7 +243,7 @@ struct disk_funs { }; #define DISK_FUNS(_l,_read,_write,_get_config,_set_config) \ -disk_funs _l = { \ +static disk_funs _l = { \ _read, \ _write, \ _get_config, \ @@ -177,4 +252,9 @@ disk_funs _l = { extern cyg_devio_table_t cyg_io_disk_devio; +// --------------------------------------------------------------------------- + +#include <cyg/io/diskio.h> + +// --------------------------------------------------------------------------- #endif // CYGONCE_DISK_H
