📄 dispatchroutines.c
字号:
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
LongBuffer = (PULONG)IoBuffer;
MapAddress.LowPart = LongBuffer[0];
MapAddress.HighPart = 0x00000000;
DebugPrint("the address needed to map:0x%x",LongBuffer[0]);
MappedAddress = (PUCHAR)MmMapIoSpace(MapAddress,pdx->PortRegisterBytes/4,MmNonCached);
if(!MappedAddress)
{
DebugPrint("the Port register call MmMapIOSpace failed!");
}
DebugPrint("the Port address after mapped is 0x%x",MappedAddress);
*LongBuffer = (ULONG)MappedAddress;
DebugPrint("Map Register end...\n");
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_3124REGISTER_MAP_GLOBAL_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124REGISTER_MAP_GLOBAL
******************************************************************************************************************/
NTSTATUS IOCTL_3124REGISTER_MAP_GLOBAL_Handler(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PIO_STACK_LOCATION pIrpStack;
PVOID IoBuffer;
PULONG LongBuffer;
PUCHAR MappedAddress;
PHYSICAL_ADDRESS MapAddress;
DebugPrint("start Map GLOBAL Register...\n");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
status = STATUS_SUCCESS;
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
LongBuffer = (PULONG)IoBuffer;
MapAddress.LowPart = LongBuffer[0];
MapAddress.HighPart = 0x00000000;
DebugPrint("the address needed to map:0x%x",LongBuffer[0]);
MappedAddress = (PUCHAR)MmMapIoSpace(MapAddress,pdx->GlobalRegisterBytes,MmNonCached);
if(!MappedAddress)
{
DebugPrint("the Global register call MmMapIOSpace failed!");
}
DebugPrint("the GLOBAL address after mapped is 0x%x",MappedAddress);
*LongBuffer = (ULONG)MappedAddress;
DebugPrint("Map Register end...\n");
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_3124REGISTER_UNMAP_PORT_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124REGISTER_UNMAP_PORT
******************************************************************************************************************/
NTSTATUS IOCTL_3124REGISTER_UNMAP_PORT_Handler(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PIO_STACK_LOCATION pIrpStack;
PVOID IoBuffer;
PULONG LongBuffer;
DebugPrint("start UNMap Port Register...\n");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
LongBuffer = (PULONG)IoBuffer;
DebugPrint("the address needed to unmap:0x%x",LongBuffer[0]);
MmUnmapIoSpace((PUCHAR)LongBuffer[0],pdx->PortRegisterBytes/4);
status = STATUS_SUCCESS;
DebugPrint("UNMap Port Register end...\n");
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_3124REGISTER_UNMAP_GLOBAL_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124REGISTER_UNMAP_GLOBAL
******************************************************************************************************************/
NTSTATUS IOCTL_3124REGISTER_UNMAP_GLOBAL_Handler(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PIO_STACK_LOCATION pIrpStack;
PVOID IoBuffer;
PULONG LongBuffer;
DebugPrint("start UNMap GLOBAL Register...\n");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
LongBuffer = (PULONG)IoBuffer;
DebugPrint("the address needed to unmap:0x%x",LongBuffer[0]);
MmUnmapIoSpace((PUCHAR)LongBuffer[0],pdx->GlobalRegisterBytes);
status = STATUS_SUCCESS;
DebugPrint("UNMap GLOBAL Register end...\n");
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_GET_3124_PORT_RESET_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124_PORT_RESET
******************************************************************************************************************/
NTSTATUS IOCTL_3124_PORT_RESET_Handler(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PIO_STACK_LOCATION pIrpStack;
ULONG i = 0;
PVOID IoBuffer;
PULONG LongBuffer;
DebugPrint("start Reset Port...\n");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
LongBuffer = (PULONG)IoBuffer;
DebugPrint("the port base address: 0x%x",LongBuffer[0]);
DebugPrint("0x%x",READ_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1800)));
DebugPrint("0x%x",READ_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1000)));
DebugPrint("0x%x",READ_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1004)));
DebugPrint("0x%x",READ_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1008)));
DebugPrint("0x%x",READ_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1010)));
WRITE_REGISTER_UCHAR((PUCHAR)((PUCHAR)(LongBuffer[0]+0x1008)),0x02);//clear the erro Interrupt
WRITE_REGISTER_UCHAR((PUCHAR)((PUCHAR)(LongBuffer[0])+0x1000),0x01);//declare the port reset condition
while(i<1000)
i++;
DebugPrint("then clear the port reset condition");
WRITE_REGISTER_UCHAR((PUCHAR)((PUCHAR)(LongBuffer[0])+0x1004),0x01);//clear the port reset condition
DebugPrint("enable the completion and erro interrupt");
WRITE_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1010),0x00000003);//enable interrupt
status = STATUS_SUCCESS;
DebugPrint("Reset Port end...\n");
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_3124_DMA_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124_DMA_READ OR IOCTL_3124_DMA_WRITE
******************************************************************************************************************/
NTSTATUS IOCTL_3124_DMA_Handler(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PIO_STACK_LOCATION pIrpStack;
PDMA_ADAPTER pAdapterObject;
PDMA_OPERATIONS pDmaOperation;
PMDL mdlAddress ;
ULONG TransferBytes = 0; //bytes of transfer
PVOID IoBuffer;
PSATAREG48 SATAREG48Buffer;
PULONG LongBuffer;
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pdx->pDmaContext = (pDmaInfo) ExAllocatePool(NonPagedPool,sizeof(DmaInfo));
status = STATUS_SUCCESS;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
SATAREG48Buffer = (PSATAREG48)IoBuffer;
LongBuffer = (PULONG)SATAREG48Buffer->rBuf;
pdx->pDmaContext->PortAddress = LongBuffer[0];
DebugPrint("the PortAddress is :0x%x",pdx->pDmaContext->PortAddress);
pdx->pDmaContext->SATAREG48Buffer = SATAREG48Buffer;
//check the PCI registers whether are all not available
if(READ_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1000)) == 0xffffffff)
{
DebugPrint("the PCI register are all not available");
pdx->TansferedCount = 0;
CompleteRequestInfo(pIrp,status,pdx->TansferedCount);
IoStartNextPacket(fdo, TRUE);
return status;
}
//check the port ready
if((READ_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1000)) & 0x80000000) != 0x80000000)
{
DebugPrint("the port is not ready,the Sstatus:0x%x",READ_REGISTER_UCHAR((PUCHAR)(LongBuffer[0]+0x1f04)));
pdx->TansferedCount = 0;
CompleteRequestInfo(pIrp,status,pdx->TansferedCount);
IoStartNextPacket(fdo, TRUE);
return status;
}
//check whether the drive power on
if((READ_REGISTER_UCHAR((PUCHAR)(LongBuffer[0]+0x1f04)) & 0x03) != 0x03)
{
DebugPrint("the device is not present and PHY communication is not established .the DET: 0x%x",READ_REGISTER_UCHAR((PUCHAR)(LongBuffer[0]+0x1f04)));
pdx->TansferedCount = 0;
CompleteRequestInfo(pIrp,status,pdx->TansferedCount);
IoStartNextPacket(fdo, TRUE);
return status;
}
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
DebugPrint("start DMA transfer...\n");
mdlAddress = pIrp->MdlAddress;
// Calculate the number of map registers needed for this transfer.
pdx->CurrentVirtualAddress =
MmGetMdlVirtualAddress (mdlAddress) ;
pdx->CurrentTransferLength =
MmGetMdlByteCount (mdlAddress) ;
DebugPrint("the total length user's Out Buffer is :%u\n",pdx->CurrentTransferLength);
pdx->WriteToDevice =(pIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_3124_DMA_WRITE);
if(pdx->WriteToDevice)
DebugPrint("the transfer is from buffer to device");
else
DebugPrint("the transfer is from device to buffer");
pAdapterObject = pdx->AdapterObject;
pDmaOperation = pAdapterObject->DmaOperations;
status = (pDmaOperation->GetScatterGatherList)(pdx->AdapterObject,fdo, mdlAddress,
pdx->CurrentVirtualAddress , pdx->CurrentTransferLength,
AdapterListControl,pdx->pDmaContext,pdx->WriteToDevice);
if(status == STATUS_SUCCESS)
DebugPrint("The adapter channel has been allocated.");
else
{
DebugPrint("The NumberOfMapRegisters is larger than the value returned by IoGetDmaAdapter.");
CompleteRequestInfo(pIrp, status, TransferBytes);
IoStartNextPacket(fdo, TRUE);
}
return status;
}
VOID
AdapterListControl (
IN PDEVICE_OBJECT fdo,
IN PIRP pIrp,
IN PSCATTER_GATHER_LIST ScatterGather,
IN PVOID Context
)
{
PDEVICE_EXTENSION pdx;
PIO_STACK_LOCATION pIrpStack;
PMDL mdlAddress ;
PDMA_ADAPTER pAdapterObject;
PHYSICAL_ADDRESS PAddress;
pDmaInfo pDmaContext;
PSATAREG48 SATAREG48Buffer;
ULONG PortBaseAddress,PortStatus,i,j,CountOfSGE,DmaRead,SGTCount,SGTRem;
USHORT SectorCount;
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pDmaContext = (pDmaInfo)Context;
SATAREG48Buffer = pDmaContext->SATAREG48Buffer;
PortBaseAddress = pDmaContext->PortAddress;
//store Port base address into DeviceExtension
pdx->PortBaseAddress = PortBaseAddress;
DebugPrint("AdapterListControl Routine begin being called....0x%x",PortBaseAddress);
mdlAddress = pIrp->MdlAddress ;
pdx->ScatterGatherList = ScatterGather;
CountOfSGE = pdx->ScatterGatherList->NumberOfElements;
KeFlushIoBuffers (mdlAddress, !pdx->WriteToDevice, TRUE) ;
DebugPrint("the count of SCATTER_GATHER_ELEMENT in list is%u",CountOfSGE);
//calculate the bytes needed to be transfered
SectorCount = SATAREG48Buffer->secc_pre;
SectorCount <<= 8;
SectorCount |= SATAREG48Buffer->secc_cur;
pdx->BytesTransfer = SectorCount * 512;
/*****************************************************************************
* Create a PRB and Fill it with specific parameters
******************************************************************************/
pdx->PRBStruct = (pPRB) ExAllocatePool(NonPagedPool,sizeof(PRB));
DebugPrint("PRB system address is:0x%x",(ULONG)pdx->PRBStruct);
PAddress = MmGetPhysicalAddress(pdx->PRBStruct);
DebugPrint("PRBS Physical address is:0x%x",(ULONG)PAddress.LowPart);
//Make PRB 8 bytes aligned
while((PAddress.LowPart)% 8 != 0)
{
ExFreePool(pdx->PRBStruct);
pdx->PRBStruct = (pPRB) ExAllocatePool(NonPagedPool,sizeof(PRB));
PAddress = MmGetPhysicalAddress(pdx->PRBStruct);
DebugPrint(" After ReAllocate Physical Address is:0x%x\n" ,PAddress.LowPart );
DebugPrint(" After ReAllocate System Address is:0x%x\n" ,(ULONG)pdx->PRBStruct);
}
pdx->PRBStruct->Control = 0x0000;
pdx->PRBStruct->ProtocolOverride = 0x0000;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -