985 lines
26 KiB
C
985 lines
26 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
diskc.c
|
||
|
||
Abstract:
|
||
|
||
This is the NEC PD756 (aka AT, aka ISA, aka ix86) and Intel 82077
|
||
(aka MIPS) floppy diskette detection code for NT. This file also
|
||
collect BIOS disk drive parameters.
|
||
|
||
Author:
|
||
|
||
Shie-Lin Tzong (shielint) Dec-26-1991.
|
||
|
||
Environment:
|
||
|
||
x86 real mode.
|
||
|
||
Revision History:
|
||
|
||
|
||
Notes:
|
||
|
||
--*/
|
||
|
||
//
|
||
// Include files.
|
||
//
|
||
|
||
#include "hwdetect.h"
|
||
#include "disk.h"
|
||
#if defined(NEC_98)
|
||
#include "string.h"
|
||
#else // PC98
|
||
#include <string.h>
|
||
|
||
#endif // PC98
|
||
|
||
FPFWCONFIGURATION_COMPONENT_DATA
|
||
GetFloppyInformation(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine tries to get floppy configuration information.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
A pointer to a FPCONFIGURATION_COMPONENT_DATA is returned. It is
|
||
the head of floppy component tree root.
|
||
|
||
--*/
|
||
|
||
{
|
||
UCHAR DriveType;
|
||
FPUCHAR ParameterTable;
|
||
FPFWCONFIGURATION_COMPONENT_DATA CurrentEntry, PreviousEntry = NULL;
|
||
FPFWCONFIGURATION_COMPONENT_DATA FirstController = NULL;
|
||
FPFWCONFIGURATION_COMPONENT Component;
|
||
HWCONTROLLER_DATA ControlData;
|
||
UCHAR FloppyNumber = 0;
|
||
UCHAR DiskName[30];
|
||
UCHAR FloppyParmTable[FLOPPY_PARAMETER_TABLE_LENGTH];
|
||
FPUCHAR fpString;
|
||
USHORT Length, z;
|
||
ULONG MaxDensity = 0;
|
||
CM_FLOPPY_DEVICE_DATA far *FloppyData;
|
||
FPHWRESOURCE_DESCRIPTOR_LIST DescriptorList;
|
||
USHORT FloppyDataVersion;
|
||
|
||
#if defined(NEC_98)
|
||
USHORT DiskEquips;
|
||
USHORT Disk2HC;
|
||
UCHAR Counter = 0;
|
||
BOOLEAN FdIoLocked = FALSE;
|
||
UCHAR status;
|
||
UCHAR driveExchange;
|
||
|
||
DiskEquips = DISK_EQUIPS_FD;
|
||
Disk2HC = DISK_2HC;
|
||
|
||
if ( (COM_ID_L == 0x98) && (COM_ID_H == 0x21) &&
|
||
(ROM_FLAG7 & LOCKED_FD) ){
|
||
|
||
FdIoLocked = TRUE;
|
||
|
||
}
|
||
#endif // PC98
|
||
for (z = 0; z < FLOPPY_PARAMETER_TABLE_LENGTH; z++ ) {
|
||
FloppyParmTable[z] = 0;
|
||
}
|
||
|
||
//
|
||
// Initialize Controller data
|
||
//
|
||
|
||
ControlData.NumberPortEntries = 0;
|
||
ControlData.NumberIrqEntries = 0;
|
||
ControlData.NumberMemoryEntries = 0;
|
||
ControlData.NumberDmaEntries = 0;
|
||
z = 0;
|
||
|
||
//
|
||
// Allocate space for Controller component and initialize it.
|
||
//
|
||
|
||
CurrentEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
|
||
sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
|
||
FirstController = CurrentEntry;
|
||
Component = &CurrentEntry->ComponentEntry;
|
||
|
||
Component->Class = ControllerClass;
|
||
Component->Type = DiskController;
|
||
Component->Flags.Removable = 1;
|
||
Component->Flags.Input = 1;
|
||
Component->Flags.Output = 1;
|
||
Component->Version = 0;
|
||
Component->Key = 0;
|
||
Component->AffinityMask = 0xffffffff;
|
||
|
||
//
|
||
// Set up Port information
|
||
//
|
||
|
||
ControlData.NumberPortEntries = 1;
|
||
ControlData.DescriptorList[z].Type = RESOURCE_PORT;
|
||
ControlData.DescriptorList[z].ShareDisposition =
|
||
CmResourceShareDeviceExclusive;
|
||
ControlData.DescriptorList[z].Flags = CM_RESOURCE_PORT_IO;
|
||
#if defined(NEC_98)
|
||
ControlData.DescriptorList[z].u.Port.Start.LowPart = (ULONG)0x90;
|
||
#else // PC98
|
||
ControlData.DescriptorList[z].u.Port.Start.LowPart = (ULONG)0x3f0;
|
||
#endif // PC98
|
||
ControlData.DescriptorList[z].u.Port.Start.HighPart = (ULONG)0;
|
||
ControlData.DescriptorList[z].u.Port.Length = 8;
|
||
z++;
|
||
|
||
//
|
||
// Set up Irq information
|
||
//
|
||
|
||
ControlData.NumberIrqEntries = 1;
|
||
ControlData.DescriptorList[z].Type = RESOURCE_INTERRUPT;
|
||
ControlData.DescriptorList[z].ShareDisposition =
|
||
CmResourceShareUndetermined;
|
||
if (HwBusType == MACHINE_TYPE_MCA) {
|
||
ControlData.DescriptorList[z].Flags = LEVEL_SENSITIVE;
|
||
} else {
|
||
ControlData.DescriptorList[z].Flags = EDGE_TRIGGERED;
|
||
}
|
||
#if defined(NEC_98)
|
||
ControlData.DescriptorList[z].u.Interrupt.Level = 11;
|
||
ControlData.DescriptorList[z].u.Interrupt.Vector = 0x13;
|
||
#else // PC98
|
||
ControlData.DescriptorList[z].u.Interrupt.Level = 6;
|
||
ControlData.DescriptorList[z].u.Interrupt.Vector = 6;
|
||
#endif // PC98
|
||
ControlData.DescriptorList[z].u.Interrupt.Affinity = ALL_PROCESSORS;
|
||
z++;
|
||
|
||
//
|
||
// Set up DMA information. Only set channel number. Timming and
|
||
// transferSize are defaulted - 8 bits and ISA compatible.
|
||
//
|
||
|
||
ControlData.NumberDmaEntries = 1;
|
||
ControlData.DescriptorList[z].Type = RESOURCE_DMA;
|
||
ControlData.DescriptorList[z].ShareDisposition =
|
||
CmResourceShareUndetermined;
|
||
ControlData.DescriptorList[z].Flags = 0;
|
||
ControlData.DescriptorList[z].u.Dma.Channel = (ULONG)2;
|
||
ControlData.DescriptorList[z].u.Dma.Port = 0;
|
||
z++;
|
||
|
||
CurrentEntry->ConfigurationData =
|
||
HwSetUpResourceDescriptor(Component,
|
||
NULL,
|
||
&ControlData,
|
||
0,
|
||
NULL
|
||
);
|
||
|
||
#if _GAMBIT_
|
||
//
|
||
// Supply the DriveTypeValue that is supplied by the following IA
|
||
// assembly programs.
|
||
//
|
||
DriveType = 0;
|
||
FloppyDataVersion = 0;
|
||
ParameterTable = NULL;
|
||
|
||
//
|
||
// Collect disk peripheral data
|
||
//
|
||
|
||
while (1) {
|
||
#else
|
||
#if defined(NEC_98)
|
||
|
||
DriveType = 0;
|
||
FloppyDataVersion = 0;
|
||
driveExchange = 0;
|
||
|
||
if ( DiskEquips & 0x0F ) {
|
||
|
||
//
|
||
// Check drive exchange.
|
||
//
|
||
status = READ_PORT_UCHAR((PUCHAR)0x94) & 0x04;
|
||
|
||
if ( status == 0 ) {
|
||
|
||
//
|
||
// internal drive is #3/#4.
|
||
//
|
||
driveExchange = 1;
|
||
}
|
||
}
|
||
|
||
if ( !(FdIoLocked) && Counter < 4 ){
|
||
|
||
if ( DiskEquips & (1 << Counter ) ){
|
||
|
||
//
|
||
// Check internal drive or extension drive.
|
||
//
|
||
|
||
if ( (Counter / (UCHAR)2) == driveExchange ) {
|
||
if (Disk2HC & (1 << Counter)) {
|
||
//
|
||
// 1.44MB drive
|
||
//
|
||
DriveType = 4;
|
||
|
||
} else {
|
||
//
|
||
// 1.2MB drive
|
||
//
|
||
DriveType = 2;
|
||
}
|
||
|
||
} else {
|
||
//
|
||
// 1.2MB extension drive.
|
||
//
|
||
DriveType = 7;
|
||
}
|
||
|
||
Counter++;
|
||
|
||
} else {
|
||
Counter++;
|
||
continue;
|
||
}
|
||
}
|
||
|
||
#else // PC98
|
||
_asm {
|
||
push es
|
||
|
||
mov DriveType, 0
|
||
mov FloppyDataVersion, CURRENT_FLOPPY_DATA_VERSION
|
||
|
||
mov ah, 15h
|
||
mov dl, FloppyNumber
|
||
int 13h
|
||
jc short CmosTest
|
||
|
||
cmp ah, 0
|
||
je short Exit
|
||
|
||
cmp ah, 2 ; make sure this is floppy
|
||
ja short Exit
|
||
|
||
mov ah, 8
|
||
mov dl, FloppyNumber
|
||
lea di, word ptr FloppyParmTable ; use 'word ptr' to quiet compiler
|
||
push ds
|
||
pop es ; (es:di)->dummy FloppyParmTable
|
||
int 13h
|
||
jc short CmosTest
|
||
|
||
mov DriveType, bl
|
||
mov ax, es
|
||
mov word ptr ParameterTable + 2, ax
|
||
mov word ptr ParameterTable, di
|
||
jmp short Exit
|
||
|
||
CmosTest:
|
||
|
||
;
|
||
; if int 13 fails, we know that floppy drive is present.
|
||
; So, we try to get the Drive Type from CMOS.
|
||
;
|
||
|
||
mov al, CMOS_FLOPPY_CONFIG_BYTE
|
||
mov dx, CMOS_CONTROL_PORT ; address port
|
||
out dx, al
|
||
jmp $ + 2 ; I/O DELAY
|
||
mov dx, CMOS_DATA_PORT ; READ IN REQUESTED CMOS DATA
|
||
in al, dx
|
||
jmp $ + 2 ; I/O DELAY
|
||
|
||
cmp FloppyNumber, 0
|
||
jne short CmosTest1
|
||
|
||
and al, 0xf0
|
||
shr al, 4
|
||
jmp short CmosTest2
|
||
|
||
CmosTest1:
|
||
cmp FloppyNumber, 1
|
||
jne short Exit
|
||
|
||
and al, 0xf
|
||
CmosTest2:
|
||
mov DriveType, al
|
||
mov FloppyDataVersion, 0
|
||
Exit:
|
||
pop es
|
||
}
|
||
#endif // PC98
|
||
#endif // _GAMBIT_
|
||
|
||
if (DriveType) {
|
||
|
||
//
|
||
// Allocate space for first pripheral component and initialize it.
|
||
//
|
||
|
||
CurrentEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
|
||
sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
|
||
|
||
Component = &CurrentEntry->ComponentEntry;
|
||
|
||
Component->Class = PeripheralClass;
|
||
Component->Type = FloppyDiskPeripheral;
|
||
Component->Version = 0;
|
||
Component->Key = FloppyNumber;
|
||
Component->AffinityMask = 0xffffffff;
|
||
Component->ConfigurationDataLength = 0;
|
||
|
||
//
|
||
// Set up type string.
|
||
//
|
||
|
||
strcpy(DiskName, "FLOPPYx");
|
||
DiskName[6] = FloppyNumber + (UCHAR)'1';
|
||
Length = strlen(DiskName) + 1;
|
||
fpString = (FPUCHAR)HwAllocateHeap(Length, FALSE);
|
||
_fstrcpy(fpString, DiskName);
|
||
Component->IdentifierLength = Length;
|
||
Component->Identifier = fpString;
|
||
|
||
//
|
||
// Set up floppy device specific data
|
||
//
|
||
|
||
switch (DriveType) {
|
||
case 1:
|
||
MaxDensity = 360;
|
||
break;
|
||
case 2:
|
||
MaxDensity = 1200;
|
||
break;
|
||
case 3:
|
||
MaxDensity = 720;
|
||
break;
|
||
case 4:
|
||
MaxDensity = 1440;
|
||
break;
|
||
case 5:
|
||
case 6:
|
||
MaxDensity = 2880;
|
||
break;
|
||
#if defined(NEC_98)
|
||
case 7:
|
||
MaxDensity = 1201;
|
||
break;
|
||
#endif
|
||
default:
|
||
MaxDensity = 0;
|
||
break;
|
||
}
|
||
if (FloppyDataVersion == CURRENT_FLOPPY_DATA_VERSION) {
|
||
Length = sizeof(CM_FLOPPY_DEVICE_DATA);
|
||
} else {
|
||
Length = (SHORT)&(((CM_FLOPPY_DEVICE_DATA*)0)->StepRateHeadUnloadTime);
|
||
}
|
||
DescriptorList = (FPHWRESOURCE_DESCRIPTOR_LIST)HwAllocateHeap(
|
||
Length + sizeof(HWRESOURCE_DESCRIPTOR_LIST),
|
||
TRUE);
|
||
CurrentEntry->ConfigurationData = DescriptorList;
|
||
Component->ConfigurationDataLength =
|
||
Length + sizeof(HWRESOURCE_DESCRIPTOR_LIST);
|
||
DescriptorList->Count = 1;
|
||
DescriptorList->PartialDescriptors[0].Type = RESOURCE_DEVICE_DATA;
|
||
DescriptorList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
|
||
Length;
|
||
FloppyData = (CM_FLOPPY_DEVICE_DATA far *)(DescriptorList + 1);
|
||
FloppyData->MaxDensity = MaxDensity;
|
||
FloppyData->Version = FloppyDataVersion;
|
||
if (FloppyDataVersion == CURRENT_FLOPPY_DATA_VERSION) {
|
||
_fmemcpy((FPCHAR)&FloppyData->StepRateHeadUnloadTime,
|
||
ParameterTable,
|
||
sizeof(CM_FLOPPY_DEVICE_DATA) -
|
||
(SHORT)&(((CM_FLOPPY_DEVICE_DATA*)0)->StepRateHeadUnloadTime)
|
||
);
|
||
}
|
||
if (FloppyNumber == 0) {
|
||
FirstController->Child = CurrentEntry;
|
||
} else {
|
||
PreviousEntry->Sibling = CurrentEntry;
|
||
}
|
||
CurrentEntry->Parent = FirstController;
|
||
PreviousEntry = CurrentEntry;
|
||
FloppyNumber++;
|
||
} else {
|
||
|
||
//
|
||
// This is a *hack* for ntldr. Here we create a arc name for
|
||
// each bios disks such that ntldr can open them.
|
||
//
|
||
|
||
if (NumberBiosDisks != 0) {
|
||
|
||
for (z = 0; z < NumberBiosDisks; z++) {
|
||
|
||
//
|
||
// Allocate space for disk peripheral component
|
||
//
|
||
|
||
CurrentEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
|
||
sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
|
||
|
||
Component = &CurrentEntry->ComponentEntry;
|
||
|
||
Component->Class = PeripheralClass;
|
||
Component->Type = DiskPeripheral;
|
||
Component->Flags.Input = 1;
|
||
Component->Flags.Output = 1;
|
||
Component->Version = 0;
|
||
Component->Key = z;
|
||
Component->AffinityMask = 0xffffffff;
|
||
|
||
//
|
||
// Set up identifier string = 8 digit signature - 8 digit checksum
|
||
// for example: 00fe964d-005467dd
|
||
//
|
||
|
||
GetDiskId((USHORT)(0x80 + z), DiskName);
|
||
if (DiskName[0] == (UCHAR)NULL) {
|
||
strcpy(DiskName, "BIOSDISKx");
|
||
DiskName[8] = (UCHAR)z + (UCHAR)'1';
|
||
}
|
||
Length = strlen(DiskName) + 1;
|
||
fpString = (FPUCHAR)HwAllocateHeap(Length, FALSE);
|
||
_fstrcpy(fpString, DiskName);
|
||
Component->IdentifierLength = Length;
|
||
Component->Identifier = fpString;
|
||
|
||
#if defined(NEC_98)
|
||
#else // PC98
|
||
#if !defined(_GAMBIT_)
|
||
//
|
||
// Set up BIOS disk device specific data.
|
||
// (If extended int 13 drive parameters are supported by
|
||
// BIOS, we will collect them and store them here.)
|
||
//
|
||
|
||
if (IsExtendedInt13Available(0x80+z)) {
|
||
DescriptorList = (FPHWRESOURCE_DESCRIPTOR_LIST)HwAllocateHeap(
|
||
sizeof(HWRESOURCE_DESCRIPTOR_LIST) +
|
||
sizeof(CM_DISK_GEOMETRY_DEVICE_DATA),
|
||
TRUE);
|
||
Length = GetExtendedDriveParameters(
|
||
0x80 + z,
|
||
(CM_DISK_GEOMETRY_DEVICE_DATA far *)(DescriptorList + 1)
|
||
);
|
||
if (Length) {
|
||
CurrentEntry->ConfigurationData = DescriptorList;
|
||
Component->ConfigurationDataLength =
|
||
Length + sizeof(HWRESOURCE_DESCRIPTOR_LIST);
|
||
DescriptorList->Count = 1;
|
||
DescriptorList->PartialDescriptors[0].Type = RESOURCE_DEVICE_DATA;
|
||
DescriptorList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
|
||
Length;
|
||
} else {
|
||
HwFreeHeap(sizeof(HWRESOURCE_DESCRIPTOR_LIST) +
|
||
sizeof(CM_DISK_GEOMETRY_DEVICE_DATA));
|
||
}
|
||
}
|
||
#endif // _GAMBIT_
|
||
#endif // PC98
|
||
|
||
if (PreviousEntry == NULL) {
|
||
FirstController->Child = CurrentEntry;
|
||
} else {
|
||
PreviousEntry->Sibling = CurrentEntry;
|
||
}
|
||
CurrentEntry->Parent = FirstController;
|
||
PreviousEntry = CurrentEntry;
|
||
}
|
||
}
|
||
return(FirstController);
|
||
}
|
||
}
|
||
}
|
||
|
||
VOID
|
||
GetDiskId(
|
||
USHORT Disk,
|
||
PUCHAR Identifier
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine reads the master boot sector of the specified harddisk drive,
|
||
compute the checksum of the sector to form a drive identifier.
|
||
|
||
The identifier will be set to "8-digit-checksum"+"-"+"8-digit-signature"
|
||
For example: 00ff6396-6549071f
|
||
|
||
Arguments:
|
||
|
||
Disk - supplies the BIOS drive number, i.e. 80h - 87h
|
||
|
||
Identifier - Supplies a buffer to receive the disk id.
|
||
|
||
Return Value:
|
||
|
||
None. In the worst case, the Identifier will be empty.
|
||
|
||
--*/
|
||
|
||
{
|
||
#if defined(_GAMBIT_)
|
||
Identifier = NULL;
|
||
#else
|
||
#if defined(NEC_98)
|
||
USHORT BootRecordSignature; // Boot Record Signature (0x55aa)
|
||
UCHAR diskNumber;
|
||
UCHAR Sector[1024];
|
||
#else // PC98
|
||
UCHAR Sector[512];
|
||
#endif // PC98
|
||
ULONG Signature, Checksum;
|
||
USHORT i, Length;
|
||
PUCHAR BufferAddress;
|
||
BOOLEAN Fail;
|
||
|
||
Identifier[0] = 0;
|
||
BufferAddress = &Sector[0];
|
||
Fail = FALSE;
|
||
|
||
//
|
||
// Read in the first sector
|
||
//
|
||
|
||
#if defined(NEC_98)
|
||
//
|
||
// We can't access over 4GB except relative access.
|
||
// Therefore we use a relative(Sequential) access.
|
||
//
|
||
Disk &= 0x7F;
|
||
diskNumber = (UCHAR)Disk;
|
||
|
||
//
|
||
// Read sectors (NTFS Signature)
|
||
//
|
||
_asm {
|
||
push es
|
||
mov ah, 0x06 // Disk read command
|
||
mov al, diskNumber // Disk No (00,01)
|
||
mov bx, 512 // Data length
|
||
mov cx, 0x10 // Sector LSW
|
||
mov dx, 0x00 // Sector HSW
|
||
push ss
|
||
pop es
|
||
push bp
|
||
mov bp, BufferAddress // ES:BP Buffer address
|
||
int 0x1b
|
||
pop bp
|
||
pop es
|
||
jnc Gdi000
|
||
|
||
mov Fail, 1
|
||
Gdi000:
|
||
}
|
||
#else // PC98
|
||
_asm {
|
||
push es
|
||
mov ax, 0x201
|
||
mov cx, 1
|
||
mov dx, Disk
|
||
push ss
|
||
pop es
|
||
mov bx, BufferAddress
|
||
int 0x13
|
||
pop es
|
||
jnc Gdixxx
|
||
|
||
mov Fail, 1
|
||
Gdixxx:
|
||
}
|
||
#endif // PC98
|
||
|
||
if (Fail) {
|
||
#if DBG
|
||
// could not get the sector, so return NULL DiskID
|
||
BlPrint("Failed to read sector -- returning NULL DiskId\n");
|
||
#endif
|
||
return;
|
||
}
|
||
|
||
#if defined(NEC_98)
|
||
//
|
||
// Get the NTFS Sinature
|
||
//
|
||
if (((PUSHORT)Sector)[BOOT_SIGNATURE_OFFSET] != BOOT_RECORD_SIGNATURE) {
|
||
Signature = 0;
|
||
} else {
|
||
Signature = ((PULONG)Sector)[0];
|
||
}
|
||
#else // PC98
|
||
Signature = ((PULONG)Sector)[PARTITION_TABLE_OFFSET/2-1];
|
||
#endif // PC98
|
||
|
||
//
|
||
// compute the checksum
|
||
//
|
||
#if defined(NEC_98)
|
||
//
|
||
// Read No 0 and 1 sectors. (for Check Sum)
|
||
//
|
||
_asm {
|
||
push es
|
||
mov ah, 0x06 // Disk read command
|
||
mov al, diskNumber // Disk No (00,01)
|
||
mov bx, 512 * 2 // Data length
|
||
mov cx, 0x00 // Sector LSW
|
||
mov dx, 0x00 // Sector HSW
|
||
push ss
|
||
pop es
|
||
push bp
|
||
mov bp, BufferAddress // ES:BP Buffer address
|
||
int 1bh
|
||
pop bp
|
||
pop es
|
||
jnc Gdi001
|
||
|
||
mov Fail, 1
|
||
Gdi001:
|
||
}
|
||
|
||
|
||
if (Fail) {
|
||
return;
|
||
}
|
||
#endif // PC98
|
||
|
||
|
||
Checksum = 0;
|
||
for (i = 0; i < 128; i++) {
|
||
#if defined(NEC_98)
|
||
Checksum += ((PULONG)Sector)[ i + 512/4 ];
|
||
#else // PC98
|
||
Checksum += ((PULONG)Sector)[i];
|
||
#endif // PC98
|
||
}
|
||
Checksum = -Checksum;
|
||
|
||
//
|
||
// Zero the identifier
|
||
//
|
||
|
||
for (i=0; i < 30; i++) {
|
||
Identifier[i]='0';
|
||
}
|
||
|
||
//
|
||
// Put the dashes in the right places.
|
||
//
|
||
|
||
Identifier[8] = '-';
|
||
Identifier[17] = '-';
|
||
|
||
//
|
||
// If the boot sector has a valid partition table signature,
|
||
// attach an 'A.' Otherwise we use 'X.'
|
||
//
|
||
|
||
if (((PUSHORT)Sector)[BOOT_SIGNATURE_OFFSET] != BOOT_RECORD_SIGNATURE) {
|
||
Identifier[18]='X';
|
||
} else {
|
||
Identifier[18]='A';
|
||
}
|
||
|
||
//
|
||
// Reuse sector buffer to build checksum string.
|
||
//
|
||
|
||
ultoa(Checksum, Sector, 16);
|
||
Length = strlen(Sector);
|
||
|
||
for (i=0; i<Length; i++) {
|
||
Identifier[7-i] = Sector[Length-i-1];
|
||
}
|
||
|
||
//
|
||
// Reuse sector buffer to build signature string.
|
||
//
|
||
|
||
ultoa(Signature, Sector, 16);
|
||
Length = strlen(Sector);
|
||
|
||
for (i=0; i<Length; i++) {
|
||
Identifier[16-i] = Sector[Length-i-1];
|
||
}
|
||
|
||
//
|
||
// Terminate string.
|
||
//
|
||
|
||
Identifier[19] = 0;
|
||
|
||
#if DBG
|
||
BlPrint("%s\n", Identifier);
|
||
#endif
|
||
|
||
#endif // _GAMBIT_
|
||
}
|
||
|
||
|
||
#if defined(NEC_98)
|
||
//
|
||
// This section was used to get some SCSI disks' information connecting to
|
||
// SCSI board that is includeing boot up disk.
|
||
//
|
||
// These information was very important when do FD-less setup.
|
||
//
|
||
// When the HIPER SCSI BIOS for array disk is abailable, it is useing a
|
||
// trick to show two scsi board as one scsi board accessing through BIOS
|
||
// functions.
|
||
//
|
||
// We must separete information per board from the two boards' information.
|
||
//
|
||
|
||
BOOLEAN
|
||
BootedFromScsiDisk(
|
||
PUSHORT pFakeScsiId,
|
||
PUSHORT pNumberScsiDisks,
|
||
PUSHORT pScsiDisksMap
|
||
)
|
||
{
|
||
|
||
USHORT DauaBootedFrom;
|
||
USHORT StartPosition = 0;
|
||
USHORT EndPosition = SCSI_MAX_ID;
|
||
USHORT tmp, i;
|
||
|
||
|
||
DauaBootedFrom = DAUA_BOOTED_FROM;
|
||
|
||
*pFakeScsiId = 0;
|
||
*pNumberScsiDisks = 0;
|
||
*pScsiDisksMap = DISK_EQUIPS_SCSI;
|
||
|
||
if (!(DauaBootedFrom & DASCSI)){
|
||
return (FALSE);
|
||
}
|
||
|
||
|
||
if ((EQUIPS_47Ch == (USHORT)0) && ((*pScsiDisksMap & 0x80) == 0)) {
|
||
//
|
||
// Array SCSI BIOS was available.
|
||
//
|
||
|
||
if (H_DISK_EQUIPS_L != (USHORT)0){ // we do not need high byte.
|
||
|
||
tmp = H_EQUIPS;
|
||
for ( i = 0; i < SCSI_MAX_ID; i++ ){
|
||
if ( tmp & (1 << i)) (*pFakeScsiId)++;
|
||
}
|
||
|
||
if ( (DauaBootedFrom & UA_MASK) >= *pFakeScsiId ){
|
||
//
|
||
// System was booted from disk connected array scsi card.
|
||
//
|
||
|
||
StartPosition = *pFakeScsiId;
|
||
EndPosition = SCSI_MAX_ID;
|
||
|
||
} else {
|
||
//
|
||
// System was booted from disk connected normal scsi card.
|
||
//
|
||
|
||
StartPosition = 0;
|
||
EndPosition = *pFakeScsiId;
|
||
*pFakeScsiId = 0; // Reset
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
for ( i = StartPosition; i < EndPosition; i++ ){
|
||
if ( *pScsiDisksMap & (1 << i)) (*pNumberScsiDisks)++;
|
||
}
|
||
|
||
*pFakeScsiId |= 0xA0;
|
||
|
||
return(TRUE);
|
||
}
|
||
|
||
|
||
FPFWCONFIGURATION_COMPONENT_DATA
|
||
GetScsiDiskInformation(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine tries to get SCSI Disk configuration information.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
A pointer to a FPCONFIGURATION_COMPONENT_DATA is returned. It is
|
||
the head of floppy component tree root.
|
||
|
||
--*/
|
||
|
||
{
|
||
FPFWCONFIGURATION_COMPONENT_DATA ControllerEntry, PreviousEntry = NULL;
|
||
FPFWCONFIGURATION_COMPONENT_DATA PeripheralEntry;
|
||
FPFWCONFIGURATION_COMPONENT_DATA FirstController = NULL;
|
||
FPFWCONFIGURATION_COMPONENT_DATA AdapterEntry;
|
||
FPFWCONFIGURATION_COMPONENT Component;
|
||
CHAR Identifier[256];
|
||
UCHAR DiskName[30];
|
||
FPUCHAR fpString;
|
||
USHORT Length;
|
||
FPCHAR IdentifierString;
|
||
|
||
USHORT DiskCount, Id;
|
||
|
||
USHORT FakeScsiId;
|
||
USHORT NumberScsiDisks;
|
||
USHORT ScsiDisksMap;
|
||
|
||
|
||
if (!BootedFromScsiDisk( &FakeScsiId, &NumberScsiDisks, &ScsiDisksMap )){
|
||
return (NULL);
|
||
}
|
||
|
||
//
|
||
// Allocate space for Controller component and initialize it.
|
||
//
|
||
|
||
AdapterEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
|
||
sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
|
||
FirstController = AdapterEntry;
|
||
|
||
Component = &AdapterEntry->ComponentEntry;
|
||
Component->Class = AdapterClass;
|
||
Component->Type = ScsiAdapter;
|
||
|
||
strcpy (Identifier, "SCSI");
|
||
Length = strlen(Identifier) + 1;
|
||
IdentifierString = (FPCHAR)HwAllocateHeap(Length, FALSE);
|
||
_fstrcpy(IdentifierString, Identifier);
|
||
|
||
Component->Version = 0;
|
||
Component->Key = 0;
|
||
Component->AffinityMask = 0xffffffff;
|
||
Component->IdentifierLength = Length;
|
||
Component->Identifier = IdentifierString;
|
||
|
||
AdapterEntry->ConfigurationData = NULL;
|
||
Component->ConfigurationDataLength = 0;
|
||
|
||
for ( DiskCount = 0, Id = 0; DiskCount < NumberScsiDisks && Id < 7 ; Id++ ) {
|
||
|
||
if ( !(ScsiDisksMap & (1 << (FakeScsiId + Id)))){
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// Allocate space for disk peripheral component
|
||
//
|
||
|
||
ControllerEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
|
||
sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
|
||
|
||
Component = &ControllerEntry->ComponentEntry;
|
||
|
||
Component->Class = ControllerClass;
|
||
Component->Type = DiskController;
|
||
Component->Flags.Input = 1;
|
||
Component->Flags.Output = 1;
|
||
Component->Version = 0;
|
||
Component->Key = Id;
|
||
Component->AffinityMask = 0xffffffff;
|
||
|
||
ControllerEntry->ConfigurationData = NULL;
|
||
|
||
//
|
||
// Set up identifier string = 8 digit signature - 8 digit checksum
|
||
// for example: 00fe964d-005467dd
|
||
//
|
||
|
||
GetDiskId(FakeScsiId + Id, DiskName);
|
||
if (DiskName[0] == (UCHAR)NULL) {
|
||
strcpy(DiskName, "BIOSDISKx");
|
||
DiskName[8] = (UCHAR)DiskCount + (UCHAR)'1';
|
||
}
|
||
Length = strlen(DiskName) + 1;
|
||
fpString = (FPUCHAR)HwAllocateHeap(Length, FALSE);
|
||
_fstrcpy(fpString, DiskName);
|
||
Component->IdentifierLength = Length;
|
||
Component->Identifier = fpString;
|
||
|
||
|
||
//
|
||
// Create Peripheral Entry
|
||
//
|
||
|
||
PeripheralEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
|
||
sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
|
||
|
||
Component = &PeripheralEntry->ComponentEntry;
|
||
Component->Class = PeripheralClass;
|
||
Component->Type = DiskPeripheral;
|
||
Component->Flags.Input = 1;
|
||
Component->Flags.Output = 1;
|
||
Component->Version = 0;
|
||
Component->Key = 0;
|
||
Component->AffinityMask = 0xffffffff;
|
||
|
||
PeripheralEntry->ConfigurationData = NULL;
|
||
|
||
Component->IdentifierLength = Length;
|
||
Component->Identifier = fpString;
|
||
|
||
PeripheralEntry->Parent = ControllerEntry;
|
||
ControllerEntry->Child = PeripheralEntry;
|
||
|
||
|
||
if (PreviousEntry == NULL) {
|
||
FirstController->Child = ControllerEntry;
|
||
} else {
|
||
PreviousEntry->Sibling = ControllerEntry;
|
||
}
|
||
|
||
ControllerEntry->Parent = FirstController;
|
||
PreviousEntry = ControllerEntry;
|
||
|
||
DiskCount++;
|
||
}
|
||
|
||
return(FirstController);
|
||
}
|
||
|
||
#endif // PC98
|