2012-11-29 14:36:55 +01:00
/*
* Copyright IBM Corp . 2012
*
* Author ( s ) :
* Jan Glauber < jang @ linux . vnet . ibm . com >
*/
# define COMPONENT "zPCI"
# define pr_fmt(fmt) COMPONENT ": " fmt
# include <linux/kernel.h>
# include <linux/stat.h>
# include <linux/pci.h>
static ssize_t show_fid ( struct device * dev , struct device_attribute * attr ,
char * buf )
{
2013-05-17 16:33:40 +02:00
struct zpci_dev * zdev = get_zdev ( to_pci_dev ( dev ) ) ;
2012-11-29 14:36:55 +01:00
2013-06-05 16:08:07 +02:00
return sprintf ( buf , " 0x%08x \n " , zdev - > fid ) ;
2012-11-29 14:36:55 +01:00
}
static DEVICE_ATTR ( function_id , S_IRUGO , show_fid , NULL ) ;
static ssize_t show_fh ( struct device * dev , struct device_attribute * attr ,
char * buf )
{
2013-05-17 16:33:40 +02:00
struct zpci_dev * zdev = get_zdev ( to_pci_dev ( dev ) ) ;
2012-11-29 14:36:55 +01:00
2013-06-05 16:08:07 +02:00
return sprintf ( buf , " 0x%08x \n " , zdev - > fh ) ;
2012-11-29 14:36:55 +01:00
}
static DEVICE_ATTR ( function_handle , S_IRUGO , show_fh , NULL ) ;
static ssize_t show_pchid ( struct device * dev , struct device_attribute * attr ,
char * buf )
{
2013-05-17 16:33:40 +02:00
struct zpci_dev * zdev = get_zdev ( to_pci_dev ( dev ) ) ;
2012-11-29 14:36:55 +01:00
2013-06-05 16:08:07 +02:00
return sprintf ( buf , " 0x%04x \n " , zdev - > pchid ) ;
2012-11-29 14:36:55 +01:00
}
static DEVICE_ATTR ( pchid , S_IRUGO , show_pchid , NULL ) ;
static ssize_t show_pfgid ( struct device * dev , struct device_attribute * attr ,
char * buf )
{
2013-05-17 16:33:40 +02:00
struct zpci_dev * zdev = get_zdev ( to_pci_dev ( dev ) ) ;
2012-11-29 14:36:55 +01:00
2013-06-05 16:08:07 +02:00
return sprintf ( buf , " 0x%02x \n " , zdev - > pfgid ) ;
2012-11-29 14:36:55 +01:00
}
static DEVICE_ATTR ( pfgid , S_IRUGO , show_pfgid , NULL ) ;
2014-02-03 14:03:04 -05:00
static ssize_t store_recover ( struct device * dev , struct device_attribute * attr ,
const char * buf , size_t count )
2013-08-29 19:35:19 +02:00
{
struct pci_dev * pdev = to_pci_dev ( dev ) ;
struct zpci_dev * zdev = get_zdev ( pdev ) ;
int ret ;
2014-02-03 14:03:04 -05:00
if ( ! device_remove_file_self ( dev , attr ) )
return count ;
2013-08-29 19:35:19 +02:00
pci_stop_and_remove_bus_device ( pdev ) ;
ret = zpci_disable_device ( zdev ) ;
if ( ret )
2014-02-03 14:03:04 -05:00
return ret ;
2013-08-29 19:35:19 +02:00
ret = zpci_enable_device ( zdev ) ;
if ( ret )
2014-02-03 14:03:04 -05:00
return ret ;
2013-08-29 19:35:19 +02:00
pci_rescan_bus ( zdev - > bus ) ;
2014-02-03 14:03:04 -05:00
return count ;
2013-08-29 19:35:19 +02:00
}
static DEVICE_ATTR ( recover , S_IWUSR , NULL , store_recover ) ;
2012-11-29 14:36:55 +01:00
static struct device_attribute * zpci_dev_attrs [ ] = {
& dev_attr_function_id ,
& dev_attr_function_handle ,
& dev_attr_pchid ,
& dev_attr_pfgid ,
2013-08-29 19:35:19 +02:00
& dev_attr_recover ,
2012-11-29 14:36:55 +01:00
NULL ,
} ;
int zpci_sysfs_add_device ( struct device * dev )
{
int i , rc = 0 ;
for ( i = 0 ; zpci_dev_attrs [ i ] ; i + + ) {
rc = device_create_file ( dev , zpci_dev_attrs [ i ] ) ;
if ( rc )
goto error ;
}
return 0 ;
error :
while ( - - i > = 0 )
device_remove_file ( dev , zpci_dev_attrs [ i ] ) ;
return rc ;
}
void zpci_sysfs_remove_device ( struct device * dev )
{
int i ;
for ( i = 0 ; zpci_dev_attrs [ i ] ; i + + )
device_remove_file ( dev , zpci_dev_attrs [ i ] ) ;
}