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

📄 genport.c

📁 win2000下
💻 C
📖 第 1 页 / 共 5 页
字号:
    }

    deviceInfo = (PLOCAL_DEVICE_INFO) deviceObject->DeviceExtension;//提取设备信息(包括地址:地址范围等)
    RtlZeroMemory(deviceInfo, sizeof(LOCAL_DEVICE_INFO));

//    deviceInfo->DeviceObject = deviceObject;

	RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);//#define DOS_DEVICE_NAME L"\\DosDevices\\GpdDev"
	DebugPrint((">>> win32DeviceName.Buffer=%s \n",win32DeviceName.Buffer));

    status = IoCreateSymbolicLink( &win32DeviceName, &ntDeviceName );//在设备和用户可见设备名之间建立连接

    if (!NT_SUCCESS(status))    // If we we couldn't create the link then
    {                           //  abort installation.
        IoDeleteDevice(deviceObject);
        return status;
    }

	DebugPrint((">>> PortAddr=%X PortCount=%d\n",
		(unsigned int)deviceInfo->PortBase ,
		deviceInfo->PortCount ));
	DebugPrint((">>> PortMemyType=%d \n",
		(unsigned int)deviceInfo->PortMemoryType   ));
/*    deviceInfo->NextLowerDriver = IoAttachDeviceToDeviceStack (//把deviceObject 附属到 物理设备PhysicalDeviceObject上
                                       deviceObject,
                                       PhysicalDeviceObject);//PhysicalDeviceObject是入口参数
    if(NULL == deviceInfo->NextLowerDriver) {
        IoDeleteSymbolicLink(&win32DeviceName);
        IoDeleteDevice(deviceObject);
        return STATUS_NO_SUCH_DEVICE;
    }
*/
    IoInitializeRemoveLock (&deviceInfo->RemoveLock , 
                            PORTIO_TAG,
                            1, // MaxLockedMinutes 
                            5); // HighWatermark, this parameter is 
                                // used only on checked build.
    //
    // Set the flag if the device is not holding a pagefile
    // crashdump file or hibernate file. 
    // 
    
//    deviceObject->Flags |=  DO_POWER_PAGABLE;

    deviceInfo->DeviceObject = deviceObject;//deviceInfo就是我们自己定义的设备参数(地址,地址空间等)
    deviceInfo->Removed = FALSE;
    deviceInfo->Started = FALSE;

//    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    //
    // This values is based on the hardware design.
    // Let us assume the address is in I/O space. 
    //
    deviceInfo->PortMemoryType = 0;//存贮器访问 20060216 

//    DebugPrint(("AddDevice: %p to %p->%p \n", deviceObject, 
//                       deviceInfo->NextLowerDriver,
//                       PhysicalDeviceObject));
	//-------------------------结束 设备创建-----------------------------------------

	//----------------查找PCI分配的954IO地址-----------------------------------------
    //
    // Ask the I/O Manager to use describe user read/write buffers using MDLs
    //
    deviceObject->Flags |= DO_BUFFERED_IO;//20060217 内存访问

    //
    // Next, get the HAL to tell us about the resources the device will use. 
    // These resources include ports, shared memory regions, interrupts, and
    // the like.  The resources will be resevered for us in the registry (so
    // we do not have to call either IoReportResourceUsage or IoAssignResources).
    //
    deviceInfo->BusNumber = busNumber-1;
    deviceInfo->SlotNumber = slotNumber;
    status = HalAssignSlotResources(RegistryPath,
                                  NULL,
                                  DriverObject,
                                  NULL,//deviceObject 20060317
                                  PCIBus,
                                  deviceInfo->BusNumber,
                                  deviceInfo->SlotNumber.u.AsULONG,
                                  &resources);

    //
    // On return from this call, all resources are identified and assigned for
    // use by our device.
    //
    if (!NT_SUCCESS(status)) {

        //
        // log an appropriate error string.
        //
#if DBG
        DbgPrint("HalAssignSlotResourced failed!  Status = 0x%0x", status);
#endif        
        //
        // Clean up the mess
        //
		if(configInfo)
			ExFreePool(configInfo);


		if(resources)
			ExFreePool(resources);

//        OsrUnload(DriverObj);

        //
        // Indicate load failure to the I/O manager
        //
        return(status);
    }

#if DBG
    //
    // For curiosity and debugging purposes, display the resources that were
    // allocated for our use.
    //
