301 lines
7.6 KiB
C
301 lines
7.6 KiB
C
|
/*
|
||
|
* OptiFireStar.C - OPTI FIRESTAR PCI chipset routines.
|
||
|
*
|
||
|
* Notes:
|
||
|
* Algorithms from OPTI FIRESTAR Data Sheet
|
||
|
* Opti contact: William@unixgate.opti.com
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include "local.h"
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* OptiFireStarSetIRQ - Set a OPTI FIRESTAR PCI link to a specific IRQ
|
||
|
*
|
||
|
* Exported.
|
||
|
*
|
||
|
* ENTRY: bIRQNumber is the new IRQ to be used.
|
||
|
*
|
||
|
* bLink is the Link to be set.
|
||
|
*
|
||
|
* EXIT: Standard PCIMP return value.
|
||
|
*
|
||
|
***************************************************************************/
|
||
|
PCIMPRET CDECL
|
||
|
OptiFireStarSetIRQ(UCHAR bIRQNumber, UCHAR bLink)
|
||
|
{
|
||
|
UCHAR bData, bOffset;
|
||
|
|
||
|
switch (bLink & 0x07)
|
||
|
{
|
||
|
case 0:
|
||
|
|
||
|
if (bLink == 0)
|
||
|
return (PCIMP_FAILURE);
|
||
|
else
|
||
|
return (PCIMP_INVALID_LINK);
|
||
|
case 1:
|
||
|
|
||
|
//
|
||
|
// FireStar IRQ
|
||
|
//
|
||
|
bLink = (UCHAR)((bLink & 0x70) >> 4);
|
||
|
bData = ReadConfigUchar(bBusPIC, bDevFuncPIC, (UCHAR)(0xB0 + bLink));
|
||
|
bData = (bData & 0xf0) | bIRQNumber;
|
||
|
if (bIRQNumber)
|
||
|
bData |= 0x10;
|
||
|
WriteConfigUchar(bBusPIC, bDevFuncPIC, (UCHAR)(0xB0 + bLink), bData);
|
||
|
|
||
|
return (PCIMP_SUCCESS);
|
||
|
|
||
|
case 2:
|
||
|
|
||
|
//
|
||
|
// FireStar PIO or Serial IRQ
|
||
|
//
|
||
|
case 3:
|
||
|
|
||
|
//
|
||
|
// FireBridge INTs
|
||
|
//
|
||
|
bOffset = (UCHAR)((bLink >> 5) & 1) + 0xB8;
|
||
|
bData = ReadConfigUchar(bBusPIC, bDevFuncPIC, bOffset);
|
||
|
if (bLink & (1<<4)) {
|
||
|
bData &= 0x0f;
|
||
|
bData |= (bIRQNumber<<4);
|
||
|
}
|
||
|
else {
|
||
|
bData &= 0xf0;
|
||
|
bData |= bIRQNumber;
|
||
|
}
|
||
|
WriteConfigUchar(bBusPIC, bDevFuncPIC, bOffset, bData);
|
||
|
|
||
|
return (PCIMP_SUCCESS);
|
||
|
|
||
|
default:
|
||
|
return (PCIMP_INVALID_LINK);
|
||
|
}
|
||
|
|
||
|
return (PCIMP_FAILURE);
|
||
|
}
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* OptiFireStarGetIRQ - Get the IRQ of a OPTI FIRESTAR PCI link
|
||
|
*
|
||
|
* Exported.
|
||
|
*
|
||
|
* ENTRY: pbIRQNumber is the buffer to fill.
|
||
|
*
|
||
|
* bLink is the Link to be read.
|
||
|
*
|
||
|
* EXIT: Standard PCIMP return value.
|
||
|
*
|
||
|
***************************************************************************/
|
||
|
PCIMPRET CDECL
|
||
|
OptiFireStarGetIRQ(PUCHAR pbIRQNumber, UCHAR bLink)
|
||
|
{
|
||
|
UCHAR bData, bOffset;
|
||
|
|
||
|
switch (bLink & 0x07)
|
||
|
{
|
||
|
case 0:
|
||
|
//
|
||
|
// Valid link?
|
||
|
//
|
||
|
if (bLink == 0)
|
||
|
return (PCIMP_FAILURE);
|
||
|
else
|
||
|
return (PCIMP_INVALID_LINK);
|
||
|
|
||
|
case 1:
|
||
|
//
|
||
|
// FireStar IRQ
|
||
|
//
|
||
|
bLink = (UCHAR)((bLink & 0x70) >> 4);
|
||
|
bData = ReadConfigUchar(bBusPIC, bDevFuncPIC, (UCHAR)(0xB0 + bLink));
|
||
|
*pbIRQNumber = (bData & 0x0f);
|
||
|
|
||
|
return (PCIMP_SUCCESS);
|
||
|
|
||
|
case 2:
|
||
|
//
|
||
|
// FireStar PIO or Serial IRQ
|
||
|
//
|
||
|
|
||
|
case 3:
|
||
|
//
|
||
|
// FireBridge INTs
|
||
|
//
|
||
|
bOffset = (UCHAR)((bLink >> 5) & 1) + 0xB8;
|
||
|
bData = ReadConfigUchar(bBusPIC, bDevFuncPIC, bOffset);
|
||
|
if (bLink & (1<<4))
|
||
|
bData >>= 4;
|
||
|
|
||
|
*pbIRQNumber = bData & 0x0f;
|
||
|
|
||
|
return (PCIMP_SUCCESS);
|
||
|
|
||
|
default:
|
||
|
return (PCIMP_INVALID_LINK);
|
||
|
}
|
||
|
|
||
|
return (PCIMP_FAILURE);
|
||
|
}
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* OptiViperSetTrigger - Set the IRQ triggering values for the OptiViper
|
||
|
*
|
||
|
* Exported.
|
||
|
*
|
||
|
* ENTRY: ulTrigger has bits set for Level triggered IRQs.
|
||
|
*
|
||
|
* EXIT: Standard PCIMP return value.
|
||
|
*
|
||
|
***************************************************************************/
|
||
|
PCIMPRET CDECL
|
||
|
OptiFireStarSetTrigger(ULONG ulTrigger)
|
||
|
{
|
||
|
ULONG i;
|
||
|
UCHAR bData;
|
||
|
|
||
|
for (i = 0; i < 8; i++)
|
||
|
{
|
||
|
UCHAR bTemp;
|
||
|
bData = ReadConfigUchar(bBusPIC, bDevFuncPIC, (UCHAR)(0xB0+i));
|
||
|
bTemp = bData & 0x0F;
|
||
|
if (bTemp && (ulTrigger & (1 << bTemp)))
|
||
|
{
|
||
|
bData |= 0x10;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bData &= ~0x10;
|
||
|
}
|
||
|
WriteConfigUchar(bBusPIC, bDevFuncPIC, (UCHAR)(0xB0+i), bData);
|
||
|
}
|
||
|
|
||
|
return (PCIMP_SUCCESS);
|
||
|
}
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* OptiViperGetTrigger - Get the IRQ triggering values for the OptiViper
|
||
|
*
|
||
|
* Exported.
|
||
|
*
|
||
|
* ENTRY: pulTrigger will have bits set for Level triggered IRQs.
|
||
|
*
|
||
|
* EXIT: Standard PCIMP return value.
|
||
|
*
|
||
|
***************************************************************************/
|
||
|
PCIMPRET CDECL
|
||
|
OptiFireStarGetTrigger(PULONG pulTrigger)
|
||
|
{
|
||
|
ULONG i;
|
||
|
UCHAR bData;
|
||
|
|
||
|
//
|
||
|
// Assume all are edge.
|
||
|
//
|
||
|
*pulTrigger = 0;
|
||
|
|
||
|
//
|
||
|
// Check PCIDV1 registers B0-B7.
|
||
|
//
|
||
|
for (i = 0; i < 8; i++)
|
||
|
{
|
||
|
bData = (UCHAR)(ReadConfigUchar(bBusPIC, bDevFuncPIC, (UCHAR)(0xB0 + i)) & 0x1F);
|
||
|
if (bData & 0x10)
|
||
|
*pulTrigger |= (1 << (bData & 0x0f));
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Check PCIDV1 registers B8-B9.
|
||
|
//
|
||
|
for (i = 0; i < 2; i++)
|
||
|
{
|
||
|
bData = ReadConfigUchar(bBusPIC, bDevFuncPIC, (UCHAR)(0xB8 + i));
|
||
|
*pulTrigger |= (1 << (bData & 0x0F));
|
||
|
bData >>= 4;
|
||
|
*pulTrigger |= (1 << (bData & 0x0F));
|
||
|
}
|
||
|
|
||
|
return (PCIMP_SUCCESS);
|
||
|
}
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* OptiFireStarValidateTable - Validate an IRQ table
|
||
|
*
|
||
|
* Exported.
|
||
|
*
|
||
|
* ENTRY: piihIRQInfoHeader points to an IRQInfoHeader followed
|
||
|
* by an IRQ Routing Table.
|
||
|
*
|
||
|
* ulFlags are PCIMP_VALIDATE flags.
|
||
|
*
|
||
|
* EXIT: Standard PCIMP return value.
|
||
|
*
|
||
|
***************************************************************************/
|
||
|
#ifdef ALLOC_PRAGMA
|
||
|
PCIMPRET CDECL
|
||
|
OptiFireStarValidateTable(PIRQINFOHEADER piihIRQInfoHeader, ULONG ulFlags);
|
||
|
#pragma alloc_text(PAGE, OptiFireStarValidateTable)
|
||
|
#endif //ALLOC_PRAGMA
|
||
|
|
||
|
PCIMPRET CDECL
|
||
|
OptiFireStarValidateTable(PIRQINFOHEADER piihIRQInfoHeader, ULONG ulFlags)
|
||
|
{
|
||
|
PIRQINFO pii=(PIRQINFO)(((PUCHAR) piihIRQInfoHeader)+sizeof(IRQINFOHEADER));
|
||
|
ULONG i, j;
|
||
|
ULONG cEntries=(piihIRQInfoHeader->TableSize-sizeof(IRQINFOHEADER))/sizeof(IRQINFO);
|
||
|
|
||
|
PAGED_CODE();
|
||
|
|
||
|
for (i=0; i<cEntries; i++) {
|
||
|
|
||
|
for (j=0; j<4; j++) {
|
||
|
|
||
|
switch (pii->PinInfo[j].Link & 0x07)
|
||
|
{
|
||
|
case 0:
|
||
|
//
|
||
|
// Valid link?
|
||
|
//
|
||
|
if (pii->PinInfo[j].Link & 0x70)
|
||
|
return (PCIMP_FAILURE);
|
||
|
break;
|
||
|
|
||
|
case 1:
|
||
|
//
|
||
|
// FireStar IRQ
|
||
|
//
|
||
|
break;
|
||
|
|
||
|
case 2:
|
||
|
//
|
||
|
// FireStar PIO or Serial IRQ
|
||
|
//
|
||
|
|
||
|
case 3:
|
||
|
//
|
||
|
// FireBridge INTs
|
||
|
//
|
||
|
if ((pii->PinInfo[j].Link & 0x70) > 0x30)
|
||
|
return (PCIMP_FAILURE);
|
||
|
break;
|
||
|
default:
|
||
|
|
||
|
return (PCIMP_FAILURE);
|
||
|
}
|
||
|
}
|
||
|
pii++;
|
||
|
}
|
||
|
|
||
|
return(i? PCIMP_SUCCESS : PCIMP_FAILURE);
|
||
|
}
|
||
|
|