📄 hardrela.cpp
字号:
#include "co_proc.h"
#include "Ioctl.h"
#include "AMCC5933.H"
NTSTATUS GetResources(IN PCO_PROC_DEVICE_EXTENSION dx,IN PCM_RESOURCE_LIST AllocatedResourcesTranslated);
BOOLEAN Co_procInterruptHandler(IN PKINTERRUPT Interrupt,IN PCO_PROC_DEVICE_EXTENSION dx);
VOID Co_procDpcForIsr(IN PKDPC Dpc,IN PDEVICE_OBJECT fdo,IN PIRP Irp,IN PCO_PROC_DEVICE_EXTENSION dx);
NTSTATUS Co_procStartDevice(IN PCO_PROC_DEVICE_EXTENSION dx,IN PCM_RESOURCE_LIST AllocatedResourcesTranslated){
if(dx->PnpState==Started){
return STATUS_SUCCESS;
}
NTSTATUS status=GetResources(dx,AllocatedResourcesTranslated);
if(!NT_SUCCESS(status)){
return status;
}
return STATUS_SUCCESS;
}
NTSTATUS GetResources(IN PCO_PROC_DEVICE_EXTENSION dx,IN PCM_RESOURCE_LIST AllocatedResourcesTranslated){
if(AllocatedResourcesTranslated==NULL||AllocatedResourcesTranslated->Count==0){
return STATUS_UNSUCCESSFUL;
}
PCM_PARTIAL_RESOURCE_LIST list=&AllocatedResourcesTranslated->List[0].PartialResourceList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR pPRD=list->PartialDescriptors;
ULONG NumResources=list->Count;
for(ULONG i=0;i<NumResources;i++,pPRD++){
switch(pPRD->Type){
case CmResourceTypePort:
dx->PortLength=pPRD->u.Port.Length;
if(dx->PortLength==64){
dx->BA0=(PUCHAR)pPRD->u.Port.Start.LowPart;
}
break;
case CmResourceTypeInterrupt:
dx->Irql=(KIRQL)pPRD->u.Interrupt.Level;
dx->Vector=pPRD->u.Interrupt.Vector;
dx->Affinity=pPRD->u.Interrupt.Affinity;
dx->Mode=(pPRD->Flags==CM_RESOURCE_INTERRUPT_LATCHED)?Latched:LevelSensitive;
break;
}
}
return STATUS_SUCCESS;
}
VOID Co_procStartIo(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
KIRQL OldIrql;
IoAcquireCancelSpinLock(&OldIrql);
IoSetCancelRoutine(Irp,NULL);
IoReleaseCancelSpinLock(OldIrql);
typedef struct _BAR_DATA{
ULONG length;
ULONG Offset;
ULONG Data;
}BAR_DATA,*PBAR_DATA;
ULONG ReadData;
PBAR_DATA Buffer=(PBAR_DATA)Irp->AssociatedIrp.SystemBuffer;
NTSTATUS status=STATUS_SUCCESS;
dx->DMAlength=Buffer->length;
// if(Offset>dx->PortLength)
// {
// status=STATUS_UNSUCCESSFUL;
// CompleteIrp(Irp,status,0);
// IoStartNextPacket(fdo,FALSE);
// IoReleaseRemoveLock(&dx->CountOfUse,NULL);
// return;
// }
switch(IrpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_CO_PROC_WRITE:
WRITE_PORT_ULONG((PULONG)(dx->BA0+Buffer->Offset),(long)Buffer->Data);
break;
case IOCTL_CO_PROC_READ:
ReadData=READ_PORT_ULONG((PULONG)(dx->BA0+Buffer->Offset));
Buffer->Data=ReadData;
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,Buffer,sizeof(BAR_DATA));
break;
default:
status=STATUS_NOT_SUPPORTED;
break;
}
}
VOID Co_procCancelIrp(IN PDEVICE_OBJECT fdo,IN PIRP Irp){
PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
if(Irp==fdo->CurrentIrp){
IoReleaseCancelSpinLock(Irp->CancelIrql);
}else{
BOOLEAN dequeued=KeRemoveEntryDeviceQueue(&fdo->DeviceQueue,&Irp->Tail.Overlay.DeviceQueueEntry);
IoReleaseCancelSpinLock(Irp->CancelIrql);
if(dequeued){
IoReleaseRemoveLock(&dx->CountOfUse,Irp);
CompleteIrp(Irp,STATUS_CANCELLED,0);
}
}
}
BOOLEAN Co_procInterruptHandler(IN PKINTERRUPT Interrupt,IN PCO_PROC_DEVICE_EXTENSION dx){
PDEVICE_OBJECT fdo=dx->fdo;
PIRP Irp=fdo->CurrentIrp;
dx->sint=READ_PORT_ULONG((PULONG)(dx->BA0+INTCSR));
if (!((dx->sint)&0x800000)) return FALSE;
if ((dx->sint)&0x20000){
WRITE_PORT_ULONG((PULONG)(dx->BA0+INTCSR),(dx->sint)&0xff02ffff);
WRITE_PORT_ULONG((PULONG)(dx->BA0+MCSR),0x700);
}
else if ((dx->sint)&0x40000){
WRITE_PORT_ULONG((PULONG)(dx->BA0+INTCSR),(dx->sint)&0xff04ffff);
IoRequestDpc(fdo,Irp,dx);
}
else if (!((dx->sint)&0x300000)){
WRITE_PORT_ULONG((PULONG)(dx->BA0+INTCSR),(dx->sint)&0xff03ffff);
}
return TRUE;
}
VOID Co_procDpcForIsr(IN PKDPC Dpc,IN PDEVICE_OBJECT fdo,IN PIRP Irp,IN PCO_PROC_DEVICE_EXTENSION dx)
{
NTSTATUS status=Irp->Cancel?STATUS_CANCELLED:Irp->IoStatus.Status;
KIRQL OldIrql;
IoAcquireCancelSpinLock(&OldIrql);
IoSetCancelRoutine(Irp,NULL);
IoReleaseCancelSpinLock(OldIrql);
IoReleaseRemoveLock(&dx->CountOfUse,Irp);
if(dx->WantToStop){
CompleteIrp(Irp,status,Irp->IoStatus.Information);
return;
}
IoStartNextPacket(fdo,TRUE);
CompleteIrp(Irp,status,Irp->IoStatus.Information);
IoReleaseRemoveLock(&dx->CountOfUse,NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -