📄 ul_wdpnp.c
字号:
//// RETURNS://// STATUS_SUCCESS;//// IRQL:////// NOTES:///////////////////////////////////////////////////////////////////////////////////NTSTATUSStartDevice(IN PULAN_DEVICE_EXTENSION DevExt, IN PIO_STACK_LOCATION IoStackLocation){ NTSTATUS code = STATUS_SUCCESS; ULONG index; PDEVICE_DESCRIPTION deviceDescription; PCM_RESOURCE_LIST pResourceList, pResourceListTranslated; PCM_PARTIAL_RESOURCE_LIST prl, prlTranslated; PCM_PARTIAL_RESOURCE_DESCRIPTOR prd, prdTranslated; PCM_FULL_RESOURCE_DESCRIPTOR frd, frdTranslated; HANDLE regKeyHandle; PWCHAR dpHWID; ULONG dpHWID_len; PWCHAR pwc; pci_device_id_t *pci_device_id; usb_device_id_t *usb_device_id; int ChipOptions=0; ULONG uLanBaudrate=19200; ULONG uLanBaudBase=0; ULONG uLanMyAddress=2; pResourceList = IoStackLocation->Parameters.StartDevice.AllocatedResources; pResourceListTranslated = IoStackLocation->Parameters.StartDevice.AllocatedResourcesTranslated; // // Ensure the base address starts as NULL // ///DevExt->AmccBaseRegisterAddress = NULL; DevExt->port=0; DevExt->irq=0; // Try to find chip category from // IoGetDeviceProperty(DeviceObject,DeviceProperty,BufferLength,PropertyBuffer,ResultLength); // subfunctions DevicePropertyHardwareID and DevicePropertyLegacyBusType // uLan: HWID : PCI\VEN_1415&DEV_950A&SUBSYS_00001415&REV_00 // uLan: HWID : PCI\VEN_1415&DEV_950A&SUBSYS_00001415 // uLan: HWID : PCI\VEN_1415&DEV_950A&CC_070006 // uLan: HWID : PCI\VEN_1415&DEV_950A&CC_0700 dpHWID_len=0; code=IoGetDeviceProperty(DevExt->PhysicalDeviceObject, DevicePropertyHardwareID, 0,NULL,&dpHWID_len); if(dpHWID_len){ dpHWID=ExAllocatePool(PagedPool,dpHWID_len); if(dpHWID==NULL) return STATUS_INSUFFICIENT_RESOURCES; code=IoGetDeviceProperty(DevExt->PhysicalDeviceObject, DevicePropertyHardwareID, dpHWID_len,dpHWID,&dpHWID_len); if (!NT_SUCCESS(code)) { #if DBG uLan_DbgPrint("uLan: IoGetDeviceProperty failed with error 0x%x", code); #endif ExFreePool(dpHWID); return(code); } pwc=dpHWID; while(*pwc){ #if DBG uLan_DbgPrint("uLan: HWID : %ws\n", pwc); #endif while(*pwc) pwc++; pwc++; } if(FindPciHWID(dpHWID,&pci_device_id)){ ChipOptions=pci_device_id->driver_data; #if DBG uLan_DbgPrint("uLan: ChipOptions %08X\n", ChipOptions); #endif } if (FindUsbHWID(dpHWID, &usb_device_id)) { ChipOptions=usb_device_id->driver_info; DevExt->usb_bus=1; #if DBG uLan_DbgPrint("uLan: ChipOptions %08X\n", ChipOptions); #endif //create usb device usb_create_dev(&((usb_device*)DevExt->dev),DevExt->DeviceToSendIrpsTo); if ( !NT_SUCCESS( code)) { uLan_DbgPrint("uLan: error in create device\n"); return code; } //set configuration code = usb_set_configuration((usb_device*)DevExt->dev,1); if ( !NT_SUCCESS( code)) { uLan_DbgPrint("uLan: error in usb_set_configuration\n"); return code; } usb_show_device((usb_device*)DevExt->dev); } ExFreePool(dpHWID); } // // Read values from registry // code = IoOpenDeviceRegistryKey(DevExt->PhysicalDeviceObject, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_WRITE, ®KeyHandle); if(NT_SUCCESS(code)) { MyGetRegistryKeyValue (regKeyHandle,L"uLanBaudrate", &uLanBaudrate,sizeof(uLanBaudrate)); MyGetRegistryKeyValue (regKeyHandle,L"uLanBaudBase", &uLanBaudBase,sizeof(uLanBaudBase)); MyGetRegistryKeyValue (regKeyHandle,L"uLanMyAddress", &uLanMyAddress,sizeof(uLanMyAddress)); ZwClose (regKeyHandle); } if (!DevExt->usb_bus) { /* not for USB device, pResourceList is NULL */ frd = &pResourceList->List[0]; frdTranslated = &pResourceListTranslated->List[0]; prl = &frd->PartialResourceList; prlTranslated = &frdTranslated->PartialResourceList;#if DBG PrintResourceList(pResourceList); PrintResourceList(pResourceListTranslated);#endif // // Walk through the partial resource descriptors to find the // hardware resources that have been allocated to us // // We need one range of port addresses (0x08 bytes long) and // and interrupt resource. // for (index = 0, prd = &prl->PartialDescriptors[index], prdTranslated = &prlTranslated->PartialDescriptors[index]; index < prl->Count && NT_SUCCESS(code); index++, prd++, prdTranslated++) { switch (prd->Type) { case CmResourceTypePort: // // Newer AMCC Demo Boards have more than just one BAR // programmed in the PCI configuration ROM. We want // the FIRST BAR, which is the base address of the // device itself. So, we ignore any ports reported to // us after the first one. // ///if (DevExt->AmccBaseRegisterAddress) { if (DevExt->port) {#if DBG uLan_DbgPrint("uLan: Ignoring additional port resource ...\n"); if(prdTranslated->Type == CmResourceTypePort) { uLan_DbgPrint("uLan: (Translated port 0x%0x)\n", prdTranslated->u.Port.Start.LowPart); } else { uLan_DbgPrint("uLan: (Translated memory 0x%0x)\n", prdTranslated->u.Memory.Start); }#endif break; }#if DBG uLan_DbgPrint("uLan: Configuring port resource ...\n");#endif // // Should only get ONE port resources // ///ASSERT(DevExt->AmccBaseRegisterAddress == NULL); // // Our port space on this card is 0x40 bytes longs // ///ASSERT(prd->u.Memory.Length == 0x40); // // Do the device ports appear in port I/O space or // in memory space on this machine. // if(prdTranslated->Type == CmResourceTypePort) { // // The port is in port space on this machine. Just // store away the address // ///DevExt->MappedPorts = FALSE; ///DevExt->AmccBaseRegisterAddress = /// (PVOID) prdTranslated->u.Port.Start.LowPart; DevExt->port = prdTranslated->u.Port.Start.LowPart;#if DBG uLan_DbgPrint("uLan: Translated resource is a port at 0x%0x\n", DevExt->port);#endif } else { ASSERT(prdTranslated->Type == CmResourceTypeMemory); // // The port is in memory space on this machine. We // need to map some virtual addresses over the physical // address provided us, and remember to do an UNMAP // if/when we have to return the resources. // DevExt->MappedPorts = TRUE; ///DevExt->AmccBaseRegisterAddress = DevExt->port = (ULONG)MmMapIoSpace(prdTranslated->u.Memory.Start, DEF_PORT_RANGE, /*prdTranslated->u.Memory.Length,*/ MmNonCached);#if DBG uLan_DbgPrint("uLan: Translated resource is MEMORY at 0x%0x\n", DevExt->port);#endif } break; case CmResourceTypeInterrupt:#if DBG uLan_DbgPrint("uLan: Configuring Interrupt resource ...\n");#endif // // Be sure we get only ONE interrupt resource // ASSERT(DevExt->irq == 0); // // Again, assume that the translated and raw resources // are in the same order and number // ASSERT(CmResourceTypeInterrupt == prdTranslated->Type); ///DevExt->InterruptLevel = (UCHAR)prdTranslated->u.Interrupt.Level; ///DevExt->InterruptVector = prdTranslated->u.Interrupt.Vector; ///DevExt->InterruptAffinity = prdTranslated->u.Interrupt.Affinity; DevExt->Irql = (UCHAR)prdTranslated->u.Interrupt.Level; DevExt->irq = prdTranslated->u.Interrupt.Vector; DevExt->InterruptAffinity = prdTranslated->u.Interrupt.Affinity; if (prdTranslated->Flags & CM_RESOURCE_INTERRUPT_LATCHED) { DevExt->InterruptMode = Latched; } else { DevExt->InterruptMode = LevelSensitive; } // // Because this is a PCI device, we KNOW it must be // a LevelSensitive Interrupt // ///ASSERT(DevExt->InterruptMode == LevelSensitive);#if DBG uLan_DbgPrint("uLan: Interrupt level: 0x%0x, Vector: 0x%0x, Affinity: 0x%0x\n", DevExt->Irql, DevExt->irq, DevExt->InterruptAffinity);#endif break; default:#if DBG uLan_DbgPrint("uLan: Unhandled Resource -- CmResourceType received 0x%x\n", prd->Type);#endif break; } } // // We NEED the interrupt info AND one port // if(!DevExt->irq || !DevExt->port){ uLan_DbgPrint("uLan: Port (0x%0lX) or Irq (%d) undefined\n", DevExt->port,DevExt->irq); return STATUS_UNSUCCESSFUL; } } // // Register our DPCforISR routine. This is the routine which will // be used to complete our interrupt processing. // ///IoInitializeDpcRequest(DevExt->DeviceObject, DpcForIsr); KeInitializeDpc(&DevExt->bottom_dpc,ulan_bottom_dpc,DevExt); KeInitializeDpc(&DevExt->wd_timer_dpc,ulan_wd_dpc,DevExt); KeInitializeTimer(&DevExt->wd_timer); // Increase spinlock level if(uL_SpinLock_Irql<DevExt->Irql) uL_SpinLock_Irql=DevExt->Irql; uLan_DbgPrint("uLan: spin lock irql=%d\n",uL_SpinLock_Irql); if (!DevExt->usb_bus) { // // Connect to interrupt from the device. After this call, // interrupts from the device will result in calls to our uLan HandleInterrupt // function. // code = IoConnectInterrupt(&DevExt->InterruptObject, uld_irq_handler, // ServiceRoutine DevExt, // ServiceContext NULL, // SpinLock DevExt->irq, // Vector DevExt->Irql, // Irql DevExt->Irql, // SynchronizeIrql DevExt->InterruptMode, // InterruptMode TRUE, // ShareVector DevExt->InterruptAffinity, // ProcessorEnableMask FALSE); // FloatingSave if (!NT_SUCCESS(code)) { #if DBG uLan_DbgPrint("uLan: IoConnectInterrupt failed with error 0x%x", code); #endif // // We're outa here // return(code); } } // // Now we are ready to start uLan communication. // ///ResetAdapter(DevExt->DeviceObject, FALSE); DevExt->baud_val=(int)uLanBaudrate; DevExt->baud_base=(int)uLanBaudBase; DevExt->my_adr=(int)uLanMyAddress; #if DBG uLan_DbgPrint("uLan: uLanBaudrate:%d, uLanMyAddress:%d\n",DevExt->baud_val,DevExt->my_adr); #endif if(DevExt->State==STATE_NEVER_STARTED) { #if DBG uLan_DbgPrint("uLan: StartDevice: Calling ul_drv_init_ext\n"); #endif code = ul_drv_init_ext(DevExt, DevExt->port, DevExt->irq, (int)uLanBaudrate, uLanBaudBase, ChipOptions, /*buffer_size*/ 0x10000, (int)uLanMyAddress); }else{ #if DBG uLan_DbgPrint("uLan: StartDevice: Calling ul_drv_new_start\n"); #endif ul_drv_new_init_state(DevExt,(int)uLanMyAddress); if(ul_drv_new_start(DevExt,0x10000)<0) code = STATUS_INSUFFICIENT_RESOURCES; else code = STATUS_SUCCESS; } if(!NT_SUCCESS(code)) { #if DBG uLan_DbgPrint("uLan: StartDevice: Start of hardware failed\n"); #endif IoDisconnectInterrupt(DevExt->InterruptObject); DevExt->InterruptObject = NULL; ul_drv_done_ext(DevExt); } return code;}/////////////////////////////////////////////////////////////////////////////////// CanStopDevice//// This routine determines if the device cab be safely stopped. In// our case we'll assume you can always stop the device. A device// might not be able to be stopped, for example, if it doesn't have// a queue for incoming requests or if it was notified that it is// in the paging path.//// INPUTS://// devExt - Address of our device extension.// Irp - Address of the input IRP.//// OUTPUTS://// None.//// RETURNS://// STATUS_SUCCESS;//// IRQL:////// NOTES:///////////////////////////////////////////////////////////////////////////////////NTSTATUS CanStopDevice(PULAN_DEVICE_EXTENSION devExt, PIRP Irp){ UNREFERENCED_PARAMETER(devExt); UNREFERENCED_PARAMETER(Irp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -