byte SI_CbusHandler ( byte channel )
{
	byte result = STATUS_SUCCESS;

	/* Check the channel interrupt status to see if anybody is  */
	/* talking to us. If they are, talk back.                   */

	result = CBusCheckInterruptStatus( channel );

	/* Don't bother with the rest if the heart is gone. */

	if ( (result == ERROR_NO_HEARTBEAT) || (result == ERROR_NACK_FROM_PEER) )
	{
		printk("SI_CbusHandler:: CBusCheckInterruptStatus returned -->> %02X\n", (int)result);
		return( result );
	}

	/* Update the channel state machine as necessary.   */

	switch ( l_cbus[ channel].state )
	{
		case CBUS_IDLE:
			result = CBusConmmandGetNextInQueue( channel );
			break;

		case CBUS_SENT:
			break;

		case CBUS_XFR_DONE:
			l_cbus[ channel].state      = CBUS_IDLE;

			/* We may be waiting for a response message, but the    */
			/* request queue is idle.                               */
			l_cbus[ channel].request[ l_cbus[channel].activeIndex].reqStatus = CBUS_REQ_IDLE;
			break;

		case CBUS_WAIT_RESPONSE:
			break;

		case CBUS_RECEIVED:
			// printk(MSG_ALWAYS, ("SI_CbusHandler:: l_cbus[ channel].state -->> %02X\n", (int)(l_cbus[ channel].state));
			// printk(MSG_ALWAYS, ("result -->> %02X\n", (int)(result));

			/* Either command or response data has been received.   */

			break;

		default:
			/* Not a valid state, reset to IDLE and get out with failure. */

			l_cbus[ channel].state = CBUS_IDLE;
			result = ERROR_INVALID;
			break;
	}

	return( result );
}
uint8_t SiiMhlRxIntrHandler ()
{
    uint8_t result = SUCCESS;
    bool_t retrycheck = false;
    /* Check the channel interrupt status to see if anybody is  */
    /* talking to us. If they are, talk back.                   */
    result = CBusCheckInterruptStatus();

    /* Don't bother with the rest if the heart is gone. */
    if ( result != SUCCESS )
    {
        if (result & ERROR_CBUS_ABORT)
        {
            //Set abort timer
#if defined(__KERNEL__)
            SiiCbusAbortTimerStart();
#else
            pCbus->chState.abortTimer = SiiTimerTotalElapsed();
#endif
            SiiCbusAbortStateSet(true);
            pCbus->chState.state = CBUS_IDLE;
            SiiMhlRxSetQueueEmpty();
        }
        else if (result & ERROR_CBUS_ABORT_OTHER)
        {
            //send MSC error cannot retry
            if (pCbus->chState.state == CBUS_SENT)
            {
                pCbus->chState.state = CBUS_IDLE;
                pCbus->chState.request[ CH_ACTIVE_INDEX ].reqStatus = CBUS_REQ_IDLE;
            }
        }
        else if (result & (ERROR_CBUS_TIMEOUT | ERROR_NACK_FROM_PEER))
        {
            //send MSC error, retry if possible
            if (pCbus->chState.state == CBUS_SENT)
            {
                retrycheck = true;
            }
        }
    }

    // If there's some in the burst queue, send it out
    CBusBurstNextInQueue();

    // Check if there's any cbus message arrived
    if (pCbus->chState.receive.arrived)
    {
        SiiMhlRxRcpRapRcvdNtfy(pCbus->chState.receive.command, pCbus->chState.receive.offsetData);
        pCbus->chState.receive.arrived = false;
    }

    /* Update the channel state machine as necessary.   */
    if ( pCbus->chState.state == CBUS_XFR_DONE )
    {
        pCbus->chState.state = CBUS_IDLE;

        /* We may be waiting for a response message, but the    */
        /* request queue is idle.                               */
        if ( pCbus->chState.request[ CH_ACTIVE_INDEX ].command == MHL_READ_DEVCAP )
        {
            DEBUG_PRINT( MSG_DBG, "Response data Received, %02X\n", pCbus->chState.request[ CH_ACTIVE_INDEX ].retData[0] );
            if (pCbus->chState.request[ CH_ACTIVE_INDEX ].offsetData < 15)
                SiiMhlRxReadDevCapReg(pCbus->chState.request[ CH_ACTIVE_INDEX ].offsetData+1);
            else
                pCbus->chState.dcap_ongoing = false;
            pCbus->chState.remote_dcap[pCbus->chState.request[ CH_ACTIVE_INDEX ].offsetData] = pCbus->chState.request[ CH_ACTIVE_INDEX ].retData[0];
        }
        if ( (pCbus->chState.request[ CH_ACTIVE_INDEX ].command == MHL_MSC_MSG )
            && ((pCbus->chState.request[ CH_ACTIVE_INDEX ].msgData[0] == MHL_MSC_MSG_RCPE) ||
            (pCbus->chState.request[ CH_ACTIVE_INDEX ].msgData[0] == MHL_MSC_MSG_UCPE)))
        {
            //Add a little delay after sending RCPE/UCPE
            HalTimerWait(20);
        }
        pCbus->chState.request[ CH_ACTIVE_INDEX ].reqStatus = CBUS_REQ_IDLE;
        CH_ACTIVE_INDEX = (CH_ACTIVE_INDEX + 1)% CBUS_MAX_COMMAND_QUEUE;
    }
#if 0
    if (pCbus->chState.state == CBUS_SENT)
    {
        //From spec need Wait for TCMD_RECEIVER_TIMEOUT, at least 320ms
        if (pCbus->chState.request[ CH_ACTIVE_INDEX ].reqStatus == CBUS_REQ_SENT)
        {
            if (SiiTimerTotalElapsed() - pCbus->chState.request[ CH_ACTIVE_INDEX ].reqTimer > CBUS_CMD_TIMEOUT)
            {
                //should never be here, when this timeout occured, there should be abort interrupt firstly.
                retrycheck = true;
            }
        }
        else
        {
            //should never be here
            pCbus->chState.state = CBUS_IDLE;
            result = ERROR_INVALID;
            return result;
        }
    }
#endif

    if (retrycheck)
    {
        pCbus->chState.state = CBUS_IDLE;
        if (pCbus->chState.request[ CH_ACTIVE_INDEX ].retry)
        {
            pCbus->chState.request[ CH_ACTIVE_INDEX ].reqStatus = CBUS_REQ_PENDING;
            pCbus->chState.request[ CH_ACTIVE_INDEX ].retry--;
        }
        else
        {
            // retry failed, skip the current index, and move on. 
            pCbus->chState.request[ CH_ACTIVE_INDEX ].reqStatus = CBUS_REQ_IDLE;
            CH_ACTIVE_INDEX = (CH_ACTIVE_INDEX + 1)% CBUS_MAX_COMMAND_QUEUE;
        }
    }

    if (pCbus->chState.state == CBUS_IDLE)
    {
        result = CBusSendNextInQueue();     // No command in progress, write new command immediately.
    }

    return( result );
}