Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendispatch.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS PCI Bus Driver 00003 * LICENSE: BSD - See COPYING.ARM in the top level directory 00004 * FILE: drivers/bus/pci/dispatch.c 00005 * PURPOSE: WDM Dispatch Routines 00006 * PROGRAMMERS: ReactOS Portable Systems Group 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include <pci.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* GLOBALS ********************************************************************/ 00016 00017 /* FUNCTIONS ******************************************************************/ 00018 00019 NTSTATUS 00020 NTAPI 00021 PciSetEventCompletion(IN PDEVICE_OBJECT DeviceObject, 00022 IN PIRP Irp, 00023 IN PVOID Context) 00024 { 00025 PKEVENT Event = (PVOID)Context; 00026 ASSERT(Event); 00027 00028 /* Set the event and return the appropriate status code */ 00029 KeSetEvent(Event, FALSE, IO_NO_INCREMENT); 00030 return STATUS_MORE_PROCESSING_REQUIRED; 00031 } 00032 00033 NTSTATUS 00034 NTAPI 00035 PciCallDownIrpStack(IN PPCI_FDO_EXTENSION DeviceExtension, 00036 IN PIRP Irp) 00037 { 00038 NTSTATUS Status; 00039 KEVENT Event; 00040 PAGED_CODE(); 00041 DPRINT1("PciCallDownIrpStack ...\n"); 00042 ASSERT_FDO(DeviceExtension); 00043 00044 /* Initialize the wait event */ 00045 KeInitializeEvent(&Event, SynchronizationEvent, 0); 00046 00047 /* Setup a completion routine */ 00048 IoCopyCurrentIrpStackLocationToNext(Irp); 00049 IoSetCompletionRoutine(Irp, PciSetEventCompletion, &Event, TRUE, TRUE, TRUE); 00050 00051 /* Call the attached device */ 00052 Status = IoCallDriver(DeviceExtension->AttachedDeviceObject, Irp); 00053 if (Status == STATUS_PENDING) 00054 { 00055 /* Wait for it to complete the request, and get its status */ 00056 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 00057 Status = Irp->IoStatus.Status; 00058 } 00059 00060 /* Return that status back to the caller */ 00061 return Status; 00062 } 00063 00064 NTSTATUS 00065 NTAPI 00066 PciPassIrpFromFdoToPdo(IN PPCI_FDO_EXTENSION DeviceExtension, 00067 IN PIRP Irp) 00068 { 00069 PIO_STACK_LOCATION IoStackLocation; 00070 NTSTATUS Status; 00071 DPRINT1("Pci PassIrp ...\n"); 00072 00073 /* Get the stack location to check which function this is */ 00074 IoStackLocation = IoGetCurrentIrpStackLocation(Irp); 00075 if (IoStackLocation->MajorFunction == IRP_MJ_POWER) 00076 { 00077 /* Power IRPs are special since we have to notify the Power Manager */ 00078 IoCopyCurrentIrpStackLocationToNext(Irp); 00079 PoStartNextPowerIrp(Irp); 00080 Status = PoCallDriver(DeviceExtension->AttachedDeviceObject, Irp); 00081 } 00082 else 00083 { 00084 /* For a normal IRP, just call the next driver in the stack */ 00085 IoSkipCurrentIrpStackLocation(Irp); 00086 Status = IoCallDriver(DeviceExtension->AttachedDeviceObject, Irp); 00087 } 00088 00089 /* Return the status back to the caller */ 00090 return Status; 00091 } 00092 00093 NTSTATUS 00094 NTAPI 00095 PciDispatchIrp(IN PDEVICE_OBJECT DeviceObject, 00096 IN PIRP Irp) 00097 { 00098 PPCI_FDO_EXTENSION DeviceExtension; 00099 PIO_STACK_LOCATION IoStackLocation; 00100 PPCI_MJ_DISPATCH_TABLE IrpDispatchTable; 00101 BOOLEAN PassToPdo; 00102 NTSTATUS Status; 00103 PPCI_MN_DISPATCH_TABLE TableArray = NULL, Table; 00104 USHORT MaxMinor; 00105 PCI_DISPATCH_STYLE DispatchStyle = 0; 00106 PCI_DISPATCH_FUNCTION DispatchFunction = NULL; 00107 DPRINT1("PCI: Dispatch IRP\n"); 00108 00109 /* Get the extension and I/O stack location for this IRP */ 00110 DeviceExtension = (PPCI_FDO_EXTENSION)DeviceObject->DeviceExtension; 00111 IoStackLocation = IoGetCurrentIrpStackLocation(Irp); 00112 ASSERT((DeviceExtension->ExtensionType == PciPdoExtensionType) || 00113 (DeviceExtension->ExtensionType == PciFdoExtensionType)); 00114 00115 /* Deleted extensions don't respond to IRPs */ 00116 if (DeviceExtension->DeviceState == PciDeleted) 00117 { 00118 /* Fail this IRP */ 00119 Status = STATUS_NO_SUCH_DEVICE; 00120 PassToPdo = FALSE; 00121 } 00122 else 00123 { 00124 /* Otherwise, get the dispatch table for the extension */ 00125 IrpDispatchTable = DeviceExtension->IrpDispatchTable; 00126 00127 /* And choose which function table to use */ 00128 switch (IoStackLocation->MajorFunction) 00129 { 00130 case IRP_MJ_POWER: 00131 00132 /* Power Manager IRPs */ 00133 TableArray = IrpDispatchTable->PowerIrpDispatchTable; 00134 MaxMinor = IrpDispatchTable->PowerIrpMaximumMinorFunction; 00135 break; 00136 00137 case IRP_MJ_PNP: 00138 00139 /* Plug-and-Play Manager IRPs */ 00140 TableArray = IrpDispatchTable->PnpIrpDispatchTable; 00141 MaxMinor = IrpDispatchTable->PnpIrpMaximumMinorFunction; 00142 break; 00143 00144 case IRP_MJ_SYSTEM_CONTROL: 00145 00146 /* WMI IRPs */ 00147 DispatchFunction = IrpDispatchTable->SystemControlIrpDispatchFunction; 00148 DispatchStyle = IrpDispatchTable->SystemControlIrpDispatchStyle; 00149 MaxMinor = 0xFFFF; 00150 break; 00151 00152 default: 00153 00154 /* Unrecognized IRPs */ 00155 DispatchFunction = IrpDispatchTable->OtherIrpDispatchFunction; 00156 DispatchStyle = IrpDispatchTable->OtherIrpDispatchStyle; 00157 MaxMinor = 0xFFFF; 00158 break; 00159 } 00160 00161 /* Only deal with recognized IRPs */ 00162 if (MaxMinor != 0xFFFF) 00163 { 00164 /* Make sure the function is recognized */ 00165 if (IoStackLocation->MinorFunction > MaxMinor) 00166 { 00167 /* Pick the terminator, which should return unrecognized */ 00168 Table = &TableArray[MaxMinor + 1]; 00169 } 00170 else 00171 { 00172 /* Pick the appropriate table for this function */ 00173 Table = &TableArray[IoStackLocation->MinorFunction]; 00174 } 00175 00176 /* From that table, get the function code and dispatch style */ 00177 DispatchStyle = Table->DispatchStyle; 00178 DispatchFunction = Table->DispatchFunction; 00179 } 00180 00181 /* Print out debugging information, and see if we should break */ 00182 if (PciDebugIrpDispatchDisplay(IoStackLocation, 00183 DeviceExtension, 00184 MaxMinor)) 00185 { 00186 /* The developer/user wants us to break for this IRP, do it */ 00187 DbgBreakPoint(); 00188 } 00189 00190 /* Check if this IRP should be sent up the stack first */ 00191 if (DispatchStyle == IRP_UPWARD) 00192 { 00193 /* Do it now before handling it ourselves */ 00194 PciCallDownIrpStack(DeviceExtension, Irp); 00195 } 00196 00197 /* Call the our driver's handler for this IRP and deal with the IRP */ 00198 Status = DispatchFunction(Irp, IoStackLocation, DeviceExtension); 00199 switch (DispatchStyle) 00200 { 00201 /* Complete IRPs are completely immediately by our driver */ 00202 case IRP_COMPLETE: 00203 PassToPdo = FALSE; 00204 break; 00205 00206 /* Downward IRPs are send to the attached FDO */ 00207 case IRP_DOWNWARD: 00208 PassToPdo = TRUE; 00209 break; 00210 00211 /* Upward IRPs are completed immediately by our driver */ 00212 case IRP_UPWARD: 00213 PassToPdo = FALSE; 00214 break; 00215 00216 /* Dispatch IRPs are immediately returned */ 00217 case IRP_DISPATCH: 00218 return Status; 00219 00220 /* There aren't any other dispatch styles! */ 00221 default: 00222 ASSERT(FALSE); 00223 return Status; 00224 } 00225 } 00226 00227 /* Pending IRPs are returned immediately */ 00228 if (Status == STATUS_PENDING) return Status; 00229 00230 /* Handled IRPs return their status in the status block */ 00231 if (Status != STATUS_NOT_SUPPORTED) Irp->IoStatus.Status = Status; 00232 00233 /* Successful, or unhandled IRPs that are "DOWNWARD" are sent to the PDO */ 00234 if ((PassToPdo) && ((NT_SUCCESS(Status)) || (Status == STATUS_NOT_SUPPORTED))) 00235 { 00236 /* Let the PDO deal with it */ 00237 Status = PciPassIrpFromFdoToPdo(DeviceExtension, Irp); 00238 } 00239 else 00240 { 00241 /* Otherwise, the IRP is returned with its status */ 00242 Status = Irp->IoStatus.Status; 00243 00244 /* Power IRPs need to notify the Power Manager that the next IRP can go */ 00245 if (IoStackLocation->MajorFunction == IRP_MJ_POWER) PoStartNextPowerIrp(Irp); 00246 00247 /* And now this IRP can be completed */ 00248 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00249 } 00250 00251 /* And the status returned back to the caller */ 00252 return Status; 00253 } 00254 00255 NTSTATUS 00256 NTAPI 00257 PciIrpNotSupported(IN PIRP Irp, 00258 IN PIO_STACK_LOCATION IoStackLocation, 00259 IN PPCI_FDO_EXTENSION DeviceExtension) 00260 { 00261 /* Not supported */ 00262 DPRINT1("WARNING: PCI received unsupported IRP!\n"); 00263 //DbgBreakPoint(); 00264 return STATUS_NOT_SUPPORTED; 00265 } 00266 00267 NTSTATUS 00268 NTAPI 00269 PciIrpInvalidDeviceRequest(IN PIRP Irp, 00270 IN PIO_STACK_LOCATION IoStackLocation, 00271 IN PPCI_FDO_EXTENSION DeviceExtension) 00272 { 00273 /* Not supported */ 00274 return STATUS_INVALID_DEVICE_REQUEST; 00275 } 00276 00277 /* EOF */ Generated on Sat May 26 2012 04:19:00 for ReactOS by
1.7.6.1
|