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 ); }