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

📄 common.cpp

📁 wince5.0 pb中pccard源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            pCfTable->ReadyActive   = *pCIS & 0x40;
            pCfTable->WaitRequired  = *pCIS & 0x80;
        } else {
            //pCfTable->IFacePresent = FALSE;
        }
        pCIS++;
        if (dwLen--==0)  goto pcft_continue;

        //
        // Parse the feature select byte
        //

        //
        // Power requirements present
        //
        bmPowerPresent = *pCIS & 0x03;

        //
        // Timing description present
        //
        TimingPresent = *pCIS & 0x04;

        //
        // I/O space descriptions present
        //
        IOPresent = *pCIS & 0x08;

        //
        // Irq description present
        //
        IrqPresent = *pCIS & 0x10;
        //
        // Memory description present
        //
        MemPresent = *pCIS & 0x60;


        pCIS++;
        if (dwLen--==0)  goto pcft_continue;

        //
        // Parse the power description structures if present
        //
	    DWORD dwParsedLength;
	    if (bmPowerPresent >= 1) {
	        pCfTable->VccDescr.ValidMask = 0xFF;
	        pCIS +=(dwParsedLength=ParseVoltageDescr(pCIS, &pCfTable->VccDescr));
	        if (dwParsedLength >dwLen)  goto pcft_continue;
	        dwLen -=dwParsedLength;
	        for (i = 0; i < 3; i++) {
	            if ((PWR_DESCR_NOMINALV << i) & pCfTable->VccDescr.ValidMask )
	                pCfTable->VccDescr.ValidMask |= (PWR_AVAIL_NOMINALV << i);
	        }
	    }
	    if (bmPowerPresent >= 2) {
	        pCfTable->Vpp1Descr.ValidMask = 0xFF;
	        pCIS += (dwParsedLength=ParseVoltageDescr(pCIS, &pCfTable->Vpp1Descr));
	        if (dwParsedLength >dwLen)  goto pcft_continue;
	        dwLen -=dwParsedLength;
	        
	        for (i = 0; i < 3; i++) {
	            if ((PWR_DESCR_NOMINALV << i) & pCfTable->Vpp1Descr.ValidMask )
	                pCfTable->Vpp1Descr.ValidMask |= (PWR_AVAIL_NOMINALV << i);
	        }
	        
	        pCfTable->Vpp2Descr.ValidMask = 0xFF;
	        if (bmPowerPresent == 3) {
	            pCIS += (dwParsedLength=ParseVoltageDescr(pCIS, &pCfTable->Vpp2Descr));
		        if (dwParsedLength >dwLen)  goto pcft_continue;
		        dwLen -=dwParsedLength;
	            for (i = 0; i < 3; i++) {
	                if ((PWR_DESCR_NOMINALV << i) & pCfTable->Vpp1Descr.ValidMask )
	                    pCfTable->Vpp2Descr.ValidMask |= (PWR_AVAIL_NOMINALV << i);
	            }
	        } else
	            pCfTable->Vpp2Descr = pCfTable->Vpp1Descr;
	    }
	    


        //
        // Skip the timing information
        //
        if ( TimingPresent ) {
            pTmp = pCIS;

            pCIS++;
            if (dwLen--==0)  goto pcft_continue;
            if ( (*pTmp & 0x03) != 0x03 ) {
                while ( *pCIS++ & TPCE_PD_EXT ){
			        if (dwLen--==0)  goto pcft_continue;
                }
            }
            if ( (*pTmp & 0x1C) != 0x1C ) {
                while ( *pCIS++ & TPCE_PD_EXT ){
			        if (dwLen--==0)  goto pcft_continue;
                }
            }
        }


        //
        // Process the I/O address ranges (up to MAX_IO_RANGES)
        //
        if (IOPresent) {
            pCfTable->NumIOAddrLines = *pCIS & 0x1F;
            pCfTable->IOAccess = (*pCIS & 0x60) >> 5;   // type of access allowed
            if (*pCIS & 0x80) {  // range present bit
                UINT8   AddrSize, LengthSize;
                pCIS++;
	          if (dwLen--==0)  goto pcft_continue;
                pCfTable->NumIOEntries = (*pCIS & 0x0F) + 1;
                if (pCfTable->NumIOEntries > MAX_IO_RANGES) {
                    DEBUGMSG(ZONE_WARNING,
                             (TEXT("PCMCIA ParseCfTable: too many I/O ranges; ignoring some.\n")));
                    pCfTable->NumIOEntries = MAX_IO_RANGES;
                }
                AddrSize = (*pCIS & 0x30) >> 4;
                if (AddrSize == 3) {
                    AddrSize = 4;
                }
                LengthSize = (*pCIS & 0xC0) >> 6;
                if (LengthSize == 3) {
                    LengthSize = 4;
                }
                pCIS++;
	          if (dwLen--==0)  goto pcft_continue;

                for (i = 0; i < pCfTable->NumIOEntries; i++) {
                    pCfTable->IOBase[i] = VarToFixed(AddrSize, pCIS);
                    pCIS += AddrSize;
			 if((dwLen - AddrSize) <= 0) goto pcft_continue;
                    pCfTable->IOLength[i] = VarToFixed(LengthSize, pCIS);
                    pCIS += LengthSize;
			 if((dwLen - AddrSize) <= 0) goto pcft_continue;
                }
		
            } else {
                // NumIOEntries is a misnomer; it's really the number of IO ranges.
                pCfTable->NumIOEntries = 0;
            }
        }

        // Irq description present
        //
        if ( IrqPresent) {
            if ((*pCIS & 0x10)==0) { // Mask Bit is set
                pCfTable->wIrqMask =(1<< (*pCIS & 0xf));
                pCIS++;
	          if (dwLen--==0)  goto pcft_continue;
            }
            else {
	          if (dwLen <3)  goto pcft_continue;
                pCIS++;
                pCfTable->wIrqMask=*pCIS+(((WORD)*(pCIS+1))<<8);
                pCIS+=2;
                dwLen -= 3;
            }
        }

        if (MemPresent) {
            if (MemPresent == 0x20) {//Signle 2 byte length present
                if (dwLen<2) goto pcft_continue;
                UINT32 uSize = *pCIS + (*(pCIS+1)<<8);
                ASSERT(uSize!=0);
                pCIS += 2;
                pCfTable->NumMemEntries= 1;
                pCfTable->MemBase[0] = 0;
                pCfTable->MemLength[0] = uSize*0x100;
                dwLen -=2;
            }
            else
            if (MemPresent == 0x40) {//Signle 2 byte length & base present
                if (dwLen<4) goto pcft_continue;
                UINT32 uSize = *pCIS + (*(pCIS+1)<<8);
                ASSERT(uSize!=0);
                pCIS +=2;
                UINT32 uBase =*pCIS + (*(pCIS+1)<<8);
                pCIS +=2;
                pCfTable->NumMemEntries = 1;
                pCfTable->MemLength[0] = uSize*0x100;
                pCfTable->MemBase[0] = uBase*0x100;
            }
            else { // Memory Descriptor structure present.
                UINT8   AddrSize, LengthSize,bHostAddress, NumOfEntries;
                pCfTable->NumMemEntries = NumOfEntries= (*pCIS & 0x07) + 1;
                LengthSize = ((*pCIS & 0x18)>>3);
                AddrSize =  ((*pCIS & 0x60)>> 5);
                bHostAddress = (*pCIS & 0x80);
                if (pCfTable->NumMemEntries > MAX_WINDOWS_RANGES) {
                    DEBUGMSG(ZONE_WARNING, (TEXT("PCMCIA ParseCfTable: too many I/O ranges; ignoring some.\n")));
                    pCfTable->NumMemEntries = MAX_IO_RANGES;
                }
                pCIS++;
                if (dwLen--==0)  goto pcft_continue;
                for (i =0 ; i< NumOfEntries; i ++) {
                    UINT32 uSize = 0;
                    UINT32 uBase = 0;
                    UINT32 uShift = 0;
                    for (int NumOfBytes =0;  NumOfBytes < LengthSize; NumOfBytes++) {
                        uSize += ((*pCIS)<<uShift);
                        pCIS++;
                        uShift +=8;
                        if (dwLen--==0) goto pcft_continue;
                    }
                    for (NumOfBytes =0;  NumOfBytes < AddrSize; NumOfBytes++) {
                        uBase += ((*pCIS)<<uShift);
                        pCIS++;
                        uShift +=8;
                        if (dwLen--==0) goto pcft_continue;
                    }
                    // We ignore host address. but we have to parsed it.
                    for (NumOfBytes =0;  NumOfBytes < AddrSize && bHostAddress!=0; NumOfBytes++) {
                        pCIS++;
                        if (dwLen--==0)  goto pcft_continue;
                    }
                    ASSERT(uSize!=0 );
                    if (i < MAX_WINDOWS_RANGES) {
                        pCfTable->MemBase[i] = uBase*0x100;
                        pCfTable->MemLength[i] = uSize*0x100;
                    }
    
                }
            }
        }

        // else it has already been either defaulted or memset to zeros.

