2019-05-27 09:55:05 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2005-04-17 02:20:36 +04:00
/*
* IBM ASM Service Processor Device Driver
*
* Copyright ( C ) IBM Corporation , 2004
*
2011-12-30 02:09:01 +04:00
* Author : Max Asböck < amax @ us . ibm . com >
2005-04-17 02:20:36 +04:00
*/
# include "ibmasm.h"
# include "dot_command.h"
2020-07-01 11:30:58 +03:00
/*
2005-04-17 02:20:36 +04:00
* Dispatch an incoming message to the specific handler for the message .
* Called from interrupt context .
*/
void ibmasm_receive_message ( struct service_processor * sp , void * message , int message_size )
{
u32 size ;
struct dot_command_header * header = ( struct dot_command_header * ) message ;
2005-06-22 04:16:36 +04:00
if ( message_size = = 0 )
return ;
2005-04-17 02:20:36 +04:00
size = get_dot_command_size ( message ) ;
2005-06-22 04:16:36 +04:00
if ( size = = 0 )
return ;
2005-04-17 02:20:36 +04:00
if ( size > message_size )
size = message_size ;
switch ( header - > type ) {
2007-07-17 15:03:58 +04:00
case sp_event :
2005-04-17 02:20:36 +04:00
ibmasm_receive_event ( sp , message , size ) ;
break ;
case sp_command_response :
2007-07-17 15:03:58 +04:00
ibmasm_receive_command_response ( sp , message , size ) ;
2005-04-17 02:20:36 +04:00
break ;
case sp_heartbeat :
ibmasm_receive_heartbeat ( sp , message , size ) ;
break ;
default :
dev_err ( sp - > dev , " Received unknown message from service processor \n " ) ;
}
}
# define INIT_BUFFER_SIZE 32
2020-07-01 11:30:58 +03:00
/*
2005-04-17 02:20:36 +04:00
* send the 4.3 .5 .10 dot command ( driver VPD ) to the service processor
*/
int ibmasm_send_driver_vpd ( struct service_processor * sp )
{
struct command * command ;
struct dot_command_header * header ;
u8 * vpd_command ;
u8 * vpd_data ;
int result = 0 ;
2005-06-22 04:16:36 +04:00
command = ibmasm_new_command ( sp , INIT_BUFFER_SIZE ) ;
2005-04-17 02:20:36 +04:00
if ( command = = NULL )
return - ENOMEM ;
header = ( struct dot_command_header * ) command - > buffer ;
header - > type = sp_write ;
header - > command_size = 4 ;
header - > data_size = 16 ;
header - > status = 0 ;
header - > reserved = 0 ;
vpd_command = command - > buffer + sizeof ( struct dot_command_header ) ;
vpd_command [ 0 ] = 0x4 ;
vpd_command [ 1 ] = 0x3 ;
vpd_command [ 2 ] = 0x5 ;
vpd_command [ 3 ] = 0xa ;
vpd_data = vpd_command + header - > command_size ;
vpd_data [ 0 ] = 0 ;
strcat ( vpd_data , IBMASM_DRIVER_VPD ) ;
vpd_data [ 10 ] = 0 ;
vpd_data [ 15 ] = 0 ;
2007-07-17 15:03:58 +04:00
2005-04-17 02:20:36 +04:00
ibmasm_exec_command ( sp , command ) ;
ibmasm_wait_for_response ( command , IBMASM_CMD_TIMEOUT_NORMAL ) ;
if ( command - > status ! = IBMASM_CMD_COMPLETE )
result = - ENODEV ;
command_put ( command ) ;
return result ;
}
struct os_state_command {
struct dot_command_header header ;
unsigned char command [ 3 ] ;
unsigned char data ;
} ;
2020-07-01 11:30:58 +03:00
/*
2005-04-17 02:20:36 +04:00
* send the 4.3 .6 dot command ( os state ) to the service processor
* During driver init this function is called with os state " up " .
* This causes the service processor to start sending heartbeats the
* driver .
2007-07-17 15:03:58 +04:00
* During driver exit the function is called with os state " down " ,
2005-04-17 02:20:36 +04:00
* causing the service processor to stop the heartbeats .
*/
int ibmasm_send_os_state ( struct service_processor * sp , int os_state )
{
struct command * cmd ;
struct os_state_command * os_state_cmd ;
int result = 0 ;
2005-06-22 04:16:36 +04:00
cmd = ibmasm_new_command ( sp , sizeof ( struct os_state_command ) ) ;
2005-04-17 02:20:36 +04:00
if ( cmd = = NULL )
return - ENOMEM ;
os_state_cmd = ( struct os_state_command * ) cmd - > buffer ;
os_state_cmd - > header . type = sp_write ;
os_state_cmd - > header . command_size = 3 ;
os_state_cmd - > header . data_size = 1 ;
os_state_cmd - > header . status = 0 ;
os_state_cmd - > command [ 0 ] = 4 ;
os_state_cmd - > command [ 1 ] = 3 ;
os_state_cmd - > command [ 2 ] = 6 ;
os_state_cmd - > data = os_state ;
ibmasm_exec_command ( sp , cmd ) ;
ibmasm_wait_for_response ( cmd , IBMASM_CMD_TIMEOUT_NORMAL ) ;
if ( cmd - > status ! = IBMASM_CMD_COMPLETE )
result = - ENODEV ;
command_put ( cmd ) ;
return result ;
}