ReactOS 0.4.15-dev-7994-gb388cb6
dispatch.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS PCI Bus Driver
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/bus/pci/dispatch.c
5 * PURPOSE: WDM Dispatch Routines
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include <pci.h>
12
13#define NDEBUG
14#include <debug.h>
15
16/* FUNCTIONS ******************************************************************/
17
18IO_COMPLETION_ROUTINE PciSetEventCompletion;
19
23 IN PIRP Irp,
25{
28
31
32 /* Set the event and return the appropriate status code */
35}
36
40 IN PIRP Irp)
41{
44 PAGED_CODE();
45 DPRINT1("PciCallDownIrpStack ...\n");
46 ASSERT_FDO(DeviceExtension);
47
48 /* Initialize the wait event */
50
51 /* Setup a completion routine */
54
55 /* Call the attached device */
56 Status = IoCallDriver(DeviceExtension->AttachedDeviceObject, Irp);
58 {
59 /* Wait for it to complete the request, and get its status */
61 Status = Irp->IoStatus.Status;
62 }
63
64 /* Return that status back to the caller */
65 return Status;
66}
67
71 IN PIRP Irp)
72{
73 PIO_STACK_LOCATION IoStackLocation;
75 DPRINT1("Pci PassIrp ...\n");
76
77 /* Get the stack location to check which function this is */
78 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
79 if (IoStackLocation->MajorFunction == IRP_MJ_POWER)
80 {
81 /* Power IRPs are special since we have to notify the Power Manager */
84 Status = PoCallDriver(DeviceExtension->AttachedDeviceObject, Irp);
85 }
86 else
87 {
88 /* For a normal IRP, just call the next driver in the stack */
90 Status = IoCallDriver(DeviceExtension->AttachedDeviceObject, Irp);
91 }
92
93 /* Return the status back to the caller */
94 return Status;
95}
96
100 IN PIRP Irp)
101{
102 PPCI_FDO_EXTENSION DeviceExtension;
103 PIO_STACK_LOCATION IoStackLocation;
104 PPCI_MJ_DISPATCH_TABLE IrpDispatchTable;
105 BOOLEAN PassToPdo;
107 PPCI_MN_DISPATCH_TABLE TableArray = NULL, Table;
108 USHORT MaxMinor;
109 PCI_DISPATCH_STYLE DispatchStyle = 0;
110 PCI_DISPATCH_FUNCTION DispatchFunction = NULL;
111 DPRINT1("PCI: Dispatch IRP\n");
112
113 /* Get the extension and I/O stack location for this IRP */
114 DeviceExtension = (PPCI_FDO_EXTENSION)DeviceObject->DeviceExtension;
115 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
116 ASSERT((DeviceExtension->ExtensionType == PciPdoExtensionType) ||
117 (DeviceExtension->ExtensionType == PciFdoExtensionType));
118
119 /* Deleted extensions don't respond to IRPs */
120 if (DeviceExtension->DeviceState == PciDeleted)
121 {
122 /* Fail this IRP */
124 PassToPdo = FALSE;
125 }
126 else
127 {
128 /* Otherwise, get the dispatch table for the extension */
129 IrpDispatchTable = DeviceExtension->IrpDispatchTable;
130
131 /* And choose which function table to use */
132 switch (IoStackLocation->MajorFunction)
133 {
134 case IRP_MJ_POWER:
135
136 /* Power Manager IRPs */
137 TableArray = IrpDispatchTable->PowerIrpDispatchTable;
138 MaxMinor = IrpDispatchTable->PowerIrpMaximumMinorFunction;
139 break;
140
141 case IRP_MJ_PNP:
142
143 /* Plug-and-Play Manager IRPs */
144 TableArray = IrpDispatchTable->PnpIrpDispatchTable;
145 MaxMinor = IrpDispatchTable->PnpIrpMaximumMinorFunction;
146 break;
147
149
150 /* WMI IRPs */
151 DispatchFunction = IrpDispatchTable->SystemControlIrpDispatchFunction;
152 DispatchStyle = IrpDispatchTable->SystemControlIrpDispatchStyle;
153 MaxMinor = 0xFFFF;
154 break;
155
156 default:
157
158 /* Unrecognized IRPs */
159 DispatchFunction = IrpDispatchTable->OtherIrpDispatchFunction;
160 DispatchStyle = IrpDispatchTable->OtherIrpDispatchStyle;
161 MaxMinor = 0xFFFF;
162 break;
163 }
164
165 /* Only deal with recognized IRPs */
166 if (MaxMinor != 0xFFFF)
167 {
168 /* Make sure the function is recognized */
169 if (IoStackLocation->MinorFunction > MaxMinor)
170 {
171 /* Pick the terminator, which should return unrecognized */
172 Table = &TableArray[MaxMinor + 1];
173 }
174 else
175 {
176 /* Pick the appropriate table for this function */
177 Table = &TableArray[IoStackLocation->MinorFunction];
178 }
179
180 /* From that table, get the function code and dispatch style */
181 DispatchStyle = Table->DispatchStyle;
182 DispatchFunction = Table->DispatchFunction;
183 }
184
185 /* Print out debugging information, and see if we should break */
186 if (PciDebugIrpDispatchDisplay(IoStackLocation,
187 DeviceExtension,
188 MaxMinor))
189 {
190 /* The developer/user wants us to break for this IRP, do it */
192 }
193
194 /* Check if this IRP should be sent up the stack first */
195 if (DispatchStyle == IRP_UPWARD)
196 {
197 /* Do it now before handling it ourselves */
198 PciCallDownIrpStack(DeviceExtension, Irp);
199 }
200
201 /* Call the our driver's handler for this IRP and deal with the IRP */
202 Status = DispatchFunction(Irp, IoStackLocation, DeviceExtension);
203 switch (DispatchStyle)
204 {
205 /* Complete IRPs are completely immediately by our driver */
206 case IRP_COMPLETE:
207 PassToPdo = FALSE;
208 break;
209
210 /* Downward IRPs are send to the attached FDO */
211 case IRP_DOWNWARD:
212 PassToPdo = TRUE;
213 break;
214
215 /* Upward IRPs are completed immediately by our driver */
216 case IRP_UPWARD:
217 PassToPdo = FALSE;
218 break;
219
220 /* Dispatch IRPs are immediately returned */
221 case IRP_DISPATCH:
222 return Status;
223
224 /* There aren't any other dispatch styles! */
225 default:
226 ASSERT(FALSE);
227 return Status;
228 }
229 }
230
231 /* Pending IRPs are returned immediately */
232 if (Status == STATUS_PENDING) return Status;
233
234 /* Handled IRPs return their status in the status block */
235 if (Status != STATUS_NOT_SUPPORTED) Irp->IoStatus.Status = Status;
236
237 /* Successful, or unhandled IRPs that are "DOWNWARD" are sent to the PDO */
238 if ((PassToPdo) && ((NT_SUCCESS(Status)) || (Status == STATUS_NOT_SUPPORTED)))
239 {
240 /* Let the PDO deal with it */
241 Status = PciPassIrpFromFdoToPdo(DeviceExtension, Irp);
242 }
243 else
244 {
245 /* Otherwise, the IRP is returned with its status */
246 Status = Irp->IoStatus.Status;
247
248 /* Power IRPs need to notify the Power Manager that the next IRP can go */
249 if (IoStackLocation->MajorFunction == IRP_MJ_POWER) PoStartNextPowerIrp(Irp);
250
251 /* And now this IRP can be completed */
253 }
254
255 /* And the status returned back to the caller */
256 return Status;
257}
258
260NTAPI
262 IN PIO_STACK_LOCATION IoStackLocation,
263 IN PPCI_FDO_EXTENSION DeviceExtension)
264{
266 UNREFERENCED_PARAMETER(IoStackLocation);
267 UNREFERENCED_PARAMETER(DeviceExtension);
268
269 /* Not supported */
270 DPRINT1("WARNING: PCI received unsupported IRP!\n");
271 //DbgBreakPoint();
273}
274
276NTAPI
278 IN PIO_STACK_LOCATION IoStackLocation,
279 IN PPCI_FDO_EXTENSION DeviceExtension)
280{
282 UNREFERENCED_PARAMETER(IoStackLocation);
283 UNREFERENCED_PARAMETER(DeviceExtension);
284
285 /* Not supported */
287}
288
289/* EOF */
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN NTAPI PciDebugIrpDispatchDisplay(IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_FDO_EXTENSION DeviceExtension, IN USHORT MaxMinor)
Definition: debug.c:124
NTSTATUS NTAPI PciIrpNotSupported(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_FDO_EXTENSION DeviceExtension)
Definition: dispatch.c:261
NTSTATUS NTAPI PciIrpInvalidDeviceRequest(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_FDO_EXTENSION DeviceExtension)
Definition: dispatch.c:277
IO_COMPLETION_ROUTINE PciSetEventCompletion
Definition: dispatch.c:18
NTSTATUS NTAPI PciCallDownIrpStack(IN PPCI_FDO_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: dispatch.c:39
NTSTATUS NTAPI PciPassIrpFromFdoToPdo(IN PPCI_FDO_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: dispatch.c:70
enum _PCI_DISPATCH_STYLE PCI_DISPATCH_STYLE
@ PciDeleted
Definition: pci.h:131
@ IRP_UPWARD
Definition: pci.h:145
@ IRP_COMPLETE
Definition: pci.h:143
@ IRP_DISPATCH
Definition: pci.h:146
@ IRP_DOWNWARD
Definition: pci.h:144
NTSTATUS(NTAPI * PCI_DISPATCH_FUNCTION)(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PVOID DeviceExtension)
Definition: pci.h:325
#define ASSERT_FDO(x)
Definition: pci.h:37
DRIVER_DISPATCH PciDispatchIrp
Definition: pci.h:541
struct _PCI_FDO_EXTENSION * PPCI_FDO_EXTENSION
@ PciFdoExtensionType
Definition: pci.h:95
@ PciPdoExtensionType
Definition: pci.h:94
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
Status
Definition: gdiplustypes.h:25
ASMGENDATA Table[]
Definition: genincdata.c:61
NTSYSAPI void WINAPI DbgBreakPoint(void)
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define ASSERT(a)
Definition: mode.c:44
#define KernelMode
Definition: asm.h:34
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
@ SynchronizationEvent
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCopyCurrentIrpStackLocationToNext(Irp)
Definition: ntifs_ex.h:413
#define IoCompleteRequest
Definition: irp.c:1240
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:758
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
BOOLEAN DeviceState
Definition: pci.h:197
ULONG ExtensionType
Definition: pci.h:195
struct _PCI_MJ_DISPATCH_TABLE * IrpDispatchTable
Definition: pci.h:196
ULONG PnpIrpMaximumMinorFunction
Definition: pci.h:345
PCI_DISPATCH_FUNCTION SystemControlIrpDispatchFunction
Definition: pci.h:350
PPCI_MN_DISPATCH_TABLE PowerIrpDispatchTable
Definition: pci.h:348
PCI_DISPATCH_STYLE OtherIrpDispatchStyle
Definition: pci.h:351
PCI_DISPATCH_FUNCTION OtherIrpDispatchFunction
Definition: pci.h:352
ULONG PowerIrpMaximumMinorFunction
Definition: pci.h:347
PPCI_MN_DISPATCH_TABLE PnpIrpDispatchTable
Definition: pci.h:346
PCI_DISPATCH_STYLE SystemControlIrpDispatchStyle
Definition: pci.h:349
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define IN
Definition: typedefs.h:39
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MJ_SYSTEM_CONTROL
#define IRP_MJ_POWER
@ Executive
Definition: ketypes.h:415