www.pudn.com > driver.zip > DispatchRoutines.c
/******************************************************************************
* * File Name:
* * DispatchRoutines.c
* * Description:
* * This file routes incoming I/O Request packets.
* * Revision History:
* * 10-11-07 : Silicon Image 1.00
*******************************************************************************/
#include "Sil3124.h"
/******************************************************************************
*
* Function : DispatchCreate
*
* Description: Handle IRP_MJ_CREATE, which allows applications to open handles
* to our device, win32 function is CreateFile().
*
******************************************************************************/
NTSTATUS DispatchCreate(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{ //DispatchCreate
DebugPrint("DispatchCreate Routine start...");
//we can do some initial things here
return(CompleteRequestInfo(pIrp, STATUS_SUCCESS,0));
} //DispatchCreate
/************************************************************************
*
* Function : DispatchClose
*
* Description: Handle IRP_MJ_CLOSE, which allows applications to close handles
* to our device£¬win32 function is CloseHandle().
*
******************************************************************************/
NTSTATUS DispatchClose(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{ //DispatchClose
//todo
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
DebugPrint("DispatchClose Routine start...");
return(CompleteRequestInfo(pIrp,STATUS_SUCCESS,0));
} //DispatchClose
/******************************************************************************
*
* Function : DispatchRead
*
* Description: Handle IRP_MJ_READ
******************************************************************************/
NTSTATUS DispatchRead(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{ //DispatchRead
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
DebugPrint("DispatchRead Routine start...");
// If the request has a buffer of length 0, we will complete it right here.
if (pIrpStack->Parameters.Read.Length == 0) {
pIrp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH ;
pIrp->IoStatus.Information = 0 ;
IoCompleteRequest (pIrp, IO_NO_INCREMENT) ;
return STATUS_INFO_LENGTH_MISMATCH ;
}
//pass this Irp to StartIo;
IoMarkIrpPending(pIrp);
IoStartPacket(fdo, pIrp, NULL, NULL);
DebugPrint("Read Device End.");
return STATUS_PENDING;
}
//DispatchRead
/******************************************************************************
*
* Function : DispatchWrite
*
* Description: Handle IRP_MJ_WRITE
******************************************************************************/
NTSTATUS DispatchWrite(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{ //DispatchWrite
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
DebugPrint("DispatchWrite Routine start...%u",sizeof(PRB));
// If the request has a buffer of length 0, we will complete it right here.
if (pIrpStack->Parameters.Write.Length == 0) {
pIrp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH ;
pIrp->IoStatus.Information = 0 ;
IoCompleteRequest (pIrp, IO_NO_INCREMENT) ;
return STATUS_INFO_LENGTH_MISMATCH ;
}
//pass this Irp to StartIo;
IoMarkIrpPending(pIrp);
IoStartPacket(fdo, pIrp, NULL, NULL);
DebugPrint("Write Device End.");
return STATUS_PENDING;
}
//DispatchWrite
/***********************************************************
*
* Function : CompleteRequestInfo
*
* Description : Complete the request without infomation.
*
************************************************************/
NTSTATUS CompleteRequest(IN PIRP Irp,
IN NTSTATUS status)
{ // CompleteRequest
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(status);
} // CompleteRequest
//////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
NTSTATUS CompleteRequestInfo(IN PIRP Irp,
IN NTSTATUS status,
IN ULONG_PTR info)
{ // CompleteRequestInfo
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = info;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(status);
} // CompleteRequestInfo
/******************************************************************************
*
* Function : StartIo
*
* Description: The StartIo Service Routine for PCI9052Demo.
*
******************************************************************************/
VOID StartIo(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{ //StartIo
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PIO_STACK_LOCATION pIrpStack;
ULONG TransferBytes = 0; //bytes of transfer
DebugPrint("the StartIo begin...");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
status = STATUS_SUCCESS;
switch(pIrpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_3124REGISTER_PIO_READ:
DebugPrint("Sil3124 PIO read begin in startIo...");
status = IOCTL_3124REGISTER_PIO_READ_Handler(fdo,pIrp);
if(status == STATUS_SUCCESS)
TransferBytes = pdx->TansferedCount;
break;
case IOCTL_3124REGISTER_PIO_WRITE:
DebugPrint("Sil3124 PIO write begin in startIo...");
status = IOCTL_3124REGISTER_PIO_WRITE_Handler(fdo,pIrp);
if(status == STATUS_SUCCESS)
TransferBytes = pdx->TansferedCount;
break;
case IOCTL_3124REGISTER_COMMAND:
DebugPrint("Sil3124 no-data commands begin in startIo...");
status = IOCTL_3124REGISTER_COMMAND_Handler(fdo,pIrp);
break;
case IOCTL_3124_DMA_READ:
DebugPrint("Sil3124 DMA Read begin in startIo...");
status = IOCTL_3124_DMA_Handler(fdo,pIrp);
break;
case IOCTL_3124_DMA_WRITE:
DebugPrint("Sil3124 DMA Write begin in startIo...");
status = IOCTL_3124_DMA_Handler(fdo,pIrp);
break;
default:
status = STATUS_NOT_SUPPORTED;
break;
}
DebugPrint("StartIo End.");
} //StartIo
/******************************************************************************
*
* Function : DispatchIoControl
*
* Description: Handle IRP_MJ_DEVICE_CONTROL
******************************************************************************/
NTSTATUS DispatchIoControl(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{ //DispatchIoControl
ULONG ReturnedValue = 0; //bytes transfered
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PIO_STACK_LOCATION pIrpStack;
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
// Assume a successful return status
status = STATUS_SUCCESS;
DebugPrint("DeviceIoControl Start...");
// Handle the Sil3124 specific request
switch (pIrpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_GET_3124REGISTER_PORT0_BASEADDRESS: //obtain channel#0's base address
DebugPrint("request Port0 Register base address...\n");
status = IOCTL_GET_3124REGISTER_PORT0_BASEADDRESS_Handler(fdo,pIrp);
if(status == STATUS_SUCCESS)
ReturnedValue = 4;
break;
case IOCTL_GET_3124REGISTER_PORT1_BASEADDRESS: //obtain channel#1's base address
DebugPrint("request Port1 Register base address...\n");
status = IOCTL_GET_3124REGISTER_PORT1_BASEADDRESS_Handler(fdo,pIrp);
if(status == STATUS_SUCCESS)
ReturnedValue = 4;
break;
case IOCTL_GET_3124REGISTER_PORT2_BASEADDRESS: //obtain channel#2's base address
DebugPrint("request Port2 Register base address...\n");
status = IOCTL_GET_3124REGISTER_PORT2_BASEADDRESS_Handler(fdo,pIrp);
if(status == STATUS_SUCCESS)
ReturnedValue = 4;
break;
case IOCTL_GET_3124REGISTER_PORT3_BASEADDRESS: //obtain channel#3's base address
DebugPrint("request Port3 Register base address...\n");
status = IOCTL_GET_3124REGISTER_PORT3_BASEADDRESS_Handler(fdo,pIrp);
if(status == STATUS_SUCCESS)
ReturnedValue = 4;
break;
case IOCTL_GET_3124REGISTER_GLOBAL_BASEADDRESS: //obtain Global base address
DebugPrint("request Global Register base address...\n");
status = IOCTL_GET_3124REGISTER_GLOBAL_BASEADDRESS_Handler(fdo,pIrp);
if(status == STATUS_SUCCESS)
ReturnedValue = 4;
break;
case IOCTL_GET_3124PORT_INDIRECT_BASEADDRESS: //obtain Global base address
DebugPrint("request indirect access Register base address...\n");
status = IOCTL_GET_3124PORT_INDIRECT_BASEADDRESS_Handler(fdo,pIrp);
if(status == STATUS_SUCCESS)
ReturnedValue = 4;
break;
case IOCTL_3124REGISTER_PIO_READ:
DebugPrint("request PIO READ command,...\n");
//pass it to StartIo
IoMarkIrpPending(pIrp);
IoStartPacket(fdo, pIrp, NULL, NULL);
status = STATUS_PENDING;
break;
case IOCTL_3124REGISTER_PIO_WRITE:
DebugPrint("request PIO WRITE command...\n");
//pass it to StartIo
IoMarkIrpPending(pIrp);
IoStartPacket(fdo, pIrp, NULL, NULL);
status = STATUS_PENDING;
break;
case IOCTL_GET_3124TASKFILE:
DebugPrint("require to obtain task file register status");
status = IOCTL_GET_3124TASKFILE_Handler(fdo,pIrp);
if(status == STATUS_SUCCESS)
ReturnedValue = 1;
break;
case IOCTL_3124REGISTER_COMMAND:
DebugPrint("request to execute ATA command(s) without data transfer");
//pass it to StartIo
IoMarkIrpPending(pIrp);
IoStartPacket(fdo, pIrp, NULL, NULL);
status = STATUS_PENDING;
break;
case IOCTL_3124REGISTER_MAP_PORT:
DebugPrint("request to map PORT register");
status = IOCTL_3124REGISTER_MAP_PORT_Handler(fdo,pIrp);
ReturnedValue = 4;
break;
case IOCTL_3124REGISTER_MAP_GLOBAL:
DebugPrint("request to map GLOBAL register");
status = IOCTL_3124REGISTER_MAP_GLOBAL_Handler(fdo,pIrp);
ReturnedValue = 4;
break;
case IOCTL_3124REGISTER_UNMAP_PORT:
DebugPrint("request to unmap PORT register");
status = IOCTL_3124REGISTER_UNMAP_PORT_Handler(fdo,pIrp);
break;
case IOCTL_3124REGISTER_UNMAP_GLOBAL:
DebugPrint("request to unmap GLOBAL register");
status = IOCTL_3124REGISTER_UNMAP_GLOBAL_Handler(fdo,pIrp);
break;
case IOCTL_3124_PORT_RESET:
DebugPrint("request to Reset Port");
status = IOCTL_3124_PORT_RESET_Handler(fdo,pIrp);
break;
case IOCTL_3124_DMA_READ:
DebugPrint("request to DMA READ");
IoMarkIrpPending(pIrp);
IoStartPacket(fdo, pIrp, NULL, NULL);
status = STATUS_PENDING;
break;
case IOCTL_3124_DMA_WRITE:
DebugPrint("request to DMA WRITE");
IoMarkIrpPending(pIrp);
IoStartPacket(fdo, pIrp, NULL, NULL);
status = STATUS_PENDING;
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
DebugPrintMsg("unsupport device control code");
break;
}
DebugPrint("DeviceIoControl End.");
if (status == STATUS_PENDING)
return STATUS_PENDING;
return CompleteRequestInfo(pIrp,status,ReturnedValue);
} //DispatchIoControl
/******************************************************************************************************************
*
* Function : IOCTL_GET_3124REGISTER_PORT0_BASEADDRESS_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_GET_3124REGISTER_PORT0_BASEADDRESS
******************************************************************************************************************/
NTSTATUS IOCTL_GET_3124REGISTER_PORT0_BASEADDRESS_Handler(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PVOID IoBuffer;
PULONG LongBuffer;
DebugPrint("start obtaining PORT0 base address...\n");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
LongBuffer = (PULONG)IoBuffer;
*LongBuffer = (ULONG)pdx->BaseAddress_PortRegister.LowPart;
DebugPrint("the port0 base address returned to user is :0x%x\n",LongBuffer[0]);
// Assume a successful return status
status = STATUS_SUCCESS;
DebugPrint("PORT0 base address getting end...\n");
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_GET_3124REGISTER_PORT1_BASEADDRESS_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_GET_3124REGISTER_PORT1_BASEADDRESS
******************************************************************************************************************/
NTSTATUS IOCTL_GET_3124REGISTER_PORT1_BASEADDRESS_Handler(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PVOID IoBuffer;
PULONG LongBuffer;
DebugPrint("start obtaining PORT1 base address...\n");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
LongBuffer = (PULONG)IoBuffer;
*LongBuffer = (ULONG)(pdx->BaseAddress_PortRegister.LowPart+0x2000);
DebugPrint("the port1 base address returned to user is :0x%x\n",LongBuffer[0]);
// Assume a successful return status
status = STATUS_SUCCESS;
DebugPrint("PORT1 base address getting end...\n");
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_GET_3124REGISTER_PORT2_BASEADDRESS_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_GET_3124REGISTER_PORT2_BASEADDRESS
******************************************************************************************************************/
NTSTATUS IOCTL_GET_3124REGISTER_PORT2_BASEADDRESS_Handler(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PVOID IoBuffer;
PULONG LongBuffer;
DebugPrint("start obtaining PORT2 base address...\n");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
LongBuffer = (PULONG)IoBuffer;
*LongBuffer = (ULONG)(pdx->BaseAddress_PortRegister.LowPart+2*0x2000);
DebugPrint("the port2 base address returned to user is :0x%x\n",LongBuffer[0]);
// Assume a successful return status
status = STATUS_SUCCESS;
DebugPrint("PORT2 base address getting end...\n");
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_GET_3124REGISTER_PORT3_BASEADDRESS_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_GET_3124REGISTER_PORT3_BASEADDRESS
******************************************************************************************************************/
NTSTATUS IOCTL_GET_3124REGISTER_PORT3_BASEADDRESS_Handler(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PVOID IoBuffer;
PULONG LongBuffer;
DebugPrint("start obtaining PORT3 base address...\n");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
LongBuffer = (PULONG)IoBuffer;
*LongBuffer = (ULONG)(pdx->BaseAddress_PortRegister.LowPart+3*0x2000);
DebugPrint("the port3 base address returned to user is :0x%x\n",LongBuffer[0]);
// Assume a successful return status
status = STATUS_SUCCESS;
DebugPrint("PORT3 base address getting end...\n");
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_GET_3124REGISTER_GLOBAL_BASEADDRESS_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_GET_3124REGISTER_GLOBAL_BASEADDRESS
******************************************************************************************************************/
NTSTATUS IOCTL_GET_3124REGISTER_GLOBAL_BASEADDRESS_Handler(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PVOID IoBuffer;
PULONG LongBuffer;
DebugPrint("start obtaining GLOBAL base address...\n");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
LongBuffer = (PULONG)IoBuffer;
*LongBuffer = (ULONG)pdx->BaseAddress_GlobalRegister.LowPart;
DebugPrint("the global base address returned to user is :0x%x\n",LongBuffer[0]);
// Assume a successful return status
status = STATUS_SUCCESS;
DebugPrint("global base address getting end...\n");
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_GET_3124PORT_INDIRECT_BASEADDRESS_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_GET_3124PORT_INDIRECT_BASEADDRESS
******************************************************************************************************************/
NTSTATUS IOCTL_GET_3124PORT_INDIRECT_BASEADDRESS_Handler(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{
NTSTATUS status;
PDEVICE_EXTENSION pdx;
PVOID IoBuffer;
PULONG LongBuffer;
DebugPrint("start obtaining indirect access base address...\n");
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
LongBuffer = (PULONG)IoBuffer;
*LongBuffer = (ULONG)pdx->BaseAddress_Indirect_Access.LowPart;
DebugPrint("the indirect access register base address returned to user is :0x%x\n",LongBuffer[0]);
// Assume a successful return status
status = STATUS_SUCCESS;
DebugPrint("indirect access base address getting end...\n");
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_3124REGISTER_PIO_READ_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124REGISTER_PIO_READ
******************************************************************************************************************/
NTSTATUS IOCTL_3124REGISTER_PIO_READ_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 PIOReadBuffer,PAddress;
ULONG PIOReadCount;
USHORT SectorCount;
ULONG i,RequestCount;
ULONG PortStatus;
PUCHAR SlotBaseAddress; //slot base address
status = STATUS_SUCCESS; // Assume a successful return status
DebugPrint("start PIO READ...\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->ReadBuffer = (PUCHAR) ExAllocatePool(NonPagedPool,RequestCount);
PIOReadBuffer = MmGetPhysicalAddress(pdx->ReadBuffer);
PIOReadCount = RequestCount;
DebugPrint("the SGE0 address is %x, data count is %u",PIOReadBuffer.LowPart,PIOReadCount);
/*****************************************************************************
* 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)PIOReadBuffer.LowPart;
pdx->PRBStruct->SGE0High = 0x00000000;
pdx->PRBStruct->SGE0Count = PIOReadCount;
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)));
WRITE_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1C00),PAddress.LowPart);
WRITE_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1C04),0x00000000);
pdx->NeedToHandle =TRUE;
return status;
}
/******************************************************************************************************************
*
* Function : IOCTL_3124REGISTER_PIO_WRITE_Handler
*
* Description: Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124REGISTER_PIO_WRITE
******************************************************************************************************************/
NTSTATUS IOCTL_3124REGISTER_PIO_WRITE_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 PIOWriteBuffer,PAddress;
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;
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;
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;
/******************** Begin to Fill SGE **********************************************/
pdx->LogicalAddress = (PHYSICAL_ADDRESS *)ExAllocatePool(NonPagedPool,CountOfSGE*sizeof(PHYSICAL_ADDRESS));
switch(CountOfSGE)
{
case 1:
pdx->LogicalAddress[0] = pdx->ScatterGatherList->Elements[0].Address;
DmaRead = pdx->ScatterGatherList->Elements[0].Length;
pdx->SGEControl = 0x80000000;
DebugPrint("the Address:0x%x....the Length :%u",pdx->LogicalAddress[0].LowPart,DmaRead);
pdx->PRBStruct->SGE0Low = pdx->LogicalAddress[0].LowPart;
pdx->PRBStruct->SGE0High = 0x00000000;
pdx->PRBStruct->SGE0Count = DmaRead;
pdx->PRBStruct->SGE0Control = pdx->SGEControl;
break;
case 2:
// fill first SGE
pdx->LogicalAddress[0] = pdx->ScatterGatherList->Elements[0].Address;
DmaRead = pdx->ScatterGatherList->Elements[0].Length;
pdx->SGEControl = 0x00000000;
DebugPrint("the Address:0x%x....the Length :%u",pdx->LogicalAddress[0].LowPart,DmaRead);
pdx->PRBStruct->SGE0Low = pdx->LogicalAddress[0].LowPart;
pdx->PRBStruct->SGE0High = 0x00000000;
pdx->PRBStruct->SGE0Count = DmaRead;
pdx->PRBStruct->SGE0Control = pdx->SGEControl;
//fill second SGE
pdx->LogicalAddress[1] = pdx->ScatterGatherList->Elements[1].Address;
DmaRead = pdx->ScatterGatherList->Elements[1].Length;
pdx->SGEControl = 0x80000000;
DebugPrint("the Address:0x%x....the Length :%u",pdx->LogicalAddress[1].LowPart,DmaRead);
pdx->PRBStruct->SGE1Low = pdx->LogicalAddress[1].LowPart;
pdx->PRBStruct->SGE1High = 0x00000000;
pdx->PRBStruct->SGE1Count = DmaRead;
pdx->PRBStruct->SGE1Control = pdx->SGEControl;
break;
default:
//if the requested SGE count is larger than two,then we must build SGT in host.
// fill first SGE
pdx->LogicalAddress[0] = pdx->ScatterGatherList->Elements[0].Address;
DmaRead = pdx->ScatterGatherList->Elements[0].Length;
pdx->SGEControl = 0x00000000;
DebugPrint("the Address:0x%x....the Length :%u",pdx->LogicalAddress[0].LowPart,DmaRead);
pdx->PRBStruct->SGE0Low = pdx->LogicalAddress[0].LowPart;
pdx->PRBStruct->SGE0High = 0x00000000;
pdx->PRBStruct->SGE0Count = DmaRead;
pdx->PRBStruct->SGE0Control = pdx->SGEControl;
//calculate the count of needed SG Table
SGTCount = CountOfSGE/3;
SGTRem = CountOfSGE%3;
DebugPrint("the count of SG table:%u",SGTCount);
pdx->SGTPAddress = (PHYSICAL_ADDRESS *)ExAllocatePool(NonPagedPool,SGTCount*sizeof(PHYSICAL_ADDRESS));
pdx->pSGT = (pSGTable)ExAllocatePool(NonPagedPool,SGTCount*sizeof(SGTable));
// DebugPrint("SGT system address is:0x%x",(ULONG)pdx->pSGT);
for(i = 0;iSGTPAddress[i] = MmGetPhysicalAddress(pdx->pSGT+i);
DebugPrint("SGT Physical address is:0x%x",(ULONG)pdx->SGTPAddress[i].LowPart);
//Make SGT 8 bytes aligned
while((pdx->SGTPAddress[i].LowPart)% 8 != 0)
{
ExFreePool(pdx->pSGT);
pdx->pSGT = (pSGTable)ExAllocatePool(NonPagedPool,SGTCount*sizeof(SGTable));
for(j=0;jSGTPAddress[j] = MmGetPhysicalAddress(pdx->pSGT+j);
DebugPrint(" After ReAllocate Physical Address is:0x%x\n" ,pdx->SGTPAddress[j].LowPart );
DebugPrint(" After ReAllocate System Address is:0x%x\n" ,(ULONG)pdx->pSGT);
}
}
//fill second SGE which contains the following SGT's address
pdx->LogicalAddress[1] = pdx->SGTPAddress[0];
// DmaRead = pdx->ScatterGatherList->Elements[1].Length;
pdx->SGEControl = 0x40000000;
DebugPrint("the first SGT's Address:0x%x....",pdx->LogicalAddress[1].LowPart);
pdx->PRBStruct->SGE1Low = pdx->LogicalAddress[1].LowPart;
pdx->PRBStruct->SGE1High = 0x00000000;
// pdx->PRBStruct->SGE1Count = DmaRead;
pdx->PRBStruct->SGE1Control = pdx->SGEControl;
//fill SGT
j = 0;
for(i = 0;ipSGT+i)->SGE0Low = pdx->ScatterGatherList->Elements[i+j+1].Address.LowPart;
(pdx->pSGT+i)->SGE0High = 0x00000000;
(pdx->pSGT+i)->SGE0Count = pdx->ScatterGatherList->Elements[i+j+1].Length;
(pdx->pSGT+i)->SGE0Control = 0x00000000;
(pdx->pSGT+i)->SGE1Low = pdx->ScatterGatherList->Elements[i+j+2].Address.LowPart;
(pdx->pSGT+i)->SGE1High = 0x00000000;
(pdx->pSGT+i)->SGE1Count = pdx->ScatterGatherList->Elements[i+j+2].Length;
if(SGTRem == 0)
(pdx->pSGT+i)->SGE1Control = 0x80000000;
else if(SGTRem == 1)
{
(pdx->pSGT+i)->SGE1Control = 0x00000000;
(pdx->pSGT+i)->SGE2Low = pdx->ScatterGatherList->Elements[i+j+3].Address.LowPart;
(pdx->pSGT+i)->SGE2High = 0x00000000;
(pdx->pSGT+i)->SGE2Count = pdx->ScatterGatherList->Elements[i+j+3].Length;
(pdx->pSGT+i)->SGE2Control = 0x80000000;
}
else
{
(pdx->pSGT+i)->SGE1Control = 0x00000000;
(pdx->pSGT+i)->SGE2Low = pdx->ScatterGatherList->Elements[i+j+3].Address.LowPart;
(pdx->pSGT+i)->SGE2High = 0x00000000;
(pdx->pSGT+i)->SGE2Count = pdx->ScatterGatherList->Elements[i+j+3].Length;
(pdx->pSGT+i)->SGE2Control = 0x00000000;
(pdx->pSGT+i)->SGE3Low = pdx->ScatterGatherList->Elements[i+j+4].Address.LowPart;
(pdx->pSGT+i)->SGE3High = 0x00000000;
(pdx->pSGT+i)->SGE3Count = pdx->ScatterGatherList->Elements[i+j+4].Length;
(pdx->pSGT+i)->SGE3Control = 0x80000000;
}
}
else
{ DebugPrint("now the start elements index:%u",i+j+1);
(pdx->pSGT+i)->SGE0Low = pdx->ScatterGatherList->Elements[i+j+1].Address.LowPart;
(pdx->pSGT+i)->SGE0High = 0x00000000;
(pdx->pSGT+i)->SGE0Count = pdx->ScatterGatherList->Elements[i+j+1].Length;
(pdx->pSGT+i)->SGE0Control = 0x00000000;
(pdx->pSGT+i)->SGE1Low = pdx->ScatterGatherList->Elements[i+j+2].Address.LowPart;
(pdx->pSGT+i)->SGE1High = 0x00000000;
(pdx->pSGT+i)->SGE1Count = pdx->ScatterGatherList->Elements[i+j+2].Length;
(pdx->pSGT+i)->SGE1Control = 0x00000000;
(pdx->pSGT+i)->SGE2Low = pdx->ScatterGatherList->Elements[i+j+3].Address.LowPart;
(pdx->pSGT+i)->SGE2High = 0x00000000;
(pdx->pSGT+i)->SGE2Count = pdx->ScatterGatherList->Elements[i+j+3].Length;
(pdx->pSGT+i)->SGE2Control = 0x00000000;
(pdx->pSGT+i)->SGE3Low = pdx->SGTPAddress[i+1].LowPart;
(pdx->pSGT+i)->SGE3High = 0x00000000;
// (pdx->pSGT+i)->SGE3Count = pdx->ScatterGatherList->Elements[i+4].Length;
(pdx->pSGT+i)->SGE3Control = 0x40000000;
}
j+=2;
}
break;
}
/**************************Fill End*********************************************************************/
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;
DebugPrint("the port slot status as soon as command is issued 0x%x",READ_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1800)));
if(pdx->pDmaContext)
{
ExFreePool(pdx->pDmaContext);
DebugPrint("ExFreePool pdx->pDmaContext");
pdx->pDmaContext = NULL;
}
}
/******************************************************************************
*
* Function : OnInterrupt
*
* Description: The Interrupt Service Routine for the device.
*
* Note£ºIRS run at DIRQL,so handle carefully
******************************************************************************/
BOOLEAN OnInterrupt(IN PKINTERRUPT pInterrupt,
IN PDEVICE_EXTENSION pdx)//IN PVOID pdx)
{ //OnInterrupt
PDEVICE_OBJECT fdo;
PIRP pIrp;
UCHAR CompleteStatus,ClearInterruptStatus;
if(!pdx->NeedToHandle)
return TRUE;
DebugPrint("Enter ISR Routine...........");
DebugPrint("0x%x,",READ_REGISTER_ULONG((PULONG)(pdx->PortBaseAddress+0x1010)));
DebugPrint("0x%x,0x%x",READ_REGISTER_ULONG((PULONG)(pdx->PortBaseAddress+0x1000)),READ_REGISTER_ULONG((PULONG)(pdx->PortBaseAddress+0x1008)));
CompleteStatus = READ_REGISTER_UCHAR((PUCHAR)(pdx->PortBaseAddress+0x1008));
CompleteStatus &= 0x01;
if(CompleteStatus != 0x01) //check if it is Sil3124's Command Completion Interrupt
{
return TRUE;
}
ClearInterruptStatus = READ_REGISTER_UCHAR((PUCHAR)(pdx->PortBaseAddress+0x1000));
ClearInterruptStatus &= 0x08;
if(ClearInterruptStatus ==0x00)//if Interrupt NCoR ==0
READ_REGISTER_ULONG((PULONG)(pdx->PortBaseAddress+0x1800)); //read port slot status register to clear completion command interrupt
else
WRITE_REGISTER_UCHAR((PUCHAR)pdx->PortBaseAddress+0x1008,0x01);// write 1 to port interrupt status clear register to clear the completion
WRITE_REGISTER_UCHAR((PUCHAR)pdx->PortBaseAddress+0x1008,0x04);//clear the Port Ready Interrupt
//if it is command completion interrupt,set NeedToHandle condition to FLASE,
//it makes power management change interrupt can not be handle by following progress
pdx->NeedToHandle = FALSE;
fdo = ((PDEVICE_EXTENSION)pdx)->pDeviceObject;
if (fdo != NULL)
{
pIrp = fdo->CurrentIrp;
if (pIrp != NULL)
{
IoRequestDpc(fdo, pIrp, (PVOID)pdx);
}
}
return TRUE;
} //OnInterrupt
/******************************************************************************
*
* Function : DpcForIsr
*
* Description: This routine will be triggered by the ISR to service an interrupt.
******************************************************************************/
VOID DpcForIsr(IN PKDPC pDpc,
IN PDEVICE_OBJECT fdo,
IN PIRP pIrp,
IN PDEVICE_EXTENSION pdx)
{ //OnInterrupt DpcForIsr
NTSTATUS status;
ULONG ReturnedValue;
PIO_STACK_LOCATION pIrpStack;
PVOID IoBuffer;
PDMA_ADAPTER pAdapterObject;
PDMA_OPERATIONS pDmaOperation;
DebugPrint("Enter DPC For ISR Routine...........");
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
ReturnedValue = READ_REGISTER_ULONG((PULONG)(pdx->PortBaseAddress+0x04));
IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
status = STATUS_SUCCESS;
switch(pIrpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_3124REGISTER_PIO_READ:
DebugPrint("Sil3124 PIO read enter DPC...");
//copy the data to be written into disk to the WriteBuffer
RtlMoveMemory(IoBuffer,pdx->ReadBuffer,ReturnedValue);
if(pdx->ReadBuffer)
{
ExFreePool(pdx->ReadBuffer);
pdx->ReadBuffer = NULL;
DebugPrint("free pdx->readbuffer");
}
if(pdx->PRBStruct)
{
ExFreePool(pdx->PRBStruct);
pdx->PRBStruct = NULL;
DebugPrint("free pdx->PRBStruct");
}
pdx->BytesTransfered = ReturnedValue;
status = STATUS_SUCCESS;
break;
case IOCTL_3124REGISTER_PIO_WRITE:
DebugPrint("Sil3124 PIO write enter DPC...");
if(pdx->WriteBuffer)
{
ExFreePool(pdx->WriteBuffer);
pdx->WriteBuffer = NULL;
DebugPrint("free pdx->Writebuffer");
}
if(pdx->PRBStruct)
{
ExFreePool(pdx->PRBStruct);
pdx->PRBStruct = NULL;
DebugPrint("free pdx->PRBStruct");
}
pdx->BytesTransfered = pdx->TansferedCount;
status = STATUS_SUCCESS;
break;
case IOCTL_3124REGISTER_COMMAND:
DebugPrint("Sil3124 PIO no data transfer commands enter DPC...");
if(pdx->PRBStruct)
{
ExFreePool(pdx->PRBStruct);
pdx->PRBStruct = NULL;
DebugPrint("free pdx->PRBStruct");
}
pdx->BytesTransfered = 0;
status = STATUS_SUCCESS;
break;
case IOCTL_3124_DMA_READ:
case IOCTL_3124_DMA_WRITE:
DebugPrint("Sil3124 DMA transfer enter DPC...");
if(pdx->LogicalAddress)
{
ExFreePool(pdx->LogicalAddress);
DebugPrint("free pdx->LogiclAddress");
pdx->LogicalAddress = NULL;
}
if(pdx->pSGT)
{
ExFreePool(pdx->pSGT);
DebugPrint("free pdx->pSGT");
pdx->pSGT = NULL;
}
if(pdx->SGTPAddress)
{
ExFreePool(pdx->SGTPAddress);
DebugPrint("free pdx->SGTAddress");
pdx->SGTPAddress = NULL;
}
if(pdx->WriteToDevice)
pdx->BytesTransfered = pdx->BytesTransfer;
else
pdx->BytesTransfered = READ_REGISTER_ULONG((PULONG)(pdx->PortBaseAddress+0x04));
pAdapterObject = pdx->AdapterObject;
pDmaOperation = pAdapterObject->DmaOperations;
pDmaOperation->PutScatterGatherList(pdx->AdapterObject,pdx->ScatterGatherList,pdx->WriteToDevice);
status = STATUS_SUCCESS;
break;
default:
status = STATUS_NOT_SUPPORTED;
break;
}
//complete IRP and start next
DebugPrint("Now,Complete this IRP");
CompleteRequestInfo(pIrp, status, pdx->BytesTransfered);
IoStartNextPacket(fdo, TRUE);
} //OnInterrupt DpcForIsr