⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 floppy.c

📁 The flpydisk sample is a floppy driver that resides in the directory \NtddkSrcStorageFdcFlpydsk. It
💻 C
📖 第 1 页 / 共 5 页
字号:

                IoAssignArcName( &disketteExtension->ArcName, &deviceName );
            }

            deviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;

            if ( deviceObject->AlignmentRequirement < FILE_WORD_ALIGNMENT ) {

                deviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
            }

            deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

            disketteExtension->DriverObject = DriverObject;

            // Set the PDO for use with PlugPlay functions
            disketteExtension->UnderlyingPDO = PhysicalDeviceObject;

            FloppyDump( FLOPSHOW, 
                        ("FloppyAddDevice: Attaching %p to %p\n", 
                        deviceObject, 
                        PhysicalDeviceObject));

            disketteExtension->TargetObject = 
                        IoAttachDeviceToDeviceStack( deviceObject,
                                                     PhysicalDeviceObject );

            FloppyDump( FLOPSHOW, 
                        ("FloppyAddDevice: TargetObject = %p\n",
                        disketteExtension->TargetObject) );

            KeInitializeSemaphore( &disketteExtension->RequestSemaphore,
                                   0L,
                                   MAXLONG );

            ExInitializeFastMutex( &disketteExtension->PowerDownMutex );

            KeInitializeSpinLock( &disketteExtension->ListSpinLock );

            ExInitializeFastMutex( &disketteExtension->ThreadReferenceMutex );

            ExInitializeFastMutex( &disketteExtension->HoldNewReqMutex );

            InitializeListHead( &disketteExtension->ListEntry );

            disketteExtension->ThreadReferenceCount = -1;

            disketteExtension->IsStarted = FALSE;
            disketteExtension->IsRemoved = FALSE;
            disketteExtension->HoldNewRequests = FALSE;
            InitializeListHead( &disketteExtension->NewRequestQueue );
            KeInitializeSpinLock( &disketteExtension->NewRequestQueueSpinLock );
            KeInitializeSpinLock( &disketteExtension->FlCancelSpinLock );

            disketteExtension->FloppyControllerAllocated = FALSE;
            disketteExtension->ReleaseFdcWithMotorRunning = FALSE;
            disketteExtension->DeviceObject = deviceObject;

            disketteExtension->IsReadOnly = FALSE;

            disketteExtension->MediaType = Undetermined;

            disketteExtension->ControllerConfigurable = (IsNEC_98) ? FALSE : TRUE;
        }
    }

    return ntStatus;
}

NTSTATUS
FlConfigCallBack(
    IN PVOID Context,
    IN PUNICODE_STRING PathName,
    IN INTERFACE_TYPE BusType,
    IN ULONG BusNumber,
    IN PKEY_VALUE_FULL_INFORMATION *BusInformation,
    IN CONFIGURATION_TYPE ControllerType,
    IN ULONG ControllerNumber,
    IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
    IN CONFIGURATION_TYPE PeripheralType,
    IN ULONG PeripheralNumber,
    IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation
    )

/*++

Routine Description:

    This routine is used to acquire all of the configuration
    information for each floppy disk controller and the
    peripheral driver attached to that controller.

Arguments:

    Context - Pointer to the confuration information we are building
              up.

    PathName - unicode registry path.  Not Used.

    BusType - Internal, Isa, ...

    BusNumber - Which bus if we are on a multibus system.

    BusInformation - Configuration information about the bus. Not Used.

    ControllerType - Should always be DiskController.

    ControllerNumber - Which controller if there is more than one
                       controller in the system.

    ControllerInformation - Array of pointers to the three pieces of
                            registry information.

    PeripheralType - Should always be FloppyDiskPeripheral.

    PeripheralNumber - Which floppy if this controller is maintaining
                       more than one.

    PeripheralInformation - Arrya of pointers to the three pieces of
                            registry information.

Return Value:

    STATUS_SUCCESS if everything went ok, or STATUS_INSUFFICIENT_RESOURCES
    if it couldn't map the base csr or acquire the adapter object, or
    all of the resource information couldn't be acquired.

--*/

