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

📄 pnputils.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
        for( id = 0 ; id < daisyChainDevCount ; ++id ) {

            BOOLEAN         bBuildStlDeviceId = FALSE;
            PPDO_EXTENSION  pdx               = NULL;


            DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - changeDetected - trying to create new daisy chain PDOs\n");

            if( P5SelectDaisyChainDevice( controller, id ) ) {

                PCHAR devId = NULL;

                // do a check to see if this is an SCM Micro device
                pdx = ExAllocatePool( PagedPool | POOL_COLD_ALLOCATION, sizeof(PDO_EXTENSION) );
                if( pdx != NULL ) {
                    RtlZeroMemory( pdx, sizeof(PDO_EXTENSION) );
                    pdx->Controller   = fdx->PortInfo.Controller;
                    bBuildStlDeviceId = ParStlCheckIfStl( pdx, id );
                    ExFreePool( pdx );
                }


                if( bBuildStlDeviceId ) {
                    
                    // SCM Micro device
                    pdx = ExAllocatePool( PagedPool | POOL_COLD_ALLOCATION, sizeof(PDO_EXTENSION) );
                    if( pdx != NULL ) {
                        ULONG DeviceIdSize;
                        RtlZeroMemory( pdx, sizeof(PDO_EXTENSION) );
                        pdx->Controller = fdx->PortInfo.Controller;
                        devId = ParStlQueryStlDeviceId(pdx, NULL, 0,&DeviceIdSize, TRUE);
                        ExFreePool (pdx);
                    }
                    
                } else {

                    // non-SCM Micro device
                    devId = P4ReadRawIeee1284DeviceId( controller );

                }

                if( devId ) {

                    // try to create a PDO for the daisy chain device
                    fdx->DaisyChainPdo[id] = P4CreatePdo( Fdo, PdoTypeDaisyChain, id, (devId+2) );

                    if( fdx->DaisyChainPdo[id] ) {
                        // have new PDO
                        DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - new DaisyChainPdo[%d]\n",id);
                        ++(fdx->PnpInfo.Ieee1284_3DeviceCount);
                        
                        if( bBuildStlDeviceId ) {
                            // SCM Micro device - requires additional initialization
                            DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - new SCM Micro DaisyChainPdo[%d]\n",id);
                            pdx = fdx->DaisyChainPdo[id]->DeviceExtension;
                            pdx->Controller = fdx->PortInfo.Controller;
                            ParStlCheckIfStl( pdx, 0 ); // update IEEE 1284 flags in the new pdx
                        }

                    } else {
                        // create PDO failed
                        DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - create DaisyChainPdo[%d] failed\n",id);
                    }
                    ExFreePool( devId );
                } else {
                    // devId failed
                    DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - devId for DC %d failed\n",id);
                }
                P5DeselectAllDaisyChainDevices( controller );
            } else {
                // select failed
                DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - select for DC %d failed\n",id);
            }
        }
    }

    {
        ULONG i;
        ULONG count = 0;
        i = 0;
        for( i = 0 ; i < 2 ; ++i ) {
            if( fdx->DaisyChainPdo[i] ) {
                ++count;
            }
        }
        DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - Ieee1284_3DeviceCount=%d  count1 = %d\n",
           fdx->PnpInfo.Ieee1284_3DeviceCount,count);
        PptAssert( fdx->PnpInfo.Ieee1284_3DeviceCount == count );
    }

    DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - daisyChainDevCount = %d, fdx->PnpInfo.Ieee1284_3DeviceCount = %d\n",
       daisyChainDevCount, fdx->PnpInfo.Ieee1284_3DeviceCount);

    // PptAssert( daisyChainDevCount == fdx->PnpInfo.Ieee1284_3DeviceCount );

#endif // _X86_

