📄 apifunctions.c
字号:
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 + -