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 DPRINT1("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
;
178 PPHYSICAL_CONNECTION Connection
;
179 DPRINT("PortClsShutdown called\n");
181 // get device extension
182 DeviceExtension
= (PPCLASS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
184 while(!IsListEmpty(&DeviceExtension
->PhysicalConnectionList
))
186 // get connection entry
187 Entry
= RemoveHeadList(&DeviceExtension
->PhysicalConnectionList
);
188 Connection
= (PPHYSICAL_CONNECTION
)CONTAINING_RECORD(Entry
, PHYSICAL_CONNECTION
, Entry
);
190 if (Connection
->FromSubDevice
)
193 Connection
->FromSubDevice
->Release();
196 if (Connection
->ToSubDevice
)
199 Connection
->ToSubDevice
->Release();
201 FreeItem(Connection
, TAG_PORTCLASS
);
204 if (DeviceExtension
->AdapterPowerManagement
)
206 // release adapter power management
207 DPRINT1("Power %u\n", DeviceExtension
->AdapterPowerManagement
->Release());
210 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
211 Irp
->IoStatus
.Information
= 0;
212 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
214 return STATUS_SUCCESS
;
220 IN PDEVICE_OBJECT DeviceObject
,
223 PIO_STACK_LOCATION IoStack
;
225 DPRINT("PcDispatchIrp called - handling IRP in PortCls\n");
227 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
229 switch ( IoStack
->MajorFunction
)
233 return PortClsCreate(DeviceObject
, Irp
);
236 return PortClsPnp(DeviceObject
, Irp
);
239 return PortClsPower(DeviceObject
, Irp
);
241 case IRP_MJ_DEVICE_CONTROL
:
242 return KsDispatchIrp(DeviceObject
, Irp
);
245 return KsDispatchIrp(DeviceObject
, Irp
);
247 case IRP_MJ_SYSTEM_CONTROL
:
248 return PortClsSysControl(DeviceObject
, Irp
);
250 case IRP_MJ_SHUTDOWN
:
251 return PortClsShutdown(DeviceObject
, Irp
);
254 DPRINT1("Unhandled function %x\n", IoStack
->MajorFunction
);
258 // If we reach here, we just complete the IRP
259 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
260 Irp
->IoStatus
.Information
= 0;
261 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
263 return STATUS_SUCCESS
;
270 IN PDEVICE_OBJECT DeviceObject
,
275 PC_ASSERT(DeviceObject
);
277 PC_ASSERT(Status
!= STATUS_PENDING
);
280 Irp
->IoStatus
.Status
= Status
;
281 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
289 IN PDEVICE_OBJECT DeviceObject
,
293 if (Irp
->PendingReturned
== TRUE
)
295 KeSetEvent ((PKEVENT
) Context
, IO_NO_INCREMENT
, FALSE
);
297 return STATUS_MORE_PROCESSING_REQUIRED
;
300 #undef IoSetCompletionRoutine
301 #define IoSetCompletionRoutine(_Irp, \
302 _CompletionRoutine, \
308 PIO_STACK_LOCATION _IrpSp; \
309 _IrpSp = IoGetNextIrpStackLocation(_Irp); \
310 _IrpSp->CompletionRoutine = (PIO_COMPLETION_ROUTINE)(_CompletionRoutine); \
311 _IrpSp->Context = (_Context); \
312 _IrpSp->Control = 0; \
313 if (_InvokeOnSuccess) _IrpSp->Control = SL_INVOKE_ON_SUCCESS; \
314 if (_InvokeOnError) _IrpSp->Control |= SL_INVOKE_ON_ERROR; \
315 if (_InvokeOnCancel) _IrpSp->Control |= SL_INVOKE_ON_CANCEL; \
322 PcForwardIrpSynchronous(
323 IN PDEVICE_OBJECT DeviceObject
,
327 PPCLASS_DEVICE_EXTENSION DeviceExt
;
330 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
332 DeviceExt
= (PPCLASS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
334 // initialize the notification event
335 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
337 IoCopyCurrentIrpStackLocationToNext(Irp
);
339 IoSetCompletionRoutine(Irp
, CompletionRoutine
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
341 // now call the driver
342 Status
= IoCallDriver(DeviceExt
->PrevDeviceObject
, Irp
);
343 // did the request complete yet
344 if (Status
== STATUS_PENDING
)
346 // not yet, lets wait a bit
347 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
348 Status
= Irp
->IoStatus
.Status
;