pcft_continue:
        pCfTable++;

pcft_next:
        if ((pBuf != NULL) && (nItems == *pnItems)) {
            status = CERR_NO_MORE_ITEMS;    // no more room in caller's buffer
        } else {
            //
            // Get the next CISTPL_CFTABLE_ENTRY
            //
            status = CardGetNextTuple(pTuple);
        }
    }   // while (status == CERR_SUCCESS)

pcft_exit:
    *pnItems = nItems;

    //
    // If there were problems and no CFTABLE_ENTRYs found then return an error.
    //
    if (nItems) {
        return CERR_SUCCESS;
    }
    return status;

}
USHORT VoltageConversionTable[16] = {
    10, 12, 13, 15, 20, 25, 30, 35,
    40, 45, 50, 55, 60, 70, 80, 90
};

//
// ConvertVoltage - normalize a single CISTPL_CFTABLE_ENTRY voltage entry and
//                  return its length in bytes
//
UINT ConvertVoltage(PUCHAR pCIS, PUSHORT pDescr)
{
    if(pCIS == NULL || pDescr == NULL)
        return 0;
        
    UINT Length;
    SHORT power;
    USHORT value;
    UCHAR MantissaExponentByte;
    UCHAR ExtensionByte;

    Length = 1;
    power = 1;
    MantissaExponentByte = pCIS[0];
    ExtensionByte = pCIS[1];
    value = VoltageConversionTable[(MantissaExponentByte >> 3) & 0x0f];

    if ((MantissaExponentByte & TPCE_PD_EXT) &&
        (ExtensionByte < 100)) {
        value = (100 * value + (ExtensionByte & 0x7f));
        power += 2;
    }

    power = (MantissaExponentByte & 0x07) - 4 - power;

    while (power > 0) {
        value *= 10;
        power--;
    }

    while (power < 0) {
        value /= 10;
        power++;
    }

    *pDescr = value;

    //
    // Skip any subsequent extension bytes for now.
    //
    while (*pCIS & TPCE_PD_EXT) {
        Length++;
        pCIS++;
    }

    return Length;
}   // ConvertVoltage


//
// ParseVoltageDescr - convert the variable length power description structure
//                     from a CISTPL_CFTABLE_ENTRY to a POWER_DESCR structure
//                     and normalize the values.
// Returns the length of the variable length power description structure.
//
// A typical call would be:
//        if (pCfTable->VccDescr.ValidMask) {
//            pCIS += ParseVoltageDescr(pCIS, &pCfTable->VccDescr);
//        }
//
UINT ParseVoltageDescr(PUCHAR pVolt, PPOWER_DESCR pDescr)
{
    if(pVolt == NULL || pDescr == NULL)
        return 0;
        
    UINT Length;
    UINT Mask;
    UINT i;
    PUSHORT pDVolt;

    Length = 1;
    Mask = pDescr->ValidMask = (UINT)*pVolt;
    pVolt++;
    pDVolt = &(pDescr->NominalV);

    while (Mask) {
        if (Mask & 1) {
            i = ConvertVoltage(pVolt, pDVolt);
            Length += i;
            pVolt += i;
        } else {
            *pDVolt = 0;
        }
        pDVolt++;
        Mask >>= 1;
    }

    return Length;
}   // ParseVoltageDescr

⌨️ 快捷键说明

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