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

📄 dispatchroutines.c

📁 此驱动程序是SATA功能的PCI卡为例
💻 C
📖 第 1 页 / 共 5 页
字号:
	ULONG            PIOWriteCount;
	USHORT           SectorCount;
	ULONG i,RequestCount;
	ULONG  PortStatus;

	PUCHAR SlotBaseAddress;  //slot base address

    status = STATUS_SUCCESS;  	// Assume a successful return status

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

	IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
    SATAREG48Buffer = (PSATAREG48)IoBuffer;
    
	LongBuffer = (PULONG)SATAREG48Buffer->rBuf;
	PortBaseAddress = LongBuffer[0];
	pdx->PortBaseAddress = PortBaseAddress;

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

	SlotBaseAddress = (PUCHAR)PortBaseAddress+Slot*0x80;
	SectorCount = SATAREG48Buffer->secc_pre;
    SectorCount <<= 8;
	SectorCount |= SATAREG48Buffer->secc_cur;
	
	RequestCount = SectorCount * 512;
	DebugPrint("the Request count to be transfered is %u,and the PAGE_SIZE is %u",RequestCount,PAGE_SIZE);
/****************************************************************************
* create the region for data transfer
****************************************************************************/
	pdx->WriteBuffer = (PUCHAR) ExAllocatePool(NonPagedPool,RequestCount);
	PIOWriteBuffer = MmGetPhysicalAddress(pdx->WriteBuffer);
	PIOWriteCount =  RequestCount;
	DebugPrint("the SGE0 address is %x, data count is %u",PIOWriteBuffer.LowPart,PIOWriteCount);
//copy the data to be written into disk to the WriteBuffer 
	RtlMoveMemory(pdx->WriteBuffer,SATAREG48Buffer->wBuf,PIOWriteCount);
/*****************************************************************************
*  Create a PRB and Fill it with specific parameters
******************************************************************************/
	pdx->PRBStruct = (pPRB) ExAllocatePool(NonPagedPool,sizeof(PRB));

	DebugPrint("PRB system address is:0x%x",(ULONG)pdx->PRBStruct);
	PAddress = MmGetPhysicalAddress(pdx->PRBStruct);
	DebugPrint("PRBS Physical address is:0x%x",(ULONG)PAddress.LowPart);
    //Make PRB 8 bytes aligned
	while((PAddress.LowPart)% 8 != 0)
	{
		ExFreePool(pdx->PRBStruct);
		pdx->PRBStruct = (pPRB) ExAllocatePool(NonPagedPool,sizeof(PRB));
		PAddress = MmGetPhysicalAddress(pdx->PRBStruct);
		DebugPrint(" After ReAllocate Physical Address is:0x%x\n" ,PAddress.LowPart );
		DebugPrint(" After ReAllocate System Address is:0x%x\n" ,(ULONG)pdx->PRBStruct);
	}
    pdx->PRBStruct->Control          = 0x0000;
	pdx->PRBStruct->ProtocolOverride = 0x0000;
	pdx->PRBStruct->ReceivedCount    = 0x00000000;
	pdx->PRBStruct->FISType          = 0x27;
	pdx->PRBStruct->PMP              = 0x80;
	pdx->PRBStruct->Command_Status   = SATAREG48Buffer->cmnd;
	pdx->PRBStruct->Features_Error   = SATAREG48Buffer->feat_cur;
	pdx->PRBStruct->SectorNumber     = SATAREG48Buffer->secn_cur;
	pdx->PRBStruct->CylLow           = SATAREG48Buffer->cyll_cur;
	pdx->PRBStruct->CylHigh          = SATAREG48Buffer->cylh_cur;
	pdx->PRBStruct->DevHead          = SATAREG48Buffer->devh;
	pdx->PRBStruct->SectorNumberExp  = SATAREG48Buffer->secn_pre;
    pdx->PRBStruct->CylLowExp        = SATAREG48Buffer->cyll_pre;
    pdx->PRBStruct->CylHighExp       = SATAREG48Buffer->cylh_pre;
	pdx->PRBStruct->FeaturesExp      = SATAREG48Buffer->feat_pre;
    pdx->PRBStruct->SectorCount      = SATAREG48Buffer->secc_cur;
	pdx->PRBStruct->SectorCountExp   = SATAREG48Buffer->secc_pre;
	pdx->PRBStruct->Reserved0        = 0x00;
	pdx->PRBStruct->DeviceControl    = SATAREG48Buffer->fxdc;
	pdx->PRBStruct->Reserved1        = 0x00000000;
	pdx->PRBStruct->Reserved2        = 0x00000000;
	pdx->PRBStruct->SGE0Low          = (ULONG)PIOWriteBuffer.LowPart;
    pdx->PRBStruct->SGE0High         = 0x00000000;
	pdx->PRBStruct->SGE0Count        = PIOWriteCount;
	pdx->PRBStruct->SGE0Control      = 0x80000000;
	pdx->PRBStruct->SGE1Low          = 0x00000000;
    pdx->PRBStruct->SGE1High         = 0x00000000;
	pdx->PRBStruct->SGE1Count        = 0;
	pdx->PRBStruct->SGE1Control      = 0x00000000;

	DebugPrint("the port interrupt status 0x%x",READ_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1008)));
    pdx->TansferedCount = RequestCount; 

	WRITE_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1C00),PAddress.LowPart);
    WRITE_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1C04),0x00000000);

	pdx->NeedToHandle =TRUE;
	return status;

}

