175 lines
4.1 KiB
C
175 lines
4.1 KiB
C
/*
|
|
* Creation Date: <2002/10/03 20:55:02 samuel>
|
|
* Time-stamp: <2002/10/29 13:00:23 samuel>
|
|
*
|
|
* <prom.c>
|
|
*
|
|
* oftree interface
|
|
*
|
|
* Copyright (C) 2002, 2003 Samuel Rydh (samuel@ibrium.se)
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation
|
|
*
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include "osi_calls.h"
|
|
#include "mol/prom.h"
|
|
|
|
/* OSI_PromClose (free linux side device tree) */
|
|
int
|
|
prom_close( void )
|
|
{
|
|
return OSI_PromIface( kPromClose, 0 );
|
|
}
|
|
|
|
/* ret: 0 no more peers, -1 if error */
|
|
mol_phandle_t
|
|
prom_peer( mol_phandle_t phandle )
|
|
{
|
|
return OSI_PromIface( kPromPeer, phandle );
|
|
}
|
|
|
|
/* ret: 0 no child, -1 if error */
|
|
mol_phandle_t
|
|
prom_child( mol_phandle_t phandle )
|
|
{
|
|
return OSI_PromIface( kPromChild, phandle );
|
|
}
|
|
|
|
/* ret: 0 if root node, -1 if error */
|
|
mol_phandle_t
|
|
prom_parent( mol_phandle_t phandle )
|
|
{
|
|
return OSI_PromIface( kPromParent, phandle );
|
|
}
|
|
|
|
/* ret: -1 error */
|
|
int
|
|
prom_package_to_path( mol_phandle_t phandle, char *buf, long buflen )
|
|
{
|
|
return OSI_PromIface2( kPromPackageToPath, phandle, (int)buf, buflen );
|
|
}
|
|
|
|
/* ret: -1 error */
|
|
int
|
|
prom_get_prop_len( mol_phandle_t phandle, const char *name )
|
|
{
|
|
return OSI_PromIface1( kPromGetPropLen, phandle, (int)name );
|
|
}
|
|
|
|
/* ret: prop len or -1 if error */
|
|
int
|
|
prom_get_prop( mol_phandle_t phandle, const char *name, char *buf, long buflen )
|
|
{
|
|
return OSI_PromIface3( kPromGetProp, phandle, (int)name, (int)buf, buflen );
|
|
}
|
|
|
|
/* ret: prop len or -1 if error */
|
|
int
|
|
prom_get_prop_by_path( const char *path, const char *name, char *buf, long buflen )
|
|
{
|
|
mol_phandle_t ph = prom_find_device(path);
|
|
return (ph != -1)? prom_get_prop( ph, name, buf, buflen) : -1;
|
|
}
|
|
|
|
/* ret: -1 error, 0 last prop, 1 otherwise */
|
|
int
|
|
prom_next_prop( mol_phandle_t phandle, const char *prev, char *buf )
|
|
{
|
|
return OSI_PromIface2( kPromNextProp, phandle, (int)prev, (int)buf );
|
|
}
|
|
|
|
/* ret: -1 if error */
|
|
int
|
|
prom_set_prop( mol_phandle_t phandle, const char *name, char *buf, long buflen )
|
|
{
|
|
return OSI_PromIface3( kPromSetProp, phandle, (int)name, (int)buf, buflen );
|
|
}
|
|
|
|
/* ret: -1 if error */
|
|
mol_phandle_t
|
|
prom_create_node( const char *path )
|
|
{
|
|
return OSI_PromPathIface( kPromCreateNode, path );
|
|
}
|
|
|
|
/* ret: -1 if not found */
|
|
mol_phandle_t
|
|
prom_find_device( const char *path )
|
|
{
|
|
mol_phandle_t ph;
|
|
char buf2[256], ch, *p;
|
|
|
|
if( !path )
|
|
return -1;
|
|
|
|
if( (ph=OSI_PromPathIface( kPromFindDevice, path )) != -1 )
|
|
return ph;
|
|
else if( path[0] == '/' )
|
|
return -1;
|
|
|
|
/* might be an alias */
|
|
if( !(p=strpbrk(path, "@:/")) )
|
|
p = (char*)path + strlen(path);
|
|
|
|
ch = *p;
|
|
*p = 0;
|
|
if( (ph=prom_get_prop(prom_find_device("/aliases"), path, buf2, sizeof(buf2))) == -1 )
|
|
return -1;
|
|
*p = ch;
|
|
strncat( buf2, p, sizeof(buf2) );
|
|
|
|
if( buf2[0] != '/' ) {
|
|
printk("Error: aliases must be absolute!\n");
|
|
return -1;
|
|
}
|
|
ph = OSI_PromPathIface( kPromFindDevice, buf2 );
|
|
return ph;
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************/
|
|
/* search the tree for nodes with matching device_type */
|
|
/************************************************************************/
|
|
|
|
static mol_phandle_t
|
|
prom_find_device_type_( mol_phandle_t ph, const char *type, int *icount, int index )
|
|
{
|
|
char buf[64];
|
|
int ph2;
|
|
|
|
if( ph == -1 || !ph )
|
|
return -1;
|
|
if( prom_get_prop( ph, "device_type", buf, sizeof(buf)) > 0 )
|
|
if( !strcmp(buf, type) )
|
|
if( (*icount)++ == index )
|
|
return ph;
|
|
if( (ph2=prom_find_device_type_( prom_peer(ph), type, icount, index )) != -1 )
|
|
return ph2;
|
|
if( (ph2=prom_find_device_type_( prom_child(ph), type, icount, index )) != -1 )
|
|
return ph2;
|
|
return -1;
|
|
}
|
|
|
|
mol_phandle_t
|
|
prom_find_device_type( const char *type, int index )
|
|
{
|
|
int count = 0;
|
|
return prom_find_device_type_( prom_peer(0), type, &count, index );
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* device tree tweaking */
|
|
/************************************************************************/
|
|
|
|
/* -1 if error */
|
|
int
|
|
prom_change_phandle( mol_phandle_t old_ph, mol_phandle_t new_ph )
|
|
{
|
|
return OSI_PromIface1( kPromChangePHandle, old_ph, (int)new_ph );
|
|
}
|