source: SVN/cambria/redboot/packages/io/common/current/src/iosys.c @ 1

Last change on this file since 1 was 1, checked in by Tim Harvey, 2 years ago

restored latest version of files from server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 10.2 KB
Line 
1//==========================================================================
2//
3//      io/iosys.c
4//
5//      I/O Subsystem + Device Table support
6//
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.
12//
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.
16//
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
20// for more details.
21//
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.
25//
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.
32//
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.
35//
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####
42//
43// Author(s):   gthomas
44// Contributors:  gthomas
45// Date:        1999-02-04
46// Purpose:     Device I/O Support
47// Description:
48//
49//####DESCRIPTIONEND####
50//
51//==========================================================================
52
53#include <pkgconf/io.h>
54#include <cyg/io/io.h>
55#include <cyg/io/devtab.h>
56#include <cyg/infra/diag.h>
57
58//extern void cyg_io_init(void) CYGBLD_ATTRIB_CONSTRUCTOR
59//  CYG_INIT_PRIORITY(CYG_INIT_BEFORE(LIBC));
60
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.
68static bool
69cyg_io_compare(const char *n1, const char *n2, const char **ptr)
70{
71    while (*n1 && *n2) {
72        if (*n1++ != *n2++) {
73            return false;
74        }
75    }
76    if (*n1) {
77        // See if the devtab name is is a substring
78        if (*(n2-1) == '/') {
79            *ptr = n1;
80            return true;
81        }
82    }
83    if (*n1 || *n2) {
84        return false;
85    }
86    *ptr = n1;
87    return true;
88}
89
90//
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. 
94//
95
96void
97cyg_io_init(void)
98{
99    static int _init = false;
100    cyg_devtab_entry_t *t;
101    if (_init) return;
102    for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++) {
103#ifdef CYGDBG_IO_INIT
104        diag_printf("Init device '%s'\n", t->name);
105#endif
106        if (t->init(t)) {
107            t->status |= CYG_DEVTAB_STATUS_AVAIL;
108        } else {
109            // What to do if device init fails?
110            // Device not [currently] available
111            t->status &= ~CYG_DEVTAB_STATUS_AVAIL; 
112        }
113    }
114    _init = true;
115}
116
117//
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
121// initializations.
122//
123
124Cyg_ErrNo
125cyg_io_lookup(const char *name, cyg_io_handle_t *handle)
126{
127    union devtab_entry_handle_union {
128        cyg_devtab_entry_t *st;
129        cyg_io_handle_t h;
130    } stunion;
131    cyg_devtab_entry_t *t;
132    Cyg_ErrNo res;
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
137            if (t->dep_name) {
138                res = cyg_io_lookup(t->dep_name, &stunion.h);
139                if (res != ENOERR) {
140                    return res;
141                }
142            } else {
143                stunion.st = NULL;
144            }
145            if (t->lookup) {
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);
150                if (res != ENOERR) {
151                    return res;
152                }
153            }
154            *handle = (cyg_io_handle_t)t;
155            return ENOERR;
156        }
157    }
158    return -ENOENT;  // Not found
159}
160
161//
162// 'write' data to a device.
163//
164
165Cyg_ErrNo
166cyg_io_write(cyg_io_handle_t handle, const void *buf, cyg_uint32 *len)
167{
168    cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
169    // Validate request
170    if (!t->handlers->write) {
171        return -EDEVNOSUPP;
172    }
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) {
176        return ENOERR;
177    }
178    return t->handlers->write(handle, buf, len);
179}
180
181//
182// 'read' data from a device.
183//
184
185Cyg_ErrNo
186cyg_io_read(cyg_io_handle_t handle, void *buf, cyg_uint32 *len)
187{
188    cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
189    // Validate request
190    if (!t->handlers->read) {
191        return -EDEVNOSUPP;
192    }
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) {
196        return ENOERR;
197    }
198    return t->handlers->read(handle, buf, len);
199}
200
201Cyg_ErrNo
202cyg_io_bwrite(cyg_io_handle_t handle, const void *buf, cyg_uint32 *len, cyg_uint32 pos)
203{
204    cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
205    // Validate request
206    if (!t->handlers->bwrite) {
207        return -EDEVNOSUPP;
208    }
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) {
212        return ENOERR;
213    }
214    return t->handlers->bwrite(handle, buf, len, pos);
215}
216
217//
218// 'read' data from a device.
219//
220
221Cyg_ErrNo
222cyg_io_bread(cyg_io_handle_t handle, void *buf, cyg_uint32 *len, cyg_uint32 pos)
223{
224    cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
225    // Validate request
226    if (!t->handlers->bread) {
227        return -EDEVNOSUPP;
228    }
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) {
232        return ENOERR;
233    }
234    return t->handlers->bread(handle, buf, len, pos);
235}
236
237//
238// Check device for available input or space for output
239//
240
241cyg_bool
242cyg_io_select(cyg_io_handle_t handle, cyg_uint32 which, CYG_ADDRWORD info)
243{
244    cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
245    // Validate request
246    if (!t->handlers->select) {
247        return -EDEVNOSUPP;
248    }
249
250    return t->handlers->select( handle, which, info );
251}
252
253//
254// Get the configuration of a device.
255//
256
257Cyg_ErrNo
258cyg_io_get_config(cyg_io_handle_t handle, cyg_uint32 key, void *buf, cyg_uint32 *len)
259{
260    cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
261    // Validate request
262    if (!t->handlers->get_config) {
263        return -EDEVNOSUPP;
264    }
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) {
268        return ENOERR;
269    }
270    return t->handlers->get_config(handle, key, buf, len);
271}
272
273//
274// Change the configuration of a device.
275//
276
277Cyg_ErrNo
278cyg_io_set_config(cyg_io_handle_t handle, cyg_uint32 key, const void *buf, cyg_uint32 *len)
279{
280    cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
281    // Validate request
282    if (!t->handlers->set_config) {
283        return -EDEVNOSUPP;
284    }
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) {
288        return ENOERR;
289    }
290    return t->handlers->set_config(handle, key, buf, len);
291}
292
293/*---------------------------------------------------------------------------*/
294// Default functions for devio tables
295
296Cyg_ErrNo cyg_devio_cwrite(cyg_io_handle_t handle, const void *buf, cyg_uint32 *len)
297{
298    return -EDEVNOSUPP;
299}
300
301Cyg_ErrNo cyg_devio_cread(cyg_io_handle_t handle, void *buf, cyg_uint32 *len)
302{
303    return -EDEVNOSUPP;
304}
305
306Cyg_ErrNo cyg_devio_bwrite(cyg_io_handle_t handle, const void *buf,
307                        cyg_uint32 *len, cyg_uint32 pos)
308{
309    return -EDEVNOSUPP;
310}
311
312Cyg_ErrNo cyg_devio_bread(cyg_io_handle_t handle, void *buf,
313                       cyg_uint32 *len, cyg_uint32 pos)
314{
315    return -EDEVNOSUPP;
316}
317
318Cyg_ErrNo
319cyg_devio_select(cyg_io_handle_t handle, cyg_uint32 which, CYG_ADDRWORD info)
320{
321    CYG_UNUSED_PARAM(cyg_io_handle_t, handle);
322    CYG_UNUSED_PARAM(cyg_uint32, which);
323    CYG_UNUSED_PARAM(CYG_ADDRWORD, info);
324    return -EDEVNOSUPP;
325}
326
327Cyg_ErrNo
328cyg_devio_get_config(cyg_io_handle_t handle, cyg_uint32 key,
329                     void* buf, cyg_uint32* len)
330{
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);
335    return -EDEVNOSUPP;
336}
337
338Cyg_ErrNo
339cyg_devio_set_config(cyg_io_handle_t handle, cyg_uint32 key,
340                     void* buf, cyg_uint32* len)
341{
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);
346    return -EDEVNOSUPP;
347}
348
349/*---------------------------------------------------------------------------*/
350/* End of io/iosys.c */
Note: See TracBrowser for help on using the repository browser.