2 This file implement UEFI driver for IDE Bus which includes device identification,
3 Child device(Disk, CDROM, etc) enumeration and child handler installation, and
6 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
9 @par Revision Reference:
10 This module is modified from DXE\IDE module for Ide Contriller Init support
16 #define PCI_CLASS_MASS_STORAGE 0x01
17 #define PCI_SUB_CLASS_IDE 0x01
21 // IDE Bus Driver Binding Protocol Instance
23 EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding
= {
24 IDEBusDriverBindingSupported
,
25 IDEBusDriverBindingStart
,
26 IDEBusDriverBindingStop
,
32 Deregister an IDE device and free resources
34 @param This Protocol instance pointer.
35 @param Controller Ide device handle
36 @param Handle Handle of device to deregister driver on
38 @retval EFI_SUCCESS Deregiter a specific IDE device successfully
44 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
45 IN EFI_HANDLE Controller
,
50 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
51 IDE_BLK_IO_DEV
*IdeBlkIoDevice
;
52 EFI_PCI_IO_PROTOCOL
*PciIo
;
55 Status
= gBS
->OpenProtocol (
57 &gEfiBlockIoProtocolGuid
,
59 This
->DriverBindingHandle
,
61 EFI_OPEN_PROTOCOL_GET_PROTOCOL
63 if (EFI_ERROR (Status
)) {
67 IdeBlkIoDevice
= IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo
);
70 // Report Status code: Device disabled
72 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
74 (EFI_IO_BUS_ATA_ATAPI
| EFI_P_PC_DISABLE
),
75 IdeBlkIoDevice
->DevicePath
79 // Close the child handle
81 Status
= gBS
->CloseProtocol (
83 &gEfiPciIoProtocolGuid
,
84 This
->DriverBindingHandle
,
88 Status
= gBS
->UninstallMultipleProtocolInterfaces (
90 &gEfiDevicePathProtocolGuid
,
91 IdeBlkIoDevice
->DevicePath
,
92 &gEfiBlockIoProtocolGuid
,
93 &IdeBlkIoDevice
->BlkIo
,
94 &gEfiDiskInfoProtocolGuid
,
95 &IdeBlkIoDevice
->DiskInfo
,
99 if (EFI_ERROR (Status
)) {
102 &gEfiPciIoProtocolGuid
,
104 This
->DriverBindingHandle
,
106 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
112 // Release allocated resources
114 Index
= IdeBlkIoDevice
->Channel
* 2 + IdeBlkIoDevice
->Device
;
115 if (Index
< MAX_IDE_DEVICE
) {
116 IdeBlkIoDevice
->IdeBusDriverPrivateData
->HaveScannedDevice
[Index
] = FALSE
;
118 ReleaseIdeResources (IdeBlkIoDevice
);
123 Supported function of Driver Binding protocol for this driver.
125 @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
126 @param ControllerHandle The handle of the controller to test.
127 @param RemainingDevicePath A pointer to the remaining portion of a device path.
129 @retval EFI_SUCCESS Driver loaded.
130 @retval other Driver not loaded.
135 IDEBusDriverBindingSupported (
136 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
137 IN EFI_HANDLE Controller
,
138 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
142 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
144 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
145 EFI_PCI_IO_PROTOCOL
*PciIo
;
148 if (RemainingDevicePath
!= NULL
) {
149 Node
= (EFI_DEV_PATH
*) RemainingDevicePath
;
151 // Check if RemainingDevicePath is the End of Device Path Node,
152 // if yes, go on checking other conditions
154 if (!IsDevicePathEnd (Node
)) {
156 // If RemainingDevicePath isn't the End of Device Path Node,
157 // check its validation
159 if (Node
->DevPath
.Type
!= MESSAGING_DEVICE_PATH
||
160 Node
->DevPath
.SubType
!= MSG_ATAPI_DP
||
161 DevicePathNodeLength(&Node
->DevPath
) != sizeof(ATAPI_DEVICE_PATH
)) {
162 return EFI_UNSUPPORTED
;
168 // Verify the Ide Controller Init Protocol, which installed by the
169 // IdeController module.
171 Status
= gBS
->OpenProtocol (
173 &gEfiIdeControllerInitProtocolGuid
,
175 This
->DriverBindingHandle
,
177 EFI_OPEN_PROTOCOL_BY_DRIVER
180 if (Status
== EFI_ALREADY_STARTED
) {
184 if (EFI_ERROR (Status
)) {
189 // Close the I/O Abstraction(s) used to perform the supported test
193 &gEfiIdeControllerInitProtocolGuid
,
194 This
->DriverBindingHandle
,
199 // Open the EFI Device Path protocol needed to perform the supported test
201 Status
= gBS
->OpenProtocol (
203 &gEfiDevicePathProtocolGuid
,
204 (VOID
**) &ParentDevicePath
,
205 This
->DriverBindingHandle
,
207 EFI_OPEN_PROTOCOL_BY_DRIVER
209 if (Status
== EFI_ALREADY_STARTED
) {
214 // Close protocol, don't use device path protocol in the Support() function
218 &gEfiDevicePathProtocolGuid
,
219 This
->DriverBindingHandle
,
224 // Get the EfiPciIoProtocol
226 Status
= gBS
->OpenProtocol (
228 &gEfiPciIoProtocolGuid
,
230 This
->DriverBindingHandle
,
232 EFI_OPEN_PROTOCOL_GET_PROTOCOL
235 if (EFI_ERROR (Status
)) {
240 // Now further check the PCI header: Base class (offset 0x0B) and
241 // Sub Class (offset 0x0A). This controller should be an IDE controller
243 Status
= PciIo
->Pci
.Read (
251 if (!EFI_ERROR (Status
)) {
253 // Examine if it is IDE mode by class code
255 if ((PciData
.Hdr
.ClassCode
[2] != PCI_CLASS_MASS_STORAGE
) || (PciData
.Hdr
.ClassCode
[1] != PCI_SUB_CLASS_IDE
)) {
256 Status
= EFI_UNSUPPORTED
;
258 Status
= EFI_SUCCESS
;
267 Start function of Driver binding protocol which start this driver on Controller
268 by detecting all disks and installing BlockIo protocol on them.
270 @param This Protocol instance pointer.
271 @param Controller Handle of device to bind driver to.
272 @param RemainingDevicePath produce all possible children.
274 @retval EFI_SUCCESS This driver is added to ControllerHandle.
275 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
276 @retval other This driver does not support this device.
281 IDEBusDriverBindingStart (
282 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
283 IN EFI_HANDLE Controller
,
284 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
288 EFI_STATUS SavedStatus
;
289 EFI_PCI_IO_PROTOCOL
*PciIo
;
290 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
293 UINT8 BeginningIdeChannel
;
296 UINT8 BeginningIdeDevice
;
298 IDE_BLK_IO_DEV
*IdeBlkIoDevice
[IdeMaxChannel
][IdeMaxDevice
];
299 IDE_BLK_IO_DEV
*IdeBlkIoDevicePtr
;
300 IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr
[IdeMaxChannel
];
301 ATA_TRANSFER_MODE TransferMode
;
302 ATA_DRIVE_PARMS DriveParameters
;
303 EFI_DEV_PATH NewNode
;
304 UINT8 ConfigurationOptions
;
305 UINT16 CommandBlockBaseAddr
;
306 UINT16 ControlBlockBaseAddr
;
308 IDE_BUS_DRIVER_PRIVATE_DATA
*IdeBusDriverPrivateData
;
312 // Local variables declaration for IdeControllerInit support
314 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
316 BOOLEAN ChannelEnabled
;
318 EFI_IDENTIFY_DATA IdentifyData
;
319 EFI_ATA_COLLECTIVE_MODE
*SupportedModes
;
321 IdeBusDriverPrivateData
= NULL
;
322 SupportedModes
= NULL
;
325 // Perform IdeBus initialization
327 Status
= gBS
->OpenProtocol (
329 &gEfiDevicePathProtocolGuid
,
330 (VOID
**) &ParentDevicePath
,
331 This
->DriverBindingHandle
,
333 EFI_OPEN_PROTOCOL_BY_DRIVER
335 if ((EFI_ERROR (Status
)) && (Status
!= EFI_ALREADY_STARTED
)) {
340 // Now open the IDE_CONTROLLER_INIT protocol. Step7.1
342 Status
= gBS
->OpenProtocol (
344 &gEfiIdeControllerInitProtocolGuid
,
346 This
->DriverBindingHandle
,
348 EFI_OPEN_PROTOCOL_BY_DRIVER
352 // The following OpenProtocol function with _GET_PROTOCOL attribute and
353 // will not return EFI_ALREADY_STARTED, so save it for now
355 SavedStatus
= Status
;
357 if ((EFI_ERROR (Status
)) && (Status
!= EFI_ALREADY_STARTED
)) {
358 DEBUG ((EFI_D_ERROR
, "Open Init, Status=%x", Status
));
360 // open protocol is not SUCCESS or not ALREADY_STARTED, error exit
366 // Save Enumall. Step7.2
368 EnumAll
= IdeInit
->EnumAll
;
371 // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL
372 // attribute will not return EFI_ALREADY_STARTED
374 Status
= gBS
->OpenProtocol (
376 &gEfiPciIoProtocolGuid
,
378 This
->DriverBindingHandle
,
380 EFI_OPEN_PROTOCOL_GET_PROTOCOL
382 if (EFI_ERROR (Status
)) {
383 DEBUG ((EFI_D_ERROR
, "Open PciIo, Status=%x", Status
));
388 // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable
390 if (SavedStatus
!= EFI_ALREADY_STARTED
) {
391 IdeBusDriverPrivateData
= AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA
));
392 if (IdeBusDriverPrivateData
== NULL
) {
393 Status
= EFI_OUT_OF_RESOURCES
;
397 ZeroMem (IdeBusDriverPrivateData
, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA
));
398 Status
= gBS
->InstallMultipleProtocolInterfaces (
401 IdeBusDriverPrivateData
,
404 if (EFI_ERROR (Status
)) {
409 Status
= gBS
->OpenProtocol (
412 (VOID
**) &IdeBusDriverPrivateData
,
413 This
->DriverBindingHandle
,
415 EFI_OPEN_PROTOCOL_GET_PROTOCOL
417 if (EFI_ERROR (Status
)) {
418 IdeBusDriverPrivateData
= NULL
;
423 Status
= PciIo
->Attributes (
425 EfiPciIoAttributeOperationSupported
,
429 if (!EFI_ERROR (Status
)) {
430 Supports
&= (UINT64
)EFI_PCI_DEVICE_ENABLE
;
431 Status
= PciIo
->Attributes (
433 EfiPciIoAttributeOperationEnable
,
439 if (EFI_ERROR (Status
)) {
444 // Read the environment variable that contains the IDEBus Driver's
445 // Config options that were set by the Driver Configuration Protocol
447 DataSize
= sizeof (ConfigurationOptions
);
448 Status
= gRT
->GetVariable (
449 (CHAR16
*) L
"Configuration",
453 &ConfigurationOptions
455 if (EFI_ERROR (Status
)) {
456 ConfigurationOptions
= 0x0f;
459 if (EnumAll
|| RemainingDevicePath
== NULL
) {
461 // If IdeInit->EnumAll is TRUE or RemainingDevicePath is NULL,
462 // must enumerate all IDE devices anyway
464 BeginningIdeChannel
= IdePrimary
;
465 EndIdeChannel
= IdeSecondary
;
466 BeginningIdeDevice
= IdeMaster
;
467 EndIdeDevice
= IdeSlave
;
469 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
471 // If RemainingDevicePath isn't the End of Device Path Node,
472 // only scan the specified device by RemainingDevicePath
474 Node
= (EFI_DEV_PATH
*) RemainingDevicePath
;
475 BeginningIdeChannel
= Node
->Atapi
.PrimarySecondary
;
476 EndIdeChannel
= BeginningIdeChannel
;
477 BeginningIdeDevice
= Node
->Atapi
.SlaveMaster
;
478 EndIdeDevice
= BeginningIdeDevice
;
479 if (BeginningIdeChannel
>= IdeMaxChannel
|| EndIdeChannel
>= IdeMaxChannel
) {
480 Status
= EFI_INVALID_PARAMETER
;
483 if (BeginningIdeDevice
>= IdeMaxDevice
|| EndIdeDevice
>= IdeMaxDevice
) {
484 Status
= EFI_INVALID_PARAMETER
;
490 // If RemainingDevicePath is the End of Device Path Node,
491 // skip enumerate any device and return EFI_SUCESSS
493 BeginningIdeChannel
= IdeMaxChannel
;
494 EndIdeChannel
= IdeMaxChannel
- 1;
495 BeginningIdeDevice
= IdeMaxDevice
;
496 EndIdeDevice
= IdeMaxDevice
- 1;
500 // Obtain IDE IO port registers' base addresses
502 Status
= GetIdeRegistersBaseAddr (PciIo
, IdeRegsBaseAddr
);
503 if (EFI_ERROR (Status
)) {
508 // Report status code: begin IdeBus initialization
510 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
512 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_PC_RESET
),
517 // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol
519 for (IdeChannel
= BeginningIdeChannel
; IdeChannel
<= EndIdeChannel
; IdeChannel
++) {
521 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelEnumeration
, IdeChannel
);
524 // now obtain channel information fron IdeControllerInit protocol. Step9
526 Status
= IdeInit
->GetChannelInfo (
532 if (EFI_ERROR (Status
)) {
533 DEBUG ((EFI_D_ERROR
, "[GetChannel, Status=%x]", Status
));
537 if (!ChannelEnabled
) {
541 EndIdeDevice
= (UINT8
) MIN ((MaxDevices
- 1), EndIdeDevice
);
542 ASSERT (EndIdeDevice
< IdeMaxDevice
);
544 // Now inform the IDE Controller Init Module. Sept10
546 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelReset
, IdeChannel
);
549 // No reset channel function implemented. Sept11
551 IdeInit
->NotifyPhase (IdeInit
, EfiIdeAfterChannelReset
, IdeChannel
);
556 IdeInit
->NotifyPhase (
558 EfiIdeBusBeforeDevicePresenceDetection
,
563 // Prepare to detect IDE device of this channel
565 InitializeIDEChannelData ();
568 // -- 1st inner loop --- Master/Slave ------------ Step14
570 for (IdeDevice
= BeginningIdeDevice
; IdeDevice
<= EndIdeDevice
; IdeDevice
++) {
572 // Check whether the configuration options allow this device
574 if ((ConfigurationOptions
& (1 << (IdeChannel
* 2 + IdeDevice
))) == 0) {
579 // The device has been scanned in another Start(), No need to scan it again
580 // for perf optimization.
582 if (IdeBusDriverPrivateData
->HaveScannedDevice
[IdeChannel
* 2 + IdeDevice
]) {
587 // create child handle for the detected device.
589 IdeBlkIoDevice
[IdeChannel
][IdeDevice
] = AllocatePool (sizeof (IDE_BLK_IO_DEV
));
590 if (IdeBlkIoDevice
[IdeChannel
][IdeDevice
] == NULL
) {
594 IdeBlkIoDevicePtr
= IdeBlkIoDevice
[IdeChannel
][IdeDevice
];
596 ZeroMem (IdeBlkIoDevicePtr
, sizeof (IDE_BLK_IO_DEV
));
598 IdeBlkIoDevicePtr
->Signature
= IDE_BLK_IO_DEV_SIGNATURE
;
599 IdeBlkIoDevicePtr
->Channel
= (EFI_IDE_CHANNEL
) IdeChannel
;
600 IdeBlkIoDevicePtr
->Device
= (EFI_IDE_DEVICE
) IdeDevice
;
603 // initialize Block IO interface's Media pointer
605 IdeBlkIoDevicePtr
->BlkIo
.Media
= &IdeBlkIoDevicePtr
->BlkMedia
;
608 // Initialize IDE IO port addresses, including Command Block registers
609 // and Control Block registers
611 IdeBlkIoDevicePtr
->IoPort
= AllocatePool (sizeof (IDE_BASE_REGISTERS
));
612 if (IdeBlkIoDevicePtr
->IoPort
== NULL
) {
616 ZeroMem (IdeBlkIoDevicePtr
->IoPort
, sizeof (IDE_BASE_REGISTERS
));
617 CommandBlockBaseAddr
= IdeRegsBaseAddr
[IdeChannel
].CommandBlockBaseAddr
;
618 ControlBlockBaseAddr
= IdeRegsBaseAddr
[IdeChannel
].ControlBlockBaseAddr
;
620 IdeBlkIoDevicePtr
->IoPort
->Data
= CommandBlockBaseAddr
;
621 (*(UINT16
*) &IdeBlkIoDevicePtr
->IoPort
->Reg1
) = (UINT16
) (CommandBlockBaseAddr
+ 0x01);
622 IdeBlkIoDevicePtr
->IoPort
->SectorCount
= (UINT16
) (CommandBlockBaseAddr
+ 0x02);
623 IdeBlkIoDevicePtr
->IoPort
->SectorNumber
= (UINT16
) (CommandBlockBaseAddr
+ 0x03);
624 IdeBlkIoDevicePtr
->IoPort
->CylinderLsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x04);
625 IdeBlkIoDevicePtr
->IoPort
->CylinderMsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x05);
626 IdeBlkIoDevicePtr
->IoPort
->Head
= (UINT16
) (CommandBlockBaseAddr
+ 0x06);
627 (*(UINT16
*) &IdeBlkIoDevicePtr
->IoPort
->Reg
) = (UINT16
) (CommandBlockBaseAddr
+ 0x07);
629 (*(UINT16
*) &IdeBlkIoDevicePtr
->IoPort
->Alt
) = ControlBlockBaseAddr
;
630 IdeBlkIoDevicePtr
->IoPort
->DriveAddress
= (UINT16
) (ControlBlockBaseAddr
+ 0x01);
632 IdeBlkIoDevicePtr
->IoPort
->MasterSlave
= (UINT16
) ((IdeDevice
== IdeMaster
) ? 1 : 0);
634 IdeBlkIoDevicePtr
->PciIo
= PciIo
;
635 IdeBlkIoDevicePtr
->IdeBusDriverPrivateData
= IdeBusDriverPrivateData
;
636 IdeBlkIoDevicePtr
->IoPort
->BusMasterBaseAddr
= IdeRegsBaseAddr
[IdeChannel
].BusMasterBaseAddr
;
639 // Report Status code: is about to detect IDE drive
641 REPORT_STATUS_CODE_EX (
643 (EFI_IO_BUS_ATA_ATAPI
| EFI_P_PC_PRESENCE_DETECT
),
652 // Discover device, now!
654 PERF_START (NULL
, "DiscoverIdeDevice", "IDE", 0);
655 Status
= DiscoverIdeDevice (IdeBlkIoDevicePtr
);
656 PERF_END (NULL
, "DiscoverIdeDevice", "IDE", 0);
658 IdeBusDriverPrivateData
->HaveScannedDevice
[IdeChannel
* 2 + IdeDevice
] = TRUE
;
659 IdeBusDriverPrivateData
->DeviceProcessed
[IdeChannel
* 2 + IdeDevice
] = FALSE
;
661 if (!EFI_ERROR (Status
)) {
665 ZeroMem (&NewNode
, sizeof (NewNode
));
666 NewNode
.DevPath
.Type
= MESSAGING_DEVICE_PATH
;
667 NewNode
.DevPath
.SubType
= MSG_ATAPI_DP
;
668 SetDevicePathNodeLength (&NewNode
.DevPath
, sizeof (ATAPI_DEVICE_PATH
));
670 NewNode
.Atapi
.PrimarySecondary
= (UINT8
) IdeBlkIoDevicePtr
->Channel
;
671 NewNode
.Atapi
.SlaveMaster
= (UINT8
) IdeBlkIoDevicePtr
->Device
;
672 NewNode
.Atapi
.Lun
= IdeBlkIoDevicePtr
->Lun
;
673 IdeBlkIoDevicePtr
->DevicePath
= AppendDevicePathNode (
677 if (IdeBlkIoDevicePtr
->DevicePath
== NULL
) {
678 ReleaseIdeResources (IdeBlkIoDevicePtr
);
683 // Submit identify data to IDE controller init driver
685 CopyMem (&IdentifyData
, IdeBlkIoDevicePtr
->IdData
, sizeof (IdentifyData
));
686 IdeBusDriverPrivateData
->DeviceFound
[IdeChannel
* 2 + IdeDevice
] = TRUE
;
687 IdeInit
->SubmitData (IdeInit
, IdeChannel
, IdeDevice
, &IdentifyData
);
690 // Device detection failed
692 IdeBusDriverPrivateData
->DeviceFound
[IdeChannel
* 2 + IdeDevice
] = FALSE
;
693 IdeInit
->SubmitData (IdeInit
, IdeChannel
, IdeDevice
, NULL
);
694 ReleaseIdeResources (IdeBlkIoDevicePtr
);
695 IdeBlkIoDevicePtr
= NULL
;
698 // end of 1st inner loop ---
702 // end of 1st outer loop =========
707 // = 2nd outer loop == Primary/Secondary =================
709 for (IdeChannel
= BeginningIdeChannel
; IdeChannel
<= EndIdeChannel
; IdeChannel
++) {
712 // -- 2nd inner loop --- Master/Slave --------
714 for (IdeDevice
= BeginningIdeDevice
; IdeDevice
<= EndIdeDevice
; IdeDevice
++) {
716 ASSERT (IdeChannel
* 2 + IdeDevice
< MAX_IDE_DEVICE
);
717 if (IdeBusDriverPrivateData
->DeviceProcessed
[IdeChannel
* 2 + IdeDevice
]) {
721 if (!IdeBusDriverPrivateData
->DeviceFound
[IdeChannel
* 2 + IdeDevice
]) {
725 Status
= IdeInit
->CalculateMode (
731 if (EFI_ERROR (Status
)) {
732 DEBUG ((EFI_D_ERROR
, "[bStStp20S=%x]", Status
));
736 ASSERT (IdeChannel
< IdeMaxChannel
&& IdeDevice
< IdeMaxDevice
);
737 IdeBlkIoDevicePtr
= IdeBlkIoDevice
[IdeChannel
][IdeDevice
];
740 // Set best supported PIO mode on this IDE device
742 if (SupportedModes
->PioMode
.Mode
<= AtaPioMode2
) {
743 TransferMode
.ModeCategory
= ATA_MODE_CATEGORY_DEFAULT_PIO
;
745 TransferMode
.ModeCategory
= ATA_MODE_CATEGORY_FLOW_PIO
;
748 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->PioMode
.Mode
);
750 if (SupportedModes
->ExtModeCount
== 0){
751 Status
= SetDeviceTransferMode (IdeBlkIoDevicePtr
, &TransferMode
);
753 if (EFI_ERROR (Status
)) {
754 IdeBusDriverPrivateData
->DeviceFound
[IdeChannel
* 2 + IdeDevice
] = FALSE
;
755 ReleaseIdeResources (IdeBlkIoDevicePtr
);
756 IdeBlkIoDevicePtr
= NULL
;
762 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
763 // be set together. Only one DMA mode can be set to a device. If setting
764 // DMA mode operation fails, we can continue moving on because we only use
765 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
767 if (SupportedModes
->UdmaMode
.Valid
) {
769 TransferMode
.ModeCategory
= ATA_MODE_CATEGORY_UDMA
;
770 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->UdmaMode
.Mode
);
771 Status
= SetDeviceTransferMode (IdeBlkIoDevicePtr
, &TransferMode
);
773 if (EFI_ERROR (Status
)) {
774 IdeBusDriverPrivateData
->DeviceFound
[IdeChannel
* 2 + IdeDevice
] = FALSE
;
775 ReleaseIdeResources (IdeBlkIoDevicePtr
);
776 IdeBlkIoDevicePtr
= NULL
;
782 IdeBlkIoDevicePtr
->UdmaMode
.Valid
= TRUE
;
783 IdeBlkIoDevicePtr
->UdmaMode
.Mode
= SupportedModes
->UdmaMode
.Mode
;
784 EnableInterrupt (IdeBlkIoDevicePtr
);
785 } else if (SupportedModes
->MultiWordDmaMode
.Valid
) {
787 TransferMode
.ModeCategory
= ATA_MODE_CATEGORY_MDMA
;
788 TransferMode
.ModeNumber
= (UINT8
) SupportedModes
->MultiWordDmaMode
.Mode
;
789 Status
= SetDeviceTransferMode (IdeBlkIoDevicePtr
, &TransferMode
);
791 if (EFI_ERROR (Status
)) {
792 IdeBusDriverPrivateData
->DeviceFound
[IdeChannel
* 2 + IdeDevice
] = FALSE
;
793 ReleaseIdeResources (IdeBlkIoDevicePtr
);
794 IdeBlkIoDevicePtr
= NULL
;
798 EnableInterrupt (IdeBlkIoDevicePtr
);
801 // Init driver parameters
803 DriveParameters
.Sector
= (UINT8
) ((ATA5_IDENTIFY_DATA
*) IdeBlkIoDevicePtr
->IdData
)->sectors_per_track
;
804 DriveParameters
.Heads
= (UINT8
) (((ATA5_IDENTIFY_DATA
*) IdeBlkIoDevicePtr
->IdData
)->heads
- 1);
805 DriveParameters
.MultipleSector
= (UINT8
) IdeBlkIoDevicePtr
->IdData
->AtaData
.multi_sector_cmd_max_sct_cnt
;
807 // Set Parameters for the device:
809 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
811 if ((IdeBlkIoDevicePtr
->Type
== IdeHardDisk
) || (IdeBlkIoDevicePtr
->Type
== Ide48bitAddressingHardDisk
)) {
812 Status
= SetDriveParameters (IdeBlkIoDevicePtr
, &DriveParameters
);
816 // Record PIO mode used in private data
818 IdeBlkIoDevicePtr
->PioMode
= (ATA_PIO_MODE
) SupportedModes
->PioMode
.Mode
;
821 // Set IDE controller Timing Blocks in the PCI Configuration Space
823 IdeInit
->SetTiming (IdeInit
, IdeChannel
, IdeDevice
, SupportedModes
);
826 // Add Component Name for the IDE/ATAPI device that was discovered.
828 IdeBlkIoDevicePtr
->ControllerNameTable
= NULL
;
829 ADD_IDE_ATAPI_NAME (IdeBlkIoDevicePtr
);
831 Status
= gBS
->InstallMultipleProtocolInterfaces (
832 &IdeBlkIoDevicePtr
->Handle
,
833 &gEfiDevicePathProtocolGuid
,
834 IdeBlkIoDevicePtr
->DevicePath
,
835 &gEfiBlockIoProtocolGuid
,
836 &IdeBlkIoDevicePtr
->BlkIo
,
837 &gEfiDiskInfoProtocolGuid
,
838 &IdeBlkIoDevicePtr
->DiskInfo
,
842 if (EFI_ERROR (Status
)) {
843 ReleaseIdeResources (IdeBlkIoDevicePtr
);
848 &gEfiPciIoProtocolGuid
,
850 This
->DriverBindingHandle
,
851 IdeBlkIoDevicePtr
->Handle
,
852 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
855 IdeBusDriverPrivateData
->DeviceProcessed
[IdeChannel
* 2 + IdeDevice
] = TRUE
;
858 // Report status code: device eanbled!
860 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
862 (EFI_IO_BUS_ATA_ATAPI
| EFI_P_PC_ENABLE
),
863 IdeBlkIoDevicePtr
->DevicePath
867 // Create event to clear pending IDE interrupt
869 Status
= gBS
->CreateEventEx (
874 &gEfiEventExitBootServicesGuid
,
875 &IdeBlkIoDevicePtr
->ExitBootServiceEvent
879 // end of 2nd inner loop ----
883 // end of 2nd outer loop ==========
888 // All configurations done! Notify IdeController to do post initialization
889 // work such as saving IDE controller PCI settings for S3 resume
891 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusPhaseMaximum
, 0);
893 if (SupportedModes
!= NULL
) {
894 FreePool (SupportedModes
);
897 PERF_START (NULL
, "Finish IDE detection", "IDE", 1);
898 PERF_END (NULL
, "Finish IDE detection", "IDE", 0);
905 // Report error code: controller error
907 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
908 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
909 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_EC_CONTROLLER_ERROR
),
915 &gEfiIdeControllerInitProtocolGuid
,
916 This
->DriverBindingHandle
,
920 gBS
->UninstallMultipleProtocolInterfaces (
923 IdeBusDriverPrivateData
,
927 if (IdeBusDriverPrivateData
!= NULL
) {
928 gBS
->FreePool (IdeBusDriverPrivateData
);
931 if (SupportedModes
!= NULL
) {
932 gBS
->FreePool (SupportedModes
);
937 &gEfiPciIoProtocolGuid
,
938 This
->DriverBindingHandle
,
944 &gEfiDevicePathProtocolGuid
,
945 This
->DriverBindingHandle
,
953 Stop function of Driver Binding Protocol which is to stop the driver on Controller Handle and all
954 child handle attached to the controller handle if there are.
956 @param This Protocol instance pointer.
957 @param Controller Handle of device to stop driver on
958 @param NumberOfChildren Not used
959 @param ChildHandleBuffer Not used
961 @retval EFI_SUCCESS This driver is removed DeviceHandle
962 @retval other This driver was not removed from this device
967 IDEBusDriverBindingStop (
968 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
969 IN EFI_HANDLE Controller
,
970 IN UINTN NumberOfChildren
,
971 IN EFI_HANDLE
*ChildHandleBuffer
975 EFI_PCI_IO_PROTOCOL
*PciIo
;
976 BOOLEAN AllChildrenStopped
;
978 IDE_BUS_DRIVER_PRIVATE_DATA
*IdeBusDriverPrivateData
;
981 IdeBusDriverPrivateData
= NULL
;
983 if (NumberOfChildren
== 0) {
985 Status
= gBS
->OpenProtocol (
987 &gEfiPciIoProtocolGuid
,
989 This
->DriverBindingHandle
,
991 EFI_OPEN_PROTOCOL_GET_PROTOCOL
993 if (!EFI_ERROR (Status
)) {
994 Status
= PciIo
->Attributes (
996 EfiPciIoAttributeOperationSupported
,
1000 if (!EFI_ERROR (Status
)) {
1001 Supports
&= (UINT64
)(EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO
| EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO
| EFI_PCI_DEVICE_ENABLE
);
1004 EfiPciIoAttributeOperationDisable
,
1014 (VOID
**) &IdeBusDriverPrivateData
,
1015 This
->DriverBindingHandle
,
1017 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1020 gBS
->UninstallMultipleProtocolInterfaces (
1023 IdeBusDriverPrivateData
,
1027 if (IdeBusDriverPrivateData
!= NULL
) {
1028 gBS
->FreePool (IdeBusDriverPrivateData
);
1031 // Close the bus driver
1033 gBS
->CloseProtocol (
1035 &gEfiIdeControllerInitProtocolGuid
,
1036 This
->DriverBindingHandle
,
1039 gBS
->CloseProtocol (
1041 &gEfiPciIoProtocolGuid
,
1042 This
->DriverBindingHandle
,
1045 gBS
->CloseProtocol (
1047 &gEfiDevicePathProtocolGuid
,
1048 This
->DriverBindingHandle
,
1055 AllChildrenStopped
= TRUE
;
1057 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
1059 Status
= DeRegisterIdeDevice (This
, Controller
, ChildHandleBuffer
[Index
]);
1061 if (EFI_ERROR (Status
)) {
1062 AllChildrenStopped
= FALSE
;
1066 if (!AllChildrenStopped
) {
1067 return EFI_DEVICE_ERROR
;
1074 issue ATA or ATAPI command to reset a block IO device.
1075 @param This Block IO protocol instance pointer.
1076 @param ExtendedVerification If FALSE,for ATAPI device, driver will only invoke ATAPI reset method
1077 If TRUE, for ATAPI device, driver need invoke ATA reset method after
1078 invoke ATAPI reset method
1080 @retval EFI_DEVICE_ERROR When the device is neighther ATA device or ATAPI device.
1081 @retval EFI_SUCCESS The device reset successfully
1087 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1088 IN BOOLEAN ExtendedVerification
1091 IDE_BLK_IO_DEV
*IdeBlkIoDevice
;
1095 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1097 IdeBlkIoDevice
= IDE_BLOCK_IO_DEV_FROM_THIS (This
);
1099 // Requery IDE IO resources in case of the switch of native and legacy modes
1101 ReassignIdeResources (IdeBlkIoDevice
);
1104 // for ATA device, using ATA reset method
1106 if (IdeBlkIoDevice
->Type
== IdeHardDisk
||
1107 IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1108 Status
= AtaSoftReset (IdeBlkIoDevice
);
1112 if (IdeBlkIoDevice
->Type
== IdeUnknown
) {
1113 Status
= EFI_DEVICE_ERROR
;
1118 // for ATAPI device, using ATAPI reset method
1120 Status
= AtapiSoftReset (IdeBlkIoDevice
);
1121 if (ExtendedVerification
) {
1122 Status
= AtaSoftReset (IdeBlkIoDevice
);
1126 gBS
->RestoreTPL (OldTpl
);
1131 Read data from a block IO device
1133 @param This Block IO protocol instance pointer.
1134 @param MediaId The media ID of the device
1135 @param Lba Starting LBA address to read data
1136 @param BufferSize The size of data to be read
1137 @param Buffer Caller supplied buffer to save data
1139 @retval EFI_DEVICE_ERROR unknown device type
1140 @retval other read data status.
1145 IDEBlkIoReadBlocks (
1146 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1149 IN UINTN BufferSize
,
1153 IDE_BLK_IO_DEV
*IdeBlkIoDevice
;
1157 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1159 IdeBlkIoDevice
= IDE_BLOCK_IO_DEV_FROM_THIS (This
);
1162 // Requery IDE IO resources in case of the switch of native and legacy modes
1164 ReassignIdeResources (IdeBlkIoDevice
);
1167 // For ATA compatible device, use ATA read block's mechanism
1169 if (IdeBlkIoDevice
->Type
== IdeHardDisk
||
1170 IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1171 Status
= AtaBlkIoReadBlocks (
1181 if (IdeBlkIoDevice
->Type
== IdeUnknown
) {
1182 Status
= EFI_DEVICE_ERROR
;
1187 // for ATAPI device, using ATAPI read block's mechanism
1189 Status
= AtapiBlkIoReadBlocks (
1198 gBS
->RestoreTPL (OldTpl
);
1204 Write data to block io device.
1206 @param This Protocol instance pointer.
1207 @param MediaId The media ID of the device
1208 @param Lba Starting LBA address to write data
1209 @param BufferSize The size of data to be written
1210 @param Buffer Caller supplied buffer to save data
1212 @retval EFI_DEVICE_ERROR unknown device type
1213 @retval other write data status
1218 IDEBlkIoWriteBlocks (
1219 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1222 IN UINTN BufferSize
,
1226 IDE_BLK_IO_DEV
*IdeBlkIoDevice
;
1230 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1232 IdeBlkIoDevice
= IDE_BLOCK_IO_DEV_FROM_THIS (This
);
1234 // Requery IDE IO resources in case of the switch of native and legacy modes
1236 ReassignIdeResources (IdeBlkIoDevice
);
1239 // for ATA device, using ATA write block's mechanism
1241 if (IdeBlkIoDevice
->Type
== IdeHardDisk
||
1242 IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1244 Status
= AtaBlkIoWriteBlocks (
1254 if (IdeBlkIoDevice
->Type
== IdeUnknown
) {
1255 Status
= EFI_DEVICE_ERROR
;
1260 // for ATAPI device, using ATAPI write block's mechanism
1262 Status
= AtapiBlkIoWriteBlocks (
1271 gBS
->RestoreTPL (OldTpl
);
1275 Flushes all modified data to a physical block devices
1277 @param This Indicates a pointer to the calling context which to sepcify a
1278 sepcific block device
1280 @retval EFI_SUCCESS Always return success.
1284 IDEBlkIoFlushBlocks (
1285 IN EFI_BLOCK_IO_PROTOCOL
*This
1295 This function is used by the IDE bus driver to get inquiry data.
1296 Data format of Identify data is defined by the Interface GUID.
1298 @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1299 @param InquiryData Pointer to a buffer for the inquiry data.
1300 @param InquiryDataSize Pointer to the value for the inquiry data size.
1302 @retval EFI_SUCCESS The command was accepted without any errors.
1303 @retval EFI_NOT_FOUND Device does not support this data class
1304 @retval EFI_DEVICE_ERROR Error reading InquiryData from device
1305 @retval EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough
1310 IDEDiskInfoInquiry (
1311 IN EFI_DISK_INFO_PROTOCOL
*This
,
1312 IN OUT VOID
*InquiryData
,
1313 IN OUT UINT32
*InquiryDataSize
1316 IDE_BLK_IO_DEV
*IdeBlkIoDevice
;
1318 IdeBlkIoDevice
= IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This
);
1320 if (*InquiryDataSize
< sizeof (ATAPI_INQUIRY_DATA
)) {
1321 *InquiryDataSize
= sizeof (ATAPI_INQUIRY_DATA
);
1322 return EFI_BUFFER_TOO_SMALL
;
1325 if (IdeBlkIoDevice
->InquiryData
== NULL
) {
1326 return EFI_NOT_FOUND
;
1329 gBS
->CopyMem (InquiryData
, IdeBlkIoDevice
->InquiryData
, sizeof (ATAPI_INQUIRY_DATA
));
1330 *InquiryDataSize
= sizeof (ATAPI_INQUIRY_DATA
);
1336 This function is used by the IDE bus driver to get identify data.
1337 Data format of Identify data is defined by the Interface GUID.
1339 @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1340 @param IdentifyData Pointer to a buffer for the identify data.
1341 @param IdentifyDataSize Pointer to the value for the identify data size.
1343 @retval EFI_SUCCESS The command was accepted without any errors.
1344 @retval EFI_NOT_FOUND Device does not support this data class
1345 @retval EFI_DEVICE_ERROR Error reading IdentifyData from device
1346 @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough
1351 IDEDiskInfoIdentify (
1352 IN EFI_DISK_INFO_PROTOCOL
*This
,
1353 IN OUT VOID
*IdentifyData
,
1354 IN OUT UINT32
*IdentifyDataSize
1357 IDE_BLK_IO_DEV
*IdeBlkIoDevice
;
1359 IdeBlkIoDevice
= IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This
);
1361 if (*IdentifyDataSize
< sizeof (EFI_IDENTIFY_DATA
)) {
1362 *IdentifyDataSize
= sizeof (EFI_IDENTIFY_DATA
);
1363 return EFI_BUFFER_TOO_SMALL
;
1366 if (IdeBlkIoDevice
->IdData
== NULL
) {
1367 return EFI_NOT_FOUND
;
1370 gBS
->CopyMem (IdentifyData
, IdeBlkIoDevice
->IdData
, sizeof (EFI_IDENTIFY_DATA
));
1371 *IdentifyDataSize
= sizeof (EFI_IDENTIFY_DATA
);
1377 This function is used by the IDE bus driver to get sense data.
1378 Data format of Sense data is defined by the Interface GUID.
1380 @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1381 @param SenseData Pointer to the SenseData.
1382 @param SenseDataSize Size of SenseData in bytes.
1383 @param SenseDataNumber Pointer to the value for the identify data size.
1385 @retval EFI_SUCCESS The command was accepted without any errors.
1386 @retval EFI_NOT_FOUND Device does not support this data class
1387 @retval EFI_DEVICE_ERROR Error reading InquiryData from device
1388 @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough
1393 IDEDiskInfoSenseData (
1394 IN EFI_DISK_INFO_PROTOCOL
*This
,
1395 IN OUT VOID
*SenseData
,
1396 IN OUT UINT32
*SenseDataSize
,
1397 OUT UINT8
*SenseDataNumber
1400 return EFI_NOT_FOUND
;
1404 This function is used by the IDE bus driver to get controller information.
1406 @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1407 @param IdeChannel Pointer to the Ide Channel number. Primary or secondary.
1408 @param IdeDevice Pointer to the Ide Device number. Master or slave.
1410 @retval EFI_SUCCESS IdeChannel and IdeDevice are valid
1411 @retval EFI_UNSUPPORTED This is not an IDE device
1416 IDEDiskInfoWhichIde (
1417 IN EFI_DISK_INFO_PROTOCOL
*This
,
1418 OUT UINT32
*IdeChannel
,
1419 OUT UINT32
*IdeDevice
1422 IDE_BLK_IO_DEV
*IdeBlkIoDevice
;
1424 IdeBlkIoDevice
= IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This
);
1425 *IdeChannel
= IdeBlkIoDevice
->Channel
;
1426 *IdeDevice
= IdeBlkIoDevice
->Device
;
1432 The is an event(generally the event is exitBootService event) call back function.
1433 Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.
1435 @param Event Pointer to this event
1436 @param Context Event handler private data
1447 UINT64 IoPortForBmis
;
1448 UINT8 RegisterValue
;
1449 IDE_BLK_IO_DEV
*IdeDev
;
1454 IdeDev
= (IDE_BLK_IO_DEV
*) Context
;
1457 // Obtain IDE IO port registers' base addresses
1459 Status
= ReassignIdeResources (IdeDev
);
1460 if (EFI_ERROR (Status
)) {
1465 // Check whether interrupt is pending
1469 // Reset IDE device to force it de-assert interrupt pin
1470 // Note: this will reset all devices on this IDE channel
1472 Status
= AtaSoftReset (IdeDev
);
1473 if (EFI_ERROR (Status
)) {
1478 // Get base address of IDE Bus Master Status Regsiter
1480 if (IdePrimary
== IdeDev
->Channel
) {
1481 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISP_OFFSET
;
1483 if (IdeSecondary
== IdeDev
->Channel
) {
1484 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISS_OFFSET
;
1490 // Read BMIS register and clear ERROR and INTR bit
1492 IdeDev
->PciIo
->Io
.Read (
1495 EFI_PCI_IO_PASS_THROUGH_BAR
,
1501 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1503 IdeDev
->PciIo
->Io
.Write (
1506 EFI_PCI_IO_PASS_THROUGH_BAR
,
1513 // Select the other device on this channel to ensure this device to release the interrupt pin
1515 if (IdeDev
->Device
== 0) {
1516 RegisterValue
= (1 << 4) | 0xe0;
1518 RegisterValue
= (0 << 4) | 0xe0;
1522 IdeDev
->IoPort
->Head
,
1529 The user Entry Point for module IdeBus. The user code starts with this function.
1531 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1532 @param[in] SystemTable A pointer to the EFI System Table.
1534 @retval EFI_SUCCESS The entry point is executed successfully.
1535 @retval other Some error occurs when executing this entry point.
1541 IN EFI_HANDLE ImageHandle
,
1542 IN EFI_SYSTEM_TABLE
*SystemTable
1548 // Install driver model protocol(s).
1550 Status
= EfiLibInstallAllDriverProtocols2 (
1553 &gIDEBusDriverBinding
,
1555 &gIDEBusComponentName
,
1556 &gIDEBusComponentName2
,
1559 &gIDEBusDriverDiagnostics
,
1560 &gIDEBusDriverDiagnostics2
1562 ASSERT_EFI_ERROR (Status
);