/* * 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; iPinInfo[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); }