📄 dispatchroutines.c
字号:
ULONG PIOWriteCount;
USHORT SectorCount;
ULONG i,RequestCount;
ULONG PortStatus;
PUCHAR SlotBaseAddress; //slot base address
status = STATUS_SUCCESS; // Assume a successful return status
DebugPrint("start PIO WRITE...\n");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
SATAREG48Buffer = (PSATAREG48)IoBuffer;
LongBuffer = (PULONG)SATAREG48Buffer->rBuf;
PortBaseAddress = LongBuffer[0];
pdx->PortBaseAddress = PortBaseAddress;
DebugPrint("the port base address is 0x%x",PortBaseAddress);
//check the PCI registers whether are all not available
if(READ_REGISTER_ULONG((PULONG)(PortBaseAddress+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)(PortBaseAddress+0x1000)) & 0x80000000) != 0x80000000)
{
DebugPrint("the port is not ready,the Sstatus:0x%x",READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+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)(PortBaseAddress+0x1f04)) & 0x03) != 0x03)
{
DebugPrint("the device is not present and PHY communication is not established .the DET: 0x%x",READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+0x1f04)));
pdx->TansferedCount = 0;
CompleteRequestInfo(pIrp,status,pdx->TansferedCount);
IoStartNextPacket(fdo, TRUE);
return status;
}
SlotBaseAddress = (PUCHAR)PortBaseAddress+Slot*0x80;
SectorCount = SATAREG48Buffer->secc_pre;
SectorCount <<= 8;
SectorCount |= SATAREG48Buffer->secc_cur;
RequestCount = SectorCount * 512;
DebugPrint("the Request count to be transfered is %u,and the PAGE_SIZE is %u",RequestCount,PAGE_SIZE);
/****************************************************************************
* create the region for data transfer
****************************************************************************/
pdx->WriteBuffer = (PUCHAR) ExAllocatePool(NonPagedPool,RequestCount);
PIOWriteBuffer = MmGetPhysicalAddress(pdx->WriteBuffer);
PIOWriteCount = RequestCount;
DebugPrint("the SGE0 address is %x, data count is %u",PIOWriteBuffer.LowPart,PIOWriteCount);
//copy the data to be written into disk to the WriteBuffer
RtlMoveMemory(pdx->WriteBuffer,SATAREG48Buffer->wBuf,PIOWriteCount);
/*****************************************************************************
* 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;
pdx->PRBStruct->ReceivedCount = 0x00000000;
pdx->PRBStruct->FISType = 0x27;
pdx->PRBStruct->PMP = 0x80;
pdx->PRBStruct->Command_Status = SATAREG48Buffer->cmnd;
pdx->PRBStruct->Features_Error = SATAREG48Buffer->feat_cur;
pdx->PRBStruct->SectorNumber = SATAREG48Buffer->secn_cur;
pdx->PRBStruct->CylLow = SATAREG48Buffer->cyll_cur;
pdx->PRBStruct->CylHigh = SATAREG48Buffer->cylh_cur;
pdx->PRBStruct->DevHead = SATAREG48Buffer->devh;
pdx->PRBStruct->SectorNumberExp = SATAREG48Buffer->secn_pre;
pdx->PRBStruct->CylLowExp = SATAREG48Buffer->cyll_pre;
pdx->PRBStruct->CylHighExp = SATAREG48Buffer->cylh_pre;
pdx->PRBStruct->FeaturesExp = SATAREG48Buffer->feat_pre;
pdx->PRBStruct->SectorCount = SATAREG48Buffer->secc_cur;
pdx->PRBStruct->SectorCountExp = SATAREG48Buffer->secc_pre;
pdx->PRBStruct->Reserved0 = 0x00;
pdx->PRBStruct->DeviceControl = SATAREG48Buffer->fxdc;
pdx->PRBStruct->Reserved1 = 0x00000000;
pdx->PRBStruct->Reserved2 = 0x00000000;
pdx->PRBStruct->SGE0Low = (ULONG)PIOWriteBuffer.LowPart;
pdx->PRBStruct->SGE0High = 0x00000000;
pdx->PRBStruct->SGE0Count = PIOWriteCount;
pdx->PRBStruct->SGE0Control = 0x80000000;
pdx->PRBStruct->SGE1Low = 0x00000000;
pdx->PRBStruct->SGE1High = 0x00000000;
pdx->PRBStruct->SGE1Count = 0;
pdx->PRBStruct->SGE1Control = 0x00000000;
DebugPrint("the port interrupt status 0x%x",READ_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1008)));
pdx->TansferedCount = RequestCount;
WRITE_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1C00),PAddress.LowPart);
WRITE_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1C04),0x00000000);
pdx->NeedToHandle =TRUE;
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_GET_3124TASKFILE_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_GET_3124TASKFILE
******************************************************************************************************************/
NTSTATUS IOCTL_GET_3124TASKFILE_Handler(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PIO_STACK_LOCATION pIrpStack;
PVOID IoBuffer;
PULONG LongBuffer;
PUCHAR CharBuffer;
ULONG PortBaseAddress,Index;
UCHAR ReadData;
UCHAR Slot = 0;
DebugPrint("start obtaining base address...\n");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
LongBuffer = (PULONG)IoBuffer;
CharBuffer = (PUCHAR)IoBuffer;
PortBaseAddress = LongBuffer[0];
Index =LongBuffer[1];
switch(Index)
{
case 0:
ReadData = READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+Slot*0x80+0x08+0x02)); //status
break;
case 1:
ReadData = READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+Slot*0x80+0x08+0x03)); //error
break;
case 2:
ReadData = READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+Slot*0x80+0x08+0x04)); //sector number
break;
case 3:
ReadData = READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+Slot*0x80+0x08+0x05)); //cyl low
break;
case 4:
ReadData = READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+Slot*0x80+0x08+0x06)); //cyl high
break;
case 5:
ReadData = READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+Slot*0x80+0x08+0x07)); //device/head
break;
case 6:
ReadData = READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+Slot*0x80+0x14)); //sector count
break;
}
CharBuffer[0] = ReadData;
// Assume a successful return status
status = STATUS_SUCCESS;
DebugPrint("TASK FILE register getting end...\n");
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_3124REGISTER_COMMAND_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124REGISTER_COMMAND
******************************************************************************************************************/
NTSTATUS IOCTL_3124REGISTER_COMMAND_Handler(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PIO_STACK_LOCATION pIrpStack;
ULONG Slot = 0;
PVOID IoBuffer;
PULONG LongBuffer;
PUSHORT ShortBuffer;
PUCHAR CharBuffer;
ULONG PortBaseAddress;
PSATAREG48 SATAREG48Buffer;
PHYSICAL_ADDRESS PAddress;
ULONG i;
ULONG PortStatus;
PUCHAR SlotBaseAddress; //slot base address
status = STATUS_SUCCESS; // Assume a successful return status
DebugPrint("start No-Data Command ...\n");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
SATAREG48Buffer = (PSATAREG48)IoBuffer;
LongBuffer = (PULONG)SATAREG48Buffer->rBuf;
PortBaseAddress = LongBuffer[0];
pdx->PortBaseAddress = PortBaseAddress;
DebugPrint("the port base address is 0x%x",PortBaseAddress);
//check the PCI registers whether are all not available
if(READ_REGISTER_ULONG((PULONG)(PortBaseAddress+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)(PortBaseAddress+0x1000)) & 0x80000000) != 0x80000000)
{
DebugPrint("the port is not ready,the Sstatus:0x%x",READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+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)(PortBaseAddress+0x1f04)) & 0x03) != 0x03)
{
DebugPrint("the device is not present and PHY communication is not established .the DET: 0x%x",READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+0x1f04)));
pdx->TansferedCount = 0;
CompleteRequestInfo(pIrp,status,pdx->TansferedCount);
IoStartNextPacket(fdo, TRUE);
return status;
}
pdx->TansferedCount = 0;
SlotBaseAddress = (PUCHAR)PortBaseAddress+Slot*0x80;
/*****************************************************************************
* 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;
pdx->PRBStruct->ReceivedCount = 0x00000000;
pdx->PRBStruct->FISType = 0x27;
pdx->PRBStruct->PMP = 0x80;
pdx->PRBStruct->Command_Status = SATAREG48Buffer->cmnd;
pdx->PRBStruct->Features_Error = SATAREG48Buffer->feat_cur;
pdx->PRBStruct->SectorNumber = SATAREG48Buffer->secn_cur;
pdx->PRBStruct->CylLow = SATAREG48Buffer->cyll_cur;
pdx->PRBStruct->CylHigh = SATAREG48Buffer->cylh_cur;
pdx->PRBStruct->DevHead = SATAREG48Buffer->devh;
pdx->PRBStruct->SectorNumberExp = SATAREG48Buffer->secn_pre;
pdx->PRBStruct->CylLowExp = SATAREG48Buffer->cyll_pre;
pdx->PRBStruct->CylHighExp = SATAREG48Buffer->cylh_pre;
pdx->PRBStruct->FeaturesExp = SATAREG48Buffer->feat_pre;
pdx->PRBStruct->SectorCount = SATAREG48Buffer->secc_cur;
pdx->PRBStruct->SectorCountExp = SATAREG48Buffer->secc_pre;
pdx->PRBStruct->Reserved0 = 0x00;
pdx->PRBStruct->DeviceControl = SATAREG48Buffer->fxdc;
pdx->PRBStruct->Reserved1 = 0x00000000;
pdx->PRBStruct->Reserved2 = 0x00000000;
pdx->PRBStruct->SGE0Low = 0x00000000;
pdx->PRBStruct->SGE0High = 0x00000000;
pdx->PRBStruct->SGE0Count = 0;
pdx->PRBStruct->SGE0Control = 0x00000000;
pdx->PRBStruct->SGE1Low = 0x00000000;
pdx->PRBStruct->SGE1High = 0x00000000;
pdx->PRBStruct->SGE1Count = 0;
pdx->PRBStruct->SGE1Control = 0x00000000;
DebugPrint("the port interrupt status 0x%x",READ_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1008)));
WRITE_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1C00),PAddress.LowPart);
WRITE_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1C04),0x00000000);
pdx->NeedToHandle =TRUE;
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_3124REGISTER_MAP_PORT_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124REGISTER_MAP_PORT
******************************************************************************************************************/
NTSTATUS IOCTL_3124REGISTER_MAP_PORT_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 PORT Register...\n");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
status = STATUS_SUCCESS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -