コード例 #1
0
ファイル: nic_req.c プロジェクト: kcrazy/winekit
VOID
NICFillPoMgmtCaps (
    __in PFDO_DATA                 FdoData,
    __out PNDIS_PNP_CAPABILITIES  pPower_Management_Capabilities,
    __inout PNDIS_STATUS            pStatus,
    __inout PULONG                  pulInfoLen
    )
/*++
Routine Description:

    Fills in the Power  Managment structure depending the capabilities of
    the software driver and the card.

    Currently this is only supported on 82559 Version of the driver

Arguments:

    FdoData                 Pointer to the FdoData structure
    pPower_Management_Capabilities - Power management struct as defined in the DDK,
    pStatus                 Status to be returned by the request,
    pulInfoLen              Length of the pPowerManagmentCapabilites

Return Value:

    Success or failure depending on the type of card
--*/

{

    BOOLEAN bIsPoMgmtSupported;

    bIsPoMgmtSupported = IsPoMgmtSupported(FdoData);

    if (bIsPoMgmtSupported == TRUE)
    {
        pPower_Management_Capabilities->Flags = NDIS_DEVICE_WAKE_UP_ENABLE;
        pPower_Management_Capabilities->WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
        pPower_Management_Capabilities->WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateD3;
        pPower_Management_Capabilities->WakeUpCapabilities.MinLinkChangeWakeUp  = NdisDeviceStateUnspecified;
        *pulInfoLen = sizeof (*pPower_Management_Capabilities);
        *pStatus =  STATUS_SUCCESS;
    }
    else
    {
        RtlZeroMemory (pPower_Management_Capabilities, sizeof(*pPower_Management_Capabilities));
        *pStatus =  STATUS_NOT_SUPPORTED;
        *pulInfoLen = 0;

    }
}
コード例 #2
0
ファイル: nic_pm.c プロジェクト: kcrazy/winekit
VOID
HwSetWakeUpConfigure(
    __in PFDO_DATA FdoData,
    PUCHAR pPoMgmtConfigType,
    UINT WakeUpParameter
    )
{


    if (IsPoMgmtSupported( FdoData) == TRUE)
    {
        (*pPoMgmtConfigType)=  ((*pPoMgmtConfigType)| CB_WAKE_ON_LINK_BYTE9 |CB_WAKE_ON_ARP_PKT_BYTE9  );

    }
}
コード例 #3
0
ファイル: nic_pm.c プロジェクト: uri247/wdk80
VOID
HwSetWakeUpConfigure(
    IN PFDO_DATA FdoData,
    PUCHAR       pPoMgmtConfigType,
    UINT         WakeUpParameter
    )
{
    UNREFERENCED_PARAMETER( WakeUpParameter );

    if (IsPoMgmtSupported( FdoData) == TRUE)
    {
        (*pPoMgmtConfigType)= ((*pPoMgmtConfigType) |
                               CB_WAKE_ON_LINK_BYTE9 |
                               CB_WAKE_ON_ARP_PKT_BYTE9  );
    }
}
コード例 #4
0
ファイル: nic_pm.c プロジェクト: uri247/wdk80
NTSTATUS
NICSetPower(
    PFDO_DATA     FdoData ,
    WDF_POWER_DEVICE_STATE   PowerState
    )
/*++
Routine Description:

    This routine is called when the FdoData receives a SetPower
    request. It redirects the call to an appropriate routine to
    Set the New PowerState

Arguments:

    FdoData                 Pointer to the FdoData structure
    PowerState              NewPowerState

Return Value:

    NTSTATUS Code

--*/
{
    NTSTATUS      status = STATUS_SUCCESS;

    if(IsPoMgmtSupported(FdoData)){

        if (PowerState == PowerDeviceD0)
        {
            TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER, "Entering fully on state\n");
            MPSetPowerD0 (FdoData);
        }
        else
        {
            TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER, "Entering a deeper sleep state\n");
            status = MPSetPowerLow (FdoData, PowerState);
        }
    }

    return status;
}
コード例 #5
0
ファイル: nic_req.c プロジェクト: kcrazy/winekit
NTSTATUS
NICHandleSetOidRequest(
    __in  PFDO_DATA                   FdoData,
    __in  PIRP                       Irp
    )
