?? devmgr.cpp
字號:
//lpFirstRegion = (__RESOURCE*)malloc(sizeof(__RESOURCE));
lpFirstRegion = (__RESOURCE*)KMemAlloc(sizeof(__RESOURCE),KMEM_SIZE_TYPE_ANY);
if(lpFirstRegion) //Allocate memory successfully.
{
lpFirstRegion->dwResType = RESOURCE_TYPE_IO;
lpFirstRegion->IOPort.wStartPort = lpPotential->IOPort.wStartPort + wSize;
lpFirstRegion->IOPort.wEndPort = lpPotential->IOPort.wEndPort;
INSERT_INTO_LIST(&lpDevMgr->FreePortResource,lpFirstRegion);
}
}
lpRes1->dwResType = RESOURCE_TYPE_IO;
lpRes1->IOPort.wStartPort = lpPotential->IOPort.wStartPort;
lpRes1->IOPort.wEndPort = lpPotential->IOPort.wStartPort + wSize - 1;
INSERT_INTO_LIST(&lpDevMgr->UsedPortResource,lpRes1);
lpRes->IOPort.wStartPort = lpRes1->IOPort.wStartPort;
lpRes->IOPort.wEndPort = lpRes1->IOPort.wEndPort;
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
bResult = TRUE;
KMemFree((LPVOID)lpPotential,KMEM_SIZE_TYPE_ANY,0L);
//free((LPVOID)lpPotential);
goto __TERMINAL;
}
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
__TERMINAL:
if(!bResult) //Failed to reserve port.
{
KMemFree((LPVOID)lpRes1,KMEM_SIZE_TYPE_ANY,0L); //Free memory used by lpRes1.
//free((LPVOID)lpRes1);
return bResult;
}
return bResult;
}
//
//The implementation of ReleasePortRegion routine.
//
static VOID ReleasePortRegion(__DEVICE_MANAGER* lpDevMgr,__RESOURCE* lpRes)
{
BOOL bResult = FALSE;
__RESOURCE* lpUsed = NULL;
DWORD dwFlags = 0L;
if((NULL == lpDevMgr) || (NULL == lpRes)) //Invalid parameters.
return;
if(RESOURCE_TYPE_IO != lpRes->dwResType) //Invalid resource descriptor.
return;
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
lpUsed = lpDevMgr->UsedPortResource.lpNext;
while(lpUsed != &lpDevMgr->UsedPortResource) //Travel whole list.
{
if((lpUsed->IOPort.wStartPort == lpRes->IOPort.wStartPort) &&
(lpUsed->IOPort.wEndPort == lpRes->IOPort.wEndPort)) //Find the same region.
{
break;
}
lpUsed = lpUsed->lpNext;
}
if(lpUsed == &lpDevMgr->UsedPortResource) //Can not find the original request one.
{
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return;
}
//
//Now,we have found the IO port region that equals to lpRes,so delete it from the
//used list,and insert it into free list.
//
DELETE_FROM_LIST(lpUsed); //Delete from used list.
INSERT_INTO_LIST(&lpDevMgr->FreePortResource,lpUsed); //Insert into free list.
MergeRegion(&lpDevMgr->FreePortResource); //Do a merge operation,to combine continues
//port region into one region.
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return;
}
//
//The implement of CheckPortRegion.
//This routine is used to check if a block of port region is used,if used,then returns FALSE,
//else,returns TRUE.
//
static BOOL CheckPortRegion(__DEVICE_MANAGER* lpDevMgr,__RESOURCE* lpRes)
{
__RESOURCE* lpTmp = NULL;
DWORD dwFlags = 0L;
if((NULL == lpDevMgr) || (NULL == lpRes)) //Invalid parameters.
return FALSE;
if(RESOURCE_TYPE_IO != lpRes->dwResType) //Also invalid parameter.
return FALSE;
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
lpTmp = lpDevMgr->FreePortResource.lpNext;
while(lpTmp != &lpDevMgr->FreePortResource) //Travel the whole free list.
{
if((lpTmp->IOPort.wStartPort <= lpRes->IOPort.wStartPort) &&
(lpTmp->IOPort.wEndPort >= lpRes->IOPort.wEndPort)) //Not used.
{
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return TRUE;
}
lpTmp = lpTmp->lpNext;
}
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return FALSE;
}
//
//The following is a helper routine,used to check if two device identifiers are match.
//If the second Identifier(second parameter),"include" the first Identifier(first parameter),
//then it returns TRUE,otherwise,returns FALSE.
//
static BOOL DeviceIdMatch(__IDENTIFIER* lpFirst,__IDENTIFIER* lpSecond)
{
UCHAR ucMask = 0;
if((NULL == lpFirst) || (NULL == lpSecond)) //Parameters check.
return FALSE;
if(lpFirst->dwBusType != lpSecond->dwBusType) //Bus type does not match.
return FALSE;
if(lpFirst->dwBusType == BUS_TYPE_NULL) //Invalid bus type.
return FALSE;
switch(lpFirst->dwBusType)
{
case BUS_TYPE_PCI: //PCI Identifier match.
#define ID_MEMBER(id,mem) ((id)->PCI_Identifier.mem)
if(ID_MEMBER(lpFirst,wVendor) == ID_MEMBER(lpSecond,wVendor))
ucMask |= PCI_IDENTIFIER_MASK_VENDOR;
if(ID_MEMBER(lpFirst,wDevice) == ID_MEMBER(lpSecond,wDevice))
ucMask |= PCI_IDENTIFIER_MASK_DEVICE;
if((lpFirst->PCI_Identifier.dwClass >> 8) ==
(lpSecond->PCI_Identifier.dwClass >> 8))
ucMask |= PCI_IDENTIFIER_MASK_CLASS;
if(ID_MEMBER(lpFirst,ucHdrType) == ID_MEMBER(lpSecond,ucHdrType))
ucMask |= PCI_IDENTIFIER_MASK_HDRTYPE;
return ((lpFirst->PCI_Identifier.ucMask & ucMask) == lpFirst->PCI_Identifier.ucMask);
case BUS_TYPE_ISA: //ISA Identifier match.
return (lpFirst->ISA_Identifier.dwDevice == lpSecond->ISA_Identifier.dwDevice);
default:
break;
}
return FALSE;
}
//
//The implementation of GetDevice routine.
//This routine returns the appropriate physical device object according to identifier.
//
static __PHYSICAL_DEVICE* GetDevice(__DEVICE_MANAGER* lpDevMgr,
DWORD dwBusType,
__IDENTIFIER* lpId,
__PHYSICAL_DEVICE* lpStart)
{
DWORD dwIndex = 0L;
DWORD dwFlags = 0L;
__PHYSICAL_DEVICE* lpPhyDev = NULL;
if((NULL == lpDevMgr) || (NULL == lpId)) //Invalid parameters.
return NULL;
if(NULL == lpStart) //Call this routine for the first time.
{
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
for(dwIndex = 0;dwIndex < MAX_BUS_NUM;dwIndex ++)
{
if(lpDevMgr->SystemBus[dwIndex].dwBusType != dwBusType) //Bus type not match.
continue;
lpPhyDev = lpDevMgr->SystemBus[dwIndex].lpDevListHdr;
while(lpPhyDev)
{
#define DEVICE_ID_MATCH(id1,id2) (DeviceIdMatch((id1),(id2)))
if(DEVICE_ID_MATCH(lpId,&lpPhyDev->DevId)) //ID match.
{
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return lpPhyDev; //Find a device object statisfying the request.
}
lpPhyDev = lpPhyDev->lpNext;
}
}
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return lpPhyDev; //If reach here,the requested device must have not been found.
}
else //This routine is called for the second time.
{
dwIndex =
(DWORD)((DWORD)(lpStart->lpHomeBus) -
(DWORD)(&lpDevMgr->SystemBus[0])) / sizeof(__SYSTEM_BUS);
lpPhyDev = lpStart->lpNext;
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
while((dwIndex < MAX_BUS_NUM) || lpPhyDev)
{
while(lpPhyDev)
{
if(DEVICE_ID_MATCH(lpId,&lpPhyDev->DevId)) //Find one.
{
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return lpPhyDev;
}
lpPhyDev = lpPhyDev->lpNext; //Try to match the next one.
}
dwIndex += 1;
while(dwIndex < MAX_BUS_NUM) //Try to search next BUS.
{
if(lpDevMgr->SystemBus[dwIndex].dwBusType != dwBusType)
{
dwIndex += 1;
continue;
}
lpPhyDev = lpDevMgr->SystemBus[dwIndex].lpDevListHdr;
break; //Break form the loop.
}
}
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return lpPhyDev; //If reach here,the routine returns NULL.
}
return lpPhyDev;
}
//
//The implementation of AppendDevice routine.
//This routine append a physical device object into a BUS.
//
static BOOL AppendDevice(__DEVICE_MANAGER* lpDevMgr,__PHYSICAL_DEVICE* lpDev)
{
return FALSE;
}
//
//The implementation of DeleteDevice routine.
//This routine deletes one physical device from system bus.
//
static VOID DeleteDevice(__DEVICE_MANAGER* lpDevMgr,__PHYSICAL_DEVICE* lpDev)
{
return;
}
/****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
****************************************************************************************/
//
//The declaration of DeviceManager object.
//
__DEVICE_MANAGER DeviceManager = {
{0}, //SystemBus array.
{0}, //FreePortResource.
{0}, //UsedPortResource.
DevMgrInitialize, //Initialize.
GetDevice, //GetDevice.
AppendDevice, //AppendDevice.
DeleteDevice, //DeleteDevice.
CheckPortRegion, //CheckPortRegion.
ReservePortRegion, //ReservePortRegion.
ReleasePortRegion //ReleasePortRegion.
};
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -