2 * COPYRIGHT: See COPYING in the top level directory
4 * FILE: drivers/wdm/audio/backpln/portcls/irp.cpp
5 * PURPOSE: Port Class driver / IRP Handling
6 * PROGRAMMER: Andrew Greenwood
13 #include "private.hpp"
18 IN PDEVICE_OBJECT DeviceObject
,
21 DPRINT("PortClsCreate called\n");
23 return KsDispatchIrp(DeviceObject
, Irp
);
30 IN PDEVICE_OBJECT DeviceObject
,
34 PPCLASS_DEVICE_EXTENSION DeviceExt
;
35 PIO_STACK_LOCATION IoStack
;
36 IResourceList
* resource_list
= NULL
;
38 DeviceExt
= (PPCLASS_DEVICE_EXTENSION
) DeviceObject
->DeviceExtension
;
39 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
42 DPRINT("PortClsPnp called %u\n", IoStack
->MinorFunction
);
44 //PC_ASSERT(DeviceExt);
46 switch (IoStack
->MinorFunction
)
48 case IRP_MN_START_DEVICE
:
49 DPRINT("IRP_MN_START_DEVICE\n");
51 // Create the resource list
52 Status
= PcNewResourceList(
56 IoStack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
,
57 IoStack
->Parameters
.StartDevice
.AllocatedResources
);
58 if (!NT_SUCCESS(Status
))
60 DPRINT("PcNewResourceList failed [0x%8x]\n", Status
);
61 Irp
->IoStatus
.Status
= Status
;
62 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
66 // forward irp to lower device object
67 Status
= PcForwardIrpSynchronous(DeviceObject
, Irp
);
69 if (!NT_SUCCESS(Status
))
71 // lower device object failed to start
72 resource_list
->Release();
73 // complete the request
74 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
80 //PC_ASSERT(DeviceExt->StartDevice);
81 // Call the StartDevice routine
82 DPRINT("Calling StartDevice at 0x%8p\n", DeviceExt
->StartDevice
);
83 Status
= DeviceExt
->StartDevice(DeviceObject
, Irp
, resource_list
);
84 if (!NT_SUCCESS(Status
))
86 DPRINT("StartDevice returned a failure code [0x%8x]\n", Status
);
87 Irp
->IoStatus
.Status
= Status
;
88 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
92 // Assign the resource list to our extension
93 DeviceExt
->resources
= resource_list
;
95 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
96 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
99 case IRP_MN_REMOVE_DEVICE
:
101 DPRINT("IRP_MN_REMOVE_DEVICE\n");
103 DeviceExt
->resources
->Release();
104 IoDeleteDevice(DeviceObject
);
107 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
108 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
109 return STATUS_SUCCESS
;
111 case IRP_MN_QUERY_INTERFACE
:
112 DPRINT("IRP_MN_QUERY_INTERFACE\n");
113 Status
= PcForwardIrpSynchronous(DeviceObject
, Irp
);
114 return PcCompleteIrp(DeviceObject
, Irp
, Status
);
115 case IRP_MN_QUERY_DEVICE_RELATIONS
:
116 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n");
117 Status
= PcForwardIrpSynchronous(DeviceObject
, Irp
);
118 return PcCompleteIrp(DeviceObject
, Irp
, Status
);
119 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
120 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
121 Status
= PcForwardIrpSynchronous(DeviceObject
, Irp
);
122 return PcCompleteIrp(DeviceObject
, Irp
, Status
);
123 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
124 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
125 Status
= PcForwardIrpSynchronous(DeviceObject
, Irp
);
126 return PcCompleteIrp(DeviceObject
, Irp
, Status
);
129 DPRINT("unhandled function %u\n", IoStack
->MinorFunction
);
131 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
132 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
133 return STATUS_UNSUCCESSFUL
;
139 IN PDEVICE_OBJECT DeviceObject
,
142 DPRINT("PortClsPower called\n");
146 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
147 Irp
->IoStatus
.Information
= 0;
148 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
150 return STATUS_SUCCESS
;
156 IN PDEVICE_OBJECT DeviceObject
,
159 DPRINT("PortClsSysControl called\n");
163 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
164 Irp
->IoStatus
.Information
= 0;
165 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
167 return STATUS_SUCCESS
;
173 IN PDEVICE_OBJECT DeviceObject
,
176 PPCLASS_DEVICE_EXTENSION DeviceExtension
;
177 DPRINT("PortClsShutdown called\n");
179 // get device extension
180 DeviceExtension
= (PPCLASS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
182 if (DeviceExtension
->AdapterPowerManagement
)
184 // release adapter power management
185 DPRINT("Power %u\n", DeviceExtension
->AdapterPowerManagement
->Release());
188 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
189 Irp
->IoStatus
.Information
= 0;
190 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
192 return STATUS_SUCCESS
;
198 IN PDEVICE_OBJECT DeviceObject
,
201 PIO_STACK_LOCATION IoStack
;
203 DPRINT("PcDispatchIrp called - handling IRP in PortCls\n");
205 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
207 switch ( IoStack
->MajorFunction
)
211 return PortClsCreate(DeviceObject
, Irp
);
214 return PortClsPnp(DeviceObject
, Irp
);
217 return PortClsPower(DeviceObject
, Irp
);
219 case IRP_MJ_DEVICE_CONTROL
:
220 return KsDispatchIrp(DeviceObject
, Irp
);
223 return KsDispatchIrp(DeviceObject
, Irp
);
225 case IRP_MJ_SYSTEM_CONTROL
:
226 return PortClsSysControl(DeviceObject
, Irp
);
228 case IRP_MJ_SHUTDOWN
:
229 return PortClsShutdown(DeviceObject
, Irp
);
232 DPRINT("Unhandled function %x\n", IoStack
->MajorFunction
);
236 // If we reach here, we just complete the IRP
237 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
238 Irp
->IoStatus
.Information
= 0;
239 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
241 return STATUS_SUCCESS
;
248 IN PDEVICE_OBJECT DeviceObject
,
253 PC_ASSERT(DeviceObject
);
255 PC_ASSERT(Status
!= STATUS_PENDING
);
258 Irp
->IoStatus
.Status
= Status
;
259 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
267 IN PDEVICE_OBJECT DeviceObject
,
271 if (Irp
->PendingReturned
== TRUE
)
273 KeSetEvent ((PKEVENT
) Context
, IO_NO_INCREMENT
, FALSE
);
275 return STATUS_MORE_PROCESSING_REQUIRED
;
278 #undef IoSetCompletionRoutine
279 #define IoSetCompletionRoutine(_Irp, \
280 _CompletionRoutine, \
286 PIO_STACK_LOCATION _IrpSp; \
287 _IrpSp = IoGetNextIrpStackLocation(_Irp); \
288 _IrpSp->CompletionRoutine = (PIO_COMPLETION_ROUTINE)(_CompletionRoutine); \
289 _IrpSp->Context = (_Context); \
290 _IrpSp->Control = 0; \
291 if (_InvokeOnSuccess) _IrpSp->Control = SL_INVOKE_ON_SUCCESS; \
292 if (_InvokeOnError) _IrpSp->Control |= SL_INVOKE_ON_ERROR; \
293 if (_InvokeOnCancel) _IrpSp->Control |= SL_INVOKE_ON_CANCEL; \
300 PcForwardIrpSynchronous(
301 IN PDEVICE_OBJECT DeviceObject
,
305 PPCLASS_DEVICE_EXTENSION DeviceExt
;
308 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
310 DeviceExt
= (PPCLASS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
312 // initialize the notification event
313 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
315 IoCopyCurrentIrpStackLocationToNext(Irp
);
317 IoSetCompletionRoutine(Irp
, CompletionRoutine
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
319 // now call the driver
320 Status
= IoCallDriver(DeviceExt
->PrevDeviceObject
, Irp
);
321 // did the request complete yet
322 if (Status
== STATUS_PENDING
)
324 // not yet, lets wait a bit
325 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
326 Status
= Irp
->IoStatus
.Status
;