1 //==========================================================================
5 // I/O Subsystem + Device Table support
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
44 // Contributors: gthomas
46 // Purpose: Device I/O Support
49 //####DESCRIPTIONEND####
51 //==========================================================================
53 #include <pkgconf/io.h>
54 #include <cyg/io/io.h>
55 #include <cyg/io/devtab.h>
56 #include <cyg/infra/diag.h>
58 //extern void cyg_io_init(void) CYGBLD_ATTRIB_CONSTRUCTOR
59 // CYG_INIT_PRIORITY(CYG_INIT_BEFORE(LIBC));
61 // Checks that two strings are "equivalent" device names
62 // 'n1' is a string from the user
63 // 'n2' is a name in a device table entry
64 // 'cyg_io_compare()' will return true IFF
65 // n1 == n2, for all characters
66 // n2 ends in '/' and matches n1 up to the terminating '/'
67 // 'ptr' will get a pointer to the residual string.
69 cyg_io_compare(const char *n1, const char *n2, const char **ptr)
77 // See if the devtab name is is a substring
91 // This function is called during system initialization. The purpose is
92 // to step through all devices linked into the system, calling their
93 // "init" entry points.
99 static int _init = false;
100 cyg_devtab_entry_t *t;
102 for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++) {
103 #ifdef CYGDBG_IO_INIT
104 diag_printf("Init device '%s'\n", t->name);
107 t->status |= CYG_DEVTAB_STATUS_AVAIL;
109 // What to do if device init fails?
110 // Device not [currently] available
111 t->status &= ~CYG_DEVTAB_STATUS_AVAIL;
118 // Look up the devtab entry for a named device and return its handle.
119 // If the device is found and it has a "lookup" function, call that
120 // function to allow the device/driver to perform any necessary
125 cyg_io_lookup(const char *name, cyg_io_handle_t *handle)
127 union devtab_entry_handle_union {
128 cyg_devtab_entry_t *st;
131 cyg_devtab_entry_t *t;
133 const char *name_ptr;
134 for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++) {
135 if (cyg_io_compare(name, t->name, &name_ptr)) {
136 // FUTURE: Check 'avail'/'online' here
138 res = cyg_io_lookup(t->dep_name, &stunion.h);
146 // This indirection + the name pointer allows the lookup routine
147 // to return a different 'devtab' handle. This will provide for
148 // 'pluggable' devices, file names, etc.
149 res = (t->lookup)(&t, stunion.st, name_ptr);
154 *handle = (cyg_io_handle_t)t;
158 return -ENOENT; // Not found
162 // 'write' data to a device.
166 cyg_io_write(cyg_io_handle_t handle, const void *buf, cyg_uint32 *len)
168 cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
170 if (!t->handlers->write) {
173 // Special check. If length is zero, this just verifies that the
174 // 'write' method exists for the given device.
175 if (NULL != len && 0 == *len) {
178 return t->handlers->write(handle, buf, len);
182 // 'read' data from a device.
186 cyg_io_read(cyg_io_handle_t handle, void *buf, cyg_uint32 *len)
188 cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
190 if (!t->handlers->read) {
193 // Special check. If length is zero, this just verifies that the
194 // 'read' method exists for the given device.
195 if (NULL != len && 0 == *len) {
198 return t->handlers->read(handle, buf, len);
202 cyg_io_bwrite(cyg_io_handle_t handle, const void *buf, cyg_uint32 *len, cyg_uint32 pos)
204 cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
206 if (!t->handlers->bwrite) {
209 // Special check. If length is zero, this just verifies that the
210 // 'bwrite' method exists for the given device.
211 if (NULL != len && 0 == *len) {
214 return t->handlers->bwrite(handle, buf, len, pos);
218 // 'read' data from a device.
222 cyg_io_bread(cyg_io_handle_t handle, void *buf, cyg_uint32 *len, cyg_uint32 pos)
224 cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
226 if (!t->handlers->bread) {
229 // Special check. If length is zero, this just verifies that the
230 // 'bread' method exists for the given device.
231 if (NULL != len && 0 == *len) {
234 return t->handlers->bread(handle, buf, len, pos);
238 // Check device for available input or space for output
242 cyg_io_select(cyg_io_handle_t handle, cyg_uint32 which, CYG_ADDRWORD info)
244 cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
246 if (!t->handlers->select) {
250 return t->handlers->select( handle, which, info );
254 // Get the configuration of a device.
258 cyg_io_get_config(cyg_io_handle_t handle, cyg_uint32 key, void *buf, cyg_uint32 *len)
260 cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
262 if (!t->handlers->get_config) {
265 // Special check. If length is zero, this just verifies that the
266 // 'get_config' method exists for the given device.
267 if (NULL != len && 0 == *len) {
270 return t->handlers->get_config(handle, key, buf, len);
274 // Change the configuration of a device.
278 cyg_io_set_config(cyg_io_handle_t handle, cyg_uint32 key, const void *buf, cyg_uint32 *len)
280 cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
282 if (!t->handlers->set_config) {
285 // Special check. If length is zero, this just verifies that the
286 // 'set_config' method exists for the given device.
287 if (NULL != len && 0 == *len) {
290 return t->handlers->set_config(handle, key, buf, len);
293 /*---------------------------------------------------------------------------*/
294 // Default functions for devio tables
296 Cyg_ErrNo cyg_devio_cwrite(cyg_io_handle_t handle, const void *buf, cyg_uint32 *len)
301 Cyg_ErrNo cyg_devio_cread(cyg_io_handle_t handle, void *buf, cyg_uint32 *len)
306 Cyg_ErrNo cyg_devio_bwrite(cyg_io_handle_t handle, const void *buf,
307 cyg_uint32 *len, cyg_uint32 pos)
312 Cyg_ErrNo cyg_devio_bread(cyg_io_handle_t handle, void *buf,
313 cyg_uint32 *len, cyg_uint32 pos)
319 cyg_devio_select(cyg_io_handle_t handle, cyg_uint32 which, CYG_ADDRWORD info)
321 CYG_UNUSED_PARAM(cyg_io_handle_t, handle);
322 CYG_UNUSED_PARAM(cyg_uint32, which);
323 CYG_UNUSED_PARAM(CYG_ADDRWORD, info);
328 cyg_devio_get_config(cyg_io_handle_t handle, cyg_uint32 key,
329 void* buf, cyg_uint32* len)
331 CYG_UNUSED_PARAM(cyg_io_handle_t, handle);
332 CYG_UNUSED_PARAM(cyg_uint32, key);
333 CYG_UNUSED_PARAM(void*, buf);
334 CYG_UNUSED_PARAM(cyg_uint32*, len);
339 cyg_devio_set_config(cyg_io_handle_t handle, cyg_uint32 key,
340 void* buf, cyg_uint32* len)
342 CYG_UNUSED_PARAM(cyg_io_handle_t, handle);
343 CYG_UNUSED_PARAM(cyg_uint32, key);
344 CYG_UNUSED_PARAM(void*, buf);
345 CYG_UNUSED_PARAM(cyg_uint32*, len);
349 /*---------------------------------------------------------------------------*/
350 /* End of io/iosys.c */