📄 xpmain.c
字号:
TimeoutDesc* timeoutDesc; XpInQueueDesc* xpInQueueDesc; CellDescriptor* controlDesc; Aal2CpsDesc* aal2ControlDesc; TimerStartData* data; int32u scoreBoard; int16u timerFired; int16u timerIndex; Boolean somethingToBeRead = FALSE; Boolean atLeastOneTimerFired = FALSE; register int32u timer = NUMBER_OF_TIMERS; register int8u* pTimeout8 = &timeout[NUMBER_OF_TIMERS-1]; int32 head = -1; int32 tail = -1; int32u error = 0; int32u all = 0; Boolean allFlag = 1; KsEventId event; ksEventRegisterInterrupt(ksEventIdQmuError, (KsFunc)&xpQmuIrqHandler, (void *)0); /* * Initialise the Queue related Descriptors */ timeoutDesc = (TimeoutDesc *) qsMessageGetData (&timeoutMsg); xpInQueueDesc = (XpInQueueDesc *) qsMessageGetData (&incomingMsg); controlDesc = (CellDescriptor *) qsMessageGetData (&controlMsg); aal2ControlDesc = (Aal2CpsDesc *) qsMessageGetData (&aal2ControlMsg); scoreBoard = XP_SONET_SOAK_TIME - (CU_TIMER_GRANULARITY * SYS_TIMER_TICKS_PER_MILLISEC); while (TRUE) {#if !defined(SIM) ksPrintService ();#endif /* * SONET timer tick event * ---------------------------------------------------------- */ if (BitIsSet(dcpCregs.eventRegister[0], EV0_TIMER_EVENT)) { scoreBoard = XP_SONET_SOAK_TIME; error = 0; all = 0; allFlag = 1; /* * Check and see if any defects have reached their * soak threshold */ sonetMonitorSoakIncrement(); /* * If 500ms timer has expired */ if ((event = ksEventNext()) == ksEventIdTimer) { /* * Reset soak timeout */ ksTimerSet(XP_SONET_SOAK_TIME); } } /* * CU timer tick event * ---------------------------------------------------------- */ if (dcpCregs.eventTimer <= scoreBoard) { /* CU timer tick. Schedule next tick and * update the CU timer related counters. */ scoreBoard -= (CU_TIMER_GRANULARITY * SYS_TIMER_TICKS_PER_MILLISEC); if (timer) { error++; } timer = NUMBER_OF_TIMERS; pTimeout8 = &timeout[NUMBER_OF_TIMERS-1]; allFlag = 1; } /* * Dequeue the timer start command descriptors from AAL2 Tx * CPs */ if (somethingToBeRead) { while(!qsMessageReceiveComplete(XP_BASE_QUEUE, &incomingMsg)); switch (xpInQueueDesc->command) { case TIMER_START_COMMAND: { data = (TimerStartData *) &(xpInQueueDesc->data.timerStartCommand); timerIndex = data->vcIndex; timeout[timerIndex] = (data->cpId << 4) | CU_TIMER_TICKS; next[timerIndex] = SetBitFieldIn(next[timerIndex], data->seqNo, SEQ_NUM); break; } default: break; } somethingToBeRead = FALSE; } else if (qsQueueGetLength(XP_BASE_QUEUE)) { qsMessageReceiveStart(XP_BASE_QUEUE, &incomingMsg); somethingToBeRead = TRUE; } /* Attempt an enqueue only if previous enqueue is completed. * Poll for the Q Write Mailbox for availability. */ if (atLeastOneTimerFired && BitIsSet(dcpCregs.eventRegister[1], EV1_QWR_MBX_AVAIL)) { /* If there is at least one element in the list of fired * timers, enqueue a Timeout message to the CPRC. */ timerFired = head; head = ((head ^ tail) ? (BitField(next[head],NEXT_POINTER)) : (tail = -1)); if (head < 0) atLeastOneTimerFired = FALSE; if (!(timeout[timerFired] & 0x0F)) /* Timeout still valid */ { timeoutDesc->seqNo = BitField(next[timerFired], SEQ_NUM); timeoutDesc->vcIndex = timerFired ; payloadEnqueue = FALSE; qsMessageSend (nqQId[timeout[timerFired] >> 4], &timeoutMsg); } } /* * Timer update */ if (timer) { if (allFlag) { all++; allFlag = 0; } do { int8u timeVal = *pTimeout8 & 0x0F; if (timeVal) { if (!(--timeVal)) { /* A timer has fired. append it to the list * of fired timers. */ if (tail < 0) { /* This is the first element being added * to the empty list. */ head = tail = timer-1; atLeastOneTimerFired = TRUE; } else { int16u* pNext16; pNext16 = &next[tail]; /* Add this element at the tail of the * queue of timers that are timed out */ *pNext16 = SetBitFieldIn(*pNext16, timer - 1, NEXT_POINTER); tail = timer-1; } } (*pTimeout8)--; } pTimeout8--; } while (--timer & 0x0007); } /* * Sonet monitoring */ if (qsQueueGetLength(XP_SONET_MONITOR_QUEUE)) { /* * Jump to SONET monitoring function to monitor any SONET * faults and defects. */ sonetMonitorXpQueue(); } /* * Control messages */ if (qsQueueGetLength(XP_ATM_CONTROL_QUEUE)) { qsMessageReceive(XP_ATM_CONTROL_QUEUE, &controlMsg);#ifdef XP_TEST ++cellNum; ksPrintf ("Aal2 Xp : Control Cell : VcIndex %d : PTI : %d", controlDesc->VcIndex,controlDesc->payloadType) ;#endif /* * For now, send the cells out of ATM TX CP 1 * to allow verification */ lastBufferEnqueued = controlDesc->Bh; payloadEnqueue = TRUE; qsMessageSend(ATM_PORT2_BASE_QUEUE, &controlMsg); } /* * Aal2 Control messages (CIDS from 1 to 7) */ if (qsQueueGetLength(XP_RES_CID_QUEUE)) { qsMessageReceive(XP_RES_CID_QUEUE, &aal2ControlMsg);#ifdef XP_TEST ++cpsNum; ksPrintf ("Xp aal2 %d, cid : %d",cpsNum, aal2ControlDesc->cid);#endif /* * For now, send the cells out through AAL2 Tx CP 10 * to allow verification */ lastBufferEnqueued = aal2ControlDesc->cpsPckPayload; payloadEnqueue = TRUE; qsMessageSend(AAL2_TX1_BASE_QUEUE, &aal2ControlMsg); } }}/* * Function: xpQmuIrqHandler() * * Description: This function is interrupt handler for QMU errors. * It is typically * called under normal congestion conditions * when an enqueue fails * to succeed due to the target queue being full. * When this occurs * this irq handler must free the buffer * associated with the last * enqueue. * * Arguments: An eventInfo block passed in by kernel services. * * Returns: */int32u xpQmuIrqHandler(void *irqInfo){ KsEventInfo *eventInfo = (KsEventInfo *)irqInfo; if(eventInfo->eventId == ksEventIdQmuError) { dcpTrace1(("Queue irq, queue %d", eventInfo->address)); /* Only free the buffer associated with the last enqueue * if the failed enqueue * was a unicast operation with payload information. */ if(payloadEnqueue == TRUE ) { /* Save any context before doing an operation. */ ksEventContextSave(); /* Free the buffer associated with the last enqueue. */ bsBufferFree(lastBufferEnqueued); /* Wait until operation is done and then restore any context. */ while(!bsBufferWriteComplete()); ksEventContextRestore(); payloadEnqueue = FALSE; } } return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -