forked from Imagelibrary/rtems
* include/confdefs.h, include/rtems/config.h, include/rtems/extension.h, include/rtems/fatal.h, include/rtems/init.h, include/rtems/io.h, include/rtems/mptables.h, include/rtems/sptables.h, include/rtems/sptables.h.in, inline/rtems/extension.inl, macros/rtems/extension.inl, src/debug.c, src/exinit.c, src/extension.c, src/extensioncreate.c, src/extensiondelete.c, src/extensionident.c, src/fatal.c, src/io.c, src/itronapi.c, src/posixapi.c, src/rtemsapi.c: URL for license changed.
421 lines
9.8 KiB
C
421 lines
9.8 KiB
C
/*
|
|
* Input/Output Manager
|
|
*
|
|
*
|
|
* COPYRIGHT (c) 1989-1999.
|
|
* On-Line Applications Research Corporation (OAR).
|
|
*
|
|
* The license and distribution terms for this file may be
|
|
* found in the file LICENSE in this distribution or at
|
|
* http://www.rtems.com/license/LICENSE.
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
#include <rtems/system.h>
|
|
#include <rtems/io.h>
|
|
#include <rtems/score/isr.h>
|
|
#include <rtems/score/thread.h>
|
|
#include <rtems/score/wkspace.h>
|
|
|
|
#include <string.h>
|
|
|
|
/*PAGE
|
|
*
|
|
* _IO_Manager_initialization
|
|
*
|
|
* The IO manager has been extended to support runtime driver
|
|
* registration. The driver table is now allocated in the
|
|
* workspace.
|
|
*
|
|
*/
|
|
|
|
void _IO_Manager_initialization(
|
|
rtems_driver_address_table *driver_table,
|
|
unsigned32 drivers_in_table,
|
|
unsigned32 number_of_drivers,
|
|
unsigned32 number_of_devices
|
|
)
|
|
{
|
|
void *tmp;
|
|
unsigned32 index;
|
|
rtems_driver_name_t *np;
|
|
|
|
if ( number_of_drivers < drivers_in_table )
|
|
number_of_drivers = drivers_in_table;
|
|
|
|
tmp = _Workspace_Allocate_or_fatal_error(
|
|
sizeof( rtems_driver_address_table ) * ( number_of_drivers )
|
|
);
|
|
|
|
_IO_Driver_address_table = (rtems_driver_address_table *) tmp;
|
|
|
|
memset(
|
|
_IO_Driver_address_table, 0,
|
|
sizeof( rtems_driver_address_table ) * ( number_of_drivers )
|
|
);
|
|
|
|
if ( drivers_in_table )
|
|
for ( index = 0 ; index < drivers_in_table ; index++ )
|
|
_IO_Driver_address_table[index] = driver_table[index];
|
|
|
|
_IO_Number_of_drivers = number_of_drivers;
|
|
_IO_Number_of_devices = number_of_devices;
|
|
|
|
tmp = _Workspace_Allocate_or_fatal_error(
|
|
sizeof( rtems_driver_name_t ) * ( number_of_devices + 1 )
|
|
);
|
|
|
|
_IO_Driver_name_table = (rtems_driver_name_t *) tmp;
|
|
|
|
for( index=0, np = _IO_Driver_name_table ;
|
|
index < _IO_Number_of_devices ;
|
|
index++, np++ ) {
|
|
np->device_name = 0;
|
|
np->device_name_length = 0;
|
|
np->major = 0;
|
|
np->minor = 0;
|
|
}
|
|
}
|
|
|
|
/*PAGE
|
|
*
|
|
* _IO_Initialize_all_drivers
|
|
*
|
|
* This routine initializes all device drivers
|
|
*
|
|
* Input Paramters: NONE
|
|
*
|
|
* Output Parameters: NONE
|
|
*/
|
|
|
|
void _IO_Initialize_all_drivers( void )
|
|
{
|
|
rtems_device_major_number major;
|
|
|
|
for ( major=0 ; major < _IO_Number_of_drivers ; major ++ )
|
|
(void) rtems_io_initialize( major, 0, NULL);
|
|
}
|
|
|
|
/*PAGE
|
|
*
|
|
* rtems_io_register_driver
|
|
*
|
|
* Register a driver into the device driver table.
|
|
*
|
|
* Input Paramters:
|
|
* major - device major number (0 means allocate
|
|
* a number)
|
|
* driver_table - driver callout function table
|
|
* registered_major - the major number which is registered
|
|
*
|
|
* Output Parameters:
|
|
* RTEMS_SUCCESSFUL - if successful
|
|
* error code - if unsuccessful
|
|
*/
|
|
|
|
rtems_status_code rtems_io_register_driver(
|
|
rtems_device_major_number major,
|
|
rtems_driver_address_table *driver_table,
|
|
rtems_device_major_number *registered_major
|
|
)
|
|
{
|
|
*registered_major = 0;
|
|
|
|
/*
|
|
* Test for initialise/open being present to indicate the driver slot is
|
|
* in use.
|
|
*/
|
|
|
|
if ( major >= _IO_Number_of_drivers )
|
|
return RTEMS_INVALID_NUMBER;
|
|
|
|
if ( major == 0 )
|
|
{
|
|
for ( major = _IO_Number_of_drivers - 1 ; major ; major-- )
|
|
if ( _IO_Driver_address_table[major].initialization_entry == 0 &&
|
|
_IO_Driver_address_table[major].open_entry == 0 )
|
|
break;
|
|
|
|
if (( major == 0 ) &&
|
|
( _IO_Driver_address_table[major].initialization_entry == 0 &&
|
|
_IO_Driver_address_table[major].open_entry == 0 ))
|
|
return RTEMS_TOO_MANY;
|
|
}
|
|
|
|
if ( _IO_Driver_address_table[major].initialization_entry == 0 &&
|
|
_IO_Driver_address_table[major].open_entry == 0 )
|
|
{
|
|
_IO_Driver_address_table[major] = *driver_table;
|
|
*registered_major = major;
|
|
|
|
rtems_io_initialize( major, 0, NULL );
|
|
|
|
return RTEMS_SUCCESSFUL;
|
|
}
|
|
|
|
return RTEMS_RESOURCE_IN_USE;
|
|
}
|
|
|
|
/*PAGE
|
|
*
|
|
* rtems_io_unregister_driver
|
|
*
|
|
* Unregister a driver from the device driver table.
|
|
*
|
|
* Input Paramters:
|
|
* major - device major number
|
|
*
|
|
* Output Parameters:
|
|
* RTEMS_SUCCESSFUL - if successful
|
|
* error code - if unsuccessful
|
|
*/
|
|
|
|
rtems_status_code rtems_io_unregister_driver(
|
|
rtems_device_major_number major
|
|
)
|
|
{
|
|
if ( major < _IO_Number_of_drivers )
|
|
{
|
|
memset(
|
|
&_IO_Driver_address_table[major],
|
|
0,
|
|
sizeof( rtems_driver_address_table )
|
|
);
|
|
return RTEMS_SUCCESSFUL;
|
|
}
|
|
return RTEMS_UNSATISFIED;
|
|
}
|
|
|
|
/*PAGE
|
|
*
|
|
* rtems_io_register_name
|
|
*
|
|
* Associate a name with a driver
|
|
*
|
|
* Input Paramters:
|
|
* device_name - pointer to name string to associate with device
|
|
* major - device major number to receive name
|
|
* minor - device minor number to receive name
|
|
*
|
|
* Output Parameters:
|
|
* RTEMS_SUCCESSFUL - if successful
|
|
* error code - if unsuccessful
|
|
*/
|
|
|
|
#if 0
|
|
rtems_status_code rtems_io_register_name(
|
|
char *device_name,
|
|
rtems_device_major_number major,
|
|
rtems_device_minor_number minor
|
|
)
|
|
{
|
|
rtems_driver_name_t *np;
|
|
unsigned32 level;
|
|
unsigned32 index;
|
|
|
|
/* find an empty slot */
|
|
for( index=0, np = _IO_Driver_name_table ;
|
|
index < _IO_Number_of_devices ;
|
|
index++, np++ )
|
|
{
|
|
|
|
_ISR_Disable(level);
|
|
if (np->device_name == 0)
|
|
{
|
|
np->device_name = device_name;
|
|
np->device_name_length = strlen(device_name);
|
|
np->major = major;
|
|
np->minor = minor;
|
|
_ISR_Enable(level);
|
|
|
|
return RTEMS_SUCCESSFUL;
|
|
}
|
|
_ISR_Enable(level);
|
|
}
|
|
|
|
return RTEMS_TOO_MANY;
|
|
}
|
|
#endif
|
|
|
|
/*PAGE
|
|
*
|
|
* rtems_io_initialize
|
|
*
|
|
* This routine is the initialization directive of the IO manager.
|
|
*
|
|
* Input Paramters:
|
|
* major - device driver number
|
|
* minor - device number
|
|
* argument - pointer to argument(s)
|
|
*
|
|
* Output Parameters:
|
|
* returns - return code
|
|
*/
|
|
|
|
rtems_status_code rtems_io_initialize(
|
|
rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void *argument
|
|
)
|
|
{
|
|
rtems_device_driver_entry callout;
|
|
|
|
if ( major >= _IO_Number_of_drivers )
|
|
return RTEMS_INVALID_NUMBER;
|
|
|
|
callout = _IO_Driver_address_table[major].initialization_entry;
|
|
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
|
|
}
|
|
|
|
/*PAGE
|
|
*
|
|
* rtems_io_open
|
|
*
|
|
* This routine is the open directive of the IO manager.
|
|
*
|
|
* Input Paramters:
|
|
* major - device driver number
|
|
* minor - device number
|
|
* argument - pointer to argument(s)
|
|
*
|
|
* Output Parameters:
|
|
* returns - return code
|
|
*/
|
|
|
|
rtems_status_code rtems_io_open(
|
|
rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void *argument
|
|
)
|
|
{
|
|
rtems_device_driver_entry callout;
|
|
|
|
if ( major >= _IO_Number_of_drivers )
|
|
return RTEMS_INVALID_NUMBER;
|
|
|
|
callout = _IO_Driver_address_table[major].open_entry;
|
|
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
|
|
}
|
|
|
|
/*PAGE
|
|
*
|
|
* rtems_io_close
|
|
*
|
|
* This routine is the close directive of the IO manager.
|
|
*
|
|
* Input Paramters:
|
|
* major - device driver number
|
|
* minor - device number
|
|
* argument - pointer to argument(s)
|
|
*
|
|
* Output Parameters:
|
|
* returns - return code
|
|
*/
|
|
|
|
rtems_status_code rtems_io_close(
|
|
rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void *argument
|
|
)
|
|
{
|
|
rtems_device_driver_entry callout;
|
|
|
|
if ( major >= _IO_Number_of_drivers )
|
|
return RTEMS_INVALID_NUMBER;
|
|
|
|
callout = _IO_Driver_address_table[major].close_entry;
|
|
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
|
|
}
|
|
|
|
/*PAGE
|
|
*
|
|
* rtems_io_read
|
|
*
|
|
* This routine is the read directive of the IO manager.
|
|
*
|
|
* Input Paramters:
|
|
* major - device driver number
|
|
* minor - device number
|
|
* argument - pointer to argument(s)
|
|
*
|
|
* Output Parameters:
|
|
* returns - return code
|
|
*/
|
|
|
|
rtems_status_code rtems_io_read(
|
|
rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void *argument
|
|
)
|
|
{
|
|
rtems_device_driver_entry callout;
|
|
|
|
if ( major >= _IO_Number_of_drivers )
|
|
return RTEMS_INVALID_NUMBER;
|
|
|
|
callout = _IO_Driver_address_table[major].read_entry;
|
|
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
|
|
}
|
|
|
|
/*PAGE
|
|
*
|
|
* rtems_io_write
|
|
*
|
|
* This routine is the write directive of the IO manager.
|
|
*
|
|
* Input Paramters:
|
|
* major - device driver number
|
|
* minor - device number
|
|
* argument - pointer to argument(s)
|
|
*
|
|
* Output Parameters:
|
|
* returns - return code
|
|
*/
|
|
|
|
rtems_status_code rtems_io_write(
|
|
rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void *argument
|
|
)
|
|
{
|
|
rtems_device_driver_entry callout;
|
|
|
|
if ( major >= _IO_Number_of_drivers )
|
|
return RTEMS_INVALID_NUMBER;
|
|
|
|
callout = _IO_Driver_address_table[major].write_entry;
|
|
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
|
|
}
|
|
|
|
/*PAGE
|
|
*
|
|
* rtems_io_control
|
|
*
|
|
* This routine is the control directive of the IO manager.
|
|
*
|
|
* Input Paramters:
|
|
* major - device driver number
|
|
* minor - device number
|
|
* argument - pointer to argument(s)
|
|
*
|
|
* Output Parameters:
|
|
* returns - return code
|
|
*/
|
|
|
|
rtems_status_code rtems_io_control(
|
|
rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void *argument
|
|
)
|
|
{
|
|
rtems_device_driver_entry callout;
|
|
|
|
if ( major >= _IO_Number_of_drivers )
|
|
return RTEMS_INVALID_NUMBER;
|
|
|
|
callout = _IO_Driver_address_table[major].control_entry;
|
|
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
|
|
}
|
|
|