// ---------------------------------------------------------------------------- // Copyright (c) 1992 Olivetti // // File: eisaini.c // // Description: EISA initialization routines. // ---------------------------------------------------------------------------- // #include "fwp.h" #include "oli2msft.h" #include "arceisa.h" #include "inc.h" #include "string.h" #include "debug.h" #include "eisastr.h" //extern BL_DEVICE_ENTRY_TABLE OmfEntryTable[]; // NOTE: Not used in JAZZ. //extern ULONG ErrorWord; // POD error flags //extern ULONG FlagWord; // system flags extern ULONG MemorySize; // size of memory in Mb extern PCHAR MnemonicTable[]; extern ULONG EisaPoolSize; // # bytes really used extern ULONG EisaDynMemSize; // dynamic memory size (bytes) extern ULONG EisaFreeTop; // top of free mem extern ULONG EisaFreeBytes; // free bytes left // remove the following function prototypes when using common code PFW_MD GetFwMd ( VOID ); PFW_MD LinkPhysFwMd ( PFW_MD * pFwMdBase, PFW_MD pFwMd ); // ---------------------------------------------------------------------------- // Declare Function Prototypes // ---------------------------------------------------------------------------- VOID EisaIni ( VOID ); VOID EisaGeneralIni ( VOID ); BOOLEAN EisaBusStructIni ( IN ULONG BusNumber ); BOOLEAN EisaCheckAdapterComponent ( IN ULONG BusNumber, OUT PCONFIGURATION_COMPONENT *pEisaComp ); BOOLEAN EisaBusPod ( IN ULONG BusNumber ); BOOLEAN EisaPortIni ( IN PUCHAR EisaIoStart ); BOOLEAN EisaIntIni ( IN PUCHAR EisaIoStart, IN PEISA_INT_INFO pIntInfo ); BOOLEAN EisaDmaIni ( IN PUCHAR EisaIoStart, IN PEISA_DMA_INFO pDmaInfo ); BOOLEAN EisaBusCfg ( IN PCONFIGURATION_COMPONENT EisaComponent ); BOOLEAN EisaPhysSlotCfg ( IN ULONG BusNumber, IN PCONFIGURATION_COMPONENT Controller, IN ULONG AdapId ); BOOLEAN EisaVirSlotCfg ( IN ULONG BusNumber, IN PCONFIGURATION_COMPONENT Controller ); BOOLEAN EisaSlotCfg ( IN ULONG BusNumber, IN PCONFIGURATION_COMPONENT Controller, IN UCHAR FunctionsNumber ); BOOLEAN EisaSlotCfgMem ( IN ULONG BusNumber, IN ULONG SlotNumber, IN PUCHAR EisaFuncInfo ); BOOLEAN EisaSlotCfgIrq ( IN PUCHAR EisaIoStart, IN PEISA_INT_INFO pIntInfo, IN PUCHAR EisaFuncInfo ); BOOLEAN EisaSlotCfgDma ( IN PUCHAR EisaIoStart, IN PEISA_DMA_INFO pDmaInfo, IN PUCHAR EisaFuncInfo ); BOOLEAN EisaSlotCfgIni ( IN PUCHAR EisaIoStart, IN PUCHAR EisaFuncInfo, OUT PBOOLEAN EnabAdapter ); VOID EisaSlotErrorLog ( IN ULONG BusNumber, IN ULONG SlotNumber, IN EISA_CFG_ERROR ErrorCode ); VOID EisaPathErrorLog ( IN PCONFIGURATION_COMPONENT Controller, IN EISA_CFG_ERROR ErrorCode ); VOID EisaStrErrorLog ( IN PCHAR Str, IN EISA_CFG_ERROR ErrorCode ); VOID EisaCheckpointFirstFase ( IN EISA_CHECKPOINT Chk ); BOOLEAN EisaCheckpointFinalFase ( IN EISA_CHECKPOINT Chk, IN BOOLEAN Passed ); BOOLEAN EisaReadReadyId ( IN PUCHAR EisaIoStart, IN ULONG SlotNumber, OUT PULONG AdapId ); VOID EisaReadId ( IN PUCHAR EisaIoStart, IN ULONG SlotNumber, OUT PULONG AdapId ); BOOLEAN EisaMemIni ( VOID ); VOID EisaDynMemIni ( VOID ); PCONFIGURATION_COMPONENT FwGetChild ( IN PCONFIGURATION_COMPONENT Component OPTIONAL ); PCONFIGURATION_COMPONENT FwGetPeer ( IN PCONFIGURATION_COMPONENT Component ); PCONFIGURATION_COMPONENT FwAddChild ( IN PCONFIGURATION_COMPONENT Component, IN PCONFIGURATION_COMPONENT NewComponent, IN PVOID ConfigurationData OPTIONAL ); PCONFIGURATION_COMPONENT FwGetComponent ( IN PCHAR Pathname ); PCONFIGURATION_COMPONENT FwGetParent ( IN PCONFIGURATION_COMPONENT Component ); VOID FwStallExecution ( IN ULONG Seconds ); ARC_STATUS AllocateMemoryResources ( IN OUT PFW_MD pBuffFwMd ); // ---------------------------------------------------------------------------- // Declare General Function Prototypes // ---------------------------------------------------------------------------- PCHAR FwToUpperStr ( IN OUT PCHAR s ); PCHAR FwToLowerStr ( IN OUT PCHAR s ); PCHAR FwGetPath ( IN PCONFIGURATION_COMPONENT Component, OUT PCHAR String ); VOID FwDelCfgTreeNode ( IN PCONFIGURATION_COMPONENT pComp, IN BOOLEAN Peer ); PCHAR FwGetMnemonic ( IN PCONFIGURATION_COMPONENT Component ); BOOLEAN FwValidMnem ( IN PCHAR Str ); ULONG Fw2UcharToUlongLSB ( IN PUCHAR String ); ULONG Fw3UcharToUlongLSB ( IN PUCHAR String ); ULONG Fw4UcharToUlongLSB ( IN PUCHAR String ); ULONG Fw4UcharToUlongMSB ( IN PUCHAR String ); PCHAR FwStoreStr ( IN PCHAR Str ); // ---------------------------------------------------------------------------- // GLOBAL: EISA configuration variables // ---------------------------------------------------------------------------- // EISA buses info EISA_BUS_INFO EisaBusInfo[ EISA_BUSES ]; // eisa bus info pointers // descriptor pointers PFW_MD LogFwMdBase = NULL; // starting logical descriptors pointer PFW_MD VirFwMdBase = NULL; // starting virtual descriptors pointer PFW_MD pFwMdPool; // descriptors pool // ---------------------------------------------------------------------------- // PROCEDURE: EisaIni: // // DESCRIPTION: This function does the eisa controller configuration. // // ARGUMENTS: none // // RETURN: none // // ASSUMPTIONS: // // CALLS: // // GLOBALS: ErrorWord // // NOTES: // ---------------------------------------------------------------------------- // VOID EisaIni ( VOID ) { // define local variables PCONFIGURATION_COMPONENT pEisaComp; // eisa bus component CHAR EisaMnemonic[MAX_MNEMONIC_LEN +1]; // to hold the eisa path ULONG EisaBus; // eisa bus number BOOLEAN IniOk; // EISA configuration bus status PRINTDBG("EisaIni\n\r"); // DEBUG SUPPORT // // perform any general initialization // EisaGeneralIni(); // NOTE: EisaMemIni not used on JAZZ. // if ( !EisaMemIni() ) // { // EisaStrErrorLog("EISA Initialization", MemAllocError); // return; // } // // initialize and configure the eisa buses (one per loop) // for ( EisaBus = 0; EisaBus < EISA_BUSES; EisaBus++ ) { // // display message // FwPrint(EISA_INIT_MSG, EisaBus); // // eisa bus structures initialization // if ( !EisaBusStructIni( EisaBus )) { EisaStrErrorLog( EISA_BUS_MSG, MemAllocError); return; } // // eisa bus hardware test and initialization // if ( EisaBusInfo[ EisaBus ].Flags.Error = !EisaBusPod( EisaBus )) { // ErrorWord |= E_HARDWARE_ERROR; } // // check the EISA adapter component // IniOk = TRUE; EisaCheckpointFirstFase( EisaCfg ); if ( !EisaCheckAdapterComponent( EisaBus, &pEisaComp )) { IniOk = FALSE; } // // Return if no EISA information available. // if (pEisaComp == NULL) { return; } // // configure the bus if no hardware errors and configuration jumper not // present. // // NOTE: FlagWord is not used in JAZZ. // if (!EisaBusInfo[EisaBus].Flags.Error && !(FlagWord & F_CONFIG_JUMPER)) if (!EisaBusInfo[EisaBus].Flags.Error) { if ( !EisaBusCfg( pEisaComp )) { IniOk = FALSE; } } EisaCheckpointFinalFase( EisaCfg, IniOk ); if ( IniOk != TRUE ) { // NOTE: Not used in JAZZ. // ErrorWord |= E_CONFIG_ERROR; } // // store the POD initialization status // EisaBusInfo[ EisaBus ].Flags.IniDone = 1; pEisaComp->Flags.Failed = EisaBusInfo[ EisaBus ].Flags.Error; if (IniOk == TRUE) { FwPrint(EISA_OK_MSG); FwStallExecution(500000); } FwPrint(EISA_CRLF_MSG); } // // Big Endian initialization // // NOTE: BigEndian is not used on JAZZ. // BiEndianIni(); // // EISA dynamic memory initializzation // // NOTE: EisaDynMemIni not used on JAZZ. // EisaDynMemIni(); // // OMF initialization: final phase // // NOTE: EisaOmfIni not used on JAZZ. // EisaOmfIni(); // // Write out the hardware id, JAZZ only. The first page of the EISA // I/O control space is actually translated into a page of memory, where // the hardware ID is stored. // *(PUCHAR)(EISA_EXTERNAL_IO_VIRTUAL_BASE + 0x0c80) = (('J' - 'A' + 1) << 2) + (('A' - 'A' + 1) >> 3); *(PUCHAR)(EISA_EXTERNAL_IO_VIRTUAL_BASE + 0x0c81) = (('A' - 'A' + 1) << 5) + ('Z' - 'A' + 1); *(PUCHAR)(EISA_EXTERNAL_IO_VIRTUAL_BASE + 0x0c82) = 0; *(PUCHAR)(EISA_EXTERNAL_IO_VIRTUAL_BASE + 0x0c83) = 0; // // all done // return; } // ---------------------------------------------------------------------------- // PROCEDURE: EisaGeneralIni: // // DESCRIPTION: This function performs general initialization // for the EISA buses. // // ARGUMENTS: none // // RETURN: none // // ASSUMPTIONS: // // CALLS: // // GLOBALS: // // NOTES: // ---------------------------------------------------------------------------- // VOID EisaGeneralIni ( VOID ) { PRINTDBG("EisaGeneralIni\n\r"); // DEBUG SUPPORT // // update system parameter block // SYSTEM_BLOCK->AdapterCount = 1; SYSTEM_BLOCK->Adapter0Type = EisaAdapter; SYSTEM_BLOCK->Adapter0Length = (ULONG)MaximumEisaRoutine * sizeof(ULONG); SYSTEM_BLOCK->Adapter0Vector = (PVOID)(SYSTEM_BLOCK->VendorVector + SYSTEM_BLOCK->VendorVectorLength); // // initialize EISA call back vectors // (PEISA_PROCESS_EOI_RTN)SYSTEM_BLOCK->Adapter0Vector [ProcessEOIRoutine] = EisaProcessEndOfInterrupt; // [ProcessEOIRoutine] = FwpReservedRoutine; (PEISA_TEST_INT_RTN)SYSTEM_BLOCK->Adapter0Vector [TestIntRoutine] = EisaTestEisaInterrupt; // [TestIntRoutine] = FwpReservedRoutine; (PEISA_REQ_DMA_XFER_RTN)SYSTEM_BLOCK->Adapter0Vector // [RequestDMARoutine] = EisaRequestEisaDmaTransfer; [RequestDMARoutine] = FwpReservedRoutine; (PEISA_ABORT_DMA_RTN)SYSTEM_BLOCK->Adapter0Vector // [AbortDMARoutine] = EisaAbortEisaDmaTransfer; [AbortDMARoutine] = FwpReservedRoutine; (PEISA_DMA_XFER_STATUS_RTN)SYSTEM_BLOCK->Adapter0Vector // [GetDMAStatusRoutine] = EisaGetEisaDmaTransferStatus; [GetDMAStatusRoutine] = FwpReservedRoutine; (PEISA_LOCK_RTN)SYSTEM_BLOCK->Adapter0Vector // [DoLockRoutine] = EisaDoLockedOperation; [DoLockRoutine] = FwpReservedRoutine; (PEISA_REQUEST_BUS_MASTER_RTN)SYSTEM_BLOCK->Adapter0Vector // [RequestBusMasterRoutine] = EisaRequestEisaBusMasterTransfer; [RequestBusMasterRoutine] = FwpReservedRoutine; (PEISA_RELEASE_BUS_MASTER_RTN)SYSTEM_BLOCK->Adapter0Vector // [ReleaseBusMasterRoutine] = EisaReleaseEisaBusMasterTransfer; [ReleaseBusMasterRoutine] = FwpReservedRoutine; (PEISA_REQUEST_CPU_TO_BUS_ACCESS_RTN)SYSTEM_BLOCK->Adapter0Vector // [RequestCpuAccessToBusRoutine] = EisaRequestCpuAccessToEisaBus; [RequestCpuAccessToBusRoutine] = FwpReservedRoutine; (PEISA_RELEASE_CPU_TO_BUS_ACCESS_RTN)SYSTEM_BLOCK->Adapter0Vector // [ReleaseCpuAccessToBusRoutine] = EisaReleaseCpuAccessToEisaBus; [ReleaseCpuAccessToBusRoutine] = FwpReservedRoutine; (PEISA_FLUSH_CACHE_RTN)SYSTEM_BLOCK->Adapter0Vector // [FlushCacheRoutine] = EisaFlushCache; [FlushCacheRoutine] = FwpReservedRoutine; (PEISA_INVALIDATE_CACHE_RTN)SYSTEM_BLOCK->Adapter0Vector // [InvalidateCacheRoutine] = EisaInvalidateCache; [InvalidateCacheRoutine] = FwpReservedRoutine; (PEISA_BEGIN_CRITICAL_SECTION_RTN)SYSTEM_BLOCK->Adapter0Vector [BeginCriticalSectionRoutine] = EisaBeginCriticalSection; // [BeginCriticalSectionRoutine] = FwpReservedRoutine; (PEISA_RESERVED_RTN)SYSTEM_BLOCK->Adapter0Vector [ReservedRoutine] = NULL; (PEISA_END_CRITICAL_SECTION_RTN)SYSTEM_BLOCK->Adapter0Vector [EndCriticalSectionRoutine] = EisaEndCriticalSection; // [EndCriticalSectionRoutine] = FwpReservedRoutine; (PEISA_GENERATE_TONE_RTN)SYSTEM_BLOCK->Adapter0Vector [GenerateToneRoutine] = EisaGenerateTone; (PEISA_FLUSH_WRITE_BUFFER_RTN)SYSTEM_BLOCK->Adapter0Vector // [FlushWriteBuffersRoutine] = EisaFlushWriteBuffers; [FlushWriteBuffersRoutine] = FwpReservedRoutine; (PEISA_YIELD_RTN)SYSTEM_BLOCK->Adapter0Vector // [YieldRoutine] = EisaYield; [YieldRoutine] = FwpReservedRoutine; (PEISA_STALL_PROCESSOR_RTN)SYSTEM_BLOCK->Adapter0Vector [StallProcessorRoutine] = FwStallExecution; // // all done // return; } // ---------------------------------------------------------------------------- // PROCEDURE: EisaBusStructIni: // // DESCRIPTION: This function builds all the required structures // for the specified EISA bus. // // ARGUMENTS: BusNumber EISA bus number // // RETURN: TRUE All done // FALSE Error // // ASSUMPTIONS: // // CALLS: // // GLOBALS: // // NOTES: This routine is hardware design dependent. // // ---------------------------------------------------------------------------- // BOOLEAN EisaBusStructIni ( IN ULONG BusNumber ) { // // define local variables // PVOID pInfo; // General pointer PEISA_BUS_INFO pBusInfo; // EISA bus info pointer PFW_MD pIoBusInfo; // I/O info pointer PFW_MD pMemBusInfo; // Memory info pointer PEISA_SLOTS_INFO pSlotsInfo; // Slots info pointer PEISA_DMA_INFO pDmaInfo; // DMA info pointer PEISA_INT_INFO pIntInfo; // INT info pointer PEISA_PORT_INFO pPortInfo; // port info pointer ULONG Index; // general index PRINTDBG("EisaBusStructIni\n\r"); // DEBUG SUPPORT // // initialize variables // pBusInfo = &EisaBusInfo[ BusNumber ]; pBusInfo->Flags.IniDone = 0; // // first EISA bus // if ( BusNumber == 0 ) { // // perform any info structure initialization // if ((pInfo = (PVOID)FwAllocatePool( sizeof( FW_MD ) + sizeof( FW_MD ) + sizeof( EISA_SLOTS_INFO ) + sizeof( EISA_DMA_INFO ) + sizeof( EISA_INT_INFO ))) == NULL ) { return FALSE; } // // I/O bus info initialization // pBusInfo->IoBusInfo = pIoBusInfo = (PFW_MD)pInfo; // set link and flags pIoBusInfo->Link = NULL; pIoBusInfo->Flags.Busy = 1; pIoBusInfo->Counter = 1; // set window size in 4k units pIoBusInfo->PhysAddr = EISA_IO_PHYSICAL_BASE/PAGE_SIZE; pIoBusInfo->PagOffs = 0; pIoBusInfo->VirAddr = (PVOID)EISA_EXTERNAL_IO_VIRTUAL_BASE; pIoBusInfo->Size = 64 * 1024; pIoBusInfo->PagNumb = 64/4; ((PFW_MD)pInfo)++; // // memory bus info initialization // pBusInfo->MemBusInfo = pMemBusInfo = (PFW_MD)pInfo; // set link and flags pMemBusInfo->Link = NULL; pMemBusInfo->Flags.Busy = 0; // window busy flag pMemBusInfo->Counter = 0; #ifdef KPW4010 // set size of window in 4k units pMemBusInfo->PhysAddr = EISA_MEM_PHYSBASE_KPW4010; // #4kpages pMemBusInfo->PagOffs = 0; pMemBusInfo->VirAddr = (PVOID)EISA_VIR_MEM; pMemBusInfo->Size = 0; // 4 Gbytes pMemBusInfo->PagNumb = PAGES_IN_4G; // // Because the EISA memory space in some designs can reach // 4Gbytes of length, it is not possible to map the entire area. // The allocation of the TLB entries for this space is done at // run time using the general calls to the TLB services. // pMemBusInfo->u.em.WinRelAddr = 0; pMemBusInfo->u.em.WinRelAddrCtrl = NULL; pMemBusInfo->u.em.WinShift = PAGE_4G_SHIFT; #else // KPW 4000 // set size of window in 4k units pMemBusInfo->PhysAddr = EISA_MEMORY_PHYSICAL_BASE/PAGE_SIZE; pMemBusInfo->PagOffs = 0; pMemBusInfo->VirAddr = (PVOID)EISA_MEMORY_VIRTUAL_BASE; pMemBusInfo->Size = PAGE_16M_SIZE; pMemBusInfo->PagNumb = PAGE_16M_SIZE/PAGE_SIZE; // // Because the EISA memory space in some designs can reach // 4Gbytes of length, it is not possible to map the entire area. // The allocation of the TLB entries for this space is done at // run time using the general calls to the TLB services. // pMemBusInfo->u.em.WinRelAddr = 0; pMemBusInfo->u.em.WinRelAddrCtrl = (PVOID)EISA_LATCH_VIRTUAL_BASE; pMemBusInfo->u.em.WinShift = PAGE_16M_SHIFT; #endif ((PFW_MD)pInfo)++; // // slot info initialization // pBusInfo->SlotsInfo = pSlotsInfo = (PEISA_SLOTS_INFO)pInfo; pSlotsInfo->PhysSlots = PHYS_0_SLOTS; pSlotsInfo->VirSlots = VIR_0_SLOTS; ((PEISA_SLOTS_INFO)pInfo)++; // // DMA info initialization // pBusInfo->DmaInfo = pDmaInfo = (PEISA_DMA_INFO)pInfo; pDmaInfo->Flags.IniDone = 0; ((PEISA_DMA_INFO)pInfo)++; // // PIC info initialization // pBusInfo->IntInfo = pIntInfo = (PEISA_INT_INFO)pInfo; pIntInfo->Flags.IniDone = 0; ((PEISA_INT_INFO)pInfo)++; // // port info initialization // pBusInfo->PortInfo = pPortInfo = (PEISA_PORT_INFO)pInfo; pPortInfo->Flags.IniDone = 0; } else { // // invalid bus number // return FALSE; } // // all done // return TRUE; } // ---------------------------------------------------------------------------- // PROCEDURE: EisaCheckAdapterComponent: // // DESCRIPTION: This function makes sure that there is an EISA adapter // component with the correct configuration data for the // specified EISA bus number. The routine uses the // following logic : // // if !(ARC component present) // { // add ARC component; // } // if (EISA bus component present) // { // if !(configuration data correct) // { // display error message; // delete EISA bus node; // add EISA bus component; // return FALSE; // } // } // else // { // add EISA bus component; // } // return TRUE; // // ARGUMENTS: BusNumber EISA bus number // pEisaComp address where to store the EISA // configuration pointer // // RETURN: FALSE The configuration tree was incorrect. // TRUE The configuration tree is correct. // // ASSUMPTIONS: The ARC component is present. // // CALLS: // // GLOBALS: // // NOTES: // ---------------------------------------------------------------------------- // BOOLEAN EisaCheckAdapterComponent ( IN ULONG BusNumber, OUT PCONFIGURATION_COMPONENT *pEisaComp ) { // // define local variables // PCONFIGURATION_COMPONENT pComp; CONFIGURATION_COMPONENT Comp; EISA_ADAPTER_DETAILS ConfigData; BOOLEAN CfgOk = TRUE; CHAR EisaMnemonic[MAX_MNEMONIC_LEN +1]; PVOID IoStart; ULONG IoSize; ULONG Slots; PRINTDBG("EisaCheckAdapterComponent\n\r"); // DEBUG SUPPORT // // initialize varables // sprintf( EisaMnemonic, "eisa(%lu)", BusNumber ); *pEisaComp = NULL; IoStart = EisaBusInfo[ BusNumber ].IoBusInfo->VirAddr; IoSize = EisaBusInfo[ BusNumber ].SlotsInfo->PhysSlots * 0x1000; Slots = EisaBusInfo[ BusNumber ].SlotsInfo->VirSlots ? EisaBusInfo[ BusNumber ].SlotsInfo->VirSlots + 16 : EisaBusInfo[ BusNumber ].SlotsInfo->PhysSlots; // // if EISA adapter component is present, check its configuration data // if ((*pEisaComp = FwGetComponent(EisaMnemonic)) != NULL) { if ((*pEisaComp)->ConfigurationDataLength != sizeof(EISA_ADAPTER_DETAILS) || FwGetConfigurationData( (PVOID)&ConfigData, *pEisaComp ) || ConfigData.NumberOfSlots != Slots || ConfigData.IoStart != IoStart || ConfigData.IoSize != IoSize ) { EisaPathErrorLog( *pEisaComp, CfgIncorrect ); FwDelCfgTreeNode( *pEisaComp, FALSE ); *pEisaComp = NULL; CfgOk = FALSE; } } // // add EISA adapter component if not present // if ( *pEisaComp == NULL ) { // get the root component pointer if ((pComp = FwGetChild(NULL)) == NULL) { return(FALSE); } // component structure RtlZeroMemory( &Comp, sizeof(CONFIGURATION_COMPONENT)); Comp.Class = AdapterClass; Comp.Type = EisaAdapter; Comp.Version = ARC_VERSION; Comp.Revision = ARC_REVISION; Comp.Key = BusNumber; Comp.ConfigurationDataLength = sizeof(EISA_ADAPTER_DETAILS); Comp.IdentifierLength = sizeof("EISA"); Comp.Identifier = "EISA"; // configuration data structure RtlZeroMemory( &ConfigData, sizeof(EISA_ADAPTER_DETAILS)); // NOTE: ConfigDataHeader is not used in JAZZ. // ConfigData.ConfigDataHeader.Version = ARC_VERSION; // ConfigData.ConfigDataHeader.Revision = ARC_REVISION; // ConfigData.ConfigDataHeader.Type = NULL; // ConfigData.ConfigDataHeader.Vendor = NULL; // ConfigData.ConfigDataHeader.ProductName = NULL; // ConfigData.ConfigDataHeader.SerialNumber = NULL; ConfigData.NumberOfSlots = Slots; ConfigData.IoStart = IoStart; ConfigData.IoSize = IoSize; *pEisaComp = FwAddChild( pComp, &Comp, (PVOID)&ConfigData ); } // // return status // return CfgOk; } // ---------------------------------------------------------------------------- // PROCEDURE: EisaBusCfg: // // DESCRIPTION: This function configures the slots of the specified // eisa bus. // // if we detect a "not-ready" board, we have to retry // reading the ID again and report a time-out error if // the ID is still not available after 100 msecs. // (according to the EISA specs, the board should be // ready within 100 msecs after reporting the "not-ready" // status). However, due to the slow init process of // the ESC-1, we need to go with the following algorithm: // - cfg the physical slots, marking the ones not ready. // - cfg the virtual slots // - go back to cfg the not-ready physical slots. // A time of 2 sec will be given to all these not-ready // slots : 200 loops of 10 msec. This period does not // include configuration time for any slot which now // comes up with a valid ID. // // ARGUMENTS: EisaComponent EISA component pointer // // RETURN: TRUE Configuration completed successfully // FALSE At least one configuration error // // ASSUMPTIONS: // // CALLS: // // GLOBALS: // // NOTES: // ---------------------------------------------------------------------------- // BOOLEAN EisaBusCfg ( IN PCONFIGURATION_COMPONENT EisaComponent ) { // // define local variables // BOOLEAN CfgOk = TRUE; // starting value: all fine ULONG IdTimeoutFlags = 0; // eisa controllers in time-out USHORT WaitTimeout=TIMEOUT_UNITS; // time to wait before aborting PCONFIGURATION_COMPONENT FirstController; // first eisa controller PCONFIGURATION_COMPONENT Controller; // eisa controller to configure ULONG BusNumber; // eisa bus number ULONG PhysSlots; // eisa physical slots ULONG MaxSlots; // eisa last slot ULONG SlotNumber; // slot number configured PULONG pSlotCfgMap; // slot cfg map pointer PUCHAR EisaIoStart; // i/o eisa starting space ULONG AdapId; // eisa controller id PRINTDBG("EisaBusCfg\n\r"); // DEBUG SUPPORT // // initialize same variables using the eisa component structure // BusNumber = EisaComponent->Key; EisaIoStart = EisaBusInfo[ BusNumber ].IoBusInfo->VirAddr; PhysSlots = EisaBusInfo[ BusNumber ].SlotsInfo->PhysSlots; MaxSlots = EisaBusInfo[ BusNumber ].SlotsInfo->VirSlots + 16; pSlotCfgMap = &EisaBusInfo[ BusNumber ].SlotsInfo->SlotCfgMap; *pSlotCfgMap = 0; FirstController = FwGetChild(EisaComponent); // // physical slot initialization : one loop per physical slot // for (SlotNumber=0; SlotNumberKey!=SlotNumber; Controller = FwGetPeer(Controller)); // skip cfg if empty slot; report an error if ARC cfg is missing if (Controller==NULL) { if (AdapId!=NO_ADAP_ID) { EisaSlotErrorLog( BusNumber, SlotNumber, CfgMissing ); CfgOk = FALSE; } continue; } // one physical slot configuration if (!EisaPhysSlotCfg(BusNumber, Controller, AdapId)) { CfgOk = FALSE; continue; } // set the "slot" bit to indicate configuration ok *pSlotCfgMap |= 1<Key!=SlotNumber; Controller = FwGetPeer(Controller)); // if component not present, skip to next virtual slot if (Controller==NULL) { continue; } // one virtual slot configuration if(!EisaVirSlotCfg(BusNumber, Controller)) { CfgOk = FALSE; continue; } // set the "slot" bit to indicate configuration ok *pSlotCfgMap |= 1<Key!=SlotNumber; Controller = FwGetPeer(Controller)); // skip cfg if empty slot; report an error if ARC cfg is missing if (Controller==NULL) { if (AdapId!=NO_ADAP_ID) { EisaSlotErrorLog(BusNumber, SlotNumber, CfgMissing); CfgOk = FALSE; } continue; } // one physical slot configuration if (!EisaPhysSlotCfg(BusNumber, Controller, AdapId)) { CfgOk = FALSE; continue; } // set the "slot" bit to indicate configuration ok *pSlotCfgMap |= 1<Key!=SlotNumber; Controller = FwGetPeer(Controller)); // if component present, set failed bit if (Controller != NULL) { Controller->Flags.Failed = 1; } } } CfgOk = FALSE; } // // // // add a wild omf path name for the physical slots non configurated. // // // // for ( SlotNumber = 0; SlotNumber < PHYS_0_SLOTS; SlotNumber++ ) // { // if ( !(*pSlotCfgMap & 1<Flags.Failed) { ErrMessage = CfgDeviceFailed; // device failure } else if ( !(Controller->ConfigurationDataLength) ) { ErrMessage = CfgMissing; // eisa configuration missing } else if (Controller->ConfigurationDataLength < EISA_SLOT_MIN_INFO) { ErrMessage = CfgIncorrect; // configuration length incorrect } else if (FwGetConfigurationDataIndex( (PVOID)&EisaSlotInfo, Controller, CONFIGDATAHEADER_SIZE, EISA_SLOT_INFO_SIZE )) { ErrMessage = CfgIncorrect; // invalid component } else if (EisaSlotInfo.FunctionsNumber * EISA_FUNC_INFO_SIZE + EISA_SLOT_MIN_INFO != Controller->ConfigurationDataLength) { ErrMessage = CfgIncorrect; // configuration length incorrect } else if (!(EisaSlotInfo.IdInfo & CFG_UNREADABLE_ID)^(AdapId != NO_ADAP_ID)) { ErrMessage = CfgIdError; // wrong configuration } else if (AdapId != NO_ADAP_ID && AdapId != Fw4UcharToUlongMSB(&EisaSlotInfo.Id1stChar)) { ErrMessage = CfgIdError; // wrong configuration } else if ((EisaSlotInfo.IdInfo & CFG_SLOT_MASK) != CFG_SLOT_EXP && (EisaSlotInfo.IdInfo & CFG_SLOT_MASK) != CFG_SLOT_EMB ) { ErrMessage = CfgIncorrect; // wrong configuration } // // if any error, dispaly error message and set the failed bit // if (ErrMessage != CfgNoErrCode) { EisaSlotErrorLog( BusNumber, Controller->Key, ErrMessage ); Controller->Flags.Failed = 1; return FALSE; } // // eisa adapter configuration // return( EisaSlotCfg( BusNumber, Controller, EisaSlotInfo.FunctionsNumber )); } // ---------------------------------------------------------------------------- // PROCEDURE: EisaVirSlotCfg: // // DESCRIPTION: This function configures the specified virtual slot. // // ARGUMENTS: BusNumber EISA bus number // Controller eisa controller component pointer. // // // RETURN: FALSE Error // TRUE All done // // ASSUMPTIONS: // // CALLS: // // GLOBALS: // // NOTES: // ---------------------------------------------------------------------------- // BOOLEAN EisaVirSlotCfg ( IN ULONG BusNumber, IN PCONFIGURATION_COMPONENT Controller ) { // // define local variables // EISA_SLOT_INFO EisaSlotInfo; // pointer to first eisa info EISA_CFG_ERROR ErrMessage = CfgNoErrCode; // eisa cfg error code PRINTDBG("EisaVirSlotCfg\n\r"); // DEBUG SUPPORT // // validate virtual slot configuration // if (Controller->Flags.Failed) { ErrMessage = CfgDeviceFailed; // device failure } else if ( !(Controller->ConfigurationDataLength) ) { ErrMessage = CfgMissing; // configuration missing } if (Controller->ConfigurationDataLength < EISA_SLOT_MIN_INFO) { ErrMessage = CfgIncorrect; // configuration length incorrect } else if (FwGetConfigurationDataIndex( (PVOID)&EisaSlotInfo, Controller, CONFIGDATAHEADER_SIZE, EISA_SLOT_INFO_SIZE )) { ErrMessage = CfgIncorrect; // invalid component } else if (EisaSlotInfo.FunctionsNumber * EISA_FUNC_INFO_SIZE + EISA_SLOT_MIN_INFO != Controller->ConfigurationDataLength) { ErrMessage = CfgIncorrect; // configuration length incorrect } else if ( !(EisaSlotInfo.IdInfo & CFG_UNREADABLE_ID) ) { ErrMessage = CfgIdError; // wrong configuration } else if ( (EisaSlotInfo.IdInfo & CFG_SLOT_MASK) != CFG_SLOT_VIR) { ErrMessage = CfgIncorrect; // wrong configuration } // // if any error, display error message and set the failed bit // if (ErrMessage != CfgNoErrCode) { EisaSlotErrorLog( BusNumber, Controller->Key, ErrMessage ); Controller->Flags.Failed = 1; return FALSE; } // // eisa adapter configuration // return( EisaSlotCfg( BusNumber, Controller, EisaSlotInfo.FunctionsNumber )); } // ---------------------------------------------------------------------------- // PROCEDURE: EisaSlotCfg: // // DESCRIPTION: This function configures the specified slot. // // ARGUMENTS: BusNumber EISA bus number // Controller Controller component pointer // FunctionsNumber Number of function to configure // // RETURN: TRUE Configuration done // FALSE Error // // ASSUMPTIONS: // // CALLS: // // GLOBALS: // // NOTES: // ---------------------------------------------------------------------------- // BOOLEAN EisaSlotCfg ( IN ULONG BusNumber, IN PCONFIGURATION_COMPONENT Controller, IN UCHAR FunctionsNumber ) { // // define local variables // UCHAR FuncFlags; // function info flags UCHAR Function; // current function number BOOLEAN CfgOk = TRUE; // local configuration status BOOLEAN EnabAdapter = TRUE; // adapter enable flag PUCHAR EnabPort; // used to enable the adapter PUCHAR EisaIoStart; // Eisa I/O virtual space PEISA_DMA_INFO pDmaInfo; // DMA info pointer PEISA_INT_INFO pIntInfo; // interrupts info pointer BOOLEAN CfgMemOk = TRUE; // prevent multiple messages BOOLEAN CfgIrqOk = TRUE; // " " " BOOLEAN CfgDmaOk = TRUE; // " " " BOOLEAN CfgIniOk = TRUE; // " " " UCHAR EisaFuncInfo[ EISA_FUNC_INFO_SIZE ]; ULONG EisaFuncIndex; PRINTDBG("EisaSlotCfg\n\r"); // DEBUG SUPPORT // // initialize variables // EisaIoStart = (PUCHAR)EisaBusInfo[ BusNumber ].IoBusInfo->VirAddr; pDmaInfo = EisaBusInfo[ BusNumber ].DmaInfo; pIntInfo = EisaBusInfo[ BusNumber ].IntInfo; EisaFuncIndex = EISA_SLOT_MIN_INFO; // // one function per loop // for ( Function = 0; Function < FunctionsNumber; Function++, EisaFuncIndex += EISA_FUNC_INFO_SIZE ) { // // read function info // FwGetConfigurationDataIndex( (PVOID)EisaFuncInfo, Controller, EisaFuncIndex, EISA_FUNC_INFO_SIZE ); // // check if configuration complete, exit if not. // if ( EisaFuncInfo[ CFG_SLOT_INFO_OFS ] & CFG_INCOMPLETE ) { EisaSlotErrorLog( BusNumber, Controller->Key, CfgIncomplete ); CfgOk = FALSE; break; } // update eisa function flags FuncFlags = EisaFuncInfo[ CFG_FN_INFO_OFS ]; // skip if free form function if ( FuncFlags & CFG_FREE_FORM ) { continue; } // // check if there is any memory entry // // NOTE: Eisa memory not supported on JAZZ. // if ( FuncFlags & CFG_MEM_ENTRY ) // { // if ( !EisaSlotCfgMem( BusNumber, Controller->Key, EisaFuncInfo ) && // CfgMemOk ) // { // EisaSlotErrorLog( BusNumber, Controller->Key, CfgMemError ); // CfgOk = CfgMemOk = FALSE; // } // } // // check if there is any interrupt entry // if ( FuncFlags & CFG_IRQ_ENTRY ) { if (!EisaSlotCfgIrq( EisaIoStart, pIntInfo, EisaFuncInfo ) && CfgIrqOk ) { EisaSlotErrorLog( BusNumber, Controller->Key, CfgIrqError ); CfgOk = CfgIrqOk = FALSE; } } // // check if there is any DMA entry // if ( FuncFlags & CFG_DMA_ENTRY ) { if ( !EisaSlotCfgDma( EisaIoStart, pDmaInfo, EisaFuncInfo ) && CfgDmaOk ) { EisaSlotErrorLog( BusNumber, Controller->Key, CfgDmaError ); CfgOk = CfgDmaOk = FALSE; } } // // check if there is any port init entry // if ( FuncFlags & CFG_INI_ENTRY ) { if ( !EisaSlotCfgIni( EisaIoStart, EisaFuncInfo, &EnabAdapter ) && CfgIniOk ) { EisaSlotErrorLog( BusNumber, Controller->Key, CfgIniError ); CfgOk = CfgIniOk = FALSE; } } } // // if all fine, enable the adapter // if (CfgOk && EnabAdapter) { EnabPort=EisaIoStart+ Controller->Key*0x1000 +EXPANSION_BOARD_CTRL_BITS; EisaOutUchar(EnabPort, EisaInUchar(EnabPort) | 0x01); } // // return status of configuration process // return CfgOk; } // ---------------------------------------------------------------------------- // PROCEDURE: EisaSlotCfgMem: // // DESCRIPTION: This function configures the eisa memory registers // based on info from NVRAM. // // ARGUMENTS: BusNumber EISA bus number. // SlotNumber EISA slot number. // EisaFuncInfo Function info pointer. // // RETURN: TRUE All done // FALSE Error // // ASSUMPTIONS: // // CALLS: // // GLOBALS: // // NOTES: // ---------------------------------------------------------------------------- // // NOTE: Eisa memory not supported on JAZZ. #if 0 BOOLEAN EisaSlotCfgMem ( IN ULONG BusNumber, IN ULONG SlotNumber, IN PUCHAR EisaFuncInfo ) { // // define local variables // BOOLEAN CfgOk = TRUE; // local configuration status PUCHAR MemBlock; // start of DMA data buffer USHORT Index = 0; // index within the memory block PFW_MD pFwMd; // memory decriptor pointer ULONG Addr; // address in 256 units ULONG Size; // size in 1k units ULONG WinSize, WinOffs; // EISA windows characteristic PFW_MD pMemInfo; // EISA memory address space info PRINTDBG("EisaSlotCfgMem\n\r"); // DEBUG SUPPORT // // initialize variables // pMemInfo = EisaBusInfo[ BusNumber ].MemBusInfo; MemBlock = &EisaFuncInfo[ CFG_MEM_BLK_OFS ]; // // one loop per each memory entry // do { // // get a memory descriptor // if ( (pFwMd = GetFwMd()) == NULL ) { EisaSlotErrorLog( BusNumber, SlotNumber, MemAllocError); return FALSE; } // // memory block start and length // Addr = Fw3UcharToUlongLSB( &MemBlock[Index + 2] ); Size = Fw2UcharToUlongLSB( &MemBlock[Index + 5] ); pFwMd->VirAddr = NULL; pFwMd->PhysAddr = Addr >> 4; pFwMd->PagOffs = (Addr << 8) & (PAGE_SIZE - 1); pFwMd->Size = Size ? Size << 10 : 64*1024*1024 ; pFwMd->PagNumb = (pFwMd->PagOffs + Size + PAGE_SIZE - 1) >> PAGE_SHIFT; pFwMd->Cache = FALSE; pFwMd->u.m.BusNumber = BusNumber; pFwMd->u.m.SlotNumber = SlotNumber; pFwMd->u.m.Type = MemBlock[ Index ] & CFG_MEM_TYPE; // // check if the memory size fits within the EISA window // if ( pMemInfo->u.em.WinShift != PAGE_4G_SHIFT ) { // window size < 4 Gbytes WinSize = 1 << pMemInfo->u.em.WinShift; WinOffs = (Addr << 8) & (WinSize - 1); if ( WinSize - WinOffs < pFwMd->Size ) { ReleaseFwMd( &pMemInfo->Link, pFwMd ); CfgOk = FALSE; continue; } } // // link the memory descriptor // if ( LinkPhysFwMd( &pMemInfo->Link, pFwMd ) == NULL ) { ReleaseFwMd( &pMemInfo->Link, pFwMd ); CfgOk = FALSE; continue; } } while ((MemBlock[Index]&CFG_MORE_ENTRY) && ((Index+=7)IrqPresent & IrqBit ) { // // IRQ already used: check if it is shareabe // if ( !(pIntInfo->IrqShareable & IrqBit) ) { CfgOk = FALSE; continue; } else if ( !(IrqBlock[Index] & CFG_IRQ_SHARE) ) { CfgOk = FALSE; continue; } // // IRQ is shareable: check if the levels are compatible // else if ( (pIntInfo->IrqLevel & IrqBit) && !(IrqBlock[Index] & CFG_IRQ_LEVEL) ) { CfgOk=FALSE; continue; } else if ( !(pIntInfo->IrqLevel & IrqBit) && (IrqBlock[Index] & CFG_IRQ_LEVEL) ) { CfgOk=FALSE; continue; } } else { // // new IRQ: check if the IRQ 0, 1, 2, 8 and 13 are configurated // for edge triggered. // switch(IrqBit) { case (0x0001): // IRQ 0 only edge triggered case (0x0002): // IRQ 1 " " " case (0x0004): // IRQ 2 " " " case (0x0100): // IRQ 8 " " " case (0x2000): // IRQ 13 " " " if (IrqBlock[Index] & CFG_IRQ_LEVEL) { CfgOk=FALSE; continue; } break; default: break; } } // // set the present bit and update sharable and edge/level // triggered variables // pIntInfo->IrqPresent |= IrqBit; if (IrqBlock[Index] & CFG_IRQ_SHARE) { pIntInfo->IrqShareable |= IrqBit; } if (IrqBlock[Index] & CFG_IRQ_LEVEL) { pIntInfo->IrqLevel |= IrqBit; } } while ((IrqBlock[Index]&CFG_MORE_ENTRY) && ((Index+=2)IrqPresent); Register |= pIntInfo->IrqLevel; EisaOutUchar(EisaIoStart + PIC1_ELCR, Register); Register = EisaInUchar(EisaIoStart + PIC2_ELCR); Register &= ~(pIntInfo->IrqPresent >> BITSXBYTE); Register |= pIntInfo->IrqLevel >> BITSXBYTE; EisaOutUchar(EisaIoStart + PIC2_ELCR, Register); // // return configuration status // return CfgOk; } // ---------------------------------------------------------------------------- // PROCEDURE: EisaSlotCfgDma: // // DESCRIPTION: This function configures the DMA registers // based on info from NVRAM. // // ARGUMENTS: EisaIoStart EISA I/O virtual address // pDmaInfo DMA info pointer // EisaFuncInfo function info pointer. // // RETURN: TRUE All done // FALSE Error // // ASSUMPTIONS: // // CALLS: // // GLOBALS: // // NOTES: // ---------------------------------------------------------------------------- // BOOLEAN EisaSlotCfgDma ( IN PUCHAR EisaIoStart, IN PEISA_DMA_INFO pDmaInfo, IN PUCHAR EisaFuncInfo ) { // // define local variables // BOOLEAN CfgOk=TRUE; // local configuration status PUCHAR DmaBlock; // start of DMA data buffer USHORT Index=0; // index within the DMA block UCHAR DmaNumber; // DMA under configuration UCHAR Register; // used to update the registers PRINTDBG("EisaSlotCfgDma\n\r"); // DEBUG SUPPORT // // initialize variables // DmaBlock = &EisaFuncInfo[ CFG_DMA_BLK_OFS ]; // // one loop per each DMA entry // do { // // skip if shareable. device drivers should init DMA, not ROM // // NOTE: the following code has been removed because all the // EISA cards that share the same DMA channel have the // same value in this register. This is guaranteed by // the configuration utility. //if ( DmaBlock[Index] & CFG_DMA_SHARED ) //{ // continue; //} // // Program the specified DMA channel using the new info. // DmaNumber = DmaBlock[Index] & CFG_DMA_MASK; // keep the "stop register" and "T-C" bits Register = pDmaInfo->DmaExtReg[ DmaNumber ] & ~CFG_DMA_CFG_MASK; // use the new timing and bit I/O selection Register |= DmaBlock[Index+1] & CFG_DMA_CFG_MASK; // update the register if (DmaNumber < 4) { EisaOutUchar(EisaIoStart + DMA_EXTMODE03, Register); } else { EisaOutUchar(EisaIoStart + DMA_EXTMODE47, Register); } // This register value is used to validate the DMA requestes // (see the "EisaRequestEisaDmaTransfer" function). // The DMA channels used by more than one card have always the // same value ( check with the configuration guys ). pDmaInfo->DmaExtReg[ DmaNumber ] = Register; } while ((DmaBlock[Index]&CFG_MORE_ENTRY) && ((Index+=2)= 16 ) { // // we don't use the memory above 16Mbytes because in this way we // can use this logic in a machine without translation registers // (logical I/O to physical) for the ISA boards which have a // transfer range of 24 bits (16Mbytes). // EisaFreeTop = EISA_FREE_TOP_16; EisaFreeBytes = EISA_FREE_BYTES_16; } else if ( MemorySize >= 12 ) { EisaFreeTop = EISA_FREE_TOP_12; EisaFreeBytes = EISA_FREE_BYTES_12; } else if ( MemorySize >= 8 ) { EisaFreeTop = EISA_FREE_TOP_8; EisaFreeBytes = EISA_FREE_BYTES_8; } else { return FALSE; } EisaFreeBytes -= EisaDynMemSize; return TRUE; } #endif // 0 // ---------------------------------------------------------------------------- // PROCEDURE: EisaDynMemIni: // // DESCRIPTION: This function allocates the requested space for the // the dynamic memory allocation. // // ARGUMENTS: none // // RETURN: none // // ASSUMPTIONS: // // CALLS: // // GLOBALS: EisaFreeTop top of free mem // EisaDynMemSize dynamic memory size (bytes) // EisaPoolSize EISA pool size (bytes) // // NOTES: // ---------------------------------------------------------------------------- // // NOTE: Not used for JAZZ. #if 0 VOID EisaDynMemIni ( VOID ) { // // define local variables // ULONG BytesToPage; // bytes left to make a page PHEADER pHdr; // memory descriptor header ptr PVOID Buffer; // data area PRINTDBG("EisaDynMemIni\n\r"); // DEBUG SUPPORT // // align the dynamic memory buffer on a page boundary // BytesToPage = PAGE_SIZE - (EisaDynMemSize & ((1 << PAGE_SHIFT) - 1)); EisaDynMemSize += BytesToPage; EisaPoolSize += BytesToPage; EisaFreeTop -= EisaDynMemSize; // // initialize first memory descriptor // pHdr = (PHEADER)EisaFreeTop; Buffer = (PVOID)(pHdr + 1); pHdr->m.id = Buffer; pHdr->m.size = EisaDynMemSize/sizeof(HEADER); EisaFreeMemory( Buffer ); return; } #endif // 0 // ---------------------------------------------------------------------------- // PROCEDURE: FwGetPath: // // DESCRIPTION: This function builds the path name for the specified // component. // // ARGUMENTS: Component Component pointer. // Str Path name pointer. // // RETURN: Str Path name pointer. // // ASSUMPTIONS: The string must be large enoungh to hold the // requested path name. // // CALLS: // // GLOBALS: // // NOTES: // ---------------------------------------------------------------------------- // PCHAR FwGetPath ( IN PCONFIGURATION_COMPONENT Component, OUT PCHAR Str ) { PCONFIGURATION_COMPONENT pComp; PRINTDBG("FwGetPath\n\r"); // DEBUG SUPPORT if ( (pComp = FwGetParent( Component )) != NULL ) { FwGetPath( pComp, Str); strcat( Str, FwGetMnemonic( Component ) ); sprintf( Str + strlen( Str ), "(%lu)", Component->Key); } else { *Str = '\0'; } return Str; } // ---------------------------------------------------------------------------- // PROCEDURE: FwDelCfgTreeNode: // // DESCRIPTION: This function removes from the configuration tree // the specified component and all its children. // // ARGUMENTS: pComp component pointer. // Peer = TRUE delete all its peers. // = FALSE delete just this branch. // // RETURN: none // // ASSUMPTIONS: // // CALLS: // // GLOBALS: // // NOTES: // ---------------------------------------------------------------------------- // VOID FwDelCfgTreeNode ( IN PCONFIGURATION_COMPONENT pComp, IN BOOLEAN Peer ) { // // define local variables // PCONFIGURATION_COMPONENT NextComp; PRINTDBG("FwDelCfgTreeNode\n\r"); // DEBUG SUPPORT // // check for a child // if ( (NextComp = FwGetChild( pComp )) != NULL ) { FwDelCfgTreeNode( NextComp, TRUE ); } // // check for a peer. // if ( Peer && (NextComp = FwGetPeer( pComp )) != NULL ) { FwDelCfgTreeNode( NextComp, TRUE ); } // // this is a leaf, delete it // FwDeleteComponent( pComp ); // // all done // return; } // ---------------------------------------------------------------------------- // PROCEDURE: FwGetMnemonic: // // DESCRIPTION: This function stores the mnemonic name for the // requested component type. // // ARGUMENTS: Component Component pointer. // // RETURN: Str Mnemonic pointer // // ASSUMPTIONS: none // // CALLS: // // GLOBALS: // // NOTES: // ---------------------------------------------------------------------------- // PCHAR FwGetMnemonic ( IN PCONFIGURATION_COMPONENT Component ) { PRINTDBG("FwGetMnemonic\n\r"); // DEBUG SUPPORT return MnemonicTable[Component->Type]; } // ---------------------------------------------------------------------------- // PROCEDURE: FwValidMnem: // // DESCRIPTION: This function validates the specified mnemonic. // If the mnemonic is valid, a TURE value is returned, // otherwise a FALSE is returned. // // ARGUMENTS: Str Mnemonic pointer // // RETURN: FALSE Mnemonic incorrect // TRUE Mnemonic correct // // ASSUMPTIONS: none // // CALLS: // // GLOBALS: // // NOTES: // ---------------------------------------------------------------------------- // BOOLEAN FwValidMnem ( IN PCHAR Str ) { // define local variables CONFIGURATION_TYPE CfgType; PRINTDBG("FwValidMnem\n\r"); // DEBUG SUPPORT // check the mnemonic table for ( CfgType = ArcSystem; CfgType < MaximumType && strcmp( MnemonicTable[ CfgType ], Str ); CfgType++ ); return CfgType < MaximumType ? TRUE : FALSE; } // ---------------------------------------------------------------------------- // GLOBAL: I/O functions variables // ---------------------------------------------------------------------------- PCHAR AsciiBlock; // pointer the ASCII block ULONG AsciiBlockLength = 0; // length of the ASCII block // ---------------------------------------------------------------------------- // PROCEDURE: FwStoreStr: // // DESCRIPTION: This function stores the specified string within // the ASCII block. The NULL pointer is returned if // there isn't space available for the string. // // ARGUMENTS: Str String pointer // // RETURN: Str String pointer // // ASSUMPTIONS: // // CALLS: // // GLOBALS: // // NOTES: // ---------------------------------------------------------------------------- // PCHAR FwStoreStr ( IN PCHAR Str ) { PRINTDBG("FwStoreStr\n\r"); // DEBUG SUPPORT // if not enough space, allocate new ASCII block if ( AsciiBlockLength < strlen( Str ) + 1 ) { if((AsciiBlock = (PUCHAR)FwAllocatePool(ASCII_BLOCK_SIZE)) == NULL) { return NULL; } } // store the string and update the pointers. Str = strcpy( AsciiBlock, Str ); AsciiBlock += strlen( Str ) + 1; AsciiBlockLength = ASCII_BLOCK_SIZE - (strlen( Str ) + 1); // all done, return the new string pointer return Str; }