📄 cardservice.c
字号:
// Save pointer to default
if (cfgP->isDefault)
{
defaultCfgP = cfgP;
}
// If the interface description is present decode the info
if (mask & (1 << 7))
{
cfgP->interfaceType = (*p >> 0) & 15;
cfgP->waitRequired = (*p >> 7) & 1;
cfgP->rdyBsyActive = (*p >> 6) & 1;
cfgP->wpActive = (*p >> 5) & 1;
cfgP->bvdActive = (*p >> 4) & 1;
p++;
}
// Get the feature selection mask
mask = *p++;
// If the power structures are present go decode
switch(mask & 3)
{
case 1:
p = decodePower(p, &cfgP->vcc);
break;
case 2:
p = decodePower(p, &cfgP->vcc);
p = decodePower(p, &cfgP->vpp1);
cfgP->vpp2 = cfgP->vpp1;
break;
case 3:
p = decodePower(p, &cfgP->vcc);
p = decodePower(p, &cfgP->vpp1);
p = decodePower(p, &cfgP->vpp2);
break;
}
// If the timing structure is present decode it
if (mask & (1 << 2))
{
p = decodeTiming(p, cfgP);
}
// If the IO structure is present decode it
if (mask & (1 << 3))
{
p = decodeIO(p, cfgP);
}
// If the IRQ structure is present decode it
if (mask & (1 << 4))
{
p = decodeIRQ(p, cfgP);
}
// If the memory structure is present decode it
if (mask & (3 << 5))
{
p = decodeMemory(p, cfgP, (mask >> 5) & 3);
}
// If the misc structure is present decode it
if (mask & (1 << 7))
{
p = decodeMisc(p, cfgP);
}
// Ignore the final descriptors, a number of cards do not fill in with
// tuples.
if (p < endP)
{
p = endP;
}
return (p);
}
/*
*******************************************************************************
*
* FUNCTION:
* decodeTuple
*
* DESCRIPTION:
* Decode a basic level 1 Card Information Structure (CIS) Tuple. Refer to
* the PC Card Standard, Volume 4, Metaformat Specification for details.
*
* INPUT PARAMETERS:
* PUCHAR p - Pointer to a CIS entry.
* CIS_EntryT * cisP - Pointer to the CIS table.
*
* RETURNS:
* None.
*
* GLOBAL EFFECTS:
* None.
*
* ASSUMPTIONS:
* The pointer to the tuple is a valid virtual address.
* The CIS pointer is a valid virtual address.
*
* CALLS:
* copyString, decodeAddrValue, decodeCFTableEntry
*
* CALLED BY:
* decodeNextTuple
*
* PROTOTYPE:
* static
* VOID decodeTuple(PUCHAR p, CIS_EntryT * cisP);
*
*******************************************************************************
*/
static
VOID decodeTuple(PUCHAR p, CIS_EntryT * cisP)
{
INT code = p[0];
INT len = p[1];
INT rasz, rmsz;
PostDisplayProgress(ERR_L_PCMCIA, 0x83, 0);
switch(code)
{
case CISTPL_Device:
PostDisplayProgress(ERR_L_PCMCIA, 0x83, 1);
cisP->deviceType = (p[2] >> 4) & 15;
cisP->wp = (p[2] >> 3) & 1;
cisP->speed = (p[2] >> 0) & 7;
cisP->size = (p[3] >> 3) & 31;
cisP->unitSize = p[3] & 7;
break;
case CISTPL_Vers_1:
PostDisplayProgress(ERR_L_PCMCIA, 0x83, 2);
cisP->version = (p[2] << 8) | p[3];
p += 4;
if (*p != 255)
{
p = copyString((PUCHAR)cisP->manName,p);
}
if (*p != 255)
{
p = copyString((PUCHAR)cisP->prodName,p);
}
if (*p != 255)
{
p = copyString((PUCHAR)cisP->prodVersion,p);
}
if (*p != 255)
{
p = copyString((PUCHAR)cisP->prodLot,p);
}
break;
case CISTPL_Manfid:
PostDisplayProgress(ERR_L_PCMCIA, 0x83, 3);
cisP->manfId = (p[3] << 8) | p[2];
cisP->prodId = p[4];
cisP->versionId = p[5];
break;
case CISTPL_Funcid:
PostDisplayProgress(ERR_L_PCMCIA, 0x83, 4);
cisP->funcType = p[2];
cisP->postInit = p[3] & 1;
cisP->expansionRom = p[3] & 2;
break;
case CISTPL_Config:
PostDisplayProgress(ERR_L_PCMCIA, 0x83, 5);
rasz = (p[2] >> 0) & 7;
rmsz = (p[2] >> 3) & 7;
cisP->lastIndex = p[3];
p += 4;
decodeAddrValue(p,rasz > 3 ? 4 : rasz+1,&cisP->radrBase);
p += rasz+1;
decodeAddrValue(p,rmsz > 3 ? 4 : rmsz+1,&cisP->rmsk);
break;
case CISTPL_CFTable_Entry:
{
PUCHAR t;
PostDisplayProgress(ERR_L_PCMCIA, 0x83, 6);
t = decodeCFTableEntry(p,&cisP->config[cisP->configCount++]);
if (t != &p[len+2])
{
DM_Warning("Incomplete config decode\r\n");
}
break;
}
case CISTPL_No_Link:
PostDisplayProgress(ERR_L_PCMCIA, 0x83, 7);
break;
case CISTPL_End:
PostDisplayProgress(ERR_L_PCMCIA, 0x83, 8);
break;
default:
PostDisplayProgress(ERR_L_PCMCIA, 0x83, 9);
break;
}
}
/*
*******************************************************************************
*
* FUNCTION:
* decodeNextTuple
*
* DESCRIPTION:
* Decode the next Card Information Structure (CIS) Tuple. Refer to the PC
* Card Standard, Volume 4, Metaformat Specification for details.
*
* INPUT PARAMETERS:
* PUINT16 p - Pointer to the entry
* CIS_EntryT * cisP - The CIS tuple
*
* RETURNS:
* The pointer to the next entry.
*
* GLOBAL EFFECTS:
* None.
*
* ASSUMPTIONS:
* The pointer to the tuple is a valid virtual address.
* The return pointer is a valid virtual address.
*
* CALLS:
* decodeTuple
*
* CALLED BY:
* decodeCIS
*
* PROTOTYPE:
* static
* unsigned short * decodeNextTuple(PUINT16 p, CIS_EntryT * cisP);
*
*******************************************************************************
*/
static
unsigned short * decodeNextTuple(PUINT16 p, CIS_EntryT * cisP)
{
INT code = p[0] & 0xff;
INT len = p[1] & 0xff;
static CHAR buffer[256];
INT i;
PostDisplayProgress(ERR_L_PCMCIA, 0x82, 0);
if ((code == 0) && (len == 0))
{
return (NULL);
}
if (code == 0xFF)
{
len = 0;
}
memset(buffer,0x55,sizeof(buffer));
for (i=0; i < len+2; i++)
{
buffer[i] = p[i];
}
PostDisplayProgress(ERR_L_PCMCIA, 0x82, 1);
decodeTuple((PUCHAR)buffer, cisP);
PostDisplayProgress(ERR_L_PCMCIA, 0x82, 2);
if (code == 0xff)
{
return (NULL);
}
return (p + len + 2);
}
/*
*******************************************************************************
*
* FUNCTION:
* decodeCIS
*
* DESCRIPTION:
* Decode a Card Information Structure (CIS) Configuration Tuple. Refer to
* the PC Card Standard, Volume 4, Metaformat Specification for details.
*
* INPUT PARAMETERS:
* SocketStatusT * infoP - Pointer to the socket status structure
* CIS_EntryT * cisP - Pointer to a CIS entry
*
* RETURNS:
* None.
*
* GLOBAL EFFECTS:
* None.
*
* ASSUMPTIONS:
* The pointer to the tuple is a valid virtual address.
*
* CALLS:
* decodeNextTuple
*
* CALLED BY:
* CardServices_Setup
*
* PROTOTYPE:
* static
* VOID decodeCIS(SocketStatusT * infoP, CIS_EntryT * cisP);
*
*******************************************************************************
*/
static VOID decodeCIS(SocketStatusT * infoP, CIS_EntryT * cisP)
{
PUINT16 attSpaceP;
// Get a pointer to attribute space
attSpaceP = (PUINT16)infoP->attSpaceP;
PostDisplayProgress(ERR_L_PCMCIA, 0x81, 0);
// Clear out the configuration record
memset(cisP, 0, sizeof(CIS_EntryT));
cisP->funcType = CIS_FunctionNone;
cisP->attSpaceP = infoP->attSpaceP;
cisP->ioSpaceP = infoP->ioSpaceP;
cisP->memSpaceP = infoP->memSpaceP;
defaultCfgP = NULL;
// Decode the CIS entries
PostDisplayProgress(ERR_L_PCMCIA, 0x81, 1);
while (((attSpaceP=decodeNextTuple(attSpaceP, cisP)) != NULL) &&
(cisP->configCount < MAX_CONFIG)) ;
PostDisplayProgress(ERR_L_PCMCIA, 0x81, 2);
// Adjust the configuration register base offset to form address
cisP->radrBase += (unsigned)infoP->attSpaceP;
}
/*
*******************************************************************************
*
* FUNCTION:
* selectConfig
*
* DESCRIPTION:
* Select a configuration and make the selection active in the card
*
* INPUT PARAMETERS:
* SocketStatusT * infoP - Pointer to the socket structure
* CIS_EntryT * cisP - Pointer to the CIS entry
* INT cfgIndex - Index into the configuration entry
*
* RETURNS:
* None
*
* GLOBAL EFFECTS:
* Set the PC Card configuration.
*
* ASSUMPTIONS:
* The pointer to the CIS is a valid virtual address.
*
* CALLS:
* None.
*
* CALLED BY:
* findConfig
*
* PROTOTYPE:
* static
* VOID selectConfig(SocketStatusT * infoP, CIS_EntryT * cisP, INT cfgIndex)
*
*******************************************************************************
*/
static
VOID selectConfig(SocketStatusT * infoP, CIS_EntryT * cisP, INT cfgIndex)
{
INT irqLevel = cisP->config[cfgIndex].irqLevel;
INT entryNum = cisP->config[cfgIndex].entryNum;
PUCHAR radrP = (PUCHAR)cisP->radrBase;
INT i;
// Set the IO and memory base from the selection
cisP->numIoBase = cisP->config[cfgIndex].numIoRange;
for (i=0; i < cisP->numIoBase; i++)
{
cisP->ioBase[i] = (unsigned)infoP->ioSpaceP +
cisP->config[cfgIndex].ioRange[i].base;
}
cisP->numMemBase = cisP->config[cfgIndex].numMemRange;
for (i=0; i < cisP->numMemBase; i++)
{
cisP->memBase[i] = (unsigned)infoP->memSpaceP +
cisP->config[cfgIndex].memRange[i].base;
}
// Write the configuration to the card
*radrP = entryNum | (irqLevel << 6);
// Save the config index
cisP->selectIndex = cfgIndex;
}
/*
*******************************************************************************
*
* FUNCTION:
* findConfig
*
* DESCRIPTION:
* Select a configuration, basic enabler
*
* INPUT PARAMETERS:
* SocketStatusT * infoP - Pointer to the socket structure
* CIS_EntryT * cisP - Pointer to the CIS entry
*
* RETURNS:
* Pointer to the configuration entry.
*
* GLOBAL EFFECTS:
* None.
*
* ASSUMPTIONS:
* None.
*
* CALLS:
* selectConfig
*
* CALLED BY:
* CardServices_Setup
*
* PROTOTYPE:
* static
* PVOID findConfig(SocketStatusT * infoP, CIS_EntryT * cisP);
*
*******************************************************************************
*/
static
PVOID findConfig(SocketStatusT * infoP, CIS_EntryT * cisP)
{
INT i;
CIS_ConfigT * xcfgP = NULL;
// Allow no config
if (cisP->configCount == 0)
{
return (NULL);
}
// Loop thru all the configuration records
for (i=0; i < cisP->configCount; i++)
{
CIS_ConfigT * cfgP = &cisP->config[i];
// Only select configurations with IO space registers
if (!cfgP->numIoRange)
{
continue;
}
// Configuration acceptable
selectConfig(infoP, cisP, i);
xcfgP = cfgP;
break;
}
return (xcfgP);
}
/*
*******************************************************************************
*
* FUNCTION:
* decodeFuncId
*
* DESCRIPTION:
* Display the function type
*
* INPUT PARAMETERS:
* int funcId - The function type
*
* RETURNS:
* Pointer to a string for the function type.
*
* GLOBAL EFFECTS:
* None.
*
* ASSUMPTIONS:
* None.
*
* CALLS:
* None.
*
* CALLED BY:
* displayCISInfo
*
* PROTOTYPE:
* static
* PCHAR decodeFuncId(int funcId)
*
*******************************************************************************
*/
static
PCHAR decodeFuncId(int funcId)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -