mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 17:16:04 +00:00
[FDC]
Enumerate all BIOS-detected floppy drives which are attached to the current controller. svn path=/trunk/; revision=61116
This commit is contained in:
parent
fa67f52657
commit
b6c0091383
2 changed files with 195 additions and 4 deletions
|
@ -9,6 +9,60 @@
|
||||||
#include <ntddk.h>
|
#include <ntddk.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#define MAX_DEVICE_NAME 255
|
||||||
|
#define MAX_ARC_PATH_LEN 255
|
||||||
|
#define MAX_DRIVES_PER_CONTROLLER 4
|
||||||
|
#define MAX_CONTROLLERS 4
|
||||||
|
|
||||||
|
struct _CONTROLLER_INFO;
|
||||||
|
|
||||||
|
typedef struct _DRIVE_INFO
|
||||||
|
{
|
||||||
|
struct _CONTROLLER_INFO *ControllerInfo;
|
||||||
|
UCHAR UnitNumber; /* 0,1,2,3 */
|
||||||
|
LARGE_INTEGER MotorStartTime;
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
CM_FLOPPY_DEVICE_DATA FloppyDeviceData;
|
||||||
|
// DISK_GEOMETRY DiskGeometry;
|
||||||
|
UCHAR BytesPerSectorCode;
|
||||||
|
WCHAR SymLinkBuffer[MAX_DEVICE_NAME];
|
||||||
|
WCHAR ArcPathBuffer[MAX_ARC_PATH_LEN];
|
||||||
|
ULONG DiskChangeCount;
|
||||||
|
BOOLEAN Initialized;
|
||||||
|
} DRIVE_INFO, *PDRIVE_INFO;
|
||||||
|
|
||||||
|
typedef struct _CONTROLLER_INFO
|
||||||
|
{
|
||||||
|
BOOLEAN Populated;
|
||||||
|
BOOLEAN Initialized;
|
||||||
|
ULONG ControllerNumber;
|
||||||
|
INTERFACE_TYPE InterfaceType;
|
||||||
|
ULONG BusNumber;
|
||||||
|
ULONG Level;
|
||||||
|
KIRQL MappedLevel;
|
||||||
|
ULONG Vector;
|
||||||
|
ULONG MappedVector;
|
||||||
|
KINTERRUPT_MODE InterruptMode;
|
||||||
|
PUCHAR BaseAddress;
|
||||||
|
ULONG Dma;
|
||||||
|
ULONG MapRegisters;
|
||||||
|
PVOID MapRegisterBase;
|
||||||
|
BOOLEAN Master;
|
||||||
|
KEVENT SynchEvent;
|
||||||
|
KDPC Dpc;
|
||||||
|
PKINTERRUPT InterruptObject;
|
||||||
|
PADAPTER_OBJECT AdapterObject;
|
||||||
|
UCHAR NumberOfDrives;
|
||||||
|
BOOLEAN ImpliedSeeks;
|
||||||
|
DRIVE_INFO DriveInfo[MAX_DRIVES_PER_CONTROLLER];
|
||||||
|
PDRIVE_INFO CurrentDrive;
|
||||||
|
BOOLEAN Model30;
|
||||||
|
KEVENT MotorStoppedEvent;
|
||||||
|
KTIMER MotorTimer;
|
||||||
|
KDPC MotorStopDpc;
|
||||||
|
BOOLEAN StopDpcQueued;
|
||||||
|
} CONTROLLER_INFO, *PCONTROLLER_INFO;
|
||||||
|
|
||||||
|
|
||||||
typedef struct _COMMON_DEVICE_EXTENSION
|
typedef struct _COMMON_DEVICE_EXTENSION
|
||||||
{
|
{
|
||||||
|
@ -23,6 +77,8 @@ typedef struct _FDO_DEVICE_EXTENSION
|
||||||
PDEVICE_OBJECT Fdo;
|
PDEVICE_OBJECT Fdo;
|
||||||
PDEVICE_OBJECT Pdo;
|
PDEVICE_OBJECT Pdo;
|
||||||
|
|
||||||
|
CONTROLLER_INFO ControllerInfo;
|
||||||
|
|
||||||
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ FdcFdoStartDevice(
|
||||||
{
|
{
|
||||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
|
||||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptorTranslated;
|
// PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptorTranslated;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
DPRINT1("FdcFdoStartDevice called\n");
|
DPRINT1("FdcFdoStartDevice called\n");
|
||||||
|
@ -172,7 +172,7 @@ FdcFdoStartDevice(
|
||||||
for (i = 0; i < ResourceList->List[0].PartialResourceList.Count; i++)
|
for (i = 0; i < ResourceList->List[0].PartialResourceList.Count; i++)
|
||||||
{
|
{
|
||||||
PartialDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[i];
|
PartialDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[i];
|
||||||
PartialDescriptorTranslated = &ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[i];
|
// PartialDescriptorTranslated = &ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[i];
|
||||||
|
|
||||||
switch (PartialDescriptor->Type)
|
switch (PartialDescriptor->Type)
|
||||||
{
|
{
|
||||||
|
@ -180,12 +180,24 @@ FdcFdoStartDevice(
|
||||||
DPRINT1("Port: 0x%lx (%lu)\n",
|
DPRINT1("Port: 0x%lx (%lu)\n",
|
||||||
PartialDescriptor->u.Port.Start.u.LowPart,
|
PartialDescriptor->u.Port.Start.u.LowPart,
|
||||||
PartialDescriptor->u.Port.Length);
|
PartialDescriptor->u.Port.Length);
|
||||||
|
if (PartialDescriptor->u.Port.Length >= 6)
|
||||||
|
DeviceExtension->ControllerInfo.BaseAddress = (PUCHAR)PartialDescriptor->u.Port.Start.u.LowPart;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CmResourceTypeInterrupt:
|
case CmResourceTypeInterrupt:
|
||||||
DPRINT1("Interrupt: Level %lu Vector %lu\n",
|
DPRINT1("Interrupt: Level %lu Vector %lu\n",
|
||||||
PartialDescriptorTranslated->u.Interrupt.Level,
|
PartialDescriptor->u.Interrupt.Level,
|
||||||
PartialDescriptorTranslated->u.Interrupt.Vector);
|
PartialDescriptor->u.Interrupt.Vector);
|
||||||
|
/*
|
||||||
|
Dirql = (KIRQL)PartialDescriptorTranslated->u.Interrupt.Level;
|
||||||
|
Vector = PartialDescriptorTranslated->u.Interrupt.Vector;
|
||||||
|
Affinity = PartialDescriptorTranslated->u.Interrupt.Affinity;
|
||||||
|
if (PartialDescriptorTranslated->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
|
||||||
|
InterruptMode = Latched;
|
||||||
|
else
|
||||||
|
InterruptMode = LevelSensitive;
|
||||||
|
ShareInterrupt = (PartialDescriptorTranslated->ShareDisposition == CmResourceShareShared);
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CmResourceTypeDma:
|
case CmResourceTypeDma:
|
||||||
|
@ -199,13 +211,136 @@ FdcFdoStartDevice(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
FdcFdoConfigCallback(
|
||||||
|
PVOID Context,
|
||||||
|
PUNICODE_STRING PathName,
|
||||||
|
INTERFACE_TYPE BusType,
|
||||||
|
ULONG BusNumber,
|
||||||
|
PKEY_VALUE_FULL_INFORMATION *BusInformation,
|
||||||
|
CONFIGURATION_TYPE ControllerType,
|
||||||
|
ULONG ControllerNumber,
|
||||||
|
PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
|
||||||
|
CONFIGURATION_TYPE PeripheralType,
|
||||||
|
ULONG PeripheralNumber,
|
||||||
|
PKEY_VALUE_FULL_INFORMATION *PeripheralInformation)
|
||||||
|
{
|
||||||
|
PKEY_VALUE_FULL_INFORMATION ControllerFullDescriptor;
|
||||||
|
PCM_FULL_RESOURCE_DESCRIPTOR ControllerResourceDescriptor;
|
||||||
|
PKEY_VALUE_FULL_INFORMATION PeripheralFullDescriptor;
|
||||||
|
PCM_FULL_RESOURCE_DESCRIPTOR PeripheralResourceDescriptor;
|
||||||
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
|
||||||
|
PCM_FLOPPY_DEVICE_DATA FloppyDeviceData;
|
||||||
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PDRIVE_INFO DriveInfo;
|
||||||
|
BOOLEAN ControllerFound = FALSE;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
DPRINT1("FdcFdoConfigCallback() called\n");
|
||||||
|
|
||||||
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)Context;
|
||||||
|
|
||||||
|
/* Get the controller resources */
|
||||||
|
ControllerFullDescriptor = ControllerInformation[IoQueryDeviceConfigurationData];
|
||||||
|
ControllerResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PCHAR)ControllerFullDescriptor +
|
||||||
|
ControllerFullDescriptor->DataOffset);
|
||||||
|
|
||||||
|
for(i = 0; i < ControllerResourceDescriptor->PartialResourceList.Count; i++)
|
||||||
|
{
|
||||||
|
PartialDescriptor = &ControllerResourceDescriptor->PartialResourceList.PartialDescriptors[i];
|
||||||
|
|
||||||
|
if (PartialDescriptor->Type == CmResourceTypePort)
|
||||||
|
{
|
||||||
|
if ((PUCHAR)PartialDescriptor->u.Port.Start.LowPart == DeviceExtension->ControllerInfo.BaseAddress)
|
||||||
|
ControllerFound = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Leave, if the enumerated controller is not the one represented by the FDO */
|
||||||
|
if (ControllerFound == FALSE)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* Get the peripheral resources */
|
||||||
|
PeripheralFullDescriptor = PeripheralInformation[IoQueryDeviceConfigurationData];
|
||||||
|
PeripheralResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PCHAR)PeripheralFullDescriptor +
|
||||||
|
PeripheralFullDescriptor->DataOffset);
|
||||||
|
|
||||||
|
DeviceExtension->ControllerInfo.NumberOfDrives = 0;
|
||||||
|
|
||||||
|
/* learn about drives attached to controller */
|
||||||
|
for(i = 0; i < PeripheralResourceDescriptor->PartialResourceList.Count; i++)
|
||||||
|
{
|
||||||
|
PartialDescriptor = &PeripheralResourceDescriptor->PartialResourceList.PartialDescriptors[i];
|
||||||
|
|
||||||
|
if (PartialDescriptor->Type != CmResourceTypeDeviceSpecific)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FloppyDeviceData = (PCM_FLOPPY_DEVICE_DATA)(PartialDescriptor + 1);
|
||||||
|
|
||||||
|
DriveInfo = &DeviceExtension->ControllerInfo.DriveInfo[i];
|
||||||
|
|
||||||
|
DriveInfo->ControllerInfo = &DeviceExtension->ControllerInfo;
|
||||||
|
DriveInfo->UnitNumber = i;
|
||||||
|
|
||||||
|
DriveInfo->FloppyDeviceData.MaxDensity = FloppyDeviceData->MaxDensity;
|
||||||
|
DriveInfo->FloppyDeviceData.MountDensity = FloppyDeviceData->MountDensity;
|
||||||
|
DriveInfo->FloppyDeviceData.StepRateHeadUnloadTime = FloppyDeviceData->StepRateHeadUnloadTime;
|
||||||
|
DriveInfo->FloppyDeviceData.HeadLoadTime = FloppyDeviceData->HeadLoadTime;
|
||||||
|
DriveInfo->FloppyDeviceData.MotorOffTime = FloppyDeviceData->MotorOffTime;
|
||||||
|
DriveInfo->FloppyDeviceData.SectorLengthCode = FloppyDeviceData->SectorLengthCode;
|
||||||
|
DriveInfo->FloppyDeviceData.SectorPerTrack = FloppyDeviceData->SectorPerTrack;
|
||||||
|
DriveInfo->FloppyDeviceData.ReadWriteGapLength = FloppyDeviceData->ReadWriteGapLength;
|
||||||
|
DriveInfo->FloppyDeviceData.FormatGapLength = FloppyDeviceData->FormatGapLength;
|
||||||
|
DriveInfo->FloppyDeviceData.FormatFillCharacter = FloppyDeviceData->FormatFillCharacter;
|
||||||
|
DriveInfo->FloppyDeviceData.HeadSettleTime = FloppyDeviceData->HeadSettleTime;
|
||||||
|
DriveInfo->FloppyDeviceData.MotorSettleTime = FloppyDeviceData->MotorSettleTime;
|
||||||
|
DriveInfo->FloppyDeviceData.MaximumTrackValue = FloppyDeviceData->MaximumTrackValue;
|
||||||
|
DriveInfo->FloppyDeviceData.DataTransferLength = FloppyDeviceData->DataTransferLength;
|
||||||
|
|
||||||
|
/* Once it's all set up, acknowledge its existance in the controller info object */
|
||||||
|
DeviceExtension->ControllerInfo.NumberOfDrives++;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceExtension->ControllerInfo.Populated = TRUE;
|
||||||
|
|
||||||
|
DPRINT1("Detected %lu floppy drives!\n",
|
||||||
|
DeviceExtension->ControllerInfo.NumberOfDrives);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
FdcFdoQueryBusRelations(
|
FdcFdoQueryBusRelations(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
OUT PDEVICE_RELATIONS *DeviceRelations)
|
OUT PDEVICE_RELATIONS *DeviceRelations)
|
||||||
{
|
{
|
||||||
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
INTERFACE_TYPE InterfaceType = Isa;
|
||||||
|
CONFIGURATION_TYPE ControllerType = DiskController;
|
||||||
|
CONFIGURATION_TYPE PeripheralType = FloppyDiskPeripheral;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT1("FdcFdoQueryBusRelations() called\n");
|
DPRINT1("FdcFdoQueryBusRelations() called\n");
|
||||||
|
|
||||||
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
Status = IoQueryDeviceDescription(&InterfaceType,
|
||||||
|
NULL,
|
||||||
|
&ControllerType,
|
||||||
|
NULL,
|
||||||
|
&PeripheralType,
|
||||||
|
NULL,
|
||||||
|
FdcFdoConfigCallback,
|
||||||
|
DeviceExtension);
|
||||||
|
if (!NT_SUCCESS(Status) && (Status != STATUS_OBJECT_NAME_NOT_FOUND))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue