2018-02-20 16:30:22 +03:00
/* SPDX-License-Identifier: GPL-2.0+ */
2005-04-17 02:20:36 +04:00
/*
* ipmi_si_sm . h
*
* State machine interface for low - level IPMI system management
* interface state machines . This code is the interface between
* the ipmi_smi code ( that handles the policy of a KCS , SMIC , or
* BT interface ) and the actual low - level state machine .
*
* Author : MontaVista Software , Inc .
* Corey Minyard < minyard @ mvista . com >
* source @ mvista . com
*
* Copyright 2002 MontaVista Software Inc .
*/
2017-09-12 22:41:56 +03:00
# include <linux/ipmi.h>
2008-04-29 12:01:10 +04:00
/*
* This is defined by the state machines themselves , it is an opaque
* data type for them to use .
*/
2005-04-17 02:20:36 +04:00
struct si_sm_data ;
2017-09-12 22:41:56 +03:00
enum si_type {
2017-09-18 20:38:17 +03:00
SI_TYPE_INVALID , SI_KCS , SI_SMIC , SI_BT
2017-09-12 22:41:56 +03:00
} ;
2008-04-29 12:01:10 +04:00
/*
* The structure for doing I / O in the state machine . The state
* machine doesn ' t have the actual I / O routines , they are done through
* this interface .
*/
struct si_sm_io {
2015-06-13 18:34:25 +03:00
unsigned char ( * inputb ) ( const struct si_sm_io * io , unsigned int offset ) ;
void ( * outputb ) ( const struct si_sm_io * io ,
2005-04-17 02:20:36 +04:00
unsigned int offset ,
unsigned char b ) ;
2008-04-29 12:01:10 +04:00
/*
* Generic info used by the actual handling routines , the
* state machine shouldn ' t touch these .
*/
2005-05-04 08:40:22 +04:00
void __iomem * addr ;
2005-04-17 02:20:36 +04:00
int regspacing ;
int regsize ;
int regshift ;
2006-03-26 13:37:20 +04:00
int addr_type ;
long addr_data ;
2017-09-12 22:41:56 +03:00
enum ipmi_addr_src addr_source ; /* ACPI, PCI, SMBIOS, hardcode, etc. */
void ( * addr_source_cleanup ) ( struct si_sm_io * io ) ;
void * addr_source_data ;
2017-09-13 05:37:02 +03:00
union ipmi_smi_info_union addr_info ;
2017-09-12 22:41:56 +03:00
2017-09-12 23:40:53 +03:00
int ( * io_setup ) ( struct si_sm_io * info ) ;
void ( * io_cleanup ) ( struct si_sm_io * info ) ;
unsigned int io_size ;
2017-09-12 22:41:56 +03:00
int irq ;
2017-09-12 23:10:22 +03:00
int ( * irq_setup ) ( struct si_sm_io * io ) ;
void * irq_handler_data ;
void ( * irq_cleanup ) ( struct si_sm_io * io ) ;
2017-09-12 22:41:56 +03:00
u8 slave_addr ;
enum si_type si_type ;
struct device * dev ;
2005-04-17 02:20:36 +04:00
} ;
/* Results of SMI events. */
2008-04-29 12:01:10 +04:00
enum si_sm_result {
2005-04-17 02:20:36 +04:00
SI_SM_CALL_WITHOUT_DELAY , /* Call the driver again immediately */
SI_SM_CALL_WITH_DELAY , /* Delay some before calling again. */
2008-04-29 12:01:10 +04:00
SI_SM_CALL_WITH_TICK_DELAY , /* Delay >=1 tick before calling again. */
2005-04-17 02:20:36 +04:00
SI_SM_TRANSACTION_COMPLETE , /* A transaction is finished. */
SI_SM_IDLE , /* The SM is in idle state. */
SI_SM_HOSED , /* The hardware violated the state machine. */
2008-04-29 12:01:10 +04:00
/*
* The hardware is asserting attn and the state machine is
* idle .
*/
SI_SM_ATTN
2005-04-17 02:20:36 +04:00
} ;
/* Handlers for the SMI state machine. */
2008-04-29 12:01:10 +04:00
struct si_sm_handlers {
/*
* Put the version number of the state machine here so the
* upper layer can print it .
*/
2005-04-17 02:20:36 +04:00
char * version ;
2008-04-29 12:01:10 +04:00
/*
* Initialize the data and return the amount of I / O space to
* reserve for the space .
*/
2005-04-17 02:20:36 +04:00
unsigned int ( * init_data ) ( struct si_sm_data * smi ,
struct si_sm_io * io ) ;
2008-04-29 12:01:10 +04:00
/*
* Start a new transaction in the state machine . This will
* return - 2 if the state machine is not idle , - 1 if the size
* is invalid ( to large or too small ) , or 0 if the transaction
* is successfully completed .
*/
2005-04-17 02:20:36 +04:00
int ( * start_transaction ) ( struct si_sm_data * smi ,
unsigned char * data , unsigned int size ) ;
2008-04-29 12:01:10 +04:00
/*
* Return the results after the transaction . This will return
* - 1 if the buffer is too small , zero if no transaction is
* present , or the actual length of the result data .
*/
2005-04-17 02:20:36 +04:00
int ( * get_result ) ( struct si_sm_data * smi ,
unsigned char * data , unsigned int length ) ;
2008-04-29 12:01:10 +04:00
/*
* Call this periodically ( for a polled interface ) or upon
* receiving an interrupt ( for a interrupt - driven interface ) .
* If interrupt driven , you should probably poll this
* periodically when not in idle state . This should be called
* with the time that passed since the last call , if it is
* significant . Time is in microseconds .
*/
2005-04-17 02:20:36 +04:00
enum si_sm_result ( * event ) ( struct si_sm_data * smi , long time ) ;
2008-04-29 12:01:10 +04:00
/*
* Attempt to detect an SMI . Returns 0 on success or nonzero
* on failure .
*/
2005-04-17 02:20:36 +04:00
int ( * detect ) ( struct si_sm_data * smi ) ;
/* The interface is shutting down, so clean it up. */
void ( * cleanup ) ( struct si_sm_data * smi ) ;
/* Return the size of the SMI structure in bytes. */
int ( * size ) ( void ) ;
} ;
/* Current state machines that we can use. */
2015-06-13 18:34:25 +03:00
extern const struct si_sm_handlers kcs_smi_handlers ;
extern const struct si_sm_handlers smic_smi_handlers ;
extern const struct si_sm_handlers bt_smi_handlers ;
2005-04-17 02:20:36 +04:00