/*++

Routine Description:

    This routine handles ioctl request for Set OIDs. Most of
    the IOCTL requests are only if the upper edge is NDIS.

Arguments:


Return Value:


--*/
{
    NTSTATUS                status = STATUS_SUCCESS;
    PNDISPROT_SET_OID       pSet;
    NDIS_OID                Oid;
    ULONG                   PacketFilter;
    PVOID                   InformationBuffer = NULL;
    ULONG                   InformationBufferLength = 0;
    KIRQL                   oldIrql;
    PVOID                   DataBuffer;
    ULONG                   BufferLength, unUsed;
    PIO_STACK_LOCATION      pIrpSp;
    DEVICE_POWER_STATE      newDeviceState, oldDeviceState;

    pIrpSp = IoGetCurrentIrpStackLocation(Irp);
    DataBuffer = Irp->AssociatedIrp.SystemBuffer;
    BufferLength = pIrpSp->Parameters.DeviceIoControl.InputBufferLength;

    DebugPrint(LOUD, DBG_IOCTLS, "--> HandleSetOIDRequest\n");

    Oid = 0;

    do
    {
        if (BufferLength < sizeof(NDISPROT_SET_OID))
        {
            status = STATUS_BUFFER_OVERFLOW;
            break;
        }

        pSet = (PNDISPROT_SET_OID)DataBuffer;
        Oid = pSet->Oid;
        InformationBuffer = &pSet->Data[0];
        InformationBufferLength = BufferLength - FIELD_OFFSET(NDISPROT_SET_OID, Data);
        switch(Oid)
        {

        case OID_802_3_MULTICAST_LIST:
            //
            // Verify the length
            //
            if (InformationBufferLength % ETH_LENGTH_OF_ADDRESS != 0)
            {
                return(STATUS_INVALID_BUFFER_SIZE);
            }

            //
            // Save the number of MC list size
            //
            FdoData->MCAddressCount = InformationBufferLength / ETH_LENGTH_OF_ADDRESS;
            ASSERT(FdoData->MCAddressCount <= NIC_MAX_MCAST_LIST);
            InformationBufferLength = InformationBufferLength > sizeof(FdoData->MCList)
					? sizeof(FdoData->MCList):InformationBufferLength;

            //
            // Save the MC list
            //
            RtlMoveMemory(
                FdoData->MCList,
                InformationBuffer,
                InformationBufferLength);

            KeAcquireSpinLock(&FdoData->Lock, &oldIrql);
            KeAcquireSpinLockAtDpcLevel(&FdoData->RcvLock);

            status = NICSetMulticastList(FdoData);

            KeReleaseSpinLockFromDpcLevel(&FdoData->RcvLock);
            KeReleaseSpinLock(&FdoData->Lock, oldIrql);
            break;

        case OID_GEN_CURRENT_PACKET_FILTER:
            //
            // Verify the Length
            //
            if (InformationBufferLength != sizeof(ULONG))
            {
                return(STATUS_INVALID_BUFFER_SIZE);
            }

            RtlMoveMemory(&PacketFilter, InformationBuffer, sizeof(ULONG));

            //
            // any bits not supported?
            //
            if (PacketFilter & ~NIC_SUPPORTED_FILTERS)
            {
                return(STATUS_NOT_SUPPORTED);
            }

            //
            // any filtering changes?
            //
            if (PacketFilter == FdoData->PacketFilter)
            {
                break;
            }

            KeAcquireSpinLock(&FdoData->Lock, &oldIrql);
            KeAcquireSpinLockAtDpcLevel(&FdoData->RcvLock);

            if (MP_TEST_FLAG(FdoData, fMP_ADAPTER_LINK_DETECTION))
            {

                //
                // The device is busy doing link detection. Let us queue
                // the IRP. When the link detection is over, the watchdog
                // timer DPC will complete this IRP.
                //
                ASSERT(!FdoData->SetRequest);
                status = PciDrvQueueIoctlIrp(FdoData, Irp);

                KeReleaseSpinLockFromDpcLevel(&FdoData->RcvLock);
                KeReleaseSpinLock(&FdoData->Lock, oldIrql);
                break;
            }

            status = NICSetPacketFilter(
                         FdoData,
                         PacketFilter);

            KeReleaseSpinLockFromDpcLevel(&FdoData->RcvLock);
            KeReleaseSpinLock(&FdoData->Lock, oldIrql);

            if (status == STATUS_SUCCESS)
            {
                FdoData->PacketFilter = PacketFilter;
            }

            break;

        case OID_PNP_SET_POWER:

            if (InformationBufferLength != sizeof(NDIS_DEVICE_POWER_STATE ))
            {
                return(STATUS_BUFFER_TOO_SMALL);
            }

            newDeviceState = *(PDEVICE_POWER_STATE UNALIGNED)InformationBuffer;
            oldDeviceState = FdoData->DevicePowerState;
            FdoData->DevicePowerState = newDeviceState;

            if (oldDeviceState == PowerDeviceD0) {

                status = PciDrvPowerBeginQueuingIrps(
                    FdoData->Self,
                    1,              // One for current OID request.
                    FALSE           // Do not query for state change.
                    );

                ASSERT(NT_SUCCESS(status));
            }

            //
            // Set the power state - Cannot fail this request
            //
            status = NICSetPower(FdoData, newDeviceState );

            if (status != STATUS_SUCCESS)
            {
                DebugPrint(ERROR, DBG_IOCTLS, "SET Power: Hardware error !!!\n");
                break;
            }

            if (newDeviceState == PowerDeviceD0) {

                //
                // Our hardware is now on again. Here we empty our existing queue of
                // requests and let in new ones.
                //
                FdoData->QueueState = AllowRequests;
                PciDrvProcessQueuedRequests(FdoData);
            }

            status = STATUS_SUCCESS;
            break;

        case OID_PNP_ADD_WAKE_UP_PATTERN:
            //
            // call a function that would program the adapter's wake
            // up pattern, return success
            //
            DebugPrint(TRACE, DBG_IOCTLS, "--> OID_PNP_ADD_WAKE_UP_PATTERN\n");

            if (IsPoMgmtSupported(FdoData) )
            {
                status = NICAddWakeUpPattern(FdoData,
                                            InformationBuffer,
                                            InformationBufferLength,
                                            &unUsed,
                                            &unUsed);
            }
            else
            {
                status = STATUS_NOT_SUPPORTED;
            }
            break;


        case OID_PNP_REMOVE_WAKE_UP_PATTERN:

            //
            // call a function that would remove the adapter's wake
            // up pattern, return success
            //
            DebugPrint(TRACE, DBG_IOCTLS, "--> OID_PNP_ADD_WAKE_UP_PATTERN\n");

            if (IsPoMgmtSupported(FdoData) )
            {
                status = NICRemoveWakeUpPattern(FdoData,
                                               InformationBuffer,
                                               InformationBufferLength,
                                               &unUsed,
                                               &unUsed);

            }
            else
            {
                status = STATUS_NOT_SUPPORTED;
            }
            break;

        case OID_PNP_ENABLE_WAKE_UP:
            //
            // call a function that would enable wake up on the adapter
            // return success
            //
            DebugPrint(TRACE, DBG_IOCTLS, "--> OID_PNP_ENABLE_WAKE_UP\n");
            if (IsPoMgmtSupported(FdoData))
            {
                ULONG       WakeUpEnable;
                RtlMoveMemory(&WakeUpEnable, InformationBuffer,sizeof(ULONG));
                //
                // The WakeUpEable can only be 0, or NDIS_PNP_WAKE_UP_PATTERN_MATCH since the driver only
                // supports wake up pattern match
                //
                if ((WakeUpEnable != 0)
                       && ((WakeUpEnable & NDIS_PNP_WAKE_UP_PATTERN_MATCH) != NDIS_PNP_WAKE_UP_PATTERN_MATCH ))
                {
                    status = STATUS_NOT_SUPPORTED;
                    FdoData->AllowWakeArming = FALSE;
                    break;
                }
                //
                // When the driver goes to low power state, it would check WakeUpEnable to decide
                // which wake up methed it should use to wake up the machine. If WakeUpEnable is 0,
                // no wake up method is enabled.
                //
                FdoData->AllowWakeArming = TRUE;

                status = STATUS_SUCCESS;
            }
            else
            {
                status = STATUS_NOT_SUPPORTED;
            }

            break;
        default:
            status = STATUS_NOT_SUPPORTED;
            break;
        }
    }while (FALSE);

    DebugPrint(LOUD, DBG_IOCTLS, "<-- HandleSetOIDRequest\n");

    return (status);
}
コード例 #6
0
ファイル: wmi.c プロジェクト: kcrazy/winekit
NTSTATUS
PciDrvQueryWmiDataBlock(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp,
    ULONG GuidIndex,
    ULONG InstanceIndex,
    ULONG InstanceCount,
    PULONG InstanceLengthArray,
    ULONG OutBufferSize,
    PUCHAR Buffer
    )
/*++

Routine Description:

    This routine is a callback into the driver to query for the contents of
    a data block. When the driver has finished filling the data block it
    must call WmiCompleteRequest to complete the irp. The driver can
    return STATUS_PENDING if the irp cannot be completed immediately.

Arguments:

    DeviceObject is the device whose data block is being queried

    Irp is the Irp that makes this request

    GuidIndex is the index into the list of guids provided when the
        device registered

    InstanceIndex is the index that denotes which instance of the data block
        is being queried.

    InstanceCount is the number of instances expected to be returned for
        the data block.

    InstanceLengthArray is a pointer to an array of ULONG that returns the
        lengths of each instance of the data block. If this is NULL then
        there was not enough space in the output buffer to fulfill the request
        so the irp should be completed with the buffer needed.

    BufferAvail on has the maximum size available to write the data
        block.

    Buffer on return is filled with the returned data block


Return Value:

    status

--*/
{
    PFDO_DATA               fdoData;
    NTSTATUS                status = STATUS_WMI_GUID_NOT_FOUND;
    ULONG                   size = 0;

    PAGED_CODE();

    DebugPrint(TRACE, DBG_WMI, "Entered PciDrvQueryWmiDataBlock\n");

    //
    // Only ever registers 1 instance per guid
    ASSERT((InstanceIndex == 0) &&
           (InstanceCount == 1));

    fdoData = (PFDO_DATA) DeviceObject->DeviceExtension;

    switch (GuidIndex) {
    case WMI_PCIDRV_DRIVER_INFORMATION:

        size = sizeof (PCIDRV_WMI_STD_DATA);
        if (OutBufferSize < size ) {
            status = STATUS_BUFFER_TOO_SMALL;
            break;
        }
        //
        // Copy the structure information
        //
        * (PPCIDRV_WMI_STD_DATA) Buffer = fdoData->StdDeviceData;

        *InstanceLengthArray = size ;
        status = STATUS_SUCCESS;
        break;


    case WMI_POWER_DEVICE_WAKE_ENABLE:

        //
        // Here we return the current preference of the user for wait-waking
        // the system. We read(IoOpenDeviceRegistryKey/ZwQueryValueKey)
        // the default value written by the INF file in the HW registery.
        // If the user changes his preference, then we must record
        // the changes in the registry to have that in affect across
        // boots.
        //

        size = sizeof(BOOLEAN);

        if (OutBufferSize < size) {
            status = STATUS_BUFFER_TOO_SMALL;
            break;
        }
        if(IsPoMgmtSupported(fdoData)){
            *(PBOOLEAN) Buffer = PciDrvGetWaitWakeEnableState(fdoData) ;
            *InstanceLengthArray = size;
            status = STATUS_SUCCESS;
        }
        break;

    case WMI_POWER_DEVICE_ENABLE:

        //
        // The same rule discussed above applies here
        // for responding to the query.
        //
        size = sizeof(BOOLEAN);

        if (OutBufferSize < size) {
            status = STATUS_BUFFER_TOO_SMALL;
            break;
        }

        if(IsPoMgmtSupported(fdoData)){

            *(PBOOLEAN) Buffer = PciDrvGetPowerSaveEnableState(fdoData);
            *InstanceLengthArray = size;
            status = STATUS_SUCCESS;
        }

        break;

    case WMI_POWER_CONSERVATION_IDLE_TIME:

        size = sizeof(ULONG);

        if (OutBufferSize < size) {
            status = STATUS_BUFFER_TOO_SMALL;
            break;
        }
        //
        // Convert the value back to secs.
        //
        *(PULONG) Buffer = (ULONG)(fdoData->ConservationIdleTime/-SECOND_TO_100NS);
        *InstanceLengthArray = size;
        status = STATUS_SUCCESS;
        break;

    case WMI_POWER_PERFORMANCE_IDLE_TIME:

        size = sizeof(ULONG);

        if (OutBufferSize < size) {
            status = STATUS_BUFFER_TOO_SMALL;
            break;
        }
        //
        // Convert the value back to secs.
        //
        *(PULONG) Buffer = (ULONG)(fdoData->PerformanceIdleTime/-SECOND_TO_100NS);
        *InstanceLengthArray = size;
        status = STATUS_SUCCESS;
        break;

    default:

        status = STATUS_WMI_GUID_NOT_FOUND;
    }

    status = WmiCompleteRequest(  DeviceObject,
                                  Irp,
                                  status,
                                  size,
                                  IO_NO_INCREMENT);

    return status;
}
コード例 #7
0
ファイル: wmi.c プロジェクト: kcrazy/winekit
NTSTATUS
PciDrvSetWmiDataBlock(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp,
    ULONG GuidIndex,
    ULONG InstanceIndex,
    ULONG BufferSize,
    PUCHAR Buffer
    )
