📄 floppy.c
字号:
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 + -