2 This module provide support function for hot plug device.
4 Copyright (c) 2006, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "PciHotPlugSupport.h"
19 EFI_PCI_HOT_PLUG_INIT_PROTOCOL
*gPciHotPlugInit
;
20 EFI_HPC_LOCATION
*gPciRootHpcPool
;
21 UINTN gPciRootHpcCount
;
22 ROOT_HPC_DATA
*gPciRootHpcData
;
25 Init HPC private data.
27 @param Event event object
28 @param Context HPC private data.
37 ROOT_HPC_DATA
*HpcData
;
39 HpcData
= (ROOT_HPC_DATA
*) Context
;
40 HpcData
->Initialized
= TRUE
;
45 Compare two device path
47 @param DevicePath1 the first device path want to be compared
48 @param DevicePath2 the first device path want to be compared
51 @retval FALSE different
54 EfiCompareDevicePath (
55 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath1
,
56 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath2
62 Size1
= GetDevicePathSize (DevicePath1
);
63 Size2
= GetDevicePathSize (DevicePath2
);
69 if (CompareMem (DevicePath1
, DevicePath2
, Size1
)) {
77 Init hot plug support and root hot plug private data.
81 InitializeHotPlugSupport (
86 EFI_HPC_LOCATION
*HpcList
;
90 // Locate the PciHotPlugInit Protocol
91 // If it doesn't exist, that means there is no
92 // hot plug controller supported on the platform
93 // the PCI Bus driver is running on. HotPlug Support
94 // is an optional feature, so absence of the protocol
95 // won't incur the penalty
97 gPciHotPlugInit
= NULL
;
98 gPciRootHpcPool
= NULL
;
100 gPciRootHpcData
= NULL
;
102 Status
= gBS
->LocateProtocol (
103 &gEfiPciHotPlugInitProtocolGuid
,
105 (VOID
**) &gPciHotPlugInit
108 if (EFI_ERROR (Status
)) {
109 return EFI_UNSUPPORTED
;
112 Status
= gPciHotPlugInit
->GetRootHpcList (
118 if (!EFI_ERROR (Status
)) {
120 gPciRootHpcPool
= HpcList
;
121 gPciRootHpcCount
= HpcCount
;
122 gPciRootHpcData
= AllocateZeroPool (sizeof (ROOT_HPC_DATA
) * gPciRootHpcCount
);
123 if (gPciRootHpcData
== NULL
) {
124 return EFI_OUT_OF_RESOURCES
;
132 Test whether device path is for root pci hot plug bus
134 @param HpbdevicePath tested device path
135 @param HpIndex Return the index of root hot plug in global array.
137 @retval TRUE device path is for root pci hot plug
138 @retval FALSE device path is not for root pci hot plug
141 IsRootPciHotPlugBus (
142 IN EFI_DEVICE_PATH_PROTOCOL
*HpbDevicePath
,
148 for (Index
= 0; Index
< gPciRootHpcCount
; Index
++) {
150 if (EfiCompareDevicePath (gPciRootHpcPool
[Index
].HpbDevicePath
, HpbDevicePath
)) {
152 if (HpIndex
!= NULL
) {
164 Test whether device path is for root pci hot plug controller
166 @param HpbdevicePath tested device path
167 @param HpIndex Return the index of root hot plug in global array.
169 @retval TRUE device path is for root pci hot plug controller
170 @retval FALSE device path is not for root pci hot plug controller
173 IsRootPciHotPlugController (
174 IN EFI_DEVICE_PATH_PROTOCOL
*HpcDevicePath
,
180 for (Index
= 0; Index
< gPciRootHpcCount
; Index
++) {
182 if (EfiCompareDevicePath (gPciRootHpcPool
[Index
].HpcDevicePath
, HpcDevicePath
)) {
184 if (HpIndex
!= NULL
) {
196 Wrapper for creating event object for HPC
198 @param HpIndex index of hot plug device in global array
199 @param Event event object
201 @return status of create event invoken
211 Status
= gBS
->CreateEvent (
215 gPciRootHpcData
+ HpIndex
,
216 &((gPciRootHpcData
+ HpIndex
)->Event
)
219 if (!EFI_ERROR (Status
)) {
220 *Event
= (gPciRootHpcData
+ HpIndex
)->Event
;
227 Wait for all root HPC initialized.
229 @param TimeoutInMicroSeconds microseconds to wait for all root hpc's initialization
232 AllRootHPCInitialized (
233 IN UINTN TimeoutInMicroSeconds
239 Delay
= (UINT32
) ((TimeoutInMicroSeconds
/ 30) + 1);
242 for (Index
= 0; Index
< gPciRootHpcCount
; Index
++) {
244 if (!gPciRootHpcData
[Index
].Initialized
) {
249 if (Index
== gPciRootHpcCount
) {
266 Check HPC capability register block
268 @param PciIoDevice PCI device instance
270 @retval EFI_SUCCESS PCI device is HPC
271 @retval EFI_NOT_FOUND PCI device is not HPC
275 PCI_IO_DEVICE
*PciIoDevice
283 return EFI_NOT_FOUND
;
287 Status
= LocateCapabilityRegBlock (
289 EFI_PCI_CAPABILITY_ID_HOTPLUG
,
295 // If the PPB has the hot plug controller build-in,
298 if (!EFI_ERROR (Status
)) {
302 return EFI_NOT_FOUND
;
306 Get resource padding for hot plug bus
308 @param PciIoDevice PCI device instance
310 @retval EFI_SUCCESS success get padding and set it into PCI device instance
311 @retval EFI_NOT_FOUND PCI device is not a hot plug bus.
314 GetResourcePaddingForHpb (
315 IN PCI_IO_DEVICE
*PciIoDevice
328 // TODO: PciIoDevice - add argument and description to function comment
329 // TODO: EFI_SUCCESS - add return value to function comment
330 // TODO: EFI_NOT_FOUND - add return value to function comment
335 EFI_HPC_PADDING_ATTRIBUTES Attributes
;
336 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
338 Status
= IsPciHotPlugBus (PciIoDevice
);
340 if (!EFI_ERROR (Status
)) {
341 PciAddress
= EFI_PCI_ADDRESS (PciIoDevice
->BusNumber
, PciIoDevice
->DeviceNumber
, PciIoDevice
->FunctionNumber
, 0);
342 Status
= gPciHotPlugInit
->GetResourcePadding (
344 PciIoDevice
->DevicePath
,
347 (VOID
**) &Descriptors
,
351 if (EFI_ERROR (Status
)) {
355 if ((State
& EFI_HPC_STATE_ENABLED
) && (State
& EFI_HPC_STATE_INITIALIZED
)) {
356 PciIoDevice
->ResourcePaddingDescriptors
= Descriptors
;
357 PciIoDevice
->PaddingAttributes
= Attributes
;
363 return EFI_NOT_FOUND
;
367 Test whether PCI device is hot plug bus.
369 @param PciIoDevice PCI device instance
371 @retval EFI_SUCCESS PCI device is hot plug bus
372 @retval EFI_NOT_FOUND PCI device is not hot plug bus
376 PCI_IO_DEVICE
*PciIoDevice
382 Status
= IsSHPC (PciIoDevice
);
385 // If the PPB has the hot plug controller build-in,
388 if (!EFI_ERROR (Status
)) {
393 // Otherwise, see if it is a Root HPC
395 Result
= IsRootPciHotPlugBus (PciIoDevice
->DevicePath
, NULL
);
401 return EFI_NOT_FOUND
;