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

📄 apifunctions.c

📁 本压缩包为作者截取的PCI9054的WDM官方驱动源码。欢迎下载。
💻 C
📖 第 1 页 / 共 5 页
字号:
    BOOLEAN          *pFlag
    )
{
    U32 RegisterValue;


    // Get EEPROM status register
    RegisterValue =
        PLX_REG_READ(
            pdx,
            PCI9054_EEPROM_CTRL_STAT
            );

    if (RegisterValue & (1 << 28))
    {
        *pFlag = TRUE;
    }
    else
    {
        *pFlag = FALSE;
    }

    return ApiSuccess;
}




/******************************************************************************
 *
 * Function   :  PlxEepromReadByOffset
 *
 * Description:  Read a value from the EEPROM at a specified offset
 *
 ******************************************************************************/
RETURN_CODE
PlxEepromReadByOffset(
    DEVICE_EXTENSION *pdx,
    U16               offset,
    U32              *pValue
    )
{
    U32         RegValue;
    BOOLEAN     bUseVpd;
    RETURN_CODE rc;


    // Verify the offset
    if ((offset & 0x3) || (offset > 0x200))
    {
        DebugPrintf(("ERROR - Invalid EEPROM offset\n"));
        return ApiInvalidOffset;
    }

    /****************************************************************
     * Note:  In the 9054, the EEPROM can be accessed either
     *        through the VPD or by the EEPROM control register.
     *
     *        However, the EEPROM control register does not work
     *        in the 9054 AA version and VPD access often fails.
     *        The 9054 AB version fixes the EEPROM control register
     *        access, but VPD may still fail.
     *
     *        As a result, PLX software does the following:
     *
     *          if (AB or newer chip)
     *              Use EEPROM Control Register
     *          else
     *              Use VPD access
     *
     *        Additionally, there is no way to determine the 9054
     *        version from the Host/PCI side.  To solve this, the
     *        PCI Revision ID is used to "tell" the host which
     *        version the 9054 is.  This value is either set by the
     *        EEPROM or the local CPU, which has the ability to
     *        determine the 9054 version.  The protocol is:
     *
     *          if (Hard-coded RevisionID != 0xA)  // Chip is not AA or AB
     *              Use EEPROM Control Register
     *          else
     *          {
     *              if (PCIRevisionID == 0xb)
     *                  Use EEPROM Control Register
     *              else
     *                  Use VPD access
     *          }
     ***************************************************************/

    // Default to VPD access
    bUseVpd = TRUE;

    // Get hard-coded revision ID
    RegValue =
        PLX_REG_READ(
            pdx,
            PCI9054_REVISION_ID
            );

    // Check if chip is other than AA or AB
    if (RegValue != 0xA)
    {
        bUseVpd = FALSE;
    }
    else
    {
        // Get PCI Revision ID
        PLX_PCI_REG_READ(
            pdx,
            PCI9054_REV_ID,
            &RegValue
            );

        // Check reported 9054 Version
        if ((RegValue & 0xFF) == 0xB)
        {
            // 9054 AB version is reported
            bUseVpd = FALSE;
        }
    }

    // Access the EEPROM
    if (bUseVpd == FALSE)
    {
        // 9054 AB or newer revision, so use EEPROM register

        // Read EEPROM
        Pci9000_EepromReadByOffset(
            pdx,
            Eeprom93CS56,
            offset,
            pValue
            );
    }
    else
    {
        // 9054 AA or unspecified version, so use VPD access

        // Check if New capabilities are enabled
        if (PlxIsNewCapabilityEnabled(
                pdx,
                CAPABILITY_VPD
                ) == FALSE)
        {
            return ApiVpdNotEnabled;
        }

        // Read EEPROM value
        rc =
            PlxPciVpdRead(
                pdx,
                offset,
                pValue
                );

        if (rc != ApiSuccess)
            return ApiFailed;
    }

    DebugPrintf((
        "EEPROM Offset %02X = %08X\n",
        offset,
        *pValue
        ));

    return ApiSuccess;
}




/******************************************************************************
 *
 * Function   :  PlxEepromWriteByOffset
 *
 * Description:  Write a 32-bit value to the EEPROM at a specified offset
 *
 ******************************************************************************/
