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 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #include <Guid/S3StorageDeviceInitList.h>
15 #include <Library/LockBoxLib.h>
18 Collect the ports that need to be enumerated on a controller for S3 phase.
20 @param[in] HcDevicePath Device path of the controller.
21 @param[in] HcDevicePathLength Length of the device path specified by
23 @param[out] PortBitMap Bitmap that indicates the ports that need
24 to be enumerated on the controller.
26 @retval The number of ports that need to be enumerated.
30 AhciS3GetEumeratePorts (
31 IN EFI_DEVICE_PATH_PROTOCOL
*HcDevicePath
,
32 IN UINTN HcDevicePathLength
,
33 OUT UINT32
*PortBitMap
38 UINTN S3InitDevicesLength
;
39 EFI_DEVICE_PATH_PROTOCOL
*S3InitDevices
;
40 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
41 UINTN DevicePathInstLength
;
43 SATA_DEVICE_PATH
*SataDeviceNode
;
48 // From the LockBox, get the list of device paths for devices need to be
52 S3InitDevicesLength
= sizeof (DummyData
);
54 Status
= RestoreLockBox (&gS3StorageDeviceInitListGuid
, &DummyData
, &S3InitDevicesLength
);
55 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
58 S3InitDevices
= AllocatePool (S3InitDevicesLength
);
59 if (S3InitDevices
== NULL
) {
63 Status
= RestoreLockBox (&gS3StorageDeviceInitListGuid
, S3InitDevices
, &S3InitDevicesLength
);
64 if (EFI_ERROR (Status
)) {
69 if (S3InitDevices
== NULL
) {
74 // Only enumerate the ports that exist in the device list.
78 // Fetch the size of current device path instance.
80 Status
= GetDevicePathInstanceSize (
82 &DevicePathInstLength
,
85 if (EFI_ERROR (Status
)) {
89 DevicePathInst
= S3InitDevices
;
90 S3InitDevices
= (EFI_DEVICE_PATH_PROTOCOL
*)((UINTN
) S3InitDevices
+ DevicePathInstLength
);
92 if (HcDevicePathLength
>= DevicePathInstLength
) {
97 // Compare the device paths to determine if the device is managed by this
103 HcDevicePathLength
- sizeof (EFI_DEVICE_PATH_PROTOCOL
)
106 // Get the port number.
108 while (DevicePathInst
->Type
!= END_DEVICE_PATH_TYPE
) {
109 if ((DevicePathInst
->Type
== MESSAGING_DEVICE_PATH
) &&
110 (DevicePathInst
->SubType
== MSG_SATA_DP
)) {
111 SataDeviceNode
= (SATA_DEVICE_PATH
*) DevicePathInst
;
113 // For now, the driver only support upto AHCI_MAX_PORTS ports and
114 // devices directly connected to a HBA.
116 if ((SataDeviceNode
->HBAPortNumber
>= AHCI_MAX_PORTS
) ||
117 (SataDeviceNode
->PortMultiplierPortNumber
!= 0xFFFF)) {
120 *PortBitMap
|= (UINT32
)BIT0
<< SataDeviceNode
->HBAPortNumber
;
123 DevicePathInst
= NextDevicePathNode (DevicePathInst
);
126 } while (!EntireEnd
);
129 // Return the number of ports need to be enumerated on this controller.
131 return AhciGetNumberOfPortsFromMap (*PortBitMap
);