📄 pcidpprivate.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 + -