1c1f22c88SEric Kohl /*
2c1f22c88SEric Kohl * PROJECT: ReactOS Floppy Disk Controller Driver
3c1f22c88SEric Kohl * LICENSE: GNU GPLv2 only as published by the Free Software Foundation
4c1f22c88SEric Kohl * FILE: drivers/storage/fdc/fdc/fdo.c
5c1f22c88SEric Kohl * PURPOSE: Functional Device Object routines
6c1f22c88SEric Kohl * PROGRAMMERS: Eric Kohl
7c1f22c88SEric Kohl */
8c1f22c88SEric Kohl
9c1f22c88SEric Kohl /* INCLUDES *******************************************************************/
10c1f22c88SEric Kohl
11c1f22c88SEric Kohl #include "fdc.h"
12c1f22c88SEric Kohl
13c1f22c88SEric Kohl #include <stdio.h>
14c1f22c88SEric Kohl #define NDEBUG
15c1f22c88SEric Kohl #include <debug.h>
16c1f22c88SEric Kohl
17c1f22c88SEric Kohl /* FUNCTIONS ******************************************************************/
18c1f22c88SEric Kohl
19c1f22c88SEric Kohl NTSTATUS
20c1f22c88SEric Kohl NTAPI
ForwardIrpAndForget(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)21c1f22c88SEric Kohl ForwardIrpAndForget(
22c1f22c88SEric Kohl IN PDEVICE_OBJECT DeviceObject,
23c1f22c88SEric Kohl IN PIRP Irp)
24c1f22c88SEric Kohl {
25c1f22c88SEric Kohl PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
26c1f22c88SEric Kohl
27c1f22c88SEric Kohl ASSERT(LowerDevice);
28c1f22c88SEric Kohl
29c1f22c88SEric Kohl IoSkipCurrentIrpStackLocation(Irp);
30c1f22c88SEric Kohl return IoCallDriver(LowerDevice, Irp);
31c1f22c88SEric Kohl }
32c1f22c88SEric Kohl
33c1f22c88SEric Kohl
34c1f22c88SEric Kohl static
35c1f22c88SEric Kohl NTSTATUS
FdcFdoStartDevice(IN PDEVICE_OBJECT DeviceObject,IN PCM_RESOURCE_LIST ResourceList,IN PCM_RESOURCE_LIST ResourceListTranslated)36c1f22c88SEric Kohl FdcFdoStartDevice(
37c1f22c88SEric Kohl IN PDEVICE_OBJECT DeviceObject,
38c1f22c88SEric Kohl IN PCM_RESOURCE_LIST ResourceList,
39c1f22c88SEric Kohl IN PCM_RESOURCE_LIST ResourceListTranslated)
40c1f22c88SEric Kohl {
41c1f22c88SEric Kohl PFDO_DEVICE_EXTENSION DeviceExtension;
42c1f22c88SEric Kohl PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
43c1f22c88SEric Kohl // PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptorTranslated;
44c1f22c88SEric Kohl ULONG i;
45c1f22c88SEric Kohl
46c1f22c88SEric Kohl DPRINT("FdcFdoStartDevice called\n");
47c1f22c88SEric Kohl
48c1f22c88SEric Kohl DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
49c1f22c88SEric Kohl
50c1f22c88SEric Kohl ASSERT(DeviceExtension);
51c1f22c88SEric Kohl
52c1f22c88SEric Kohl if (ResourceList == NULL ||
53c1f22c88SEric Kohl ResourceListTranslated == NULL)
54c1f22c88SEric Kohl {
55c1f22c88SEric Kohl DPRINT1("No allocated resources sent to driver\n");
56c1f22c88SEric Kohl return STATUS_INSUFFICIENT_RESOURCES;
57c1f22c88SEric Kohl }
58c1f22c88SEric Kohl
59c1f22c88SEric Kohl if (ResourceList->Count != 1)
60c1f22c88SEric Kohl {
61c1f22c88SEric Kohl DPRINT1("Wrong number of allocated resources sent to driver\n");
62c1f22c88SEric Kohl return STATUS_INSUFFICIENT_RESOURCES;
63c1f22c88SEric Kohl }
64c1f22c88SEric Kohl
65c1f22c88SEric Kohl if (ResourceList->List[0].PartialResourceList.Version != 1 ||
66c1f22c88SEric Kohl ResourceList->List[0].PartialResourceList.Revision != 1 ||
67c1f22c88SEric Kohl ResourceListTranslated->List[0].PartialResourceList.Version != 1 ||
68c1f22c88SEric Kohl ResourceListTranslated->List[0].PartialResourceList.Revision != 1)
69c1f22c88SEric Kohl {
70c1f22c88SEric Kohl DPRINT1("Revision mismatch: %u.%u != 1.1 or %u.%u != 1.1\n",
71c1f22c88SEric Kohl ResourceList->List[0].PartialResourceList.Version,
72c1f22c88SEric Kohl ResourceList->List[0].PartialResourceList.Revision,
73c1f22c88SEric Kohl ResourceListTranslated->List[0].PartialResourceList.Version,
74c1f22c88SEric Kohl ResourceListTranslated->List[0].PartialResourceList.Revision);
75c1f22c88SEric Kohl return STATUS_REVISION_MISMATCH;
76c1f22c88SEric Kohl }
77c1f22c88SEric Kohl
78c1f22c88SEric Kohl for (i = 0; i < ResourceList->List[0].PartialResourceList.Count; i++)
79c1f22c88SEric Kohl {
80c1f22c88SEric Kohl PartialDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[i];
81c1f22c88SEric Kohl // PartialDescriptorTranslated = &ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[i];
82c1f22c88SEric Kohl
83c1f22c88SEric Kohl switch (PartialDescriptor->Type)
84c1f22c88SEric Kohl {
85c1f22c88SEric Kohl case CmResourceTypePort:
86c1f22c88SEric Kohl DPRINT("Port: 0x%lx (%lu)\n",
87c1f22c88SEric Kohl PartialDescriptor->u.Port.Start.u.LowPart,
88c1f22c88SEric Kohl PartialDescriptor->u.Port.Length);
89c1f22c88SEric Kohl if (PartialDescriptor->u.Port.Length >= 6)
90c1f22c88SEric Kohl DeviceExtension->ControllerInfo.BaseAddress = (PUCHAR)(ULONG_PTR)PartialDescriptor->u.Port.Start.QuadPart;
91c1f22c88SEric Kohl break;
92c1f22c88SEric Kohl
93c1f22c88SEric Kohl case CmResourceTypeInterrupt:
94c1f22c88SEric Kohl DPRINT("Interrupt: Level %lu Vector %lu\n",
95c1f22c88SEric Kohl PartialDescriptor->u.Interrupt.Level,
96c1f22c88SEric Kohl PartialDescriptor->u.Interrupt.Vector);
97c1f22c88SEric Kohl /*
98c1f22c88SEric Kohl Dirql = (KIRQL)PartialDescriptorTranslated->u.Interrupt.Level;
99c1f22c88SEric Kohl Vector = PartialDescriptorTranslated->u.Interrupt.Vector;
100c1f22c88SEric Kohl Affinity = PartialDescriptorTranslated->u.Interrupt.Affinity;
101c1f22c88SEric Kohl if (PartialDescriptorTranslated->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
102c1f22c88SEric Kohl InterruptMode = Latched;
103c1f22c88SEric Kohl else
104c1f22c88SEric Kohl InterruptMode = LevelSensitive;
105c1f22c88SEric Kohl ShareInterrupt = (PartialDescriptorTranslated->ShareDisposition == CmResourceShareShared);
106c1f22c88SEric Kohl */
107c1f22c88SEric Kohl break;
108c1f22c88SEric Kohl
109c1f22c88SEric Kohl case CmResourceTypeDma:
110c1f22c88SEric Kohl DPRINT("Dma: Channel %lu\n",
111c1f22c88SEric Kohl PartialDescriptor->u.Dma.Channel);
112c1f22c88SEric Kohl break;
113c1f22c88SEric Kohl }
114c1f22c88SEric Kohl }
115c1f22c88SEric Kohl
116c1f22c88SEric Kohl return STATUS_SUCCESS;
117c1f22c88SEric Kohl }
118c1f22c88SEric Kohl
119c1f22c88SEric Kohl
120c1f22c88SEric Kohl static
121c1f22c88SEric Kohl NTSTATUS
122c1f22c88SEric Kohl 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)123c1f22c88SEric Kohl FdcFdoConfigCallback(
124c1f22c88SEric Kohl PVOID Context,
125c1f22c88SEric Kohl PUNICODE_STRING PathName,
126c1f22c88SEric Kohl INTERFACE_TYPE BusType,
127c1f22c88SEric Kohl ULONG BusNumber,
128c1f22c88SEric Kohl PKEY_VALUE_FULL_INFORMATION *BusInformation,
129c1f22c88SEric Kohl CONFIGURATION_TYPE ControllerType,
130c1f22c88SEric Kohl ULONG ControllerNumber,
131c1f22c88SEric Kohl PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
132c1f22c88SEric Kohl CONFIGURATION_TYPE PeripheralType,
133c1f22c88SEric Kohl ULONG PeripheralNumber,
134c1f22c88SEric Kohl PKEY_VALUE_FULL_INFORMATION *PeripheralInformation)
135c1f22c88SEric Kohl {
136c1f22c88SEric Kohl PKEY_VALUE_FULL_INFORMATION ControllerFullDescriptor;
137c1f22c88SEric Kohl PCM_FULL_RESOURCE_DESCRIPTOR ControllerResourceDescriptor;
138c1f22c88SEric Kohl PKEY_VALUE_FULL_INFORMATION PeripheralFullDescriptor;
139c1f22c88SEric Kohl PCM_FULL_RESOURCE_DESCRIPTOR PeripheralResourceDescriptor;
140c1f22c88SEric Kohl PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
141c1f22c88SEric Kohl PCM_FLOPPY_DEVICE_DATA FloppyDeviceData;
142c1f22c88SEric Kohl PFDO_DEVICE_EXTENSION DeviceExtension;
143c1f22c88SEric Kohl PDRIVE_INFO DriveInfo;
144c1f22c88SEric Kohl BOOLEAN ControllerFound = FALSE;
145c1f22c88SEric Kohl ULONG i;
146c1f22c88SEric Kohl
147c1f22c88SEric Kohl DPRINT("FdcFdoConfigCallback() called\n");
148c1f22c88SEric Kohl
149c1f22c88SEric Kohl DeviceExtension = (PFDO_DEVICE_EXTENSION)Context;
150c1f22c88SEric Kohl
151c1f22c88SEric Kohl /* Get the controller resources */
152c1f22c88SEric Kohl ControllerFullDescriptor = ControllerInformation[IoQueryDeviceConfigurationData];
153c1f22c88SEric Kohl ControllerResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PCHAR)ControllerFullDescriptor +
154c1f22c88SEric Kohl ControllerFullDescriptor->DataOffset);
155c1f22c88SEric Kohl
156c1f22c88SEric Kohl for(i = 0; i < ControllerResourceDescriptor->PartialResourceList.Count; i++)
157c1f22c88SEric Kohl {
158c1f22c88SEric Kohl PartialDescriptor = &ControllerResourceDescriptor->PartialResourceList.PartialDescriptors[i];
159c1f22c88SEric Kohl
160c1f22c88SEric Kohl if (PartialDescriptor->Type == CmResourceTypePort)
161c1f22c88SEric Kohl {
162c1f22c88SEric Kohl if ((PUCHAR)(ULONG_PTR)PartialDescriptor->u.Port.Start.QuadPart == DeviceExtension->ControllerInfo.BaseAddress)
163c1f22c88SEric Kohl ControllerFound = TRUE;
164c1f22c88SEric Kohl }
165c1f22c88SEric Kohl }
166c1f22c88SEric Kohl
167c1f22c88SEric Kohl /* Leave, if the enumerated controller is not the one represented by the FDO */
168c1f22c88SEric Kohl if (ControllerFound == FALSE)
169c1f22c88SEric Kohl return STATUS_SUCCESS;
170c1f22c88SEric Kohl
171c1f22c88SEric Kohl /* Get the peripheral resources */
172c1f22c88SEric Kohl PeripheralFullDescriptor = PeripheralInformation[IoQueryDeviceConfigurationData];
173c1f22c88SEric Kohl PeripheralResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PCHAR)PeripheralFullDescriptor +
174c1f22c88SEric Kohl PeripheralFullDescriptor->DataOffset);
175c1f22c88SEric Kohl
176c1f22c88SEric Kohl /* learn about drives attached to controller */
177c1f22c88SEric Kohl for(i = 0; i < PeripheralResourceDescriptor->PartialResourceList.Count; i++)
178c1f22c88SEric Kohl {
179c1f22c88SEric Kohl PartialDescriptor = &PeripheralResourceDescriptor->PartialResourceList.PartialDescriptors[i];
180c1f22c88SEric Kohl
181c1f22c88SEric Kohl if (PartialDescriptor->Type != CmResourceTypeDeviceSpecific)
182c1f22c88SEric Kohl continue;
183c1f22c88SEric Kohl
184c1f22c88SEric Kohl FloppyDeviceData = (PCM_FLOPPY_DEVICE_DATA)(PartialDescriptor + 1);
185c1f22c88SEric Kohl
186c1f22c88SEric Kohl DriveInfo = &DeviceExtension->ControllerInfo.DriveInfo[DeviceExtension->ControllerInfo.NumberOfDrives];
187c1f22c88SEric Kohl
188c1f22c88SEric Kohl DriveInfo->ControllerInfo = &DeviceExtension->ControllerInfo;
189c1f22c88SEric Kohl DriveInfo->UnitNumber = DeviceExtension->ControllerInfo.NumberOfDrives;
190c1f22c88SEric Kohl DriveInfo->PeripheralNumber = PeripheralNumber;
191c1f22c88SEric Kohl
192c1f22c88SEric Kohl DriveInfo->FloppyDeviceData.MaxDensity = FloppyDeviceData->MaxDensity;
193c1f22c88SEric Kohl DriveInfo->FloppyDeviceData.MountDensity = FloppyDeviceData->MountDensity;
194c1f22c88SEric Kohl DriveInfo->FloppyDeviceData.StepRateHeadUnloadTime = FloppyDeviceData->StepRateHeadUnloadTime;
195c1f22c88SEric Kohl DriveInfo->FloppyDeviceData.HeadLoadTime = FloppyDeviceData->HeadLoadTime;
196c1f22c88SEric Kohl DriveInfo->FloppyDeviceData.MotorOffTime = FloppyDeviceData->MotorOffTime;
197c1f22c88SEric Kohl DriveInfo->FloppyDeviceData.SectorLengthCode = FloppyDeviceData->SectorLengthCode;
198c1f22c88SEric Kohl DriveInfo->FloppyDeviceData.SectorPerTrack = FloppyDeviceData->SectorPerTrack;
199c1f22c88SEric Kohl DriveInfo->FloppyDeviceData.ReadWriteGapLength = FloppyDeviceData->ReadWriteGapLength;
200c1f22c88SEric Kohl DriveInfo->FloppyDeviceData.FormatGapLength = FloppyDeviceData->FormatGapLength;
201c1f22c88SEric Kohl DriveInfo->FloppyDeviceData.FormatFillCharacter = FloppyDeviceData->FormatFillCharacter;
202c1f22c88SEric Kohl DriveInfo->FloppyDeviceData.HeadSettleTime = FloppyDeviceData->HeadSettleTime;
203c1f22c88SEric Kohl DriveInfo->FloppyDeviceData.MotorSettleTime = FloppyDeviceData->MotorSettleTime;
204c1f22c88SEric Kohl DriveInfo->FloppyDeviceData.MaximumTrackValue = FloppyDeviceData->MaximumTrackValue;
205c1f22c88SEric Kohl DriveInfo->FloppyDeviceData.DataTransferLength = FloppyDeviceData->DataTransferLength;
206c1f22c88SEric Kohl
207c1f22c88SEric Kohl /* Once it's all set up, acknowledge its existence in the controller info object */
208c1f22c88SEric Kohl DeviceExtension->ControllerInfo.NumberOfDrives++;
209c1f22c88SEric Kohl }
210c1f22c88SEric Kohl
211c1f22c88SEric Kohl DeviceExtension->ControllerInfo.Populated = TRUE;
212c1f22c88SEric Kohl
213c1f22c88SEric Kohl DPRINT("Detected %lu floppy drives!\n",
214c1f22c88SEric Kohl DeviceExtension->ControllerInfo.NumberOfDrives);
215c1f22c88SEric Kohl
216c1f22c88SEric Kohl return STATUS_SUCCESS;
217c1f22c88SEric Kohl }
218c1f22c88SEric Kohl
219c1f22c88SEric Kohl
220c1f22c88SEric Kohl static
221c1f22c88SEric Kohl NTSTATUS
PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs)222c1f22c88SEric Kohl PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs)
223c1f22c88SEric Kohl {
224c1f22c88SEric Kohl WCHAR Buffer[256];
225c1f22c88SEric Kohl UNICODE_STRING BufferU;
226c1f22c88SEric Kohl ULONG Index;
227c1f22c88SEric Kohl
228c1f22c88SEric Kohl Index = 0;
229c1f22c88SEric Kohl Index += swprintf(&Buffer[Index],
230c1f22c88SEric Kohl L"FDC\\GENERIC_FLOPPY_DRIVE");
231c1f22c88SEric Kohl Index++;
232c1f22c88SEric Kohl
233c1f22c88SEric Kohl Buffer[Index] = UNICODE_NULL;
234c1f22c88SEric Kohl
235c1f22c88SEric Kohl BufferU.Length = BufferU.MaximumLength = (USHORT) Index * sizeof(WCHAR);
236c1f22c88SEric Kohl BufferU.Buffer = Buffer;
237c1f22c88SEric Kohl
238c1f22c88SEric Kohl return DuplicateUnicodeString(0, &BufferU, HardwareIDs);
239c1f22c88SEric Kohl }
240c1f22c88SEric Kohl
241c1f22c88SEric Kohl
242c1f22c88SEric Kohl static
243c1f22c88SEric Kohl NTSTATUS
PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs)244c1f22c88SEric Kohl PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs)
245c1f22c88SEric Kohl {
246c1f22c88SEric Kohl WCHAR Buffer[256];
247c1f22c88SEric Kohl UNICODE_STRING BufferU;
248c1f22c88SEric Kohl ULONG Index;
249c1f22c88SEric Kohl
250c1f22c88SEric Kohl Index = 0;
251c1f22c88SEric Kohl Index += swprintf(&Buffer[Index],
252c1f22c88SEric Kohl L"GenFloppyDisk");
253c1f22c88SEric Kohl Index++;
254c1f22c88SEric Kohl
255c1f22c88SEric Kohl Buffer[Index] = UNICODE_NULL;
256c1f22c88SEric Kohl
257c1f22c88SEric Kohl BufferU.Length = BufferU.MaximumLength = (USHORT)Index * sizeof(WCHAR);
258c1f22c88SEric Kohl BufferU.Buffer = Buffer;
259c1f22c88SEric Kohl
260c1f22c88SEric Kohl return DuplicateUnicodeString(0, &BufferU, CompatibleIDs);
261c1f22c88SEric Kohl }
262c1f22c88SEric Kohl
263c1f22c88SEric Kohl
264c1f22c88SEric Kohl static
265c1f22c88SEric Kohl NTSTATUS
PciCreateInstanceIDString(PUNICODE_STRING InstanceID,ULONG PeripheralNumber)266c1f22c88SEric Kohl PciCreateInstanceIDString(PUNICODE_STRING InstanceID,
267c1f22c88SEric Kohl ULONG PeripheralNumber)
268c1f22c88SEric Kohl {
269c1f22c88SEric Kohl WCHAR Buffer[3];
270c1f22c88SEric Kohl
271c1f22c88SEric Kohl swprintf(Buffer, L"%02X", PeripheralNumber & 0xff);
272c1f22c88SEric Kohl
273c1f22c88SEric Kohl return RtlCreateUnicodeString(InstanceID, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
274c1f22c88SEric Kohl }
275c1f22c88SEric Kohl
276c1f22c88SEric Kohl
277c1f22c88SEric Kohl static
278c1f22c88SEric Kohl NTSTATUS
FdcFdoQueryBusRelations(IN PDEVICE_OBJECT DeviceObject,OUT PDEVICE_RELATIONS * DeviceRelations)279c1f22c88SEric Kohl FdcFdoQueryBusRelations(
280c1f22c88SEric Kohl IN PDEVICE_OBJECT DeviceObject,
281c1f22c88SEric Kohl OUT PDEVICE_RELATIONS *DeviceRelations)
282c1f22c88SEric Kohl {
283c1f22c88SEric Kohl PFDO_DEVICE_EXTENSION FdoDeviceExtension;
284c1f22c88SEric Kohl PPDO_DEVICE_EXTENSION PdoDeviceExtension;
285c1f22c88SEric Kohl INTERFACE_TYPE InterfaceType = Isa;
286c1f22c88SEric Kohl CONFIGURATION_TYPE ControllerType = DiskController;
287c1f22c88SEric Kohl CONFIGURATION_TYPE PeripheralType = FloppyDiskPeripheral;
288c1f22c88SEric Kohl PDEVICE_RELATIONS Relations;
289c1f22c88SEric Kohl PDRIVE_INFO DriveInfo;
290c1f22c88SEric Kohl PDEVICE_OBJECT Pdo;
291c1f22c88SEric Kohl WCHAR DeviceNameBuffer[80];
292c1f22c88SEric Kohl UNICODE_STRING DeviceName;
293c1f22c88SEric Kohl ULONG DeviceNumber = 0;
294c1f22c88SEric Kohl ULONG Size;
295c1f22c88SEric Kohl ULONG i;
296c1f22c88SEric Kohl NTSTATUS Status;
297c1f22c88SEric Kohl
298c1f22c88SEric Kohl DPRINT("FdcFdoQueryBusRelations() called\n");
299c1f22c88SEric Kohl
300c1f22c88SEric Kohl FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
301c1f22c88SEric Kohl
302c1f22c88SEric Kohl Status = IoQueryDeviceDescription(&InterfaceType,
303c1f22c88SEric Kohl NULL,
304c1f22c88SEric Kohl &ControllerType,
305c1f22c88SEric Kohl NULL,
306c1f22c88SEric Kohl &PeripheralType,
307c1f22c88SEric Kohl NULL,
308c1f22c88SEric Kohl FdcFdoConfigCallback,
309c1f22c88SEric Kohl FdoDeviceExtension);
310c1f22c88SEric Kohl if (!NT_SUCCESS(Status) && (Status != STATUS_NO_MORE_ENTRIES))
311c1f22c88SEric Kohl return Status;
312c1f22c88SEric Kohl
313c1f22c88SEric Kohl Size = sizeof(DEVICE_RELATIONS) +
314c1f22c88SEric Kohl sizeof(Relations->Objects) * (FdoDeviceExtension->ControllerInfo.NumberOfDrives - 1);
315c1f22c88SEric Kohl Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
316c1f22c88SEric Kohl if (Relations == NULL)
317c1f22c88SEric Kohl {
318c1f22c88SEric Kohl return STATUS_INSUFFICIENT_RESOURCES;
319c1f22c88SEric Kohl }
320c1f22c88SEric Kohl
321c1f22c88SEric Kohl Relations->Count = FdoDeviceExtension->ControllerInfo.NumberOfDrives;
322c1f22c88SEric Kohl
323c1f22c88SEric Kohl for (i = 0; i < FdoDeviceExtension->ControllerInfo.NumberOfDrives; i++)
324c1f22c88SEric Kohl {
325c1f22c88SEric Kohl DriveInfo = &FdoDeviceExtension->ControllerInfo.DriveInfo[i];
326c1f22c88SEric Kohl
327c1f22c88SEric Kohl if (DriveInfo->DeviceObject == NULL)
328c1f22c88SEric Kohl {
329c1f22c88SEric Kohl do
330c1f22c88SEric Kohl {
331c1f22c88SEric Kohl swprintf(DeviceNameBuffer, L"\\Device\\FloppyPDO%lu", DeviceNumber++);
332c1f22c88SEric Kohl RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
333c1f22c88SEric Kohl DPRINT("Device name: %S\n", DeviceNameBuffer);
334c1f22c88SEric Kohl
335c1f22c88SEric Kohl /* Create physical device object */
336c1f22c88SEric Kohl Status = IoCreateDevice(FdoDeviceExtension->Common.DeviceObject->DriverObject,
337c1f22c88SEric Kohl sizeof(PDO_DEVICE_EXTENSION),
338c1f22c88SEric Kohl &DeviceName,
339c1f22c88SEric Kohl FILE_DEVICE_MASS_STORAGE,
340c1f22c88SEric Kohl FILE_DEVICE_SECURE_OPEN,
341c1f22c88SEric Kohl FALSE,
342c1f22c88SEric Kohl &Pdo);
343c1f22c88SEric Kohl }
344c1f22c88SEric Kohl while (Status == STATUS_OBJECT_NAME_COLLISION);
345c1f22c88SEric Kohl
346c1f22c88SEric Kohl if (!NT_SUCCESS(Status))
347c1f22c88SEric Kohl {
348c1f22c88SEric Kohl DPRINT1("PDO creation failed (Status 0x%08lx)\n", Status);
349c1f22c88SEric Kohl goto done;
350c1f22c88SEric Kohl }
351c1f22c88SEric Kohl
352c1f22c88SEric Kohl DPRINT("PDO created: %S\n", DeviceNameBuffer);
353c1f22c88SEric Kohl
354c1f22c88SEric Kohl DriveInfo->DeviceObject = Pdo;
355c1f22c88SEric Kohl
356c1f22c88SEric Kohl PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Pdo->DeviceExtension;
357c1f22c88SEric Kohl RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
358c1f22c88SEric Kohl
359c1f22c88SEric Kohl PdoDeviceExtension->Common.IsFDO = FALSE;
360c1f22c88SEric Kohl PdoDeviceExtension->Common.DeviceObject = Pdo;
361c1f22c88SEric Kohl
362c1f22c88SEric Kohl PdoDeviceExtension->Fdo = FdoDeviceExtension->Common.DeviceObject;
363c1f22c88SEric Kohl PdoDeviceExtension->DriveInfo = DriveInfo;
364c1f22c88SEric Kohl
365c1f22c88SEric Kohl Pdo->Flags |= DO_DIRECT_IO;
366c1f22c88SEric Kohl Pdo->Flags |= DO_POWER_PAGABLE;
367c1f22c88SEric Kohl Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
368c1f22c88SEric Kohl
369c1f22c88SEric Kohl /* Add Device ID string */
370c1f22c88SEric Kohl RtlCreateUnicodeString(&PdoDeviceExtension->DeviceId,
371c1f22c88SEric Kohl L"FDC\\GENERIC_FLOPPY_DRIVE");
372c1f22c88SEric Kohl DPRINT("DeviceID: %S\n", PdoDeviceExtension->DeviceId.Buffer);
373c1f22c88SEric Kohl
374c1f22c88SEric Kohl /* Add Hardware IDs string */
375c1f22c88SEric Kohl Status = PciCreateHardwareIDsString(&PdoDeviceExtension->HardwareIds);
376c1f22c88SEric Kohl if (!NT_SUCCESS(Status))
377c1f22c88SEric Kohl {
378c1f22c88SEric Kohl // ErrorStatus = Status;
379c1f22c88SEric Kohl // ErrorOccurred = TRUE;
380c1f22c88SEric Kohl break;
381c1f22c88SEric Kohl }
382c1f22c88SEric Kohl
383c1f22c88SEric Kohl /* Add Compatible IDs string */
384c1f22c88SEric Kohl Status = PciCreateCompatibleIDsString(&PdoDeviceExtension->CompatibleIds);
385c1f22c88SEric Kohl if (!NT_SUCCESS(Status))
386c1f22c88SEric Kohl {
387c1f22c88SEric Kohl // ErrorStatus = Status;
388c1f22c88SEric Kohl // ErrorOccurred = TRUE;
389c1f22c88SEric Kohl break;
390c1f22c88SEric Kohl }
391c1f22c88SEric Kohl
392c1f22c88SEric Kohl /* Add Instance ID string */
393c1f22c88SEric Kohl Status = PciCreateInstanceIDString(&PdoDeviceExtension->InstanceId,
394c1f22c88SEric Kohl DriveInfo->PeripheralNumber);
395c1f22c88SEric Kohl if (!NT_SUCCESS(Status))
396c1f22c88SEric Kohl {
397c1f22c88SEric Kohl // ErrorStatus = Status;
398c1f22c88SEric Kohl // ErrorOccurred = TRUE;
399c1f22c88SEric Kohl break;
400c1f22c88SEric Kohl }
401c1f22c88SEric Kohl
402c1f22c88SEric Kohl #if 0
403c1f22c88SEric Kohl /* Add device description string */
404c1f22c88SEric Kohl Status = PciCreateDeviceDescriptionString(&PdoDeviceExtension->DeviceDescription, Device);
405c1f22c88SEric Kohl if (!NT_SUCCESS(Status))
406c1f22c88SEric Kohl {
407c1f22c88SEric Kohl // ErrorStatus = Status;
408c1f22c88SEric Kohl // ErrorOccurred = TRUE;
409c1f22c88SEric Kohl break;
410c1f22c88SEric Kohl }
411c1f22c88SEric Kohl
412c1f22c88SEric Kohl /* Add device location string */
413c1f22c88SEric Kohl Status = PciCreateDeviceLocationString(&PdoDeviceExtension->DeviceLocation, Device);
414c1f22c88SEric Kohl if (!NT_SUCCESS(Status))
415c1f22c88SEric Kohl {
416c1f22c88SEric Kohl // ErrorStatus = Status;
417c1f22c88SEric Kohl // ErrorOccurred = TRUE;
418c1f22c88SEric Kohl break;
419c1f22c88SEric Kohl }
420c1f22c88SEric Kohl #endif
421c1f22c88SEric Kohl }
422c1f22c88SEric Kohl
423c1f22c88SEric Kohl ObReferenceObject(DriveInfo->DeviceObject);
424c1f22c88SEric Kohl Relations->Objects[i] = DriveInfo->DeviceObject;
425c1f22c88SEric Kohl }
426c1f22c88SEric Kohl
427c1f22c88SEric Kohl done:
428c1f22c88SEric Kohl if (NT_SUCCESS(Status))
429c1f22c88SEric Kohl {
430c1f22c88SEric Kohl *DeviceRelations = Relations;
431c1f22c88SEric Kohl }
432c1f22c88SEric Kohl else
433c1f22c88SEric Kohl {
434c1f22c88SEric Kohl if (Relations != NULL)
435c1f22c88SEric Kohl ExFreePool(Relations);
436c1f22c88SEric Kohl }
437c1f22c88SEric Kohl
438c1f22c88SEric Kohl return Status;
439c1f22c88SEric Kohl }
440c1f22c88SEric Kohl
441c1f22c88SEric Kohl
442c1f22c88SEric Kohl NTSTATUS
443c1f22c88SEric Kohl NTAPI
FdcFdoPnp(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)444c1f22c88SEric Kohl FdcFdoPnp(
445c1f22c88SEric Kohl IN PDEVICE_OBJECT DeviceObject,
446c1f22c88SEric Kohl IN PIRP Irp)
447c1f22c88SEric Kohl {
448*7ed1883cSVictor Perevertkin PFDO_DEVICE_EXTENSION FdoExtension;
449c1f22c88SEric Kohl PIO_STACK_LOCATION IrpSp;
450c1f22c88SEric Kohl PDEVICE_RELATIONS DeviceRelations = NULL;
451c1f22c88SEric Kohl ULONG_PTR Information = 0;
452c1f22c88SEric Kohl NTSTATUS Status = STATUS_NOT_SUPPORTED;
453c1f22c88SEric Kohl
454c1f22c88SEric Kohl DPRINT("FdcFdoPnp()\n");
455c1f22c88SEric Kohl
456c1f22c88SEric Kohl IrpSp = IoGetCurrentIrpStackLocation(Irp);
457c1f22c88SEric Kohl
458c1f22c88SEric Kohl switch (IrpSp->MinorFunction)
459c1f22c88SEric Kohl {
460c1f22c88SEric Kohl case IRP_MN_START_DEVICE:
461c1f22c88SEric Kohl DPRINT(" IRP_MN_START_DEVICE received\n");
462*7ed1883cSVictor Perevertkin
463c1f22c88SEric Kohl /* Call lower driver */
464*7ed1883cSVictor Perevertkin Status = STATUS_UNSUCCESSFUL;
465*7ed1883cSVictor Perevertkin FdoExtension = DeviceObject->DeviceExtension;
466*7ed1883cSVictor Perevertkin
467*7ed1883cSVictor Perevertkin if (IoForwardIrpSynchronously(FdoExtension->LowerDevice, Irp))
468*7ed1883cSVictor Perevertkin {
469*7ed1883cSVictor Perevertkin Status = Irp->IoStatus.Status;
470c1f22c88SEric Kohl if (NT_SUCCESS(Status))
471c1f22c88SEric Kohl {
472c1f22c88SEric Kohl Status = FdcFdoStartDevice(DeviceObject,
473c1f22c88SEric Kohl IrpSp->Parameters.StartDevice.AllocatedResources,
474c1f22c88SEric Kohl IrpSp->Parameters.StartDevice.AllocatedResourcesTranslated);
475c1f22c88SEric Kohl }
476*7ed1883cSVictor Perevertkin }
477*7ed1883cSVictor Perevertkin
478c1f22c88SEric Kohl break;
479c1f22c88SEric Kohl
480c1f22c88SEric Kohl case IRP_MN_QUERY_REMOVE_DEVICE:
481c1f22c88SEric Kohl DPRINT(" IRP_MN_QUERY_REMOVE_DEVICE\n");
482c1f22c88SEric Kohl break;
483c1f22c88SEric Kohl
484c1f22c88SEric Kohl case IRP_MN_REMOVE_DEVICE:
485c1f22c88SEric Kohl DPRINT(" IRP_MN_REMOVE_DEVICE received\n");
486c1f22c88SEric Kohl break;
487c1f22c88SEric Kohl
488c1f22c88SEric Kohl case IRP_MN_CANCEL_REMOVE_DEVICE:
489c1f22c88SEric Kohl DPRINT(" IRP_MN_CANCEL_REMOVE_DEVICE\n");
490c1f22c88SEric Kohl break;
491c1f22c88SEric Kohl
492c1f22c88SEric Kohl case IRP_MN_STOP_DEVICE:
493c1f22c88SEric Kohl DPRINT(" IRP_MN_STOP_DEVICE received\n");
494c1f22c88SEric Kohl break;
495c1f22c88SEric Kohl
496c1f22c88SEric Kohl case IRP_MN_QUERY_STOP_DEVICE:
497c1f22c88SEric Kohl DPRINT(" IRP_MN_QUERY_STOP_DEVICE received\n");
498c1f22c88SEric Kohl break;
499c1f22c88SEric Kohl
500c1f22c88SEric Kohl case IRP_MN_CANCEL_STOP_DEVICE:
501c1f22c88SEric Kohl DPRINT(" IRP_MN_CANCEL_STOP_DEVICE\n");
502c1f22c88SEric Kohl break;
503c1f22c88SEric Kohl
504c1f22c88SEric Kohl case IRP_MN_QUERY_DEVICE_RELATIONS:
505c1f22c88SEric Kohl DPRINT(" IRP_MN_QUERY_DEVICE_RELATIONS\n");
506c1f22c88SEric Kohl
507c1f22c88SEric Kohl switch (IrpSp->Parameters.QueryDeviceRelations.Type)
508c1f22c88SEric Kohl {
509c1f22c88SEric Kohl case BusRelations:
510c1f22c88SEric Kohl DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
511c1f22c88SEric Kohl Status = FdcFdoQueryBusRelations(DeviceObject, &DeviceRelations);
512c1f22c88SEric Kohl Information = (ULONG_PTR)DeviceRelations;
513c1f22c88SEric Kohl break;
514c1f22c88SEric Kohl
515c1f22c88SEric Kohl case RemovalRelations:
516c1f22c88SEric Kohl DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
517c1f22c88SEric Kohl return ForwardIrpAndForget(DeviceObject, Irp);
518c1f22c88SEric Kohl
519c1f22c88SEric Kohl default:
520c1f22c88SEric Kohl DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
521c1f22c88SEric Kohl IrpSp->Parameters.QueryDeviceRelations.Type);
522c1f22c88SEric Kohl return ForwardIrpAndForget(DeviceObject, Irp);
523c1f22c88SEric Kohl }
524c1f22c88SEric Kohl break;
525c1f22c88SEric Kohl
526c1f22c88SEric Kohl case IRP_MN_SURPRISE_REMOVAL:
527c1f22c88SEric Kohl DPRINT(" IRP_MN_SURPRISE_REMOVAL received\n");
528c1f22c88SEric Kohl break;
529c1f22c88SEric Kohl
530c1f22c88SEric Kohl default:
531c1f22c88SEric Kohl DPRINT(" Unknown IOCTL 0x%lx\n", IrpSp->MinorFunction);
532c1f22c88SEric Kohl return ForwardIrpAndForget(DeviceObject, Irp);
533c1f22c88SEric Kohl }
534c1f22c88SEric Kohl
535c1f22c88SEric Kohl Irp->IoStatus.Information = Information;
536c1f22c88SEric Kohl Irp->IoStatus.Status = Status;
537c1f22c88SEric Kohl IoCompleteRequest(Irp, IO_NO_INCREMENT);
538c1f22c88SEric Kohl
539c1f22c88SEric Kohl return Status;
540c1f22c88SEric Kohl }
541c1f22c88SEric Kohl
542c1f22c88SEric Kohl /* EOF */
543