Annotation of ntddk/src/scsi/atdisk/i386/atd_conf.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1991, 1992, 1993  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     i386\atd_conf.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This file includes the routine to get ix86 platform-dependent
        !            12:     configuration information for the AT disk (aka ST506, ISA, and ix86
        !            13:     standard hard disk) driver for NT.
        !            14: 
        !            15:     If this driver is ported to a different platform, this file (and
        !            16:     atd_plat.h) will need to be modified extensively.  The build
        !            17:     procedure should make sure that the proper version of this file is
        !            18:     available as atd_conf.h (which is included by atdisk.c) when
        !            19:     building for a specific platform.
        !            20: 
        !            21: Author:
        !            22: 
        !            23:     Chad Schwitters (chads) 21-Feb-1991.
        !            24: 
        !            25: Environment:
        !            26: 
        !            27:     Kernel mode only.
        !            28: 
        !            29: Notes:
        !            30: 
        !            31: Revision History:
        !            32: 
        !            33: --*/
        !            34: 
        !            35: #include "ntddk.h"                  // various NT definitions
        !            36: #include "ntdddisk.h"               // disk device driver I/O control codes
        !            37: #include <atd_plat.h>               // this driver's platform dependent stuff
        !            38: #include <atd_data.h>               // this driver's data declarations
        !            39: 
        !            40: NTSTATUS
        !            41: AtConfigCallBack(
        !            42:     IN PVOID Context,
        !            43:     IN PUNICODE_STRING PathName,
        !            44:     IN INTERFACE_TYPE BusType,
        !            45:     IN ULONG BusNumber,
        !            46:     IN PKEY_VALUE_FULL_INFORMATION *BusInformation,
        !            47:     IN CONFIGURATION_TYPE ControllerType,
        !            48:     IN ULONG ControllerNumber,
        !            49:     IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
        !            50:     IN CONFIGURATION_TYPE PeripheralType,
        !            51:     IN ULONG PeripheralNumber,
        !            52:     IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation
        !            53:     );
        !            54: 
        !            55: BOOLEAN
        !            56: UpdateGeometryFromBios(
        !            57:     PDRIVER_OBJECT DriverObject,
        !            58:     DRIVE_DATA *DriveData,
        !            59:     ULONG DiskNumber
        !            60:     );
        !            61: 
        !            62: BOOLEAN
        !            63: UpdateGeometryFromParameterTable(
        !            64:     DRIVE_DATA *DriveData,
        !            65:     CCHAR *ControlFlags,
        !            66:     ULONG ParameterTableOffset
        !            67:     );
        !            68: 
        !            69: BOOLEAN
        !            70: GetGeometryFromIdentify(
        !            71:     PCONTROLLER_DATA ControllerData,
        !            72:     ULONG DiskNumber
        !            73:     );
        !            74: 
        !            75: BOOLEAN
        !            76: IssueIdentify(
        !            77:     PCONTROLLER_DATA ControllerData,
        !            78:     PUCHAR Buffer,
        !            79:     ULONG DiskNumber
        !            80:     );
        !            81: 
        !            82: #ifdef ALLOC_PRAGMA
        !            83: #pragma alloc_text(init,AtConfigCallBack)
        !            84: #pragma alloc_text(init,AtGetConfigInfo)
        !            85: #pragma alloc_text(init,UpdateGeometryFromBios)
        !            86: #pragma alloc_text(init,UpdateGeometryFromParameterTable)
        !            87: #endif
        !            88: 
        !            89: 
        !            90: NTSTATUS
        !            91: AtConfigCallBack(
        !            92:     IN PVOID Context,
        !            93:     IN PUNICODE_STRING PathName,
        !            94:     IN INTERFACE_TYPE BusType,
        !            95:     IN ULONG BusNumber,
        !            96:     IN PKEY_VALUE_FULL_INFORMATION *BusInformation,
        !            97:     IN CONFIGURATION_TYPE ControllerType,
        !            98:     IN ULONG ControllerNumber,
        !            99:     IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
        !           100:     IN CONFIGURATION_TYPE PeripheralType,
        !           101:     IN ULONG PeripheralNumber,
        !           102:     IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation
        !           103:     )
        !           104: 
        !           105: /*++
        !           106: 
        !           107: Routine Description:
        !           108: 
        !           109:     This routine is used to acquire all of the configuration
        !           110:     information for each floppy disk controller and the
        !           111:     peripheral driver attached to that controller.
        !           112: 
        !           113: Arguments:
        !           114: 
        !           115:     Context - Pointer to boolean.
        !           116: 
        !           117:     PathName - unicode registry path.  Not Used.
        !           118: 
        !           119:     BusType - Internal, Isa, ...
        !           120: 
        !           121:     BusNumber - Should Always be zero.
        !           122: 
        !           123:     BusInformation - Configuration information about the bus. Not Used.
        !           124: 
        !           125:     ControllerType - Controller Type. Not Used.
        !           126: 
        !           127:     ControllerNumber - Which controller if there is more than one
        !           128:                        controller in the system. Not Used
        !           129: 
        !           130:     ControllerInformation - Array of pointers to the three pieces of
        !           131:                             registry information. Not Used
        !           132: 
        !           133:     PeripheralType - Peripheral Type. Not Used.
        !           134: 
        !           135:     PeripheralNumber - Which floppy if this controller is maintaining
        !           136:                        more than one. Not Used
        !           137: 
        !           138:     PeripheralInformation - Arrya of pointers to the three pieces of
        !           139:                             registry information. Not Used.
        !           140: 
        !           141: Return Value:
        !           142: 
        !           143:     STATUS_SUCCESS
        !           144: 
        !           145: --*/
        !           146: 
        !           147: {
        !           148: 
        !           149:     ASSERT(BusNumber == 0);
        !           150:     *((PBOOLEAN)Context) = TRUE;
        !           151:     return STATUS_SUCCESS;
        !           152: 
        !           153: }
        !           154: 
        !           155: NTSTATUS
        !           156: AtGetConfigInfo(
        !           157:     IN PDRIVER_OBJECT DriverObject,
        !           158:     IN PUNICODE_STRING RegistryPath,
        !           159:     IN OUT PCONFIG_DATA ConfigData
        !           160:     )
        !           161: 
        !           162: /*++
        !           163: 
        !           164: Routine Description:
        !           165: 
        !           166:     This routine is called once at initialization time by
        !           167:     AtDiskInitialize() to get information about the disks that are to be
        !           168:     supported.
        !           169: 
        !           170:     Some values here are simply assumed (i.e. number of controllers, and
        !           171:     base address of controller).  Other are determined by poking CMOS
        !           172:     (i.e. how many drives are on the controller) or by peering into ROM (i.e.
        !           173:     sectors per track for each drive).
        !           174: 
        !           175: Arguments:
        !           176: 
        !           177:     DriverObject - The driver object for this driver.
        !           178: 
        !           179:     RegistryPath - The string that takes us to this drivers service node.
        !           180: 
        !           181:     ConfigData - a pointer to the pointer to a data structure that
        !           182:     describes the controllers and the disks attached to them
        !           183: 
        !           184: Return Value:
        !           185: 
        !           186:     Returns STATUS_SUCCESS unless there is no drive 0.
        !           187: 
        !           188: --*/
        !           189: 
        !           190: {
        !           191:     ULONG paramTable;
        !           192:     PUSHORT paramVector;
        !           193:     UCHAR *namePointer;
        !           194:     ULONG i, j, k;
        !           195:     UCHAR configuredIrq;
        !           196:     UCHAR writeValue;
        !           197:     UCHAR driveTypes;
        !           198:     PCONFIGURATION_INFORMATION configurationInformation;
        !           199:     BOOLEAN machineIsCompaq = FALSE;
        !           200:     BOOLEAN foundIt = FALSE;
        !           201:     ULONG diskCount;
        !           202:     INTERFACE_TYPE defaultInterfaceType;
        !           203:     ULONG defaultBusNumber;
        !           204:     KIRQL defaultIrql;
        !           205:     PHYSICAL_ADDRESS defaultBaseAddress;
        !           206:     PHYSICAL_ADDRESS defaultPortAddress;
        !           207:     RTL_QUERY_REGISTRY_TABLE registryTable[2] = {0};
        !           208:     UNICODE_STRING ps1Data;
        !           209:     UNICODE_STRING ps1Value;
        !           210:     BOOLEAN ps1Detected;
        !           211:     UCHAR buffer[512];
        !           212:     CCHAR badDisks[][40] = {" 94244-383"};
        !           213:     ULONG numberOfBadDisks = sizeof(badDisks)/sizeof(badDisks[0]);
        !           214: 
        !           215:     //
        !           216:     // Get the temporary configuration manager information.
        !           217:     //
        !           218: 
        !           219:     configurationInformation = IoGetConfigurationInformation( );
        !           220:     ConfigData->HardDiskCount = &configurationInformation->DiskCount;
        !           221:     ConfigData->ArcNamePrefix = TemporaryArcNamePrefix;
        !           222:     diskCount = configurationInformation->DiskCount;
        !           223: 
        !           224:     //
        !           225:     // This driver only knows how to work on the first isa
        !           226:     // or eisa bus in the system.  Call IoQeuryDeviceDescription
        !           227:     // to make sure that there is such a bus on the system.
        !           228:     //
        !           229: 
        !           230:     foundIt = FALSE;
        !           231: 
        !           232:     //
        !           233:     // If it can't find the bus then just assume that it's the
        !           234:     // first isa bus.
        !           235:     //
        !           236: 
        !           237:     defaultInterfaceType = Isa;
        !           238:     defaultBusNumber = 0;
        !           239: 
        !           240:     IoQueryDeviceDescription(
        !           241:         &defaultInterfaceType,
        !           242:         &defaultBusNumber,
        !           243:         NULL,
        !           244:         NULL,
        !           245:         NULL,
        !           246:         NULL,
        !           247:         AtConfigCallBack,
        !           248:         &foundIt
        !           249:         );
        !           250: 
        !           251:     if (!foundIt) {
        !           252: 
        !           253:         defaultInterfaceType = Eisa;
        !           254:         defaultBusNumber = 0;
        !           255:         IoQueryDeviceDescription(
        !           256:             &defaultInterfaceType,
        !           257:             &defaultBusNumber,
        !           258:             NULL,
        !           259:             NULL,
        !           260:             NULL,
        !           261:             NULL,
        !           262:             AtConfigCallBack,
        !           263:             &foundIt
        !           264:             );
        !           265: 
        !           266:         if (!foundIt) {
        !           267: 
        !           268:             defaultInterfaceType = Isa;
        !           269:             defaultBusNumber = 0;
        !           270:             AtDump(
        !           271:                 ATERRORS,
        !           272:                 ("ATDISK: Not EISA OR ISA BY CONFIG, ASSUME ISA\n")
        !           273:                 );
        !           274: 
        !           275:         }
        !           276:     }
        !           277: 
        !           278:     //
        !           279:     // Check if first controller s unclaimed.
        !           280:     //
        !           281: 
        !           282:     if (!configurationInformation->AtDiskPrimaryAddressClaimed) {
        !           283: 
        !           284:         //
        !           285:         // Fill in some controller information.
        !           286:         //
        !           287: 
        !           288:         defaultBaseAddress.LowPart = 0x1F0;
        !           289:         defaultBaseAddress.HighPart = 0;
        !           290:         defaultPortAddress.LowPart = 0x3f6;
        !           291:         defaultPortAddress.HighPart = 0;
        !           292:         defaultIrql = 14;
        !           293:         AtDiskControllerInfo(
        !           294:             DriverObject,
        !           295:             RegistryPath,
        !           296:             0,
        !           297:             &ConfigData->Controller[0],
        !           298:             defaultBaseAddress,
        !           299:             defaultPortAddress,
        !           300:             defaultIrql,
        !           301:             defaultInterfaceType,
        !           302:             defaultBusNumber,
        !           303:             TRUE
        !           304:             );
        !           305: 
        !           306:         //
        !           307:         // Check if controller active at primary address.
        !           308:         //
        !           309: 
        !           310:         if (AtControllerPresent(&ConfigData->Controller[0])) {
        !           311: 
        !           312:             //
        !           313:             // Claim ATDISK primary IO address range.
        !           314:             //
        !           315: 
        !           316:             configurationInformation->AtDiskPrimaryAddressClaimed = TRUE;
        !           317: 
        !           318:             ConfigData->Controller[0].OkToUseThisController = TRUE;
        !           319: 
        !           320:             //
        !           321:             // Check to see if this is a ps/1 compatible.  If it is
        !           322:             // then we have to do something different.  (Don't ask
        !           323:             // me, ask IBM.  I'm sure that they have an interesting
        !           324:             // answer.)  If it is a ps/1 compatible, then zero out
        !           325:             // the cmos types.  We'll look in the BIOS.
        !           326:             //
        !           327: 
        !           328:             ps1Data.Length = 0;
        !           329:             ps1Data.MaximumLength = sizeof(buffer);
        !           330:             ps1Data.Buffer = (PWCHAR)&buffer[0];
        !           331:             RtlInitUnicodeString(
        !           332:                 &ps1Value,
        !           333:                 L"PS1/PS1 COMPATIBLE"
        !           334:                 );
        !           335:             registryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT |
        !           336:                                   RTL_QUERY_REGISTRY_REQUIRED;
        !           337:             registryTable[0].Name = L"Identifier";
        !           338:             registryTable[0].EntryContext = &ps1Data;
        !           339: 
        !           340:             if (!NT_SUCCESS(RtlQueryRegistryValues(
        !           341:                                 RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
        !           342:                                 L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM",
        !           343:                                 &registryTable[0],
        !           344:                                 NULL,
        !           345:                                 NULL
        !           346:                                 ))) {
        !           347: 
        !           348:                 //
        !           349:                 // How odd, no identifer string! We'll it's probably not a ps1.
        !           350:                 //
        !           351: 
        !           352:                 ps1Detected = FALSE;
        !           353: 
        !           354:             } else {
        !           355: 
        !           356:                 ps1Detected = RtlEqualUnicodeString(
        !           357:                                   &ps1Data,
        !           358:                                   &ps1Value,
        !           359:                                   FALSE
        !           360:                                   );
        !           361: 
        !           362: 
        !           363:             }
        !           364: 
        !           365:             if (ps1Detected) {
        !           366: 
        !           367:                 ConfigData->Controller[0].Disk[0].DriveType = 0;
        !           368:                 ConfigData->Controller[0].Disk[1].DriveType = 0;
        !           369: 
        !           370:             } else {
        !           371: 
        !           372:                 //
        !           373:                 // Check CMOS for drive types for first and second disk.
        !           374:                 //
        !           375: 
        !           376:                 WRITE_PORT_UCHAR(CFGMEM_QUERY_PORT, CFGMEM_FIRST_CONTROLLER_DRIVE_TYPES);
        !           377: 
        !           378:                 KeStallExecutionProcessor( 1L );
        !           379: 
        !           380:                 driveTypes = READ_PORT_UCHAR( CFGMEM_DATA_PORT );
        !           381: 
        !           382:                 ConfigData->Controller[0].Disk[0].DriveType = (UCHAR)
        !           383:                     ( driveTypes & CFGMEM_DRIVES_FIRST_DRIVE_MASK );
        !           384: 
        !           385:                 if ( ConfigData->Controller[0].Disk[0].DriveType == 0xf0 ) {
        !           386: 
        !           387:                     WRITE_PORT_UCHAR( CFGMEM_QUERY_PORT, CFGMEM_HARD_DRIVE_TYPE_ONE );
        !           388: 
        !           389:                     KeStallExecutionProcessor( 1L );
        !           390: 
        !           391:                     ConfigData->Controller[0].Disk[0].DriveType =
        !           392:                         READ_PORT_UCHAR( CFGMEM_DATA_PORT );
        !           393:                 }
        !           394: 
        !           395:                 ConfigData->Controller[0].Disk[1].DriveType = (UCHAR)
        !           396:                     ( driveTypes & CFGMEM_DRIVES_SECOND_DRIVE_MASK );
        !           397: 
        !           398:                 if ( ConfigData->Controller[0].Disk[1].DriveType == 0x0f ) {
        !           399: 
        !           400:                     WRITE_PORT_UCHAR( CFGMEM_QUERY_PORT, CFGMEM_HARD_DRIVE_TYPE_TWO );
        !           401: 
        !           402:                     KeStallExecutionProcessor( 1L );
        !           403: 
        !           404:                     ConfigData->Controller[0].Disk[1].DriveType =
        !           405:                         READ_PORT_UCHAR( CFGMEM_DATA_PORT );
        !           406:                 }
        !           407: 
        !           408:             }
        !           409: 
        !           410:             if (ConfigData->Controller[0].Disk[0].DriveType) {
        !           411: 
        !           412:                 //
        !           413:                 // Bump disk count.
        !           414:                 //
        !           415: 
        !           416:                 diskCount++;
        !           417: 
        !           418:                 //
        !           419:                 // Map BIOS vector 41 for first disk.
        !           420:                 //
        !           421: 
        !           422:                 paramVector = MmMapIoSpace(
        !           423:                     RtlConvertUlongToLargeInteger (
        !           424:                         PTR_TO_FDPT0_ADDRESS),
        !           425:                     sizeof( ULONG ),
        !           426:                     FALSE );
        !           427: 
        !           428:                 //
        !           429:                 // Map drive parameter table for first disk.
        !           430:                 //
        !           431: 
        !           432:                 if (*paramVector) {
        !           433: 
        !           434:                     UpdateGeometryFromParameterTable(&ConfigData->Controller[0].Disk[0],
        !           435:                                                      &ConfigData->Controller[0].ControlFlags,
        !           436:                                                      ((*(paramVector + 1)) << 4 ) + *paramVector);
        !           437: 
        !           438:                 } else {
        !           439: 
        !           440:                     //
        !           441:                     // Check BIOS information passed in from NTDETECT.
        !           442:                     //
        !           443: 
        !           444:                     if (UpdateGeometryFromBios(DriverObject,
        !           445:                                            &ConfigData->Controller[0].Disk[0],
        !           446:                                            0)) {
        !           447:                         ConfigData->Controller[0].Disk[0].DriveType = 0xFF;
        !           448:                     }
        !           449:                 }
        !           450: 
        !           451:                 MmUnmapIoSpace( paramVector, sizeof( ULONG ) );
        !           452: 
        !           453:             } else {
        !           454: 
        !           455:                 //
        !           456:                 // Verify that a disk is attached to the first controller.
        !           457:                 //
        !           458: 
        !           459:                 if (IssueIdentify(&ConfigData->Controller[0],
        !           460:                                   buffer,
        !           461:                                   0)) {
        !           462: 
        !           463:                     //
        !           464:                     // Check BIOS information passed in from NTDETECT.
        !           465:                     //
        !           466: 
        !           467:                     if (UpdateGeometryFromBios(DriverObject,
        !           468:                                            &ConfigData->Controller[0].Disk[0],
        !           469:                                            0)) {
        !           470: 
        !           471:                         diskCount++;
        !           472:                         ConfigData->Controller[0].Disk[0].DriveType = 0xFF;
        !           473:                     }
        !           474:                 }
        !           475:             }
        !           476: 
        !           477:             if (ConfigData->Controller[0].Disk[1].DriveType) {
        !           478: 
        !           479:                 //
        !           480:                 // Bump disk count.
        !           481:                 //
        !           482: 
        !           483:                 diskCount++;
        !           484: 
        !           485:                 //
        !           486:                 // Map BIOS vector 46 for second disk.
        !           487:                 //
        !           488: 
        !           489:                 paramVector = MmMapIoSpace(
        !           490:                     RtlConvertUlongToLargeInteger (
        !           491:                         PTR_TO_FDPT1_ADDRESS),
        !           492:                     sizeof( ULONG ),
        !           493:                     FALSE );
        !           494: 
        !           495:                 //
        !           496:                 // Map drive parameter table for second disk.
        !           497:                 //
        !           498: 
        !           499:                 if (*paramVector) {
        !           500: 
        !           501:                     if (UpdateGeometryFromParameterTable(&ConfigData->Controller[0].Disk[1],
        !           502:                                                          &ConfigData->Controller[0].ControlFlags,
        !           503:                                                      ((*(paramVector + 1)) << 4 ) + *paramVector)) {
        !           504:                         ConfigData->Controller[0].Disk[1].DriveType = 0xFF;
        !           505:                     }
        !           506: 
        !           507:                 } else {
        !           508: 
        !           509:                     //
        !           510:                     // Check BIOS information passed in from NTDETECT.
        !           511:                     //
        !           512: 
        !           513:                     if (UpdateGeometryFromBios(DriverObject,
        !           514:                                            &ConfigData->Controller[0].Disk[1],
        !           515:                                            1)) {
        !           516:                         ConfigData->Controller[0].Disk[1].DriveType = 0xFF;
        !           517:                     }
        !           518:                 }
        !           519: 
        !           520:                 MmUnmapIoSpace( paramVector, sizeof( ULONG ) );
        !           521: 
        !           522:             } else {
        !           523: 
        !           524:                 //
        !           525:                 // Verify that a second disk is attached to the first controller.
        !           526:                 //
        !           527: 
        !           528:                 if (IssueIdentify(&ConfigData->Controller[0],
        !           529:                                   buffer,
        !           530:                                   1)) {
        !           531: 
        !           532:                     //
        !           533:                     // Check BIOS information passed in from NTDETECT.
        !           534:                     //
        !           535: 
        !           536:                     if (UpdateGeometryFromBios(DriverObject,
        !           537:                                            &ConfigData->Controller[0].Disk[1],
        !           538:                                            1)) {
        !           539: 
        !           540:                         diskCount++;
        !           541:                         ConfigData->Controller[0].Disk[1].DriveType = 0xFF;
        !           542:                     }
        !           543:                 }
        !           544:             }
        !           545:         }
        !           546:     }
        !           547: 
        !           548:     //
        !           549:     // Check for unclaimed second controller.
        !           550:     //
        !           551: 
        !           552:     if (!configurationInformation->AtDiskSecondaryAddressClaimed) {
        !           553: 
        !           554:         //
        !           555:         // Fill in controller description.
        !           556:         //
        !           557: 
        !           558:         defaultBaseAddress.LowPart = 0x170;
        !           559:         defaultBaseAddress.HighPart = 0;
        !           560:         defaultPortAddress.LowPart = 0x376;
        !           561:         defaultPortAddress.HighPart = 0;
        !           562: 
        !           563:         //
        !           564:         // If this is a compaq then the values for the
        !           565:         // vector may be wrong.  They will get mapped
        !           566:         // to the correct value in a little bit.
        !           567:         //
        !           568: 
        !           569:         defaultIrql = 15;
        !           570:         AtDiskControllerInfo(
        !           571:             DriverObject,
        !           572:             RegistryPath,
        !           573:             1,
        !           574:             &ConfigData->Controller[1],
        !           575:             defaultBaseAddress,
        !           576:             defaultPortAddress,
        !           577:             defaultIrql,
        !           578:             defaultInterfaceType,
        !           579:             defaultBusNumber,
        !           580:             TRUE
        !           581:             );
        !           582: 
        !           583:         //
        !           584:         // Check if controller present at secondary address.
        !           585:         //
        !           586: 
        !           587:         if (AtControllerPresent(&ConfigData->Controller[1])) {
        !           588: 
        !           589:             //
        !           590:             // Claim ATDISK secondary IO address range.
        !           591:             //
        !           592: 
        !           593:             configurationInformation->AtDiskSecondaryAddressClaimed = TRUE;
        !           594: 
        !           595:             ConfigData->Controller[1].OkToUseThisController = TRUE;
        !           596: 
        !           597:             //
        !           598:             // Map BIOS vendor signature to check for Compaq.
        !           599:             //
        !           600: 
        !           601:             namePointer = MmMapIoSpace( RtlConvertUlongToLargeInteger (
        !           602:                                             PTR_TO_NAME_STRING),
        !           603:                                         NAME_STRING_LENGTH,
        !           604:                                         FALSE );
        !           605: 
        !           606:             if ( ( *namePointer == 'C' ) &&
        !           607:                 ( *( namePointer + 1 ) == 'O' ) &&
        !           608:                 ( *( namePointer + 2 ) == 'M' ) &&
        !           609:                 ( *( namePointer + 3 ) == 'P' ) &&
        !           610:                 ( *( namePointer + 4 ) == 'A' ) &&
        !           611:                 ( *( namePointer + 5 ) == 'Q' ) ) {
        !           612: 
        !           613:                 machineIsCompaq = TRUE;
        !           614:                 AtDump(
        !           615:                     ATINIT,
        !           616:                     ("ATDISK: Machine is a compaq!\n")
        !           617:                     );
        !           618: 
        !           619:             }
        !           620: 
        !           621:             MmUnmapIoSpace( namePointer, NAME_STRING_LENGTH );
        !           622: 
        !           623:             //
        !           624:             // Compaq uses CMOS to store the drive type for up to two disks
        !           625:             // attached to their secondary controllers.
        !           626:             //
        !           627: 
        !           628:             if ( machineIsCompaq ) {
        !           629: 
        !           630:                 //
        !           631:                 // Query CMOS about types of drives 3 and 4.  If they exist, get
        !           632:                 // pointers to the appropriate places in our internal fixed disk
        !           633:                 // parameter table.
        !           634:                 //
        !           635: 
        !           636:                 WRITE_PORT_UCHAR( CFGMEM_QUERY_PORT, CFGMEM_HARD_DRIVE_TYPE_THREE );
        !           637: 
        !           638:                 KeStallExecutionProcessor( 1L );
        !           639: 
        !           640:                 ConfigData->Controller[1].Disk[0].DriveType =
        !           641:                     READ_PORT_UCHAR( CFGMEM_DATA_PORT );
        !           642: 
        !           643:                 if (ConfigData->Controller[1].Disk[0].DriveType) {
        !           644: 
        !           645:                     //
        !           646:                     // Bump disk count.
        !           647:                     //
        !           648: 
        !           649:                     diskCount++;
        !           650: 
        !           651:                     //
        !           652:                     // Use drive type as an index into the system BIOS drive parameter
        !           653:                     // table to find a corresponding geometry entry.
        !           654:                     //
        !           655: 
        !           656:                     paramTable = DRIVE_PARAMETER_TABLE_OFFSET +
        !           657:                                  (ConfigData->Controller[1].Disk[0].DriveType -1) *
        !           658:                                  sizeof(FIXED_DISK_PARAMETER_TABLE);
        !           659: 
        !           660:                     UpdateGeometryFromParameterTable(&ConfigData->Controller[1].Disk[0],
        !           661:                                                      &ConfigData->Controller[1].ControlFlags,
        !           662:                                                      paramTable);
        !           663:                 }
        !           664: 
        !           665:                 WRITE_PORT_UCHAR( CFGMEM_QUERY_PORT, CFGMEM_HARD_DRIVE_TYPE_FOUR );
        !           666: 
        !           667:                 KeStallExecutionProcessor( 1L );
        !           668: 
        !           669:                 ConfigData->Controller[1].Disk[1].DriveType =
        !           670:                     READ_PORT_UCHAR( CFGMEM_DATA_PORT );
        !           671: 
        !           672:                 if (ConfigData->Controller[1].Disk[1].DriveType) {
        !           673: 
        !           674:                     //
        !           675:                     // Bump disk count.
        !           676:                     //
        !           677: 
        !           678:                     diskCount++;
        !           679: 
        !           680:                     //
        !           681:                     // Use drive type as an index into the system BIOS drive parameter
        !           682:                     // table to find a corresponding geometry entry.
        !           683:                     //
        !           684: 
        !           685:                     paramTable = DRIVE_PARAMETER_TABLE_OFFSET +
        !           686:                                  (ConfigData->Controller[1].Disk[1].DriveType -1) *
        !           687:                                  sizeof(FIXED_DISK_PARAMETER_TABLE);
        !           688: 
        !           689:                     UpdateGeometryFromParameterTable(&ConfigData->Controller[1].Disk[1],
        !           690:                                                      &ConfigData->Controller[1].ControlFlags,
        !           691:                                                      paramTable);
        !           692:                 }
        !           693: 
        !           694:                 //
        !           695:                 // If disk 3 or 4 was found, set up the secondary controller.
        !           696:                 //
        !           697: 
        !           698:                 if ( ( ConfigData->Controller[1].Disk[0].DriveType != 0 ) ||
        !           699:                     ( ConfigData->Controller[1].Disk[1].DriveType != 0 ) ) {
        !           700: 
        !           701:                     configuredIrq = READ_PORT_UCHAR( SECOND_CONTROLLER_IRQ_PORT );
        !           702: 
        !           703:                     if ( ( configuredIrq & IRQ_PORT_DISABLED_MASK ) ==
        !           704:                         IRQ_PORT_DISABLED ) {
        !           705: 
        !           706:                         //
        !           707:                         // NT (or OS/2) has already written to this port, which
        !           708:                         // disables further writes.  The bit set in the lower
        !           709:                         // nibble indicates which IRQ is being used.
        !           710:                         //
        !           711: 
        !           712:                         switch ( configuredIrq ) {
        !           713: 
        !           714:                             case IRQ_PORT_DISABLED + 1: {
        !           715: 
        !           716:                                 configuredIrq = 11;
        !           717:                                 break;
        !           718:                             }
        !           719: 
        !           720:                             case IRQ_PORT_DISABLED + 2: {
        !           721: 
        !           722:                                 configuredIrq = 12;
        !           723:                                 break;
        !           724:                             }
        !           725: 
        !           726:                             case IRQ_PORT_DISABLED + 4: {
        !           727: 
        !           728:                                 configuredIrq = 14;
        !           729:                                 break;
        !           730:                             }
        !           731: 
        !           732:                             default: {
        !           733: 
        !           734:                                 //
        !           735:                                 // Case 8 is IRQ 15; but in case we got garbage
        !           736:                                 // let's assume 15 and see if it works.
        !           737:                                 //
        !           738: 
        !           739:                                 configuredIrq = 15;
        !           740:                                 break;
        !           741:                             }
        !           742:                         }
        !           743: 
        !           744:                     } else {
        !           745: 
        !           746:                         //
        !           747:                         // This is the first boot after a powercycle.  We need
        !           748:                         // to determine the IRQ being used by checking which bit
        !           749:                         // *isn't* set in the *high* nibble.  Then we need to
        !           750:                         // write the IRQ_PORT_DISABLED + the proper IRQ bit in
        !           751:                         // the lower nibble.
        !           752:                         //
        !           753: 
        !           754:                         switch ( configuredIrq ) {
        !           755: 
        !           756:                             case 0xe0: {
        !           757: 
        !           758:                                 configuredIrq = 11;
        !           759:                                 writeValue = IRQ_PORT_DISABLED + 1;
        !           760:                                 break;
        !           761:                             }
        !           762: 
        !           763:                             case 0xd0: {
        !           764: 
        !           765:                                 configuredIrq = 12;
        !           766:                                 writeValue = IRQ_PORT_DISABLED + 2;
        !           767:                                 break;
        !           768:                             }
        !           769: 
        !           770:                             case 0xb0: {
        !           771: 
        !           772:                                 configuredIrq = 14;
        !           773:                                 writeValue = IRQ_PORT_DISABLED + 4;
        !           774:                                 break;
        !           775:                             }
        !           776: 
        !           777:                             default: {
        !           778: 
        !           779:                                 //
        !           780:                                 // Case 0x70 is IRQ 15, but we also want to try
        !           781:                                 // IRQ 15 if we got garbage from the register.
        !           782:                                 //
        !           783: 
        !           784:                                 configuredIrq = 15;
        !           785:                                 writeValue = IRQ_PORT_DISABLED + 8;
        !           786:                                 break;
        !           787:                             }
        !           788:                         }
        !           789: 
        !           790:                         WRITE_PORT_UCHAR( SECOND_CONTROLLER_IRQ_PORT, writeValue );
        !           791:                     }
        !           792: 
        !           793:                     ConfigData->Controller[1].OriginalControllerIrql   = configuredIrq;
        !           794:                     ConfigData->Controller[1].OriginalControllerVector = configuredIrq;
        !           795: 
        !           796:                     ConfigData->Controller[1].ControllerVector =
        !           797:                         HalGetInterruptVector(
        !           798:                             ConfigData->Controller[1].InterfaceType,
        !           799:                             ConfigData->Controller[1].BusNumber,
        !           800:                             ConfigData->Controller[1].OriginalControllerIrql,
        !           801:                             ConfigData->Controller[1].OriginalControllerVector,
        !           802:                             &ConfigData->Controller[1].ControllerIrql,
        !           803:                             &ConfigData->Controller[1].ProcessorNumber );
        !           804:                 }
        !           805: 
        !           806:             } else {
        !           807: 
        !           808:                 //
        !           809:                 // If it's not a compaq then the interrupt is already
        !           810:                 // set up.
        !           811:                 //
        !           812: 
        !           813:                 //
        !           814:                 // Verify a disk is attached to the second controller.
        !           815:                 //
        !           816: 
        !           817:                 if (IssueIdentify(&ConfigData->Controller[1],
        !           818:                                   buffer,
        !           819:                                   0)) {
        !           820: 
        !           821:                     //
        !           822:                     // Check if the BIOS has information about this disk.
        !           823:                     //
        !           824: 
        !           825:                     if (UpdateGeometryFromBios(DriverObject,
        !           826:                                            &ConfigData->Controller[1].Disk[0],
        !           827:                                            diskCount)) {
        !           828: 
        !           829:                         diskCount++;
        !           830:                         ConfigData->Controller[1].Disk[0].DriveType = 0xFF;
        !           831: 
        !           832:                     } else {
        !           833: 
        !           834:                         //
        !           835:                         // Get geometry information for disk 0 from IDENTIFY command.
        !           836:                         //
        !           837: 
        !           838:                         if (GetGeometryFromIdentify(&ConfigData->Controller[1],
        !           839:                                                     0)) {
        !           840: 
        !           841:                             diskCount++;
        !           842:                             ConfigData->Controller[1].Disk[0].DriveType = 0xFF;
        !           843:                         }
        !           844:                     }
        !           845: 
        !           846:                     //
        !           847:                     // Verify a disk is attached to the second controller.
        !           848:                     //
        !           849: 
        !           850:                     if (IssueIdentify(&ConfigData->Controller[1],
        !           851:                                       buffer,
        !           852:                                       1)) {
        !           853: 
        !           854:                         //
        !           855:                         // Check if the BIOS has information about this disk.
        !           856:                         //
        !           857: 
        !           858:                         if (UpdateGeometryFromBios(DriverObject,
        !           859:                                                &ConfigData->Controller[1].Disk[1],
        !           860:                                                diskCount)) {
        !           861: 
        !           862:                             diskCount++;
        !           863:                             ConfigData->Controller[1].Disk[1].DriveType = 0xFF;
        !           864: 
        !           865:                         } else {
        !           866: 
        !           867:                             //
        !           868:                             // Get geometry information for disk 1 from IDENTIFY command.
        !           869:                             //
        !           870: 
        !           871:                             if (GetGeometryFromIdentify(&ConfigData->Controller[1],
        !           872:                                                         1)) {
        !           873: 
        !           874:                                 diskCount++;
        !           875:                                 ConfigData->Controller[1].Disk[1].DriveType = 0xFF;
        !           876:                             }
        !           877:                         }
        !           878:                     }
        !           879:                 }
        !           880:             }
        !           881:         }
        !           882:     }
        !           883: 
        !           884:     for (i=2;i < MAXIMUM_NUMBER_OF_CONTROLLERS;i++) {
        !           885: 
        !           886:         if (AtDiskControllerInfo(
        !           887:                 DriverObject,
        !           888:                 RegistryPath,
        !           889:                 i,
        !           890:                 &ConfigData->Controller[i],
        !           891:                 defaultBaseAddress,
        !           892:                 defaultPortAddress,
        !           893:                 defaultIrql,
        !           894:                 defaultInterfaceType,
        !           895:                 defaultBusNumber,
        !           896:                 FALSE
        !           897:                 )) {
        !           898: 
        !           899:             //
        !           900:             // Assume that if it is such a "high" controller,
        !           901:             // is following the ata spec, and that it's ok
        !           902:             // to set the control flags as we should.
        !           903:             //
        !           904: 
        !           905:             ConfigData->Controller[i].ControlFlags = 0x08;
        !           906: 
        !           907:             if (!AtControllerPresent(&ConfigData->Controller[i])) {
        !           908: 
        !           909:                 continue;
        !           910: 
        !           911:             }
        !           912: 
        !           913:             if (!AtResetController(
        !           914:                     ConfigData->Controller[i].ControllerBaseAddress + STATUS_REGISTER,
        !           915:                     ConfigData->Controller[i].ControlPortAddress,
        !           916:                     ConfigData->Controller[i].ControlFlags
        !           917:                     )) {
        !           918: 
        !           919:                 continue;
        !           920: 
        !           921:             }
        !           922: 
        !           923:             ConfigData->Controller[i].OkToUseThisController = TRUE;
        !           924: 
        !           925:             //
        !           926:             // Get geometry information for disk 0 from IDENTIFY command.
        !           927:             //
        !           928: 
        !           929:             if (GetGeometryFromIdentify(&ConfigData->Controller[i],
        !           930:                                         0)) {
        !           931: 
        !           932:                 diskCount++;
        !           933:                 ConfigData->Controller[i].Disk[0].DriveType = 0xFF;
        !           934: 
        !           935:                 //
        !           936:                 // Get geometry information for disk 1 from IDENTIFY command.
        !           937:                 //
        !           938: 
        !           939:                 if (GetGeometryFromIdentify(&ConfigData->Controller[i],
        !           940:                                             1)) {
        !           941: 
        !           942:                     diskCount++;
        !           943:                     ConfigData->Controller[i].Disk[1].DriveType = 0xFF;
        !           944:                 }
        !           945:             }
        !           946:         }
        !           947:     }
        !           948:     //
        !           949:     // Check if any disks were found.
        !           950:     //
        !           951: 
        !           952:     if (!diskCount) {
        !           953:         return STATUS_NO_SUCH_DEVICE;
        !           954:     }
        !           955: 
        !           956:     //
        !           957:     // Update device map in registry with disk information.
        !           958:     //
        !           959: 
        !           960:     for (i=0; i< MAXIMUM_NUMBER_OF_CONTROLLERS; i++) {
        !           961:         for (j=0; j< MAXIMUM_NUMBER_OF_DISKS_PER_CONTROLLER; j++) {
        !           962: 
        !           963: 
        !           964:             if (!ConfigData->Controller[i].Disk[j].DriveType) {
        !           965:                 continue;
        !           966:             }
        !           967: 
        !           968:             //
        !           969:             // Issue IDENTIFY command.
        !           970:             //
        !           971: 
        !           972:             if (IssueIdentify(&ConfigData->Controller[i],
        !           973:                               buffer,
        !           974:                               j)) {
        !           975: 
        !           976:                 PUSHORT tempS;
        !           977:                 UCHAR tempByte;
        !           978: 
        !           979:                 //
        !           980:                 // Byte flip model number, revision, and serial number string.
        !           981:                 //
        !           982: 
        !           983:                 tempS = ((PIDENTIFY_DATA)buffer)->ModelNumber;
        !           984:                 for (k=0; k<20; k++) {
        !           985:                     tempByte = (UCHAR)(tempS[k] & 0x00FF);
        !           986:                     tempS[k] = tempS[k] >> 8;
        !           987:                     tempS[k] |= tempByte << 8;
        !           988:                 }
        !           989: 
        !           990:                 tempS = ((PIDENTIFY_DATA)buffer)->FirmwareRevision;
        !           991:                 for (k=0; k<4; k++) {
        !           992:                     tempByte = (UCHAR)(tempS[k] & 0x00FF);
        !           993:                     tempS[k] = tempS[k] >> 8;
        !           994:                     tempS[k] |= tempByte << 8;
        !           995:                 }
        !           996: 
        !           997:                 tempS = ((PIDENTIFY_DATA)buffer)->SerialNumber;
        !           998:                 for (k=0; k<10; k++) {
        !           999:                     tempByte = (UCHAR)(tempS[k] & 0x00FF);
        !          1000:                     tempS[k] = tempS[k] >> 8;
        !          1001:                     tempS[k] |= tempByte << 8;
        !          1002:                 }
        !          1003: 
        !          1004:             } else {
        !          1005: 
        !          1006:                 RtlZeroMemory(
        !          1007:                     &buffer[0],
        !          1008:                     512
        !          1009:                     );
        !          1010: 
        !          1011:             }
        !          1012: 
        !          1013:             for (k=0;k<numberOfBadDisks;k++) {
        !          1014: 
        !          1015:                 //
        !          1016:                 // Check if we should disable the read cache.
        !          1017:                 //
        !          1018: 
        !          1019:                 if (!strncmp(
        !          1020:                          &badDisks[k][0],
        !          1021:                          (PUCHAR)&((PIDENTIFY_DATA)buffer)->ModelNumber[0],
        !          1022:                          strlen(&badDisks[k][0])
        !          1023:                          )) {
        !          1024: 
        !          1025:                     ConfigData->Controller[i].Disk[j].DisableReadCache = TRUE;
        !          1026: 
        !          1027:                 }
        !          1028: 
        !          1029:             }
        !          1030: 
        !          1031:             //
        !          1032:             // Update device map.
        !          1033:             //
        !          1034: 
        !          1035:             AtBuildDeviceMap(i,
        !          1036:                              j,
        !          1037:                              ConfigData->Controller[i].OriginalControllerBaseAddress,
        !          1038:                              ConfigData->Controller[i].OriginalControllerIrql,
        !          1039:                              &ConfigData->Controller[i].Disk[j],
        !          1040:                              (PIDENTIFY_DATA)buffer);
        !          1041: 
        !          1042:         }
        !          1043:     }
        !          1044: 
        !          1045:     return STATUS_SUCCESS;
        !          1046: }
        !          1047: 
        !          1048: 
        !          1049: BOOLEAN
        !          1050: UpdateGeometryFromBios(
        !          1051:     PDRIVER_OBJECT DriverObject,
        !          1052:     DRIVE_DATA *DriveData,
        !          1053:     ULONG DiskNumber
        !          1054:     )
        !          1055: 
        !          1056: /*++
        !          1057: 
        !          1058: Routine Description:
        !          1059: 
        !          1060:     This updates geometry information in a disk extension
        !          1061:     from BIOS information passed in from NTDETECT.
        !          1062: 
        !          1063: Arguments:
        !          1064: 
        !          1065:     DriverObject - Contains pointer to NTDETECT information.
        !          1066:     DriveData - Store geometry in this structure.
        !          1067:     DiskNumber - Drive 1(0) or drive 2(1).
        !          1068: 
        !          1069: Return Value:
        !          1070: 
        !          1071:     TRUE if information for this disk exists in registry from BIOS.
        !          1072: 
        !          1073: --*/
        !          1074: 
        !          1075: {
        !          1076:     OBJECT_ATTRIBUTES objectAttributes;
        !          1077:     UNICODE_STRING valueName;
        !          1078:     NTSTATUS status;
        !          1079:     PCM_FULL_RESOURCE_DESCRIPTOR resourceDescriptor;
        !          1080:     PKEY_VALUE_FULL_INFORMATION keyData;
        !          1081:     PUCHAR buffer;
        !          1082:     ULONG length;
        !          1083:     ULONG numberOfDrives;
        !          1084:     HANDLE biosKey;
        !          1085:     PCM_INT13_DRIVE_PARAMETER int13ParamTable;
        !          1086: 
        !          1087:     //
        !          1088:     // Initialize the object for the key.
        !          1089:     //
        !          1090: 
        !          1091:     InitializeObjectAttributes( &objectAttributes,
        !          1092:                                 DriverObject->HardwareDatabase,
        !          1093:                                 OBJ_CASE_INSENSITIVE,
        !          1094:                                 NULL,
        !          1095:                                 (PSECURITY_DESCRIPTOR) NULL );
        !          1096: 
        !          1097:     //
        !          1098:     // Create the key.
        !          1099:     //
        !          1100: 
        !          1101:     status =  ZwOpenKey(
        !          1102:                     &biosKey,
        !          1103:                     KEY_READ,
        !          1104:                     &objectAttributes
        !          1105:                     );
        !          1106: 
        !          1107: 
        !          1108:     if (!NT_SUCCESS(status)) {
        !          1109:         return FALSE;
        !          1110:     }
        !          1111: 
        !          1112:     RtlInitUnicodeString( &valueName, L"Configuration Data" );
        !          1113: 
        !          1114:     keyData = ExAllocatePool(PagedPool, 2048);
        !          1115: 
        !          1116:     if (keyData == NULL) {
        !          1117:         ZwClose(biosKey);
        !          1118:         return FALSE;
        !          1119:     }
        !          1120: 
        !          1121:     status = ZwQueryValueKey(
        !          1122:         biosKey,
        !          1123:         &valueName,
        !          1124:         KeyValueFullInformation,
        !          1125:         keyData,
        !          1126:         2048,
        !          1127:         &length
        !          1128:         );
        !          1129: 
        !          1130:     ZwClose(biosKey);
        !          1131: 
        !          1132:     if (!NT_SUCCESS(status)) {
        !          1133:         ExFreePool(keyData);
        !          1134:         return FALSE;
        !          1135:     }
        !          1136: 
        !          1137:     resourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR) ((PUCHAR) keyData +
        !          1138:         keyData->DataOffset);
        !          1139: 
        !          1140:     //
        !          1141:     // Check that the data is long enough to hold a full resource descriptor,
        !          1142:     // and that the last resouce list is device-specific and long enough.
        !          1143:     //
        !          1144: 
        !          1145:     if (keyData->DataLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR) ||
        !          1146:         resourceDescriptor->PartialResourceList.Count == 0 ||
        !          1147:         resourceDescriptor->PartialResourceList.PartialDescriptors[0].Type !=
        !          1148:         CmResourceTypeDeviceSpecific ||
        !          1149:         resourceDescriptor->PartialResourceList.PartialDescriptors[0]
        !          1150:             .u.DeviceSpecificData.DataSize < sizeof(ULONG)
        !          1151:             ) {
        !          1152: 
        !          1153:         ExFreePool(keyData);
        !          1154:         return FALSE;
        !          1155:     }
        !          1156: 
        !          1157:     length = resourceDescriptor->PartialResourceList.PartialDescriptors[0]
        !          1158:             .u.DeviceSpecificData.DataSize;
        !          1159: 
        !          1160:     //
        !          1161:     // Point to the BIOS data. The BIOS data is located after the first
        !          1162:     // partial Resource list which should be device specific data.
        !          1163:     //
        !          1164: 
        !          1165:     buffer = (PUCHAR) keyData + keyData->DataOffset +
        !          1166:         sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
        !          1167: 
        !          1168: 
        !          1169:     numberOfDrives = length / sizeof(CM_INT13_DRIVE_PARAMETER);
        !          1170: 
        !          1171:     //
        !          1172:     // Use the defaults if the drive number is greater than the
        !          1173:     // number of drives detected by the BIOS.
        !          1174:     //
        !          1175: 
        !          1176:     if (numberOfDrives <= DiskNumber) {
        !          1177:         ExFreePool(keyData);
        !          1178:         return FALSE;
        !          1179:     }
        !          1180: 
        !          1181:     //
        !          1182:     // Point to the array of drive parameters.
        !          1183:     //
        !          1184: 
        !          1185:     int13ParamTable = (PCM_INT13_DRIVE_PARAMETER) buffer + DiskNumber;
        !          1186: 
        !          1187:     //
        !          1188:     // Initialize this drive.
        !          1189:     //
        !          1190: 
        !          1191:     DriveData->BytesPerSector = 512;
        !          1192:     DriveData->BytesPerInterrupt = 512;
        !          1193: 
        !          1194:     DriveData->ReadCommand    = 0x20;
        !          1195:     DriveData->WriteCommand   = 0x30;
        !          1196:     DriveData->VerifyCommand  = 0x40;
        !          1197: 
        !          1198:     DriveData->PretendNumberOfCylinders =
        !          1199:     DriveData->NumberOfCylinders =
        !          1200:         (USHORT)(int13ParamTable->MaxCylinders + 1);
        !          1201:     DriveData->PretendTracksPerCylinder =
        !          1202:     DriveData->TracksPerCylinder =
        !          1203:         (int13ParamTable->MaxHeads + 1);
        !          1204:     DriveData->PretendSectorsPerTrack =
        !          1205:     DriveData->SectorsPerTrack =
        !          1206:         int13ParamTable->SectorsPerTrack;
        !          1207:     DriveData->WritePrecomp = 0;
        !          1208: 
        !          1209:     return TRUE;
        !          1210: }
        !          1211: 
        !          1212: 
        !          1213: BOOLEAN
        !          1214: UpdateGeometryFromParameterTable(
        !          1215:     DRIVE_DATA *DriveData,
        !          1216:     CCHAR *ControlFlags,
        !          1217:     ULONG ParameterTableOffset
        !          1218:     )
        !          1219: 
        !          1220: /*++
        !          1221: 
        !          1222: Routine Description:
        !          1223: 
        !          1224:     This updates geometry information in a disk extension
        !          1225:     from a BIOS parameter table entry.
        !          1226: 
        !          1227: Arguments:
        !          1228: 
        !          1229:     DriveData - Store geometry in this structure.
        !          1230:     ControlFlags - Points to a value to set in the controller when initializing.
        !          1231:     ParameterTableOffset - Raw ROM address.
        !          1232: 
        !          1233: Return Value:
        !          1234: 
        !          1235:     Nothing.
        !          1236: 
        !          1237: --*/
        !          1238: 
        !          1239: {
        !          1240:     PFIXED_DISK_PARAMETER_TABLE parameterTable;
        !          1241: 
        !          1242:     //
        !          1243:     // Map system BIOS drive parameter table.
        !          1244:     //
        !          1245: 
        !          1246:     parameterTable = MmMapIoSpace(RtlConvertUlongToLargeInteger(
        !          1247:                                     ParameterTableOffset),
        !          1248:                                     DRIVE_PARAMETER_TABLE_LENGTH,
        !          1249:                                   FALSE);
        !          1250: 
        !          1251:     //
        !          1252:     // Initialize this drive.
        !          1253:     //
        !          1254: 
        !          1255:     DriveData->BytesPerSector = 512;
        !          1256:     DriveData->BytesPerInterrupt = 512;
        !          1257: 
        !          1258:     DriveData->ReadCommand    = 0x20;
        !          1259:     DriveData->WriteCommand   = 0x30;
        !          1260:     DriveData->VerifyCommand  = 0x40;
        !          1261: 
        !          1262:     DriveData->PretendNumberOfCylinders =
        !          1263:         parameterTable->MaxCylinders;
        !          1264:     DriveData->PretendTracksPerCylinder =
        !          1265:         parameterTable->MaxHeads;
        !          1266:     DriveData->PretendSectorsPerTrack =
        !          1267:         parameterTable->SectorsPerTrack;
        !          1268:     DriveData->WritePrecomp =
        !          1269:         parameterTable->StartWritePrecomp;
        !          1270:     *ControlFlags = parameterTable->ControlFlags;
        !          1271: 
        !          1272:     //
        !          1273:     // Some of these values might have been "pretend" values useful for
        !          1274:     // dealing with DOS.  If so, determine the real values.
        !          1275:     //
        !          1276: 
        !          1277:     if ( ( parameterTable->Signature & 0xf0 ) == 0xa0 ) {
        !          1278: 
        !          1279:         //
        !          1280:         // The values obtained were fake; get the real ones.
        !          1281:         //
        !          1282: 
        !          1283:         DriveData->NumberOfCylinders =
        !          1284:             parameterTable->TranslatedMaxCylinders;
        !          1285:         DriveData->TracksPerCylinder =
        !          1286:             parameterTable->TranslatedMaxHeads;
        !          1287:         DriveData->SectorsPerTrack =
        !          1288:             parameterTable->TranslatedSectorsPerTrack;
        !          1289: 
        !          1290:     } else {
        !          1291: 
        !          1292:         //
        !          1293:         // The values obtained were correct (as far as it goes).
        !          1294:         //
        !          1295: 
        !          1296:         DriveData->NumberOfCylinders =
        !          1297:             parameterTable->MaxCylinders;
        !          1298:         DriveData->TracksPerCylinder =
        !          1299:             parameterTable->MaxHeads;
        !          1300:         DriveData->SectorsPerTrack =
        !          1301:             parameterTable->SectorsPerTrack;
        !          1302: 
        !          1303: 
        !          1304:     }
        !          1305: 
        !          1306:     MmUnmapIoSpace(parameterTable, sizeof(FIXED_DISK_PARAMETER_TABLE));
        !          1307: 
        !          1308:     return TRUE;
        !          1309: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.