RETURN_CODE
PlxEepromWriteByOffset(
    DEVICE_EXTENSION *pdx,
    U16               offset,
    U32               value
    )
{
    U32         RegValue;
    U32         RegisterSave;
    BOOLEAN     bUseVpd;
    RETURN_CODE rc;


    // Verify the offset
    if ((offset & 0x3) || (offset > 0x200))
    {
        DebugPrintf(("ERROR - Invalid EEPROM offset\n"));
        return ApiInvalidOffset;
    }

    // Unprotect the EEPROM for write access
    RegisterSave =
        PLX_REG_READ(
            pdx,
            PCI9054_ENDIAN_DESC
            );

    PLX_REG_WRITE(
        pdx,
        PCI9054_ENDIAN_DESC,
        RegisterSave & ~(0xFF << 16)
        );

    /****************************************************************
     * Note:  In the 9054, the EEPROM can be accessed either
     *        through the VPD or by the EEPROM control register.
     *
     *        However, the EEPROM control register does not work
     *        in the 9054 AA version and VPD access often fails.
     *        The 9054 AB version fixes the EEPROM control register
     *        access, but VPD may still fail.
     *
     *        As a result, PLX software does the following:
     *
     *          if (AB or newer chip)
     *              Use EEPROM Control Register
     *          else
     *              Use VPD access
     *
     *        Additionally, there is no way to determine the 9054
     *        version from the Host/PCI side.  To solve this, the
     *        PCI Revision ID is used to "tell" the host which
     *        version the 9054 is.  This value is either set by the
     *        EEPROM or the local CPU, which has the ability to
     *        determine the 9054 version.  The protocol is:
     *
     *          if (Hard-coded RevisionID != 0xA)  // Chip is not AA or AB
     *              Use EEPROM Control Register
     *          else
     *          {
     *              if (PCIRevisionID == 0xb)
     *                  Use EEPROM Control Register
     *              else
     *                  Use VPD access
     *          }
     ***************************************************************/

    // Default to VPD access
    bUseVpd = TRUE;

    // Get hard-coded revision ID
    RegValue =
        PLX_REG_READ(
            pdx,
            PCI9054_REVISION_ID
            );

    // Check if chip is other than AA or AB
    if (RegValue != 0xA)
    {
        bUseVpd = FALSE;
    }
    else
    {
        // Get PCI Revision ID
        PLX_PCI_REG_READ(
            pdx,
            PCI9054_REV_ID,
            &RegValue
            );

        // Check reported 9054 Version
        if ((RegValue & 0xFF) == 0xB)
        {
            // 9054 AB version is reported
            bUseVpd = FALSE;
        }
    }

    // Access the EEPROM
    if (bUseVpd == FALSE)
    {
        // 9054 AB or newer revision, so use EEPROM register

        // Write to EEPROM
        Pci9000_EepromWriteByOffset(
            pdx,
            Eeprom93CS56,
            offset,
            value
            );
    }
    else
    {
        // 9054 AA or unspecified version, so use VPD access

        // Check if New capabilities are enabled
        if (PlxIsNewCapabilityEnabled(
                pdx,
                CAPABILITY_VPD
                ) == FALSE)
        {
            return ApiVpdNotEnabled;
        }

        // Write value to the EEPROM
        rc =
            PlxPciVpdWrite(
                pdx,
                offset,
                value
                );

        if (rc != ApiSuccess)
        {
            // Restore EEPROM Write-Protected Address Boundary
            PLX_REG_WRITE(
                pdx,
                PCI9054_ENDIAN_DESC,
                RegisterSave
                );

            return ApiFailed;
        }
    }

    // Restore EEPROM Write-Protected Address Boundary
    PLX_REG_WRITE(
        pdx,
        PCI9054_ENDIAN_DESC,
        RegisterSave
        );

    DebugPrintf((
        "Wrote %08X to EEPROM Offset %02X\n",
        value,
        offset
        ));

    return ApiSuccess;
}




/******************************************************************************
 *
 * Function   :  PlxRegisterMailboxRead
 *
 * Description:  Reads a valid Mailbox register from the PLX device
 *
 ******************************************************************************/
