Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. dispatch.c
  5. Abstract:
  6. This module contains the global dispatch related
  7. routines for the pcmcia controller & it's child devices
  8. Author:
  9. Ravisankar Pudipeddi (ravisp) 11/1/96
  10. Environment:
  11. Kernel mode
  12. Revision History :
  13. --*/
  14. #include "pch.h"
  15. #ifdef ALLOC_PRAGMA
  16. #pragma alloc_text(PAGE, PcmciaInitDeviceDispatchTable)
  17. #endif
  18. //
  19. // Dispatch table array for FDOs/PDOs
  20. //
  21. PDRIVER_DISPATCH DeviceObjectDispatch[sizeof(DEVICE_OBJECT_TYPE)][IRP_MJ_MAXIMUM_FUNCTION + 1];
  22. VOID
  23. PcmciaInitDeviceDispatchTable(
  24. IN PDRIVER_OBJECT DriverObject
  25. )
  26. /*++
  27. Routine Description:
  28. Initializes the IRP dispatch tables for Pdo's & Fdo's
  29. Arguments:
  30. None
  31. Return value:
  32. None
  33. --*/
  34. {
  35. ULONG i;
  36. PAGED_CODE();
  37. //
  38. // Init the controller (FDO) dispatch table
  39. //
  40. DeviceObjectDispatch[FDO][IRP_MJ_CREATE] = PcmciaOpenCloseDispatch;
  41. DeviceObjectDispatch[FDO][IRP_MJ_CLOSE] = PcmciaOpenCloseDispatch;
  42. DeviceObjectDispatch[FDO][IRP_MJ_CLEANUP]= PcmciaCleanupDispatch;
  43. DeviceObjectDispatch[FDO][IRP_MJ_DEVICE_CONTROL] = PcmciaDeviceControl;
  44. DeviceObjectDispatch[FDO][IRP_MJ_SYSTEM_CONTROL] = PcmciaFdoSystemControl;
  45. DeviceObjectDispatch[FDO][IRP_MJ_PNP] = PcmciaFdoPnpDispatch;
  46. DeviceObjectDispatch[FDO][IRP_MJ_POWER] = PcmciaFdoPowerDispatch;
  47. //
  48. // Init the PDO dispatch table
  49. //
  50. DeviceObjectDispatch[PDO][IRP_MJ_DEVICE_CONTROL] = PcmciaPdoDeviceControl;
  51. DeviceObjectDispatch[PDO][IRP_MJ_SYSTEM_CONTROL] = PcmciaPdoSystemControl;
  52. DeviceObjectDispatch[PDO][IRP_MJ_PNP] = PcmciaPdoPnpDispatch;
  53. DeviceObjectDispatch[PDO][IRP_MJ_POWER] = PcmciaPdoPowerDispatch;
  54. //
  55. // Set the global dispatch table
  56. DriverObject->MajorFunction[IRP_MJ_CREATE] = PcmciaDispatch;
  57. DriverObject->MajorFunction[IRP_MJ_CLOSE] = PcmciaDispatch;
  58. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = PcmciaDispatch;
  59. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PcmciaDispatch;
  60. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = PcmciaDispatch;
  61. DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = PcmciaDispatch;
  62. DriverObject->MajorFunction[IRP_MJ_PNP] = PcmciaDispatch;
  63. DriverObject->MajorFunction[IRP_MJ_POWER] = PcmciaDispatch;
  64. }
  65. NTSTATUS
  66. PcmciaDispatch(
  67. IN PDEVICE_OBJECT DeviceObject,
  68. IN PIRP Irp
  69. )
  70. /*++
  71. Routine Description:
  72. Dispatch routine for all IRPs handled by this driver. This dispatch would then
  73. call the appropriate real dispatch routine which corresponds to the device object
  74. type (physical or functional).
  75. Arguments:
  76. DeviceObject - Pointer to the device object this dispatch is intended for
  77. Irp - Pointer to the IRP to be handled
  78. Return value:
  79. Returns the status from the 'real' dispatch routine which handles this IRP
  80. --*/
  81. {
  82. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  83. NTSTATUS status;
  84. DEVICE_OBJECT_TYPE devtype = IS_PDO(DeviceObject) ? PDO : FDO;
  85. UCHAR MajorFunction = irpStack->MajorFunction;
  86. if ((MajorFunction > IRP_MJ_MAXIMUM_FUNCTION) ||
  87. (DeviceObjectDispatch[devtype][MajorFunction] == NULL)) {
  88. DebugPrint((PCMCIA_DEBUG_INFO, "PCMCIA: Dispatch skipping unimplemented Irp MJ function %x\n", MajorFunction));
  89. status = Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  90. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  91. } else if (((devtype == PDO) && IsDeviceDeleted((PPDO_EXTENSION)DeviceObject->DeviceExtension)) ||
  92. ((devtype == FDO) && IsDeviceDeleted((PFDO_EXTENSION)DeviceObject->DeviceExtension))) {
  93. //
  94. // This do was supposed to have been already deleted
  95. // so we don't support any IRPs on it
  96. //
  97. DebugPrint((PCMCIA_DEBUG_INFO, "PCMCIA: Dispatch skipping Irp on deleted DO %08x MJ function %x\n", DeviceObject, MajorFunction));
  98. if (MajorFunction == IRP_MJ_POWER) {
  99. PoStartNextPowerIrp(Irp);
  100. }
  101. status = Irp->IoStatus.Status = STATUS_DELETE_PENDING;
  102. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  103. } else if (((KeGetCurrentIrql() == DISPATCH_LEVEL) && (MajorFunction != IRP_MJ_POWER)) ||
  104. (KeGetCurrentIrql() > DISPATCH_LEVEL)) {
  105. //
  106. // This is too high an IRQL to handle
  107. //
  108. if (MajorFunction == IRP_MJ_POWER) {
  109. PoStartNextPowerIrp(Irp);
  110. }
  111. status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
  112. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  113. } else {
  114. //
  115. // Dispatch the irp
  116. //
  117. status = ((*DeviceObjectDispatch[devtype][MajorFunction])(DeviceObject, Irp));
  118. }
  119. return status;
  120. }