/* ======================================================================== Routine Description: MLME kernel thread. Arguments: *Context the pAd, driver control block pointer Return Value: 0 close the thread Note: ======================================================================== */ INT MlmeThread( IN ULONG Context) { RTMP_ADAPTER *pAd; RTMP_OS_TASK *pTask; int status; status = 0; pTask = (RTMP_OS_TASK *)Context; pAd = (PRTMP_ADAPTER)pTask->priv; RtmpOSTaskCustomize(pTask); while(!pTask->task_killed) { #ifdef KTHREAD_SUPPORT RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); #else RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); /* unlock the device pointers */ if (status != 0) { RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); break; } #endif /* lock the device pointers , need to check if required*/ //down(&(pAd->usbdev_semaphore)); if (!pAd->PM_FlgSuspend) MlmeHandler(pAd); } /* notify the exit routine that we're actually exiting now * * complete()/wait_for_completion() is similar to up()/down(), * except that complete() is safe in the case where the structure * is getting deleted in a parallel mode of execution (i.e. just * after the down() -- that's necessary for the thread-shutdown * case. * * complete_and_exit() goes even further than this -- it is safe in * the case that the thread of the caller is going away (not just * the structure) -- this is necessary for the module-remove case. * This is important in preemption kernels, which transfer the flow * of execution immediately upon a complete(). */ DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__)); #ifndef KTHREAD_SUPPORT pTask->taskPID = THREAD_PID_INIT_VALUE; complete_and_exit (&pTask->taskComplete, 0); #endif return 0; }
static void RtmpTimerQHandle(RTMP_ADAPTER *pAd) { #ifndef KTHREAD_SUPPORT int status; #endif RALINK_TIMER_STRUCT *pTimer; RTMP_TIMER_TASK_ENTRY *pEntry; unsigned long irqFlag; RTMP_OS_TASK *pTask; pTask = &pAd->timerTask; while(!pTask->task_killed) { pTimer = NULL; #ifdef KTHREAD_SUPPORT RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); #else RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); #endif if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED) break; // event happened. while(pAd->TimerQ.pQHead) { RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag); pEntry = pAd->TimerQ.pQHead; if (pEntry) { pTimer = pEntry->pRaTimer; // update pQHead pAd->TimerQ.pQHead = pEntry->pNext; if (pEntry == pAd->TimerQ.pQTail) pAd->TimerQ.pQTail = NULL; // return this queue entry to timerQFreeList. pEntry->pNext = pAd->TimerQ.pQPollFreeList; pAd->TimerQ.pQPollFreeList = pEntry; } RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag); if (pTimer) { if ((pTimer->handle != NULL) && (!pAd->PM_FlgSuspend)) pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer); if ((pTimer->Repeat) && (pTimer->State == FALSE)) RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue); } } #ifndef KTHREAD_SUPPORT if (status != 0) { pAd->TimerQ.status = RTMP_TASK_STAT_STOPED; RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); break; } #endif } }
/* ======================================================================== Routine Description: USB command kernel thread. Arguments: *Context the pAd, driver control block pointer Return Value: 0 close the thread Note: ======================================================================== */ INT RTUSBCmdThread( IN ULONG Context) { RTMP_ADAPTER *pAd; RTMP_OS_TASK *pTask; int status; status = 0; pTask = (RTMP_OS_TASK *)Context; pAd = (PRTMP_ADAPTER)pTask->priv; RtmpOSTaskCustomize(pTask); NdisAcquireSpinLock(&pAd->CmdQLock); pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING; NdisReleaseSpinLock(&pAd->CmdQLock); while (pAd && pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING) { #ifdef KTHREAD_SUPPORT RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); #else /* lock the device pointers */ RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); if (status != 0) { RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); break; } #endif if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED) break; if (!pAd->PM_FlgSuspend) CMDHandler(pAd); } if (pAd && !pAd->PM_FlgSuspend) { // Clear the CmdQElements. CmdQElmt *pCmdQElmt = NULL; NdisAcquireSpinLock(&pAd->CmdQLock); pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED; while(pAd->CmdQ.size) { RTThreadDequeueCmd(&pAd->CmdQ, &pCmdQElmt); if (pCmdQElmt) { if (pCmdQElmt->CmdFromNdis == TRUE) { if (pCmdQElmt->buffer != NULL) os_free_mem(pAd, pCmdQElmt->buffer); os_free_mem(pAd, (PUCHAR)pCmdQElmt); } else { if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0)) os_free_mem(pAd, pCmdQElmt->buffer); os_free_mem(pAd, (PUCHAR)pCmdQElmt); } } } NdisReleaseSpinLock(&pAd->CmdQLock); } /* notify the exit routine that we're actually exiting now * * complete()/wait_for_completion() is similar to up()/down(), * except that complete() is safe in the case where the structure * is getting deleted in a parallel mode of execution (i.e. just * after the down() -- that's necessary for the thread-shutdown * case. * * complete_and_exit() goes even further than this -- it is safe in * the case that the thread of the caller is going away (not just * the structure) -- this is necessary for the module-remove case. * This is important in preemption kernels, which transfer the flow * of execution immediately upon a complete(). */ DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n")); #ifndef KTHREAD_SUPPORT pTask->taskPID = THREAD_PID_INIT_VALUE; complete_and_exit (&pTask->taskComplete, 0); #endif return 0; }