📄 amcc_orig.cpp
字号:
Return Value:
STATUS_SUCCESS if successful
NT status code
*/
NTSTATUS SheldonUnMapDirect(PDEVICE_EXTENSION pdx)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
int i;
KdPrint(("SIWDM - Entering SheldonUnMapDirect\n"));
for(i=0;i<PCI_TYPE0_ADDRESSES;i++)
{
if(pdx->Direct_Baddr[i] != NULL)
{
__try
{
MmUnmapLockedPages((PVOID) pdx->Direct_Baddr[i], pdx->Mdl[i]);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
ntStatus = GetExceptionCode();
KdPrint(("SIWDM - SheldonUnMapDirect: Fail to Unmap Mdl[%x]\n", i));
KdPrint(("SIWDM - SheldonUnMapDirect: Error Code %x\n", ntStatus));
}
pdx->Direct_Baddr[i] = NULL;
}
if(pdx->Mdl[i] != NULL)
{
__try
{
IoFreeMdl(pdx->Mdl[i]);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
ntStatus = GetExceptionCode();
KdPrint(("SIWDM - SheldonUnMapDirect: Fail to Free Mdl[%x]\n", i));
KdPrint(("SIWDM - SheldonUnMapDirect: Error Code %x\n", ntStatus));
}
pdx->Mdl[i] = NULL;
}
}
KdPrint(("SIWDM - Exiting SheldonUnMapDirect\n"));
return ntStatus;
}
/*
Function Name:
SheldonConfigRead
Routine Description:
Enables the user application to read the PCI configuration space for the device.
This function creates an IRP which is passed down to the PCI bus driver, which handles
the request.
Arguments:
fdo - pointer to the function device object
Irp - I/O request being serviced
pdx - pointer to the device extension.
Return Value:
STATUS_SUCCESS if successful
NT status code
*/
NTSTATUS SheldonConfigRead(IN PDEVICE_OBJECT fdo, PIRP Irp, PDEVICE_EXTENSION pdx)
{
PULONG params;
NTSTATUS ntStatus;
PIO_STACK_LOCATION ConfigIrpStack;
PIRP ConfigIrp;
KEVENT ConfigEvent;
ULONG byteCount;
// read the configuration space of the device
params = (PULONG) Irp->AssociatedIrp.SystemBuffer;
byteCount = params[SI_CONFIG_COUNT_INDEX];
// write number of bytes coming back, before this param is overwritten
Irp->IoStatus.Information = byteCount;
ConfigIrp = IoAllocateIrp(fdo->StackSize, FALSE);
if(ConfigIrp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
KeInitializeEvent(&ConfigEvent, NotificationEvent, FALSE);
IoSetCompletionRoutine
(
ConfigIrp,
(PIO_COMPLETION_ROUTINE) OnRequestComplete,
&ConfigEvent,
TRUE, TRUE, TRUE
);
ConfigIrpStack = IoGetNextIrpStackLocation(ConfigIrp);
if(ConfigIrpStack == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
ConfigIrpStack -> MajorFunction = IRP_MJ_PNP;
ConfigIrpStack -> MinorFunction = IRP_MN_READ_CONFIG;
ConfigIrpStack -> Parameters.ReadWriteConfig.Buffer = (PVOID) &(params[SI_CONFIG_READ_DATA_INDEX]);
ConfigIrpStack -> Parameters.ReadWriteConfig.Offset = params[SI_CONFIG_OFFSET_INDEX];
ConfigIrpStack -> Parameters.ReadWriteConfig.Length = byteCount;
ntStatus = IoCallDriver(fdo, ConfigIrp);
if(ntStatus == STATUS_PENDING)
{
KeWaitForSingleObject(&ConfigEvent, Executive, KernelMode, FALSE, NULL);
ntStatus = ConfigIrp->IoStatus.Status;
}
IoFreeIrp(ConfigIrp);
return ntStatus;
}
/*
Function Name:
SheldonConfigWrite
Routine Description:
Enables the user application to write the PCI configuration space for the device.
This function creates an IRP which is passed down to the PCI bus driver, which handles
the request. This function has not been tested.
Arguments:
fdo - pointer to the function device object
Irp - I/O request being serviced
pdx - pointer to the device extension.
Return Value:
STATUS_SUCCESS if successful
NT status code
*/
#define JUST_TESTING
//#define ORIGINAL_CODE
NTSTATUS SheldonConfigWrite(IN PDEVICE_OBJECT fdo, PIRP Irp, PDEVICE_EXTENSION pdx)
{
#ifdef JUST_TESTING
PULONG params;
KEVENT event;
NTSTATUS status;
PIRP irp2;
IO_STATUS_BLOCK ioStatusBlock;
PIO_STACK_LOCATION irpStack;
PDEVICE_OBJECT targetObject;
PAGED_CODE();
// read the configuration space of the device
params = (PULONG) Irp->AssociatedIrp.SystemBuffer;
KeInitializeEvent( &event, NotificationEvent, FALSE );
targetObject = IoGetAttachedDeviceReference( fdo );
irp2 = IoBuildSynchronousFsdRequest( IRP_MJ_PNP,
targetObject,
NULL,
0,
NULL,
&event,
&ioStatusBlock );
if (irp2 == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto End;
}
irpStack = IoGetNextIrpStackLocation( irp2 );
irpStack->MinorFunction = IRP_MN_WRITE_CONFIG;
irpStack->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
irpStack->Parameters.ReadWriteConfig.Buffer = (PVOID) &(params[SI_CONFIG_WRITE_DATA_INDEX]);
irpStack->Parameters.ReadWriteConfig.Offset = params[SI_CONFIG_OFFSET_INDEX];
irpStack->Parameters.ReadWriteConfig.Length = params[SI_CONFIG_COUNT_INDEX];
//
// Initialize the status to error in case the bus driver does not
// set it correctly.
//
irp2->IoStatus.Status = STATUS_NOT_SUPPORTED ;
status = IoCallDriver( targetObject, irp2 );
if (status == STATUS_PENDING) {
KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
status = ioStatusBlock.Status;
}
End:
//
// Done with reference
//
ObDereferenceObject( targetObject );
return status;
#endif
#ifdef ORIGINAL_CODE
// origonal code
PULONG params;
NTSTATUS ntStatus;
PIO_STACK_LOCATION ConfigIrpStack;
PIRP ConfigIrp;
KEVENT ConfigEvent;
// read the configuration space of the device
params = (PULONG) Irp->AssociatedIrp.SystemBuffer;
ConfigIrp = IoAllocateIrp(fdo->StackSize, FALSE);
if(ConfigIrp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
KeInitializeEvent(&ConfigEvent, NotificationEvent, FALSE);
IoSetCompletionRoutine(ConfigIrp, (PIO_COMPLETION_ROUTINE) OnRequestComplete, &ConfigEvent, TRUE, TRUE, TRUE);
ConfigIrpStack = IoGetNextIrpStackLocation(ConfigIrp);
if(ConfigIrpStack == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
ConfigIrpStack -> MajorFunction = IRP_MJ_PNP;
ConfigIrpStack -> MinorFunction = IRP_MN_WRITE_CONFIG;
ConfigIrpStack -> Parameters.ReadWriteConfig.Buffer = (PVOID) &(params[SI_CONFIG_WRITE_DATA_INDEX]);
ConfigIrpStack -> Parameters.ReadWriteConfig.Offset = params[SI_CONFIG_OFFSET_INDEX];
ConfigIrpStack -> Parameters.ReadWriteConfig.Length = params[SI_CONFIG_COUNT_INDEX];
ntStatus = IoCallDriver(fdo, ConfigIrp);
if(ntStatus == STATUS_PENDING)
{
KeWaitForSingleObject(&ConfigEvent, Executive, KernelMode, FALSE, NULL);
ntStatus = ConfigIrp->IoStatus.Status;
}
IoFreeIrp(ConfigIrp);
return ntStatus;
#endif
}
#ifdef XXXXXXXX
// From mocrosoft.com
NTSTATUS
ReadWriteConfigSpace(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG ReadOrWrite, // 0 for read 1 for write
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length
)
{
KEVENT event;
NTSTATUS status;
PIRP irp;
IO_STATUS_BLOCK ioStatusBlock;
PIO_STACK_LOCATION irpStack;
PDEVICE_OBJECT targetObject;
PAGED_CODE();
KeInitializeEvent( &event, NotificationEvent, FALSE );
targetObject = IoGetAttachedDeviceReference( DeviceObject );
irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP,
targetObject,
NULL,
0,
NULL,
&event,
&ioStatusBlock );
if (irp == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto End;
}
irpStack = IoGetNextIrpStackLocation( irp );
if (ReadOrWrite == 0) {
irpStack->MinorFunction = IRP_MN_READ_CONFIG;
}else {
irpStack->MinorFunction = IRP_MN_WRITE_CONFIG;
}
irpStack->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
irpStack->Parameters.ReadWriteConfig.Buffer = Buffer;
irpStack->Parameters.ReadWriteConfig.Offset = Offset;
irpStack->Parameters.ReadWriteConfig.Length = Length;
//
// Initialize the status to error in case the bus driver does not
// set it correctly.
//
irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;
status = IoCallDriver( targetObject, irp );
if (status == STATUS_PENDING) {
KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
status = ioStatusBlock.Status;
}
End:
//
// Done with reference
//
ObDereferenceObject( targetObject );
return status;
}
#endif
//=================================================================
// Following two calls are used by Sheldon Instruments hardware.
// They can be safely ignored or removed from the driver if non-SI
// hardware is used.
//=================================================================
#define SI_ROBS_REGS 1
#define SI_DUAL_ACCESS_READ_ADDRESS_OFFSET 0
#define SI_DUAL_ACCESS_WRITE_ADDRESS_OFFSET 1
#define SI_DUAL_ACCESS_DATA_OFFSET 2
NTSTATUS
SheldonDualAccessRead(PIRP Irp, PDEVICE_EXTENSION pDeviceExt)
{
PULONG Buffer;
ULONG dsp_address;
ULONG i;
ULONG count;
// get a ULONG pointer to the buffer
Buffer = (ULONG *)MmGetSystemAddressForMdl(Irp->MdlAddress);
count= MmGetMdlByteCount(Irp->MdlAddress)/sizeof(ULONG);
// get the dsp_address
dsp_address=*(PULONG)Irp->AssociatedIrp.SystemBuffer;
for (i=0;i<count;i++)
{
WRITE_REGISTER_ULONG
(
pDeviceExt->base[SI_ROBS_REGS]
+SI_DUAL_ACCESS_READ_ADDRESS_OFFSET,
dsp_address++
);
*Buffer++ =
READ_REGISTER_ULONG
(
pDeviceExt->base[SI_ROBS_REGS]
+ SI_DUAL_ACCESS_DATA_OFFSET
);
}
Irp->IoStatus.Information=sizeof(ULONG)*count;
return STATUS_SUCCESS;
}
//===========================================================
NTSTATUS
SheldonDualAccessWrite(PIRP Irp, PDEVICE_EXTENSION pDeviceExt)
{
PULONG Buffer;
ULONG dsp_address;
ULONG i;
ULONG count;
// get a ULONG pointer to the buffer
Buffer = (ULONG *)MmGetSystemAddressForMdl(Irp->MdlAddress);
count= MmGetMdlByteCount(Irp->MdlAddress)/sizeof(ULONG);
// get the dsp_address
dsp_address=*(PULONG)Irp->AssociatedIrp.SystemBuffer;
for (i=0;i<count;i++)
{
WRITE_REGISTER_ULONG
(
pDeviceExt->base[SI_ROBS_REGS]
+SI_DUAL_ACCESS_WRITE_ADDRESS_OFFSET,
dsp_address++
);
WRITE_REGISTER_ULONG
(
pDeviceExt->base[SI_ROBS_REGS]
+SI_DUAL_ACCESS_DATA_OFFSET,
*Buffer++
);
}
Irp->IoStatus.Information=0;
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -