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