X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fdrivers%2Fbus%2Fpcix%2Ffdo.c;h=785dfca3c5290ebcdbe33d8810147850e6fbe9d6;hp=d7c51150830229efa322c02391e427b79cee3dad;hb=022f4b2ce569305456ad2588a78ba88fe7694e1b;hpb=23b4ebaf890f907a76f406fa5c8971b64a1c9b53 diff --git a/reactos/drivers/bus/pcix/fdo.c b/reactos/drivers/bus/pcix/fdo.c index d7c51150830..785dfca3c52 100644 --- a/reactos/drivers/bus/pcix/fdo.c +++ b/reactos/drivers/bus/pcix/fdo.c @@ -19,41 +19,41 @@ BOOLEAN PciBreakOnDefault; PCI_MN_DISPATCH_TABLE PciFdoDispatchPowerTable[] = { - {IRP_DISPATCH, PciFdoWaitWake}, - {IRP_DOWNWARD, PciIrpNotSupported}, - {IRP_DOWNWARD, PciFdoSetPowerState}, - {IRP_DOWNWARD, PciFdoIrpQueryPower}, - {IRP_DOWNWARD, PciIrpNotSupported} + {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciFdoWaitWake}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoSetPowerState}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryPower}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported} }; PCI_MN_DISPATCH_TABLE PciFdoDispatchPnpTable[] = { - {IRP_UPWARD, PciFdoIrpStartDevice}, - {IRP_DOWNWARD, PciFdoIrpQueryRemoveDevice}, - {IRP_DISPATCH, PciFdoIrpRemoveDevice}, - {IRP_DOWNWARD, PciFdoIrpCancelRemoveDevice}, - {IRP_DOWNWARD, PciFdoIrpStopDevice}, - {IRP_DOWNWARD, PciFdoIrpQueryStopDevice}, - {IRP_DOWNWARD, PciFdoIrpCancelStopDevice}, - {IRP_DOWNWARD, PciFdoIrpQueryDeviceRelations}, - {IRP_DISPATCH, PciFdoIrpQueryInterface}, - {IRP_UPWARD, PciFdoIrpQueryCapabilities}, - {IRP_DOWNWARD, PciIrpNotSupported}, - {IRP_DOWNWARD, PciIrpNotSupported}, - {IRP_DOWNWARD, PciIrpNotSupported}, - {IRP_DOWNWARD, PciIrpNotSupported}, - {IRP_DOWNWARD, PciIrpNotSupported}, - {IRP_DOWNWARD, PciIrpNotSupported}, - {IRP_DOWNWARD, PciIrpNotSupported}, - {IRP_DOWNWARD, PciIrpNotSupported}, - {IRP_DOWNWARD, PciIrpNotSupported}, - {IRP_DOWNWARD, PciIrpNotSupported}, - {IRP_DOWNWARD, PciIrpNotSupported}, - {IRP_DOWNWARD, PciIrpNotSupported}, - {IRP_UPWARD, PciFdoIrpDeviceUsageNotification}, - {IRP_DOWNWARD, PciFdoIrpSurpriseRemoval}, - {IRP_DOWNWARD, PciFdoIrpQueryLegacyBusInformation}, - {IRP_DOWNWARD, PciIrpNotSupported} + {IRP_UPWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpStartDevice}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryRemoveDevice}, + {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciFdoIrpRemoveDevice}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpCancelRemoveDevice}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpStopDevice}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryStopDevice}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpCancelStopDevice}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryDeviceRelations}, + {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryInterface}, + {IRP_UPWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryCapabilities}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, + {IRP_UPWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpDeviceUsageNotification}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpSurpriseRemoval}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryLegacyBusInformation}, + {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported} }; PCI_MJ_DISPATCH_TABLE PciFdoDispatchTable = @@ -63,9 +63,9 @@ PCI_MJ_DISPATCH_TABLE PciFdoDispatchTable = IRP_MN_QUERY_POWER, PciFdoDispatchPowerTable, IRP_DOWNWARD, - PciIrpNotSupported, + (PCI_DISPATCH_FUNCTION)PciIrpNotSupported, IRP_DOWNWARD, - PciIrpNotSupported + (PCI_DISPATCH_FUNCTION)PciIrpNotSupported }; /* FUNCTIONS ******************************************************************/ @@ -76,9 +76,48 @@ PciFdoIrpStartDevice(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_FDO_EXTENSION DeviceExtension) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_NOT_SUPPORTED; + NTSTATUS Status; + PCM_RESOURCE_LIST Resources; + PAGED_CODE(); + + /* The device stack must be starting the FDO in a success path */ + if (!NT_SUCCESS(Irp->IoStatus.Status)) return STATUS_NOT_SUPPORTED; + + /* Attempt to switch the state machine to the started state */ + Status = PciBeginStateTransition(DeviceExtension, PciStarted); + if (!NT_SUCCESS(Status)) return Status; + + /* Check for any boot-provided resources */ + Resources = IoStackLocation->Parameters.StartDevice.AllocatedResources; + if ((Resources) && !(PCI_IS_ROOT_FDO(DeviceExtension))) + { + /* These resources would only be for non-root FDOs, unhandled for now */ + ASSERT(Resources->Count == 1); + UNIMPLEMENTED; + while (TRUE); + } + + /* Initialize the arbiter for this FDO */ + Status = PciInitializeArbiterRanges(DeviceExtension, Resources); + if (!NT_SUCCESS(Status)) + { + /* Cancel the transition if this failed */ + PciCancelStateTransition(DeviceExtension, PciStarted); + return Status; + } + + /* Again, check for boot-provided resources for non-root FDO */ + if ((Resources) && !(PCI_IS_ROOT_FDO(DeviceExtension))) + { + /* Unhandled for now */ + ASSERT(Resources->Count == 1); + UNIMPLEMENTED; + while (TRUE); + } + + /* Commit the transition to the started state */ + PciCommitStateTransition(DeviceExtension, PciStarted); + return STATUS_SUCCESS; } NTSTATUS @@ -88,7 +127,6 @@ PciFdoIrpQueryRemoveDevice(IN PIRP Irp, IN PPCI_FDO_EXTENSION DeviceExtension) { UNIMPLEMENTED; - while (TRUE); return STATUS_NOT_SUPPORTED; } @@ -153,9 +191,25 @@ PciFdoIrpQueryDeviceRelations(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_FDO_EXTENSION DeviceExtension) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_NOT_SUPPORTED; + NTSTATUS Status; + PAGED_CODE(); + + /* Are bus relations being queried? */ + if (IoStackLocation->Parameters.QueryDeviceRelations.Type != BusRelations) + { + /* The FDO is a bus, so only bus relations can be obtained */ + Status = STATUS_NOT_SUPPORTED; + } + else + { + /* Scan the PCI bus and build the device relations for the caller */ + Status = PciQueryDeviceRelations(DeviceExtension, + (PDEVICE_RELATIONS*) + &Irp->IoStatus.Information); + } + + /* Return the enumeration status back */ + return Status; } NTSTATUS @@ -164,9 +218,73 @@ PciFdoIrpQueryInterface(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_FDO_EXTENSION DeviceExtension) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_NOT_SUPPORTED; + NTSTATUS Status; + PAGED_CODE(); + ASSERT(DeviceExtension->ExtensionType == PciFdoExtensionType); + + /* Deleted extensions don't respond to IRPs */ + if (DeviceExtension->DeviceState == PciDeleted) + { + /* Hand it back to try to deal with it */ + return PciPassIrpFromFdoToPdo(DeviceExtension, Irp); + } + + /* Query our driver for this interface */ + Status = PciQueryInterface(DeviceExtension, + IoStackLocation->Parameters.QueryInterface. + InterfaceType, + IoStackLocation->Parameters.QueryInterface. + Size, + IoStackLocation->Parameters.QueryInterface. + Version, + IoStackLocation->Parameters.QueryInterface. + InterfaceSpecificData, + IoStackLocation->Parameters.QueryInterface. + Interface, + FALSE); + if (NT_SUCCESS(Status)) + { + /* We found it, let the PDO handle it */ + Irp->IoStatus.Status = Status; + return PciPassIrpFromFdoToPdo(DeviceExtension, Irp); + } + else if (Status == STATUS_NOT_SUPPORTED) + { + /* Otherwise, we can't handle it, let someone else down the stack try */ + Status = PciCallDownIrpStack(DeviceExtension, Irp); + if (Status == STATUS_NOT_SUPPORTED) + { + /* They can't either, try a last-resort interface lookup */ + Status = PciQueryInterface(DeviceExtension, + IoStackLocation->Parameters.QueryInterface. + InterfaceType, + IoStackLocation->Parameters.QueryInterface. + Size, + IoStackLocation->Parameters.QueryInterface. + Version, + IoStackLocation->Parameters.QueryInterface. + InterfaceSpecificData, + IoStackLocation->Parameters.QueryInterface. + Interface, + TRUE); + } + } + + /* Has anyone claimed this interface yet? */ + if (Status == STATUS_NOT_SUPPORTED) + { + /* No, return the original IRP status */ + Status = Irp->IoStatus.Status; + } + else + { + /* Yes, set the new IRP status */ + Irp->IoStatus.Status = Status; + } + + /* Complete this IRP */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; } NTSTATUS @@ -175,9 +293,23 @@ PciFdoIrpQueryCapabilities(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_FDO_EXTENSION DeviceExtension) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_NOT_SUPPORTED; + PDEVICE_CAPABILITIES Capabilities; + PAGED_CODE(); + ASSERT_FDO(DeviceExtension); + + /* Get the capabilities */ + Capabilities = IoStackLocation->Parameters.DeviceCapabilities.Capabilities; + + /* Inherit wake levels and power mappings from the higher-up capabilities */ + DeviceExtension->PowerState.SystemWakeLevel = Capabilities->SystemWake; + DeviceExtension->PowerState.DeviceWakeLevel = Capabilities->DeviceWake; + RtlCopyMemory(DeviceExtension->PowerState.SystemStateMapping, + Capabilities->DeviceState, + sizeof(DeviceExtension->PowerState.SystemStateMapping)); + + /* Dump the capabilities and return success */ + PciDebugDumpQueryCapabilities(Capabilities); + return STATUS_SUCCESS; } NTSTATUS @@ -302,6 +434,7 @@ PciAddDevice(IN PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT AttachedTo; PPCI_FDO_EXTENSION FdoExtension; PPCI_FDO_EXTENSION ParentExtension; + PPCI_PDO_EXTENSION PdoExtension; PDEVICE_OBJECT DeviceObject; UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)]; PKEY_VALUE_PARTIAL_INFORMATION ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buffer; @@ -315,6 +448,8 @@ PciAddDevice(IN PDRIVER_OBJECT DriverObject, /* Zero out variables so failure path knows what to do */ AttachedTo = NULL; + FdoExtension = NULL; + PdoExtension = NULL; do { /* Check if there's already a device extension for this bus */ @@ -322,9 +457,44 @@ PciAddDevice(IN PDRIVER_OBJECT DriverObject, &PciGlobalLock); if (ParentExtension) { - /* More than one PCI bus, this is not expected yet */ - UNIMPLEMENTED; - while (TRUE); + /* Make sure we find a real PDO */ + PdoExtension = PhysicalDeviceObject->DeviceExtension; + ASSERT_PDO(PdoExtension); + + /* Make sure it's a PCI-to-PCI bridge */ + if ((PdoExtension->BaseClass != PCI_CLASS_BRIDGE_DEV) || + (PdoExtension->SubClass != PCI_SUBCLASS_BR_PCI_TO_PCI)) + { + /* This should never happen */ + DPRINT1("PCI - PciAddDevice for Non-Root/Non-PCI-PCI bridge,\n" + " Class %02x, SubClass %02x, will not add.\n", + PdoExtension->BaseClass, + PdoExtension->SubClass); + ASSERT((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) && + (PdoExtension->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI)); + + /* Enter the failure path */ + Status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + + /* Subordinate bus on the bridge */ + DPRINT1("PCI - AddDevice (new bus is child of bus 0x%x).\n", + ParentExtension->BaseBus); + + /* Make sure PCI bus numbers are configured */ + if (!PciAreBusNumbersConfigured(PdoExtension)) + { + /* This is a critical failure */ + DPRINT1("PCI - Bus numbers not configured for bridge (0x%x.0x%x.0x%x)\n", + ParentExtension->BaseBus, + PdoExtension->Slot.u.bits.DeviceNumber, + PdoExtension->Slot.u.bits.FunctionNumber); + + /* Enter the failure path */ + Status = STATUS_INVALID_DEVICE_REQUEST; + break; + } } /* Create the FDO for the bus */ @@ -350,11 +520,15 @@ PciAddDevice(IN PDRIVER_OBJECT DriverObject, ASSERT(AttachedTo != NULL); if (!AttachedTo) break; FdoExtension->AttachedDeviceObject = AttachedTo; + + /* Check if this is a child bus, or the root */ if (ParentExtension) { - /* More than one PCI bus, this is not expected yet */ - UNIMPLEMENTED; - while (TRUE); + /* The child inherits root data */ + FdoExtension->BaseBus = PdoExtension->Dependent.type1.SecondaryBus; + FdoExtension->BusRootFdoExtension = ParentExtension->BusRootFdoExtension; + PdoExtension->BridgeFdoExtension = FdoExtension; + FdoExtension->ParentFdoExtension = ParentExtension; } else { @@ -371,7 +545,9 @@ PciAddDevice(IN PDRIVER_OBJECT DriverObject, { /* Root PDO in ReactOS does not assign boot resources */ UNIMPLEMENTED; - while (TRUE); +// while (TRUE); + DPRINT1("Encountered during setup\n"); + Descriptor = NULL; } if (Descriptor) @@ -448,12 +624,16 @@ PciAddDevice(IN PDRIVER_OBJECT DriverObject, /* The Bus FDO is now initialized */ DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; - DPRINT1("PCI Root FDO Added: %p %p\n", DeviceObject, FdoExtension); return STATUS_SUCCESS; } while (FALSE); /* This is the failure path */ ASSERT(!NT_SUCCESS(Status)); + + /* Check if the FDO extension exists */ + if (FdoExtension) DPRINT1("Should destroy secondaries\n"); + + /* Delete device objects */ if (AttachedTo) IoDetachDevice(AttachedTo); if (DeviceObject) IoDeleteDevice(DeviceObject); return Status;