Annotation of ntddk/src/scsi/atdisk/i386/atd_conf.c, revision 1.1.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.