@ -70,23 +70,6 @@ struct ssi_sd_state {
# define TYPE_SSI_SD "ssi-sd"
OBJECT_DECLARE_SIMPLE_TYPE ( ssi_sd_state , SSI_SD )
/* State word bits. */
# define SSI_SDR_LOCKED 0x0001
# define SSI_SDR_WP_ERASE 0x0002
# define SSI_SDR_ERROR 0x0004
# define SSI_SDR_CC_ERROR 0x0008
# define SSI_SDR_ECC_FAILED 0x0010
# define SSI_SDR_WP_VIOLATION 0x0020
# define SSI_SDR_ERASE_PARAM 0x0040
# define SSI_SDR_OUT_OF_RANGE 0x0080
# define SSI_SDR_IDLE 0x0100
# define SSI_SDR_ERASE_RESET 0x0200
# define SSI_SDR_ILLEGAL_COMMAND 0x0400
# define SSI_SDR_COM_CRC_ERROR 0x0800
# define SSI_SDR_ERASE_SEQ_ERROR 0x1000
# define SSI_SDR_ADDRESS_ERROR 0x2000
# define SSI_SDR_PARAMETER_ERROR 0x4000
/* multiple block write */
# define SSI_TOKEN_MULTI_WRITE 0xfc
/* terminate multiple block write */
@ -104,7 +87,7 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val)
{
ssi_sd_state * s = SSI_SD ( dev ) ;
SDRequest request ;
uint8_t longresp [ 16 ] ;
uint8_t longresp [ 5 ] ;
/*
* Special case : allow CMD12 ( STOP TRANSMISSION ) while reading data .
@ -171,74 +154,18 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val)
/* FIXME: Check CRC. */
request . cmd = s - > cmd ;
request . arg = ldl_be_p ( s - > cmdarg ) ;
DPRINTF ( " CMD%d arg 0x%08x \n " , s - > cmd , request . arg ) ;
s - > arglen = sdbus_do_command ( & s - > sdbus , & request ,
longresp , sizeof ( longresp ) ) ;
if ( s - > arglen = = 0 ) {
s - > arglen = 1 ;
s - > response [ 0 ] = 4 ;
DPRINTF ( " SD command failed \n " ) ;
} else if ( s - > cmd = = 8 | | s - > cmd = = 58 ) {
/* CMD8/CMD58 returns R3/R7 response */
DPRINTF ( " Returned R3/R7 \n " ) ;
s - > arglen = 5 ;
s - > response [ 0 ] = 1 ;
memcpy ( & s - > response [ 1 ] , longresp , 4 ) ;
} else if ( s - > arglen ! = 4 ) {
BADF ( " Unexpected response to cmd %d \n " , s - > cmd ) ;
/* Illegal command is about as near as we can get. */
s - > arglen = 1 ;
s - > response [ 0 ] = 4 ;
} else {
/* All other commands return status. */
uint32_t cardstatus ;
uint16_t status ;
DPRINTF ( " CMD%d arg 0x%08x = %d \n " , s - > cmd , request . arg , s - > arglen ) ;
assert ( s - > arglen > 0 ) ;
/* CMD13 returns a 2-byte statuse work. Other commands
only return the first byte . */
s - > arglen = ( s - > cmd = = 13 ) ? 2 : 1 ;
memcpy ( s - > response , longresp , s - > arglen ) ;
/* handle R1b */
if ( s - > cmd = = 28 | | s - > cmd = = 29 | | s - > cmd = = 38 ) {
s - > stopping = 1 ;
}
cardstatus = ldl_be_p ( longresp ) ;
status = 0 ;
if ( ( ( cardstatus > > 9 ) & 0xf ) < 4 )
status | = SSI_SDR_IDLE ;
if ( cardstatus & ERASE_RESET )
status | = SSI_SDR_ERASE_RESET ;
if ( cardstatus & ILLEGAL_COMMAND )
status | = SSI_SDR_ILLEGAL_COMMAND ;
if ( cardstatus & COM_CRC_ERROR )
status | = SSI_SDR_COM_CRC_ERROR ;
if ( cardstatus & ERASE_SEQ_ERROR )
status | = SSI_SDR_ERASE_SEQ_ERROR ;
if ( cardstatus & ADDRESS_ERROR )
status | = SSI_SDR_ADDRESS_ERROR ;
if ( cardstatus & CARD_IS_LOCKED )
status | = SSI_SDR_LOCKED ;
if ( cardstatus & ( LOCK_UNLOCK_FAILED | WP_ERASE_SKIP ) )
status | = SSI_SDR_WP_ERASE ;
if ( cardstatus & SD_ERROR )
status | = SSI_SDR_ERROR ;
if ( cardstatus & CC_ERROR )
status | = SSI_SDR_CC_ERROR ;
if ( cardstatus & CARD_ECC_FAILED )
status | = SSI_SDR_ECC_FAILED ;
if ( cardstatus & WP_VIOLATION )
status | = SSI_SDR_WP_VIOLATION ;
if ( cardstatus & ERASE_PARAM )
status | = SSI_SDR_ERASE_PARAM ;
if ( cardstatus & ( OUT_OF_RANGE | CID_CSD_OVERWRITE ) )
status | = SSI_SDR_OUT_OF_RANGE ;
/* ??? Don't know what Parameter Error really means, so
assume it ' s set if the second byte is nonzero . */
if ( status & 0xff )
status | = SSI_SDR_PARAMETER_ERROR ;
s - > response [ 0 ] = status > > 8 ;
s - > response [ 1 ] = status ;
DPRINTF ( " Card status 0x%02x \n " , status ) ;
/* handle R1b (busy signal) */
if ( s - > cmd = = 28 | | s - > cmd = = 29 | | s - > cmd = = 38 ) {
s - > stopping = 1 ;
}
s - > mode = SSI_SD_PREP_RESP ;
s - > response_pos = 0 ;