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

📄 ul_wdpnp.c

📁 linux下的RS485的驱动 值得一看
💻 C
📖 第 1 页 / 共 5 页
字号:
        //        // We're here if we're running and the PnP Manager sends us        // a QUERY_STOP_DEVICE request.  He'll do this if he wants to        // rebalance resources, to see if we're willing to give up the        // hardware resources that were allocated for us when we got        // our IRP_MN_START_DEVICE.        //        // To proess this QUERY_STOP, we check to see if the stop is        // acceptable to us (in this driver it always is), and then        // we just transition the device to STOP_PENDING state.  In        // this state, new requests that arrive are queued.  When a        // currently in-progress request is completed, a new request        // is NOT started.  Thus, ON OUR DEVICE, we sort of hope that        // between the QUERY_STOP IRP arrive and actual STOP IRP arriving        // that any in-progress I/O will complete of its own accord.        // We like this scheme, particularly because at least on NT        // during startup the device seems to get lots of QUERY_STOP        // IRPs, that are just followed by CANCEL_STOP.  Thus, we think        // it would be unfortunate to do anything radical with the        // outstanding requests (like cancel them) when we receive a        // QUERY_STOP.        //        case STATE_STARTED + IRP_MN_QUERY_STOP_DEVICE:#if DBG            uLan_DbgPrint("uLan: DispatchPnp: PROCESSING QUERY_STOP_DEVICE\n");#endif            //            // WE process this request before the BUS DRIVER            //            //            // See if we're OK with stopping the device at this point.            // We do NOT actually RETURN the resources here... we            // just affirm or deny that we're OK with returning them.            //            code = CanStopDevice(devExt, Irp);                        //            // Replace status code that's in the IRP to indicate our            // opinion about stopping the device.  If we're            // OK with returning the resources, this will be            // STATUS_SUCCESS.            //            Irp->IoStatus.Status = code;            if(!NT_SUCCESS(code)) {                //                // NOPE.  Can't stop the device because, for some                // reason (perhaps because we can't return our                // resources).  Too bad. Tell the PnP Manager that                // stopping right now is not an option for us.                //                // NOTE: NO NEED to pass IRP down if WE can't stop                // it doesn't matter if the Bus Driver can.                //                IoCompleteRequest(Irp, IO_NO_INCREMENT);                                                    } else {                                    //                // We CAN stop our device and return the resources.                // Pass the IRP down to see if the bus driver is                // equally ammenable to the request.                //#if DBG                uLan_DbgPrint("uLan: DispatchPnp: Agreeing to stop device.\n");#endif                //                // Set new state. This state results in no new                // requests being started on the device, but incoming                // requests are still allowed and queued.                //                devExt->State = STATE_STOP_PENDING;                //                // Pass this request on down to the bus driver                //                IoSkipCurrentIrpStackLocation(Irp);                code = IoCallDriver(devExt->DeviceToSendIrpsTo, Irp);            }            break;        //        // STATE:   STOP_PENDING        // IRP_MN:  _STOP_DEVICE        //        // We're in this state because we previously received a         // QUERY_STOP_DEVICE, that we agreed that we could grant.        // Thus, we're waiting to receive a STOP_DEVICE request.        // To process this request, we first wait for any in-progress        // requests to complete (note that no NEW requests have been        // started since the transition to STOP_PENDING state as a        // result of receiving the QUERY_STOP IRP).  After all in-        // progress requests are complete, we return our resources        // and wait for further instructions from the PnP Manager (        // which better include a START_DEVICE someplace down the line!).        //         // While in this state, any IRPs we receive will be queued        // for processing after we get the START_DEVICE.        //        case STATE_STOP_PENDING + IRP_MN_STOP_DEVICE:#if DBG            uLan_DbgPrint("uLan: DispatchPnp: PROCESSING STOP_DEVICE\n");#endif            //            // Assume success            //            devExt->State = STATE_STOPPED;        #if DBG            uLan_DbgPrint("uLan: DispatchPnp: Waiting for in-progress requests to complete\n");#endif            //            // We process this request before passing it to the bus            // driver            //            //            // Wait until all active requests on the device have            // completed...            //            WaitForStop(devExt);                        //            // There are NO ACTIVE IRPs on the device at this point.            //            //            // Return any resources we're using.            //            ReturnResources(devExt);            //            // NOTE: We DO NOT delete our device object here.  This is            // one difference between a _STOP_DEVICE and _REMOVE_DEVICE.            //#if DBG            uLan_DbgPrint("uLan: DispatchPnp: Passing along request\n");#endif            //            // Pass this request on down to the bus driver            //            IoSkipCurrentIrpStackLocation(Irp);                        //            // We're cool with the stop...            //            Irp->IoStatus.Status = STATUS_SUCCESS;            code = IoCallDriver(devExt->DeviceToSendIrpsTo, Irp);            break;                //        // STATE:   STOP_PENDING        // IRP_MN:  _CANCEL_STOP_DEVICE        //        // We're here because we've already received a QUERY_STOP,        // that we've agreed to.  We've completed any pending I/O        // requests.  Now we've received a CANCEL_STOP_DEVICE        // IRP, that sort of says "never mind" about that stop.        //        // We restart our queues and return to Started state.        //        case STATE_STOP_PENDING + IRP_MN_CANCEL_STOP_DEVICE:#if DBG            uLan_DbgPrint("uLan: DispatchPnp: PROCESSING CANCEL_STOP\n");#endif            //            // fall through...            //        //        // STATE:   REMOVE_PENDING        // IRP_MN:  _CANCEL_REMOVE_DEVICE        //        // We're here because we've already received a QUERY_REMOVE,        // that we've agreed to.  We've completed any pending I/O        // requests.  Now we've received a CANCEL_REMOVE_DEVICE        // IRP, that sort of says "never mind" about that remove.        //        // We restart our queues and return to Started state.        //        case STATE_REMOVE_PENDING + IRP_MN_CANCEL_REMOVE_DEVICE:#if DBG            if( devExt->State == STATE_REMOVE_PENDING) {                            uLan_DbgPrint("uLan: DispatchPnp: PROCESSING CANCEL_REMOVE\n");                   }#endif            //            // The Underlying BUS DRIVER must handle these IRPs            // before we do...            //            //            // We need to wait for the underlying bus driver to            // get restarted, before we can continue processing.            //            IoCopyCurrentIrpStackLocationToNext(Irp);            IoSetCompletionRoutine(Irp,                                   PnpComplete,                                   &eventWaitLowerDrivers,                                   TRUE,                                   TRUE,                                   TRUE);            code = IoCallDriver(devExt->DeviceToSendIrpsTo, Irp);            if(code == STATUS_PENDING) {                KeWaitForSingleObject(&eventWaitLowerDrivers,                                      Executive,                                      KernelMode,                                      FALSE,                                      NULL);            }            //            // We're now in STARTED state            //            devExt->State = STATE_STARTED;            //            // Go see if there's a request that we can start now            //            ProcessQueuedRequests(devExt);            code = STATUS_SUCCESS;            Irp->IoStatus.Status = code;            Irp->IoStatus.Information = 0;            IoCompleteRequest(Irp, IO_NO_INCREMENT);            break;#ifdef UL_WITH_WIN_PWR        //        // STATE:   QUERY_CAPABILITIES        // IRP_MN:  IRP_MN_QUERY_CAPABILITIES        //        case STATE_STARTED + IRP_MN_QUERY_CAPABILITIES:#if DBG            uLan_DbgPrint("uLan: DispatchPnp: QUERY_CAPABILITIES\n");#endif            IoCopyCurrentIrpStackLocationToNext(Irp);            IoSetCompletionRoutine(Irp,                                   PnpComplete,                                   &eventWaitLowerDrivers,                                   TRUE,                                   TRUE,                                   TRUE);            code = IoCallDriver(devExt->DeviceToSendIrpsTo, Irp);            if(code == STATUS_PENDING) {                KeWaitForSingleObject(&eventWaitLowerDrivers,                                      Executive,                                      KernelMode,                                      FALSE,                                      NULL);            }                        break;                    code = STATUS_SUCCESS;            Irp->IoStatus.Status = code;            Irp->IoStatus.Information = 0;            IoCompleteRequest(Irp, IO_NO_INCREMENT);                        break;#endif /* UL_WITH_WIN_PWR */        default:            //            // DEFAULT CASE            // Just pass the request to the lower driver            //#if DBG            uLan_DbgPrint("uLan: DispatchPnp: Default case: Just pass it along...\n");#endif            IoSkipCurrentIrpStackLocation (Irp);            code = IoCallDriver (devExt->DeviceToSendIrpsTo, Irp);            break;    }    //    // Adjust in-progress request count    //    RequestDecrement(devExt);#if DBG    uLan_DbgPrint("uLan: DispatchPnp: Leaving with new state ");    PrintState(devExt);    uLan_DbgPrint("uLan: DispatchPnp: exit (%d.).\n", devExt->OutstandingIO);#endif    //    // We always finish our work in this function    //    ASSERT(code != STATUS_PENDING);    return(code);}//// PnpComplete// // This is the completion routine for IRP_MJ_PNP requests//NTSTATUSPnpComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context){    PIO_STACK_LOCATION  iostack;    PKEVENT pEvent = (PKEVENT) Context;    NTSTATUS status = STATUS_SUCCESS;#ifdef UL_WITH_WIN_PWR    PULAN_DEVICE_EXTENSION devExt;    PDEVICE_CAPABILITIES Capabilities;    devExt = (PULAN_DEVICE_EXTENSION)DeviceObject->DeviceExtension;#else    UNREFERENCED_PARAMETER (DeviceObject); #endif /* UL_WITH_WIN_PWR */    iostack = IoGetCurrentIrpStackLocation (Irp);//// Driver Writers, please note:////  The following code is only necessary IF (a) WE have a completion//  routine, AND (b) WE return STATUS_PENDING from our dispatch entry//  point after re-claiming the IRP.  Since neither of these things//  is true... this code does not belong here.////    if (Irp->PendingReturned) {////        IoMarkIrpPending( Irp );////    }    switch (iostack->MajorFunction) {        case IRP_MJ_PNP:#ifdef UL_WITH_WIN_PWR            if (iostack->MinorFunction == IRP_MN_QUERY_CAPABILITIES) {                        Capabilities = iostack->Parameters.DeviceCapabilities.Capabilities;                        //Modify the PnP values here as necessary                        Capabilities->Removable = TRUE;                        Capabilities->SurpriseRemovalOK = FALSE;                            //Save the device capabilities int the device extension                        RtlCopyMemory(&devExt->DeviceCapabilities,                                Capabilities,                                sizeof(DEVICE_CAPABILITIES));                                                PrintCapabilityInfo(&devExt->DeviceCapabilities);                                    }#endif /* UL_WITH_WIN_PWR */            KeSetEvent(pEvent, 0, FALSE);            //            // Take the IRP back so that we can continue using it during            // the IRP_MN_START_DEVICE dispatch routine.            // NB: we will have to call IoCompleteRequest            //            return STATUS_MORE_PROCESSING_REQUIRED;            break;        case IRP_MJ_POWER:            KeSetEvent(pEvent, 1, FALSE);            //            // Take the IRP back so that we can continue using it during            // the IRP_MN_START_DEVICE dispatch routine.            // NB: we will have to call IoCompleteRequest            //            return STATUS_MORE_PROCESSING_REQUIRED;            break;        default:#if DBG            uLan_DbgPrint("uLan: PnpComplete: NOT MJ_PNP or MJ_POWER IRP??\n");#endif            break;    }    return status;}/////////////////////////////////////////////////////////////////////////////////// StartDevice////      This function is called from the DispatchPnp Entry Point to//      actually start the hardware.////  INPUTS:////      DevExt  - Address of our device extension.//      IoStackLocation -- Pointer to I/O Stack Location containing//                  configuration information////  OUTPUTS:////      None.

⌨️ 快捷键说明

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