//    OsrPrintResourceList(resources);
        
    DbgPrint("%d. resource descriptor list(s) returned\n", resources->Count);

    for (index = 0; index < resources->Count; index++)  {
        
        DbgPrint("\t[%d] Interface Type 0x%x\n",
                index, resources->List[index].InterfaceType);
        DbgPrint("\t[%d] BusNumber 0x%x\n",
                index, resources->List[index].BusNumber);
        DbgPrint("\t[%d] Version 0x%x\n",
                index, resources->List[index].PartialResourceList.Version);
        DbgPrint("\t[%d] Revision 0x%x\n",
                index, resources->List[index].PartialResourceList.Revision);
        
        DbgPrint("\t[%d] Partial Resource Descriptors %d.\n",
                index, resources->List[index].PartialResourceList.Count);
        for (index2 = 0;
            index2 < resources->List[index].PartialResourceList.Count;
            index2++)  {

            PCM_PARTIAL_RESOURCE_DESCRIPTOR prd; // Too much to type!
            
            prd = &resources->List[index].PartialResourceList.PartialDescriptors[index2];

            DbgPrint("\t\t[%d] Type 0x%x (%s)\n",
                    index2, prd->Type, CmResourceTypeStrings[prd->Type]);
            DbgPrint("\t\t[%d] Share Disposition 0x%x (%s)\n",
                    index2, prd->ShareDisposition,
                    CmShareDispositionStrings[prd->ShareDisposition]);
            DbgPrint("\t\t[%d] Flags 0x%x\n", index2, prd->Flags);
            DbgPrint("\t\t[%d] Raw 0x%x %x %x\n",
                    index2, prd->u.DeviceSpecificData.DataSize,
                    prd->u.DeviceSpecificData.Reserved1,
                    prd->u.DeviceSpecificData.Reserved2);

            switch (prd->Type) {
                
                case CmResourceTypePort:
                    if (prd->Flags == CM_RESOURCE_PORT_MEMORY)
                        DbgPrint("\t\t[%d] port memory starting at 0x%x length 0x%x\n", 
                                      index2, prd->u.Port.Start.LowPart,
                                      prd->u.Port.Length);
                    if (prd->Flags == CM_RESOURCE_PORT_IO)
                       DbgPrint("\t\t[%d] port i/o starting at 0x%x length 0x%x\n", 
                                     index2, prd->u.Port.Start.LowPart,
                                     prd->u.Port.Length);
                    break;

                case CmResourceTypeInterrupt:
                    if (prd->Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE)
                        DbgPrint("\t\t[%d] level interrupt at lvl 0x%x vector 0x%x affinity 0x%x\n", 
                                     index2, prd->u.Interrupt.Level,
                                     prd->u.Interrupt.Vector,
                                     prd->u.Interrupt.Affinity);
                    if (prd->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
                        DbgPrint("\t\t[%d] latched interrupt at lvl 0x%x vector 0x%x affinity 0x%x\n", 
                                     index2, prd->u.Interrupt.Level,
                                     prd->u.Interrupt.Vector,
                                     prd->u.Interrupt.Affinity);
                    break;

                case CmResourceTypeMemory:
                    if (prd->Flags == CM_RESOURCE_MEMORY_READ_WRITE)
                        DbgPrint("\t\t[%d] r/w memory starting at 0x%x length 0x%x\n",
                                 index2, prd->u.Memory.Start.LowPart,
                                 prd->u.Memory.Length);
                    if (prd->Flags & CM_RESOURCE_MEMORY_READ_ONLY)
                        DbgPrint("\t\t[%d] r/o memory starting at 0x%x length 0x%x\n",
                                 index2, prd->u.Memory.Start.LowPart,
                                 prd->u.Memory.Length);
                    if (prd->Flags & CM_RESOURCE_MEMORY_WRITE_ONLY)
                        DbgPrint("\t\t[%d] w/o memory starting at 0x%x length 0x%x\n",
                                 index2, prd->u.Memory.Start.LowPart,
                                 prd->u.Memory.Length);
                    break;

                case CmResourceTypeDma:
                    DbgPrint("\t\t[%d] DMA on channel 0x%x\n",
                        index2, prd->u.Dma.Channel);
                    break;

                case CmResourceTypeDeviceSpecific:
                    DbgPrint("\t\t[%d] Device specific data at 0x%x length 0x%x\n",
                                 index2,
                                 ((ULONG) &prd->u.DeviceSpecificData.Reserved2) + (ULONG)sizeof(ULONG),
                                 prd->u.DeviceSpecificData.DataSize);
                    break;

                default:
                    //
                    // Say what?!!  Unknown resource type.  Something is pretty wierd here.
                    //
                    DbgPrint("Unknown resource type 0x%x\n", prd->Type);
                    break;
            }
            
        }
            DbgPrint("\t[%d] ***** End dump ******\n", index);
    }

    portStart.LowPart = 0;
    portLength = 0;
    interruptLevel = 0;
    interruptVector = 0;

#endif
    
    //
    // Decode the returned resources
    //
    // For our device, we know to expect an interrupt resource, and ONE set
    // I/O space port resources.  We expect, and we attempt to handle, no
    // other resources.
    //
    for (index = 0; index < resources->Count; index++)  {
        
        for (index2 = 0;
             index2 < resources->List[index].PartialResourceList.Count;
             index2++) {

            PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
            
            prd = &resources->List[index].PartialResourceList.PartialDescriptors[index2];

            switch (prd->Type) {
                
                case CmResourceTypePort:

                    //
                    // Our port resources are in I/O space.  And our port
                    // space is 64. bytes long.
                    //
//                    ASSERT(prd->Flags == CM_RESOURCE_PORT_IO);
//                    ASSERT(prd->u.Port.Length == 64);

                    portStart.HighPart = 0;
                    portStart.LowPart  =  prd->u.Port.Start.LowPart;
                    portLength =  prd->u.Port.Length;
                    break;

                case CmResourceTypeInterrupt:

                    //
                    // PCI interrupts are level sensitive
                    //
                    ASSERT(prd->Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE);

                    interruptLevel = prd->u.Interrupt.Level;
                    interruptVector = prd->u.Interrupt.Vector;
                    if (prd->Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE)
                        DbgPrint("\t\t[%d] level interrupt at lvl 0x%x vector 0x%x affinity 0x%x\n", 
                                     index2, prd->u.Interrupt.Level,
                                     prd->u.Interrupt.Vector,
                                     prd->u.Interrupt.Affinity);
                    if (prd->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
                        DbgPrint("\t\t[%d] latched interrupt at lvl 0x%x vector 0x%x affinity 0x%x\n", 
                                     index2, prd->u.Interrupt.Level,
                                     prd->u.Interrupt.Vector,
                                     prd->u.Interrupt.Affinity);
                    break;

#if DBG
                case CmResourceTypeMemory:
                    portStart  =  prd->u.Memory.Start;
                    portLength =  prd->u.Memory.Length;
                    DbgPrint("...Unexpected memory resource!\n");
                    DbgPrint("\t\tCmResourceTypeMemory[%d] memory starting at 0x%x length 0x%x\n",
                                 index2, prd->u.Memory.Start.LowPart,
                                 prd->u.Memory.Length);
                    break;

                case CmResourceTypeDma:
                    DbgPrint("...Unexpected DMA resource!\n");
                    break;

                case CmResourceTypeDeviceSpecific:
                    DbgPrint("...Unexpected device specific resource!\n");
                    break;
#endif
                default:
                    DbgPrint("Unexpected and unknown resource type\n");
                    break;
            }
            
        }

    }
    //
    // We NEED the interrupt info AND one port
    //
    ASSERT(interruptLevel && interruptVector && portStart.LowPart && portLength);

    //
    // Indciate that the resigsters are in port space on this card
    //
//    addressSpace = 0x01;//原来的程序
    addressSpace = 0x00;//20060217 内存空间
    //
    // Get the HAL to translate our bus-relative port base address, to an
    // unambiguous address to be used for device access.  If we're returned
    // FALSE, the call failed.
    //
    if (!HalTranslateBusAddress(PCIBus,
                               deviceInfo->BusNumber,
                               portStart,
                               &addressSpace,
                               &address))  {
        //
        // Print an appropriate error string.
        //
#if DBG
        DbgPrint("HalAssignSlotResourced failed\n");
#endif

        //
        // Clean up the mess
        //
//        OsrReturnPool(configInfo, deviceDescription, resources);
		if(configInfo)
			ExFreePool(configInfo);


		if(resources)
			ExFreePool(resources);

//        OsrUnload(DriverObj);

        //
        //
        return(STATUS_UNSUCCESSFUL);
    }
    
    //
    // If this card's I/O space registers actually appear in memory space on
    // this processor, we need to map them with some kernel virtual addresses
    // so we can access them. This may be the case on, for example, some RISC
    // processors. NOTE HOWEVER, that regardless of the addressSpace returned,
    // since the registers on the card are in PORT I/O space, we will ALWAYS
    // access them in the driver using WRITE_PORT_xxx and READ_PORT_xxx.
    //
    if (addressSpace == 0x0) {
        ULONG lengthInBytes;

#if DBG
        DbgPrint("Address space for port is MEMORY\n");
#endif

        lengthInBytes =
           resources->List[0].PartialResourceList.PartialDescriptors[2].u.Memory.Length;

        DbgPrint("lengthInBytes = 0x%X\n",lengthInBytes);
        //
        // Maps a potentially 64 bit physical address to a 32 bit virtual address.
        //
        deviceInfo->PortBase = MmMapIoSpace(address,
                                                       lengthInBytes,
                                                       FALSE);
		deviceInfo->PortCount = lengthInBytes;
        deviceInfo->PortWasMapped = TRUE;
		DebugPrint(("deviceInfo = 0x%X PortBase = 0x%X length 0x%X",deviceInfo,deviceInfo->PortBase,deviceInfo->PortCount));
		//找到内存映射地址之后初始化相关参数
		for(i = 0;i < COM_NUM;i ++)
		{
			for(j = 0;j < 2;j++)
			{
				deviceInfo->BufBase     [j][i] = (PVOID)((ULONG)deviceInfo->PortBase + (ULONG)BUFBASE[j][i]);
				deviceInfo->PtrBuf		[j][i] = deviceInfo->BufBase     [j][i];
				deviceInfo->DataNumBase [j][i] = (PVOID)((ULONG)deviceInfo->PortBase + (ULONG)NUMBASE[j][i]);
				KeInitializeSemaphore(&deviceInfo->BufSemaphore[j][i], 1, 1);

⌨️ 快捷键说明

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