42 ASSERT (PciIo !=
NULL);
72 IN UINT16 *DisPioMode OPTIONAL,
73 OUT UINT16 *SelectedMode
77 UINT16 AdvancedPioMode;
80 UINT16 MinimumPioCycleTime;
84 PioMode = (UINT8)(((
ATA5_IDENTIFY_DATA *)(&(IdentifyData->AtaData)))->pio_cycle_timing >> 8);
89 if ((IdentifyData->AtaData.field_validity & 0x02) == 0x02) {
90 AdvancedPioMode = IdentifyData->AtaData.advanced_pio_modes;
91 DEBUG ((DEBUG_INFO,
"CalculateBestPioMode: AdvancedPioMode = %x\n", AdvancedPioMode));
93 for (Index = 0; Index < 8; Index++) {
94 if ((AdvancedPioMode & 0x01) != 0) {
98 AdvancedPioMode >>= 1;
107 AdvancedPioMode = (UINT16)(Temp + 3);
109 AdvancedPioMode = PioMode;
115 PioMode = (UINT16)
MIN (AdvancedPioMode, 4);
117 MinimumPioCycleTime = IdentifyData->AtaData.min_pio_cycle_time_with_flow_control;
119 if (MinimumPioCycleTime <= 120) {
120 PioMode = (UINT16)
MIN (4, PioMode);
121 }
else if (MinimumPioCycleTime <= 180) {
122 PioMode = (UINT16)
MIN (3, PioMode);
123 }
else if (MinimumPioCycleTime <= 240) {
124 PioMode = (UINT16)
MIN (2, PioMode);
132 if (DisPioMode !=
NULL) {
133 if (*DisPioMode < 2) {
134 return EFI_UNSUPPORTED;
137 if (PioMode >= *DisPioMode) {
138 PioMode = (UINT16)(*DisPioMode - 1);
145 *SelectedMode = PioMode;
152 if (DisPioMode !=
NULL) {
153 if (*DisPioMode < 2) {
154 return EFI_UNSUPPORTED;
157 if (PioMode == *DisPioMode) {
186 IN UINT16 *DisUDmaMode OPTIONAL,
187 OUT UINT16 *SelectedMode
191 UINT16 DeviceUDmaMode;
198 if ((IdentifyData->AtaData.field_validity & 0x04) == 0x00) {
199 return EFI_UNSUPPORTED;
202 DeviceUDmaMode = IdentifyData->AtaData.ultra_dma_mode;
203 DEBUG ((DEBUG_INFO,
"CalculateBestUdmaMode: DeviceUDmaMode = %x\n", DeviceUDmaMode));
204 DeviceUDmaMode &= 0x3f;
207 while ((DeviceUDmaMode >>= 1) != 0) {
214 if (DisUDmaMode !=
NULL) {
215 if (*DisUDmaMode == 0) {
217 return EFI_UNSUPPORTED;
220 if (TempMode >= *DisUDmaMode) {
221 TempMode = (UINT16)(*DisUDmaMode - 1);
228 *SelectedMode = TempMode;
298 Status =
gBS->OpenProtocol (
300 &gEfiDevicePathProtocolGuid,
301 (VOID *)&ParentDevicePath,
302 This->DriverBindingHandle,
304 EFI_OPEN_PROTOCOL_BY_DRIVER
306 if (EFI_ERROR (Status)) {
315 &gEfiDevicePathProtocolGuid,
316 This->DriverBindingHandle,
323 Status =
gBS->OpenProtocol (
325 &gEfiPciIoProtocolGuid,
327 This->DriverBindingHandle,
329 EFI_OPEN_PROTOCOL_GET_PROTOCOL
331 if (EFI_ERROR (Status)) {
339 Status = PciIo->Pci.
Read (
342 PCI_CLASSCODE_OFFSET,
343 sizeof (PciData.Hdr.ClassCode),
344 PciData.Hdr.ClassCode
346 if (EFI_ERROR (Status)) {
347 return EFI_UNSUPPORTED;
354 return EFI_UNSUPPORTED;
389 DEBUG ((DEBUG_INFO,
"SataControllerStart start\n"));
392 BailLogMask = DEBUG_ERROR;
397 Status =
gBS->OpenProtocol (
399 &gEfiPciIoProtocolGuid,
401 This->DriverBindingHandle,
403 EFI_OPEN_PROTOCOL_BY_DRIVER
405 if (EFI_ERROR (Status)) {
406 if (Status == EFI_ALREADY_STARTED) {
412 BailLogMask = DEBUG_INFO;
422 if (Private ==
NULL) {
423 Status = EFI_OUT_OF_RESOURCES;
430 Private->Signature = SATA_CONTROLLER_SIGNATURE;
431 Private->PciIo = PciIo;
438 Private->IdeInit.
EnumAll = SATA_ENUMER_ALL;
439 Private->PciAttributesChanged =
FALSE;
444 Status = PciIo->Attributes (
448 &Private->OriginalPciAttributes
450 if (EFI_ERROR (Status)) {
451 goto FreeSataPrivate;
456 "Original PCI Attributes = 0x%llx\n",
457 Private->OriginalPciAttributes
460 Status = PciIo->Attributes (
466 if (EFI_ERROR (Status)) {
467 goto FreeSataPrivate;
470 DEBUG ((DEBUG_INFO,
"Supported PCI Attributes = 0x%llx\n", Supports));
472 Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
473 Status = PciIo->Attributes (
479 if (EFI_ERROR (Status)) {
480 goto FreeSataPrivate;
483 DEBUG ((DEBUG_INFO,
"Enabled PCI Attributes = 0x%llx\n", Supports));
484 Private->PciAttributesChanged =
TRUE;
486 Status = PciIo->Pci.
Read (
489 PCI_CLASSCODE_OFFSET,
490 sizeof (PciData.Hdr.ClassCode),
491 PciData.Hdr.ClassCode
493 if (EFI_ERROR (Status)) {
495 goto RestorePciAttributes;
506 DEBUG ((DEBUG_INFO,
"Ports Implemented(PI) = 0x%x\n", Data32));
508 Status = EFI_UNSUPPORTED;
509 goto RestorePciAttributes;
513 while (MaxPortNumber > 0) {
514 if ((Data32 & ((UINT32)1 << MaxPortNumber)) != 0) {
530 DEBUG ((DEBUG_INFO,
"HBA Capabilities(CAP) = 0x%x\n", Data32));
532 if ((Data32 & B_AHCI_CAP_SPM) == B_AHCI_CAP_SPM) {
539 if (Private->DisqualifiedModes ==
NULL) {
540 Status = EFI_OUT_OF_RESOURCES;
541 goto RestorePciAttributes;
545 if (Private->IdentifyData ==
NULL) {
546 Status = EFI_OUT_OF_RESOURCES;
547 goto FreeDisqualifiedModes;
550 Private->IdentifyValid =
AllocateZeroPool ((
sizeof (BOOLEAN)) * TotalCount);
551 if (Private->IdentifyValid ==
NULL) {
552 Status = EFI_OUT_OF_RESOURCES;
553 goto FreeIdentifyData;
559 Status =
gBS->InstallMultipleProtocolInterfaces (
561 &gEfiIdeControllerInitProtocolGuid,
566 if (EFI_ERROR (Status)) {
567 goto FreeIdentifyValid;
570 DEBUG ((DEBUG_INFO,
"SataControllerStart end with %r\n", Status));
578FreeDisqualifiedModes:
579 FreePool (Private->DisqualifiedModes);
584 Private->PciIo->Attributes (
587 Private->OriginalPciAttributes,
593 gBS->CloseProtocol (Controller, &gEfiPciIoProtocolGuid, This->DriverBindingHandle, Controller);
595 DEBUG ((BailLogMask,
"SataControllerStart error return status = %r\n", Status));
627 Status =
gBS->OpenProtocol (
629 &gEfiIdeControllerInitProtocolGuid,
631 This->DriverBindingHandle,
633 EFI_OPEN_PROTOCOL_GET_PROTOCOL
635 if (EFI_ERROR (Status)) {
636 return EFI_UNSUPPORTED;
639 Private = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (IdeInit);
644 Status =
gBS->UninstallMultipleProtocolInterfaces (
646 &gEfiIdeControllerInitProtocolGuid,
650 if (EFI_ERROR (Status)) {
654 if (Private->DisqualifiedModes !=
NULL) {
655 FreePool (Private->DisqualifiedModes);
658 if (Private->IdentifyData !=
NULL) {
662 if (Private->IdentifyValid !=
NULL) {
666 if (Private->PciAttributesChanged) {
670 Private->PciIo->Attributes (
673 Private->OriginalPciAttributes,
683 return gBS->CloseProtocol (
685 &gEfiPciIoProtocolGuid,
686 This->DriverBindingHandle,
715 ASSERT (Private !=
NULL);
716 ASSERT (Channel < Private->IdeInit.ChannelCount);
717 ASSERT (Device < Private->DeviceCount);
719 return Channel * Private->DeviceCount + Device;
767 OUT BOOLEAN *Enabled,
768 OUT UINT8 *MaxDevices
773 ASSERT (This !=
NULL);
774 Private = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
776 if (Channel < This->ChannelCount) {
778 *MaxDevices = Private->DeviceCount;
783 return EFI_INVALID_PARAMETER;
873 ASSERT (This !=
NULL);
874 Private = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
876 if ((Channel >= This->ChannelCount) || (Device >= Private->DeviceCount)) {
877 return EFI_INVALID_PARAMETER;
885 if (IdentifyData !=
NULL) {
887 &(Private->IdentifyData[DeviceIndex]),
892 Private->IdentifyValid[DeviceIndex] =
TRUE;
894 Private->IdentifyValid[DeviceIndex] =
FALSE;
952 ASSERT (This !=
NULL);
953 Private = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
955 if ((Channel >= This->ChannelCount) || (BadModes ==
NULL) || (Device >= Private->DeviceCount)) {
956 return EFI_INVALID_PARAMETER;
966 &(Private->DisqualifiedModes[DeviceIndex]),
1039 BOOLEAN IdentifyValid;
1041 UINT16 SelectedMode;
1045 ASSERT (This !=
NULL);
1046 Private = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
1048 if ((Channel >= This->ChannelCount) || (SupportedModes ==
NULL) || (Device >= Private->DeviceCount)) {
1049 return EFI_INVALID_PARAMETER;
1053 if (*SupportedModes ==
NULL) {
1054 ASSERT (*SupportedModes !=
NULL);
1055 return EFI_OUT_OF_RESOURCES;
1060 IdentifyData = &(Private->IdentifyData[DeviceIndex]);
1061 IdentifyValid = Private->IdentifyValid[DeviceIndex];
1062 DisqualifiedModes = &(Private->DisqualifiedModes[DeviceIndex]);
1067 if (!IdentifyValid) {
1069 return EFI_NOT_READY;
1077 if (!EFI_ERROR (Status)) {
1078 (*SupportedModes)->PioMode.Valid =
TRUE;
1079 (*SupportedModes)->PioMode.Mode = SelectedMode;
1081 (*SupportedModes)->PioMode.Valid =
FALSE;
1084 DEBUG ((DEBUG_INFO,
"IdeInitCalculateMode: PioMode = %x\n", (*SupportedModes)->PioMode.Mode));
1092 if (!EFI_ERROR (Status)) {
1093 (*SupportedModes)->UdmaMode.Valid =
TRUE;
1094 (*SupportedModes)->UdmaMode.Mode = SelectedMode;
1096 (*SupportedModes)->UdmaMode.Valid =
FALSE;
1099 DEBUG ((DEBUG_INFO,
"IdeInitCalculateMode: UdmaMode = %x\n", (*SupportedModes)->UdmaMode.Mode));
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_IDE_CONTROLLER_ENUM_PHASE
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gSataControllerComponentName
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gSataControllerComponentName2
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
@ EfiPciIoAttributeOperationGet
@ EfiPciIoAttributeOperationEnable
@ EfiPciIoAttributeOperationSet
@ EfiPciIoAttributeOperationSupported
#define IS_PCI_SATADPA(_p)
EFI_STATUS EFIAPI SataControllerSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
STATIC UINTN FlatDeviceIndex(IN CONST EFI_SATA_CONTROLLER_PRIVATE_DATA *Private, IN UINTN Channel, IN UINTN Device)
EFI_STATUS EFIAPI IdeInitNotifyPhase(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase, IN UINT8 Channel)
EFI_STATUS EFIAPI InitializeSataControllerDriver(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS CalculateBestUdmaMode(IN EFI_IDENTIFY_DATA *IdentifyData, IN UINT16 *DisUDmaMode OPTIONAL, OUT UINT16 *SelectedMode)
UINT32 EFIAPI AhciReadReg(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT32 Offset)
EFI_STATUS CalculateBestPioMode(IN EFI_IDENTIFY_DATA *IdentifyData, IN UINT16 *DisPioMode OPTIONAL, OUT UINT16 *SelectedMode)
EFI_STATUS EFIAPI IdeInitSubmitData(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, IN UINT8 Channel, IN UINT8 Device, IN EFI_IDENTIFY_DATA *IdentifyData)
EFI_STATUS EFIAPI IdeInitSetTiming(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, IN UINT8 Channel, IN UINT8 Device, IN EFI_ATA_COLLECTIVE_MODE *Modes)
EFI_DRIVER_BINDING_PROTOCOL gSataControllerDriverBinding
EFI_STATUS EFIAPI SataControllerStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
EFI_STATUS EFIAPI IdeInitGetChannelInfo(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, IN UINT8 Channel, OUT BOOLEAN *Enabled, OUT UINT8 *MaxDevices)
EFI_STATUS EFIAPI SataControllerStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
EFI_STATUS EFIAPI IdeInitDisqualifyMode(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, IN UINT8 Channel, IN UINT8 Device, IN EFI_ATA_COLLECTIVE_MODE *BadModes)
EFI_STATUS EFIAPI IdeInitCalculateMode(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, IN UINT8 Channel, IN UINT8 Device, OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes)
#define AHCI_MULTI_MAX_DEVICES
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_IDE_CONTROLLER_SUBMIT_DATA SubmitData
EFI_IDE_CONTROLLER_DISQUALIFY_MODE DisqualifyMode
EFI_IDE_CONTROLLER_SET_TIMING SetTiming
EFI_IDE_CONTROLLER_CALCULATE_MODE CalculateMode
EFI_IDE_CONTROLLER_NOTIFY_PHASE NotifyPhase
EFI_IDE_CONTROLLER_GET_CHANNEL_INFO GetChannelInfo
UINT32 Mode
The actual ATA mode. This field is not a bit map.
BOOLEAN Valid
TRUE if Mode is valid.
EFI_PCI_IO_PROTOCOL_CONFIG Read