{

    //
    // So we don't have to typecast the context.
    //
    PDISKETTE_EXTENSION disketteExtension = Context;

    //
    // Simple iteration variable.
    //
    ULONG i;

    PCM_FULL_RESOURCE_DESCRIPTOR peripheralData;

    NTSTATUS ntStatus;

    ASSERT(ControllerType == DiskController);
    ASSERT(PeripheralType == FloppyDiskPeripheral);

    //
    // Check if the infprmation from the registry for this device
    // is valid.
    //

    if (!(((PUCHAR)PeripheralInformation[IoQueryDeviceConfigurationData]) +
        PeripheralInformation[IoQueryDeviceConfigurationData]->DataLength)) {

        ASSERT(FALSE);
        return STATUS_INVALID_PARAMETER;

    }

    peripheralData = (PCM_FULL_RESOURCE_DESCRIPTOR)
        (((PUCHAR)PeripheralInformation[IoQueryDeviceConfigurationData]) +
        PeripheralInformation[IoQueryDeviceConfigurationData]->DataOffset);

    //
    // With Version 2.0 or greater for this resource list, we will get
    // the full int13 information for the drive. So get that if available.
    //
    // Otherwise, the only thing that we want out of the peripheral information
    // is the maximum drive capacity.
    //
    // Drop any information on the floor other than the
    // device specfic floppy information.
    //

    for ( i = 0; i < peripheralData->PartialResourceList.Count; i++ ) {

        PCM_PARTIAL_RESOURCE_DESCRIPTOR partial =
            &peripheralData->PartialResourceList.PartialDescriptors[i];

        if ( partial->Type == CmResourceTypeDeviceSpecific ) {

            //
            // Point to right after this partial.  This will take
            // us to the beginning of the "real" device specific.
            //

            PCM_FLOPPY_DEVICE_DATA fDeviceData;
            UCHAR driveType;
            PDRIVE_MEDIA_CONSTANTS biosDriveMediaConstants =
                &(disketteExtension->BiosDriveMediaConstants);


            fDeviceData = (PCM_FLOPPY_DEVICE_DATA)(partial + 1);

            //
            // Get the driver density
            //

            switch ( fDeviceData->MaxDensity ) {

                case 360:   driveType = DRIVE_TYPE_0360;    break;
                case 1200:  driveType = DRIVE_TYPE_1200;    break;
                case 1185:  driveType = DRIVE_TYPE_1200;    break;
                case 1423:  driveType = DRIVE_TYPE_1440;    break;
                case 1440:  driveType = DRIVE_TYPE_1440;    break;
                case 2880:  driveType = DRIVE_TYPE_2880;    break;
                case 1201:  if (IsNEC_98) {
                                driveType = DRIVE_TYPE_1200_E;  break;
                            } // (IsNEC_98)

                default:

                    FloppyDump( 
                        FLOPDBGP, 
                        ("Floppy: Bad DriveCapacity!\n"
                        "------  density is %d\n",
                        fDeviceData->MaxDensity) 
                        );

                    driveType = DRIVE_TYPE_1200;

                    FloppyDump( 
                        FLOPDBGP,
                        ("Floppy: run a setup program to set the floppy\n"
                        "------  drive type; assuming 1.2mb\n"
                        "------  (type is %x)\n",fDeviceData->MaxDensity) 
                        );

                    break;

            }

            disketteExtension->DriveType = driveType;

            //
            // Pick up all the default from our own table and override
            // with the BIOS information
            //

            *biosDriveMediaConstants = DriveMediaConstants[
                DriveMediaLimits[driveType].HighestDriveMediaType];

            //
            // If the version is high enough, get the rest of the
            // information.  DeviceSpecific information with a version >= 2
            // should have this information
            //

            if ( fDeviceData->Version >= 2 ) {


                // biosDriveMediaConstants->MediaType =

                biosDriveMediaConstants->StepRateHeadUnloadTime =
                    fDeviceData->StepRateHeadUnloadTime;

                biosDriveMediaConstants->HeadLoadTime =
                    fDeviceData->HeadLoadTime;

                biosDriveMediaConstants->MotorOffTime =
                    fDeviceData->MotorOffTime;

                biosDriveMediaConstants->SectorLengthCode =
                    fDeviceData->SectorLengthCode;

                // biosDriveMediaConstants->BytesPerSector =

                if (fDeviceData->SectorPerTrack == 0) {
                    // This is not a valid sector per track value.
                    // We don't recognize this drive.  This bogus
                    // value is often returned by SCSI floppies.
                    return STATUS_SUCCESS;
                }

                if (fDeviceData->MaxDensity == 0 ) {
                    //
                    // This values are returned by the LS-120 atapi drive.
                    // BIOS function 8, in int 13 is returned in bl, which
                    // is mapped to this field. The LS-120 returns 0x10
                    // which is mapped to 0.  Thats why we wont pick it up
                    // as a normal floppy.
                    //
                    return STATUS_SUCCESS;
                }

                biosDriveMediaConstants->SectorsPerTrack =
                    fDeviceData->SectorPerTrack;

                biosDriveMediaConstants->ReadWriteGapLength =
                    fDeviceData->ReadWriteGapLength;

                biosDriveMediaConstants->FormatGapLength =
                    fDeviceData->FormatGapLength;

                biosDriveMediaConstants->FormatFillCharacter =
                    fDeviceData->FormatFillCharacter;

                biosDriveMediaConstants->HeadSettleTime =
                    fDeviceData->HeadSettleTime;

                biosDriveMediaConstants->MotorSettleTimeRead =
                    fDeviceData->MotorSettleTime * 1000 / 8;

                biosDriveMediaConstants->MotorSettleTimeWrite =
                    fDeviceData->MotorSettleTime * 1000 / 8;

                if (fDeviceData->MaximumTrackValue == 0) {
                    // This is not a valid maximum track value.
                    // We don't recognize this drive.  This bogus
                    // value is often returned by SCSI floppies.
                    return STATUS_SUCCESS;
                }

                biosDriveMediaConstants->MaximumTrack =
                    fDeviceData->MaximumTrackValue;

                biosDriveMediaConstants->DataLength =
                    fDeviceData->DataTransferLength;
            }
        }
    }

    return STATUS_SUCCESS;
}