/*++

Routine Description:

    This routine is a callback into the driver to set the contents of
    a data block. When the driver has finished filling the data block it
    must call WmiCompleteRequest to complete the irp. The driver can
    return STATUS_PENDING if the irp cannot be completed immediately.

Arguments:

    DeviceObject is the device whose data block is being queried

    Irp is the Irp that makes this request

    GuidIndex is the index into the list of guids provided when the
        device registered

    InstanceIndex is the index that denotes which instance of the data block
        is being queried.

    BufferSize has the size of the data block passed

    Buffer has the new values for the data block


Return Value:

    status

--*/
{
    PFDO_DATA   fdoData;
    NTSTATUS    status = STATUS_WMI_GUID_NOT_FOUND;
    BOOLEAN     waitWakeEnabled;
    BOOLEAN     powerSaveEnabled;
    LONGLONG    newIdleTime, prevIdleTime;
    ULONG       requiredSize = 0;

    PAGED_CODE();

    fdoData = (PFDO_DATA) DeviceObject->DeviceExtension;

    DebugPrint(TRACE, DBG_WMI, "Entered PciDrvSetWmiDataBlock\n");

    switch(GuidIndex) {
    case WMI_PCIDRV_DRIVER_INFORMATION:

        //
        // We will update only writable elements.
        //
        requiredSize = sizeof(PCIDRV_WMI_STD_DATA);
        if (BufferSize < requiredSize) {
            status = STATUS_BUFFER_TOO_SMALL;
            break;
        }
        DebugLevel = fdoData->StdDeviceData.DebugPrintLevel =
                    ((PPCIDRV_WMI_STD_DATA)Buffer)->DebugPrintLevel;

        status = STATUS_SUCCESS;

        break;


    case WMI_POWER_DEVICE_WAKE_ENABLE:

        //
        // If the wait-wake state is true (box is checked), we send a IRP_MN_WAIT_WAKE
        //  irp to the bus driver. If it's FALSE, we cancel it.
        // Every time the user changes his preference,
        // we write that to the registry to carry over his preference across boot.
        // If the user tries to enable wait-wake, and if the driver stack is not
        // able to do, it will reset the value in the registry to indicate that
        // the device is incapable of wait-waking the system.
        //
        requiredSize = sizeof(BOOLEAN);
        if (BufferSize < requiredSize) {
            status = STATUS_BUFFER_TOO_SMALL;
            break;
        }

        if(IsPoMgmtSupported(fdoData)){

            waitWakeEnabled = *(PBOOLEAN) Buffer;

            PciDrvSetWaitWakeEnableState(fdoData, waitWakeEnabled);

            if (waitWakeEnabled) {

                PciDrvArmForWake(fdoData, FALSE);

            } else {

                PciDrvDisarmWake(fdoData, FALSE);
            }

            status = STATUS_SUCCESS;
        }
        break;

    case WMI_POWER_DEVICE_ENABLE:

        requiredSize = sizeof(BOOLEAN);
        if (BufferSize < requiredSize) {
            status = STATUS_BUFFER_TOO_SMALL;
            break;
        }

        if(IsPoMgmtSupported(fdoData)){

            powerSaveEnabled = *(PBOOLEAN) Buffer;

            PciDrvSetPowerSaveEnableState(fdoData,  powerSaveEnabled);

            if(powerSaveEnabled) {

                PciDrvRegisterForIdleDetection(fdoData, FALSE);

            } else {

                PciDrvDeregisterIdleDetection(fdoData, FALSE);
            }

            status = STATUS_SUCCESS;
        }
        break;

    case WMI_POWER_CONSERVATION_IDLE_TIME:

        requiredSize =  sizeof(ULONG);
        if (BufferSize < requiredSize) {
            status = STATUS_BUFFER_TOO_SMALL;
            break;
        }

        newIdleTime = *(PULONG) Buffer;
        newIdleTime = max(newIdleTime, PCIDRV_MIN_IDLE_TIME);
        //
        // Convert that to ms time units
        //
        newIdleTime = (LONGLONG) -SECOND_TO_100NS * newIdleTime;
        prevIdleTime = fdoData->ConservationIdleTime;
        fdoData->ConservationIdleTime = newIdleTime;

        if(IsPoMgmtSupported(fdoData) &&
            newIdleTime != prevIdleTime){ // if not setting the same value

            //
            // Reset the timer by deregistering and registering the Idle
            // detection.
            //
            PciDrvDeregisterIdleDetection(fdoData, FALSE);
            PciDrvRegisterForIdleDetection(fdoData, FALSE);

        }
        status = STATUS_SUCCESS;
        break;

    case WMI_POWER_PERFORMANCE_IDLE_TIME:

        requiredSize = sizeof(ULONG);
        if (BufferSize < requiredSize) {
            status = STATUS_BUFFER_TOO_SMALL;
            break;
        }

        newIdleTime = *(PULONG) Buffer;
        newIdleTime = max(newIdleTime, PCIDRV_MIN_IDLE_TIME);
        //
        // Convert that to ms time units
        //
        newIdleTime = (LONGLONG) -SECOND_TO_100NS * newIdleTime;
        prevIdleTime = fdoData->PerformanceIdleTime;
        fdoData->PerformanceIdleTime = newIdleTime;

        if(IsPoMgmtSupported(fdoData) &&
            newIdleTime != prevIdleTime){ // if not setting the same value
                        //
            // Reset the timer by deregistering and registering the Idle
            // detection.
            //
            PciDrvDeregisterIdleDetection(fdoData, FALSE);
            PciDrvRegisterForIdleDetection(fdoData, FALSE);
        }
        status = STATUS_SUCCESS;
        break;

    default:

        status = STATUS_WMI_GUID_NOT_FOUND;
    }

    status = WmiCompleteRequest(  DeviceObject,
                                  Irp,
                                  status,
                                  requiredSize,
                                  IO_NO_INCREMENT);

    return(status);
}