NT4/private/ntos/boot/setup/arcdtect.c
2020-09-30 17:12:29 +02:00

554 lines
13 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
arcdtect.c
Abstract:
Provides HAL and SCSI detection for ARC-compliant machines.
Author:
John Vert (jvert) 21-Oct-1993
Revision History:
--*/
#include "setupldr.h"
#include <stdlib.h>
//
// Stuff used for detecting video
//
#define MAX_VIDEO_ADAPTERS 5
ULONG VideoAdapterCount;
PCONFIGURATION_COMPONENT_DATA VideoAdapter[MAX_VIDEO_ADAPTERS];
VOID
DecideVideoAdapter(
VOID
);
BOOLEAN FoundUnknownScsi;
//
// private function prototypes
//
PCHAR
SlpSearchSection(
IN PCHAR SectionName,
IN PCHAR TargetName
);
BOOLEAN
EnumerateSCSIAdapters(
IN PCONFIGURATION_COMPONENT_DATA ConfigData
);
BOOLEAN
EnumerateVideoAdapters(
IN PCONFIGURATION_COMPONENT_DATA ConfigData
);
PCHAR
SlDetectHal(
IN PSETUP_LOADER_BLOCK SetupBlock
)
/*++
Routine Description:
Determines the canonical short machine name for the HAL to be loaded for
this machine.
It does this by enumerating the [Map.Computer] section of the INF file and
comparing the strings there with the computer description in the ARC tree.
[Map.Computer]
msjazz_up = *Jazz
desksta1_up = "DESKTECH-ARCStation I"
pica61_up = "PICA-61"
duo_mp = *Duo
[Map.Computer]
DECjensen = "DEC-20Jensen"
DECjensen = "DEC-10Jensen"
Arguments:
SetupBlock - Supplies a pointer to the Setup loader block.
Return Value:
PCHAR - pointer to canonical shortname for the machine.
NULL - the type of machine could not be determined.
--*/
{
PCONFIGURATION_COMPONENT_DATA Node;
PCHAR MachineName;
//
// Find the system description node
//
Node = KeFindConfigurationEntry(BlLoaderBlock->ConfigurationRoot,
SystemClass,
ArcSystem,
NULL);
if (Node==NULL) {
SlError(0);
return(NULL);
}
MachineName = Node->ComponentEntry.Identifier;
return(MachineName ? SlpSearchSection("Map.Computer", MachineName) : NULL);
}
VOID
SlDetectScsi(
IN PSETUP_LOADER_BLOCK SetupBlock
)
/*++
Routine Description:
Detects SCSI adapters on an ARC machine by walking the ARC firmware tree.
Fills in the appropriate entries in the setuploaderblock
Arguments:
SetupBlock - Supplies a pointer to the setup loader block.
Return Value:
None.
--*/
{
FoundUnknownScsi = FALSE;
BlSearchConfigTree(BlLoaderBlock->ConfigurationRoot,
AdapterClass,
ScsiAdapter,
(ULONG)-1,
EnumerateSCSIAdapters);
if (FoundUnknownScsi) {
//
// We found at least one scsi device we didn't recognize,
// so force the OEM selection menu.
//
PromptOemScsi=TRUE;
}
SetupBlock->ScalarValues.LoadedScsi = 1;
}
BOOLEAN
EnumerateSCSIAdapters(
IN PCONFIGURATION_COMPONENT_DATA ConfigData
)
/*++
Routine Description:
Callback function for enumerating SCSI adapters in the ARC tree.
Adds the SCSI adapter that was found to the list of detected SCSI devices.
Arguments:
ConfigData - Supplies a pointer to the ARC node of the SCSI adapter.
Return Value:
TRUE - continue searching
FALSE - some error, abort the search
--*/
{
PDETECTED_DEVICE ScsiDevice;
PCHAR AdapterName;
ULONG Ordinal;
PCHAR ScsiFileName;
PCHAR ScsiDescription;
SCSI_INSERT_STATUS sis;
AdapterName = SlpSearchSection("Map.SCSI",ConfigData->ComponentEntry.Identifier);
if (AdapterName==NULL) {
//
// We found an adapter in the ARC tree, but it is not one of the ones
// specified in our INF file, so trigger the prompt for an OEM driver
// disk.
//
FoundUnknownScsi = TRUE;
return(TRUE);
}
//
// Find this adapter's ordinal within the Scsi.Load section of txtsetup.sif
//
Ordinal = SlGetSectionKeyOrdinal(InfFile, "Scsi.Load", AdapterName);
if(Ordinal == (ULONG)-1) {
FoundUnknownScsi = TRUE;
return(TRUE);
}
//
// Find the driver filename
//
ScsiFileName = SlGetSectionKeyIndex(InfFile,
"Scsi.Load",
AdapterName,
SIF_FILENAME_INDEX);
if(!ScsiFileName) {
FoundUnknownScsi = TRUE;
return(TRUE);
}
//
// Create a new detected device entry.
//
if((sis = SlInsertScsiDevice(Ordinal, &ScsiDevice)) == ScsiInsertError) {
SlFriendlyError(ENOMEM, "SCSI detection", 0, NULL);
return(FALSE);
}
if(sis == ScsiInsertExisting) {
#if DBG
//
// Sanity check to make sure we're talking about the same driver
//
if(_strcmpi(ScsiDevice->BaseDllName, ScsiFileName)) {
SlError(400);
return FALSE;
}
#endif
} else {
//
// Find the driver description
//
ScsiDescription = SlGetIniValue(InfFile,
"SCSI",
AdapterName,
AdapterName);
ScsiDevice->IdString = AdapterName;
ScsiDevice->Description = ScsiDescription;
ScsiDevice->ThirdPartyOptionSelected = FALSE;
ScsiDevice->FileTypeBits = 0;
ScsiDevice->Files = NULL;
ScsiDevice->BaseDllName = ScsiFileName;
}
return(TRUE);
}
VOID
SlDetectVideo(
IN PSETUP_LOADER_BLOCK SetupBlock
)
/*++
Routine Description:
Detects video adapters on an ARC machine by walking the ARC firmware tree.
Fills in the appropriate entries in the setuploaderblock
Arguments:
SetupBlock - Supplies a pointer to the setup loader block.
Return Value:
None.
--*/
{
//
// On arc machines, there is no default video type.
//
SetupBlock->VideoDevice.Next = NULL;
SetupBlock->VideoDevice.IdString = NULL;
SetupBlock->VideoDevice.ThirdPartyOptionSelected = FALSE;
SetupBlock->VideoDevice.FileTypeBits = 0;
SetupBlock->VideoDevice.Files = NULL;
SetupBlock->VideoDevice.BaseDllName = NULL;
SetupBlock->Monitor = NULL;
SetupBlock->MonitorId = NULL;
BlSearchConfigTree(BlLoaderBlock->ConfigurationRoot,
ControllerClass,
DisplayController,
(ULONG)-1,
EnumerateVideoAdapters);
DecideVideoAdapter();
}
BOOLEAN
EnumerateVideoAdapters(
IN PCONFIGURATION_COMPONENT_DATA ConfigData
)
/*++
Routine Description:
Callback function for enumerating video adapters in the ARC tree.
Adds the video adapter that was found to the setup block.
Arguments:
ConfigData - Supplies a pointer to the ARC node of the display adapter.
Return Value:
TRUE - continue searching
FALSE - some error, abort the search
--*/
{
//
// Just remember this guy for later.
//
if(VideoAdapterCount < MAX_VIDEO_ADAPTERS) {
VideoAdapter[VideoAdapterCount++] = ConfigData;
}
return(TRUE);
}
VOID
DecideVideoAdapter(
VOID
)
{
IN PCONFIGURATION_COMPONENT_DATA ConfigData;
PCHAR AdapterName,MonitorId;
PCONFIGURATION_COMPONENT_DATA MonitorData;
PMONITOR_CONFIGURATION_DATA Monitor;
CHAR ArcPath[256];
CHAR ConsoleOut[256];
PCHAR p,q;
ULONG u;
if(VideoAdapterCount) {
//
// The first thing we want to do is to see whether any of the
// adapters we found match the value of the CONSOLEOUT nvram var.
// If so then use that node for detection. Before comparing we have to
// change all instances of () to (0) in the value of CONSOLEOUT.
//
ConfigData = NULL;
if(p = ArcGetEnvironmentVariable("CONSOLEOUT")) {
strncpy(ArcPath,p,sizeof(ArcPath)-1);
ArcPath[sizeof(ArcPath)-1] = 0;
ConsoleOut[0] = 0;
for(p=ArcPath; q=strstr(p,"()"); p=q+2) {
*q = 0;
strcat(ConsoleOut,p);
strcat(ConsoleOut,"(0)");
}
strcat(ConsoleOut,p);
//
// Finally, we need to truncate the consoleout variable after
// the video adapter, if any.
//
_strlwr(ConsoleOut);
if(p = strstr(ConsoleOut,")video(")) {
*(p+sizeof(")video(")+1) = 0;
}
for(u=0; u<VideoAdapterCount; u++) {
ArcPath[0] = 0;
BlGetPathnameFromComponent(VideoAdapter[u],ArcPath);
if(!_stricmp(ConsoleOut,ArcPath)) {
ConfigData = VideoAdapter[u];
break;
}
}
}
//
// If we didn't find a match for CONSOLEOUT then use the last node
// we found in the tree scan.
//
if(!ConfigData) {
ConfigData = VideoAdapter[VideoAdapterCount-1];
}
AdapterName = SlpSearchSection("Map.Display",ConfigData->ComponentEntry.Identifier);
if (AdapterName==NULL) {
//
// We found a display adapter in the ARC tree, but it is not one of the ones
// specified in our INF file, so trigger the prompt for an OEM driver
// disk.
//
PromptOemVideo = TRUE;
return;
}
BlLoaderBlock->SetupLoaderBlock->VideoDevice.IdString = AdapterName;
BlLoaderBlock->SetupLoaderBlock->VideoDevice.Description = NULL;
BlLoaderBlock->SetupLoaderBlock->VideoDevice.ThirdPartyOptionSelected = FALSE;
BlLoaderBlock->SetupLoaderBlock->VideoDevice.FileTypeBits = 0;
BlLoaderBlock->SetupLoaderBlock->VideoDevice.Files = NULL;
BlLoaderBlock->SetupLoaderBlock->VideoDevice.BaseDllName = NULL;
//
// If there is a monitor peripheral associated with this device,
// capture its configuration data. Otherwise, let Setup assume an
// appropriate default.
//
MonitorData = ConfigData->Child;
if (MonitorData==NULL) {
BlLoaderBlock->SetupLoaderBlock->Monitor = NULL;
BlLoaderBlock->SetupLoaderBlock->MonitorId = NULL;
} else {
Monitor = BlAllocateHeap(MonitorData->ComponentEntry.ConfigurationDataLength);
if (Monitor==NULL) {
SlFriendlyError(ENOMEM, "video detection", 0, NULL);
return;
}
MonitorId = BlAllocateHeap(MonitorData->ComponentEntry.IdentifierLength+1);
if (MonitorId==NULL) {
SlFriendlyError(ENOMEM, "video detection", 0, NULL);
return;
}
strncpy(MonitorId,
MonitorData->ComponentEntry.Identifier,
MonitorData->ComponentEntry.IdentifierLength);
MonitorId[MonitorData->ComponentEntry.IdentifierLength] = 0;
RtlCopyMemory((PVOID)Monitor,
MonitorData->ConfigurationData,
MonitorData->ComponentEntry.ConfigurationDataLength);
BlLoaderBlock->SetupLoaderBlock->Monitor = Monitor;
BlLoaderBlock->SetupLoaderBlock->MonitorId = MonitorId;
}
}
}
PCHAR
SlpSearchSection(
IN PCHAR SectionName,
IN PCHAR TargetName
)
/*++
Routine Description:
Searches a section in the INF file to match a name from the ARC identifier
with the canonical shortname.
If a string starts with *, then use strstr to find it in the node's id
string, else use strcmpi.
[Map.Computer]
msjazz_up = *Jazz
desksta1_up = "DESKTECH-ARCStation I"
pica61_up = "PICA-61"
duo_mp = *Duo
[Map.Computer]
DECjensen = "DEC-20Jensen"
DECjensen = "DEC-10Jensen"
Arguments:
SectionName - Supplies the name of the section ("Map.Computer")
TargetName - Supplies the ARC string to be matched ("DEC-20Jensen")
Return Value:
NULL - No match was found.
PCHAR - Pointer to the canonical shortname of the device.
--*/
{
ULONG i;
PCHAR SearchName;
//
// Enumerate the entries in the section. If the 0 value
// begins with a *, then see if the system name contains the string that
// follows. Otherwise, do a case-insensitive compare on the name.
//
for (i=0;;i++) {
SearchName = SlGetSectionLineIndex(InfFile,
SectionName,
i,
0);
if (SearchName==NULL) {
//
// we have enumerated the entire section without finding a match,
// return failure.
//
return(NULL);
}
if (SearchName[0]=='*') {
if (strstr(TargetName,SearchName+1) != 0) {
//
// we have a match
//
break;
}
} else {
if (_stricmp(TargetName, SearchName) == 0) {
//
// we have a match
//
break;
}
}
}
//
// i is the index into the section of the short machine name
//
return(SlGetKeyName(InfFile,
SectionName,
i));
}