target_failed_to_acquire_port: // jump here if we couldn't get the port - result is that we report that nothing has changed

    //
    // Count the number of devices that we are going to report to PnP
    //   so that we can allocate a DEVICE_RELATIONS structure of the
    //   appropriate size.
    //

    if( fdx->RawPortPdo ) {
        ++deviceCount;
    }

    if( fdx->EndOfChainPdo ) {
        ++deviceCount;
    }

    if( fdx->LegacyZipPdo ) {
        ++deviceCount;
    }

    {
        const ULONG maxDaisyChainId = 1;
        ULONG i;
        for( i=0 ; i <= maxDaisyChainId; ++i ) {
            if( fdx->DaisyChainPdo[i] ) {
                ++deviceCount;
            } else {
                break;
            }
        }
    }

    if( deviceCount > 0 && fdx->RawPortPdo ) {

        //
        // Allocate and populate DEVICE_RELATIONS structure that we return to PnP
        //
        
        devRelSize = sizeof(DEVICE_RELATIONS) + (deviceCount-1)*sizeof(PDEVICE_OBJECT);
        devRel     = ExAllocatePool( PagedPool | POOL_COLD_ALLOCATION, devRelSize );
        
        if( !devRel ) {
            // release port and fail IRP
            P4ReleaseBus( Fdo );
            return P4CompleteRequestReleaseRemLock( Irp, STATUS_INSUFFICIENT_RESOURCES, Irp->IoStatus.Information, &fdx->RemoveLock );
        }
        
        { // local block - begin
            ULONG idx = 0;
            
            RtlZeroMemory( devRel, devRelSize );
            
            ++(devRel->Count);
            ObReferenceObject( fdx->RawPortPdo );
            devRel->Objects[ idx++ ] = fdx->RawPortPdo;
            
            if( fdx->EndOfChainPdo ) {
                ++(devRel->Count);
                ObReferenceObject( fdx->EndOfChainPdo );
                devRel->Objects[ idx++ ] = fdx->EndOfChainPdo;
            }
            
            if( fdx->LegacyZipPdo ) {
                ++(devRel->Count);
                ObReferenceObject( fdx->LegacyZipPdo );
                devRel->Objects[ idx++ ] = fdx->LegacyZipPdo;
            }
            
            {
                const ULONG maxDaisyChainId = 3;
                ULONG       i;
                
                for( i=0 ; i <= maxDaisyChainId; ++i ) {
                    if( fdx->DaisyChainPdo[i] ) {
                        ++(devRel->Count);
                        ObReferenceObject( fdx->DaisyChainPdo[i] );
                        devRel->Objects[ idx++ ] = fdx->DaisyChainPdo[i];
                    } else {
                        break;
                    }
                }
            }
            
        } // local block - end
        
        PptAssert( deviceCount == devRel->Count ); // verify that our two counts match
        
        DD((PCE)fdx,DDE,"PptFdoHandleBusRelations - reporting %d devices\n",devRel->Count);
        
        Irp->IoStatus.Status      = STATUS_SUCCESS;
        Irp->IoStatus.Information = (ULONG_PTR)devRel;
    } else {
        // deviceCount <= 0 - error somewhere - likely two ports
        //   have the same LPTx name in the FDO stack's devnode

        // RMT - this assert needs to be changed to ErrorLog msg 
        PptAssert(!"no RawPort device - likely multiple ports have same LPTx name - email: DFritz");
    }


    DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - passing IRP down stack\n");

    status = PptPnpPassThroughPnpIrpAndReleaseRemoveLock( fdx, Irp );

    //
    // Release our lock on the bus and pass Irp down the stack
    //
    if( acquiredPort ) {
        PIO_WORKITEM workItem = IoAllocateWorkItem( Fdo );
        if( workItem ) {

            PIO_WORKITEM oldWorkItem = InterlockedCompareExchangePointer( &fdx->FreePortWorkItem, workItem, NULL );
            if( NULL == oldWorkItem ) {

                // no workitem currently in use, queue this one
                IoQueueWorkItem( workItem, P5WorkItemFreePort, DelayedWorkQueue, fdx );

            } else {

                // there is already a workitem in use, bail out and recover as best we can

                // We really shouldn't be able to get here - how in blazes did we
                // acquire the port at the top of this function if the workitem
                // that we queued to free the port during the previous invocation
                // of this function has not yet freed the port?

                PptAssertMsg( "workitem collision - port arbitration state may be hosed", (oldWorkItem != NULL) );
                IoFreeWorkItem( workItem );
                PptFreePort( fdx );

            }

        } else {
            PptFreePort( fdx );
        }
        // DbgPrint("xxx work item to free port has been queued\n");
        //DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - Releasing Port\n");
        //PptFreePort( fdx );
        //DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - Port Released\n");
    } else {
        DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - Port Not acquired so no need to release\n");
    }

    DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - exit\n");

    return status;
}

NTSTATUS
PptPnpStartScanPciCardCmResourceList(
    IN  PFDO_EXTENSION Fdx,
    IN  PIRP              Irp, 
    OUT PBOOLEAN          FoundPort,
    OUT PBOOLEAN          FoundIrq,
    OUT PBOOLEAN          FoundDma
    )
/*++dvdf3

Routine Description:

    This routine is used to parse the resource list for what we
      believe are PCI parallel port cards.

    This function scans the CM_RESOURCE_LIST supplied with the Pnp 
      IRP_MN_START_DEVICE IRP, extracts the resources from the list, 
      and saves them in the device extension.

Arguments:

    Fdx    - The device extension of the target of the START IRP
    Irp          - The IRP
    FoundPort    - Did we find a  Port resource?
    FoundIrq     - Did we find an IRQ  resource?
    FoundDma     - Did we find a  DMA  resource?

Return Value:

    STATUS_SUCCESS                - if we were given a resource list,
    STATUS_INSUFFICIENT_RESOURCES - otherwise

--*/
{
    NTSTATUS                        status   = STATUS_SUCCESS;
    PIO_STACK_LOCATION              irpStack = IoGetCurrentIrpStackLocation( Irp );
    PCM_RESOURCE_LIST               ResourceList;
    PCM_FULL_RESOURCE_DESCRIPTOR    FullResourceDescriptor;
    PCM_PARTIAL_RESOURCE_LIST       PartialResourceList;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResourceDescriptor;
    ULONG                           i;
    ULONG                           length;
    
    *FoundPort = FALSE;
    *FoundIrq  = FALSE;
    *FoundDma  = FALSE;
    
    ResourceList = irpStack->Parameters.StartDevice.AllocatedResourcesTranslated;
    
    FullResourceDescriptor = &ResourceList->List[0];
    
    if( FullResourceDescriptor ) {
        
        Fdx->InterfaceType = FullResourceDescriptor->InterfaceType;
        
        PartialResourceList = &FullResourceDescriptor->PartialResourceList;
        
        for (i = 0; i < PartialResourceList->Count; i++) {
            
            PartialResourceDescriptor = &PartialResourceList->PartialDescriptors[i];
            
            switch (PartialResourceDescriptor->Type) {
                
            case CmResourceTypePort:
                
                length = PartialResourceDescriptor->u.Port.Length;

                //
                // Use a heuristic based on length to guess which register set is
                //   SPP+EPP, which is ECP, and which is PCI Config or other.
                //
                switch( length ) {

                case 8: // SPP + EPP base address

                    Fdx->PortInfo.OriginalController = PartialResourceDescriptor->u.Port.Start;
                    Fdx->PortInfo.SpanOfController   = PartialResourceDescriptor->u.Port.Length;
                    Fdx->PortInfo.Controller         = (PUCHAR)(ULONG_PTR)Fdx->PortInfo.OriginalController.QuadPart;
                    Fdx->AddressSpace                = PartialResourceDescriptor->Flags;
                    *FoundPort = TRUE;
                    break;

                case 4: // ECP base address
                    
                    Fdx->PnpInfo.OriginalEcpController = PartialResourceDescriptor->u.Port.Start;
                    Fdx->PnpInfo.SpanOfEcpController   = PartialResourceDescriptor->u.Port.Length;
                    Fdx->PnpInfo.EcpController         = (PUCHAR)(ULONG_PTR)Fdx->PnpInfo.OriginalEcpController.QuadPart;
                    Fdx->EcpAddressSpace               = PartialResourceDescriptor->Flags;
                    break;

                default:
                    // don't know what this is - ignore it
                    ;
                }
                break;
                
            case CmResourceTypeBusNumber:
                
                Fdx->BusNumber = PartialResourceDescriptor->u.BusNumber.Start;
                break;
                
            case CmResourceTypeInterrupt:
                
                *FoundIrq = TRUE;
                Fdx->FoundInterrupt       = TRUE;
                Fdx->InterruptLevel       = (KIRQL)PartialResourceDescriptor->u.Interrupt.Level;
                Fdx->InterruptVector      = PartialResourceDescriptor->u.Interrupt.Vector;
                Fdx->InterruptAffinity    = PartialResourceDescriptor->u.Interrupt.Affinity;
                
                if (PartialResourceDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED) {
                    
                    Fdx->InterruptMode = Latched;
                    
                } else {
                    
                    Fdx->InterruptMode = LevelSensitive;
                }
                break;
                

⌨️ 快捷键说明

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