NTSTATUS
FlAcpiConfigureFloppy(
    PDISKETTE_EXTENSION DisketteExtension,
    PFDC_INFO FdcInfo
    )

/*++

Routine Description:

Arguments:

Return Value:

--*/

{
    UCHAR driveType;

    PDRIVE_MEDIA_CONSTANTS biosDriveMediaConstants =
                &(DisketteExtension->BiosDriveMediaConstants);

    if ( !FdcInfo->AcpiFdiSupported ) {

        return STATUS_UNSUCCESSFUL;
    }

    //
    // Get the driver density
    //
    //    JB:TBD - review this drive type list.
    //
    switch ( (ACPI_FDI_DEVICE_TYPE)FdcInfo->AcpiFdiData.DeviceType ) {

    case Form525Capacity360:   driveType = DRIVE_TYPE_0360;    break;
    case Form525Capacity1200:  driveType = DRIVE_TYPE_1200;    break;
    case Form35Capacity720:    driveType = DRIVE_TYPE_0720;    break;
    case Form35Capacity1440:   driveType = DRIVE_TYPE_1440;    break;
    case Form35Capacity2880:   driveType = DRIVE_TYPE_2880;    break;

    default:                   driveType = DRIVE_TYPE_1200;    break;

    }

    DisketteExtension->DriveType = driveType;

    //
    // Pick up all the default from our own table and override
    // with the BIOS information
    //

    *biosDriveMediaConstants = DriveMediaConstants[
        DriveMediaLimits[driveType].HighestDriveMediaType];

    biosDriveMediaConstants->StepRateHeadUnloadTime = (UCHAR) FdcInfo->AcpiFdiData.StepRateHeadUnloadTime;
    biosDriveMediaConstants->HeadLoadTime           = (UCHAR) FdcInfo->AcpiFdiData.HeadLoadTime;
    biosDriveMediaConstants->MotorOffTime           = (UCHAR) FdcInfo->AcpiFdiData.MotorOffTime;
    biosDriveMediaConstants->SectorLengthCode       = (UCHAR) FdcInfo->AcpiFdiData.SectorLengthCode;
    biosDriveMediaConstants->SectorsPerTrack        = (UCHAR) FdcInfo->AcpiFdiData.SectorPerTrack;
    biosDriveMediaConstants->ReadWriteGapLength     = (UCHAR) FdcInfo->AcpiFdiData.ReadWriteGapLength;
    biosDriveMediaConstants->FormatGapLength        = (UCHAR) FdcInfo->AcpiFdiData.FormatGapLength;
    biosDriveMediaConstants->FormatFillCharacter    = (UCHAR) FdcInfo->AcpiFdiData.FormatFillCharacter;
    biosDriveMediaConstants->HeadSettleTime         = (UCHAR) FdcInfo->AcpiFdiData.HeadSettleTime;
    biosDriveMediaConstants->MotorSettleTimeRead    = (UCHAR) FdcInfo->AcpiFdiData.MotorSettleTime * 1000 / 8;
    biosDriveMediaConstants->MotorSettleTimeWrite   = (USHORT) FdcInfo->AcpiFdiData.MotorSettleTime * 1000 / 8;
    biosDriveMediaConstants->MaximumTrack           = (UCHAR) FdcInfo->AcpiFdiData.MaxCylinderNumber;
    biosDriveMediaConstants->DataLength             = (UCHAR) FdcInfo->AcpiFdiData.DataTransferLength;

    return STATUS_SUCCESS;
}

NTSTATUS
FlQueueIrpToThread(
    IN OUT  PIRP                Irp,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -