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

📄 dispatchroutines.c

📁 此驱动程序是SATA功能的PCI卡为例
💻 C
📖 第 1 页 / 共 5 页
字号:
	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;i<SGTCount;i++)
		{
		pdx->SGTPAddress[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;j<SGTCount;j++)
           pdx->SGTPAddress[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;i<SGTCount;i++)
		 {
				 if(i == SGTCount-1)
				 {    
					  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;

					 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);
			DebugPri

⌨️ 快捷键说明

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