2 The AhciPei driver is used to manage ATA hard disk device working under AHCI
5 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions
9 of the BSD License which accompanies this distribution. The
10 full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 #include <Guid/S3StorageDeviceInitList.h>
22 #include <Library/LockBoxLib.h>
25 Collect the ports that need to be enumerated on a controller for S3 phase.
27 @param[in] HcDevicePath Device path of the controller.
28 @param[in] HcDevicePathLength Length of the device path specified by
30 @param[out] PortBitMap Bitmap that indicates the ports that need
31 to be enumerated on the controller.
33 @retval The number of ports that need to be enumerated.
37 AhciS3GetEumeratePorts (
38 IN EFI_DEVICE_PATH_PROTOCOL
*HcDevicePath
,
39 IN UINTN HcDevicePathLength
,
40 OUT UINT32
*PortBitMap
45 UINTN S3InitDevicesLength
;
46 EFI_DEVICE_PATH_PROTOCOL
*S3InitDevices
;
47 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
48 UINTN DevicePathInstLength
;
50 SATA_DEVICE_PATH
*SataDeviceNode
;
55 // From the LockBox, get the list of device paths for devices need to be
59 S3InitDevicesLength
= sizeof (DummyData
);
61 Status
= RestoreLockBox (&gS3StorageDeviceInitListGuid
, &DummyData
, &S3InitDevicesLength
);
62 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
65 S3InitDevices
= AllocatePool (S3InitDevicesLength
);
66 if (S3InitDevices
== NULL
) {
70 Status
= RestoreLockBox (&gS3StorageDeviceInitListGuid
, S3InitDevices
, &S3InitDevicesLength
);
71 if (EFI_ERROR (Status
)) {
76 if (S3InitDevices
== NULL
) {
81 // Only enumerate the ports that exist in the device list.
85 // Fetch the size of current device path instance.
87 Status
= GetDevicePathInstanceSize (
89 &DevicePathInstLength
,
92 if (EFI_ERROR (Status
)) {
96 DevicePathInst
= S3InitDevices
;
97 S3InitDevices
= (EFI_DEVICE_PATH_PROTOCOL
*)((UINTN
) S3InitDevices
+ DevicePathInstLength
);
99 if (HcDevicePathLength
>= DevicePathInstLength
) {
104 // Compare the device paths to determine if the device is managed by this
110 HcDevicePathLength
- sizeof (EFI_DEVICE_PATH_PROTOCOL
)
113 // Get the port number.
115 while (DevicePathInst
->Type
!= END_DEVICE_PATH_TYPE
) {
116 if ((DevicePathInst
->Type
== MESSAGING_DEVICE_PATH
) &&
117 (DevicePathInst
->SubType
== MSG_SATA_DP
)) {
118 SataDeviceNode
= (SATA_DEVICE_PATH
*) DevicePathInst
;
120 // For now, the driver only support upto AHCI_MAX_PORTS ports and
121 // devices directly connected to a HBA.
123 if ((SataDeviceNode
->HBAPortNumber
>= AHCI_MAX_PORTS
) ||
124 (SataDeviceNode
->PortMultiplierPortNumber
!= 0xFFFF)) {
127 *PortBitMap
|= (UINT32
)BIT0
<< SataDeviceNode
->HBAPortNumber
;
130 DevicePathInst
= NextDevicePathNode (DevicePathInst
);
133 } while (!EntireEnd
);
136 // Return the number of ports need to be enumerated on this controller.
138 return AhciGetNumberOfPortsFromMap (*PortBitMap
);