windows-nt/Source/XPSP1/NT/base/hals/pciirqmp/i386/pciirqmp.c
2020-09-26 16:20:57 +08:00

550 lines
12 KiB
C

/*++
Copyright (c) 1990-1998 Microsoft Corporation
Module Name:
pciirqmp.c
Abstract:
This is the PCI IRQ Miniport library.
Author:
Santosh Jodh (santoshj) 09-June-1998
Environment:
kernel mode only
Revision History:
--*/
#include "local.h"
//
// Macro to declare a table of function pointers for the chipset
// module.
//
#define DECLARE_CHIPSET(x) \
{ DECLARE_MINIPORT_FUNCTION(x, ValidateTable), \
DECLARE_MINIPORT_FUNCTION(x, GetIRQ), \
DECLARE_MINIPORT_FUNCTION(x, SetIRQ), \
DECLARE_MINIPORT_FUNCTION(x, GetTrigger), \
DECLARE_MINIPORT_FUNCTION(x, SetTrigger) \
}
//
// Macro to declare a table of function pointers for EISA
// compatible chipset module.
//
#define DECLARE_EISA_CHIPSET(x) \
{ DECLARE_MINIPORT_FUNCTION(x, ValidateTable), \
DECLARE_MINIPORT_FUNCTION(x, GetIRQ), \
DECLARE_MINIPORT_FUNCTION(x, SetIRQ), \
EisaGetTrigger, \
EisaSetTrigger \
}
//
// Macro to declare the functions to be provided by the chipset
// module.
//
#define DECLARE_IRQ_MINIPORT(x) \
NTSTATUS \
DECLARE_MINIPORT_FUNCTION(x, ValidateTable) ( \
IN PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable, \
IN ULONG Flags \
); \
NTSTATUS \
DECLARE_MINIPORT_FUNCTION(x, GetIRQ) ( \
OUT PUCHAR Irq, \
IN UCHAR Link \
); \
NTSTATUS \
DECLARE_MINIPORT_FUNCTION( x, SetIRQ) ( \
IN UCHAR Irq, \
IN UCHAR Link \
); \
NTSTATUS \
DECLARE_MINIPORT_FUNCTION(x, GetTrigger) ( \
OUT PULONG Trigger \
); \
NTSTATUS \
DECLARE_MINIPORT_FUNCTION(x, SetTrigger) ( \
IN ULONG Trigger \
);
//
// Macro to declare the functions to be provided by the EISA
// compatible chipset.
//
#define DECLARE_EISA_IRQ_MINIPORT(x) \
NTSTATUS \
DECLARE_MINIPORT_FUNCTION(x, ValidateTable) ( \
IN PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable, \
IN ULONG Flags \
); \
NTSTATUS \
DECLARE_MINIPORT_FUNCTION(x, GetIRQ) ( \
OUT PUCHAR Irq, \
IN UCHAR Link \
); \
NTSTATUS \
DECLARE_MINIPORT_FUNCTION( x, SetIRQ) ( \
IN UCHAR Irq, \
IN UCHAR Link \
);
//
// Function prototypes for functions that every chipset module
// has to provide.
//
typedef
NTSTATUS
(*PIRQMINI_VALIDATE_TABLE) (
PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable,
ULONG Flags
);
typedef
NTSTATUS
(*PIRQMINI_GET_IRQ) (
OUT PUCHAR Irq,
IN UCHAR Link
);
typedef
NTSTATUS
(*PIRQMINI_SET_IRQ) (
IN UCHAR Irq,
IN UCHAR Link
);
typedef
NTSTATUS
(*PIRQMINI_GET_TRIGGER) (
OUT PULONG Trigger
);
typedef
NTSTATUS
(*PIRQMINI_SET_TRIGGER) (
IN ULONG Trigger
);
//
// Chipset specific data contains a table of function pointers
// to program the chipset.
//
typedef struct _CHIPSET_DATA {
PIRQMINI_VALIDATE_TABLE ValidateTable;
PIRQMINI_GET_IRQ GetIrq;
PIRQMINI_SET_IRQ SetIrq;
PIRQMINI_GET_TRIGGER GetTrigger;
PIRQMINI_SET_TRIGGER SetTrigger;
} CHIPSET_DATA, *PCHIPSET_DATA;
//
// Declare all miniports here.
//
DECLARE_EISA_IRQ_MINIPORT(Mercury)
DECLARE_EISA_IRQ_MINIPORT(Triton)
DECLARE_IRQ_MINIPORT(VLSI)
DECLARE_IRQ_MINIPORT(OptiViper)
DECLARE_EISA_IRQ_MINIPORT(SiS5503)
DECLARE_IRQ_MINIPORT(VLSIEagle)
DECLARE_EISA_IRQ_MINIPORT(M1523)
DECLARE_IRQ_MINIPORT(NS87560)
DECLARE_EISA_IRQ_MINIPORT(Compaq3)
DECLARE_EISA_IRQ_MINIPORT(M1533)
DECLARE_IRQ_MINIPORT(OptiFireStar)
DECLARE_EISA_IRQ_MINIPORT(VT586)
DECLARE_EISA_IRQ_MINIPORT(CPQOSB)
DECLARE_EISA_IRQ_MINIPORT(CPQ1000)
DECLARE_EISA_IRQ_MINIPORT(Cx5520)
DECLARE_IRQ_MINIPORT(Toshiba)
DECLARE_IRQ_MINIPORT(NEC)
DECLARE_IRQ_MINIPORT(VESUVIUS)
//
// Table of chipset drivers.
//
const CHIPSET_DATA rgChipData[] = {
DECLARE_EISA_CHIPSET(Mercury), // Intel 82374EB\SB (80860482)
DECLARE_EISA_CHIPSET(Triton), // Intel 82430FX (8086122E)
DECLARE_CHIPSET(VLSI), // VLSI VL82C596/7
DECLARE_CHIPSET(OptiViper), // OPTi Viper-M
DECLARE_EISA_CHIPSET(SiS5503), // SIS P54C
DECLARE_CHIPSET(VLSIEagle), // VLSI VL82C534
DECLARE_EISA_CHIPSET(M1523), // ALi M1523
DECLARE_CHIPSET(NS87560), // Nat Semi NS87560
DECLARE_EISA_CHIPSET(Compaq3), // Compaq MISC 3
DECLARE_EISA_CHIPSET(M1533), // ALi M1533
DECLARE_CHIPSET(OptiFireStar), // OPTI FIRESTAR
DECLARE_EISA_CHIPSET(VT586), // VIATECH 82C586B
DECLARE_EISA_CHIPSET(CPQOSB), // Conpaq OSB
DECLARE_EISA_CHIPSET(CPQ1000), // Conpaq 1000
DECLARE_EISA_CHIPSET(Cx5520), // Cyrix 5520
DECLARE_CHIPSET(Toshiba), // Toshiba
DECLARE_CHIPSET(NEC), // NEC PC9800
DECLARE_CHIPSET(VESUVIUS) //
};
#define NUMBER_OF_CHIPSETS (sizeof(rgChipData) / sizeof(CHIPSET_DATA))
//
// Global variables shared by all modules.
//
ULONG bBusPIC = -1;
ULONG bDevFuncPIC = -1;
CHIPSET_DATA const* rgChipSet = NULL;
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, PciirqmpInit)
#pragma alloc_text(PAGE, PciirqmpExit)
#pragma alloc_text(PAGE, PciirqmpValidateTable)
#endif //ALLOC_PRAGMA
NTSTATUS
PciirqmpInit (
ULONG Instance,
ULONG RouterBus,
ULONG RouterDevFunc
)
/*++
Routine Description:
This routine initializes calls the individual chipset handler
to validate the Pci Irq Routing Table.
Parameters:
PciIrqRoutingTable - Pci Irq Routing Table.
Flags - Flags specifying source of the Pci Irq Routing Table.
Return Value:
Standard Pci Irq Miniport return value.
Notes:
--*/
{
PAGED_CODE();
//
// Check to make sure that we are not already initialized.
//
if (rgChipSet != NULL)
{
PCIIRQMPPRINT(("IRQ miniport already initialized!"));
return (PCIIRQMP_STATUS_ALREADY_INITIALIZED);
}
//
// Check for invalid instance.
//
if (Instance >= NUMBER_OF_CHIPSETS)
{
PCIIRQMPPRINT(("Invalid IRQ miniport instance %08X", Instance));
return (PCIIRQMP_STATUS_INVALID_INSTANCE);
}
//
// Save our global data.
//
rgChipSet = &rgChipData[Instance];
bBusPIC = RouterBus;
bDevFuncPIC = RouterDevFunc;
return (PCIMP_SUCCESS);
}
NTSTATUS
PciirqmpExit (
VOID
)
/*++
Routine Description:
This routine cleans up after the Pci Irq Routing miniport library.
Parameters:
None.
Return Value:
Standard Pci Irq Miniport return value.
Notes:
--*/
{
PAGED_CODE();
//
// Were we ever initialized?
//
if (rgChipSet == NULL)
{
PCIIRQMPPRINT(("Cannot exit without having been initialized!"));
return (PCIIRQMP_STATUS_NOT_INITIALIZED);
}
//
// Clean up.
//
rgChipSet = NULL;
bBusPIC = -1;
bDevFuncPIC = -1;
return (PCIMP_SUCCESS);
}
NTSTATUS
PciirqmpValidateTable (
IN PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable,
IN ULONG Flags
)
/*++
Routine Description:
This routine normalizes calls the individual chipset handler
to validate the Pci Irq Routing Table.
Parameters:
PciIrqRoutingTable - Pci Irq Routing Table.
Flags - Flags specifying source of the Pci Irq Routing Table.
Return Value:
Standard Pci Irq Miniport return value.
Notes:
--*/
{
PAGED_CODE();
//
// Were we ever initialized?
//
if (rgChipSet == NULL)
{
PCIIRQMPPRINT(("Not initialized yet!"));
return (PCIIRQMP_STATUS_NOT_INITIALIZED);
}
//
// Call the chipset handler.
//
return (rgChipSet->ValidateTable(PciIrqRoutingTable, Flags));
}
NTSTATUS
PciirqmpGetIrq (
OUT PUCHAR Irq,
IN UCHAR Link
)
/*++
Routine Description:
This routine calls the individual chipset handler
to set the link to the specified Irq.
Parameters:
Irq - Variable that receives the Irq.
Link - Link to be read.
Return Value:
Standard Pci Irq Miniport return value.
Notes:
--*/
{
//
// Were we ever initialized?
//
if (rgChipSet == NULL)
{
PCIIRQMPPRINT(("Not initialized yet!"));
return (PCIIRQMP_STATUS_NOT_INITIALIZED);
}
//
// Call the chipset handler.
//
return (rgChipSet->GetIrq(Irq, Link));
}
NTSTATUS
PciirqmpSetIrq (
IN UCHAR Irq,
IN UCHAR Link
)
/*++
Routine Description:
This routine calls the individual chipset handler
to set the link to the specified Irq.
Parameters:
Irq - Irq to be set.
Link - Link to be programmed.
Return Value:
Standard Pci Irq Miniport return value.
Notes:
--*/
{
//
// Were we ever initialized?
//
if (rgChipSet == NULL)
{
PCIIRQMPPRINT(("Not initialized yet!"));
return (PCIIRQMP_STATUS_NOT_INITIALIZED);
}
//
// Call the chipset handler.
//
return (rgChipSet->SetIrq(Irq, Link));
}
NTSTATUS
PciirqmpGetTrigger (
OUT PULONG Trigger
)
/*++
Routine Description:
This routine calls the individual chipset handler
to get the interrupt edge\level mask.
Parameters:
Trigger - Variable that receives edge\level mask.
Return Value:
Standard Pci Irq Miniport return value.
Notes:
--*/
{
//
// Were we ever initialized?
//
if (rgChipSet == NULL)
{
PCIIRQMPPRINT(("Not initialized yet!"));
return (PCIIRQMP_STATUS_NOT_INITIALIZED);
}
//
// Call the chipset handler.
//
return (rgChipSet->GetTrigger(Trigger));
}
NTSTATUS
PciirqmpSetTrigger (
IN ULONG Trigger
)
/*++
Routine Description:
This routine calls the individual chipset handler
to set the interrupt edge\level mask.
Parameters:
Trigger - Edge\level mask to be set.
Return Value:
Standard Pci Irq Miniport return value.
Notes:
--*/
{
//
// Were we ever initialized?
//
if (rgChipSet == NULL)
{
PCIIRQMPPRINT(("Not initialized yet!"));
return (PCIIRQMP_STATUS_NOT_INITIALIZED);
}
//
// Call the chipset handler and return the result.
//
return (rgChipSet->SetTrigger(Trigger));
}