3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 This module is modified from DXE\IDE module for Ide Contriller Init support
26 #define PCI_CLASS_MASS_STORAGE 0x01
27 #define PCI_SUB_CLASS_IDE 0x01
31 // IDE Bus Driver Binding Protocol Instance
33 EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding
= {
34 IDEBusDriverBindingSupported
,
35 IDEBusDriverBindingStart
,
36 IDEBusDriverBindingStop
,
43 // ***********************************************************************************
44 // IDEBusDriverBindingSupported
45 // ***********************************************************************************
49 IDEBusDriverBindingSupported (
50 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
51 IN EFI_HANDLE Controller
,
52 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
57 Register Driver Binding protocol for this driver.
60 This -- A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
61 ControllerHandle -- The handle of the controller to test.
62 RemainingDevicePath -- A pointer to the remaining portion of a device path.
65 EFI_SUCCESS - Driver loaded.
66 other - Driver not loaded.
68 // TODO: Controller - add argument and description to function comment
69 // TODO: EFI_UNSUPPORTED - add return value to function comment
72 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
74 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
76 if (RemainingDevicePath
!= NULL
) {
77 Node
= (EFI_DEV_PATH
*) RemainingDevicePath
;
78 if (Node
->DevPath
.Type
!= MESSAGING_DEVICE_PATH
||
79 Node
->DevPath
.SubType
!= MSG_ATAPI_DP
||
80 DevicePathNodeLength(&Node
->DevPath
) != sizeof(ATAPI_DEVICE_PATH
)) {
81 return EFI_UNSUPPORTED
;
86 // Open the IO Abstraction(s) needed to perform the supported test
88 Status
= gBS
->OpenProtocol (
90 &gEfiDevicePathProtocolGuid
,
91 (VOID
**) &ParentDevicePath
,
92 This
->DriverBindingHandle
,
94 EFI_OPEN_PROTOCOL_BY_DRIVER
96 if (Status
== EFI_ALREADY_STARTED
) {
100 if (EFI_ERROR (Status
)) {
105 // Clsoe protocol, don't use device path protocol in the .Support() function
109 &gEfiDevicePathProtocolGuid
,
110 This
->DriverBindingHandle
,
115 // Verify the Ide Controller Init Protocol, which installed by the
116 // IdeController module.
117 // Note 1: PciIo protocol has been opened BY_DRIVER by ide_init, so We can't
118 // open BY_DRIVER here) That's why we don't check pciio protocol
119 // Note 2: ide_init driver check ide controller's pci config space, so we dont
120 // check here any more to save code size
122 Status
= gBS
->OpenProtocol (
124 &gEfiIdeControllerInitProtocolGuid
,
126 This
->DriverBindingHandle
,
128 EFI_OPEN_PROTOCOL_BY_DRIVER
131 if (Status
== EFI_ALREADY_STARTED
) {
136 // If protocols were opened normally, closed it
140 &gEfiIdeControllerInitProtocolGuid
,
141 This
->DriverBindingHandle
,
149 // ***********************************************************************************
150 // IDEBusDriverBindingStart
151 // ***********************************************************************************
155 IDEBusDriverBindingStart (
156 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
157 IN EFI_HANDLE Controller
,
158 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
163 Start this driver on Controller by detecting all disks and installing
164 BlockIo protocol on them.
167 This - Protocol instance pointer.
168 Controller - Handle of device to bind driver to.
169 RemainingDevicePath - Not used, always produce all possible children.
172 EFI_SUCCESS - This driver is added to ControllerHandle.
173 EFI_ALREADY_STARTED - This driver is already running on ControllerHandle.
174 other - This driver does not support this device.
179 EFI_STATUS SavedStatus
;
180 EFI_PCI_IO_PROTOCOL
*PciIo
;
181 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
184 UINT8 BeginningIdeChannel
;
187 UINT8 BeginningIdeDevice
;
189 IDE_BLK_IO_DEV
*IdeBlkIoDevice
[IdeMaxChannel
][IdeMaxDevice
];
190 IDE_BLK_IO_DEV
*IdeBlkIoDevicePtr
;
191 IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr
[IdeMaxChannel
];
192 ATA_TRANSFER_MODE TransferMode
;
193 ATA_DRIVE_PARMS DriveParameters
;
194 EFI_DEV_PATH NewNode
;
195 UINT8 ConfigurationOptions
;
196 UINT16 CommandBlockBaseAddr
;
197 UINT16 ControlBlockBaseAddr
;
200 IDE_BUS_DRIVER_PRIVATE_DATA
*IdeBusDriverPrivateData
;
203 // Local variables declaration for IdeControllerInit support
205 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
207 BOOLEAN ChannelEnabled
;
210 EFI_IDENTIFY_DATA IdentifyData
;
211 EFI_ATA_COLLECTIVE_MODE
*SupportedModes
;
213 IdeBusDriverPrivateData
= NULL
;
214 SupportedModes
= NULL
;
217 // Perform IdeBus initialization
219 Status
= gBS
->OpenProtocol (
221 &gEfiDevicePathProtocolGuid
,
222 (VOID
**) &ParentDevicePath
,
223 This
->DriverBindingHandle
,
225 EFI_OPEN_PROTOCOL_BY_DRIVER
227 if ((EFI_ERROR (Status
)) && (Status
!= EFI_ALREADY_STARTED
)) {
232 // Now open the IDE_CONTROLLER_INIT protocol. Step7.1
234 Status
= gBS
->OpenProtocol (
236 &gEfiIdeControllerInitProtocolGuid
,
238 This
->DriverBindingHandle
,
240 EFI_OPEN_PROTOCOL_BY_DRIVER
244 // The following OpenProtocol function with _GET_PROTOCOL attribute and
245 // will not return EFI_ALREADY_STARTED, so save it for now
247 SavedStatus
= Status
;
249 if ((EFI_ERROR (Status
)) && (Status
!= EFI_ALREADY_STARTED
)) {
250 DEBUG ((EFI_D_ERROR
, "Open Init, Status=%x", Status
));
252 // open protocol is not SUCCESS or not ALREADY_STARTED, error exit
258 // Save Enumall and ChannelCount. Step7.2
260 EnumAll
= IdeInit
->EnumAll
;
261 ChannelCount
= IdeInit
->ChannelCount
;
264 // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL
265 // attribute will not return EFI_ALREADY_STARTED
267 Status
= gBS
->OpenProtocol (
269 &gEfiPciIoProtocolGuid
,
271 This
->DriverBindingHandle
,
273 EFI_OPEN_PROTOCOL_GET_PROTOCOL
275 if (EFI_ERROR (Status
)) {
276 DEBUG ((EFI_D_ERROR
, "Open PciIo, Status=%x", Status
));
281 // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable
283 if (SavedStatus
!= EFI_ALREADY_STARTED
) {
284 IdeBusDriverPrivateData
= AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA
));
285 if (IdeBusDriverPrivateData
== NULL
) {
286 Status
= EFI_OUT_OF_RESOURCES
;
290 ZeroMem (IdeBusDriverPrivateData
, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA
));
291 Status
= gBS
->InstallMultipleProtocolInterfaces (
294 IdeBusDriverPrivateData
,
297 if (EFI_ERROR (Status
)) {
302 Status
= gBS
->OpenProtocol (
305 (VOID
**) &IdeBusDriverPrivateData
,
306 This
->DriverBindingHandle
,
308 EFI_OPEN_PROTOCOL_GET_PROTOCOL
310 if (EFI_ERROR (Status
)) {
311 IdeBusDriverPrivateData
= NULL
;
316 Status
= PciIo
->Attributes (
318 EfiPciIoAttributeOperationEnable
,
319 EFI_PCI_DEVICE_ENABLE
,
322 if (EFI_ERROR (Status
)) {
327 // Read the environment variable that contains the IDEBus Driver's
328 // Config options that were set by the Driver Configuration Protocol
330 DataSize
= sizeof (ConfigurationOptions
);
331 Status
= gRT
->GetVariable (
332 (CHAR16
*) L
"Configuration",
336 &ConfigurationOptions
338 if (EFI_ERROR (Status
)) {
339 ConfigurationOptions
= 0x0f;
344 // If IdeInit->EnumAll is TRUE, must enumerate all IDE device anyway
346 BeginningIdeChannel
= IdePrimary
;
347 EndIdeChannel
= IdeSecondary
;
348 BeginningIdeDevice
= IdeMaster
;
349 EndIdeDevice
= IdeSlave
;
350 } else if (RemainingDevicePath
== NULL
) {
352 // RemainingDevicePath is NULL, scan IDE bus for each device;
354 BeginningIdeChannel
= IdePrimary
;
355 EndIdeChannel
= IdeSecondary
;
356 BeginningIdeDevice
= IdeMaster
;
358 // default, may be redefined by IdeInit
360 EndIdeDevice
= IdeSlave
;
363 // RemainingDevicePath is not NULL, only scan the specified device.
365 Node
= (EFI_DEV_PATH
*) RemainingDevicePath
;
366 BeginningIdeChannel
= Node
->Atapi
.PrimarySecondary
;
367 EndIdeChannel
= BeginningIdeChannel
;
368 BeginningIdeDevice
= Node
->Atapi
.SlaveMaster
;
369 EndIdeDevice
= BeginningIdeDevice
;
373 // Obtain IDE IO port registers' base addresses
375 Status
= GetIdeRegistersBaseAddr (PciIo
, IdeRegsBaseAddr
);
376 if (EFI_ERROR (Status
)) {
381 // Report status code: begin IdeBus initialization
383 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
385 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_PC_RESET
),
390 // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol
392 for (IdeChannel
= BeginningIdeChannel
; IdeChannel
<= EndIdeChannel
; IdeChannel
++) {
394 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelEnumeration
, IdeChannel
);
397 // now obtain channel information fron IdeControllerInit protocol. Step9
399 Status
= IdeInit
->GetChannelInfo (
405 if (EFI_ERROR (Status
)) {
406 DEBUG ((EFI_D_ERROR
, "[GetChannel, Status=%x]", Status
));
410 if (!ChannelEnabled
) {
414 EndIdeDevice
= (UINT8
) EFI_MIN ((MaxDevices
- 1), EndIdeDevice
);
417 // Now inform the IDE Controller Init Module. Sept10
419 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelReset
, IdeChannel
);
422 // No reset channel function implemented. Sept11
424 IdeInit
->NotifyPhase (IdeInit
, EfiIdeAfterChannelReset
, IdeChannel
);
429 IdeInit
->NotifyPhase (
431 EfiIdeBusBeforeDevicePresenceDetection
,
435 // -- 1st inner loop --- Master/Slave ------------ Step14
437 for (IdeDevice
= BeginningIdeDevice
; IdeDevice
<= EndIdeDevice
; IdeDevice
++) {
439 // Check whether the configuration options allow this device
441 if (!(ConfigurationOptions
& (1 << (IdeChannel
* 2 + IdeDevice
)))) {
446 // The device has been scanned in another Start(), No need to scan it again
447 // for perf optimization.
449 if (IdeBusDriverPrivateData
->HaveScannedDevice
[IdeChannel
* 2 + IdeDevice
]) {
454 // create child handle for the detected device.
456 IdeBlkIoDevice
[IdeChannel
][IdeDevice
] = AllocatePool (sizeof (IDE_BLK_IO_DEV
));
457 if (IdeBlkIoDevice
[IdeChannel
][IdeDevice
] == NULL
) {
461 IdeBlkIoDevicePtr
= IdeBlkIoDevice
[IdeChannel
][IdeDevice
];
463 ZeroMem (IdeBlkIoDevicePtr
, sizeof (IDE_BLK_IO_DEV
));
465 IdeBlkIoDevicePtr
->Signature
= IDE_BLK_IO_DEV_SIGNATURE
;
466 IdeBlkIoDevicePtr
->Channel
= IdeChannel
;
467 IdeBlkIoDevicePtr
->Device
= IdeDevice
;
470 // initialize Block IO interface's Media pointer
472 IdeBlkIoDevicePtr
->BlkIo
.Media
= &IdeBlkIoDevicePtr
->BlkMedia
;
475 // Initialize IDE IO port addresses, including Command Block registers
476 // and Control Block registers
478 IdeBlkIoDevicePtr
->IoPort
= AllocatePool (sizeof (IDE_BASE_REGISTERS
));
479 if (IdeBlkIoDevicePtr
->IoPort
== NULL
) {
483 ZeroMem (IdeBlkIoDevicePtr
->IoPort
, sizeof (IDE_BASE_REGISTERS
));
484 CommandBlockBaseAddr
= IdeRegsBaseAddr
[IdeChannel
].CommandBlockBaseAddr
;
485 ControlBlockBaseAddr
= IdeRegsBaseAddr
[IdeChannel
].ControlBlockBaseAddr
;
487 IdeBlkIoDevicePtr
->IoPort
->Data
= CommandBlockBaseAddr
;
488 (*(UINT16
*) &IdeBlkIoDevicePtr
->IoPort
->Reg1
) = (UINT16
) (CommandBlockBaseAddr
+ 0x01);
489 IdeBlkIoDevicePtr
->IoPort
->SectorCount
= (UINT16
) (CommandBlockBaseAddr
+ 0x02);
490 IdeBlkIoDevicePtr
->IoPort
->SectorNumber
= (UINT16
) (CommandBlockBaseAddr
+ 0x03);
491 IdeBlkIoDevicePtr
->IoPort
->CylinderLsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x04);
492 IdeBlkIoDevicePtr
->IoPort
->CylinderMsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x05);
493 IdeBlkIoDevicePtr
->IoPort
->Head
= (UINT16
) (CommandBlockBaseAddr
+ 0x06);
494 (*(UINT16
*) &IdeBlkIoDevicePtr
->IoPort
->Reg
) = (UINT16
) (CommandBlockBaseAddr
+ 0x07);
496 (*(UINT16
*) &IdeBlkIoDevicePtr
->IoPort
->Alt
) = ControlBlockBaseAddr
;
497 IdeBlkIoDevicePtr
->IoPort
->DriveAddress
= (UINT16
) (ControlBlockBaseAddr
+ 0x01);
499 IdeBlkIoDevicePtr
->IoPort
->MasterSlave
= (UINT16
) ((IdeDevice
== IdeMaster
) ? 1 : 0);
501 IdeBlkIoDevicePtr
->PciIo
= PciIo
;
502 IdeBlkIoDevicePtr
->IdeBusDriverPrivateData
= IdeBusDriverPrivateData
;
503 IdeBlkIoDevicePtr
->IoPort
->BusMasterBaseAddr
= IdeRegsBaseAddr
[IdeChannel
].BusMasterBaseAddr
;
506 // Discover device, now!
508 PERF_START (0, "DiscoverIdeDevice", "IDE", 0);
509 Status
= DiscoverIdeDevice (IdeBlkIoDevicePtr
);
510 PERF_END (0, "DiscoverIdeDevice", "IDE", 0);
512 IdeBusDriverPrivateData
->HaveScannedDevice
[IdeChannel
* 2 + IdeDevice
] = TRUE
;
513 IdeBusDriverPrivateData
->DeviceProcessed
[IdeChannel
* 2 + IdeDevice
] = FALSE
;
515 if (!EFI_ERROR (Status
)) {
519 ZeroMem (&NewNode
, sizeof (NewNode
));
520 NewNode
.DevPath
.Type
= MESSAGING_DEVICE_PATH
;
521 NewNode
.DevPath
.SubType
= MSG_ATAPI_DP
;
522 SetDevicePathNodeLength (&NewNode
.DevPath
, sizeof (ATAPI_DEVICE_PATH
));
524 NewNode
.Atapi
.PrimarySecondary
= (UINT8
) IdeBlkIoDevicePtr
->Channel
;
525 NewNode
.Atapi
.SlaveMaster
= (UINT8
) IdeBlkIoDevicePtr
->Device
;
526 NewNode
.Atapi
.Lun
= IdeBlkIoDevicePtr
->Lun
;
527 IdeBlkIoDevicePtr
->DevicePath
= AppendDevicePathNode (
531 if (IdeBlkIoDevicePtr
->DevicePath
== NULL
) {
532 ReleaseIdeResources (IdeBlkIoDevicePtr
);
537 // Submit identify data to IDE controller init driver
539 CopyMem (&IdentifyData
, IdeBlkIoDevicePtr
->pIdData
, sizeof (IdentifyData
));
540 // IdentifyData = *IdeBlkIoDevicePtr->pIdData;
541 IdeBusDriverPrivateData
->DeviceFound
[IdeChannel
* 2 + IdeDevice
] = TRUE
;
542 IdeInit
->SubmitData (IdeInit
, IdeChannel
, IdeDevice
, &IdentifyData
);
545 // Device detection failed
547 IdeBusDriverPrivateData
->DeviceFound
[IdeChannel
* 2 + IdeDevice
] = FALSE
;
548 IdeInit
->SubmitData (IdeInit
, IdeChannel
, IdeDevice
, NULL
);
549 ReleaseIdeResources (IdeBlkIoDevicePtr
);
550 IdeBlkIoDevicePtr
= NULL
;
553 // end of 1st inner loop ---
557 // end of 1st outer loop =========
562 // = 2nd outer loop == Primary/Secondary =================
564 for (IdeChannel
= BeginningIdeChannel
; IdeChannel
<= EndIdeChannel
; IdeChannel
++) {
567 // -- 2nd inner loop --- Master/Slave --------
569 for (IdeDevice
= BeginningIdeDevice
; IdeDevice
<= EndIdeDevice
; IdeDevice
++) {
571 if (IdeBusDriverPrivateData
->DeviceProcessed
[IdeChannel
* 2 + IdeDevice
]) {
575 if (!IdeBusDriverPrivateData
->DeviceFound
[IdeChannel
* 2 + IdeDevice
]) {
579 Status
= IdeInit
->CalculateMode (
585 if (EFI_ERROR (Status
)) {
586 DEBUG ((EFI_D_ERROR
, "[bStStp20S=%x]", Status
));
590 IdeBlkIoDevicePtr
= IdeBlkIoDevice
[IdeChannel
][IdeDevice
];
593 // Set best supported PIO mode on this IDE device
595 if (SupportedModes
->PioMode
.Mode
<= ATA_PIO_MODE_2
) {
596 TransferMode
.ModeCategory
= ATA_MODE_CATEGORY_DEFAULT_PIO
;
598 TransferMode
.ModeCategory
= ATA_MODE_CATEGORY_FLOW_PIO
;
601 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->PioMode
.Mode
);
603 if (SupportedModes
->ExtModeCount
== 0){
604 Status
= SetDeviceTransferMode (IdeBlkIoDevicePtr
, &TransferMode
);
606 if (EFI_ERROR (Status
)) {
607 IdeBusDriverPrivateData
->DeviceFound
[IdeChannel
* 2 + IdeDevice
] = FALSE
;
608 ReleaseIdeResources (IdeBlkIoDevicePtr
);
609 IdeBlkIoDevicePtr
= NULL
;
615 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
616 // be set together. Only one DMA mode can be set to a device. If setting
617 // DMA mode operation fails, we can continue moving on because we only use
618 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
620 if (SupportedModes
->UdmaMode
.Valid
) {
622 TransferMode
.ModeCategory
= ATA_MODE_CATEGORY_UDMA
;
623 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->UdmaMode
.Mode
);
624 Status
= SetDeviceTransferMode (IdeBlkIoDevicePtr
, &TransferMode
);
626 if (EFI_ERROR (Status
)) {
627 IdeBusDriverPrivateData
->DeviceFound
[IdeChannel
* 2 + IdeDevice
] = FALSE
;
628 ReleaseIdeResources (IdeBlkIoDevicePtr
);
629 IdeBlkIoDevicePtr
= NULL
;
633 EnableInterrupt (IdeBlkIoDevicePtr
);
634 } else if (SupportedModes
->MultiWordDmaMode
.Valid
) {
636 TransferMode
.ModeCategory
= ATA_MODE_CATEGORY_MDMA
;
637 TransferMode
.ModeNumber
= (UINT8
) SupportedModes
->MultiWordDmaMode
.Mode
;
638 Status
= SetDeviceTransferMode (IdeBlkIoDevicePtr
, &TransferMode
);
640 if (EFI_ERROR (Status
)) {
641 IdeBusDriverPrivateData
->DeviceFound
[IdeChannel
* 2 + IdeDevice
] = FALSE
;
642 ReleaseIdeResources (IdeBlkIoDevicePtr
);
643 IdeBlkIoDevicePtr
= NULL
;
647 EnableInterrupt (IdeBlkIoDevicePtr
);
650 // Init driver parameters
652 DriveParameters
.Sector
= (UINT8
) IdeBlkIoDevicePtr
->pIdData
->AtaData
.sectors_per_track
;
653 DriveParameters
.Heads
= (UINT8
) (IdeBlkIoDevicePtr
->pIdData
->AtaData
.heads
- 1);
654 DriveParameters
.MultipleSector
= (UINT8
) IdeBlkIoDevicePtr
->pIdData
->AtaData
.multi_sector_cmd_max_sct_cnt
;
656 // Set Parameters for the device:
658 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
660 if ((IdeBlkIoDevicePtr
->Type
== IdeHardDisk
) || (IdeBlkIoDevicePtr
->Type
== Ide48bitAddressingHardDisk
)) {
661 Status
= SetDriveParameters (IdeBlkIoDevicePtr
, &DriveParameters
);
665 // Record PIO mode used in private data
667 IdeBlkIoDevicePtr
->PioMode
= SupportedModes
->PioMode
.Mode
;
670 // Set IDE controller Timing Blocks in the PCI Configuration Space
672 IdeInit
->SetTiming (IdeInit
, IdeChannel
, IdeDevice
, SupportedModes
);
675 // Add Component Name for the IDE/ATAPI device that was discovered.
677 IdeBlkIoDevicePtr
->ControllerNameTable
= NULL
;
678 ADD_NAME (IdeBlkIoDevicePtr
);
680 Status
= gBS
->InstallMultipleProtocolInterfaces (
681 &IdeBlkIoDevicePtr
->Handle
,
682 &gEfiDevicePathProtocolGuid
,
683 IdeBlkIoDevicePtr
->DevicePath
,
684 &gEfiBlockIoProtocolGuid
,
685 &IdeBlkIoDevicePtr
->BlkIo
,
686 &gEfiDiskInfoProtocolGuid
,
687 &IdeBlkIoDevicePtr
->DiskInfo
,
691 if (EFI_ERROR (Status
)) {
692 ReleaseIdeResources (IdeBlkIoDevicePtr
);
697 &gEfiPciIoProtocolGuid
,
699 This
->DriverBindingHandle
,
700 IdeBlkIoDevicePtr
->Handle
,
701 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
704 IdeBusDriverPrivateData
->DeviceProcessed
[IdeChannel
* 2 + IdeDevice
] = TRUE
;
707 // Report status code: device eanbled!
709 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
711 (EFI_IO_BUS_ATA_ATAPI
| EFI_P_PC_ENABLE
),
712 IdeBlkIoDevicePtr
->DevicePath
715 // end of 2nd inner loop ----
719 // end of 2nd outer loop ==========
724 // All configurations done! Notify IdeController to do post initialization
725 // work such as saving IDE controller PCI settings for S3 resume
727 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusPhaseMaximum
, 0);
729 if (SupportedModes
!= NULL
) {
730 gBS
->FreePool (SupportedModes
);
733 PERF_START (0, "Finish IDE detection", "IDE", 1);
734 PERF_END (0, "Finish IDE detection", "IDE", 0);
741 // Report error code: controller error
743 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
744 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
745 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_EC_CONTROLLER_ERROR
),
751 &gEfiIdeControllerInitProtocolGuid
,
752 This
->DriverBindingHandle
,
756 gBS
->UninstallMultipleProtocolInterfaces (
759 IdeBusDriverPrivateData
,
763 if (IdeBusDriverPrivateData
!= NULL
) {
764 gBS
->FreePool (IdeBusDriverPrivateData
);
767 if (SupportedModes
!= NULL
) {
768 gBS
->FreePool (SupportedModes
);
773 &gEfiPciIoProtocolGuid
,
774 This
->DriverBindingHandle
,
780 &gEfiDevicePathProtocolGuid
,
781 This
->DriverBindingHandle
,
790 // ***********************************************************************************
791 // IDEBusDriverBindingStop
792 // ***********************************************************************************
796 IDEBusDriverBindingStop (
797 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
798 IN EFI_HANDLE Controller
,
799 IN UINTN NumberOfChildren
,
800 IN EFI_HANDLE
*ChildHandleBuffer
805 Stop this driver on Controller Handle.
808 This - Protocol instance pointer.
809 DeviceHandle - Handle of device to stop driver on
810 NumberOfChildren - Not used
811 ChildHandleBuffer - Not used
814 EFI_SUCCESS - This driver is removed DeviceHandle
815 other - This driver was not removed from this device
818 // TODO: Controller - add argument and description to function comment
819 // TODO: EFI_DEVICE_ERROR - add return value to function comment
822 EFI_PCI_IO_PROTOCOL
*PciIo
;
823 BOOLEAN AllChildrenStopped
;
825 IDE_BUS_DRIVER_PRIVATE_DATA
*IdeBusDriverPrivateData
;
827 IdeBusDriverPrivateData
= NULL
;
829 if (NumberOfChildren
== 0) {
831 Status
= gBS
->OpenProtocol (
833 &gEfiPciIoProtocolGuid
,
835 This
->DriverBindingHandle
,
837 EFI_OPEN_PROTOCOL_GET_PROTOCOL
839 if (!EFI_ERROR (Status
)) {
842 EfiPciIoAttributeOperationDisable
,
843 EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO
| EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO
| EFI_PCI_DEVICE_ENABLE
,
851 (VOID
**) &IdeBusDriverPrivateData
,
852 This
->DriverBindingHandle
,
854 EFI_OPEN_PROTOCOL_GET_PROTOCOL
857 gBS
->UninstallMultipleProtocolInterfaces (
860 IdeBusDriverPrivateData
,
864 if (IdeBusDriverPrivateData
!= NULL
) {
865 gBS
->FreePool (IdeBusDriverPrivateData
);
868 // Close the bus driver
872 &gEfiIdeControllerInitProtocolGuid
,
873 This
->DriverBindingHandle
,
878 &gEfiPciIoProtocolGuid
,
879 This
->DriverBindingHandle
,
884 &gEfiDevicePathProtocolGuid
,
885 This
->DriverBindingHandle
,
892 AllChildrenStopped
= TRUE
;
894 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
896 Status
= DeRegisterIdeDevice (This
, Controller
, ChildHandleBuffer
[Index
]);
898 if (EFI_ERROR (Status
)) {
899 AllChildrenStopped
= FALSE
;
903 if (!AllChildrenStopped
) {
904 return EFI_DEVICE_ERROR
;
911 // ***********************************************************************************
912 // DeRegisterIdeDevice
913 // ***********************************************************************************
916 DeRegisterIdeDevice (
917 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
918 IN EFI_HANDLE Controller
,
925 Deregister an IDE device and free resources
929 This - Protocol instance pointer.
930 Controller - Ide device handle
931 Handle - Handle of device to deregister driver on
938 // TODO: EFI_SUCCESS - add return value to function comment
941 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
942 IDE_BLK_IO_DEV
*IdeBlkIoDevice
;
943 EFI_PCI_IO_PROTOCOL
*PciIo
;
946 Status
= gBS
->OpenProtocol (
948 &gEfiBlockIoProtocolGuid
,
950 This
->DriverBindingHandle
,
952 EFI_OPEN_PROTOCOL_GET_PROTOCOL
954 if (EFI_ERROR (Status
)) {
958 IdeBlkIoDevice
= IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo
);
961 // Report Status code: Device disabled
963 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
965 (EFI_IO_BUS_ATA_ATAPI
| EFI_P_PC_DISABLE
),
966 IdeBlkIoDevice
->DevicePath
970 // Close the child handle
972 Status
= gBS
->CloseProtocol (
974 &gEfiPciIoProtocolGuid
,
975 This
->DriverBindingHandle
,
979 Status
= gBS
->UninstallMultipleProtocolInterfaces (
981 &gEfiDevicePathProtocolGuid
,
982 IdeBlkIoDevice
->DevicePath
,
983 &gEfiBlockIoProtocolGuid
,
984 &IdeBlkIoDevice
->BlkIo
,
985 &gEfiDiskInfoProtocolGuid
,
986 &IdeBlkIoDevice
->DiskInfo
,
990 if (EFI_ERROR (Status
)) {
993 &gEfiPciIoProtocolGuid
,
995 This
->DriverBindingHandle
,
997 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1003 // Release allocated resources
1005 Index
= IdeBlkIoDevice
->Channel
* 2 + IdeBlkIoDevice
->Device
;
1006 IdeBlkIoDevice
->IdeBusDriverPrivateData
->HaveScannedDevice
[Index
] = FALSE
;
1008 ReleaseIdeResources (IdeBlkIoDevice
);
1014 // ***********************************************************************************
1016 // ***********************************************************************************
1021 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1022 IN BOOLEAN ExtendedVerification
1026 Routine Description:
1035 // TODO: This - add argument and description to function comment
1036 // TODO: ExtendedVerification - add argument and description to function comment
1037 // TODO: EFI_DEVICE_ERROR - add return value to function comment
1039 IDE_BLK_IO_DEV
*IdeBlkIoDevice
;
1042 IdeBlkIoDevice
= IDE_BLOCK_IO_DEV_FROM_THIS (This
);
1044 // Requery IDE IO resources in case of the switch of native and legacy modes
1046 ReassignIdeResources (IdeBlkIoDevice
);
1049 // for ATA device, using ATA reset method
1051 if (IdeBlkIoDevice
->Type
== IdeHardDisk
) {
1052 return AtaSoftReset (IdeBlkIoDevice
);
1055 if (IdeBlkIoDevice
->Type
== IdeUnknown
) {
1056 return EFI_DEVICE_ERROR
;
1060 // for ATAPI device, using ATAPI reset method
1062 Status
= AtapiSoftReset (IdeBlkIoDevice
);
1063 if (ExtendedVerification
) {
1064 Status
= AtaSoftReset (IdeBlkIoDevice
);
1072 IDEBlkIoReadBlocks (
1073 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1076 IN UINTN BufferSize
,
1081 Routine Description:
1083 Read data from block io device
1087 This - Protocol instance pointer.
1088 MediaId - The media ID of the device
1089 LBA - Starting LBA address to read data
1090 BufferSize - The size of data to be read
1091 Buffer - Caller supplied buffer to save data
1098 // TODO: EFI_DEVICE_ERROR - add return value to function comment
1100 IDE_BLK_IO_DEV
*IdeBlkIoDevice
;
1102 IdeBlkIoDevice
= IDE_BLOCK_IO_DEV_FROM_THIS (This
);
1105 // Requery IDE IO resources in case of the switch of native and legacy modes
1107 ReassignIdeResources (IdeBlkIoDevice
);
1110 // For ATA compatible device, use ATA read block's mechanism
1112 if (IdeBlkIoDevice
->Type
== IdeHardDisk
||
1113 IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1114 return AtaBlkIoReadBlocks (
1123 if (IdeBlkIoDevice
->Type
== IdeUnknown
) {
1124 return EFI_DEVICE_ERROR
;
1128 // for ATAPI device, using ATAPI read block's mechanism
1130 return AtapiBlkIoReadBlocks (
1142 IDEBlkIoWriteBlocks (
1143 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1146 IN UINTN BufferSize
,
1151 Routine Description:
1153 Write data to block io device
1157 This - Protocol instance pointer.
1158 MediaId - The media ID of the device
1159 LBA - Starting LBA address to write data
1160 BufferSize - The size of data to be written
1161 Buffer - Caller supplied buffer to save data
1168 // TODO: EFI_DEVICE_ERROR - add return value to function comment
1170 IDE_BLK_IO_DEV
*IdeBlkIoDevice
;
1172 IdeBlkIoDevice
= IDE_BLOCK_IO_DEV_FROM_THIS (This
);
1174 // Requery IDE IO resources in case of the switch of native and legacy modes
1176 ReassignIdeResources (IdeBlkIoDevice
);
1179 // for ATA device, using ATA write block's mechanism
1181 if (IdeBlkIoDevice
->Type
== IdeHardDisk
||
1182 IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1184 return AtaBlkIoWriteBlocks (
1193 if (IdeBlkIoDevice
->Type
== IdeUnknown
) {
1194 return EFI_DEVICE_ERROR
;
1198 // for ATAPI device, using ATAPI write block's mechanism
1200 return AtapiBlkIoWriteBlocks (
1210 // ***********************************************************************************
1211 // IDEBlkIoFlushBlocks
1212 // ***********************************************************************************
1216 IDEBlkIoFlushBlocks (
1217 IN EFI_BLOCK_IO_PROTOCOL
*This
1221 Routine Description:
1230 // TODO: This - add argument and description to function comment
1231 // TODO: EFI_SUCCESS - add return value to function comment
1241 IDEDiskInfoInquiry (
1242 IN EFI_DISK_INFO_PROTOCOL
*This
,
1243 IN OUT VOID
*InquiryData
,
1244 IN OUT UINT32
*InquiryDataSize
1248 Routine Description:
1249 Return the results of the Inquiry command to a drive in InquiryData.
1250 Data format of Inquiry data is defined by the Interface GUID.
1253 This - Protocol instance pointer.
1254 InquiryData - Results of Inquiry command to device
1255 InquiryDataSize - Size of InquiryData in bytes.
1258 EFI_SUCCESS - InquiryData valid
1259 EFI_NOT_FOUND - Device does not support this data class
1260 EFI_DEVICE_ERROR - Error reading InquiryData from device
1261 EFI_BUFFER_TOO_SMALL - IntquiryDataSize not big enough
1265 IDE_BLK_IO_DEV
*IdeBlkIoDevice
;
1267 IdeBlkIoDevice
= IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This
);
1269 if (*InquiryDataSize
< sizeof (INQUIRY_DATA
)) {
1270 *InquiryDataSize
= sizeof (INQUIRY_DATA
);
1271 return EFI_BUFFER_TOO_SMALL
;
1274 if (IdeBlkIoDevice
->pInquiryData
== NULL
) {
1275 return EFI_NOT_FOUND
;
1278 gBS
->CopyMem (InquiryData
, IdeBlkIoDevice
->pInquiryData
, sizeof (INQUIRY_DATA
));
1279 *InquiryDataSize
= sizeof (INQUIRY_DATA
);
1286 IDEDiskInfoIdentify (
1287 IN EFI_DISK_INFO_PROTOCOL
*This
,
1288 IN OUT VOID
*IdentifyData
,
1289 IN OUT UINT32
*IdentifyDataSize
1293 Routine Description:
1294 Return the results of the Identify command to a drive in IdentifyData.
1295 Data format of Identify data is defined by the Interface GUID.
1298 This - Protocol instance pointer.
1299 IdentifyData - Results of Identify command to device
1300 IdentifyDataSize - Size of IdentifyData in bytes.
1303 EFI_SUCCESS - IdentifyData valid
1304 EFI_NOT_FOUND - Device does not support this data class
1305 EFI_DEVICE_ERROR - Error reading IdentifyData from device
1306 EFI_BUFFER_TOO_SMALL - IdentifyDataSize not big enough
1310 IDE_BLK_IO_DEV
*IdeBlkIoDevice
;
1312 IdeBlkIoDevice
= IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This
);
1314 if (*IdentifyDataSize
< sizeof (EFI_IDENTIFY_DATA
)) {
1315 *IdentifyDataSize
= sizeof (EFI_IDENTIFY_DATA
);
1316 return EFI_BUFFER_TOO_SMALL
;
1319 if (IdeBlkIoDevice
->pIdData
== NULL
) {
1320 return EFI_NOT_FOUND
;
1323 gBS
->CopyMem (IdentifyData
, IdeBlkIoDevice
->pIdData
, sizeof (EFI_IDENTIFY_DATA
));
1324 *IdentifyDataSize
= sizeof (EFI_IDENTIFY_DATA
);
1331 IDEDiskInfoSenseData (
1332 IN EFI_DISK_INFO_PROTOCOL
*This
,
1333 IN OUT VOID
*SenseData
,
1334 IN OUT UINT32
*SenseDataSize
,
1335 OUT UINT8
*SenseDataNumber
1339 Routine Description:
1340 Return the results of the Request Sense command to a drive in SenseData.
1341 Data format of Sense data is defined by the Interface GUID.
1344 This - Protocol instance pointer.
1345 SenseData - Results of Request Sense command to device
1346 SenseDataSize - Size of SenseData in bytes.
1347 SenseDataNumber - Type of SenseData
1350 EFI_SUCCESS - InquiryData valid
1351 EFI_NOT_FOUND - Device does not support this data class
1352 EFI_DEVICE_ERROR - Error reading InquiryData from device
1353 EFI_BUFFER_TOO_SMALL - SenseDataSize not big enough
1357 return EFI_NOT_FOUND
;
1362 IDEDiskInfoWhichIde (
1363 IN EFI_DISK_INFO_PROTOCOL
*This
,
1364 OUT UINT32
*IdeChannel
,
1365 OUT UINT32
*IdeDevice
1369 Routine Description:
1370 Return the results of the Request Sense command to a drive in SenseData.
1371 Data format of Sense data is defined by the Interface GUID.
1374 This - Protocol instance pointer.
1375 IdeChannel - Primary or Secondary
1376 IdeDevice - Master or Slave
1379 EFI_SUCCESS - IdeChannel and IdeDevice are valid
1380 EFI_UNSUPPORTED - This is not an IDE device
1384 IDE_BLK_IO_DEV
*IdeBlkIoDevice
;
1386 IdeBlkIoDevice
= IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This
);
1387 *IdeChannel
= IdeBlkIoDevice
->Channel
;
1388 *IdeDevice
= IdeBlkIoDevice
->Device
;