/******************************************************************************************************************
 *
 * Function   :  IOCTL_GET_3124TASKFILE_Handler
 *
 * Description:  Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_GET_3124TASKFILE
 ******************************************************************************************************************/
NTSTATUS IOCTL_GET_3124TASKFILE_Handler(IN PDEVICE_OBJECT fdo,
						                       IN PIRP pIrp)
{
	NTSTATUS status;
	PDEVICE_EXTENSION	pdx;
    PIO_STACK_LOCATION  pIrpStack;
    
	PVOID   IoBuffer;
    PULONG  LongBuffer;
	PUCHAR  CharBuffer;
	ULONG PortBaseAddress,Index;
	
	UCHAR   ReadData;
	UCHAR   Slot = 0;

	DebugPrint("start obtaining base address...\n");
    
    pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
    pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

	IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
	LongBuffer = (PULONG)IoBuffer;
	CharBuffer = (PUCHAR)IoBuffer;
	PortBaseAddress = LongBuffer[0];
	Index =LongBuffer[1];
	switch(Index)
	{
	case 0:
		ReadData = READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+Slot*0x80+0x08+0x02));    //status
		break;
	case 1:
		ReadData = READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+Slot*0x80+0x08+0x03));    //error
		break;
	case 2:
		ReadData = READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+Slot*0x80+0x08+0x04));    //sector number
		break;
	case 3:
		 ReadData = READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+Slot*0x80+0x08+0x05));    //cyl low
		 break;
	case 4:
         ReadData = READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+Slot*0x80+0x08+0x06));    //cyl high
		 break;
	case 5:
		 ReadData = READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+Slot*0x80+0x08+0x07));    //device/head
		 break;
	case 6:
		 ReadData = READ_REGISTER_UCHAR((PUCHAR)(PortBaseAddress+Slot*0x80+0x14));         //sector count
		 break;
	}
    CharBuffer[0] = ReadData;
	 // Assume a successful return status
    status = STATUS_SUCCESS;
	DebugPrint("TASK FILE register getting end...\n");
	return status;
}
/******************************************************************************************************************
 *
 * Function   :  IOCTL_3124REGISTER_COMMAND_Handler
 *
 * Description:  Handle IRP_MJ_DEVICE_CONTROL which Control_Code is IOCTL_3124REGISTER_COMMAND
 ******************************************************************************************************************/
