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