Author: evb Date: Sat Aug 14 17:33:10 2010 New Revision: 48549
URL: http://svn.reactos.org/svn/reactos?rev=48549&view=rev Log: - IRP_MN_QUERY_RESOURCES support for PDO (PciQueryResources, PciAllocateCmResourceList), now remain IRP_MN_QUERY_RESOURCE_REQUIREMENTS to last device stack interogration from PNPMGR
Modified: trunk/reactos/drivers/bus/pcix/enum.c trunk/reactos/drivers/bus/pcix/utils.c
Modified: trunk/reactos/drivers/bus/pcix/enum.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/pcix/enum.c?rev... ============================================================================== --- trunk/reactos/drivers/bus/pcix/enum.c [iso-8859-1] (original) +++ trunk/reactos/drivers/bus/pcix/enum.c [iso-8859-1] Sat Aug 14 17:33:10 2010 @@ -49,14 +49,190 @@
/* FUNCTIONS ******************************************************************/
+PCM_RESOURCE_LIST +NTAPI +PciAllocateCmResourceList(IN ULONG Count, + IN ULONG BusNumber) +{ + SIZE_T Size; + PCM_RESOURCE_LIST ResourceList; + + /* Calculate the final size of the list, including each descriptor */ + Size = sizeof(CM_RESOURCE_LIST); + if (Count > 1) Size = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (Count - 1) + + sizeof(CM_RESOURCE_LIST); + + /* Allocate the list */ + ResourceList = ExAllocatePoolWithTag(PagedPool, Size, 'BicP'); + if (!ResourceList) return NULL; + + /* Initialize it */ + RtlZeroMemory(ResourceList, Size); + ResourceList->Count = 1; + ResourceList->List[0].BusNumber = BusNumber; + ResourceList->List[0].InterfaceType = PCIBus; + ResourceList->List[0].PartialResourceList.Version = 1; + ResourceList->List[0].PartialResourceList.Revision = 1; + ResourceList->List[0].PartialResourceList.Count = Count; + + /* Return it */ + return ResourceList; +} + NTSTATUS NTAPI PciQueryResources(IN PPCI_PDO_EXTENSION PdoExtension, OUT PCM_RESOURCE_LIST *Buffer) { - /* Not yet implemented */ - UNIMPLEMENTED; - while (TRUE); + PPCI_FUNCTION_RESOURCES PciResources; + BOOLEAN HaveVga, HaveMemSpace, HaveIoSpace; + USHORT BridgeControl, PciCommand; + ULONG Count, i; + PCM_PARTIAL_RESOURCE_DESCRIPTOR Partial, Resource, LastResource; + PCM_RESOURCE_LIST ResourceList; + UCHAR InterruptLine; + PAGED_CODE(); + + /* Assume failure */ + Count = 0; + HaveVga = FALSE; + *Buffer = NULL; + + /* Make sure there's some resources to query */ + PciResources = PdoExtension->Resources; + if (!PciResources) return STATUS_SUCCESS; + + /* Read the decodes */ + PciReadDeviceConfig(PdoExtension, + &PciCommand, + FIELD_OFFSET(PCI_COMMON_HEADER, Command), + sizeof(USHORT)); + + /* Check which ones are turned on */ + HaveIoSpace = PciCommand & PCI_ENABLE_IO_SPACE; + HaveMemSpace = PciCommand & PCI_ENABLE_MEMORY_SPACE; + + /* Loop maximum possible descriptors */ + for (i = 0; i < 7; i++) + { + /* Check if the decode for this descriptor is actually turned on */ + Partial = &PciResources->Current[i]; + if (((HaveMemSpace) && (Partial->Type == CmResourceTypeMemory)) || + ((HaveIoSpace) && (Partial->Type == CmResourceTypePort))) + { + /* One more fully active descriptor */ + Count++; + } + } + + /* If there's an interrupt pin associated, check at least one decode is on */ + if ((PdoExtension->InterruptPin) && ((HaveMemSpace) || (HaveIoSpace))) + { + /* Read the interrupt line for the pin, add a descriptor if it's valid */ + InterruptLine = PdoExtension->AdjustedInterruptLine; + if ((InterruptLine) && (InterruptLine != -1)) Count++; + } + + /* Check for PCI bridge */ + if (PdoExtension->HeaderType == PCI_BRIDGE_TYPE) + { + /* Read bridge settings, check if VGA is present */ + PciReadDeviceConfig(PdoExtension, + &BridgeControl, + FIELD_OFFSET(PCI_COMMON_HEADER, u.type1.BridgeControl), + sizeof(USHORT)); + if (BridgeControl & PCI_ENABLE_BRIDGE_VGA) + { + /* Remember for later */ + HaveVga = TRUE; + + /* One memory descriptor for 0xA0000, plus the two I/O port ranges */ + if (HaveMemSpace) Count++; + if (HaveIoSpace) Count += 2; + } + } + + /* If there's no descriptors in use, there's no resources, so return */ + if (!Count) return STATUS_SUCCESS; + + /* Allocate a resource list to hold the resources */ + ResourceList = PciAllocateCmResourceList(Count, + PdoExtension->ParentFdoExtension->BaseBus); + if (!ResourceList) return STATUS_INSUFFICIENT_RESOURCES; + + /* This is where the descriptors will be copied into */ + Resource = ResourceList->List[0].PartialResourceList.PartialDescriptors; + LastResource = Resource + Count + 1; + + /* Loop maximum possible descriptors */ + for (i = 0; i < 7; i++) + { + /* Check if the decode for this descriptor is actually turned on */ + Partial = &PciResources->Current[i]; + if (((HaveMemSpace) && (Partial->Type == CmResourceTypeMemory)) || + ((HaveIoSpace) && (Partial->Type == CmResourceTypePort))) + { + /* Copy the descriptor into the resource list */ + *Resource++ = *Partial; + } + } + + /* Check if earlier the code detected this was a PCI bridge with VGA on it */ + if (HaveVga) + { + /* Are the memory decodes enabled? */ + if (HaveMemSpace) + { + /* Build a memory descriptor for a 128KB framebuffer at 0xA0000 */ + Resource->Flags = CM_RESOURCE_MEMORY_READ_WRITE; + Resource->u.Generic.Start.HighPart = 0; + Resource->Type = CmResourceTypeMemory; + Resource->u.Generic.Start.LowPart = 0xA0000; + Resource->u.Generic.Length = 0x20000; + Resource++; + } + + /* Are the I/O decodes enabled? */ + if (HaveIoSpace) + { + /* Build an I/O descriptor for the graphic ports at 0x3B0 */ + Resource->Type = CmResourceTypePort; + Resource->Flags = CM_RESOURCE_PORT_POSITIVE_DECODE | CM_RESOURCE_PORT_10_BIT_DECODE; + Resource->u.Port.Start.QuadPart = 0x3B0u; + Resource->u.Port.Length = 0xC; + Resource++; + + /* Build an I/O descriptor for the graphic ports at 0x3C0 */ + Resource->Type = CmResourceTypePort; + Resource->Flags = CM_RESOURCE_PORT_POSITIVE_DECODE | CM_RESOURCE_PORT_10_BIT_DECODE; + Resource->u.Port.Start.QuadPart = 0x3C0u; + Resource->u.Port.Length = 0x20; + Resource++; + } + } + + /* If there's an interrupt pin associated, check at least one decode is on */ + if ((PdoExtension->InterruptPin) && ((HaveMemSpace) || (HaveIoSpace))) + { + /* Read the interrupt line for the pin, check if it's valid */ + InterruptLine = PdoExtension->AdjustedInterruptLine; + if ((InterruptLine) && (InterruptLine != -1)) + { + /* Make sure there's still space */ + ASSERT(Resource < LastResource); + + /* Add the interrupt descriptor */ + Resource->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; + Resource->Type = CmResourceTypeInterrupt; + Resource->ShareDisposition = CmResourceShareShared; + Resource->u.Interrupt.Affinity = -1; + Resource->u.Interrupt.Level = InterruptLine; + Resource->u.Interrupt.Vector = InterruptLine; + } + } + + /* Return the resouce list */ + *Buffer = ResourceList; return STATUS_SUCCESS; }
Modified: trunk/reactos/drivers/bus/pcix/utils.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/pcix/utils.c?re... ============================================================================== --- trunk/reactos/drivers/bus/pcix/utils.c [iso-8859-1] (original) +++ trunk/reactos/drivers/bus/pcix/utils.c [iso-8859-1] Sat Aug 14 17:33:10 2010 @@ -1355,7 +1355,7 @@ SlotInfo->BusNumber, SlotInfo->DeviceNumber, SlotInfo->SlotNumber); - + /* Check if this slot information matches the PDO being queried */ if ((ParentExtension->BaseBus == SlotInfo->BusNumber) && (PdoExtension->Slot.u.bits.DeviceNumber == SlotInfo->DeviceNumber >> 3) && @@ -1365,7 +1365,7 @@ *SlotNumber = SlotInfo->SlotNumber; return STATUS_SUCCESS; } - + /* Try the next slot */ SlotInfo++; } @@ -1475,7 +1475,7 @@ DEVICE_CAPABILITIES AttachedCaps; DEVICE_POWER_STATE NewPowerState, DevicePowerState, DeviceWakeLevel, DeviceWakeState; SYSTEM_POWER_STATE SystemWakeState, DeepestWakeState, CurrentState; - + /* Nothing is known at first */ DeviceWakeState = PowerDeviceUnspecified; SystemWakeState = DeepestWakeState = PowerSystemUnspecified; @@ -1523,7 +1523,7 @@ sizeof(DeviceCapability->DeviceState)); return STATUS_SUCCESS; } - + /* The PCI Device has power capabilities, so read which ones are supported */ DeviceCapability->DeviceD1 = PdoExtension->PowerCapabilities.Support.D1; DeviceCapability->DeviceD2 = PdoExtension->PowerCapabilities.Support.D2; @@ -1560,7 +1560,7 @@ /* Read the current mapping from the attached device */ DevicePowerState = AttachedCaps.DeviceState[CurrentState]; NewPowerState = DevicePowerState; - + /* The attachee suports D1, but this PDO does not */ if ((NewPowerState == PowerDeviceD1) && !(PdoExtension->PowerCapabilities.Support.D1)) @@ -1568,7 +1568,7 @@ /* Fall back to D2 */ NewPowerState = PowerDeviceD2; } - + /* The attachee supports D2, but this PDO does not */ if ((NewPowerState == PowerDeviceD2) && !(PdoExtension->PowerCapabilities.Support.D2)) @@ -1576,10 +1576,10 @@ /* Fall back to D3 */ NewPowerState = PowerDeviceD3; } - + /* Set the mapping based on the best state supported */ DeviceCapability->DeviceState[CurrentState] = NewPowerState; - + /* Check if sleep states are being processed, and a mapping was found */ if ((CurrentState < PowerSystemHibernate) && (NewPowerState != PowerDeviceUnspecified)) @@ -1587,8 +1587,8 @@ /* Save this state as being the deepest one found until now */ DeepestWakeState = CurrentState; } - - /* + + /* * Finally, check if the computed sleep state is within the states that * this device can wake the system from, and if it's higher or equal to * the sleep state mapping that came from the attachee, assuming that it @@ -1618,10 +1618,10 @@ DeviceWakeState = NewPowerState; } } - + /* Read the current wake level */ DeviceWakeLevel = PdoExtension->PowerState.DeviceWakeLevel; - + /* Check if the attachee's wake levels are valid, and the PDO's is higher */ if ((AttachedCaps.SystemWake != PowerSystemUnspecified) && (AttachedCaps.DeviceWake != PowerDeviceUnspecified) && @@ -1639,7 +1639,7 @@ /* Bump to D1 */ DeviceCapability->DeviceWake = PowerDeviceD1; } - + /* Now check if the wake level is D1, but the PDO doesn't support it */ if ((DeviceCapability->DeviceWake == PowerDeviceD1) && !(DeviceCapability->WakeFromD1)) @@ -1647,7 +1647,7 @@ /* Bump to D2 */ DeviceCapability->DeviceWake = PowerDeviceD2; } - + /* Now check if the wake level is D2, but the PDO doesn't support it */ if ((DeviceCapability->DeviceWake == PowerDeviceD2) && !(DeviceCapability->WakeFromD2)) @@ -1655,7 +1655,7 @@ /* Bump it to D3 */ DeviceCapability->DeviceWake = PowerDeviceD3; } - + /* Now check if the wake level is D3, but the PDO doesn't support it */ if ((DeviceCapability->DeviceWake == PowerDeviceD3) && !(DeviceCapability->WakeFromD3)) @@ -1676,12 +1676,12 @@ /* Use the wake state that had been computed earlier */ DeviceCapability->DeviceWake = DeviceWakeState; DeviceCapability->SystemWake = SystemWakeState; - + /* If that state was D3, then the device supports Hot/Cold D3 */ if (DeviceWakeState == PowerDeviceD3) DeviceCapability->WakeFromD3 = TRUE; } } - + /* * Finally, check for off states (lower than S3, such as hibernate) and * make sure that the device both supports waking from D3 as well as @@ -1694,12 +1694,12 @@ /* It doesn't, so pick the computed lowest wake state from earlier */ DeviceCapability->SystemWake = DeepestWakeState; } - + /* Set the PCI Specification mandated maximum latencies for transitions */ DeviceCapability->D1Latency = 0; DeviceCapability->D2Latency = 2; DeviceCapability->D3Latency = 100; - + /* Sanity check */ ASSERT(DeviceCapability->DeviceState[PowerSystemWorking] == PowerDeviceD0); } @@ -1710,7 +1710,7 @@ DeviceCapability->D2Latency = 0; DeviceCapability->D3Latency = 0; } - + /* This function always succeeds, even without power management support */ return STATUS_SUCCESS; }