2 * PROJECT: ReactOS Floppy Disk Controller Driver
3 * LICENSE: GNU GPLv2 only as published by the Free Software Foundation
4 * FILE: drivers/storage/fdc/fdc/fdo.c
5 * PURPOSE: Functional Device Object routines
6 * PROGRAMMERS: Eric Kohl
9 /* INCLUDES *******************************************************************/
13 /* FUNCTIONS ******************************************************************/
15 static IO_COMPLETION_ROUTINE ForwardIrpAndWaitCompletion
;
20 ForwardIrpAndWaitCompletion(
21 IN PDEVICE_OBJECT DeviceObject
,
25 if (Irp
->PendingReturned
)
26 KeSetEvent((PKEVENT
)Context
, IO_NO_INCREMENT
, FALSE
);
27 return STATUS_MORE_PROCESSING_REQUIRED
;
33 IN PDEVICE_OBJECT DeviceObject
,
36 PDEVICE_OBJECT LowerDevice
= ((PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->LowerDevice
;
42 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
43 IoCopyCurrentIrpStackLocationToNext(Irp
);
45 DPRINT("Calling lower device %p\n", LowerDevice
);
46 IoSetCompletionRoutine(Irp
, ForwardIrpAndWaitCompletion
, &Event
, TRUE
, TRUE
, TRUE
);
48 Status
= IoCallDriver(LowerDevice
, Irp
);
49 if (Status
== STATUS_PENDING
)
51 Status
= KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
52 if (NT_SUCCESS(Status
))
53 Status
= Irp
->IoStatus
.Status
;
63 IN PDEVICE_OBJECT DeviceObject
,
66 PDEVICE_OBJECT LowerDevice
= ((PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->LowerDevice
;
70 IoSkipCurrentIrpStackLocation(Irp
);
71 return IoCallDriver(LowerDevice
, Irp
);
78 IN PDRIVER_OBJECT DriverObject
,
79 IN PDEVICE_OBJECT Pdo
)
81 PFDO_DEVICE_EXTENSION DeviceExtension
= NULL
;
82 PDEVICE_OBJECT Fdo
= NULL
;
85 DPRINT1("FdcAddDevice()\n");
90 /* Create functional device object */
91 Status
= IoCreateDevice(DriverObject
,
92 sizeof(FDO_DEVICE_EXTENSION
),
94 FILE_DEVICE_CONTROLLER
,
95 FILE_DEVICE_SECURE_OPEN
,
98 if (NT_SUCCESS(Status
))
100 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
101 RtlZeroMemory(DeviceExtension
, sizeof(FDO_DEVICE_EXTENSION
));
103 DeviceExtension
->Common
.IsFDO
= TRUE
;
105 DeviceExtension
->Fdo
= Fdo
;
106 DeviceExtension
->Pdo
= Pdo
;
109 Status
= IoAttachDeviceToDeviceStackSafe(Fdo
, Pdo
, &DeviceExtension
->LowerDevice
);
110 if (!NT_SUCCESS(Status
))
112 DPRINT1("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status
);
118 Fdo
->Flags
|= DO_DIRECT_IO
;
119 Fdo
->Flags
|= DO_POWER_PAGABLE
;
121 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
131 IN PDEVICE_OBJECT DeviceObject
,
132 IN PCM_RESOURCE_LIST ResourceList
,
133 IN PCM_RESOURCE_LIST ResourceListTranslated
)
135 PFDO_DEVICE_EXTENSION DeviceExtension
;
136 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
137 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptorTranslated
;
140 DPRINT1("FdcFdoStartDevice called\n");
142 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
144 ASSERT(DeviceExtension
);
146 if (ResourceList
== NULL
||
147 ResourceListTranslated
== NULL
)
149 DPRINT1("No allocated resources sent to driver\n");
150 return STATUS_INSUFFICIENT_RESOURCES
;
153 if (ResourceList
->Count
!= 1)
155 DPRINT1("Wrong number of allocated resources sent to driver\n");
156 return STATUS_INSUFFICIENT_RESOURCES
;
159 if (ResourceList
->List
[0].PartialResourceList
.Version
!= 1 ||
160 ResourceList
->List
[0].PartialResourceList
.Revision
!= 1 ||
161 ResourceListTranslated
->List
[0].PartialResourceList
.Version
!= 1 ||
162 ResourceListTranslated
->List
[0].PartialResourceList
.Revision
!= 1)
164 DPRINT1("Revision mismatch: %u.%u != 1.1 or %u.%u != 1.1\n",
165 ResourceList
->List
[0].PartialResourceList
.Version
,
166 ResourceList
->List
[0].PartialResourceList
.Revision
,
167 ResourceListTranslated
->List
[0].PartialResourceList
.Version
,
168 ResourceListTranslated
->List
[0].PartialResourceList
.Revision
);
169 return STATUS_REVISION_MISMATCH
;
172 for (i
= 0; i
< ResourceList
->List
[0].PartialResourceList
.Count
; i
++)
174 PartialDescriptor
= &ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
[i
];
175 PartialDescriptorTranslated
= &ResourceListTranslated
->List
[0].PartialResourceList
.PartialDescriptors
[i
];
177 switch (PartialDescriptor
->Type
)
179 case CmResourceTypePort
:
180 DPRINT1("Port: 0x%lx (%lu)\n",
181 PartialDescriptor
->u
.Port
.Start
.u
.LowPart
,
182 PartialDescriptor
->u
.Port
.Length
);
185 case CmResourceTypeInterrupt
:
186 DPRINT1("Interrupt: Level %lu Vector %lu\n",
187 PartialDescriptorTranslated
->u
.Interrupt
.Level
,
188 PartialDescriptorTranslated
->u
.Interrupt
.Vector
);
191 case CmResourceTypeDma
:
192 DPRINT1("Dma: Channel %lu\n",
193 PartialDescriptor
->u
.Dma
.Channel
);
198 return STATUS_SUCCESS
;
204 FdcFdoQueryBusRelations(
205 IN PDEVICE_OBJECT DeviceObject
,
206 OUT PDEVICE_RELATIONS
*DeviceRelations
)
208 DPRINT1("FdcFdoQueryBusRelations() called\n");
209 return STATUS_SUCCESS
;
216 IN PDEVICE_OBJECT DeviceObject
,
219 PIO_STACK_LOCATION IrpSp
;
220 PDEVICE_RELATIONS DeviceRelations
= NULL
;
221 ULONG_PTR Information
= 0;
222 NTSTATUS Status
= STATUS_NOT_SUPPORTED
;
224 DPRINT1("FdcFdoPnp()\n");
226 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
228 switch (IrpSp
->MinorFunction
)
230 case IRP_MN_START_DEVICE
:
231 DPRINT1(" IRP_MN_START_DEVICE received\n");
232 /* Call lower driver */
233 Status
= ForwardIrpAndWait(DeviceObject
, Irp
);
234 if (NT_SUCCESS(Status
))
236 Status
= FdcFdoStartDevice(DeviceObject
,
237 IrpSp
->Parameters
.StartDevice
.AllocatedResources
,
238 IrpSp
->Parameters
.StartDevice
.AllocatedResourcesTranslated
);
242 case IRP_MN_QUERY_REMOVE_DEVICE
:
243 DPRINT1(" IRP_MN_QUERY_REMOVE_DEVICE\n");
246 case IRP_MN_REMOVE_DEVICE
:
247 DPRINT1(" IRP_MN_REMOVE_DEVICE received\n");
250 case IRP_MN_CANCEL_REMOVE_DEVICE
:
251 DPRINT1(" IRP_MN_CANCEL_REMOVE_DEVICE\n");
254 case IRP_MN_STOP_DEVICE
:
255 DPRINT1(" IRP_MN_STOP_DEVICE received\n");
258 case IRP_MN_QUERY_STOP_DEVICE
:
259 DPRINT1(" IRP_MN_QUERY_STOP_DEVICE received\n");
262 case IRP_MN_CANCEL_STOP_DEVICE
:
263 DPRINT1(" IRP_MN_CANCEL_STOP_DEVICE\n");
266 case IRP_MN_QUERY_DEVICE_RELATIONS
:
267 DPRINT1(" IRP_MN_QUERY_DEVICE_RELATIONS\n");
269 switch (IrpSp
->Parameters
.QueryDeviceRelations
.Type
)
272 DPRINT1(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
273 Status
= FdcFdoQueryBusRelations(DeviceObject
, &DeviceRelations
);
274 Information
= (ULONG_PTR
)DeviceRelations
;
277 case RemovalRelations
:
278 DPRINT1(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
279 return ForwardIrpAndForget(DeviceObject
, Irp
);
282 DPRINT1(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
283 IrpSp
->Parameters
.QueryDeviceRelations
.Type
);
284 return ForwardIrpAndForget(DeviceObject
, Irp
);
288 case IRP_MN_SURPRISE_REMOVAL
:
289 DPRINT1(" IRP_MN_SURPRISE_REMOVAL received\n");
293 DPRINT(" Unknown IOCTL 0x%lx\n", IrpSp
->MinorFunction
);
294 return ForwardIrpAndForget(DeviceObject
, Irp
);
297 Irp
->IoStatus
.Information
= Information
;
298 Irp
->IoStatus
.Status
= Status
;
299 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);