ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dispatch.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.