⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ul_wdpwr.c

📁 linux下的RS485的驱动 值得一看
💻 C
📖 第 1 页 / 共 2 页
字号:
    // When passing a power IRP down to a lower-level driver, the caller should use    // IoSkipCurrentIrpStackLocation or IoCopyCurrentIrpStackLocationToNext to copy the IRP to    // the next stack location, then call PoCallDriver. Use IoCopyCurrentIrpStackLocationToNext    // if processing the IRP requires setting a completion routine, or IoSkipCurrentStackLocation    // if no completion routine is needed.    PoCallDriver(deviceExtension->DeviceToSendIrpsTo, irp);     RequestDecrement(deviceExtension);    uLan_DbgPrint("uLan: PoRequestCompletion() Exit IRP_MN_SET_POWER\n");    deviceExtension->PowerIrp = NULL;    return ntStatus;}NTSTATUSPowerIrp_Complete(    IN PDEVICE_OBJECT NullDeviceObject,    IN PIRP Irp,    IN PVOID Context    )/*++Routine Description:    This routine is called when An IRP_MN_SET_POWER of type 'DevicePowerState'    has been received by ProcessPowerIrp(), and that routine has  determined        1) the request is for full powerup ( to PowerDeviceD0 ), and        2) We are not already in that state    A call is then made to PoRequestPowerIrp() with this routine set as the completion routine.Arguments:    DeviceObject - Pointer to the device object for the class device.    Irp - Irp completed.    Context - Driver defined context.Return Value:    The function value is the final status from the operation.--*/{    NTSTATUS ntStatus = STATUS_SUCCESS;    PDEVICE_OBJECT deviceObject;    PIO_STACK_LOCATION irpStack;    PULAN_DEVICE_EXTENSION deviceExtension;    uLan_DbgPrint("uLan: enter PowerIrp_Complete\n");    deviceObject = (PDEVICE_OBJECT) Context;    deviceExtension = deviceObject->DeviceExtension;    //  If the lower driver returned PENDING, mark our stack location as pending also.    if (Irp->PendingReturned) {        IoMarkIrpPending(Irp);    }    irpStack = IoGetCurrentIrpStackLocation (Irp);    // We can assert that we're a  device powerup-to D0 request,    // because that was the only type of request we set a completion routine    // for in the first place    ASSERT(irpStack->MajorFunction == IRP_MJ_POWER);    ASSERT(irpStack->MinorFunction == IRP_MN_SET_POWER);    ASSERT(irpStack->Parameters.Power.Type==DevicePowerState);    ASSERT(irpStack->Parameters.Power.State.DeviceState==PowerDeviceD0);    // Now that we know we've let the lower drivers do what was needed to power up,    //  we can set our device extension flags accordingly    deviceExtension->CurrentDevicePowerState = PowerDeviceD0;    Irp->IoStatus.Status = ntStatus;    RequestDecrement(deviceExtension);    uLan_DbgPrint("uLan: exit PowerIrp_Complete Exit IRP_MN_SET_POWER D0 complete\n");    return ntStatus;}NTSTATUSSelfSuspendOrActivate(    IN PDEVICE_OBJECT DeviceObject,    IN BOOLEAN fSuspend    )/*++Routine Description:        Called on PnPAddDevice() to power down until needed (i.e., till a pipe is actually opened).        Called on Create() to power up device to D0 before opening 1st pipe.        Called on Close() to power down device if this is the last pipe.Arguments:    DeviceObject - Pointer to the device object    fSuspend; TRUE to Suspend, FALSE to acivate.Return Value:    If the operation is not attemtped, SUCCESS is returned.    If the operation is attemtped, the value is the final status from the operation.--*/{    NTSTATUS ntStatus = STATUS_SUCCESS;    POWER_STATE PowerState;    PULAN_DEVICE_EXTENSION deviceExtension;    deviceExtension = DeviceObject->DeviceExtension;    uLan_DbgPrint("uLan: Enter SelfSuspendOrActivate(),fSuspend = %d\n", fSuspend);        // Can't accept request if:    //  1) device is removed,    //  2) has never been started,    //  3) is stopped,    //  4) has a remove request pending,    //  5) has a stop device pending/*    if ( !BulkUsb_CanAcceptIoRequests( DeviceObject ) ) {        ntStatus = STATUS_DELETE_PENDING;                BULKUSB_KdPrint( DBGLVL_MEDIUM,("ABORTING BulkUsb_SelfSuspendOrActivate()\n"));        return ntStatus;    }*/    // don't do anything if any System-generated Device Pnp irps are pending    if ( NULL != deviceExtension->PowerIrp ) {        uLan_DbgPrint("uLan: Exit SelfSuspendOrActivate(),refusing on pending deviceExtension->PowerIrp 0x%x\n", deviceExtension->PowerIrp);        return ntStatus;    }    // don't do anything if any self-generated Device Pnp irps are pending    if ( deviceExtension->SelfPowerIrp ) {        uLan_DbgPrint("uLan: Exit SelfSuspendOrActivate(),refusing on pending deviceExtension->SelfPowerIrp\n" );        return ntStatus;    }    //  has been set to  zero, PowerDeviceD0 ( 1 ), or a bogus high value    if ( ( deviceExtension->PowerDownLevel == PowerDeviceD0 ) ||         ( deviceExtension->PowerDownLevel == PowerDeviceUnspecified)  ||         ( deviceExtension->PowerDownLevel >= PowerDeviceMaximum ) ) {        uLan_DbgPrint("uLan: Exit SelfSuspendOrActivate(), refusing on deviceExtension->PowerDownLevel == %d\n", deviceExtension->PowerDownLevel);        return ntStatus;    }    if ( fSuspend )        PowerState.DeviceState = deviceExtension->PowerDownLevel;    else        PowerState.DeviceState = PowerDeviceD0;  // power up all the way; we're probably just about to do some IO    ntStatus = SelfRequestPowerIrp( DeviceObject, PowerState );    uLan_DbgPrint("uLan: SelfSuspendOrActivate() status 0x%x on setting dev state %s\n", ntStatus, DevicePowerStateString[PowerState.DeviceState]);    return ntStatus;}NTSTATUSSelfRequestPowerIrp(    IN PDEVICE_OBJECT DeviceObject,    IN POWER_STATE PowerState    )/*++Routine Description:    This routine is called by SelfSuspendOrActivate() to    actually make the system request for a powerdown/up to PowerState.    It first checks to see if we are already in Powerstate and immediately    returns  SUCCESS with no further processing if soArguments:    DeviceObject - Pointer to the device object    PowerState. power state requested, e.g PowerDeviceD0.Return Value:    The function value is the final status from the operation.--*/{    NTSTATUS ntStatus = STATUS_SUCCESS;    PULAN_DEVICE_EXTENSION deviceExtension;    PIRP pIrp = NULL;    deviceExtension = DeviceObject->DeviceExtension;    // This should have been reset in completion routine    ASSERT( !deviceExtension->SelfPowerIrp );    if (  deviceExtension->CurrentDevicePowerState ==  PowerState.DeviceState )        return STATUS_SUCCESS;  // nothing to do    uLan_DbgPrint("uLan: Enter SelfRequestPowerIrp() will request power irp to state %s\n",        DevicePowerStateString[PowerState.DeviceState]);    RequestIncrement(deviceExtension);        // flag we're handling a self-generated power irp    deviceExtension->SelfPowerIrp = TRUE;        // actually request the Irp    ntStatus = PoRequestPowerIrp(deviceExtension->DeviceObject,                         IRP_MN_SET_POWER,                         PowerState,                         PoSelfRequestCompletion,                         DeviceObject,                         NULL);    if  ( ntStatus == STATUS_PENDING ) {        // status pending is the return code we wanted        // We only need to wait for completion if we're powering up        if ( (ULONG) PowerState.DeviceState < deviceExtension->PowerDownLevel ) {            NTSTATUS waitStatus;            waitStatus = KeWaitForSingleObject(                           &deviceExtension->SelfRequestedPowerIrpEvent,                           Suspended,                           KernelMode,                           FALSE,                           NULL);        }        ntStatus = STATUS_SUCCESS;        deviceExtension->SelfPowerIrp = FALSE;        uLan_DbgPrint("uLan: SelfRequestPowerIrp() SUCCESS\n    IRP 0x%x to state %s\n",            pIrp, DevicePowerStateString[PowerState.DeviceState]);    }    else {        // The return status was not STATUS_PENDING; any other codes must be considered in error here;        //  i.e., it is not possible to get a STATUS_SUCCESS  or any other non-error return from this call;        uLan_DbgPrint("uLan: SelfRequestPowerIrp() to state %s FAILED, status = 0x%x\n",            DevicePowerStateString[ PowerState.DeviceState ],ntStatus);    }    return ntStatus;}NTSTATUSPoSelfRequestCompletion(    IN PDEVICE_OBJECT       DeviceObject,    IN UCHAR                MinorFunction,    IN POWER_STATE          PowerState,    IN PVOID                Context,    IN PIO_STATUS_BLOCK     IoStatus    )/*++Routine Description:    This routine is called when the driver completes a self-originated power IRP        that was generated by a call to SelfSuspendOrActivate().    We power down whenever the last pipe is closed and power up when the first pipe is opened.    For power-up , we set an event in our FDO extension to signal this IRP done    so the power request can be treated as a synchronous call.    We need to know the device is powered up before opening the first pipe, for example.    For power-down, we do not set the event, as no caller waits for powerdown complete.Arguments:    DeviceObject - Pointer to the device object for the class device. ( Physical Device Object )    Context - Driver defined context, in this case our FDO ( functional device object )Return Value:    The function value is the final status from the operation.--*/{    PDEVICE_OBJECT deviceObject = Context;    PULAN_DEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;    NTSTATUS ntStatus = IoStatus->Status;    // we should not be in the midst of handling a system-generated power irp    ASSERT( NULL == deviceExtension->PowerIrp );    // We only need to set the event if we're powering up;    // No caller waits on power down complete    if ( (ULONG) PowerState.DeviceState < deviceExtension->PowerDownLevel ) {        // Trigger Self-requested power irp completed event;        //  The caller is waiting for completion        KeSetEvent(&deviceExtension->SelfRequestedPowerIrpEvent, 1, FALSE);    }    RequestDecrement(deviceExtension);    uLan_DbgPrint("uLan: Exit PoSelfRequestCompletion() ntStatus = 0x%x\n", ntStatus );    return ntStatus;}BOOLEANSetDevicePowerState(    IN PDEVICE_OBJECT DeviceObject,    IN DEVICE_POWER_STATE DeviceState    )/*++Routine Description:    This routine is called when An IRP_MN_SET_POWER of type 'DevicePowerState'    has been received by Usb_ProcessPowerIrp().Arguments:    DeviceObject - Pointer to the device object for the class device.    DeviceState - Device specific power state to set the device in to.Return Value:    For requests to DeviceState D0 ( fully on ), returns TRUE to signal caller    that we must set a completion routine and finish there.--*/{    NTSTATUS ntStatus = STATUS_SUCCESS;    PULAN_DEVICE_EXTENSION deviceExtension;    BOOLEAN fRes = FALSE;    deviceExtension = (PULAN_DEVICE_EXTENSION)DeviceObject->DeviceExtension;    switch (DeviceState) {    case PowerDeviceD3:        //        // Device will be going OFF,                // TODO: add any needed device-dependent code to save state here.                //  ( We have nothing to do in this sample )        //        uLan_DbgPrint("uLan: SetDevicePowerState() PowerDeviceD3 (OFF)\n");        deviceExtension->CurrentDevicePowerState = DeviceState;        break;    case PowerDeviceD1:    case PowerDeviceD2:        //        // power states D1,D2 translate to USB suspend        uLan_DbgPrint("uLan: SetDevicePowerState()  %s\n",            DevicePowerStateString[DeviceState]);        deviceExtension->CurrentDevicePowerState = DeviceState;        break;    case PowerDeviceD0:        uLan_DbgPrint("uLan: SetDevicePowerState() PowerDeviceD0 (ON)\n");        // We'll need to finish the rest in the completion routine;        //   signal caller we're going to D0 and will need to set a completion routine        fRes = TRUE;        // Caller will pass on to PDO ( Physical Device object )        break;    default:        uLan_DbgPrint("uLan: Bogus DeviceState = %x\n", DeviceState);    }    return fRes;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -