source: rtems/cpukit/sapi/src/io.c @ 059a3714

4.104.114.84.95
Last change on this file since 059a3714 was 059a3714, checked in by Joel Sherrill <joel.sherrill@…>, on 10/16/01 at 19:05:29

2001-10-16 Chris Johns <ccj@…>

  • include/confdefs.h, include/rtems/config.h, include/rtems/io.h, optman/no-io.c, src/exinit.c, src/io.c: Added a device driver register/unregister interface to allow device drivers to be installed and removed at runtime. This means you do not need devices present in the device table when you build.
  • Property mode set to 100644
File size: 10.7 KB
Line 
1/*
2 *  Input/Output Manager
3 *
4 *
5 *  COPYRIGHT (c) 1989-1999.
6 *  On-Line Applications Research Corporation (OAR).
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.OARcorp.com/rtems/license.html.
11 *
12 *  $Id$
13 */
14
15#include <rtems/system.h>
16#include <rtems/io.h>
17#include <rtems/score/isr.h>
18#include <rtems/score/thread.h>
19#include <rtems/score/wkspace.h>
20
21#include <string.h>
22
23/*PAGE
24 *
25 *  _IO_Manager_initialization
26 *
27 *  The IO manager has been extended to support runtime driver
28 *  registration. The driver table is now allocated in the
29 *  workspace.
30 *
31 */
32 
33void _IO_Manager_initialization(
34    rtems_driver_address_table *driver_table,
35    unsigned32                  drivers_in_table,
36    unsigned32                  number_of_drivers,
37    unsigned32                  number_of_devices
38)
39{
40  void                *tmp;
41  unsigned32           index;
42  rtems_driver_name_t *np;
43
44  if ( number_of_drivers < drivers_in_table )
45      number_of_drivers = drivers_in_table;
46 
47  tmp = _Workspace_Allocate_or_fatal_error(
48    sizeof( rtems_driver_address_table ) * ( number_of_drivers )
49  );
50 
51  _IO_Driver_address_table = (rtems_driver_address_table *) tmp;
52
53  memset(
54    _IO_Driver_address_table, 0,
55    sizeof( rtems_driver_address_table ) * ( number_of_drivers )
56  );
57
58  if ( drivers_in_table )
59      for ( index = 0 ; index < drivers_in_table ; index++ )
60        _IO_Driver_address_table[index] = driver_table[index];
61 
62  _IO_Number_of_drivers = number_of_drivers;
63  _IO_Number_of_devices = number_of_devices;
64 
65  tmp = _Workspace_Allocate_or_fatal_error(
66    sizeof( rtems_driver_name_t ) * ( number_of_devices + 1 )
67  );
68 
69  _IO_Driver_name_table = (rtems_driver_name_t *) tmp;
70 
71  for( index=0, np = _IO_Driver_name_table ;
72       index < _IO_Number_of_devices ;
73       index++, np++ ) {
74    np->device_name = 0;
75    np->device_name_length = 0;
76    np->major = 0;
77    np->minor = 0;
78  }
79}
80
81/*PAGE
82 *
83 *  _IO_Initialize_all_drivers
84 *
85 *  This routine initializes all device drivers
86 *
87 *  Input Paramters:   NONE
88 *
89 *  Output Parameters: NONE
90 */
91
92void _IO_Initialize_all_drivers( void )
93{
94   rtems_device_major_number major;
95
96   for ( major=0 ; major < _IO_Number_of_drivers ; major ++ )
97     (void) rtems_io_initialize( major, 0, NULL);
98}
99
100/*PAGE
101 *
102 *  rtems_io_register_driver
103 *
104 *  Register a driver into the device driver table.
105 *
106 *  Input Paramters:
107 *    major            - device major number (0 means allocate
108 *                       a number)
109 *    driver_table     - driver callout function table
110 *    registered_major - the major number which is registered
111 *
112 *  Output Parameters:
113 *    RTEMS_SUCCESSFUL - if successful
114 *    error code       - if unsuccessful
115 */
116
117rtems_status_code rtems_io_register_driver(
118    rtems_device_major_number   major,
119    rtems_driver_address_table *driver_table,
120    rtems_device_major_number  *registered_major
121)
122{
123    *registered_major = 0;
124
125    /*
126     * Test for initialise/open being present to indicate the driver slot is
127     * in use.
128     */
129
130    if ( major >= _IO_Number_of_drivers )
131      return RTEMS_INVALID_NUMBER;
132
133    if ( major == 0 )
134    {
135        for ( major = _IO_Number_of_drivers - 1 ; major ; major-- )
136            if ( _IO_Driver_address_table[major].initialization_entry == 0 &&
137                 _IO_Driver_address_table[major].open_entry == 0 )
138                break;
139
140        if (( major == 0 ) &&
141            ( _IO_Driver_address_table[major].initialization_entry == 0 &&
142              _IO_Driver_address_table[major].open_entry == 0 ))
143            return RTEMS_TOO_MANY;
144    }
145   
146    if ( _IO_Driver_address_table[major].initialization_entry == 0 &&
147         _IO_Driver_address_table[major].open_entry == 0 )
148    {
149        _IO_Driver_address_table[major] = *driver_table;
150        *registered_major               = major;
151
152        rtems_io_initialize( major, 0, NULL);
153
154        return RTEMS_SUCCESSFUL;
155    }
156
157    return RTEMS_RESOURCE_IN_USE;
158}
159
160/*PAGE
161 *
162 *  rtems_io_unregister_driver
163 *
164 *  Unregister a driver from the device driver table.
165 *
166 *  Input Paramters:
167 *    major            - device major number
168 *
169 *  Output Parameters:
170 *    RTEMS_SUCCESSFUL - if successful
171 *    error code       - if unsuccessful
172 */
173
174rtems_status_code rtems_io_unregister_driver(
175    rtems_device_major_number major
176)
177{
178    if ( major < _IO_Number_of_drivers )
179    {
180        memset(
181            &_IO_Driver_address_table[major],
182            0,
183            sizeof( rtems_driver_address_table )
184        );
185        return RTEMS_SUCCESSFUL;
186    }
187    return RTEMS_UNSATISFIED;
188}
189
190/*PAGE
191 *
192 *  rtems_io_register_name
193 *
194 *  Associate a name with a driver
195 *
196 *  Input Paramters:
197 *    device_name - pointer to name string to associate with device
198 *    major       - device major number to receive name
199 *    minor       - device minor number to receive name
200 *
201 *  Output Parameters:
202 *    RTEMS_SUCCESSFUL - if successful
203 *    error code       - if unsuccessful
204 */
205
206#if 0
207rtems_status_code rtems_io_register_name(
208    char *device_name,
209    rtems_device_major_number major,
210    rtems_device_minor_number minor
211  )
212{
213    rtems_driver_name_t *np;
214    unsigned32 level;
215    unsigned32 index;
216
217    /* find an empty slot */
218    for( index=0, np = _IO_Driver_name_table ;
219         index < _IO_Number_of_devices ;
220         index++, np++ )
221    {
222
223        _ISR_Disable(level);
224        if (np->device_name == 0)
225        {
226            np->device_name = device_name;
227            np->device_name_length = strlen(device_name);
228            np->major = major;
229            np->minor = minor;
230            _ISR_Enable(level);
231
232            return RTEMS_SUCCESSFUL;
233        }
234        _ISR_Enable(level);
235    }
236
237    return RTEMS_TOO_MANY;
238}
239#endif
240
241/*PAGE
242 *
243 *  rtems_io_lookup_name
244 *
245 *  Find what driver "owns" this name
246 *
247 *  Input Paramters:
248 *    name - name to lookup the associated device
249 *
250 *  Output Parameters:
251 *    device_info      - device associate with name
252 *    RTEMS_SUCCESSFUL - if successful
253 *    error code       - if unsuccessful
254 */
255
256#if 0
257rtems_status_code rtems_io_lookup_name(
258    const char           *name,
259    rtems_driver_name_t **device_info
260)
261{
262    rtems_driver_name_t *np;
263    unsigned32 index;
264
265    for( index=0, np = _IO_Driver_name_table ;
266         index < _IO_Number_of_devices ;
267         index++, np++ )
268        if (np->device_name)
269            if (strncmp(np->device_name, name, np->device_name_length) == 0)
270            {               
271                *device_info = np;
272                return RTEMS_SUCCESSFUL;
273            }
274   
275    *device_info = 0;
276    return RTEMS_UNSATISFIED;
277}
278#endif
279
280
281/*PAGE
282 *
283 *  rtems_io_initialize
284 *
285 *  This routine is the initialization directive of the IO manager.
286 *
287 *  Input Paramters:
288 *    major        - device driver number
289 *    minor        - device number
290 *    argument     - pointer to argument(s)
291 *
292 *  Output Parameters:
293 *    returns       - return code
294 */
295
296rtems_status_code rtems_io_initialize(
297  rtems_device_major_number  major,
298  rtems_device_minor_number  minor,
299  void                      *argument
300)
301{
302    rtems_device_driver_entry callout;
303   
304    if ( major >= _IO_Number_of_drivers )
305        return RTEMS_INVALID_NUMBER;
306
307    callout = _IO_Driver_address_table[major].initialization_entry;
308    return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
309}
310
311/*PAGE
312 *
313 *  rtems_io_open
314 *
315 *  This routine is the open directive of the IO manager.
316 *
317 *  Input Paramters:
318 *    major        - device driver number
319 *    minor        - device number
320 *    argument     - pointer to argument(s)
321 *
322 *  Output Parameters:
323 *    returns       - return code
324 */
325
326rtems_status_code rtems_io_open(
327  rtems_device_major_number  major,
328  rtems_device_minor_number  minor,
329  void                      *argument
330)
331{
332    rtems_device_driver_entry callout;
333   
334    if ( major >= _IO_Number_of_drivers )
335        return RTEMS_INVALID_NUMBER;
336
337    callout = _IO_Driver_address_table[major].open_entry;
338    return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
339}
340
341/*PAGE
342 *
343 *  rtems_io_close
344 *
345 *  This routine is the close directive of the IO manager.
346 *
347 *  Input Paramters:
348 *    major        - device driver number
349 *    minor        - device number
350 *    argument     - pointer to argument(s)
351 *
352 *  Output Parameters:
353 *    returns       - return code
354 */
355
356rtems_status_code rtems_io_close(
357  rtems_device_major_number  major,
358  rtems_device_minor_number  minor,
359  void                      *argument
360)
361{
362    rtems_device_driver_entry callout;
363   
364    if ( major >= _IO_Number_of_drivers )
365        return RTEMS_INVALID_NUMBER;
366
367    callout = _IO_Driver_address_table[major].close_entry;
368    return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
369}
370
371/*PAGE
372 *
373 *  rtems_io_read
374 *
375 *  This routine is the read directive of the IO manager.
376 *
377 *  Input Paramters:
378 *    major        - device driver number
379 *    minor        - device number
380 *    argument     - pointer to argument(s)
381 *
382 *  Output Parameters:
383 *    returns       - return code
384 */
385
386rtems_status_code rtems_io_read(
387  rtems_device_major_number  major,
388  rtems_device_minor_number  minor,
389  void                      *argument
390)
391{
392    rtems_device_driver_entry callout;
393   
394    if ( major >= _IO_Number_of_drivers )
395        return RTEMS_INVALID_NUMBER;
396
397    callout = _IO_Driver_address_table[major].read_entry;
398    return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
399}
400
401/*PAGE
402 *
403 *  rtems_io_write
404 *
405 *  This routine is the write directive of the IO manager.
406 *
407 *  Input Paramters:
408 *    major        - device driver number
409 *    minor        - device number
410 *    argument     - pointer to argument(s)
411 *
412 *  Output Parameters:
413 *    returns       - return code
414 */
415
416rtems_status_code rtems_io_write(
417  rtems_device_major_number  major,
418  rtems_device_minor_number  minor,
419  void                      *argument
420)
421{
422    rtems_device_driver_entry callout;
423   
424    if ( major >= _IO_Number_of_drivers )
425        return RTEMS_INVALID_NUMBER;
426
427    callout = _IO_Driver_address_table[major].write_entry;
428    return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
429}
430
431/*PAGE
432 *
433 *  rtems_io_control
434 *
435 *  This routine is the control directive of the IO manager.
436 *
437 *  Input Paramters:
438 *    major        - device driver number
439 *    minor        - device number
440 *    argument     - pointer to argument(s)
441 *
442 *  Output Parameters:
443 *    returns       - return code
444 */
445
446rtems_status_code rtems_io_control(
447  rtems_device_major_number  major,
448  rtems_device_minor_number  minor,
449  void                      *argument
450)
451{
452    rtems_device_driver_entry callout;
453   
454    if ( major >= _IO_Number_of_drivers )
455        return RTEMS_INVALID_NUMBER;
456
457    callout = _IO_Driver_address_table[major].control_entry;
458    return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
459}
460
Note: See TracBrowser for help on using the repository browser.