Mercurial > ecos
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 2299:04006a2b020d | 2300:654c837cc618 |
|---|---|
| 9 // ==================================================================== | 9 // ==================================================================== |
| 10 //####ECOSGPLCOPYRIGHTBEGIN#### | 10 //####ECOSGPLCOPYRIGHTBEGIN#### |
| 11 // ------------------------------------------- | 11 // ------------------------------------------- |
| 12 // This file is part of eCos, the Embedded Configurable Operating System. | 12 // This file is part of eCos, the Embedded Configurable Operating System. |
| 13 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. | 13 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
| 14 // Copyright (C) 2003 Savin Zlobec | 14 // Copyright (C) 2003 Savin Zlobec |
| 15 // Copyright (C) 2004, 2005 eCosCentric Limited | |
| 15 // | 16 // |
| 16 // eCos is free software; you can redistribute it and/or modify it under | 17 // eCos is free software; you can redistribute it and/or modify it under |
| 17 // the terms of the GNU General Public License as published by the Free | 18 // the terms of the GNU General Public License as published by the Free |
| 18 // Software Foundation; either version 2 or (at your option) any later version. | 19 // Software Foundation; either version 2 or (at your option) any later version. |
| 19 // | 20 // |
| 57 | 58 |
| 58 #include <pkgconf/system.h> | 59 #include <pkgconf/system.h> |
| 59 #include <pkgconf/io_disk.h> | 60 #include <pkgconf/io_disk.h> |
| 60 | 61 |
| 61 #include <cyg/infra/cyg_type.h> | 62 #include <cyg/infra/cyg_type.h> |
| 63 #include <cyg/io/devtab.h> | |
| 62 #include <cyg/io/io.h> | 64 #include <cyg/io/io.h> |
| 63 #include <cyg/io/diskio.h> | |
| 64 #include <cyg/hal/drv_api.h> | 65 #include <cyg/hal/drv_api.h> |
| 65 | 66 #include <string.h> /* memset() */ |
| 66 typedef struct disk_channel disk_channel; | 67 |
| 67 typedef struct disk_funs disk_funs; | 68 // --------------------------------------------------------------------------- |
| 69 | |
| 70 typedef struct cyg_disk_partition_t cyg_disk_partition_t; | |
| 71 typedef struct cyg_disk_info_t cyg_disk_info_t; | |
| 72 typedef struct cyg_disk_identify_t cyg_disk_identify_t; | |
| 73 | |
| 74 typedef struct disk_channel disk_channel; | |
| 75 typedef struct disk_controller disk_controller; | |
| 76 typedef struct disk_funs disk_funs; | |
| 77 | |
| 78 // --------------------------------------------------------------------------- | |
| 68 | 79 |
| 69 // Pointers into upper-level driver | 80 // Pointers into upper-level driver |
| 70 typedef struct { | 81 typedef struct { |
| 71 | 82 |
| 72 // Initialize the disk | 83 // Initialize the disk |
| 75 // Disk device has been connected | 86 // Disk device has been connected |
| 76 Cyg_ErrNo (*disk_connected)(struct cyg_devtab_entry *tab, | 87 Cyg_ErrNo (*disk_connected)(struct cyg_devtab_entry *tab, |
| 77 cyg_disk_identify_t *ident); | 88 cyg_disk_identify_t *ident); |
| 78 | 89 |
| 79 // Disk device has been disconnected | 90 // Disk device has been disconnected |
| 80 Cyg_ErrNo (*disk_disconnected)(struct cyg_devtab_entry *tab); | 91 Cyg_ErrNo (*disk_disconnected)(struct disk_channel *chan); |
| 81 | 92 |
| 82 // Lookup disk device | 93 // Lookup disk device |
| 83 Cyg_ErrNo (*disk_lookup)(struct cyg_devtab_entry **tab, | 94 Cyg_ErrNo (*disk_lookup)(struct cyg_devtab_entry **tab, |
| 84 struct cyg_devtab_entry *sub_tab, | 95 struct cyg_devtab_entry *sub_tab, |
| 85 const char *name); | 96 const char *name); |
| 97 | |
| 98 // Asynchronous block transfer done | |
| 99 void (*disk_transfer_done)(struct disk_channel *chan, Cyg_ErrNo res); | |
| 100 | |
| 86 } disk_callbacks_t; | 101 } disk_callbacks_t; |
| 87 | 102 |
| 88 #define DISK_CALLBACKS(_l, \ | 103 #define DISK_CALLBACKS(_l, \ |
| 89 _init, \ | 104 _init, \ |
| 90 _connected, \ | 105 _connected, \ |
| 91 _disconnected, \ | 106 _disconnected, \ |
| 92 _lookup) \ | 107 _lookup, \ |
| 93 disk_callbacks_t _l = { \ | 108 _transfer_done) \ |
| 94 _init, \ | 109 disk_callbacks_t _l = { \ |
| 95 _connected, \ | 110 _init, \ |
| 96 _disconnected, \ | 111 _connected, \ |
| 97 _lookup \ | 112 _disconnected, \ |
| 113 _lookup, \ | |
| 114 _transfer_done \ | |
| 98 }; | 115 }; |
| 99 | 116 |
| 100 extern disk_callbacks_t cyg_io_disk_callbacks; | 117 extern disk_callbacks_t cyg_io_disk_callbacks; |
| 101 | 118 |
| 119 // --------------------------------------------------------------------------- | |
| 120 // Private data which describes a disk controller | |
| 121 | |
| 122 struct disk_controller { | |
| 123 cyg_drv_mutex_t lock; // Per-controller lock | |
| 124 cyg_drv_cond_t queue; // Access wait list | |
| 125 cyg_drv_cond_t async; // Async transfer waits here | |
| 126 void *priv; // Private data | |
| 127 volatile Cyg_ErrNo result; // Last operation result | |
| 128 cyg_bool init; // Initialized? | |
| 129 volatile cyg_bool busy; // Busy? | |
| 130 }; | |
| 131 | |
| 132 #define DISK_CONTROLLER(_l, _priv) \ | |
| 133 static disk_controller _l = { \ | |
| 134 priv: &_priv, \ | |
| 135 init: false, \ | |
| 136 busy: false \ | |
| 137 }; | |
| 138 | |
| 139 // --------------------------------------------------------------------------- | |
| 102 // Private data which describes this channel | 140 // Private data which describes this channel |
| 141 | |
| 103 struct disk_channel { | 142 struct disk_channel { |
| 104 disk_funs *funs; | 143 disk_funs *funs; |
| 105 disk_callbacks_t *callbacks; | 144 disk_callbacks_t *callbacks; |
| 106 void *dev_priv; // device private data | 145 void *dev_priv; // device private data |
| 146 disk_controller *controller; // pointer to controller | |
| 107 cyg_disk_info_t *info; // disk info | 147 cyg_disk_info_t *info; // disk info |
| 108 cyg_disk_partition_t *partition; // partition data | 148 cyg_disk_partition_t *partition; // partition data |
| 109 struct cyg_devtab_entry *pdevs_dev; // partition devs devtab ents | 149 struct cyg_devtab_entry *pdevs_dev; // partition devs devtab ents |
| 110 disk_channel *pdevs_chan; // partition devs disk chans | 150 disk_channel *pdevs_chan; // partition devs disk chans |
| 111 cyg_bool mbr_support; // true if disk has MBR | 151 cyg_bool mbr_support; // true if disk has MBR |
| 112 cyg_bool valid; // true if device valid | 152 cyg_bool valid; // true if device valid |
| 113 cyg_bool init; // true if initialized | 153 cyg_bool init; // true if initialized |
| 154 cyg_ucount16 mounts; // count of number of mounts | |
| 114 }; | 155 }; |
| 115 | 156 |
| 116 // Initialization macro for disk channel | 157 // Initialization macro for disk channel |
| 117 #define DISK_CHANNEL(_l, \ | 158 #define DISK_CHANNEL(_l, \ |
| 118 _funs, \ | 159 _funs, \ |
| 119 _dev_priv, \ | 160 _dev_priv, \ |
| 161 _controller, \ | |
| 120 _mbr_supp, \ | 162 _mbr_supp, \ |
| 121 _max_part_num) \ | 163 _max_part_num) \ |
| 122 static struct cyg_devtab_entry _l##_part_dev[_max_part_num]; \ | 164 static struct cyg_devtab_entry _l##_part_dev[_max_part_num]; \ |
| 123 static disk_channel _l##_part_chan[_max_part_num]; \ | 165 static disk_channel _l##_part_chan[_max_part_num]; \ |
| 124 static cyg_disk_partition_t _l##_part_tab[_max_part_num]; \ | 166 static cyg_disk_partition_t _l##_part_tab[_max_part_num]; \ |
| 128 }; \ | 170 }; \ |
| 129 static disk_channel _l = { \ | 171 static disk_channel _l = { \ |
| 130 &(_funs), \ | 172 &(_funs), \ |
| 131 &cyg_io_disk_callbacks, \ | 173 &cyg_io_disk_callbacks, \ |
| 132 &(_dev_priv), \ | 174 &(_dev_priv), \ |
| 175 &(_controller), \ | |
| 133 &(_l##_disk_info), \ | 176 &(_l##_disk_info), \ |
| 134 NULL, \ | 177 NULL, \ |
| 135 _l##_part_dev, \ | 178 _l##_part_dev, \ |
| 136 _l##_part_chan, \ | 179 _l##_part_chan, \ |
| 137 _mbr_supp, \ | 180 _mbr_supp, \ |
| 138 false, \ | 181 false, \ |
| 139 false \ | 182 false, \ |
| 140 }; | 183 0 \ |
| 141 | 184 }; |
| 185 | |
| 186 // Initialization macro for disk channel allocated elsewhere. | |
| 187 #define DISK_CHANNEL_INIT(_dc, \ | |
| 188 _funs, \ | |
| 189 _dev_priv, \ | |
| 190 _controller, \ | |
| 191 _disk_info, \ | |
| 192 _part_dev, \ | |
| 193 _part_chan, \ | |
| 194 _part_tab, \ | |
| 195 _mbr_supp, \ | |
| 196 _max_part_num) \ | |
| 197 CYG_MACRO_START \ | |
| 198 memset((_disk_info), 0, sizeof(cyg_disk_info_t)); \ | |
| 199 (_dc).funs = &(_funs); \ | |
| 200 (_dc).callbacks = &cyg_io_disk_callbacks; \ | |
| 201 (_dc).dev_priv = (_dev_priv); \ | |
| 202 (_dc).controller = &(_controller); \ | |
| 203 (_dc).info = &(_disk_info); \ | |
| 204 (_dc).info->partitions = (_part_tab); \ | |
| 205 (_dc).pdevs_dev = (_part_dev); \ | |
| 206 (_dc).pdevs_chan = (_part_chan); \ | |
| 207 (_dc).partition = NULL; \ | |
| 208 (_dc).mbr_support = (_mbr_supp); \ | |
| 209 (_dc).valid = false; \ | |
| 210 (_dc).init = false; \ | |
| 211 (_dc).mounts = 0; \ | |
| 212 (_dc).info->partitions_num = (_max_part_num); \ | |
| 213 CYG_MACRO_END | |
| 214 | |
| 215 // --------------------------------------------------------------------------- | |
| 142 // Low level interface functions | 216 // Low level interface functions |
| 217 | |
| 143 struct disk_funs { | 218 struct disk_funs { |
| 144 | 219 |
| 145 // Read block data into buf | 220 // Read block data into buf |
| 146 Cyg_ErrNo (*read)(disk_channel *priv, | 221 Cyg_ErrNo (*read)(disk_channel *priv, |
| 147 void *buf, | 222 void *buf, |
| 166 const void *xbuf, | 241 const void *xbuf, |
| 167 cyg_uint32 *len); | 242 cyg_uint32 *len); |
| 168 }; | 243 }; |
| 169 | 244 |
| 170 #define DISK_FUNS(_l,_read,_write,_get_config,_set_config) \ | 245 #define DISK_FUNS(_l,_read,_write,_get_config,_set_config) \ |
| 171 disk_funs _l = { \ | 246 static disk_funs _l = { \ |
| 172 _read, \ | 247 _read, \ |
| 173 _write, \ | 248 _write, \ |
| 174 _get_config, \ | 249 _get_config, \ |
| 175 _set_config \ | 250 _set_config \ |
| 176 }; | 251 }; |
| 177 | 252 |
| 178 extern cyg_devio_table_t cyg_io_disk_devio; | 253 extern cyg_devio_table_t cyg_io_disk_devio; |
| 179 | 254 |
| 255 // --------------------------------------------------------------------------- | |
| 256 | |
| 257 #include <cyg/io/diskio.h> | |
| 258 | |
| 259 // --------------------------------------------------------------------------- | |
| 180 #endif // CYGONCE_DISK_H | 260 #endif // CYGONCE_DISK_H |
