2005-04-16 15:20:36 -07:00
/*
* Interface for Dynamic Logical Partitioning of I / O Slots on
* RPA - compliant PPC64 platform .
*
* John Rose < johnrose @ austin . ibm . com >
* October 2003
*
* Copyright ( C ) 2003 IBM .
*
* 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 ; either version
* 2 of the License , or ( at your option ) any later version .
*/
# include <linux/kobject.h>
# include <linux/string.h>
# include "pci_hotplug.h"
# include "rpadlpar.h"
# define DLPAR_KOBJ_NAME "control"
# define ADD_SLOT_ATTR_NAME "add_slot"
# define REMOVE_SLOT_ATTR_NAME "remove_slot"
# define MAX_DRC_NAME_LEN 64
/* Store return code of dlpar operation in attribute struct */
struct dlpar_io_attr {
int rc ;
struct attribute attr ;
ssize_t ( * store ) ( struct dlpar_io_attr * dlpar_attr , const char * buf ,
size_t nbytes ) ;
} ;
/* Common show callback for all attrs, display the return code
* of the dlpar op */
static ssize_t
dlpar_attr_show ( struct kobject * kobj , struct attribute * attr , char * buf )
{
struct dlpar_io_attr * dlpar_attr = container_of ( attr ,
struct dlpar_io_attr , attr ) ;
return sprintf ( buf , " %d \n " , dlpar_attr - > rc ) ;
}
static ssize_t
dlpar_attr_store ( struct kobject * kobj , struct attribute * attr ,
const char * buf , size_t nbytes )
{
struct dlpar_io_attr * dlpar_attr = container_of ( attr ,
struct dlpar_io_attr , attr ) ;
return dlpar_attr - > store ?
2005-04-29 01:26:27 -05:00
dlpar_attr - > store ( dlpar_attr , buf , nbytes ) : - EIO ;
2005-04-16 15:20:36 -07:00
}
static struct sysfs_ops dlpar_attr_sysfs_ops = {
. show = dlpar_attr_show ,
. store = dlpar_attr_store ,
} ;
static ssize_t add_slot_store ( struct dlpar_io_attr * dlpar_attr ,
const char * buf , size_t nbytes )
{
char drc_name [ MAX_DRC_NAME_LEN ] ;
char * end ;
if ( nbytes > MAX_DRC_NAME_LEN )
return 0 ;
memcpy ( drc_name , buf , nbytes ) ;
end = strchr ( drc_name , ' \n ' ) ;
if ( ! end )
end = & drc_name [ nbytes ] ;
* end = ' \0 ' ;
dlpar_attr - > rc = dlpar_add_slot ( drc_name ) ;
return nbytes ;
}
static ssize_t remove_slot_store ( struct dlpar_io_attr * dlpar_attr ,
const char * buf , size_t nbytes )
{
char drc_name [ MAX_DRC_NAME_LEN ] ;
char * end ;
if ( nbytes > MAX_DRC_NAME_LEN )
return 0 ;
memcpy ( drc_name , buf , nbytes ) ;
end = strchr ( drc_name , ' \n ' ) ;
if ( ! end )
end = & drc_name [ nbytes ] ;
* end = ' \0 ' ;
dlpar_attr - > rc = dlpar_remove_slot ( drc_name ) ;
return nbytes ;
}
static struct dlpar_io_attr add_slot_attr = {
. rc = 0 ,
. attr = { . name = ADD_SLOT_ATTR_NAME , . mode = 0644 , } ,
. store = add_slot_store ,
} ;
static struct dlpar_io_attr remove_slot_attr = {
. rc = 0 ,
. attr = { . name = REMOVE_SLOT_ATTR_NAME , . mode = 0644 } ,
. store = remove_slot_store ,
} ;
static struct attribute * default_attrs [ ] = {
& add_slot_attr . attr ,
& remove_slot_attr . attr ,
NULL ,
} ;
static void dlpar_io_release ( struct kobject * kobj )
{
/* noop */
return ;
}
struct kobj_type ktype_dlpar_io = {
. release = dlpar_io_release ,
. sysfs_ops = & dlpar_attr_sysfs_ops ,
. default_attrs = default_attrs ,
} ;
struct kset dlpar_io_kset = {
. subsys = & pci_hotplug_slots_subsys ,
. kobj = { . name = DLPAR_KOBJ_NAME , . ktype = & ktype_dlpar_io , } ,
. ktype = & ktype_dlpar_io ,
} ;
int dlpar_sysfs_init ( void )
{
if ( kset_register ( & dlpar_io_kset ) ) {
printk ( KERN_ERR " rpadlpar_io: cannot register kset for %s \n " ,
dlpar_io_kset . kobj . name ) ;
return - EINVAL ;
}
return 0 ;
}
void dlpar_sysfs_exit ( void )
{
kset_unregister ( & dlpar_io_kset ) ;
}