xref: /reactos/drivers/storage/floppy/fdc/fdo.c (revision 4f410007)
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