| 45,6 → 45,8 |
| //------------------------------------------------------------------------ |
| // DEFINES |
| // |
| #define arraysize(p) (sizeof(p)/sizeof((p)[0])) |
| |
| #ifndef DWORD |
| #define DWORD ULONG |
| #endif |
| 131,12 → 133,20 |
| { |
| int i; |
| UNICODE_STRING symbol_name; |
| if (!driverObj->DeviceObject) { |
| KdPrint(("PCIVMEUnload() DeviceObject does not exist \n")); |
| return; |
| } |
| DEVICE_EXT *ext = (DEVICE_EXT*)(driverObj->DeviceObject->DeviceExtension); |
| int nPCIADAs = ext->nPCIADAs; |
| PCIADA *pciada; |
| |
| KdPrint(("PCIVMEUnload()\n")); |
| KdPrint(("PCIVMEUnload() InitState %d \n", ext->nInitState )); |
| |
| //if (ext->LowerDeviceObject) IoDetachDevice(ext->LowerDeviceObject); |
| //IoDeleteDevice(driverObj->DeviceObject); |
| if (ext->nInitState!=100) return; |
| |
| switch (ext->nInitState) |
| { |
| case 8: |
| 183,7 → 193,7 |
| case 2: |
| // HalTranslateBusAddress has no counterpart |
| case 1: |
| PCIVMEFreeResources(driverObj->DeviceObject); |
| // PCIVMEFreeResources(driverObj->DeviceObject); // not used in pnp |
| default: |
| case 0: |
| RtlInitUnicodeString(&symbol_name, DOS_DEVICE_NAME); |
| 192,9 → 202,10 |
| IoDeleteSymbolicLink( &symbol_name); |
| |
| // delete the deviceObject |
| if (ext->LowerDeviceObject) IoDetachDevice(ext->LowerDeviceObject); |
| IoDeleteDevice(driverObj->DeviceObject); |
| } |
| |
| |
| KdPrint(("PCIVMEUnload() OK.\n")); |
| } |
| |
| 631,7 → 642,7 |
| } |
| } |
| } |
| |
| KdPrint(("SearchDevices() found %d devices\n", (*found))); |
| return STATUS_SUCCESS; |
| } |
| |
| 640,6 → 651,7 |
| // |
| NTSTATUS PLX9050BugFix(PDEVICE_OBJECT device_Obj) |
| { |
| // http://permalink.gmane.org/gmane.linux.kernel.pci/18419 |
| DEVICE_EXT *DeviceExtension = (DEVICE_EXT*)device_Obj->DeviceExtension; |
| int i; |
| ULONG dwData; |
| 701,15 → 713,74 |
| return STATUS_SUCCESS; |
| } |
| |
| static VOID ShowResources(IN PCM_PARTIAL_RESOURCE_LIST list) |
| { // ShowResources |
| PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = list->PartialDescriptors; |
| ULONG nres = list->Count; |
| ULONG i; |
| |
| for (i = 0; i < nres; ++i, ++resource) |
| { // for each resource |
| ULONG type = resource->Type; |
| |
| static char* namelow[] = { |
| "CmResourceTypeNull",// 0 // ResType_All or ResType_None (0x0000) |
| "CmResourceTypePort",// 1 // ResType_IO (0x0002) |
| "CmResourceTypeInterrupt",// 2 // ResType_IRQ (0x0004) |
| "CmResourceTypeMemory",// 3 // ResType_Mem (0x0001) |
| "CmResourceTypeDma",// 4 // ResType_DMA (0x0003) |
| "CmResourceTypeDeviceSpecific",// 5 // ResType_ClassSpecific (0xFFFF) |
| "CmResourceTypeBusNumber",// 6 // ResType_BusNumber (0x0006) |
| "CmResourceTypeMemoryLarge" // 7 // ResType_MemLarge (0x0007) |
| }; |
| static char* namehigh[] = { |
| //"CmResourceTypeNonArbitrated" ,// 128 // Not arbitrated if 0x80 bit set |
| "CmResourceTypeConfigData",// 128 // ResType_Reserved (0x8000) |
| "CmResourceTypeDevicePrivate",// 129 // ResType_DevicePrivate (0x8001) |
| "CmResourceTypePcCardConfig",// 130 // ResType_PcCardConfig (0x8002) |
| "CmResourceTypeMfCardConfig",// 131 // ResType_MfCardConfig (0x8003) |
| "CmResourceTypeConnection" // 132 // ResType_Connection (0x8004) |
| }; |
| |
| if (type<8) KdPrint((" [%d] type %s", type, type < arraysize(namelow) ? namelow[type] : "unknown")); |
| if (type>127) KdPrint((" [%d] type %s", type, type-128 < arraysize(namehigh) ? namehigh[type-128] : "unknown")); |
| switch (type) |
| { // select on resource type |
| case CmResourceTypePort: |
| KdPrint((" start ADDR=0x%p 0x%8X%8.8lX length %X\n", |
| resource->u.Port.Start, resource->u.Port.Start.HighPart, resource->u.Port.Start.LowPart, |
| resource->u.Port.Length)); |
| break; |
| case CmResourceTypeMemory: |
| KdPrint((" %d start ADDR=0x%p \n", i, resource->u.Memory.Start )); |
| break; |
| |
| case CmResourceTypeInterrupt: |
| KdPrint((" IRQL %d, vector %d, affinity %d\n", |
| resource->u.Interrupt.Level, resource->u.Interrupt.Vector, |
| resource->u.Interrupt.Affinity)); |
| break; |
| |
| case CmResourceTypeDma: |
| KdPrint((" channel %d, port %X\n", |
| resource->u.Dma.Channel, resource->u.Dma.Port)); |
| |
| |
| |
| } // select on resource type |
| } // for each resource |
| } // ShowResources |
| |
| |
| //------------------------------------------------------------------------ |
| // reserve resources for PCIADAs |
| // |
| NTSTATUS PCIVMEExtractResources(PCIADA *pciada, PCM_RESOURCE_LIST pList) |
| NTSTATUS PCIVMEExtractResources(PCIADA *pciada, PIRP irp) |
| { |
| PCM_RESOURCE_LIST pResourceList; |
| PCM_FULL_RESOURCE_DESCRIPTOR pFullDescriptor; |
| PCM_PARTIAL_RESOURCE_LIST pPartialList; |
| //PCM_RESOURCE_LIST pResourceList; |
| ///PCM_FULL_RESOURCE_DESCRIPTOR pFullDescriptor; |
| PCM_PARTIAL_RESOURCE_LIST pPartialList = NULL; |
| PCM_PARTIAL_RESOURCE_LIST pListTranslated = NULL; |
| PCM_PARTIAL_RESOURCE_DESCRIPTOR pPartialDescriptor; |
| int i; |
| int bug = 0; |
| 716,13 → 787,20 |
| |
| KdPrint(("PCIVMEExtractResources()\n")); |
| |
| pResourceList = pList; |
| pFullDescriptor = pResourceList->List; |
| pPartialList = &pFullDescriptor->PartialResourceList; |
| |
| ///pResourceList = pList; |
| ///pFullDescriptor = pResourceList->List; |
| ///pPartialList = &pFullDescriptor->PartialResourceList; |
| PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(irp); |
| if (stack->Parameters.StartDevice.AllocatedResources) |
| pPartialList = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList; |
| KdPrint(("Allocated Resources:------------------\n")); |
| ShowResources(pPartialList); |
| |
| int plcount = 0; |
| for (i=0; i<(int)pPartialList->Count; i++) |
| { |
| pPartialDescriptor = &pPartialList->PartialDescriptors[i]; |
| |
| switch (pPartialDescriptor->Type) |
| { |
| case CmResourceTypeInterrupt: |
| 730,15 → 808,15 |
| pciada->Vector = pPartialDescriptor->u.Interrupt.Vector; |
| pciada->Affinity = pPartialDescriptor->u.Interrupt.Affinity; |
| |
| KdPrint(("Irq : Irql: %d, Vector: %d, Affinity: %d\n", |
| KdPrint(("AllocatedResources Irq : Irql: %d, Vector: %d, Affinity: %d\n", |
| pciada->Irql, pciada->Vector, pciada->Affinity)); |
| break; |
| case CmResourceTypeDma: |
| KdPrint(("Dma : \n")); |
| KdPrint(("AllocatedResources Dma : \n")); |
| break; |
| case CmResourceTypePort: |
| |
| KdPrint(("Port : 0x%p\n", pPartialDescriptor->u.Port.Start)); |
| KdPrint(("AllocatedResources Port : 0x%p\n", pPartialDescriptor->u.Port.Start)); |
| break; |
| case CmResourceTypeMemory: |
| // special handling of PLXBUG here because of WIN2000 |
| 745,39 → 823,108 |
| // WIN2000 doesn't recognize late address changes |
| if (!bug) |
| { |
| if (i == 0) |
| if (plcount == 0) |
| { |
| pciada->pvPhysLcr = pPartialDescriptor->u.Memory.Start; |
| |
| if (pciada->pvPhysLcr.LowPart & 0x80) |
| if (pciada->pvPhysLcr.LowPart & 0x80) { |
| bug = 1; |
| KdPrint(("AllocatedResources PLXBug\n")); |
| } |
| } |
| } |
| else |
| { |
| if (i == 3) |
| if (plcount == 3) |
| pciada->pvPhysLcr = pPartialDescriptor->u.Memory.Start; |
| } |
| |
| if (i == 2) |
| if (plcount == 2){ |
| pciada->pvPhysIfr = pPartialDescriptor->u.Memory.Start; |
| |
| KdPrint(("Memory : 0x%p\n", (PUCHAR)pPartialDescriptor->u.Memory.Start.LowPart)); |
| KdPrint(("PCIVMEExtractResources() IFR=0x%p \n", pciada->pvPhysIfr)); |
| } |
| KdPrint(("[%d] AllocatedResources Memory : 0x%p\n", plcount, (PUCHAR)pPartialDescriptor->u.Memory.Start.LowPart)); |
| break; |
| } |
| if (pPartialDescriptor->Type < 8) plcount++; |
| } |
| |
| KdPrint(("PCIVMEExtractResources() LCR=0x%p IFR=0x%p \n", pciada->pvPhysLcr, pciada->pvPhysIfr)); |
| |
| if (stack->Parameters.StartDevice.AllocatedResourcesTranslated) |
| pListTranslated = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList; |
| KdPrint(("Translated Resources:------------------\n")); |
| ShowResources(pListTranslated); |
| plcount = 0; |
| bug = 0; |
| for (i = 0; i<(int)pPartialList->Count; i++) |
| { |
| pPartialDescriptor = &pListTranslated->PartialDescriptors[i]; |
| |
| switch (pPartialDescriptor->Type) |
| { |
| case CmResourceTypeInterrupt: |
| pciada->Irql = (KIRQL)pPartialDescriptor->u.Interrupt.Level; |
| pciada->Vector = pPartialDescriptor->u.Interrupt.Vector; |
| pciada->Affinity = pPartialDescriptor->u.Interrupt.Affinity; |
| |
| KdPrint(("AllocatedResourcesTranslated Irq : Irql: %d, Vector: %d, Affinity: %d\n", |
| pciada->Irql, pciada->Vector, pciada->Affinity)); |
| break; |
| case CmResourceTypeDma: |
| KdPrint(("AllocatedResourcesTranslated Dma : \n")); |
| break; |
| case CmResourceTypePort: |
| |
| KdPrint(("AllocatedResourcesTranslated Port : 0x%p\n", pPartialDescriptor->u.Port.Start)); |
| break; |
| case CmResourceTypeMemory: |
| // special handling of PLXBUG here because of WIN2000 |
| // WIN2000 doesn't recognize late address changes |
| if (!bug) |
| { |
| if (plcount == 0) |
| { |
| pciada->pvPhysLcr = pPartialDescriptor->u.Memory.Start; |
| KdPrint(("0 PCIVMEExtractResources() LCR=0x%p \n", pciada->pvPhysLcr)); |
| if (pciada->pvPhysLcr.LowPart & 0x80) { |
| bug = 1; |
| KdPrint(("AllocatedResourcesTranslated PLXBug\n")); |
| } |
| } |
| } |
| else |
| { |
| if (plcount == 3){ |
| pciada->pvPhysLcr = pPartialDescriptor->u.Memory.Start; |
| KdPrint(("3 PCIVMEExtractResources() LCR=0x%p \n", pciada->pvPhysLcr)); |
| } |
| } |
| |
| if (plcount == 2){ |
| pciada->pvPhysIfr = pPartialDescriptor->u.Memory.Start; |
| KdPrint(("2 PCIVMEExtractResources() IFR=0x%p \n", pciada->pvPhysIfr)); |
| } |
| |
| KdPrint(("[%d] AllocatedResourcesTranslated Memory : 0x%p\n", plcount, (PUCHAR)pPartialDescriptor->u.Memory.Start.LowPart)); |
| break; |
| } |
| if (pPartialDescriptor->Type < 8) plcount++; |
| } |
| |
| |
| |
| if (pciada->Irql == 0) |
| return STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT; |
| |
| KdPrint(("PCIVMEExtractResources() OK.\n")); |
| KdPrint(("PCIVMEExtractResources() Translated LCR=0x%p IFR=0x%p \n", pciada->pvPhysLcr, pciada->pvPhysIfr)); |
| |
| return STATUS_SUCCESS; |
| } |
| |
| NTSTATUS PCIVMEReserveResources(PDEVICE_OBJECT device_Obj) |
| NTSTATUS PCIVMEReserveResources(PDEVICE_OBJECT device_Obj, PIRP irp) |
| { |
| PCM_RESOURCE_LIST pList = NULL; |
| //PCM_RESOURCE_LIST pList = NULL; |
| NTSTATUS result = STATUS_SUCCESS; |
| int i; |
| DEVICE_EXT *pDevExt = (DEVICE_EXT*)(device_Obj->DeviceExtension); |
| 788,27 → 935,32 |
| KdPrint(("PCIVMEReserveResources()\n")); |
| |
| // prepare resource claiming |
| RtlInitUnicodeString(&DriverClassName, L"PCICC32"); |
| |
| //RtlInitUnicodeString(&DriverClassName, L"PCICC32"); |
| RtlInitUnicodeString(&DriverClassName, L"PCIVME"); |
| // cycle through all busses and slots assigned to PCIADAs |
| for (i = 0; i < nPCIADAs; i++) |
| { |
| pciada = &pDevExt->pciada[i]; |
| |
| result = HalAssignSlotResources(NULL, &DriverClassName, device_Obj->DriverObject, device_Obj, |
| PCIBus, pciada->Bus, pciada->Slot.u.AsULONG, &pList); |
| |
| if (result != STATUS_SUCCESS) |
| //result = HalAssignSlotResources(NULL, &DriverClassName, device_Obj->DriverObject, device_Obj, |
| // PCIBus, pciada->Bus, pciada->Slot.u.AsULONG, &pList); |
| /* |
| result = IoReportDetectedDevice(device_Obj->DriverObject, PCIBus, pciada->Bus, pciada->Slot.u.AsULONG, pList, NULL, FALSE, &device_Obj); |
| if (result != STATUS_SUCCESS){ |
| KdPrint(("PCIVMEReserveResources(0x%08x) HalAssignSlotResources ***ERROR*** faliure to get slot information\n", result)); |
| break; |
| } |
| */ |
| result = PCIVMEExtractResources(pciada, irp); |
| |
| result = PCIVMEExtractResources(pciada, pList); |
| |
| if (result != STATUS_SUCCESS) |
| if (result != STATUS_SUCCESS){ |
| KdPrint(("PCIVMEReserveResources(0x%08x) PCIVMEExtractResources\n", result)); |
| break; |
| } |
| } |
| |
| // its my part to free allocated resources |
| if (pList != NULL) ExFreePoolWithTag(pList,'nepo'); |
| //if (pList != NULL) ExFreePoolWithTag(pList,'nepo'); |
| |
| KdPrint(("PCIVMEReserveResources(0x%08x)\n", result)); |
| |
| 841,7 → 993,7 |
| //------------------------------------------------------------------------ |
| // translate memory resources to neutral for PCIADAs |
| // |
| NTSTATUS PCIVMETranslateBusAddresses(PDEVICE_OBJECT device_Obj) |
| NTSTATUS PCIVMETranslateBusAddresses(PDEVICE_OBJECT device_Obj, PIRP irp) |
| { |
| int i; |
| NTSTATUS result = STATUS_SUCCESS; |
| 848,14 → 1000,18 |
| int nPCIADAs = ((DEVICE_EXT*)(device_Obj->DeviceExtension))->nPCIADAs; |
| ULONG memType0, memType2; |
| PCIADA *pciada; |
| PCM_PARTIAL_RESOURCE_LIST pPartialList = NULL; |
| PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(irp); |
| if (stack->Parameters.StartDevice.AllocatedResourcesTranslated) |
| pPartialList = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList; |
| |
| KdPrint(("TranslateBusAddresseses()\n")); |
| |
| for (i = 0; i < nPCIADAs; i++) |
| { |
| pciada = &((DEVICE_EXT*)(device_Obj->DeviceExtension))->pciada[i]; |
| |
| memType0 = memType2 = 0; |
| |
| /* |
| if (!(HalTranslateBusAddress(PCIBus, pciada->Bus, pciada->pvPhysLcr, &memType0, |
| &pciada->pvPhysLcr)) || |
| !(HalTranslateBusAddress(PCIBus, pciada->Bus, pciada->pvPhysIfr, &memType2, |
| 864,6 → 1020,8 |
| result = STATUS_UNSUCCESSFUL; |
| break; |
| } |
| */ |
| KdPrint(("PCIADA %d TranslateBusAddresseses() -- no translation is made\n", i)); |
| |
| if ((memType0) || (memType2)) |
| { |
| 871,6 → 1029,7 |
| break; |
| } |
| } |
| |
| return result; |
| } |
| |
| 983,124 → 1142,182 |
| ((DEVICE_EXT*)(device_Obj->DeviceExtension))->vmemm[i] = NULL; |
| } |
| |
| //------------------------------------------------------------------------ |
| // the ultimate starting point of a driver |
| NTSTATUS DriverEntry(PDRIVER_OBJECT driverObj, PUNICODE_STRING regPath ) |
| NTSTATUS OnRequestComplete(PDEVICE_OBJECT fdo, PIRP Irp, PKEVENT pev) |
| { |
| UNREFERENCED_PARAMETER(regPath); |
| PDEVICE_OBJECT device_object; // pointer to the device object |
| UNICODE_STRING device_name; |
| UNICODE_STRING symbol_name; |
| NTSTATUS result = STATUS_SUCCESS; |
| int nPCIADAs; // count of PCIADAs |
| DEVICE_EXT *DeviceExtension = NULL; |
| UNREFERENCED_PARAMETER(fdo); |
| UNREFERENCED_PARAMETER(Irp); |
| KeSetEvent(pev, 0, FALSE); |
| return STATUS_MORE_PROCESSING_REQUIRED; |
| } |
| |
| KdPrint(("DriverEntry() ---%d.%d---------------------------------\n", (DRIVER_VERSION >> 16) & 0xff, DRIVER_VERSION & 0xff)); |
| NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS status, ULONG_PTR Information) |
| { |
| Irp->IoStatus.Status = status; |
| Irp->IoStatus.Information = Information; |
| IoCompleteRequest(Irp, IO_NO_INCREMENT); |
| return status; |
| } |
| NTSTATUS ForwardAndWait(PDEVICE_OBJECT fdo, PIRP Irp) |
| { |
| KEVENT event; |
| KeInitializeEvent(&event, NotificationEvent, FALSE); |
| IoCopyCurrentIrpStackLocationToNext(Irp); |
| IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) OnRequestComplete, (PVOID)&event, TRUE, TRUE, TRUE); |
| PDEVICE_EXT pdx = (PDEVICE_EXT ) fdo->DeviceExtension; |
| IoCallDriver(pdx->LowerDeviceObject, Irp); |
| KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); |
| return Irp->IoStatus.Status; |
| } |
| |
| driverObj->DriverUnload = PCIVMEUnload; |
| driverObj->MajorFunction[IRP_MJ_CREATE] = PCIVMEOpen; |
| driverObj->MajorFunction[IRP_MJ_CLOSE] = PCIVMEClose; |
| driverObj->MajorFunction[IRP_MJ_READ] = PCIVMERead; |
| driverObj->MajorFunction[IRP_MJ_WRITE] = PCIVMEWrite; |
| driverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PCIVMEDeviceControl; |
| #ifdef DO_CLEANUP |
| driverObj->MajorFunction[IRP_MJ_CLEANUP] = PCIVMECancel; |
| #endif |
| driverObj->MajorFunction[IRP_MJ_SHUTDOWN] = PCIVMEShutdown; |
| NTSTATUS HandleStartDevice(PDEVICE_OBJECT fdo, PIRP Irp) |
| { |
| PIO_STACK_LOCATION stack; |
| Irp->IoStatus.Status = STATUS_SUCCESS; |
| NTSTATUS status = ForwardAndWait(fdo, Irp); |
| if (!NT_SUCCESS(status)) |
| return CompleteRequest(Irp, status, Irp->IoStatus.Information); |
| |
| stack = IoGetCurrentIrpStackLocation(Irp); |
| status = PCIVMEStartDevice(fdo, Irp); |
| return CompleteRequest(Irp, status, Irp->IoStatus.Information); |
| } |
| |
| RtlInitUnicodeString(&device_name, L"\\Device\\PCIVME"); |
| |
| /* DeviceObject durch IO-Manager erzeugen */ |
| result = IoCreateDevice( driverObj, // DriverObject received by the DriverEntry Call |
| sizeof(DEVICE_EXT), // required Memory for the DeviceExtension |
| &device_name, // Name of the device in the device-Directory |
| FILE_DEVICE_UNKNOWN, // Device-ID |
| 0, // Device-Characteristics normal 0 |
| FALSE, // TRUE : one Thread can open the driver |
| &device_object); // DeviceObject returned from the IO-Manager |
| NTSTATUS DefaultPnpHandler(PDEVICE_OBJECT fdo, PIRP Irp) |
| { |
| IoSkipCurrentIrpStackLocation(Irp); |
| PDEVICE_EXT pdx = (PDEVICE_EXT )fdo->DeviceExtension; |
| return IoCallDriver(pdx->LowerDeviceObject, Irp); |
| } |
| |
| // defines how the data are handled between user / kernel Adress-Space |
| device_object->Flags |= DO_DIRECT_IO; |
| NTSTATUS HandleStopDevice(PDEVICE_OBJECT fdo, PIRP Irp) |
| { |
| IoSkipCurrentIrpStackLocation(Irp); |
| UNICODE_STRING symbol_name; |
| RtlInitUnicodeString(&symbol_name, DOS_DEVICE_NAME); |
| // delete the symbolicLink in the registry |
| IoDeleteSymbolicLink(&symbol_name); |
| DEVICE_EXT *ext = (DEVICE_EXT*)(fdo->DeviceExtension); |
| // delete the deviceObject |
| if (ext->LowerDeviceObject) IoDetachDevice(ext->LowerDeviceObject); |
| IoDeleteDevice(fdo); |
| KdPrint(("HandleStopDevice (OK)\n")); |
| return STATUS_SUCCESS; |
| } |
| |
| #if 0 |
| // register the shutdown notification entry |
| IoRegisterShutdownNotification(device_object); |
| #endif |
| |
| // anounce driver as symbolic device --------------------------------- |
| if (result == STATUS_SUCCESS) |
| { |
| /* now the symbolic Link is created. If there is no S.L. a program cannot connect to the driver */ |
| RtlInitUnicodeString(&symbol_name, DOS_DEVICE_NAME); |
| result = IoCreateSymbolicLink(&symbol_name,&device_name); |
| if (result != STATUS_SUCCESS) |
| { |
| IoDeleteDevice(device_object); |
| return result; |
| } |
| } |
| NTSTATUS PCIVMEDispatchPnp(PDEVICE_OBJECT fdo, PIRP Irp) |
| { |
| PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); |
| ULONG fcn = stack->MinorFunction; |
| static char* pnpname[] = { |
| "IRP_MN_START_DEVICE", |
| "IRP_MN_QUERY_REMOVE_DEVICE", |
| "IRP_MN_REMOVE_DEVICE", |
| "IRP_MN_CANCEL_REMOVE_DEVICE", |
| "IRP_MN_STOP_DEVICE", |
| "IRP_MN_QUERY_STOP_DEVICE", |
| "IRP_MN_CANCEL_STOP_DEVICE", |
| "IRP_MN_QUERY_DEVICE_RELATIONS", |
| "IRP_MN_QUERY_INTERFACE", |
| "IRP_MN_QUERY_CAPABILITIES", |
| "IRP_MN_QUERY_RESOURCES", |
| "IRP_MN_QUERY_RESOURCE_REQUIREMENTS", |
| "IRP_MN_QUERY_DEVICE_TEXT", |
| "IRP_MN_FILTER_RESOURCE_REQUIREMENTS", |
| "", |
| "IRP_MN_READ_CONFIG", |
| "IRP_MN_WRITE_CONFIG", |
| "IRP_MN_EJECT", |
| "IRP_MN_SET_LOCK", |
| "IRP_MN_QUERY_ID", |
| "IRP_MN_QUERY_PNP_DEVICE_STATE", |
| "IRP_MN_QUERY_BUS_INFORMATION", |
| "IRP_MN_DEVICE_USAGE_NOTIFICATION", |
| "IRP_MN_SURPRISE_REMOVAL", |
| "IRP_MN_QUERY_LEGACY_BUS_INFORMATION", |
| }; |
| |
| if (fcn < arraysize(pnpname)) |
| KdPrint(("PCIVMEDispatchPnp - IRP_MJ_PNP (%s)\n", pnpname[fcn])); |
| else |
| return result; |
| KdPrint(( "PCIVMEDispatchPnp - IRP_MJ_PNP (%2.2X)\n", fcn)); |
| |
| DeviceExtension = (DEVICE_EXT*)device_object->DeviceExtension; |
| static NTSTATUS(*fcntab[])(PDEVICE_OBJECT, PIRP) = { |
| HandleStartDevice, // IRP_MN_START_DEVICE |
| HandleStopDevice // IRP_MN_QUERY_REMOVE_DEVICE |
| }; |
| |
| DeviceExtension->actualIrp = NULL; |
| DeviceExtension->driverObj = driverObj; |
| DeviceExtension->nInitState = 0; |
| if (fcn >= arraysize(fcntab)) |
| return DefaultPnpHandler(fdo, Irp); |
| return (*fcntab[fcn])(fdo, Irp); |
| } |
| |
| |
| NTSTATUS PCIVMEStartDevice(PDEVICE_OBJECT device_object, PIRP irp){ |
| NTSTATUS result = STATUS_SUCCESS; |
| int nPCIADAs; // count of PCIADAs |
| DEVICE_EXT *DeviceExtension = NULL; |
| DeviceExtension = (DEVICE_EXT*)device_object->DeviceExtension; |
| // init pciada structures ------------------------------------ |
| PCIVMESoftInit(device_object); |
| |
| // search for PCIADAs ---------------------------------------- |
| result = SearchDevices(device_object); |
| result = SearchDevices(device_object); |
| nPCIADAs = DeviceExtension->nPCIADAs; |
| |
| if ((result != STATUS_SUCCESS) || !(nPCIADAs)) |
| { |
| PCIVMEUnload(driverObj); |
| KdPrint(("PCIVMEStartDevice Device not found\n")); |
| PCIVMEUnload(DeviceExtension->driverObj); |
| return STATUS_DEVICE_DOES_NOT_EXIST; |
| } |
| } |
| |
| // request exclusive ownership of .. --------------------------------- |
| if ((result = PCIVMEReserveResources(device_object)) != STATUS_SUCCESS) |
| if ((result = PCIVMEReserveResources(device_object, irp)) != STATUS_SUCCESS) |
| { |
| PCIVMEUnload(driverObj); |
| KdPrint(("PCIVMEStartDevice Resource not reserved PCIVMEReserveResources \n")); |
| PCIVMEUnload(DeviceExtension->driverObj); |
| return result; |
| } |
| } |
| else |
| DeviceExtension->nInitState++; |
| // fix PLX9050 Bug ------------------------------------------- |
| if ((result = PLX9050BugFix(device_object)) != STATUS_SUCCESS) |
| { |
| PCIVMEUnload(driverObj); |
| KdPrint(("PCIVMEStartDevice PLX9050BugFix\n")); |
| PCIVMEUnload(DeviceExtension->driverObj); |
| return result; |
| } |
| |
| |
| DeviceExtension->nInitState += 2; |
| /* |
| // translate BUS relative addresses ---------------------------------- |
| if ((result = PCIVMETranslateBusAddresses(device_object)) != STATUS_SUCCESS) |
| if ((result = PCIVMETranslateBusAddresses(device_object,irp)) != STATUS_SUCCESS) |
| { |
| PCIVMEUnload(driverObj); |
| PCIVMEUnload(DeviceExtension->driverObj); |
| return STATUS_DEVICE_DOES_NOT_EXIST; |
| } |
| } |
| else |
| DeviceExtension->nInitState++; |
| |
| |
| // translate Interrupt Resources used -------------------------------- |
| if ((result = PCIVMETranslateInterrupts(device_object)) != STATUS_SUCCESS) |
| { |
| PCIVMEUnload(driverObj); |
| PCIVMEUnload(DeviceExtension->driverObj); |
| return STATUS_DEVICE_DOES_NOT_EXIST; |
| } |
| else |
| DeviceExtension->nInitState++; |
| |
| */ |
| |
| // map address spaces to virtual addresses --------------------------- |
| if ((result = PCIVMEMapIOspace(device_object)) != STATUS_SUCCESS) |
| { |
| PCIVMEUnload(driverObj); |
| PCIVMEUnload(DeviceExtension->driverObj); |
| return STATUS_DEVICE_DOES_NOT_EXIST; |
| } |
| } |
| else |
| DeviceExtension->nInitState++; |
| |
| 1107,18 → 1324,18 |
| // initialze my custom DPC objects ----------------------------------- |
| if ((result = InitializeCustomDPCObjects(device_object)) != STATUS_SUCCESS) |
| { |
| PCIVMEUnload(driverObj); |
| PCIVMEUnload(DeviceExtension->driverObj); |
| return result; |
| } |
| } |
| else |
| DeviceExtension->nInitState++; |
| |
| |
| // initialze the queue for IRPs waiting for vectors ------------------ |
| if ((result = InitializeIRPQueue(device_object)) != STATUS_SUCCESS) |
| { |
| PCIVMEUnload(driverObj); |
| PCIVMEUnload(DeviceExtension->driverObj); |
| return result; |
| } |
| } |
| else |
| DeviceExtension->nInitState++; |
| |
| 1125,7 → 1342,7 |
| // connect interrupts to service routines ---------------------------- |
| if ((result = PCIVMEConnectInterrupt(device_object)) != STATUS_SUCCESS) |
| { |
| PCIVMEUnload(driverObj); |
| PCIVMEUnload(DeviceExtension->driverObj); |
| return STATUS_DEVICE_DOES_NOT_EXIST; |
| } |
| else |
| 1134,14 → 1351,91 |
| // scan all connected VMEMM for info and later use ------------------- |
| if ((result = PCIVMEScanVMEMM(device_object)) != STATUS_SUCCESS) |
| { |
| PCIVMEUnload(driverObj); |
| PCIVMEUnload(DeviceExtension->driverObj); |
| return STATUS_DEVICE_DOES_NOT_EXIST; |
| } |
| } |
| |
| device_object->Flags &= ~DO_DEVICE_INITIALIZING; |
| return result; |
| } |
| |
| KdPrint(("DriverEntry() OK.\n")); |
| NTSTATUS PCIVMEAddDevice(PDRIVER_OBJECT driverObj, PDEVICE_OBJECT pdo) |
| { // AddDevice |
| |
| UNICODE_STRING device_name; |
| UNICODE_STRING symbol_name; |
| NTSTATUS result = STATUS_SUCCESS; |
| //int nPCIADAs; // count of PCIADAs |
| DEVICE_EXT *DeviceExtension = NULL; |
| PDEVICE_OBJECT device_object; |
| RtlInitUnicodeString(&device_name, L"\\Device\\PCIVME"); |
| KdPrint(("PCIVME AddDevice() v%d.%d\n", (DRIVER_VERSION >> 16) & 0xff, DRIVER_VERSION & 0xff)); |
| /* DeviceObject durch IO-Manager erzeugen */ |
| result = IoCreateDevice( driverObj, // DriverObject received by the DriverEntry Call |
| sizeof(DEVICE_EXT), // required Memory for the DeviceExtension |
| &device_name, // Name of the device in the device-Directory |
| FILE_DEVICE_UNKNOWN, // Device-ID |
| 0, // Device-Characteristics normal 0 |
| FALSE, // TRUE : one Thread can open the driver |
| &device_object); // DeviceObject returned from the IO-Manager |
| |
| // defines how the data are handled between user / kernel Adress-Space |
| device_object->Flags |= DO_DIRECT_IO; |
| |
| #if 0 |
| // register the shutdown notification entry |
| IoRegisterShutdownNotification(device_object); |
| #endif |
| |
| // anounce driver as symbolic device --------------------------------- |
| if (result == STATUS_SUCCESS) |
| { |
| /* now the symbolic Link is created. If there is no S.L. a program cannot connect to the driver */ |
| RtlInitUnicodeString(&symbol_name, DOS_DEVICE_NAME); |
| result = IoCreateSymbolicLink(&symbol_name,&device_name); |
| if (result != STATUS_SUCCESS) |
| { |
| |
| IoDeleteDevice(device_object); |
| return result; |
| } |
| } |
| else |
| return result; |
| |
| |
| DeviceExtension = (DEVICE_EXT*)device_object->DeviceExtension; |
| |
| DeviceExtension->actualIrp = NULL; |
| DeviceExtension->driverObj = driverObj; |
| DeviceExtension->nInitState = 0; |
| |
| |
| DeviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(device_object, pdo); |
| KdPrint(("AddDevice() OK.\n")); |
| |
| return result; |
| } |
| |
| //------------------------------------------------------------------------ |
| // the ultimate starting point of a driver |
| NTSTATUS DriverEntry(PDRIVER_OBJECT driverObj, PUNICODE_STRING regPath) |
| { |
| UNREFERENCED_PARAMETER(regPath); |
| |
| KdPrint(("PCIVME DriverEntry() v%d.%d\n", (DRIVER_VERSION >> 16) & 0xff, DRIVER_VERSION & 0xff)); |
| |
| driverObj->DriverUnload = PCIVMEUnload; |
| driverObj->DriverExtension->AddDevice = PCIVMEAddDevice; |
| driverObj->MajorFunction[IRP_MJ_CREATE] = PCIVMEOpen; |
| driverObj->MajorFunction[IRP_MJ_CLOSE] = PCIVMEClose; |
| driverObj->MajorFunction[IRP_MJ_READ] = PCIVMERead; |
| driverObj->MajorFunction[IRP_MJ_WRITE] = PCIVMEWrite; |
| driverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PCIVMEDeviceControl; |
| #ifdef DO_CLEANUP |
| driverObj->MajorFunction[IRP_MJ_CLEANUP] = PCIVMECancel; |
| #endif |
| driverObj->MajorFunction[IRP_MJ_SHUTDOWN] = PCIVMEShutdown; |
| driverObj->MajorFunction[IRP_MJ_PNP] = PCIVMEDispatchPnp; |
| return STATUS_SUCCESS;; |
| } |