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

📄 i80312pcilib.c

📁 VXWORKS BSP开发包,初始化 驱动文件
💻 C
📖 第 1 页 / 共 4 页
字号:
* i80312PciAbortsClear - clear primary or secondary PCI aborts** This routine clears the abort status bits either in the primary* or in the secondary.* * RETURNS : OK, or ERROR.**/LOCAL STATUS i80312PciAbortsClear    (    int brNum    )    {    UINT32 atuPriStat;    UINT32 atuSecStat;    UINT16 atuStat;    volatile ATU_CFG_SPACE * pAtuCfg = (ATU_CFG_SPACE *)I80312_ATU_CFG_BASE;    STATUS   rtnStatus = OK;    if (brNum == i80312_BusNumbers[PRIMARY_BUS_INDEX])        {        if ( (atuStat = *BRIDGE_PSR) & MASTER_ABORT)            {            *BRIDGE_PSR = MASTER_ABORT;            rtnStatus = ERROR;            }        if ( (atuStat = *ATU_PATUSR) & MASTER_ABORT)            {            *ATU_PATUSR = MASTER_ABORT;            rtnStatus = ERROR;            }        atuPriStat = *ATU_PATUISR;        if (atuPriStat &            (I80312_BRIDGE_TARGET_ABORT | I80312_BRIDGE_MASTER_TARGET_ABORT |              I80312_BRIDGE_MASTER_ABORT))            {            if (atuPriStat & I80312_BRIDGE_TARGET_ABORT)                {                *ATU_PATUISR |= I80312_BRIDGE_TARGET_ABORT;                pAtuCfg->ATU_PrimaryStatus |= TARGET_ABORT;                }            if (atuPriStat & I80312_BRIDGE_MASTER_TARGET_ABORT)                {                *ATU_PATUISR |= I80312_BRIDGE_MASTER_TARGET_ABORT;                pAtuCfg->ATU_PrimaryStatus |= MASTER_TARGET_ABORT;                }            if (atuPriStat & I80312_BRIDGE_MASTER_ABORT)                {                *ATU_PATUISR |= I80312_BRIDGE_MASTER_ABORT;                pAtuCfg->ATU_PrimaryStatus |= MASTER_ABORT;                }            rtnStatus = ERROR;            }        }    else if (brNum == i80312_BusNumbers[SECONDARY_BUS_INDEX])        {        if ( (atuStat = *BRIDGE_SSR) & MASTER_ABORT)            {            *BRIDGE_SSR = MASTER_ABORT;            rtnStatus = ERROR;            }        if ( (atuStat = *ATU_SATUSR) & MASTER_ABORT)            {            *ATU_SATUSR = MASTER_ABORT;            rtnStatus = ERROR;            }        atuSecStat = *ATU_SATUISR;        if (atuSecStat &            (I80312_BRIDGE_TARGET_ABORT | I80312_BRIDGE_MASTER_TARGET_ABORT |              I80312_BRIDGE_MASTER_ABORT))            {            if (atuSecStat & I80312_BRIDGE_TARGET_ABORT)                *ATU_SATUISR |= I80312_BRIDGE_TARGET_ABORT;            if (atuSecStat & I80312_BRIDGE_MASTER_TARGET_ABORT)                *ATU_SATUISR |= I80312_BRIDGE_MASTER_TARGET_ABORT;            if (atuSecStat & I80312_BRIDGE_MASTER_ABORT)                *ATU_SATUISR |= I80312_BRIDGE_MASTER_ABORT;            rtnStatus = ERROR;            }        }    return(rtnStatus);    }/************************************************************************** i80312PciCfgWr - perform a configuration write* * This routine performs a configuration write using the primary or secondary * Address Translation Unit (ATU).** RETURNS: OK, or ERROR if the transaction fails.** SEE ALSO: i80312PciCfgRd()*/STATUS i80312PciCfgWr    (    int			brNum,   /* Primary or Secondary */    PCI_CFG_ADDR	cfgAddr, /* configuration address command format */    UINT32		val      /* value writes to   */     )    {    volatile UINT32 idsel;    int indexNum;    int lockKey,status;    int lowTwobits = cfgAddr.u.bit.regPos;    int len = cfgAddr.u.bit.regLen;    indexNum = (brNum >= i80312_BusNumbers[SECONDARY_BUS_INDEX])?1:0;    /* highest possible number for RP */    if (cfgAddr.u.bit.devNum > I80312_PCI_DEVICE_MAX_NUM)        return(ERROR);    /* form either configuration type 0 or type 1 command */    if ( cfgAddr.u.bit.cfgType == PCI_CFG_TYP1)         idsel = cfgAddr.u.whole & 0x0fffffff; /* mask off reserved area */    else         {               /* save pertinent part of the address */        idsel = (cfgAddr.u.whole & 0x000007ff);        /* add device number to ID select */        idsel |= (1 << (cfgAddr.u.bit.devNum + 11));        }    lockKey = intLock();    /* write cfg space data */    if (len == PCI_BYTE_ACCESS)        {        *(i80312CfgRegs[indexNum].addrReg) = idsel;        *(volatile char *)(i80312CfgRegs[indexNum].dataReg + lowTwobits) = (char)val;        }    else if (len == PCI_UINT16_ACCESS)        {        *(i80312CfgRegs[indexNum].addrReg) = idsel;        *(volatile UINT16 *)(i80312CfgRegs[indexNum].dataReg+lowTwobits) = (UINT16)val;        }    else        {        *(i80312CfgRegs[indexNum].addrReg) = idsel;        *(volatile UINT32 *)(i80312CfgRegs[indexNum].dataReg) = val;        }    status = i80312PciAbortsClear(brNum);    intUnlock(lockKey);    return(status);    }/********************************************************************* i80312PciCfgRd - perform a configuration read ** This routine performs a configuration read using the primary or secondary * Address Translation Unit (ATU).** RETURNS: OK, or ERROR if the transaction fails.** SEE ALSO: i80312PciCfgWr()*/STATUS i80312PciCfgRd    (    int	         brNum,       PCI_CFG_ADDR cfgAddr, /* configuration address command format */    UINT32*      pVal     /* store data read, must be a 32-bit pointer */    )    {    volatile UINT32 data = 0xffffffff;    int indexNum;    int lockKey;    int lowTwobits = cfgAddr.u.bit.regPos;    int len = cfgAddr.u.bit.regLen;    char * atu0ccdr;    volatile UINT32 idsel;    int status = ERROR;    indexNum = (brNum >= i80312_BusNumbers[SECONDARY_BUS_INDEX])?1:0;    /* highest possible number for RP */    if (cfgAddr.u.bit.devNum > I80312_PCI_DEVICE_MAX_NUM)    return(ERROR);    /* form either configuration type 0 or type 1 command */    if ( cfgAddr.u.bit.cfgType == PCI_CFG_TYP1)         {    /* form configuration type 1 command */        idsel = cfgAddr.u.whole & 0x0ffffff; /* mask off reserved area */        }    else        {        /* form configuration type 0 command */        idsel = (cfgAddr.u.whole & 0x000007ff);        /* add device number to ID select */        idsel |= (1 << (cfgAddr.u.bit.devNum + 11));        }    /* Select Register Address to read data from */    if (len == PCI_BYTE_ACCESS || len == PCI_UINT16_ACCESS)    {        atu0ccdr = (char *)(i80312CfgRegs[indexNum].dataReg + lowTwobits);    }    else     {        atu0ccdr = (char *)(i80312CfgRegs[indexNum].dataReg);    }    /* have the exclusive access */    lockKey = intLock ();    /* Select config space addr to read. */    *(i80312CfgRegs[indexNum].addrReg) = idsel;    /*       Coyanosa generates Data Aborts when non-responding addresses       are read, so we must use MemProbe for PCI config space reads.    */     status = vxMemProbe (atu0ccdr, VX_READ, len, (char *)&data);    /* release the exclusive access */    intUnlock (lockKey);    if (data == 0xffffffff)        status = ERROR;    if (status != ERROR)        {        switch(len)            {            case PCI_BYTE_ACCESS:                *pVal = data & 0xff;  /* writes to return field */                break;            case PCI_UINT16_ACCESS:                *pVal = data & 0xffff;  /* writes to return field */                break;            default:                *pVal = data;  /* writes to return field */                break;            }        }    else        *pVal = 0xffffffff;    status = i80312PciAbortsClear(brNum);    return(status);    }/*************************************************************************** i80312PciFindDevice - find a PCI device by vendor and device ID** This routine finds a device on the PCI bus based on its vendor ID* (<vendorId>) and device ID (<deviceId>). The index number (<index>)* indicates the instance of the specified board: 0 meaning the first board,* 1 meaning the second, etc.** RETURNS: OK, or ERROR if no device is found.*/STATUS i80312PciFindDevice    (    int    vendorId,	/* vendor ID */    int    deviceId,	/* device ID */    int    index,	/* desired instance of device */    UINT32 *  pBusNo,	/* bus number */    UINT32 *  pDeviceNo,	/* device number */    UINT32 *  pFuncNo	/* function number */    )    {    int busNo, ebusNo;    int deviceNo;    int funcNo, configType;    UINT32 device;    UINT32 vendor;    int maxFuncNum;    PCI_CFG_ADDR cfgAddr;    UINT8 rotary = I80310_ROT_STAT_REG_RD();    if (rotary != 0x7)           /* rotary switch NOT in position 7 - stand-alone backplane */        {         /* Start with the Primary Bus */         busNo = i80312PciChkBusNumbers(i80312_BusNumbers[PRIMARY_BUS_INDEX]);         ebusNo = busNo + 2;        }    else        {         /* Start with the Secondary Bus */         busNo = i80312PciChkBusNumbers(i80312_BusNumbers[SECONDARY_BUS_INDEX]);         ebusNo = busNo + 1;        }    for(; busNo <= ebusNo; busNo++)        {        if(busNo <= i80312_BusNumbers[SECONDARY_BUS_INDEX])            configType = PCI_CFG_TYP0;        else            configType = PCI_CFG_TYP1;            for (deviceNo=0; deviceNo < 0x1f; deviceNo++)            {            cfgAddr.u.whole=CONFIG_WORD_PACK (configType,PCI_CFG_HEADER_TYPE,0,deviceNo,                                              busNo,PCI_BYTE_ACCESS);                maxFuncNum = i80312PciDeviceProbe (busNo,cfgAddr);                for (funcNo=0; funcNo < maxFuncNum; funcNo++)                {                /* device found, set up PCI configuration address info */                 cfgAddr.u.whole = CONFIG_WORD_PACK(configType,                        PCI_CFG_VENDOR_ID,funcNo,deviceNo,busNo,PCI_UINT16_ACCESS);                    /* find out the vendor id */                if (i80312PciCfgRd((int)busNo,cfgAddr,(UINT32 *)&vendor) != OK)    		    break;                    cfgAddr.u.whole = CONFIG_WORD_PACK(configType,                        PCI_CFG_DEVICE_ID, funcNo,deviceNo,busNo,PCI_UINT16_ACCESS);                    /* find out the the device id */                i80312PciCfgRd((int)busNo,cfgAddr, (UINT32 *)&device);                    if ((vendor == vendorId) &&                    (device == deviceId) &&                    (index-- == 0))                    {                    *pBusNo = busNo;                    *pDeviceNo = deviceNo;                    *pFuncNo = funcNo;                    return (OK);                        }                }            }        }    return (ERROR);    }/****************************************************************************** i80312PciDeviceProbe - check if the device is in a PCI slot** This routine checks if there is a device in the specified PCI slot.* It returns one of the following macros:* .IP "NO_DEVICE (0)" 24* device not found* .IP "FUNC0_DEVICE (1)" 24* single-function device found* .IP "MULTI_FUNC_DEVICE" 24* multiple-function device found with a maximum of eight functions* .LP** RETURNS: The possible number of functions for this board.*/int i80312PciDeviceProbe    (    int busMaster,       /* which PCI interface Primary or Secondary */    PCI_CFG_ADDR cfgAddr /* configuration address word               */    )    {    UINT32 type;    int status;    /* read it */    status = i80312PciCfgRd(busMaster, cfgAddr, (UINT32 *)&type);		     if (status != OK || type == 0xffffffff)    return (NO_DEVICE);   /* no device found */    if (!(type & PCI_MULTI_FUNCTION) )    return (FUNC0_DEVICE);   /* single function device found */    /*  multifunction device */    return (MULTI_FUNC_DEVICE);     /* assume maximum 8 functions for now */    }/*************************************************************************** pciBusScan - scan for a device on a PCI bus * * This routine scans both the primary and secondary PCI buses on the* I80312 in search of any device.  It prints out the device ID * and vendor ID for any device is found.

⌨️ 快捷键说明

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