summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZane Shelley <zshelle@us.ibm.com>2015-05-18 13:46:12 -0500
committerGuillermo J. Silva <guilsilv@us.ibm.com>2015-05-21 10:22:02 -0500
commit05393b27b991a0b1f1ed023a8c50bf79f26ed8bc (patch)
treef38ea3102e5059d35507d622423ea7be10dfc9b6
parentfc589ce298575115823d716951b3171aa028f2d1 (diff)
downloadtalos-occ-05393b27b991a0b1f1ed023a8c50bf79f26ed8bc.tar.gz
talos-occ-05393b27b991a0b1f1ed023a8c50bf79f26ed8bc.zip
Error path handling of getfsi/putfsi
Change-Id: If806612b72ec1e8ee0260f1d3ea28022e8c96258 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/17841 Reviewed-by: Guillermo J. Silva <guilsilv@us.ibm.com> Tested-by: Guillermo J. Silva <guilsilv@us.ibm.com>
-rw-r--r--src/occ/firdata/fsi.c72
-rw-r--r--src/occ/firdata/fsi.h24
-rw-r--r--src/occ/firdata/scom_util.c48
3 files changed, 71 insertions, 73 deletions
diff --git a/src/occ/firdata/fsi.c b/src/occ/firdata/fsi.c
index 92c85fc..4235677 100644
--- a/src/occ/firdata/fsi.c
+++ b/src/occ/firdata/fsi.c
@@ -37,98 +37,96 @@
/**
* @brief Poll for completion of a FSI operation, return data on read
*/
-uint32_t poll_for_complete( void )
+int32_t poll_for_complete( uint32_t * o_val )
{
int32_t rc = SUCCESS;
enum { MAX_OPB_TIMEOUT_NS = 10*NS_PER_MSEC }; /*=10ms */
- /* poll for complete */
- uint64_t read_data = FSIFAIL;
+ *o_val = 0;
+
+ uint64_t read_data = 0;
uint64_t elapsed_time_ns = 0;
do
{
rc = xscom_read( OPB_REG_STAT, &read_data );
if ( SUCCESS != rc )
{
- return FSIFAIL;
+ return rc;
}
- /* check for completion or xscom error */
- /* note: not checking for FSI errors */
- if ( (read_data & OPB_STAT_BUSY) == 0 ) /*not busy */
- {
- break;
- }
- else
- {
- read_data = FSIFAIL;
- }
+ /* Check for completion. Note: not checking for FSI errors. */
+ if ( (read_data & OPB_STAT_BUSY) == 0 ) break; /* Not busy */
- sleep( 10000 ); /*sleep for 10,000 ns */
+ sleep( 10000 ); /* sleep for 10,000 ns */
elapsed_time_ns += 10000;
- } while( elapsed_time_ns <= MAX_OPB_TIMEOUT_NS );
- return (uint32_t)read_data; /*data in the bottom half */
+ } while ( elapsed_time_ns <= MAX_OPB_TIMEOUT_NS );
+
+ if ( MAX_OPB_TIMEOUT_NS < elapsed_time_ns )
+ {
+ TRAC_ERR( "[poll_for_complete] FSI request timed out." );
+ return FAIL;
+ }
+
+ *o_val = (uint32_t)read_data; /* Data in the bottom half. */
+
+ return rc;
}
/**
* @brief Read a FSI register
*/
-uint32_t getfsi( SCOM_Trgt_t i_target, uint32_t i_address )
+int32_t getfsi( SCOM_Trgt_t i_trgt, uint32_t i_addr, uint32_t * o_val )
{
int32_t rc = SUCCESS;
- uint32_t fsi_base = i_target.fsiBaseAddr;
- uint32_t fsi_addr = fsi_base | i_address;
+ uint32_t fsi_addr = i_trgt.fsiBaseAddr | i_addr;
/* setup the OPB command register */
/* only supporting 4-byte access */
- uint64_t fsi_cmd = fsi_addr | 0x60000000; /*011=Read Full Word */
+ uint64_t fsi_cmd = fsi_addr | 0x60000000; /* 011=Read Full Word */
fsi_cmd <<= 32; /* Command is in the upper word of the scom */
/* Write the OPB command register to trigger the read */
rc = xscom_write( OPB_REG_CMD, fsi_cmd );
if ( SUCCESS != rc )
{
- return FSIFAIL;
+ return rc;
}
- /* poll for complete and get the data back */
- uint32_t out_data = poll_for_complete();
+ /* Poll for complete and get the data back. */
+ rc = poll_for_complete( o_val );
- return out_data;
+ return rc;
}
-
/**
* @brief Write a FSI register
*/
-void putfsi( SCOM_Trgt_t i_target,
- uint32_t i_address,
- uint32_t i_data )
+int32_t putfsi( SCOM_Trgt_t i_trgt, uint32_t i_addr, uint32_t i_val )
{
int32_t rc = SUCCESS;
- uint32_t fsi_base = i_target.fsiBaseAddr;
- uint32_t fsi_addr = fsi_base | i_address;
+ uint32_t fsi_addr = i_trgt.fsiBaseAddr | i_addr;
/* setup the OPB command register */
/* only supporting 4-byte access */
uint64_t fsi_cmd = fsi_addr | 0xE0000000; /* 111=Write Full Word */
- fsi_cmd <<= 32; /* Command is in the upper word of the scom */
- fsi_cmd |= i_data; /* Data is in the bottom 32-bits */
+ fsi_cmd <<= 32; /* Command is in the upper word of the scom */
+ fsi_cmd |= i_val; /* Data is in the bottom 32-bits */
/* Write the OPB command register to trigger the read */
rc = xscom_write( OPB_REG_CMD, fsi_cmd );
if ( SUCCESS != rc )
{
- return;
+ return rc;
}
- /* poll for complete */
- poll_for_complete();
+ /* Poll for complete */
+ uint32_t junk = 0; // Not used.
+ rc = poll_for_complete( &junk );
- return;
+ return rc;
}
diff --git a/src/occ/firdata/fsi.h b/src/occ/firdata/fsi.h
index f3e6fab..870e47f 100644
--- a/src/occ/firdata/fsi.h
+++ b/src/occ/firdata/fsi.h
@@ -27,21 +27,21 @@
#include <scom_trgt.h>
-#define FSIFAIL 0xDEADBEEF
-
/**
- * @brief Read a FSI register
- * @param[in] Chip/unit to read from
- * @param[in] FSI address to read, relative to slave's base address
- * @return FSI data on success, FSIFAIL on error
+ * @brief Read a FSI register.
+ * @param i_trgt Chip/unit to read from.
+ * @param i_addr FSI address to read, relative to slave's base address.
+ * @param o_val Returned value.
+ * @return Non-SUCCESS if an internal function fails. SUCCESS otherwise.
*/
-uint32_t getfsi( SCOM_Trgt_t i_target, uint32_t i_address );
+int32_t getfsi( SCOM_Trgt_t i_trgt, uint32_t i_addr, uint32_t * o_val );
/**
- * @brief Write a FSI register
- * @param[in] Chip/unit to write to
- * @param[in] FSI address to write, relative to slave's base address
- * @param[in] Data to write
+ * @brief Write a FSI register.
+ * @param i_trgt Chip/unit to write to.
+ * @param i_addr FSI address to write, relative to slave's base address.
+ * @param o_val Value to write.
+ * @return Non-SUCCESS if an internal function fails. SUCCESS otherwise.
*/
-void putfsi( SCOM_Trgt_t i_target, uint32_t i_address, uint32_t i_data );
+int32_t putfsi( SCOM_Trgt_t i_trgt, uint32_t i_addr, uint32_t i_val );
diff --git a/src/occ/firdata/scom_util.c b/src/occ/firdata/scom_util.c
index 8a29b87..a51ff04 100644
--- a/src/occ/firdata/scom_util.c
+++ b/src/occ/firdata/scom_util.c
@@ -235,7 +235,6 @@ uint32_t translate_scom( SCOM_Trgt_t i_target,
return l_addr;
}
-
/**
* @brief Perform a getscom operation with no address translation
*/
@@ -254,28 +253,26 @@ uint64_t getscomraw( SCOM_Trgt_t i_chip,
return scomdata;
}
- /*1) send the command to do the scom read */
- putfsi( i_chip, COMMAND_REG, i_address );
+ /* 1) Sent the command to do the SCOM read. */
+ rc = putfsi( i_chip, COMMAND_REG, i_address );
+ if ( SUCCESS != rc ) return SCOMFAIL;
+
/*2) check status next -- TODO */
- /*3) read the two data regs */
- uint32_t data = getfsi( i_chip, DATA0_REG );
- if( data == FSIFAIL )
- {
- return SCOMFAIL;
- }
- scomdata = data;
- scomdata <<= 32;
- data = getfsi( i_chip, DATA1_REG );
- if( data == FSIFAIL )
- {
- return SCOMFAIL;
- }
- scomdata |= (uint64_t)data;
+
+ /* 3) Read the two data registers. */
+ uint32_t data0, data1;
+
+ rc = getfsi( i_chip, DATA0_REG, &data0 );
+ if ( SUCCESS != rc ) return SCOMFAIL;
+
+ rc = getfsi( i_chip, DATA1_REG, &data1 );
+ if ( SUCCESS != rc ) return SCOMFAIL;
+
+ scomdata = ((uint64_t)data0 << 32) | (uint64_t)data1;
return scomdata;
}
-
/**
* @brief Perform a scom operation with no address translation
*/
@@ -292,17 +289,20 @@ void putscomraw( SCOM_Trgt_t i_chip,
return; // TODO: Will need to return rc.
}
- /*1) write the two data regs */
- putfsi( i_chip, DATA0_REG, i_data >> 32 );
- putfsi( i_chip, DATA1_REG, (uint32_t)i_data );
+ /* 1) Write the two data registers. */
+ rc = putfsi( i_chip, DATA0_REG, i_data >> 32 );
+ if ( SUCCESS != rc ) return;
+
+ rc = putfsi( i_chip, DATA1_REG, (uint32_t)i_data );
+ if ( SUCCESS != rc ) return;
- /*2) send the command to do the scom write */
- putfsi( i_chip, COMMAND_REG, i_address | 0x80000000 );
+ /* 2) Send the command to do the SCOM write. */
+ rc = putfsi( i_chip, COMMAND_REG, i_address | 0x80000000 );
+ if ( SUCCESS != rc ) return;
/*3) check status next -- TODO */
}
-
/**
* @brief Execute standard getscom and return result
*/
OpenPOWER on IntegriCloud