NTSTATUS IOCTL_3124REGISTER_COMMAND_Handler(IN PDEVICE_OBJECT fdo,
												IN PIRP pIrp)
{
	NTSTATUS status;
	PDEVICE_EXTENSION	pdx;
    PIO_STACK_LOCATION  pIrpStack;
	ULONG Slot = 0;

	PVOID   IoBuffer;
    PULONG  LongBuffer; 
	PUSHORT ShortBuffer;
	PUCHAR  CharBuffer;
	ULONG   PortBaseAddress;
	PSATAREG48 SATAREG48Buffer;
    
	PHYSICAL_ADDRESS PAddress;
	ULONG i;
	ULONG  PortStatus;

	PUCHAR SlotBaseAddress;  //slot base address

    status = STATUS_SUCCESS;  	// Assume a successful return status

	DebugPrint("start No-Data Command ...\n");
   
    pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
    pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

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

    pdx->TansferedCount = 0;
	SlotBaseAddress = (PUCHAR)PortBaseAddress+Slot*0x80;
/*****************************************************************************
*  Create a PRB and Fill it with specific parameters
******************************************************************************/
	pdx->PRBStruct = (pPRB) ExAllocatePool(NonPagedPool,sizeof(PRB));

	DebugPrint("PRB system address is:0x%x",(ULONG)pdx->PRBStruct);
	PAddress = MmGetPhysicalAddress(pdx->PRBStruct);
	DebugPrint("PRBS Physical address is:0x%x",(ULONG)PAddress.LowPart);
    //Make PRB 8 bytes aligned
	while((PAddress.LowPart)% 8 != 0)
	{
		ExFreePool(pdx->PRBStruct);
		pdx->PRBStruct = (pPRB) ExAllocatePool(NonPagedPool,sizeof(PRB));
		PAddress = MmGetPhysicalAddress(pdx->PRBStruct);
		DebugPrint(" After ReAllocate Physical Address is:0x%x\n" ,PAddress.LowPart );
		DebugPrint(" After ReAllocate System Address is:0x%x\n" ,(ULONG)pdx->PRBStruct);
	}
    pdx->PRBStruct->Control          = 0x0000;
	pdx->PRBStruct->ProtocolOverride = 0x0000;
	pdx->PRBStruct->ReceivedCount    = 0x00000000;
	pdx->PRBStruct->FISType          = 0x27;
	pdx->PRBStruct->PMP              = 0x80;
	pdx->PRBStruct->Command_Status   = SATAREG48Buffer->cmnd;
	pdx->PRBStruct->Features_Error   = SATAREG48Buffer->feat_cur;
	pdx->PRBStruct->SectorNumber     = SATAREG48Buffer->secn_cur;
	pdx->PRBStruct->CylLow           = SATAREG48Buffer->cyll_cur;
	pdx->PRBStruct->CylHigh          = SATAREG48Buffer->cylh_cur;
	pdx->PRBStruct->DevHead          = SATAREG48Buffer->devh;
	pdx->PRBStruct->SectorNumberExp  = SATAREG48Buffer->secn_pre;
    pdx->PRBStruct->CylLowExp        = SATAREG48Buffer->cyll_pre;
    pdx->PRBStruct->CylHighExp       = SATAREG48Buffer->cylh_pre;
	pdx->PRBStruct->FeaturesExp      = SATAREG48Buffer->feat_pre;
    pdx->PRBStruct->SectorCount      = SATAREG48Buffer->secc_cur;
	pdx->PRBStruct->SectorCountExp   = SATAREG48Buffer->secc_pre;
	pdx->PRBStruct->Reserved0        = 0x00;
	pdx->PRBStruct->DeviceControl    = SATAREG48Buffer->fxdc;
	pdx->PRBStruct->Reserved1        = 0x00000000;
	pdx->PRBStruct->Reserved2        = 0x00000000;
	pdx->PRBStruct->SGE0Low          = 0x00000000;
    pdx->PRBStruct->SGE0High         = 0x00000000;
	pdx->PRBStruct->SGE0Count        = 0;
	pdx->PRBStruct->SGE0Control      = 0x00000000;
	pdx->PRBStruct->SGE1Low          = 0x00000000;
    pdx->PRBStruct->SGE1High         = 0x00000000;
	pdx->PRBStruct->SGE1Count        = 0;
	pdx->PRBStruct->SGE1Control      = 0x00000000;

	DebugPrint("the port interrupt status 0x%x",READ_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1008)));    
	WRITE_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1C00),PAddress.LowPart);
    WRITE_REGISTER_ULONG((PULONG)(PortBaseAddress+0x1C04),0x00000000);
 
	pdx->NeedToHandle =TRUE;
	return status;


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

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

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

⌨️ 快捷键说明

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