/********************************************************** NDIS5.X handler of power management ***********************************************************/ NDIS_STATUS ParaNdis_OnSetPower(PARANDIS_ADAPTER *pContext, tOidDesc *pOid) { NDIS_STATUS status; NDIS_DEVICE_POWER_STATE newState; DEBUG_ENTRY(0); status = ParaNdis_OidSetCopy(pOid, &newState, sizeof(newState)); if (status == NDIS_STATUS_SUCCESS) { tPowerWorkItem *pwi = ParaNdis_AllocateMemory(pContext, sizeof(tPowerWorkItem)); status = NDIS_STATUS_FAILURE; if (pwi) { pwi->pContext = pContext; pwi->state = newState; NdisInitializeWorkItem(&pwi->wi, OnSetPowerWorkItem, pwi); if (NdisScheduleWorkItem(&pwi->wi) == NDIS_STATUS_SUCCESS) { status = NDIS_STATUS_PENDING; } else NdisFreeMemory(pwi, 0, 0); } } return status; }
void mp8711init(_adapter *padapter) { struct mp_priv *pmppriv=&padapter->mppriv; // MP8711 WorkItem struct mp_wi_cntx *pmp_wi_cntx = &(pmppriv->wi_cntx); pmp_wi_cntx->bmpdrv_unload =_FALSE; pmp_wi_cntx->bmp_wi_progress=_FALSE; pmp_wi_cntx->curractfunc=NULL; NdisInitializeEvent(&(pmp_wi_cntx->mp_wi_evt)); NdisAllocateSpinLock(&(pmp_wi_cntx->mp_wi_lock)); NdisInitializeWorkItem(&(pmp_wi_cntx->mp_wi), mp_wi_callback,// MP8711WorkItemCallback, padapter); // H2C/C2H // padapter->nH2cCmdCnt = 0 ; // NdisAllocateSpinLock(&(pAdapter->MpH2cSpinLock)); // NdisInitializeEvent(&(pAdapter->CMDCommEvent)); //New Arch. init_mp_priv(&padapter->mppriv); }
/************************************************************* Required NDIS procedure Called when some procedure (like OID handler) returns PENDING and does not complete or when CheckForHang return TRUE *************************************************************/ static NDIS_STATUS ParaNdis5_Reset( OUT PBOOLEAN AddressingReset, IN NDIS_HANDLE MiniportAdapterContext) { NDIS_STATUS status; tGeneralWorkItem *pwi; PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportAdapterContext; DEBUG_ENTRY(0); ParaNdis_DebugHistory(pContext, hopSysReset, NULL, 1, 0, 0); status = NDIS_STATUS_FAILURE; pwi = ParaNdis_AllocateMemory(pContext, sizeof(tGeneralWorkItem)); if (pwi) { pwi->pContext = pContext; NdisInitializeWorkItem(&pwi->wi, OnResetWorkItem, pwi); if (NdisScheduleWorkItem(&pwi->wi) == NDIS_STATUS_SUCCESS) { status = NDIS_STATUS_PENDING; } else { NdisFreeMemory(pwi, 0, 0); } } if (status != NDIS_STATUS_PENDING) { ParaNdis_DebugHistory(pContext, hopSysReset, NULL, 0, status, 0); } return status; }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtWorkItemSchedule -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. // DtStatus DtWorkItemSchedule(DtWorkItem* pWorkItem, DtWorkItemArgs* pArgs) { DtStatus Result = DT_STATUS_OK; Int OldState; Bool DoRun = FALSE; Bool DoQueue = FALSE; DtWorkItemStruct WorkItemStruct; DT_ASSERT(pWorkItem->m_SchedulingEnabled); // Allocate workitem Result = DtWorkItemStructCreate(&WorkItemStruct, pWorkItem->m_pDevice); if (!DT_SUCCESS(Result)) return Result; // Try to set running from idle state OldState = DtAtomicCompareExchange((Int*)&pWorkItem->m_State, 0, WI_STATE_BIT_RUNNING); if (OldState == 0) // Successfully running DoRun = TRUE; else if (pWorkItem->m_QueueIfRunning) { // Try to set Queuing OldState = DtAtomicCompareExchange((Int*)&pWorkItem->m_State, WI_STATE_BIT_RUNNING, WI_STATE_BIT_RUNNING|WI_STATE_BIT_QUEUING); if (OldState == WI_STATE_BIT_RUNNING) // Successfully set to queuing DoQueue = TRUE; // Not running anymore? // Try to set running again to be sure a full execution of the worker is pending // after the call the DtDpcSchedule... else if ((OldState&WI_STATE_BIT_RUNNING) == 0) { // Retry to set running from idle state OldState = DtAtomicCompareExchange((Int*)&pWorkItem->m_State, 0, WI_STATE_BIT_RUNNING); if (OldState == 0) // Successfully set to running DoRun = TRUE; else Result = DT_STATUS_IN_USE; } else Result = DT_STATUS_IN_USE; } if (!DT_SUCCESS(Result)) { // Delete workitem DtWorkItemStructDelete(&WorkItemStruct); return Result; } // Queue WorkItem? if (DoQueue) { // Copy arguments pWorkItem->m_QueuedArgs = *pArgs; // Set to queued (running|queuing|queued) OldState = DtAtomicCompareExchange((Int*)&pWorkItem->m_State, WI_STATE_BIT_RUNNING|WI_STATE_BIT_QUEUING, WI_STATE_BIT_RUNNING|WI_STATE_BIT_QUEUING|WI_STATE_BIT_QUEUED); // Check if we failed because we were not running anymore if (OldState == WI_STATE_BIT_QUEUING) { // Choose running slot --> try to set from queuing to running instead of // queued OldState = DtAtomicCompareExchange((Int*)&pWorkItem->m_State, WI_STATE_BIT_QUEUING, WI_STATE_BIT_RUNNING); if (OldState == WI_STATE_BIT_QUEUING) DoRun = TRUE; else { Result = DT_STATUS_IN_USE; // Can not happen? DT_ASSERT(FALSE); } } } // Start initial WorkItem? if (DoRun) { pWorkItem->m_Args = *pArgs; DtWorkItemStructCopy(&pWorkItem->m_WorkStruct, &WorkItemStruct); #ifdef WINBUILD #ifdef USES_NDIS NdisInitializeWorkItem(&pWorkItem->m_WorkStruct.m_NdisWorkItem, DtWorkItemWorker, pWorkItem); NdisScheduleWorkItem(&pWorkItem->m_WorkStruct.m_NdisWorkItem); #else IoQueueWorkItem(pWorkItem->m_WorkStruct.m_pIoWorkItem, DtWorkItemWorker, DelayedWorkQueue, pWorkItem); #endif // USES_NDIS #else #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) // INIT_WORK has been redefined in kernel version 2.6.20 (no 3rd context parameter) INIT_WORK(&pWorkItem->m_WorkStruct.m_Work, DtWorkItemWorker); #else INIT_WORK(&pWorkItem->m_WorkStruct.m_Work, DtWorkItemWorker, pWorkItem); #endif schedule_work(&pWorkItem->m_WorkStruct.m_Work); #endif // Running flag is already set... } else // We do not need the WorkItemStruct. DtWorkItemStructDelete(&WorkItemStruct); return Result; }