2001-12-11 11:42:30 +00:00
/*
2002-01-10 18:12:26 +00:00
* Copyright ( C ) 2002 Sistina Software
2001-12-11 11:42:30 +00:00
*
* This file is released under the LGPL .
*/
# include "label.h"
2002-01-10 15:01:58 +00:00
# include "list.h"
# include "dbg_malloc.h"
2002-01-10 16:48:28 +00:00
# include "log.h"
2001-12-11 11:42:30 +00:00
2002-01-10 15:01:58 +00:00
/*
* Internal labeller struct .
*/
struct labeller_i {
struct list list ;
2001-12-11 11:42:30 +00:00
2002-01-10 15:01:58 +00:00
struct labeller * l ;
char name [ 0 ] ;
} ;
2001-12-13 08:40:47 +00:00
2002-01-10 15:01:58 +00:00
static struct list _labellers ;
2001-12-11 11:42:30 +00:00
2002-01-10 15:01:58 +00:00
static struct labeller_i * _alloc_li ( const char * name , struct labeller * l )
2001-12-11 11:42:30 +00:00
{
2002-01-10 15:01:58 +00:00
struct labeller_i * li ;
size_t len ;
2001-12-11 11:42:30 +00:00
2002-01-10 15:01:58 +00:00
len = sizeof ( * li ) + strlen ( name ) + 1 ;
2001-12-11 11:42:30 +00:00
2002-01-10 15:01:58 +00:00
if ( ! ( li = dbg_malloc ( len ) ) ) {
log_err ( " Couldn't allocate memory for labeller list object. " ) ;
return NULL ;
}
li - > l = l ;
strcpy ( li - > name , name ) ;
return li ;
2001-12-12 09:05:44 +00:00
}
2001-12-11 11:42:30 +00:00
2002-01-11 10:43:32 +00:00
static void _free_li ( struct labeller_i * li )
2001-12-12 09:05:44 +00:00
{
2002-01-10 15:01:58 +00:00
dbg_free ( li ) ;
}
2001-12-11 11:42:30 +00:00
2001-12-11 16:49:40 +00:00
2002-01-10 15:01:58 +00:00
int label_init ( void )
{
list_init ( & _labellers ) ;
2002-01-10 16:48:28 +00:00
return 1 ;
2001-12-11 11:42:30 +00:00
}
2002-01-10 15:01:58 +00:00
void label_exit ( void )
2001-12-14 13:15:15 +00:00
{
2002-01-10 15:01:58 +00:00
struct list * c , * n ;
2002-01-11 10:43:32 +00:00
struct labeller_i * li ;
2002-01-10 15:01:58 +00:00
for ( c = _labellers . n ; c ! = & _labellers ; c = n ) {
n = c - > n ;
2002-01-11 10:43:32 +00:00
li = list_item ( c , struct labeller_i ) ;
_free_li ( li ) ;
2002-01-10 15:01:58 +00:00
}
2001-12-14 13:15:15 +00:00
}
2002-01-10 15:01:58 +00:00
int label_register_handler ( const char * name , struct labeller * handler )
2001-12-11 11:42:30 +00:00
{
2002-01-10 15:01:58 +00:00
struct labeller_i * li ;
if ( ! ( li = _alloc_li ( name , handler ) ) ) {
2001-12-11 11:42:30 +00:00
stack ;
2001-12-11 16:49:40 +00:00
return 0 ;
2001-12-11 11:42:30 +00:00
}
2002-01-10 15:01:58 +00:00
list_add ( & _labellers , & li - > list ) ;
return 1 ;
2001-12-11 11:42:30 +00:00
}
2002-01-10 15:01:58 +00:00
struct labeller * label_get_handler ( const char * name )
2001-12-11 11:42:30 +00:00
{
2002-01-10 15:01:58 +00:00
struct list * lih ;
struct labeller_i * li ;
2001-12-11 11:42:30 +00:00
2002-01-10 15:01:58 +00:00
list_iterate ( lih , & _labellers ) {
li = list_item ( lih , struct labeller_i ) ;
if ( ! strcmp ( li - > name , name ) )
return li - > l ;
}
2001-12-11 11:42:30 +00:00
2002-01-10 15:01:58 +00:00
return NULL ;
}
2001-12-11 11:42:30 +00:00
2002-01-11 10:43:32 +00:00
static struct labeller * _find_labeller ( struct device * dev )
2001-12-11 11:42:30 +00:00
{
2002-01-10 15:01:58 +00:00
struct list * lih ;
struct labeller_i * li ;
2001-12-11 11:42:30 +00:00
2002-01-10 15:01:58 +00:00
list_iterate ( lih , & _labellers ) {
li = list_item ( lih , struct labeller_i ) ;
2002-01-11 10:43:32 +00:00
if ( li - > l - > ops - > can_handle ( li - > l , dev ) )
2002-01-10 15:01:58 +00:00
return li - > l ;
}
2001-12-11 11:42:30 +00:00
2002-01-11 10:43:32 +00:00
log_err ( " Could not find label on device '%s'. " , dev_name ( dev ) ) ;
2002-01-10 15:01:58 +00:00
return NULL ;
2001-12-11 11:42:30 +00:00
}
2002-01-11 10:43:32 +00:00
int label_remove ( struct device * dev )
2001-12-11 11:42:30 +00:00
{
2002-01-10 15:01:58 +00:00
struct labeller * l ;
2002-01-11 10:43:32 +00:00
if ( ! ( l = _find_labeller ( dev ) ) ) {
2002-01-10 15:01:58 +00:00
stack ;
return 0 ;
2001-12-11 16:49:40 +00:00
}
2001-12-11 11:42:30 +00:00
2002-01-11 10:43:32 +00:00
return l - > ops - > remove ( l , dev ) ;
2001-12-11 11:42:30 +00:00
}
2002-01-11 10:43:32 +00:00
int label_read ( struct device * dev , struct label * * result )
2001-12-11 11:42:30 +00:00
{
2002-01-10 15:01:58 +00:00
struct labeller * l ;
2001-12-11 11:42:30 +00:00
2002-01-11 10:43:32 +00:00
if ( ! ( l = _find_labeller ( dev ) ) ) {
2001-12-11 11:42:30 +00:00
stack ;
2002-01-10 15:01:58 +00:00
return 0 ;
2001-12-11 11:42:30 +00:00
}
2002-01-11 10:43:32 +00:00
return l - > ops - > read ( l , dev , result ) ;
2001-12-11 11:42:30 +00:00
}
2002-01-11 10:43:32 +00:00
int label_verify ( struct device * dev )
2001-12-11 11:42:30 +00:00
{
2002-01-10 15:01:58 +00:00
struct labeller * l ;
2001-12-11 11:42:30 +00:00
2002-01-11 10:43:32 +00:00
if ( ! ( l = _find_labeller ( dev ) ) ) {
2001-12-11 11:42:30 +00:00
stack ;
2002-01-10 15:01:58 +00:00
return 0 ;
2001-12-11 11:42:30 +00:00
}
2002-01-11 10:43:32 +00:00
return l - > ops - > verify ( l , dev ) ;
2001-12-11 16:49:40 +00:00
}
2002-01-10 15:01:58 +00:00
void label_free ( struct label * l )
2001-12-11 16:49:40 +00:00
{
2002-01-10 15:01:58 +00:00
dbg_free ( l - > extra_info ) ;
dbg_free ( l ) ;
2001-12-11 16:49:40 +00:00
}