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

📄 pcidpprivate.c

📁 一个amccs5933芯片的驱动程序开发源程序和部分文档
💻 C
字号:
//*****************************************************************************
// THIS CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 
// OR IMPLIED. THIS CODE IS LABELED "OPEN SOFTWARE" AND MAY BE FREELY USED, 
// REPRODUCED, MODIFIED, AND/OR REDISTRIBUTED WITH THE STIPULATION THAT THIS 
// NOTICE REMAIN INTACT. REDISTRIBUTION OF ANY KIND IMPLIES THAT ALL
// MODIFICATIONS FALL UNDER THIS "OPEN SOFTWARE" LABEL.
//
// Copyright (C) 2000, Foxen Solutions
// Copyright (C) 2000, FXN
//
// All Rights Reserved.
//*****************************************************************************
//
//
// This is PCIDPPrivate.c.  It contains those routines whose access status
// is private within the PCIDP kernel driver.


#pragma code_seg("_LTEXT")	//match PCIDP assembly module code segment
#pragma data_seg("_LDATA")	//match PCIDP assembly module data segment


#include "PCIDPInc.h"
#include "PCIDP.h"



// These routines are the linked list utilities.  They protect the linked list 
// with a spin lock, limiting access to one thread at a time.  The linked list 
// contains those pending IRPs.
BOOLEAN GetNextEntry(
	pPCIDP_EXTENSION ObjExt,
	pLINKED_LIST* FirstLink,
	pLINKED_LIST* CurrentLink,
	pREGISTERED_INTERRUPT* Entry
){

	BOOLEAN Status = FALSE;
	KIRQL LListIrql;
	pLINKED_LIST CurrentLnk;
	//short* MapBase = (short*)ObjExt->MappingBase;

	Begin_Critical_Section(0);

	if(*FirstLink == NULL){
		if(ObjExt->LLData.InsertedCount > 0){
			*FirstLink = ObjExt->LLData.CurrentLink;
			*CurrentLink = *FirstLink;
			CurrentLnk = *CurrentLink;
			if(CurrentLnk->Status == LL_INSERTED){
				CurrentLnk->Status = LL_CHECKEDOUT;
				ObjExt->LLData.InsertedCount--;
				*Entry = &(CurrentLnk->RegisteredInterrupt);
				Status = TRUE;
				goto GetNextExit;
			}
		}
	}

	if(*FirstLink != NULL){
		CurrentLnk = *CurrentLink;
		CurrentLnk = CurrentLnk->Next;
		while(CurrentLnk != *FirstLink){
			if(CurrentLnk->Status == LL_INSERTED){
				CurrentLnk->Status = LL_CHECKEDOUT;
				ObjExt->LLData.InsertedCount--;
				*Entry = &(CurrentLnk->RegisteredInterrupt);
				Status = TRUE;
				break;
			}
			CurrentLnk = CurrentLnk->Next;
		}
		*CurrentLink = CurrentLnk;
	}

	GetNextExit:
	//MapBase[InsertedCount] = ObjExt->LLData.InsertedCount;
	End_Critical_Section();

	return Status;
}


BOOLEAN PutBackEntry(pPCIDP_EXTENSION ObjExt, pLINKED_LIST CurrentLink){

	BOOLEAN Status;
	KIRQL LListIrql;

	//short* MapBase = (short*)ObjExt->MappingBase;
	Begin_Critical_Section(0);
	if(CurrentLink->Status == LL_CHECKEDOUT){ 
		CurrentLink->Status = LL_INSERTED;
		ObjExt->LLData.InsertedCount++;
		Status = TRUE;
	}
	else
		Status = FALSE;

	End_Critical_Section();
	//MapBase[InsertedCount] = ObjExt->LLData.InsertedCount;
	//MapBase[PutBack]++;
	return Status;
}


BOOLEAN FreeEntry(pPCIDP_EXTENSION ObjExt, pLINKED_LIST CurrentLink){

	BOOLEAN Status;
	KIRQL LListIrql;
	//short* MapBase = (short*)ObjExt->MappingBase;

	Begin_Critical_Section(0);
	if(CurrentLink->Status == LL_CHECKEDOUT || CurrentLink->Status == LL_ACQUIRED){
		CurrentLink->Status = LL_AVAILABLE;
		ObjExt->LLData.CurrentLink = CurrentLink->Prev;
		Status = TRUE;
	}
	else
		Status = FALSE;

	End_Critical_Section();
	//MapBase[FreeUp]++;

	return Status;
}