RETURN_CODE
PlxRegisterMailboxRead(
    DEVICE_EXTENSION *pdx,
    MAILBOX_ID        MailboxId,
    U32              *pValue
    )
{
    // Verify Mailbox ID
    if (MailboxId < MailBox0 || MailboxId > MailBox7)
    {
        *pValue = (U32)-1;
        return ApiInvalidRegister;
    }

    // Check if Mailbox 0 or 1
    if (MailboxId == MailBox0 || MailboxId == MailBox1)
    {
        *pValue =
            PLX_REG_READ(
                pdx,
                PCI9054_MAILBOX0 + (MailboxId * sizeof(U32))
                );
    }
    else
    {
        // Mailboxes 2 to 7 are not based from Malibox 0
        *pValue =
            PLX_REG_READ(
                pdx,
                PCI9054_MAILBOX2 + ((MailboxId-2) * sizeof(U32))
                );
    }

    return ApiSuccess;
}




/******************************************************************************
 *
 * Function   :  PlxRegisterMailboxWrite
 *
 * Description:  Write to one of the PLX device's Mailbox registers
 *
 ******************************************************************************/
RETURN_CODE
PlxRegisterMailboxWrite(
    DEVICE_EXTENSION *pdx,
    MAILBOX_ID        MailboxId,
    U32               value
    )
{
    // Verify Mailbox ID
    if (MailboxId < MailBox0 || MailboxId > MailBox7)
    {
        return ApiInvalidRegister;
    }

    if (MailboxId == MailBox0 || MailboxId == MailBox1)
    {
        PLX_REG_WRITE(
            pdx,
            PCI9054_MAILBOX0 + (MailboxId * sizeof(U32)),
            value
            );
    }
    else
    {
        PLX_REG_WRITE(
            pdx,
            PCI9054_MAILBOX2 + ((MailboxId-2) * sizeof(U32)),
            value
            );
    }

    return ApiSuccess;
}




/******************************************************************************
 *
 * Function   :  PlxRegisterDoorbellRead
 *
 * Description:  Returns the last doorbell interrupt value
 *
 ******************************************************************************/
RETURN_CODE
PlxRegisterDoorbellRead(
    DEVICE_EXTENSION *pdx,
    U32              *pValue
    )
{
    *pValue = pdx->IntrDoorbellValue;

    return ApiSuccess;
}




/******************************************************************************
 *
 * Function   :  PlxRegisterDoorbellWrite
 *
 * Description:  Sets the local Doorbell Register
 *
 ******************************************************************************/
RETURN_CODE
PlxRegisterDoorbellWrite(
    DEVICE_EXTENSION *pdx,
    U32               value
    )
{
    PLX_REG_WRITE(
        pdx,
        PCI9054_LOCAL_DOORBELL,
        value
        );

    return ApiSuccess;
}




/******************************************************************************
 *
 * Function   :  PlxMuInboundPortRead
 *
 * Description:  Read the Inbound messaging port of a PLX device
 *
 ******************************************************************************/
RETURN_CODE
PlxMuInboundPortRead(
    DEVICE_EXTENSION *pdx,
    U32              *pFrame
    )
{
    *pFrame =
        PLX_REG_READ(
            pdx,
            0x40
            );

    return ApiSuccess;
}




/******************************************************************************
 *
 * Function   :  PlxMuInboundPortWrite
 *
 * Description:  Write a posted message frame to the inbound port
 *
 ******************************************************************************/
RETURN_CODE
PlxMuInboundPortWrite(
    DEVICE_EXTENSION *pdx,
    U32               Frame
    )
{
    PLX_REG_WRITE(
        pdx,
        0x40,
        Frame
        );

    return ApiSuccess;
}




/******************************************************************************
 *
 * Function   :  PlxMuOutboundPortRead
 *
 * Description:  Reads the posted message frame from the outbound port
 *
 ******************************************************************************/
RETURN_CODE
PlxMuOutboundPortRead(
    DEVICE_EXTENSION *pdx,
    U32              *pFrame
    )
{
    *pFrame =
        PLX_REG_READ(
            pdx,
            0x44
            );

    return ApiSuccess;

⌨️ 快捷键说明

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