ReactOS  0.4.13-dev-73-gcfe54aa
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 
18 IO_COMPLETION_ROUTINE PciSetEventCompletion;
19 
21 NTAPI
23  IN PIRP Irp,
25 {
27  ASSERT(Event);
28 
31 
32  /* Set the event and return the appropriate status code */
35 }
36 
38 NTAPI
40  IN PIRP Irp)
41 {
43  KEVENT Event;
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);
57  if (Status == STATUS_PENDING)
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 
69 NTAPI
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 
98 NTAPI
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 */
191  DbgBreakPoint();
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 
259 NTSTATUS
260 NTAPI
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();
272  return STATUS_NOT_SUPPORTED;
273 }
274 
275 NTSTATUS
276 NTAPI
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 */
#define IN
Definition: typedefs.h:38
ASMGENDATA Table[]
Definition: genincdata.c:61
#define TRUE
Definition: types.h:120
ULONG PnpIrpMaximumMinorFunction
Definition: pci.h:343
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
NTSTATUS NTAPI PoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: power.c:485
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
PCI_DISPATCH_FUNCTION SystemControlIrpDispatchFunction
Definition: pci.h:348
struct _PCI_MJ_DISPATCH_TABLE * IrpDispatchTable
Definition: pci.h:194
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
ULONG PowerIrpMaximumMinorFunction
Definition: pci.h:345
void DbgBreakPoint()
Definition: mach.c:558
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define PAGED_CODE()
Definition: video.h:57
BOOLEAN DeviceState
Definition: pci.h:195
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
NTSTATUS NTAPI PciPassIrpFromFdoToPdo(IN PPCI_FDO_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: dispatch.c:70
#define ASSERT_FDO(x)
Definition: pci.h:35
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
PCI_DISPATCH_FUNCTION OtherIrpDispatchFunction
Definition: pci.h:350
struct _PCI_FDO_EXTENSION * PPCI_FDO_EXTENSION
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
PPCI_MN_DISPATCH_TABLE PowerIrpDispatchTable
Definition: pci.h:346
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:434
enum _PCI_DISPATCH_STYLE PCI_DISPATCH_STYLE
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
void * PVOID
Definition: retypes.h:9
PCI_DISPATCH_STYLE SystemControlIrpDispatchStyle
Definition: pci.h:347
BOOLEAN NTAPI PciDebugIrpDispatchDisplay(IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_FDO_EXTENSION DeviceExtension, IN USHORT MaxMinor)
Definition: debug.c:124
NTSTATUS NTAPI PciCallDownIrpStack(IN PPCI_FDO_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: dispatch.c:39
PCI_DISPATCH_STYLE OtherIrpDispatchStyle
Definition: pci.h:349
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define IRP_MJ_POWER
NTSTATUS NTAPI PciDispatchIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: dispatch.c:99
ULONG ExtensionType
Definition: pci.h:193
PPCI_MN_DISPATCH_TABLE PnpIrpDispatchTable
Definition: pci.h:344
#define IRP_MJ_SYSTEM_CONTROL
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:626
unsigned short USHORT
Definition: pedump.c:61
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define DPRINT1
Definition: precomp.h:8
IO_COMPLETION_ROUTINE PciSetEventCompletion
Definition: dispatch.c:18
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
NTSTATUS(NTAPI * PCI_DISPATCH_FUNCTION)(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PVOID DeviceExtension)
Definition: pci.h:323
#define IO_NO_INCREMENT
Definition: iotypes.h:565
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