pLINKED_LIST GetFreeEntry(pPCIDP_EXTENSION ObjExt){

	pLINKED_LIST FirstLink;
	pLINKED_LIST ReturnLink = NULL;
	KIRQL LListIrql;

	Begin_Critical_Section(0);
	if(ObjExt->LLData.IsEmpty == FALSE) {
		FirstLink = ObjExt->LLData.CurrentLink;
		do{
			ObjExt->LLData.CurrentLink = ObjExt->LLData.CurrentLink->Next;
			if(ObjExt->LLData.CurrentLink->Status == LL_AVAILABLE){
				ObjExt->LLData.CurrentLink->Status = LL_ACQUIRED;
				ReturnLink = ObjExt->LLData.CurrentLink;
				break;
			}
		} while(FirstLink != ObjExt->LLData.CurrentLink);
	}
	End_Critical_Section();

	if(ReturnLink == NULL){
		ReturnLink = (PVOID)_HeapAllocate( sizeof(LINKED_LIST), HEAPZEROINIT);
		if(ReturnLink != NULL){
			ReturnLink->Status = LL_NEW;
		}
	}

	return ReturnLink;
}


BOOLEAN InsertEntry(pPCIDP_EXTENSION ObjExt, pLINKED_LIST Entry){

	//short* MapBase = (short*)ObjExt->MappingBase;
	BOOLEAN Status = TRUE;
	pLINKED_LIST CurrentLink;
	KIRQL LListIrql;

	Begin_Critical_Section(0);
	if(Entry->Status == LL_NEW){
		Entry->Status = LL_INSERTED;
		ObjExt->LLData.FreeMax++;
		ObjExt->LLData.InsertedCount++;
		if(ObjExt->LLData.IsEmpty == TRUE) {
			Entry->Prev = Entry;
			Entry->Next = Entry;
			ObjExt->LLData.CurrentLink = Entry;
			ObjExt->LLData.IsEmpty = FALSE;
		}
		else {
			CurrentLink = ObjExt->LLData.CurrentLink;
			Entry->Prev = CurrentLink;
			Entry->Next = CurrentLink->Next;

			CurrentLink->Next->Prev = Entry;
			CurrentLink->Next = Entry;
		}
	}
	else if(Entry->Status == LL_ACQUIRED){
		Entry->Status = LL_INSERTED;
		ObjExt->LLData.InsertedCount++;
	}
	else
		Status = FALSE;

	End_Critical_Section();
	//MapBase[FreeMax] = ObjExt->LLData.FreeMax;
	//MapBase[InsertedCount] = ObjExt->LLData.InsertedCount;

	return Status;
}


BOOLEAN DeleteAllEntries(pPCIDP_EXTENSION ObjExt){

	//short* MapBase = (short*)ObjExt->MappingBase;
	pLINKED_LIST CurrentLink = ObjExt->LLData.CurrentLink;

	while(ObjExt->LLData.IsEmpty == FALSE) {

		if(CurrentLink->Status == LL_INSERTED)
			ObjExt->LLData.InsertedCount--;

		if(CurrentLink->Next == CurrentLink) {
			ObjExt->LLData.IsEmpty = TRUE;
		}
		else {
			CurrentLink->Prev->Next = CurrentLink->Next;
			CurrentLink->Next->Prev = CurrentLink->Prev;
			CurrentLink = CurrentLink->Prev;
		}
		ObjExt->LLData.FreeMax--;
		//MapBase[FreeMax] = ObjExt->LLData.FreeMax;
		//MapBase[InsertedCount] = ObjExt->LLData.InsertedCount;

		_HeapFree((PVOID)ObjExt->LLData.CurrentLink, 0);
	}

	return(!ObjExt->LLData.IsEmpty);
}



#pragma code_seg()
#pragma data_seg()

⌨️ 快捷键说明

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