1340 lines
39 KiB
C++
1340 lines
39 KiB
C++
#include "pch.h"
|
|
#pragma hdrstop
|
|
#include <ncxbase.h>
|
|
#include "hwres.h"
|
|
#include "kkcwinf.h"
|
|
#include "ncreg.h"
|
|
|
|
extern const WCHAR c_szAfIoAddr[];
|
|
extern const WCHAR c_szAfIrq[];
|
|
extern const WCHAR c_szAfDma[];
|
|
extern const WCHAR c_szAfMem[];
|
|
extern const WCHAR c_szBusType[];
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::CHwRes
|
|
//
|
|
// Purpose: Class constructor. (Variable initialization)
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes: Doesn't do much. Just some member variable initialization.
|
|
// Bulk of the init work is done in HrInit().
|
|
//
|
|
CHwRes::CHwRes()
|
|
: m_DevNode(NULL),
|
|
m_pnccItem(NULL),
|
|
m_fInitialized(FALSE),
|
|
m_fHrInitCalled(FALSE),
|
|
m_fDirty(FALSE)
|
|
{
|
|
m_vAfDma.InitNotPresent(VALUETYPE_DWORD);
|
|
m_vAfIrq.InitNotPresent(VALUETYPE_DWORD);
|
|
m_vAfMem.InitNotPresent(VALUETYPE_DWORD);
|
|
m_vAfMemEnd.InitNotPresent(VALUETYPE_DWORD);
|
|
m_vAfIo.InitNotPresent(VALUETYPE_DWORD);
|
|
m_vAfIoEnd.InitNotPresent(VALUETYPE_DWORD);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::HrInit
|
|
//
|
|
// Purpose: Initialize class
|
|
//
|
|
// Arguments:
|
|
// hInst [in] Handle to our instance.
|
|
// pnccItem [in] Our INetCfgComponent.
|
|
//
|
|
// Returns: S_OK - init successfull;
|
|
// HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) - no config
|
|
// info for device; E_FAIL - other failure (device not found,etc)
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes: - should initialize all non-ui stuff
|
|
// - initialize configuration and resource lists.
|
|
//
|
|
HRESULT CHwRes::HrInit(const DEVNODE& devnode)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
m_fHrInitCalled = TRUE;
|
|
|
|
|
|
// use the config manager to get devnode
|
|
// Since the devnode might have a problem, e.g. resources not set
|
|
// correctly, we need to retrieve possible phantoms
|
|
//
|
|
CONFIGRET crRet = ERROR_SUCCESS;
|
|
HKEY hkey;
|
|
|
|
// We only do work on Isa adapters so we need to get the bustype
|
|
// value from the driver (software) key
|
|
crRet = CM_Open_DevNode_Key(devnode, KEY_READ, 0,
|
|
RegDisposition_OpenExisting, &hkey, CM_REGISTRY_SOFTWARE);
|
|
|
|
if (CR_SUCCESS == crRet)
|
|
{
|
|
// Get BusType
|
|
ULONG ulBusType;
|
|
hr = HrRegQueryStringAsUlong(hkey, c_szBusType, c_nBase10,
|
|
&ulBusType);
|
|
|
|
RegCloseKey(hkey);
|
|
|
|
// If Isa, than we can continue
|
|
if (SUCCEEDED(hr) && (Isa == ulBusType))
|
|
{
|
|
m_DevNode = devnode;
|
|
// read configuration current config info
|
|
hr = HrInitConfigList();
|
|
}
|
|
else
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
m_fInitialized = TRUE;
|
|
}
|
|
|
|
TraceError("CHwRes::HrInit",
|
|
(HRESULT_FROM_WIN32(ERROR_FILE_EXISTS) == hr ||
|
|
S_FALSE == hr) ? S_OK : hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::GetNextElement
|
|
//
|
|
// Purpose: Gets the next (or prev) element in a resource list
|
|
//
|
|
// Arguments:
|
|
// pResource [in] resource list to traverse.
|
|
// ppeList [out] the "next" element is returned.
|
|
// fNext [in] TRUE - moving fwd in list; FALSE - move bkwrds.
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID CHwRes::GetNextElement(PRESOURCE pResource, PVOID *ppeList, BOOL fNext)
|
|
{
|
|
UINT size = 0;
|
|
|
|
AssertSz(m_fInitialized,
|
|
"GetNextElement called before CHwRes is HrInit'ed");
|
|
|
|
Assert(pResource != NULL);
|
|
// get the vector size (dependant on resource type)
|
|
switch (pResource->ResourceType) {
|
|
case ResType_IRQ:
|
|
size = pResource->pIRQList->size();
|
|
break;
|
|
case ResType_DMA:
|
|
size = pResource->pDMAList->size();
|
|
break;
|
|
case ResType_IO:
|
|
size = pResource->pIOList->size();
|
|
break;
|
|
case ResType_Mem:
|
|
size = pResource->pMEMList->size();
|
|
break;
|
|
default:
|
|
Assert(FALSE);
|
|
break;
|
|
}
|
|
|
|
// increment/decrement current position within vector
|
|
if (fNext)
|
|
{
|
|
pResource->pos++;
|
|
}
|
|
else
|
|
{
|
|
pResource->pos--;
|
|
}
|
|
// Check for wrapping
|
|
if ((int)(pResource->pos) < 0)
|
|
{
|
|
Assert(pResource->pos == -1);
|
|
Assert(!fNext); // we're going backwards
|
|
pResource->pos = size-1;
|
|
}
|
|
else if (pResource->pos >= size)
|
|
{
|
|
Assert(pResource->pos == size);
|
|
Assert(fNext);
|
|
pResource->pos = 0;
|
|
}
|
|
|
|
// return the current vector element (dependant on res type)
|
|
// REVIEW: do we ever use the element that's gathered below?
|
|
switch (pResource->ResourceType) {
|
|
case ResType_IRQ:
|
|
*ppeList = (*pResource->pIRQList)[pResource->pos];
|
|
break;
|
|
case ResType_DMA:
|
|
*ppeList = (*pResource->pDMAList)[pResource->pos];
|
|
break;
|
|
case ResType_IO:
|
|
*ppeList = (*pResource->pIOList)[pResource->pos];
|
|
break;
|
|
case ResType_Mem:
|
|
*ppeList = (*pResource->pMEMList)[pResource->pos];
|
|
break;
|
|
default:
|
|
Assert(FALSE);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::HrInitConfigList
|
|
//
|
|
// Purpose: Initialize m_ConfigList (the internal vector of
|
|
// configurations.)
|
|
//
|
|
// Returns: S_OK - init successful;
|
|
// HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) if no device configs
|
|
// found; E_FAIL otherwise (invalid device, etc.)
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes: "Lists" are actually implemented as STL vectors.
|
|
//
|
|
HRESULT CHwRes::HrInitConfigList() {
|
|
HRESULT hr = S_OK;
|
|
PCONFIGURATION pConfiguration;
|
|
CONFIGRET ConfigRet;
|
|
LOG_CONF lcCurrent, lcNext;
|
|
UINT iBasicConfig;
|
|
BOOL fFoundConfig = FALSE;
|
|
|
|
Assert(NULL != m_DevNode);
|
|
|
|
// erase all elements
|
|
m_ConfigList.erase(m_ConfigList.begin(), m_ConfigList.end());
|
|
|
|
// Boot Configuration
|
|
if (CM_Get_First_Log_Conf(&lcCurrent, m_DevNode, BOOT_LOG_CONF)
|
|
== CR_SUCCESS)
|
|
{
|
|
TraceTag(ttidNetComm, "Boot config already exists");
|
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_EXISTS);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Basic Configurations (may be more than one)
|
|
iBasicConfig = 0;
|
|
ConfigRet = CM_Get_First_Log_Conf(&lcCurrent, m_DevNode, BASIC_LOG_CONF);
|
|
|
|
#ifdef ENABLETRACE
|
|
if (CR_SUCCESS != ConfigRet)
|
|
{
|
|
TraceTag(ttidNetComm, "CM_Get_First_Log_conf returned %lX", ConfigRet);
|
|
}
|
|
#endif // ENABLETRACE
|
|
while (CR_SUCCESS == ConfigRet)
|
|
{
|
|
pConfiguration = new CONFIGURATION;
|
|
|
|
if (pConfiguration == NULL)
|
|
{
|
|
TraceError("pConfiguration == NULL", E_FAIL);
|
|
goto error;
|
|
}
|
|
|
|
pConfiguration->LogConf = lcCurrent;
|
|
pConfiguration->fBoot = FALSE;
|
|
pConfiguration->fAlloc = FALSE;
|
|
|
|
if (!FInitResourceList(pConfiguration))
|
|
{
|
|
hr = E_FAIL;
|
|
TraceError("CHwRes::FInitResourceList",hr);
|
|
goto error;
|
|
}
|
|
|
|
m_ConfigList.push_back(pConfiguration);
|
|
|
|
// Move on to the next basic config
|
|
iBasicConfig++;
|
|
ConfigRet = CM_Get_Next_Log_Conf(&lcNext, lcCurrent, 0);
|
|
lcCurrent = lcNext;
|
|
fFoundConfig = TRUE;
|
|
}
|
|
|
|
if (!fFoundConfig)
|
|
{
|
|
TraceTag(ttidNetComm, "No basic configs");
|
|
|
|
// if no config entries found, return ERROR_FILE_NOT_FOUND.
|
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
|
}
|
|
}
|
|
|
|
error:
|
|
// ERROR_FILE_NOT_FOUND is an okay error message.
|
|
TraceError("CHwRes::HrInitConfigList",
|
|
(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr ||
|
|
HRESULT_FROM_WIN32(ERROR_FILE_EXISTS) == hr ) ? S_OK : hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::FInitResourceList
|
|
//
|
|
// Purpose: Initializes the resource list for a given logical config.
|
|
//
|
|
// Arguments:
|
|
// pConfiguration [in] configuration who's resource list is to
|
|
// be initialized.
|
|
//
|
|
// Returns: TRUE if init sucessful; FALSE otherwise.
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes: Requires pConfiguration->LogConf to be initialized.
|
|
//
|
|
BOOL CHwRes::FInitResourceList(PCONFIGURATION pConfiguration)
|
|
{
|
|
RES_DES rdCurrent;
|
|
RES_DES rdNext;
|
|
RESOURCEID ResType;
|
|
UINT iResource;
|
|
#define RESOURCE_BUFFER_SIZE 4096
|
|
BYTE Buffer[RESOURCE_BUFFER_SIZE];
|
|
ULONG ulDataSize;
|
|
RESOURCE * pRes;
|
|
CONFIGRET cr;
|
|
|
|
Assert(pConfiguration->LogConf);
|
|
rdCurrent = (RES_DES) pConfiguration->LogConf;
|
|
iResource = 0;
|
|
while ((cr = CM_Get_Next_Res_Des(&rdNext, rdCurrent,
|
|
ResType_All, &ResType, 0)) == CR_SUCCESS)
|
|
{
|
|
rdCurrent = rdNext;
|
|
// Only process this resource if the ignore bit is not set
|
|
if (ResType_Ignored_Bit != ResType)
|
|
{
|
|
pRes = &(pConfiguration->aResource[iResource]);
|
|
pRes->ResDes = rdCurrent;
|
|
pRes->ResourceType = ResType;
|
|
cr = CM_Get_Res_Des_Data_Size(&ulDataSize, rdCurrent, 0);
|
|
if (CR_SUCCESS != cr)
|
|
{
|
|
TraceTag (ttidDefault, "CM_Get_Res_Des_Data_Size returned 0x%08x", cr);
|
|
goto error;
|
|
}
|
|
|
|
AssertSz (ulDataSize, "CM_Get_Res_Des_Data_Size returned 0!");
|
|
AssertSz (ulDataSize <= sizeof(Buffer), "CHwRes::FInitResourceList: buffer is too small.");;
|
|
|
|
cr = CM_Get_Res_Des_Data(rdCurrent, Buffer, sizeof(Buffer), 0);
|
|
if (CR_SUCCESS != cr)
|
|
{
|
|
TraceTag (ttidDefault, "CM_Get_Res_Des_Data returned 0x%08x", cr);
|
|
goto error;
|
|
}
|
|
|
|
// Depending on the ResType, we have to initialize our resource list.
|
|
switch (ResType)
|
|
{
|
|
case ResType_Mem:
|
|
InitMEMList(&(pRes->pMEMList), (PMEM_RESOURCE)Buffer);
|
|
break;
|
|
case ResType_IO:
|
|
InitIOList(&(pRes->pIOList), (PIO_RESOURCE)Buffer);
|
|
break;
|
|
case ResType_DMA:
|
|
InitDMAList(&(pRes->pDMAList), (PDMA_RESOURCE)Buffer);
|
|
break;
|
|
case ResType_IRQ:
|
|
InitIRQList(&(pRes->pIRQList), (PIRQ_RESOURCE)Buffer);
|
|
break;
|
|
default:
|
|
AssertSz (ResType_None != ResType, "ResType_None hit caught in CHwRes::FInitResourceList.");
|
|
break;
|
|
}
|
|
// set the list position to the first element;
|
|
// applied_pos will get copied to pos when dialog box is created.
|
|
pRes->applied_pos = 0;
|
|
|
|
iResource++;
|
|
pConfiguration->cResource = iResource;
|
|
if (iResource >= c_nMaxResCtls)
|
|
{
|
|
break; // we're done.
|
|
}
|
|
}
|
|
} //while
|
|
if ((CR_SUCCESS != cr) && (CR_NO_MORE_RES_DES != cr))
|
|
{
|
|
TraceTag (ttidDefault, "CM_Get_Next_Res_Des returned 0x%08x", cr);
|
|
goto error;
|
|
}
|
|
|
|
return TRUE;
|
|
error:
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::InitIRQList
|
|
//
|
|
// Purpose: Initialize an IRQ resource vector given a config manager
|
|
// resource structure.
|
|
//
|
|
// Arguments:
|
|
// ppIRQList [out] returns IRQ_LIST that will be created.
|
|
// pIRQResource [in] IRQ_RESOURCE structure from config manager.
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID CHwRes::InitIRQList(PIRQ_LIST* ppIRQList, PIRQ_RESOURCE pIRQResource) {
|
|
PIRQ_DES pIRQHeader;
|
|
PIRQ_RANGE pIRQData;
|
|
PIRQ_LIST_ELEMENT pIRQListElement;
|
|
|
|
pIRQHeader = &(pIRQResource->IRQ_Header);
|
|
pIRQData = &(pIRQResource->IRQ_Data[0]);
|
|
|
|
// Create a new list.
|
|
*ppIRQList = new IRQ_LIST;
|
|
|
|
if (*ppIRQList == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ULONG iData;
|
|
ULONG iIRQ;
|
|
|
|
for (iData = 0; iData < pIRQHeader->IRQD_Count; iData++)
|
|
{
|
|
for (iIRQ = pIRQData[iData].IRQR_Min;
|
|
iIRQ <= pIRQData[iData].IRQR_Max;
|
|
iIRQ++)
|
|
{
|
|
// For each IRQ that falls within the given range,
|
|
// create new IRQ List Element, populate its fields and insert
|
|
// it into the m_IRQList.
|
|
pIRQListElement = new IRQ_LIST_ELEMENT;
|
|
|
|
if (pIRQListElement == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
pIRQListElement->dwIRQ = iIRQ;
|
|
pIRQListElement->fConflict = FALSE;
|
|
pIRQListElement->fAllocated = FALSE;
|
|
(*ppIRQList)->push_back(pIRQListElement);
|
|
}
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::InitDMAList
|
|
//
|
|
// Purpose: Initialize a DMA resource vector given a config manager
|
|
// resource structure.
|
|
//
|
|
// Arguments:
|
|
// ppDMAList [out] returns DMA_LIST that will be created.
|
|
// pDMAResource [in] DMA_RESOURCE structure from config manager.
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID CHwRes::InitDMAList(PDMA_LIST* ppDMAList, PDMA_RESOURCE pDMAResource) {
|
|
PDMA_DES pDMAHeader;
|
|
PDMA_RANGE pDMAData;
|
|
PDMA_LIST_ELEMENT peDMAList;
|
|
|
|
pDMAHeader = &(pDMAResource->DMA_Header);
|
|
pDMAData = &(pDMAResource->DMA_Data[0]);
|
|
|
|
// Create a new list.
|
|
*ppDMAList = new DMA_LIST;
|
|
|
|
if (*ppDMAList == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ULONG iData; // index of DMA_Range structure we're looking at.
|
|
ULONG iDMA; // current DMA number we're adding to the list.
|
|
|
|
// Go through all the DMA_Range structures, and all DMAs in the
|
|
// specified range to the list.
|
|
|
|
for (iData = 0; iData < pDMAHeader->DD_Count; iData++)
|
|
{
|
|
for (iDMA = pDMAData[iData].DR_Min;
|
|
iDMA <= pDMAData[iData].DR_Max;
|
|
iDMA++)
|
|
{
|
|
// For each DMA that falls within the given range,
|
|
// create new DMA List Element, populate its fields and insert
|
|
// it into the DMAList.
|
|
peDMAList = new DMA_LIST_ELEMENT;
|
|
|
|
if (peDMAList == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
peDMAList->dwDMA = iDMA;
|
|
peDMAList->fConflict = FALSE;
|
|
peDMAList->fAllocated = FALSE;
|
|
(*ppDMAList)->push_back(peDMAList);
|
|
}
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::InitMEMList
|
|
//
|
|
// Purpose: Initialize a MEM resource vector given a config manager
|
|
// resource structure.
|
|
//
|
|
// Arguments:
|
|
// ppMEMList [out] returns MEM_LIST that will be created.
|
|
// pMEMResource [in] MEM_RESOURCE structure from config manager.
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID CHwRes::InitMEMList(PMEM_LIST* ppMEMList, PMEM_RESOURCE pMEMResource)
|
|
{
|
|
PMEM_DES pMEMHeader;
|
|
PMEM_RANGE pMEMData;
|
|
PMEM_LIST_ELEMENT peMEMList;
|
|
|
|
// For easy access
|
|
pMEMHeader = &(pMEMResource->MEM_Header);
|
|
pMEMData = pMEMResource->MEM_Data;
|
|
|
|
// Create a new list.
|
|
*ppMEMList = new MEM_LIST;
|
|
|
|
if (*ppMEMList == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ULONG iData; // index of MEM_Range structure we're looking at.
|
|
DWORDLONG MEMBase; // current MEM Base we're adding to the list.
|
|
ULONG cMEMBytes; // number of bytes required.
|
|
DWORDLONG MEMAlign;
|
|
|
|
// Go through all the MEM_Range structures, and all MEMs in the
|
|
// specified range to the list.
|
|
|
|
for (iData = 0; iData < pMEMHeader->MD_Count; iData++)
|
|
{
|
|
MEMAlign = pMEMData[iData].MR_Align;
|
|
cMEMBytes = pMEMData[iData].MR_nBytes;
|
|
|
|
// do sanity checks
|
|
if (0 == MEMAlign)
|
|
{
|
|
TraceTag(ttidNetComm, "CHwRes::InitMEMList() - Bogus alignment "
|
|
"field while processing info from Config Manager.");
|
|
break;
|
|
}
|
|
|
|
if (0 == cMEMBytes)
|
|
{
|
|
TraceTag(ttidNetComm, "CHwRes::InitMEMList() - Bogus membytes "
|
|
"field while processing info from Config Manager.");
|
|
break;
|
|
}
|
|
|
|
for (MEMBase = pMEMData[iData].MR_Min;
|
|
MEMBase+cMEMBytes-1 <= pMEMData[iData].MR_Max;
|
|
MEMBase += ~MEMAlign + 1)
|
|
{
|
|
// For each MEM that falls within the given range,
|
|
// create new MEM List Element, populate its fields and insert
|
|
// it into the MEMList.
|
|
peMEMList = new MEM_LIST_ELEMENT;
|
|
|
|
if (peMEMList == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
peMEMList->dwMEM_Base = MEMBase;
|
|
peMEMList->dwMEM_End = MEMBase + cMEMBytes - 1;
|
|
peMEMList->fConflict = FALSE;
|
|
peMEMList->fAllocated = FALSE;
|
|
(*ppMEMList)->push_back(peMEMList);
|
|
|
|
// Check for wrapping.
|
|
if (MEMBase >= MEMBase + ~MEMAlign + 1)
|
|
{
|
|
TraceTag(ttidError, "Memory base is greater than Memory "
|
|
"end!!!");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::InitIOList
|
|
//
|
|
// Purpose: Initialize an IO resource vector given a config manager
|
|
// resource structure.
|
|
//
|
|
// Arguments:
|
|
// ppIOList [out] returns IO_LIST that will be created.
|
|
// pIOResource [in] IO_RESOURCE structure from config manager.
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID CHwRes::InitIOList(PIO_LIST* ppIOList, PIO_RESOURCE pIOResource)
|
|
{
|
|
PIO_DES pIOHeader;
|
|
PIO_RANGE pIOData;
|
|
PIO_LIST_ELEMENT peIOList;
|
|
|
|
// For easy access
|
|
pIOHeader = &(pIOResource->IO_Header);
|
|
pIOData = pIOResource->IO_Data;
|
|
|
|
// Create a new list.
|
|
*ppIOList = new IO_LIST;
|
|
|
|
if (*ppIOList == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ULONG iData; // index of IO_Range structure we're looking at.
|
|
DWORDLONG IOBase; // current IO Base we're adding to the list.
|
|
ULONG cIOBytes; // number of bytes required.
|
|
DWORDLONG IOAlign;
|
|
|
|
// Go through all the IO_Range structures, and all IOs in the
|
|
// specified range to the list.
|
|
|
|
for (iData = 0; iData < pIOHeader->IOD_Count; iData++)
|
|
{
|
|
IOAlign = pIOData[iData].IOR_Align;
|
|
cIOBytes = pIOData[iData].IOR_nPorts;
|
|
|
|
// Perform sanity checks.
|
|
if (0 == IOAlign)
|
|
{
|
|
TraceTag(ttidError, "CHwRes::InitIOList - Bogus alignment field "
|
|
"while processing data from Config Manager.");
|
|
break;
|
|
}
|
|
|
|
if (0 == cIOBytes)
|
|
{
|
|
TraceTag(ttidError, "CHwRes::InitIOList - Bogus IObytes field "
|
|
"while processing data from Config Manager.");
|
|
break;
|
|
}
|
|
|
|
for (IOBase = pIOData[iData].IOR_Min;
|
|
IOBase+cIOBytes-1 <= pIOData[iData].IOR_Max;
|
|
IOBase += ~IOAlign + 1)
|
|
{
|
|
// For each IO that falls within the given range,
|
|
// create new IO List Element, populate its fields and insert
|
|
// it into the IOList.
|
|
peIOList = new IO_LIST_ELEMENT;
|
|
|
|
if (peIOList == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
peIOList->dwIO_Base = IOBase;
|
|
peIOList->dwIO_End = IOBase + cIOBytes-1;
|
|
peIOList->fConflict = FALSE;
|
|
peIOList->fAllocated = FALSE;
|
|
(*ppIOList)->push_back(peIOList);
|
|
|
|
// Check for wrapping.
|
|
if (IOBase >= IOBase + ~IOAlign+1)
|
|
{
|
|
TraceTag(ttidError, "IO base is greater than IO end!!!");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::UseAnswerFile
|
|
//
|
|
// Purpose: Reads in settings from answerfile and puts them into m_vAf*
|
|
// member variables.
|
|
//
|
|
// Arguments:
|
|
// szAnswerFile [in] Path to answerfile.
|
|
// szSection [in] Section to read within answerfile
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID CHwRes::UseAnswerFile(const WCHAR * const szAnswerFile, const WCHAR * const szSection) {
|
|
CWInfFile AnswerFile;
|
|
PCWInfSection pSection;
|
|
|
|
DWORD dw;
|
|
|
|
AssertSz(m_fInitialized,
|
|
"UseAnswerFile called before CHwRes class HrInit'ed");
|
|
|
|
// initialize answer file class
|
|
if (AnswerFile.Init() == FALSE)
|
|
{
|
|
AssertSz(FALSE,"CHwRes::UseAnswerFile - Failed to initialize CWInfFile");
|
|
return;
|
|
}
|
|
|
|
// Open the answerfile and find the desired section.
|
|
AnswerFile.Open(szAnswerFile);
|
|
pSection = AnswerFile.FindSection(szSection);
|
|
|
|
// If the answer file section specified is missing
|
|
// we should skip trying to read
|
|
//
|
|
if (pSection)
|
|
{
|
|
// Get the hardware resource keys
|
|
if (pSection->GetIntValue(c_szAfIoAddr, &dw))
|
|
{
|
|
// set this only if the value isn't obviously wrong (i.e. <= 0)
|
|
if (dw > 0)
|
|
{
|
|
m_vAfIo.SetDword(dw);
|
|
m_vAfIo.SetPresent(TRUE);
|
|
}
|
|
}
|
|
if (pSection->GetIntValue(c_szAfIrq, &dw))
|
|
{
|
|
// set this only if the value isn't obviously wrong (i.e. <= 0)
|
|
if (dw > 0)
|
|
{
|
|
m_vAfIrq.SetDword(dw);
|
|
m_vAfIrq.SetPresent(TRUE);
|
|
}
|
|
}
|
|
if (pSection->GetIntValue(c_szAfDma, &dw))
|
|
{
|
|
// set this only if the value isn't obviously wrong (i.e. <= 0)
|
|
if (dw > 0)
|
|
{
|
|
m_vAfDma.SetDword(dw);
|
|
m_vAfDma.SetPresent(TRUE);
|
|
}
|
|
}
|
|
if (pSection->GetIntValue(c_szAfMem, &dw))
|
|
{
|
|
// set this only if the value isn't obviously wrong (i.e. <= 0)
|
|
if (dw > 0)
|
|
{
|
|
m_vAfMem.SetDword(dw);
|
|
m_vAfMem.SetPresent(TRUE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::FValidateAnswerfileSettings
|
|
//
|
|
// Purpose:
|
|
// Ensures that the hw resource settings read in from the answerfile
|
|
// are valid. It will, optionally, raise UI if the properties
|
|
// are invalid.
|
|
//
|
|
// Arguments:
|
|
// fDisplayUI [in] TRUE, if an error UI is to be displayed if the
|
|
// answerfile settings are invalid
|
|
//
|
|
// Returns: HRESULT. S_OK if the answerfile settings are valid, S_FALSE if there
|
|
// are no resources to set, an error code otherwise
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes:
|
|
// Will set the m_vAfMemEnd and m_vAfIoEnd to correspond to
|
|
// m_vAfMem and m_vAfIo.
|
|
//
|
|
HRESULT
|
|
CHwRes::HrValidateAnswerfileSettings(BOOL fDisplayUI)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
AssertSz(m_fInitialized, "FValidateAnswerfileSettings called before "
|
|
"CHwRes class HrInit'ed");
|
|
|
|
// override current resource settings
|
|
if (!m_vAfDma.IsPresent() &&
|
|
!m_vAfIrq.IsPresent() &&
|
|
!m_vAfIo.IsPresent() &&
|
|
!m_vAfMem.IsPresent())
|
|
{
|
|
// no resources found...
|
|
TraceTag(ttidNetComm, "No Hardware Resources found in answerfile.");
|
|
hr = S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (!FValidateAnswerfileResources())
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
|
|
TraceError("Error setting adapter resources from "
|
|
"answerfile.", hr);
|
|
}
|
|
else
|
|
{
|
|
// m_vAfMemEnd and m_vAfIoEnd were set by
|
|
// FValidateAnswerfileResources()
|
|
Assert(FImplies(m_vAfMem.IsPresent(), m_vAfMemEnd.IsPresent()));
|
|
Assert(FImplies(m_vAfIo.IsPresent(), m_vAfIoEnd.IsPresent()));
|
|
}
|
|
}
|
|
TraceError("CHwRes::HrValidateAnswerfileSettings",
|
|
(S_FALSE == hr) ? S_OK : hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::FCommitAnswerfileSettings
|
|
//
|
|
// Purpose:
|
|
// Commits (to the config manager) the hw resource settings read
|
|
// in from the Answerfile.
|
|
//
|
|
// Returns: FALSE if there were problems writing the BootConfig entry.
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL CHwRes::FCommitAnswerfileSettings()
|
|
{
|
|
AssertSz(m_fInitialized, "FCommitAnswerfileSettings called before "
|
|
"CHwRes class HrInit'ed");
|
|
|
|
Assert(FImplies(m_vAfIo.IsPresent(), m_vAfIoEnd.IsPresent()));
|
|
Assert(FImplies(m_vAfMem.IsPresent(), m_vAfMemEnd.IsPresent()));
|
|
|
|
// write out forced config entry to the config manager
|
|
BOOL f;
|
|
f = FCreateBootConfig(&m_vAfMem, &m_vAfMemEnd,
|
|
&m_vAfIo, &m_vAfIo,
|
|
&m_vAfDma,
|
|
&m_vAfIrq);
|
|
return f;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::FValidateAnswerfileResources
|
|
//
|
|
// Purpose: Validates the resource requirements read in from Answerfile.
|
|
//
|
|
// Arguments:
|
|
// nID [out] ID of thingy.
|
|
// fInstall [in] TRUE if installing, FALSE otherwise.
|
|
// ppv [in,out] Old value is freed and this returns new value.
|
|
//
|
|
// Returns: TRUE, if resource requirement are valid.
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes:
|
|
// Implementation note: We have a set of resource requirements from
|
|
// the answerfile (stored in m_vAf*). This method iterates through
|
|
// every logical config (execept alloc or boot ones) and tests to see
|
|
// if the resource requirements are valid in the logical config.
|
|
// If they are, then we can use the resource requirements. If they're
|
|
// not all valid in any logical config, then we return FALSE.
|
|
//
|
|
BOOL CHwRes::FValidateAnswerfileResources()
|
|
{
|
|
DWORD dwMemEnd;
|
|
DWORD dwIoEnd;
|
|
BOOL fResourceValid;
|
|
|
|
AssertSz(m_fInitialized, "FValidateAnswerfileResources called before "
|
|
"CHwRes class HrInit'ed");
|
|
|
|
// Configuration List should be initialized
|
|
Assert(0 != m_ConfigList.size());
|
|
PRESOURCE pResource;
|
|
for (size_t iConfig = 0; iConfig < m_ConfigList.size(); iConfig++)
|
|
{
|
|
// we only want Basic configurations, so skip alloc or boot.
|
|
if (m_ConfigList[iConfig]->fBoot || m_ConfigList[iConfig]->fAlloc)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
fResourceValid = TRUE;
|
|
if (m_vAfDma.IsPresent())
|
|
{
|
|
if (!FValidateDMA(m_ConfigList[iConfig], m_vAfDma.GetDword()))
|
|
{
|
|
fResourceValid = FALSE;
|
|
}
|
|
}
|
|
if (m_vAfIrq.IsPresent())
|
|
{
|
|
if (!FValidateIRQ(m_ConfigList[iConfig], m_vAfIrq.GetDword()))
|
|
{
|
|
fResourceValid = FALSE;
|
|
}
|
|
}
|
|
if (m_vAfIo.IsPresent())
|
|
{
|
|
if (!FGetIOEndPortGivenBasePort(m_ConfigList[iConfig],
|
|
m_vAfIo.GetDword(), &dwIoEnd))
|
|
{
|
|
m_vAfIoEnd.SetPresent(FALSE);
|
|
fResourceValid = FALSE;
|
|
}
|
|
else
|
|
{
|
|
m_vAfIoEnd.SetDword(dwIoEnd);
|
|
m_vAfIoEnd.SetPresent(TRUE);
|
|
}
|
|
}
|
|
if (m_vAfMem.IsPresent())
|
|
{
|
|
if (!FGetMEMEndGivenBase(m_ConfigList[iConfig],
|
|
m_vAfMem.GetDword(), &dwMemEnd))
|
|
{
|
|
m_vAfMemEnd.SetPresent(FALSE);
|
|
fResourceValid = FALSE;
|
|
}
|
|
else
|
|
{
|
|
m_vAfMemEnd.SetDword(dwMemEnd);
|
|
m_vAfMemEnd.SetPresent(TRUE);
|
|
}
|
|
}
|
|
if (fResourceValid) break; // found valid one.
|
|
}
|
|
// something has to be present (otherwise don't call this function!)
|
|
Assert(m_vAfIo.IsPresent() || m_vAfIrq.IsPresent() ||
|
|
m_vAfDma.IsPresent() || m_vAfMem.IsPresent());
|
|
return fResourceValid;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::FCreateBootConfig
|
|
//
|
|
// Purpose: Create and insert a Boot Config entry into the Config
|
|
// Manager.
|
|
//
|
|
// Arguments:
|
|
// pvMem [in] Memory range base
|
|
// pvMemEnd [in] Memory range end
|
|
// pvIo [in] Io range base
|
|
// pvIoEnd [in] Io range end
|
|
// pvDma [in] Dma resource required.
|
|
// pvIrq [in] Irq resource required.
|
|
//
|
|
// Returns: TRUE if creation of forced config was successful.
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL CHwRes::FCreateBootConfig(
|
|
CValue * pvMem,
|
|
CValue * pvMemEnd,
|
|
CValue * pvIo,
|
|
CValue * pvIoEnd,
|
|
CValue * pvDma,
|
|
CValue * pvIrq)
|
|
{
|
|
DMA_RESOURCE DMARes;
|
|
IO_RESOURCE IORes;
|
|
MEM_RESOURCE MEMRes;
|
|
IRQ_RESOURCE IRQRes;
|
|
LOG_CONF lcLogConf = NULL;
|
|
|
|
AssertSz(pvMem && pvMemEnd && pvIo && pvIoEnd && pvDma && pvIrq,
|
|
"One of the pointer parameters passed to CHwRes::FCreate"
|
|
"BootConfig() is null.");
|
|
AssertSz(m_fInitialized, "FCreateBootConfig called before "
|
|
"CHwRes class HrInit'ed");
|
|
|
|
|
|
TraceTag(ttidNetComm, "In FCreateBootConfig");
|
|
|
|
// Create a boot config
|
|
//
|
|
if (CM_Add_Empty_Log_Conf(&lcLogConf, m_DevNode, LCPRI_BOOTCONFIG,
|
|
BOOT_LOG_CONF)
|
|
!= CR_SUCCESS)
|
|
{
|
|
TraceTag(ttidNetComm, "Unable to create BOOT_LOG_CONF");
|
|
return FALSE;
|
|
}
|
|
|
|
if (pvDma->IsPresent())
|
|
{
|
|
Assert(pvDma->GetDword() > 0);
|
|
// fill out DMAResource structure's header
|
|
ZeroMemory(&DMARes, sizeof(DMARes));
|
|
DMARes.DMA_Header.DD_Count = 0;
|
|
DMARes.DMA_Header.DD_Type = DType_Range;
|
|
DMARes.DMA_Header.DD_Flags = 0;
|
|
DMARes.DMA_Header.DD_Alloc_Chan = pvDma->GetDword();
|
|
// add to boot conf
|
|
CM_Add_Res_Des(NULL, lcLogConf, ResType_DMA, &DMARes,
|
|
sizeof(DMARes), 0);
|
|
TraceTag(ttidNetComm, "added Dma resource %lX", pvDma->GetDword());
|
|
}
|
|
if (pvIrq->IsPresent())
|
|
{
|
|
Assert(pvIrq->GetDword() > 0);
|
|
// IRQResource structure
|
|
ZeroMemory(&IRQRes, sizeof(IRQRes));
|
|
IRQRes.IRQ_Header.IRQD_Count = 0;
|
|
IRQRes.IRQ_Header.IRQD_Type = IRQType_Range;
|
|
IRQRes.IRQ_Header.IRQD_Flags |= fIRQD_Edge;
|
|
IRQRes.IRQ_Header.IRQD_Alloc_Num = pvIrq->GetDword();
|
|
IRQRes.IRQ_Header.IRQD_Affinity = 0;
|
|
// add to boot conf
|
|
CM_Add_Res_Des(NULL, lcLogConf, ResType_IRQ, &IRQRes,
|
|
sizeof(IRQRes), 0);
|
|
TraceTag(ttidNetComm, "added IRQ resource %lX", pvIrq->GetDword());
|
|
}
|
|
if (pvIo->IsPresent()) {
|
|
Assert(pvIo->GetDword() > 0);
|
|
Assert(pvIoEnd->GetDword() > 0);
|
|
ZeroMemory(&IORes, sizeof(IORes));
|
|
IORes.IO_Header.IOD_Count = 0;
|
|
IORes.IO_Header.IOD_Type = IOType_Range;
|
|
IORes.IO_Header.IOD_Alloc_Base = pvIo->GetDword();
|
|
IORes.IO_Header.IOD_Alloc_End = pvIoEnd->GetDword();
|
|
IORes.IO_Header.IOD_DesFlags = fIOD_10_BIT_DECODE;
|
|
// add to boot conf
|
|
CM_Add_Res_Des(NULL, lcLogConf, ResType_IO, &IORes, sizeof(IORes), 0);
|
|
TraceTag(ttidNetComm, "added IO resource %lX-%lX", pvIo->GetDword(),
|
|
pvIoEnd->GetDword());
|
|
}
|
|
|
|
if (pvMem->IsPresent()) {
|
|
Assert(pvMem->GetDword() > 0);
|
|
Assert(pvMemEnd->GetDword() > 0);
|
|
ZeroMemory(&MEMRes, sizeof(MEMRes));
|
|
MEMRes.MEM_Header.MD_Count = 0;
|
|
MEMRes.MEM_Header.MD_Type = MType_Range;
|
|
MEMRes.MEM_Header.MD_Alloc_Base = pvMem->GetDword();
|
|
MEMRes.MEM_Header.MD_Alloc_End = pvMemEnd->GetDword();
|
|
MEMRes.MEM_Header.MD_Flags = 0;
|
|
// add to boot conf
|
|
CM_Add_Res_Des(NULL, lcLogConf, ResType_Mem, &MEMRes,
|
|
sizeof(MEMRes), 0);
|
|
TraceTag(ttidNetComm, "added Memory resource %lX - %lX",
|
|
pvMem->GetDword(), pvMemEnd->GetDword());
|
|
}
|
|
|
|
CM_Free_Log_Conf_Handle(lcLogConf);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::FValidateIRQ
|
|
//
|
|
// Purpose: Validates that the IRQ given is valid in the given config.
|
|
//
|
|
// Arguments:
|
|
// pConfig [in] Config to use.
|
|
// dwIRQ [in] irq setting to validate.
|
|
//
|
|
// Returns: TRUE if irq setting is valid.
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL CHwRes::FValidateIRQ(PCONFIGURATION pConfig, ULONG dwIRQ)
|
|
{
|
|
PIRQ_LIST pIRQList;
|
|
|
|
AssertSz(m_fInitialized, "FValidateIRQ called before "
|
|
"CHwRes class HrInit'ed");
|
|
|
|
Assert(pConfig != NULL);
|
|
Assert(dwIRQ > 0);
|
|
// For each IRQ resource in the given config
|
|
// go through list of valid IRQ looking for given one
|
|
// if found, return TRUE
|
|
for (size_t iRes = 0; iRes < pConfig->cResource; iRes++)
|
|
{
|
|
if (pConfig->aResource[iRes].ResourceType != ResType_IRQ)
|
|
continue;
|
|
|
|
pIRQList = pConfig->aResource[iRes].pIRQList; // for easy access
|
|
for (size_t iIRQ = 0; iIRQ < pIRQList->size(); iIRQ++)
|
|
{
|
|
if ((*pIRQList)[iIRQ]->dwIRQ == dwIRQ)
|
|
{
|
|
return TRUE; // found it.
|
|
}
|
|
}
|
|
}
|
|
|
|
TraceTag(ttidNetComm, "IRQ %lX is not valid for this device", dwIRQ);
|
|
return FALSE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::FValidateDMA
|
|
//
|
|
// Purpose: Validate that given DMA is valid in given config.
|
|
//
|
|
// Arguments:
|
|
// pConfig [in] configuration to use
|
|
// dwDMA [in] dma setting to validate
|
|
//
|
|
// Returns: TRUE if dma setting is valid
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL CHwRes::FValidateDMA(PCONFIGURATION pConfig, ULONG dwDMA)
|
|
{
|
|
PDMA_LIST pDMAList;
|
|
|
|
AssertSz(m_fInitialized, "FValidateDMA called before "
|
|
"CHwRes class HrInit'ed");
|
|
|
|
Assert(pConfig != NULL);
|
|
Assert(dwDMA > 0);
|
|
// For each dma resource in the given config
|
|
// go through list of valid dma looking for given one
|
|
// if found, return TRUE
|
|
for (size_t iRes = 0; iRes < pConfig->cResource; iRes++)
|
|
{
|
|
if (pConfig->aResource[iRes].ResourceType != ResType_DMA)
|
|
continue;
|
|
|
|
pDMAList = pConfig->aResource[iRes].pDMAList; // for easy access
|
|
for (size_t iDMA = 0; iDMA < pDMAList->size(); iDMA++)
|
|
{
|
|
if ((*pDMAList)[iDMA]->dwDMA == dwDMA)
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
TraceTag(ttidNetComm, "DMA %lX is not valid for this device", dwDMA);
|
|
return FALSE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::FGetIOEndPortGivenBasePort
|
|
//
|
|
// Purpose: Get an IO Range given only the BasePort
|
|
//
|
|
// Arguments:
|
|
// pConfig [in] configuration to use.
|
|
// dwBase [in] Io base
|
|
// pdwEnd [out] Io end is returned
|
|
//
|
|
// Returns: TRUE if Io base is valid in given config.
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL CHwRes::FGetIOEndPortGivenBasePort(PCONFIGURATION pConfig, DWORD dwBase,
|
|
DWORD * pdwEnd)
|
|
{
|
|
PIO_LIST pIOList;
|
|
|
|
AssertSz(m_fInitialized, "FGetIOEndPortGivenBasePort called before "
|
|
"CHwRes class HrInit'ed");
|
|
|
|
Assert(pConfig != NULL);
|
|
Assert(dwBase > 0);
|
|
// For each resource in the given configuration
|
|
// if it's an IO Resource
|
|
// Go through the list of valid IO resources looking for
|
|
// a matching base port
|
|
// if found, then set the corresponding end port, return TRUE;
|
|
for (size_t iRes = 0; iRes < pConfig->cResource; iRes++)
|
|
{
|
|
// ensure we're looking at an IO type
|
|
if (pConfig->aResource[iRes].ResourceType != ResType_IO)
|
|
continue;
|
|
|
|
pIOList = pConfig->aResource[iRes].pIOList; // for easy access
|
|
// go through all IO Elements in this list
|
|
for (size_t iIO = 0; iIO < pIOList->size(); iIO++)
|
|
{
|
|
if ((*pIOList)[iIO]->dwIO_Base == dwBase)
|
|
{
|
|
// found matching IO base port
|
|
*pdwEnd = (*pIOList)[iIO]->dwIO_End;
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
TraceTag(ttidNetComm, "IO %lX is not valid for this device", dwBase);
|
|
return FALSE; // not found
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHwRes::FGetMEMEndGivenBase
|
|
//
|
|
// Purpose: Get a MEM range given the Mem base and config.
|
|
//
|
|
// Arguments:
|
|
// pConfig [in] configuration to use
|
|
// dwBase [in] mem base
|
|
// pdwEnd [out] mem end is returned.
|
|
//
|
|
// Returns: TRUE if the dwBase is a valid mem setting.
|
|
//
|
|
// Author: t-nabilr 07 Apr 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL CHwRes::FGetMEMEndGivenBase(PCONFIGURATION pConfig, DWORD dwBase,
|
|
DWORD * pdwEnd)
|
|
{
|
|
PMEM_LIST pMEMList;
|
|
|
|
AssertSz(m_fInitialized, "FGetMEMEndGivenBase called before "
|
|
"CHwRes class HrInit'ed");
|
|
|
|
Assert(pConfig != NULL);
|
|
Assert(dwBase > 0);
|
|
// For each resource in the given configuration
|
|
// if it's an MEM Resource
|
|
// Go through the list of valid MEM resources looking for
|
|
// a matching base port
|
|
// if found, then set the corresponding end port,return TRUE;
|
|
for (size_t iRes = 0; iRes < pConfig->cResource; iRes++)
|
|
{
|
|
// ensure we're looking at an MEM type
|
|
if (pConfig->aResource[iRes].ResourceType != ResType_Mem)
|
|
continue;
|
|
|
|
pMEMList = pConfig->aResource[iRes].pMEMList; // for easy access
|
|
// go through all MEM Elements in this list
|
|
for (size_t iMEM = 0; iMEM < pMEMList->size(); iMEM++)
|
|
{
|
|
if ((*pMEMList)[iMEM]->dwMEM_Base == dwBase)
|
|
{
|
|
// found matching MEM base addr
|
|
*pdwEnd = (*pMEMList)[iMEM]->dwMEM_End;
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
TraceTag(ttidNetComm, "Memory %lX is not valid for this device", dwBase);
|
|
return FALSE; // not found
|
|
}
|
|
|
|
//$REVIEW (t-pkoch) this function isn't yet in our custom STL...
|
|
// it can be removed later (when it causes errors)
|
|
|
|
template<class T> void os_release(vector<T> & v)
|
|
{
|
|
for(vector<T>::iterator iterDelete = v.begin() ; iterDelete != v.end() ;
|
|
++iterDelete)
|
|
delete *iterDelete;
|
|
}
|
|
|
|
|
|
CHwRes::~CHwRes()
|
|
{
|
|
AssertSz(m_fHrInitCalled, "CHwRes destructor called before "
|
|
"CHwRes::HrInit() called");
|
|
|
|
vector<CONFIGURATION *>::iterator ppConfig;
|
|
RESOURCE * pRes;
|
|
|
|
// Delete everything from m_ConfigList.
|
|
for (ppConfig = m_ConfigList.begin(); ppConfig != m_ConfigList.end();
|
|
ppConfig++)
|
|
{
|
|
for (size_t iRes = 0; iRes < (*ppConfig)->cResource; iRes++)
|
|
{
|
|
pRes = &((*ppConfig)->aResource[iRes]);
|
|
switch(pRes->ResourceType)
|
|
{
|
|
case ResType_IRQ:
|
|
os_release(*(pRes->pIRQList));
|
|
delete pRes->pIRQList;
|
|
break;
|
|
case ResType_DMA:
|
|
os_release(*(pRes->pDMAList));
|
|
delete pRes->pDMAList;
|
|
break;
|
|
case ResType_IO:
|
|
os_release(*(pRes->pIOList));
|
|
delete pRes->pIOList;
|
|
break;
|
|
case ResType_Mem:
|
|
os_release(*(pRes->pMEMList));
|
|
delete pRes->pMEMList;
|
|
break;
|
|
}
|
|
}
|
|
delete *ppConfig;
|
|
}
|
|
|
|
|
|
ReleaseObj(m_pnccItem);
|
|
}
|