⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dispatchroutines.c

📁 此驱动程序是SATA功能的PCI卡为例
💻 C
📖 第 1 页 / 共 5 页
字号:
	IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
	LongBuffer = (PULONG)IoBuffer;
	MapAddress.LowPart = LongBuffer[0];
	MapAddress.HighPart = 0x00000000;
	DebugPrint("the address needed to map:0x%x",LongBuffer[0]);
    
	MappedAddress = (PUCHAR)MmMapIoSpace(MapAddress,pdx->PortRegisterBytes/4,MmNonCached);
		if(!MappedAddress)
		{
			DebugPrint("the Port register call MmMapIOSpace failed!");		
		}

    DebugPrint("the Port address after mapped is 0x%x",MappedAddress);
    *LongBuffer = (ULONG)MappedAddress;
	DebugPrint("Map Register end...\n");
	return status;

}
/******************************************************************************************************************
 *
 * Function   :  IOCTL_3124REGISTER_MAP_GLOBAL_Handler
 *
 * Description:  Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124REGISTER_MAP_GLOBAL
 ******************************************************************************************************************/
NTSTATUS IOCTL_3124REGISTER_MAP_GLOBAL_Handler(IN PDEVICE_OBJECT fdo,
						                         IN PIRP pIrp)
{
	NTSTATUS status;
	PDEVICE_EXTENSION	pdx;
    PIO_STACK_LOCATION  pIrpStack;

	PVOID   IoBuffer;
    PULONG  LongBuffer; 
	PUCHAR  MappedAddress;
	PHYSICAL_ADDRESS MapAddress;

	DebugPrint("start Map GLOBAL Register...\n");
    
    pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
    pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
	status = STATUS_SUCCESS;

	IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
	LongBuffer = (PULONG)IoBuffer;
	MapAddress.LowPart = LongBuffer[0];
	MapAddress.HighPart = 0x00000000;
	DebugPrint("the address needed to map:0x%x",LongBuffer[0]);

	MappedAddress = (PUCHAR)MmMapIoSpace(MapAddress,pdx->GlobalRegisterBytes,MmNonCached);
		if(!MappedAddress)
		{
			DebugPrint("the Global register call MmMapIOSpace failed!");		
		}

    DebugPrint("the GLOBAL address after mapped is 0x%x",MappedAddress);
    *LongBuffer = (ULONG)MappedAddress;
	DebugPrint("Map Register end...\n");
	return status;

}
/******************************************************************************************************************
 *
 * Function   :  IOCTL_3124REGISTER_UNMAP_PORT_Handler
 *
 * Description:  Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124REGISTER_UNMAP_PORT
 ******************************************************************************************************************/
NTSTATUS IOCTL_3124REGISTER_UNMAP_PORT_Handler(IN PDEVICE_OBJECT fdo,
						                         IN PIRP pIrp)
{
	NTSTATUS status;
	PDEVICE_EXTENSION	pdx;
    PIO_STACK_LOCATION  pIrpStack;

	PVOID   IoBuffer;
    PULONG  LongBuffer; 

	DebugPrint("start UNMap Port Register...\n");

    pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
    pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

	
    IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
	LongBuffer = (PULONG)IoBuffer;
	DebugPrint("the address needed to unmap:0x%x",LongBuffer[0]);

	MmUnmapIoSpace((PUCHAR)LongBuffer[0],pdx->PortRegisterBytes/4);

	status = STATUS_SUCCESS;
	DebugPrint("UNMap Port Register end...\n");
	return status;

}
/******************************************************************************************************************
 *
 * Function   :  IOCTL_3124REGISTER_UNMAP_GLOBAL_Handler
 *
 * Description:  Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124REGISTER_UNMAP_GLOBAL
 ******************************************************************************************************************/
NTSTATUS IOCTL_3124REGISTER_UNMAP_GLOBAL_Handler(IN PDEVICE_OBJECT fdo,
						                         IN PIRP pIrp)
{
	NTSTATUS status;
	PDEVICE_EXTENSION	pdx;
    PIO_STACK_LOCATION  pIrpStack;

	PVOID   IoBuffer;
    PULONG  LongBuffer; 

	DebugPrint("start UNMap GLOBAL Register...\n");

    pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
    pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

	
    IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
	LongBuffer = (PULONG)IoBuffer;
	DebugPrint("the address needed to unmap:0x%x",LongBuffer[0]);
	
	MmUnmapIoSpace((PUCHAR)LongBuffer[0],pdx->GlobalRegisterBytes);

	status = STATUS_SUCCESS;
	DebugPrint("UNMap GLOBAL Register end...\n");
	return status;

}

/******************************************************************************************************************
 *
 * Function   :  IOCTL_GET_3124_PORT_RESET_Handler
 *
 * Description:  Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124_PORT_RESET
 ******************************************************************************************************************/
NTSTATUS IOCTL_3124_PORT_RESET_Handler(IN PDEVICE_OBJECT fdo,
						                   IN PIRP pIrp)
{
	NTSTATUS status;
	PDEVICE_EXTENSION	pdx;
    PIO_STACK_LOCATION  pIrpStack;
	ULONG  i = 0;

	PVOID   IoBuffer;
    PULONG  LongBuffer;

	DebugPrint("start Reset Port...\n");
    
    pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
    pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

	IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
	LongBuffer = (PULONG)IoBuffer;
	DebugPrint("the port base address: 0x%x",LongBuffer[0]);

	DebugPrint("0x%x",READ_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1800)));
    DebugPrint("0x%x",READ_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1000)));
	DebugPrint("0x%x",READ_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1004)));
	DebugPrint("0x%x",READ_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1008)));
	DebugPrint("0x%x",READ_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1010)));

	WRITE_REGISTER_UCHAR((PUCHAR)((PUCHAR)(LongBuffer[0]+0x1008)),0x02);//clear the erro Interrupt
    WRITE_REGISTER_UCHAR((PUCHAR)((PUCHAR)(LongBuffer[0])+0x1000),0x01);//declare the port reset condition
	  while(i<1000)
		  i++;
	  DebugPrint("then clear the port reset condition");
      WRITE_REGISTER_UCHAR((PUCHAR)((PUCHAR)(LongBuffer[0])+0x1004),0x01);//clear the port reset condition
	  DebugPrint("enable the completion and erro interrupt");
      WRITE_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1010),0x00000003);//enable interrupt
	status = STATUS_SUCCESS;
	DebugPrint("Reset Port end...\n");
	return status;

}
/******************************************************************************************************************
 *
 * Function   :  IOCTL_3124_DMA_Handler
 *
 * Description:  Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124_DMA_READ OR IOCTL_3124_DMA_WRITE
 ******************************************************************************************************************/
NTSTATUS IOCTL_3124_DMA_Handler(IN PDEVICE_OBJECT fdo,
						                   IN PIRP pIrp)
{
	NTSTATUS status;
	PDEVICE_EXTENSION	pdx;
    PIO_STACK_LOCATION  pIrpStack;

    PDMA_ADAPTER pAdapterObject;
	PDMA_OPERATIONS pDmaOperation;
    PMDL mdlAddress ;
	ULONG TransferBytes             = 0;  //bytes of transfer


	PVOID   IoBuffer;
	PSATAREG48 SATAREG48Buffer;
    PULONG  LongBuffer;

	 pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
    
	pdx->pDmaContext = (pDmaInfo) ExAllocatePool(NonPagedPool,sizeof(DmaInfo));

	status = STATUS_SUCCESS;
   
    pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
      
	IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
    SATAREG48Buffer = (PSATAREG48)IoBuffer;
	LongBuffer = (PULONG)SATAREG48Buffer->rBuf;
	pdx->pDmaContext->PortAddress = LongBuffer[0];
	DebugPrint("the PortAddress is :0x%x",pdx->pDmaContext->PortAddress);
	pdx->pDmaContext->SATAREG48Buffer = SATAREG48Buffer;

	 //check the PCI registers whether are all not available
	if(READ_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1000)) == 0xffffffff)
    {
		DebugPrint("the PCI register  are all not available");
		pdx->TansferedCount = 0;
		CompleteRequestInfo(pIrp,status,pdx->TansferedCount);
		IoStartNextPacket(fdo, TRUE);
		return status;
	}
	//check the port ready
	if((READ_REGISTER_ULONG((PULONG)(LongBuffer[0]+0x1000)) & 0x80000000)  != 0x80000000)
	{
		DebugPrint("the port is not ready,the Sstatus:0x%x",READ_REGISTER_UCHAR((PUCHAR)(LongBuffer[0]+0x1f04)));
		pdx->TansferedCount = 0;
		CompleteRequestInfo(pIrp,status,pdx->TansferedCount);
		IoStartNextPacket(fdo, TRUE);
		return status;
	}
	 //check  whether the drive power on 
	if((READ_REGISTER_UCHAR((PUCHAR)(LongBuffer[0]+0x1f04)) & 0x03) != 0x03)
	{
		DebugPrint("the device is not present and PHY communication is not established .the DET: 0x%x",READ_REGISTER_UCHAR((PUCHAR)(LongBuffer[0]+0x1f04)));
		pdx->TansferedCount = 0;
		CompleteRequestInfo(pIrp,status,pdx->TansferedCount);
		IoStartNextPacket(fdo, TRUE);
		return status;
	}

	pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
    pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

    DebugPrint("start DMA transfer...\n");
 
    mdlAddress = pIrp->MdlAddress;

    // Calculate the number of map registers needed for this transfer.
    pdx->CurrentVirtualAddress =
		    MmGetMdlVirtualAddress (mdlAddress) ;
   pdx->CurrentTransferLength =
		    MmGetMdlByteCount (mdlAddress) ;
	DebugPrint("the total length user's Out Buffer is :%u\n",pdx->CurrentTransferLength);
 
	pdx->WriteToDevice =(pIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_3124_DMA_WRITE);
	if(pdx->WriteToDevice)
		DebugPrint("the transfer is from buffer to device");
	else
		DebugPrint("the transfer is from device to buffer");
    
	pAdapterObject = pdx->AdapterObject;
	pDmaOperation = pAdapterObject->DmaOperations;
   status = (pDmaOperation->GetScatterGatherList)(pdx->AdapterObject,fdo, mdlAddress, 
		                                           pdx->CurrentVirtualAddress , pdx->CurrentTransferLength, 
												   AdapterListControl,pdx->pDmaContext,pdx->WriteToDevice);
	if(status == STATUS_SUCCESS)
		DebugPrint("The adapter channel has been allocated.");
	else
	{
        DebugPrint("The NumberOfMapRegisters is larger than the value returned by IoGetDmaAdapter.");
        CompleteRequestInfo(pIrp, status, TransferBytes);
        IoStartNextPacket(fdo, TRUE);
	}
    
	return status;

}

VOID
AdapterListControl (
    IN PDEVICE_OBJECT fdo,
    IN PIRP pIrp,
    IN PSCATTER_GATHER_LIST ScatterGather,
    IN PVOID Context
    )

{
    PDEVICE_EXTENSION	pdx;
    PIO_STACK_LOCATION  pIrpStack;
    PMDL mdlAddress ;
	PDMA_ADAPTER pAdapterObject;
	PHYSICAL_ADDRESS PAddress;

	pDmaInfo pDmaContext;
	PSATAREG48 SATAREG48Buffer;
	ULONG    PortBaseAddress,PortStatus,i,j,CountOfSGE,DmaRead,SGTCount,SGTRem;
	USHORT   SectorCount;

    pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
    pDmaContext = (pDmaInfo)Context;
	SATAREG48Buffer = pDmaContext->SATAREG48Buffer;
	PortBaseAddress = pDmaContext->PortAddress;
	//store Port base address into DeviceExtension
	pdx->PortBaseAddress = PortBaseAddress;

	DebugPrint("AdapterListControl Routine begin being called....0x%x",PortBaseAddress);
    mdlAddress = pIrp->MdlAddress ;

	pdx->ScatterGatherList = ScatterGather;

	CountOfSGE = pdx->ScatterGatherList->NumberOfElements;

    KeFlushIoBuffers (mdlAddress, !pdx->WriteToDevice, TRUE) ;
	DebugPrint("the count of SCATTER_GATHER_ELEMENT in list is%u",CountOfSGE);
    //calculate the bytes needed to be transfered
    SectorCount = SATAREG48Buffer->secc_pre;
    SectorCount <<= 8;
	SectorCount |= SATAREG48Buffer->secc_cur;
	
	pdx->BytesTransfer = SectorCount * 512;
/*****************************************************************************
*  Create a PRB and Fill it with specific parameters
******************************************************************************/
	pdx->PRBStruct = (pPRB) ExAllocatePool(NonPagedPool,sizeof(PRB));
	DebugPrint("PRB system address is:0x%x",(ULONG)pdx->PRBStruct);
	PAddress = MmGetPhysicalAddress(pdx->PRBStruct);
	DebugPrint("PRBS Physical address is:0x%x",(ULONG)PAddress.LowPart);
    //Make PRB 8 bytes aligned
	while((PAddress.LowPart)% 8 != 0)
	{
		ExFreePool(pdx->PRBStruct);
		pdx->PRBStruct = (pPRB) ExAllocatePool(NonPagedPool,sizeof(PRB));
		PAddress = MmGetPhysicalAddress(pdx->PRBStruct);
		DebugPrint(" After ReAllocate Physical Address is:0x%x\n" ,PAddress.LowPart );
		DebugPrint(" After ReAllocate System Address is:0x%x\n" ,(ULONG)pdx->PRBStruct);
	}
    pdx->PRBStruct->Control          = 0x0000;
	pdx->PRBStruct->ProtocolOverride = 0x0000;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -