VOID LsuDecrementTdiClientInProgress() { KIRQL oldIrql; ACQUIRE_SPIN_LOCK(&TDICLIENT_CONTEXT.TdiPnPSpinLock, &oldIrql); TDICLIENT_CONTEXT.ClientInProgressIOCount--; ASSERT(TDICLIENT_CONTEXT.ClientInProgressIOCount >= 0); LsuCurrentTime(&TDICLIENT_CONTEXT.LastOperationTime); RELEASE_SPIN_LOCK(&TDICLIENT_CONTEXT.TdiPnPSpinLock, oldIrql); }
VOID LsuDecrementTdiClientInProgress() { KIRQL oldIrql; ACQUIRE_SPIN_LOCK(&TdiPnPSpinLock, &oldIrql); ClientInProgress--; ASSERT(ClientInProgress >= 0); LsuCurrentTime(&LastOperationTime); RELEASE_SPIN_LOCK(&TdiPnPSpinLock, oldIrql); }
NTSTATUS LsuClientPnPPowerChange( IN PUNICODE_STRING DeviceName, IN PNET_PNP_EVENT PowerEvent, IN PTDI_PNP_CONTEXT Context1, IN PTDI_PNP_CONTEXT Context2 ){ NTSTATUS status; UNICODE_STRING lpxPrefix; NET_DEVICE_POWER_STATE powerState; UNREFERENCED_PARAMETER(Context1); UNREFERENCED_PARAMETER(Context2); if (DeviceName==NULL) { KDPrintM(DBG_OTHER_ERROR, ( "NO DEVICE NAME SUPPLIED when power event of type %x.\n", PowerEvent->NetEvent)); return STATUS_SUCCESS; } if(PowerEvent == NULL) { return STATUS_SUCCESS; } if(PowerEvent->Buffer == NULL || PowerEvent->BufferLength == 0) { powerState = NetDeviceStateUnspecified; } else { powerState = *((PNET_DEVICE_POWER_STATE) PowerEvent->Buffer); } #if DBG if(DeviceName->Buffer) { KDPrintM(DBG_OTHER_ERROR, ("DeviceName=%ws PowerEvent=%x BufferLen=%u PowerStat=%x\n", DeviceName->Buffer, PowerEvent->NetEvent, PowerEvent->BufferLength, powerState)); } else { KDPrintM(DBG_OTHER_ERROR, ("DeviceName=NULL PowerEvent=%x BufferLen=%u PowerStat=%x\n", PowerEvent->NetEvent, PowerEvent->BufferLength, powerState)); } #endif // // We support LPX for now. // We need to support TCP/IP for the future. // RtlInitUnicodeString(&lpxPrefix, LPX_BOUND_DEVICE_NAME_PREFIX); if( DeviceName == NULL || RtlPrefixUnicodeString(&lpxPrefix, DeviceName, TRUE) == FALSE) { KDPrintM(DBG_OTHER_ERROR, ( "Not LPX binding device.\n")); return STATUS_SUCCESS; } status = STATUS_SUCCESS; switch(PowerEvent->NetEvent) { case NetEventSetPower: KDPrintM(DBG_OTHER_INFO, ("SetPower\n")); #if 0 if(powerState != NetDeviceStateD0) { LARGE_INTEGER interval; LONG loopCnt; KIRQL oldIrql; // // Delay power event if Clients' operations are in progress. // KDPrintM(DBG_OTHER_INFO, ("Start holding power down\n")); interval.QuadPart = - NANO100_PER_SEC; loopCnt = 0; while(TRUE) { ACQUIRE_SPIN_LOCK(&TDICLIENT_CONTEXT.TdiPnPSpinLock, &oldIrql); // // If 5 seconds passes after last operation, exit. // if(TDICLIENT_CONTEXT.ClientInProgressIOCount == 0) { LARGE_INTEGER currentTime; LsuCurrentTime(¤tTime); if(currentTime.QuadPart - TDICLIENT_CONTEXT.LastOperationTime.QuadPart > LSTRANS_LPX_POWERDOWN_TIMEOUT) { RELEASE_SPIN_LOCK(&TDICLIENT_CONTEXT.TdiPnPSpinLock, oldIrql); break; } } RELEASE_SPIN_LOCK(&TDICLIENT_CONTEXT.TdiPnPSpinLock, oldIrql); KeDelayExecutionThread(KernelMode, FALSE, &interval); loopCnt ++; if(loopCnt >= TDIPNPCLIENT_MAX_HOLDING_LOOP) { KDPrintM(DBG_OTHER_ERROR, ("Too long holding.\n")); break; } KDPrintM(DBG_OTHER_INFO, ("Loop count:%u\n", loopCnt)); } // // Hold power down by returning PENDING. // KDPrintM(DBG_OTHER_INFO, ("Finished holding power down\n")); } #endif break; case NetEventQueryPower: KDPrintM(DBG_OTHER_INFO, ("NetEventQueryPower\n")); break; case NetEventQueryRemoveDevice: KDPrintM(DBG_OTHER_INFO, ("NetEventQueryRemoveDevice\n")); break; case NetEventCancelRemoveDevice: KDPrintM(DBG_OTHER_INFO, ("NetEventCancelRemoveDevice\n")); break; case NetEventReconfigure: KDPrintM(DBG_OTHER_INFO, ("NetEventReconfigure\n")); break; case NetEventBindList: KDPrintM(DBG_OTHER_INFO, ("NetEventBindList\n")); break; case NetEventBindsComplete: KDPrintM(DBG_OTHER_INFO, ("NetEventBindsComplete\n")); break; case NetEventPnPCapabilities: KDPrintM(DBG_OTHER_INFO, ("NetEventPnPCapabilities\n")); break; default: KDPrintM(DBG_OTHER_ERROR, ("Unknown PnP code. %x\n", PowerEvent->NetEvent)); } return status; }