2019-03-12 00:10:41 +02:00
// SPDX-License-Identifier: GPL-2.0
2013-04-05 22:10:34 +03:00
/*
2019-03-12 00:10:44 +02:00
* Copyright ( c ) 2012 - 2016 , Intel Corporation . All rights reserved
2013-04-05 22:10:34 +03:00
* Intel Management Engine Interface ( Intel MEI ) Linux driver
*/
2019-03-12 00:10:41 +02:00
2013-04-05 22:10:34 +03:00
# include <linux/slab.h>
# include <linux/kernel.h>
# include <linux/device.h>
# include <linux/debugfs.h>
2019-05-20 11:55:39 +03:00
# include <linux/seq_file.h>
2013-04-05 22:10:34 +03:00
# include <linux/mei.h>
# include "mei_dev.h"
2015-01-11 00:07:16 +02:00
# include "client.h"
2013-04-05 22:10:34 +03:00
# include "hw.h"
2019-05-20 11:55:39 +03:00
static int mei_dbgfs_meclients_show ( struct seq_file * m , void * unused )
2013-04-05 22:10:34 +03:00
{
2019-05-20 11:55:39 +03:00
struct mei_device * dev = m - > private ;
2015-02-10 10:39:31 +02:00
struct mei_me_client * me_cl ;
2014-08-21 14:29:13 +03:00
int i = 0 ;
2013-04-05 22:10:34 +03:00
2019-05-20 11:55:39 +03:00
if ( ! dev )
return - ENODEV ;
2013-04-05 22:10:34 +03:00
2015-02-10 10:39:31 +02:00
down_read ( & dev - > me_clients_rwsem ) ;
2014-09-29 16:31:34 +03:00
2019-05-20 11:55:39 +03:00
seq_puts ( m , " |id|fix| UUID |con|msg len|sb|refc| \n " ) ;
2014-09-29 16:31:34 +03:00
2014-01-08 22:31:46 +02:00
/* if the driver is not enabled the list won't be consistent */
2013-04-05 22:10:34 +03:00
if ( dev - > dev_state ! = MEI_DEV_ENABLED )
goto out ;
2015-02-10 10:39:31 +02:00
list_for_each_entry ( me_cl , & dev - > me_clients , list ) {
2019-05-20 11:55:39 +03:00
if ( ! mei_me_cl_get ( me_cl ) )
continue ;
seq_printf ( m , " %2d|%2d|%3d|%pUl|%3d|%7d|%2d|%4d| \n " ,
i + + , me_cl - > client_id ,
me_cl - > props . fixed_address ,
& me_cl - > props . protocol_name ,
me_cl - > props . max_number_of_connections ,
me_cl - > props . max_msg_length ,
me_cl - > props . single_recv_buf ,
kref_read ( & me_cl - > refcnt ) ) ;
mei_me_cl_put ( me_cl ) ;
2013-04-05 22:10:34 +03:00
}
2015-02-10 10:39:31 +02:00
2013-04-05 22:10:34 +03:00
out :
2015-02-10 10:39:31 +02:00
up_read ( & dev - > me_clients_rwsem ) ;
2019-05-20 11:55:39 +03:00
return 0 ;
2013-04-05 22:10:34 +03:00
}
2019-05-20 11:55:39 +03:00
DEFINE_SHOW_ATTRIBUTE ( mei_dbgfs_meclients ) ;
2013-04-05 22:10:34 +03:00
2019-05-20 11:55:39 +03:00
static int mei_dbgfs_active_show ( struct seq_file * m , void * unused )
2014-01-14 23:21:41 +02:00
{
2019-05-20 11:55:39 +03:00
struct mei_device * dev = m - > private ;
2014-01-14 23:21:41 +02:00
struct mei_cl * cl ;
int i = 0 ;
2016-02-07 23:35:17 +02:00
2014-01-14 23:21:41 +02:00
if ( ! dev )
return - ENODEV ;
2016-02-07 23:35:17 +02:00
mutex_lock ( & dev - > device_lock ) ;
2019-05-20 11:55:39 +03:00
seq_puts ( m , " |me|host|state|rd|wr|wrq \n " ) ;
2014-01-14 23:21:41 +02:00
2014-09-29 16:31:47 +03:00
/* if the driver is not enabled the list won't be consistent */
2014-01-14 23:21:41 +02:00
if ( dev - > dev_state ! = MEI_DEV_ENABLED )
goto out ;
list_for_each_entry ( cl , & dev - > file_list , link ) {
2019-05-20 11:55:39 +03:00
seq_printf ( m , " %3d|%2d|%4d|%5d|%2d|%2d|%3u \n " ,
i , mei_cl_me_id ( cl ) , cl - > host_client_id , cl - > state ,
! list_empty ( & cl - > rd_completed ) , cl - > writing_state ,
cl - > tx_cb_queued ) ;
2014-01-14 23:21:41 +02:00
i + + ;
}
out :
mutex_unlock ( & dev - > device_lock ) ;
2019-05-20 11:55:39 +03:00
return 0 ;
2014-01-14 23:21:41 +02:00
}
2019-05-20 11:55:39 +03:00
DEFINE_SHOW_ATTRIBUTE ( mei_dbgfs_active ) ;
2014-01-14 23:21:41 +02:00
2019-05-20 11:55:39 +03:00
static int mei_dbgfs_devstate_show ( struct seq_file * m , void * unused )
2013-04-05 22:10:34 +03:00
{
2019-05-20 11:55:39 +03:00
struct mei_device * dev = m - > private ;
2013-04-05 22:10:34 +03:00
2019-05-20 11:55:39 +03:00
seq_printf ( m , " dev: %s \n " , mei_dev_state_str ( dev - > dev_state ) ) ;
seq_printf ( m , " hbm: %s \n " , mei_hbm_state_str ( dev - > hbm_state ) ) ;
2015-05-21 13:35:48 +03:00
2016-02-07 23:35:18 +02:00
if ( dev - > hbm_state > = MEI_HBM_ENUM_CLIENTS & &
dev - > hbm_state < = MEI_HBM_STARTED ) {
2019-05-20 11:55:39 +03:00
seq_puts ( m , " hbm features: \n " ) ;
seq_printf ( m , " \t PG: %01d \n " , dev - > hbm_f_pg_supported ) ;
seq_printf ( m , " \t DC: %01d \n " , dev - > hbm_f_dc_supported ) ;
seq_printf ( m , " \t IE: %01d \n " , dev - > hbm_f_ie_supported ) ;
seq_printf ( m , " \t DOT: %01d \n " , dev - > hbm_f_dot_supported ) ;
seq_printf ( m , " \t EV: %01d \n " , dev - > hbm_f_ev_supported ) ;
seq_printf ( m , " \t FA: %01d \n " , dev - > hbm_f_fa_supported ) ;
seq_printf ( m , " \t OS: %01d \n " , dev - > hbm_f_os_supported ) ;
seq_printf ( m , " \t DR: %01d \n " , dev - > hbm_f_dr_supported ) ;
2015-05-21 13:35:48 +03:00
}
2019-05-20 11:55:39 +03:00
seq_printf ( m , " pg: %s, %s \n " ,
mei_pg_is_enabled ( dev ) ? " ENABLED " : " DISABLED " ,
mei_pg_state_str ( mei_pg_state ( dev ) ) ) ;
return 0 ;
2013-04-05 22:10:34 +03:00
}
2019-05-20 11:55:39 +03:00
DEFINE_SHOW_ATTRIBUTE ( mei_dbgfs_devstate ) ;
2013-04-05 22:10:34 +03:00
2016-02-07 23:35:38 +02:00
static ssize_t mei_dbgfs_write_allow_fa ( struct file * file ,
const char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct mei_device * dev ;
int ret ;
dev = container_of ( file - > private_data ,
struct mei_device , allow_fixed_address ) ;
ret = debugfs_write_file_bool ( file , user_buf , count , ppos ) ;
if ( ret < 0 )
return ret ;
dev - > override_fixed_address = true ;
return ret ;
}
2019-05-20 11:55:39 +03:00
static const struct file_operations mei_dbgfs_allow_fa_fops = {
2016-02-07 23:35:38 +02:00
. open = simple_open ,
. read = debugfs_read_file_bool ,
. write = mei_dbgfs_write_allow_fa ,
. llseek = generic_file_llseek ,
} ;
2013-04-05 22:10:34 +03:00
/**
* mei_dbgfs_deregister - Remove the debugfs files and directories
2014-09-29 16:31:49 +03:00
*
* @ dev : the mei device structure
2013-04-05 22:10:34 +03:00
*/
void mei_dbgfs_deregister ( struct mei_device * dev )
{
if ( ! dev - > dbgfs_dir )
return ;
debugfs_remove_recursive ( dev - > dbgfs_dir ) ;
dev - > dbgfs_dir = NULL ;
}
/**
2014-09-29 16:31:49 +03:00
* mei_dbgfs_register - Add the debugfs files
2013-04-05 22:10:34 +03:00
*
2014-09-29 16:31:49 +03:00
* @ dev : the mei device structure
* @ name : the mei device name
2013-04-05 22:10:34 +03:00
*/
2019-06-11 20:38:16 +02:00
void mei_dbgfs_register ( struct mei_device * dev , const char * name )
2013-04-05 22:10:34 +03:00
{
2019-06-11 20:38:16 +02:00
struct dentry * dir ;
2014-09-29 16:31:37 +03:00
2013-04-05 22:10:34 +03:00
dir = debugfs_create_dir ( name , NULL ) ;
2015-08-24 15:27:37 +03:00
dev - > dbgfs_dir = dir ;
2019-06-11 20:38:16 +02:00
debugfs_create_file ( " meclients " , S_IRUSR , dir , dev ,
2019-07-12 12:24:03 -07:00
& mei_dbgfs_meclients_fops ) ;
2019-06-11 20:38:16 +02:00
debugfs_create_file ( " active " , S_IRUSR , dir , dev ,
2019-07-12 12:24:03 -07:00
& mei_dbgfs_active_fops ) ;
2019-06-11 20:38:16 +02:00
debugfs_create_file ( " devstate " , S_IRUSR , dir , dev ,
2019-07-12 12:24:03 -07:00
& mei_dbgfs_devstate_fops ) ;
2019-06-11 20:38:16 +02:00
debugfs_create_file ( " allow_fixed_address " , S_IRUSR | S_IWUSR , dir ,
& dev - > allow_fixed_address ,
2019-07-12 12:24:03 -07:00
& mei_dbgfs_allow_fa_fops ) ;
2013-04-05 22:10:34 +03:00
}