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