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;; |
} |