554 lines
13 KiB
C
554 lines
13 KiB
C
|
/*++
|
|||
|
|
|||
|
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));
|
|||
|
|
|||
|
|
|||
|
}
|