2 This file implements protocol interfaces for ATA bus driver.
4 This file implements protocol interfaces: Driver Binding protocol,
5 Block IO protocol and DiskInfo protocol.
7 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
8 This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The 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.
22 // ATA Bus Driver Binding Protocol Instance
24 EFI_DRIVER_BINDING_PROTOCOL gAtaBusDriverBinding
= {
25 AtaBusDriverBindingSupported
,
26 AtaBusDriverBindingStart
,
27 AtaBusDriverBindingStop
,
34 // Template for ATA Child Device.
36 ATA_DEVICE gAtaDeviceTemplate
= {
37 ATA_DEVICE_SIGNATURE
, // Signature
40 EFI_BLOCK_IO_PROTOCOL_REVISION
,
44 AtaBlockIoWriteBlocks
,
50 AtaBlockIoReadBlocksEx
,
51 AtaBlockIoWriteBlocksEx
,
52 AtaBlockIoFlushBlocksEx
56 FALSE
, // RemovableMedia
58 FALSE
, // LogicPartition
60 FALSE
, // WritingCache
64 0, // LowestAlignedLba
65 1 // LogicalBlocksPerPhysicalBlock
68 EFI_DISK_INFO_IDE_INTERFACE_GUID
,
75 NULL
, // AtaBusDriverData
77 0, // PortMultiplierPort
84 NULL
, // ControllerNameTable
85 {L
'\0', }, // ModelName
86 {NULL
, NULL
} // AtaTaskList
90 Allocates an aligned buffer for ATA device.
92 This function allocates an aligned buffer for the ATA device to perform
93 ATA pass through operations. The alignment requirement is from ATA pass
96 @param AtaDevice The ATA child device involved for the operation.
97 @param BufferSize The request buffer size.
99 @return A pointer to the aligned buffer or NULL if the allocation fails.
103 AllocateAlignedBuffer (
104 IN ATA_DEVICE
*AtaDevice
,
108 return AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize
), AtaDevice
->AtaBusDriverData
->AtaPassThru
->Mode
->IoAlign
);
112 Frees an aligned buffer for ATA device.
114 This function frees an aligned buffer for the ATA device to perform
115 ATA pass through operations.
117 @param Buffer The aligned buffer to be freed.
118 @param BufferSize The request buffer size.
127 if (Buffer
!= NULL
) {
128 FreePages (Buffer
, EFI_SIZE_TO_PAGES (BufferSize
));
134 Release all the resources allocated for the ATA device.
136 This function releases all the resources allocated for the ATA device.
138 @param AtaDevice The ATA child device involved for the operation.
142 ReleaseAtaResources (
143 IN ATA_DEVICE
*AtaDevice
146 ATA_BUS_ASYN_TASK
*Task
;
148 LIST_ENTRY
*DelEntry
;
151 FreeUnicodeStringTable (AtaDevice
->ControllerNameTable
);
152 FreeAlignedBuffer (AtaDevice
->Asb
, sizeof (*AtaDevice
->Asb
));
153 FreeAlignedBuffer (AtaDevice
->IdentifyData
, sizeof (*AtaDevice
->IdentifyData
));
154 if (AtaDevice
->DevicePath
!= NULL
) {
155 FreePool (AtaDevice
->DevicePath
);
157 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
158 if (!IsListEmpty (&AtaDevice
->AtaTaskList
)) {
160 // Free the Subtask list.
162 for(Entry
= (&AtaDevice
->AtaTaskList
)->ForwardLink
;
163 Entry
!= (&AtaDevice
->AtaTaskList
);
166 Entry
= Entry
->ForwardLink
;
167 Task
= ATA_AYNS_TASK_FROM_ENTRY (DelEntry
);
169 RemoveEntryList (DelEntry
);
170 FreeAtaSubTask (Task
);
173 gBS
->RestoreTPL (OldTpl
);
174 FreePool (AtaDevice
);
179 Registers an ATA device.
181 This function allocates an ATA device structure for the ATA device specified by
182 Port and PortMultiplierPort if the ATA device is identified as a valid one.
183 Then it will create child handle and install Block IO and Disk Info protocol on
186 @param AtaBusDriverData The parent ATA bus driver data structure.
187 @param Port The port number of the ATA device.
188 @param PortMultiplierPort The port multiplier port number of the ATA device.
190 @retval EFI_SUCCESS The ATA device is successfully registered.
191 @retval EFI_OUT_OF_RESOURCES There is not enough memory to allocate the ATA device
192 and related data structures.
193 @return Others Some error occurs when registering the ATA device.
197 IN OUT ATA_BUS_DRIVER_DATA
*AtaBusDriverData
,
199 IN UINT16 PortMultiplierPort
203 ATA_DEVICE
*AtaDevice
;
204 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
205 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePathNode
;
206 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
207 EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
;
208 EFI_HANDLE DeviceHandle
;
211 NewDevicePathNode
= NULL
;
213 RemainingDevicePath
= NULL
;
218 AtaPassThru
= AtaBusDriverData
->AtaPassThru
;
219 Status
= AtaPassThru
->BuildDevicePath (AtaPassThru
, Port
, PortMultiplierPort
, &NewDevicePathNode
);
220 if (EFI_ERROR (Status
)) {
224 DevicePath
= AppendDevicePathNode (AtaBusDriverData
->ParentDevicePath
, NewDevicePathNode
);
225 if (DevicePath
== NULL
) {
226 Status
= EFI_OUT_OF_RESOURCES
;
231 RemainingDevicePath
= DevicePath
;
232 Status
= gBS
->LocateDevicePath (&gEfiDevicePathProtocolGuid
, &RemainingDevicePath
, &DeviceHandle
);
233 if (!EFI_ERROR (Status
) && (DeviceHandle
!= NULL
) && IsDevicePathEnd(RemainingDevicePath
)) {
234 Status
= EFI_ALREADY_STARTED
;
235 FreePool (DevicePath
);
240 // Allocate ATA device from the template.
242 AtaDevice
= AllocateCopyPool (sizeof (gAtaDeviceTemplate
), &gAtaDeviceTemplate
);
243 if (AtaDevice
== NULL
) {
244 Status
= EFI_OUT_OF_RESOURCES
;
249 // Initializes ATA device structures and allocates the required buffer.
251 AtaDevice
->BlockIo
.Media
= &AtaDevice
->BlockMedia
;
252 AtaDevice
->BlockIo2
.Media
= &AtaDevice
->BlockMedia
;
253 AtaDevice
->AtaBusDriverData
= AtaBusDriverData
;
254 AtaDevice
->DevicePath
= DevicePath
;
255 AtaDevice
->Port
= Port
;
256 AtaDevice
->PortMultiplierPort
= PortMultiplierPort
;
257 AtaDevice
->Asb
= AllocateAlignedBuffer (AtaDevice
, sizeof (*AtaDevice
->Asb
));
258 if (AtaDevice
->Asb
== NULL
) {
259 Status
= EFI_OUT_OF_RESOURCES
;
262 AtaDevice
->IdentifyData
= AllocateAlignedBuffer (AtaDevice
, sizeof (*AtaDevice
->IdentifyData
));
263 if (AtaDevice
->IdentifyData
== NULL
) {
264 Status
= EFI_OUT_OF_RESOURCES
;
269 // Initial Ata Task List
271 InitializeListHead (&AtaDevice
->AtaTaskList
);
274 // Try to identify the ATA device via the ATA pass through command.
276 Status
= DiscoverAtaDevice (AtaDevice
);
277 if (EFI_ERROR (Status
)) {
282 // Build controller name for Component Name (2) protocol.
284 Status
= AddUnicodeString2 (
286 gAtaBusComponentName
.SupportedLanguages
,
287 &AtaDevice
->ControllerNameTable
,
288 AtaDevice
->ModelName
,
291 if (EFI_ERROR (Status
)) {
295 Status
= AddUnicodeString2 (
297 gAtaBusComponentName2
.SupportedLanguages
,
298 &AtaDevice
->ControllerNameTable
,
299 AtaDevice
->ModelName
,
302 if (EFI_ERROR (Status
)) {
307 // Update to AHCI interface GUID based on device path node. The default one
308 // is IDE interface GUID copied from template.
310 if (NewDevicePathNode
->SubType
== MSG_SATA_DP
) {
311 CopyGuid (&AtaDevice
->DiskInfo
.Interface
, &gEfiDiskInfoAhciInterfaceGuid
);
314 Status
= gBS
->InstallMultipleProtocolInterfaces (
316 &gEfiDevicePathProtocolGuid
,
317 AtaDevice
->DevicePath
,
318 &gEfiBlockIoProtocolGuid
,
320 &gEfiBlockIo2ProtocolGuid
,
321 &AtaDevice
->BlockIo2
,
322 &gEfiDiskInfoProtocolGuid
,
323 &AtaDevice
->DiskInfo
,
326 if (EFI_ERROR (Status
)) {
331 AtaBusDriverData
->Controller
,
332 &gEfiAtaPassThruProtocolGuid
,
333 (VOID
**) &AtaPassThru
,
334 AtaBusDriverData
->DriverBindingHandle
,
336 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
340 if (NewDevicePathNode
!= NULL
) {
341 FreePool (NewDevicePathNode
);
344 if (EFI_ERROR (Status
) && (AtaDevice
!= NULL
)) {
345 ReleaseAtaResources (AtaDevice
);
346 DEBUG ((DEBUG_ERROR
| DEBUG_INIT
, "Failed to initialize Port %x PortMultiplierPort %x, status = %r\n", Port
, PortMultiplierPort
, Status
));
353 Unregisters an ATA device.
355 This function removes the protocols installed on the controller handle and
356 frees the resources allocated for the ATA device.
358 @param This The pointer to EFI_DRIVER_BINDING_PROTOCOL instance.
359 @param Controller The controller handle of the ATA device.
360 @param Handle The child handle.
362 @retval EFI_SUCCESS The ATA device is successfully unregistered.
363 @return Others Some error occurs when unregistering the ATA device.
367 UnregisterAtaDevice (
368 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
369 IN EFI_HANDLE Controller
,
374 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
375 EFI_BLOCK_IO2_PROTOCOL
*BlockIo2
;
376 ATA_DEVICE
*AtaDevice
;
377 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
381 Status
= gBS
->OpenProtocol (
383 &gEfiBlockIoProtocolGuid
,
385 This
->DriverBindingHandle
,
387 EFI_OPEN_PROTOCOL_GET_PROTOCOL
389 if (EFI_ERROR (Status
)) {
391 // Locate BlockIo2 protocol
393 Status
= gBS
->OpenProtocol (
395 &gEfiBlockIo2ProtocolGuid
,
397 This
->DriverBindingHandle
,
399 EFI_OPEN_PROTOCOL_GET_PROTOCOL
401 if (EFI_ERROR (Status
)) {
407 // Get AtaDevice data.
409 if (BlockIo
!= NULL
) {
410 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO (BlockIo
);
412 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO2 (BlockIo2
);
416 // Close the child handle
420 &gEfiAtaPassThruProtocolGuid
,
421 This
->DriverBindingHandle
,
426 // The Ata Bus driver installs the BlockIo and BlockIo2 in the DriverBindingStart().
427 // Here should uninstall both of them.
429 Status
= gBS
->UninstallMultipleProtocolInterfaces (
431 &gEfiDevicePathProtocolGuid
,
432 AtaDevice
->DevicePath
,
433 &gEfiBlockIoProtocolGuid
,
435 &gEfiBlockIo2ProtocolGuid
,
436 &AtaDevice
->BlockIo2
,
437 &gEfiDiskInfoProtocolGuid
,
438 &AtaDevice
->DiskInfo
,
442 if (EFI_ERROR (Status
)) {
445 &gEfiAtaPassThruProtocolGuid
,
446 (VOID
**) &AtaPassThru
,
447 This
->DriverBindingHandle
,
449 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
454 ReleaseAtaResources (AtaDevice
);
461 Tests to see if this driver supports a given controller. If a child device is provided,
462 it further tests to see if this driver supports creating a handle for the specified child device.
464 This function checks to see if the driver specified by This supports the device specified by
465 ControllerHandle. Drivers will typically use the device path attached to
466 ControllerHandle and/or the services from the bus I/O abstraction attached to
467 ControllerHandle to determine if the driver supports ControllerHandle. This function
468 may be called many times during platform initialization. In order to reduce boot times, the tests
469 performed by this function must be very small, and take as little time as possible to execute. This
470 function must not change the state of any hardware devices, and this function must be aware that the
471 device specified by ControllerHandle may already be managed by the same driver or a
472 different driver. This function must match its calls to AllocatePages() with FreePages(),
473 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
474 Since ControllerHandle may have been previously started by the same driver, if a protocol is
475 already in the opened state, then it must not be closed with CloseProtocol(). This is required
476 to guarantee the state of ControllerHandle is not modified by this function.
478 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
479 @param[in] ControllerHandle The handle of the controller to test. This handle
480 must support a protocol interface that supplies
481 an I/O abstraction to the driver.
482 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
483 parameter is ignored by device drivers, and is optional for bus
484 drivers. For bus drivers, if this parameter is not NULL, then
485 the bus driver must determine if the bus controller specified
486 by ControllerHandle and the child controller specified
487 by RemainingDevicePath are both supported by this
490 @retval EFI_SUCCESS The device specified by ControllerHandle and
491 RemainingDevicePath is supported by the driver specified by This.
492 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
493 RemainingDevicePath is already being managed by the driver
495 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
496 RemainingDevicePath is already being managed by a different
497 driver or an application that requires exclusive access.
498 Currently not implemented.
499 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
500 RemainingDevicePath is not supported by the driver specified by This.
504 AtaBusDriverBindingSupported (
505 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
506 IN EFI_HANDLE Controller
,
507 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
511 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
512 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
514 UINT16 PortMultiplierPort
;
517 // Test EFI_ATA_PASS_THRU_PROTOCOL on controller handle.
519 Status
= gBS
->OpenProtocol (
521 &gEfiAtaPassThruProtocolGuid
,
522 (VOID
**) &AtaPassThru
,
523 This
->DriverBindingHandle
,
525 EFI_OPEN_PROTOCOL_BY_DRIVER
528 if (Status
== EFI_ALREADY_STARTED
) {
532 if (EFI_ERROR (Status
)) {
537 // Test RemainingDevicePath is valid or not.
539 if ((RemainingDevicePath
!= NULL
) && !IsDevicePathEnd (RemainingDevicePath
)) {
540 Status
= AtaPassThru
->GetDevice (AtaPassThru
, RemainingDevicePath
, &Port
, &PortMultiplierPort
);
541 if (EFI_ERROR (Status
)) {
547 // Close the I/O Abstraction(s) used to perform the supported test
551 &gEfiAtaPassThruProtocolGuid
,
552 This
->DriverBindingHandle
,
557 // Open the EFI Device Path protocol needed to perform the supported test
559 Status
= gBS
->OpenProtocol (
561 &gEfiDevicePathProtocolGuid
,
562 (VOID
**) &ParentDevicePath
,
563 This
->DriverBindingHandle
,
565 EFI_OPEN_PROTOCOL_GET_PROTOCOL
572 Starts a device controller or a bus controller.
574 The Start() function is designed to be invoked from the EFI boot service ConnectController().
575 As a result, much of the error checking on the parameters to Start() has been moved into this
576 common boot service. It is legal to call Start() from other locations,
577 but the following calling restrictions must be followed or the system behavior will not be deterministic.
578 1. ControllerHandle must be a valid EFI_HANDLE.
579 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
580 EFI_DEVICE_PATH_PROTOCOL.
581 3. Prior to calling Start(), the Supported() function for the driver specified by This must
582 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
584 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
585 @param[in] ControllerHandle The handle of the controller to start. This handle
586 must support a protocol interface that supplies
587 an I/O abstraction to the driver.
588 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
589 parameter is ignored by device drivers, and is optional for bus
590 drivers. For a bus driver, if this parameter is NULL, then handles
591 for all the children of Controller are created by this driver.
592 If this parameter is not NULL and the first Device Path Node is
593 not the End of Device Path Node, then only the handle for the
594 child device specified by the first Device Path Node of
595 RemainingDevicePath is created by this driver.
596 If the first Device Path Node of RemainingDevicePath is
597 the End of Device Path Node, no child handle is created by this
600 @retval EFI_SUCCESS The device was started.
601 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
602 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
603 @retval Others The driver failded to start the device.
608 AtaBusDriverBindingStart (
609 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
610 IN EFI_HANDLE Controller
,
611 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
615 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
616 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
617 ATA_BUS_DRIVER_DATA
*AtaBusDriverData
;
619 UINT16 PortMultiplierPort
;
621 AtaBusDriverData
= NULL
;
623 Status
= gBS
->OpenProtocol (
625 &gEfiDevicePathProtocolGuid
,
626 (VOID
**) &ParentDevicePath
,
627 This
->DriverBindingHandle
,
629 EFI_OPEN_PROTOCOL_GET_PROTOCOL
631 if (EFI_ERROR (Status
)) {
635 Status
= gBS
->OpenProtocol (
637 &gEfiAtaPassThruProtocolGuid
,
638 (VOID
**) &AtaPassThru
,
639 This
->DriverBindingHandle
,
641 EFI_OPEN_PROTOCOL_BY_DRIVER
643 if ((EFI_ERROR (Status
)) && (Status
!= EFI_ALREADY_STARTED
)) {
648 // Check EFI_ALREADY_STARTED to reuse the original ATA_BUS_DRIVER_DATA.
650 if (Status
!= EFI_ALREADY_STARTED
) {
651 AtaBusDriverData
= AllocateZeroPool (sizeof (ATA_BUS_DRIVER_DATA
));
652 if (AtaBusDriverData
== NULL
) {
653 Status
= EFI_OUT_OF_RESOURCES
;
657 AtaBusDriverData
->AtaPassThru
= AtaPassThru
;
658 AtaBusDriverData
->Controller
= Controller
;
659 AtaBusDriverData
->ParentDevicePath
= ParentDevicePath
;
660 AtaBusDriverData
->DriverBindingHandle
= This
->DriverBindingHandle
;
662 Status
= gBS
->InstallMultipleProtocolInterfaces (
668 if (EFI_ERROR (Status
)) {
673 Status
= gBS
->OpenProtocol (
676 (VOID
**) &AtaBusDriverData
,
677 This
->DriverBindingHandle
,
679 EFI_OPEN_PROTOCOL_GET_PROTOCOL
681 if (EFI_ERROR (Status
)) {
682 AtaBusDriverData
= NULL
;
687 if (RemainingDevicePath
== NULL
) {
690 Status
= AtaPassThru
->GetNextPort (AtaPassThru
, &Port
);
691 if (EFI_ERROR (Status
)) {
693 // We cannot find more legal port then we are done.
698 PortMultiplierPort
= 0xFFFF;
700 Status
= AtaPassThru
->GetNextDevice (AtaPassThru
, Port
, &PortMultiplierPort
);
701 if (EFI_ERROR (Status
)) {
703 // We cannot find more legal port multiplier port number for ATA device
704 // on the port, then we are done.
708 RegisterAtaDevice (AtaBusDriverData
, Port
, PortMultiplierPort
);
711 Status
= EFI_SUCCESS
;
712 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
713 Status
= AtaPassThru
->GetDevice (AtaPassThru
, RemainingDevicePath
, &Port
, &PortMultiplierPort
);
714 if (!EFI_ERROR (Status
)) {
715 Status
= RegisterAtaDevice (AtaBusDriverData
,Port
, PortMultiplierPort
);
723 if (AtaBusDriverData
!= NULL
) {
724 gBS
->UninstallMultipleProtocolInterfaces (
730 FreePool (AtaBusDriverData
);
735 &gEfiAtaPassThruProtocolGuid
,
736 This
->DriverBindingHandle
,
746 Stops a device controller or a bus controller.
748 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
749 As a result, much of the error checking on the parameters to Stop() has been moved
750 into this common boot service. It is legal to call Stop() from other locations,
751 but the following calling restrictions must be followed or the system behavior will not be deterministic.
752 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
753 same driver's Start() function.
754 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
755 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
756 Start() function, and the Start() function must have called OpenProtocol() on
757 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
759 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
760 @param[in] ControllerHandle A handle to the device being stopped. The handle must
761 support a bus specific I/O protocol for the driver
762 to use to stop the device.
763 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
764 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
765 if NumberOfChildren is 0.
767 @retval EFI_SUCCESS The device was stopped.
768 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
773 AtaBusDriverBindingStop (
774 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
775 IN EFI_HANDLE Controller
,
776 IN UINTN NumberOfChildren
,
777 IN EFI_HANDLE
*ChildHandleBuffer
781 BOOLEAN AllChildrenStopped
;
783 ATA_BUS_DRIVER_DATA
*AtaBusDriverData
;
785 if (NumberOfChildren
== 0) {
786 Status
= gBS
->OpenProtocol (
789 (VOID
**) &AtaBusDriverData
,
790 This
->DriverBindingHandle
,
792 EFI_OPEN_PROTOCOL_GET_PROTOCOL
794 if (!EFI_ERROR (Status
)) {
795 gBS
->UninstallMultipleProtocolInterfaces (
801 FreePool (AtaBusDriverData
);
806 &gEfiAtaPassThruProtocolGuid
,
807 This
->DriverBindingHandle
,
814 AllChildrenStopped
= TRUE
;
816 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
818 Status
= UnregisterAtaDevice (This
, Controller
, ChildHandleBuffer
[Index
]);
819 if (EFI_ERROR (Status
)) {
820 AllChildrenStopped
= FALSE
;
824 if (!AllChildrenStopped
) {
825 return EFI_DEVICE_ERROR
;
833 Reset the Block Device.
835 @param This Indicates a pointer to the calling context.
836 @param ExtendedVerification Driver may perform diagnostics on reset.
838 @retval EFI_SUCCESS The device was reset.
839 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
846 IN EFI_BLOCK_IO_PROTOCOL
*This
,
847 IN BOOLEAN ExtendedVerification
851 ATA_DEVICE
*AtaDevice
;
854 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
856 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO (This
);
858 Status
= ResetAtaDevice (AtaDevice
);
860 if (EFI_ERROR (Status
)) {
861 Status
= EFI_DEVICE_ERROR
;
864 gBS
->RestoreTPL (OldTpl
);
870 Read/Write BufferSize bytes from Lba from/into Buffer.
872 @param[in] This Indicates a pointer to the calling context. Either be
873 block I/O or block I/O2.
874 @param[in] MediaId The media ID that the read/write request is for.
875 @param[in] Lba The starting logical block address to be read/written.
876 The caller is responsible for reading/writing to only
877 legitimate locations.
878 @param[in, out] Token A pointer to the token associated with the transaction.
879 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
880 @param[out] Buffer A pointer to the destination/source buffer for the data.
881 @param[in] IsBlockIo2 Indicate the calling is from BlockIO or BlockIO2. TURE is
882 from BlockIO2, FALSE is for BlockIO.
883 @param[in] IsWrite Indicates whether it is a write operation.
885 @retval EFI_SUCCESS The data was read/written correctly to the device.
886 @retval EFI_WRITE_PROTECTED The device can not be read/written to.
887 @retval EFI_DEVICE_ERROR The device reported an error while performing the read/write.
888 @retval EFI_NO_MEDIA There is no media in the device.
889 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
890 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
891 @retval EFI_INVALID_PARAMETER The read/write request contains LBAs that are not valid,
892 or the buffer is not on proper alignment.
900 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
,
903 IN BOOLEAN IsBlockIo2
,
907 ATA_DEVICE
*AtaDevice
;
910 EFI_BLOCK_IO_MEDIA
*Media
;
912 UINTN NumberOfBlocks
;
916 Media
= ((EFI_BLOCK_IO2_PROTOCOL
*) This
)->Media
;
917 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO2 (This
);
919 Media
= ((EFI_BLOCK_IO_PROTOCOL
*) This
)->Media
;
920 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO (This
);
923 if (MediaId
!= Media
->MediaId
) {
924 return EFI_MEDIA_CHANGED
;
930 if (Buffer
== NULL
) {
931 return EFI_INVALID_PARAMETER
;
934 if (BufferSize
== 0) {
938 BlockSize
= Media
->BlockSize
;
939 if ((BufferSize
% BlockSize
) != 0) {
940 return EFI_BAD_BUFFER_SIZE
;
943 NumberOfBlocks
= BufferSize
/ BlockSize
;
944 if ((Lba
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
945 return EFI_INVALID_PARAMETER
;
948 IoAlign
= Media
->IoAlign
;
949 if (IoAlign
> 0 && (((UINTN
) Buffer
& (IoAlign
- 1)) != 0)) {
950 return EFI_INVALID_PARAMETER
;
953 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
956 // Invoke low level AtaDevice Access Routine.
958 Status
= AccessAtaDevice (AtaDevice
, Buffer
, Lba
, NumberOfBlocks
, IsWrite
, Token
);
960 gBS
->RestoreTPL (OldTpl
);
967 Read BufferSize bytes from Lba into Buffer.
969 @param This Indicates a pointer to the calling context.
970 @param MediaId Id of the media, changes every time the media is replaced.
971 @param Lba The starting Logical Block Address to read from
972 @param BufferSize Size of Buffer, must be a multiple of device block size.
973 @param Buffer A pointer to the destination buffer for the data. The caller is
974 responsible for either having implicit or explicit ownership of the buffer.
976 @retval EFI_SUCCESS The data was read correctly from the device.
977 @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
978 @retval EFI_NO_MEDIA There is no media in the device.
979 @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
980 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
981 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
982 or the buffer is not on proper alignment.
987 AtaBlockIoReadBlocks (
988 IN EFI_BLOCK_IO_PROTOCOL
*This
,
995 return BlockIoReadWrite ((VOID
*) This
, MediaId
, Lba
, NULL
, BufferSize
, Buffer
, FALSE
, FALSE
);
1000 Write BufferSize bytes from Lba into Buffer.
1002 @param This Indicates a pointer to the calling context.
1003 @param MediaId The media ID that the write request is for.
1004 @param Lba The starting logical block address to be written. The caller is
1005 responsible for writing to only legitimate locations.
1006 @param BufferSize Size of Buffer, must be a multiple of device block size.
1007 @param Buffer A pointer to the source buffer for the data.
1009 @retval EFI_SUCCESS The data was written correctly to the device.
1010 @retval EFI_WRITE_PROTECTED The device can not be written to.
1011 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
1012 @retval EFI_NO_MEDIA There is no media in the device.
1013 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
1014 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
1015 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
1016 or the buffer is not on proper alignment.
1021 AtaBlockIoWriteBlocks (
1022 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1025 IN UINTN BufferSize
,
1029 return BlockIoReadWrite ((VOID
*) This
, MediaId
, Lba
, NULL
, BufferSize
, Buffer
, FALSE
, TRUE
);
1034 Flush the Block Device.
1036 @param This Indicates a pointer to the calling context.
1038 @retval EFI_SUCCESS All outstanding data was written to the device
1039 @retval EFI_DEVICE_ERROR The device reported an error while writing back the data
1040 @retval EFI_NO_MEDIA There is no media in the device.
1045 AtaBlockIoFlushBlocks (
1046 IN EFI_BLOCK_IO_PROTOCOL
*This
1056 Reset the Block Device.
1058 @param[in] This Indicates a pointer to the calling context.
1059 @param[in] ExtendedVerification Driver may perform diagnostics on reset.
1061 @retval EFI_SUCCESS The device was reset.
1062 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
1069 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
1070 IN BOOLEAN ExtendedVerification
1074 ATA_DEVICE
*AtaDevice
;
1077 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1079 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO2 (This
);
1081 Status
= ResetAtaDevice (AtaDevice
);
1083 if (EFI_ERROR (Status
)) {
1084 Status
= EFI_DEVICE_ERROR
;
1087 gBS
->RestoreTPL (OldTpl
);
1092 Read BufferSize bytes from Lba into Buffer.
1094 @param[in] This Indicates a pointer to the calling context.
1095 @param[in] MediaId Id of the media, changes every time the media is replaced.
1096 @param[in] Lba The starting Logical Block Address to read from.
1097 @param[in, out] Token A pointer to the token associated with the transaction.
1098 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
1099 @param[out] Buffer A pointer to the destination buffer for the data. The caller is
1100 responsible for either having implicit or explicit ownership of the buffer.
1102 @retval EFI_SUCCESS The read request was queued if Event is not NULL.
1103 The data was read correctly from the device if
1105 @retval EFI_DEVICE_ERROR The device reported an error while performing
1107 @retval EFI_NO_MEDIA There is no media in the device.
1108 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
1109 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
1110 intrinsic block size of the device.
1111 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
1112 or the buffer is not on proper alignment.
1113 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
1119 AtaBlockIoReadBlocksEx (
1120 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
1123 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
,
1124 IN UINTN BufferSize
,
1128 return BlockIoReadWrite ((VOID
*) This
, MediaId
, Lba
, Token
, BufferSize
, Buffer
, TRUE
, FALSE
);
1133 Write BufferSize bytes from Lba into Buffer.
1135 @param[in] This Indicates a pointer to the calling context.
1136 @param[in] MediaId The media ID that the write request is for.
1137 @param[in] Lba The starting logical block address to be written. The
1138 caller is responsible for writing to only legitimate
1140 @param[in, out] Token A pointer to the token associated with the transaction.
1141 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
1142 @param[in] Buffer A pointer to the source buffer for the data.
1144 @retval EFI_SUCCESS The data was written correctly to the device.
1145 @retval EFI_WRITE_PROTECTED The device can not be written to.
1146 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
1147 @retval EFI_NO_MEDIA There is no media in the device.
1148 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
1149 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
1150 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
1151 or the buffer is not on proper alignment.
1156 AtaBlockIoWriteBlocksEx (
1157 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
1160 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
,
1161 IN UINTN BufferSize
,
1165 return BlockIoReadWrite ((VOID
*) This
, MediaId
, Lba
, Token
, BufferSize
, Buffer
, TRUE
, TRUE
);
1170 Flush the Block Device.
1172 @param[in] This Indicates a pointer to the calling context.
1173 @param[in, out] Token A pointer to the token associated with the transaction.
1175 @retval EFI_SUCCESS All outstanding data was written to the device
1176 @retval EFI_DEVICE_ERROR The device reported an error while writing back the data
1177 @retval EFI_NO_MEDIA There is no media in the device.
1182 AtaBlockIoFlushBlocksEx (
1183 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
1184 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
1188 // Signla event and return directly.
1190 if (Token
!= NULL
&& Token
->Event
!= NULL
) {
1191 Token
->TransactionStatus
= EFI_SUCCESS
;
1192 gBS
->SignalEvent (Token
->Event
);
1197 Provides inquiry information for the controller type.
1199 This function is used by the IDE bus driver to get inquiry data. Data format
1200 of Identify data is defined by the Interface GUID.
1202 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1203 @param[in, out] InquiryData Pointer to a buffer for the inquiry data.
1204 @param[in, out] InquiryDataSize Pointer to the value for the inquiry data size.
1206 @retval EFI_SUCCESS The command was accepted without any errors.
1207 @retval EFI_NOT_FOUND Device does not support this data class
1208 @retval EFI_DEVICE_ERROR Error reading InquiryData from device
1209 @retval EFI_BUFFER_TOO_SMALL InquiryDataSize not big enough
1214 AtaDiskInfoInquiry (
1215 IN EFI_DISK_INFO_PROTOCOL
*This
,
1216 IN OUT VOID
*InquiryData
,
1217 IN OUT UINT32
*InquiryDataSize
1220 return EFI_NOT_FOUND
;
1225 Provides identify information for the controller type.
1227 This function is used by the IDE bus driver to get identify data. Data format
1228 of Identify data is defined by the Interface GUID.
1230 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL
1232 @param[in, out] IdentifyData Pointer to a buffer for the identify data.
1233 @param[in, out] IdentifyDataSize Pointer to the value for the identify data
1236 @retval EFI_SUCCESS The command was accepted without any errors.
1237 @retval EFI_NOT_FOUND Device does not support this data class
1238 @retval EFI_DEVICE_ERROR Error reading IdentifyData from device
1239 @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough
1244 AtaDiskInfoIdentify (
1245 IN EFI_DISK_INFO_PROTOCOL
*This
,
1246 IN OUT VOID
*IdentifyData
,
1247 IN OUT UINT32
*IdentifyDataSize
1251 ATA_DEVICE
*AtaDevice
;
1253 AtaDevice
= ATA_DEVICE_FROM_DISK_INFO (This
);
1255 Status
= EFI_BUFFER_TOO_SMALL
;
1256 if (*IdentifyDataSize
>= sizeof (*AtaDevice
->IdentifyData
)) {
1257 Status
= EFI_SUCCESS
;
1258 CopyMem (IdentifyData
, AtaDevice
->IdentifyData
, sizeof (*AtaDevice
->IdentifyData
));
1260 *IdentifyDataSize
= sizeof (*AtaDevice
->IdentifyData
);
1267 Provides sense data information for the controller type.
1269 This function is used by the IDE bus driver to get sense data.
1270 Data format of Sense data is defined by the Interface GUID.
1272 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1273 @param[in, out] SenseData Pointer to the SenseData.
1274 @param[in, out] SenseDataSize Size of SenseData in bytes.
1275 @param[out] SenseDataNumber Pointer to the value for the sense data size.
1277 @retval EFI_SUCCESS The command was accepted without any errors.
1278 @retval EFI_NOT_FOUND Device does not support this data class.
1279 @retval EFI_DEVICE_ERROR Error reading SenseData from device.
1280 @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough.
1285 AtaDiskInfoSenseData (
1286 IN EFI_DISK_INFO_PROTOCOL
*This
,
1287 IN OUT VOID
*SenseData
,
1288 IN OUT UINT32
*SenseDataSize
,
1289 OUT UINT8
*SenseDataNumber
1292 return EFI_NOT_FOUND
;
1297 This function is used by the IDE bus driver to get controller information.
1299 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1300 @param[out] IdeChannel Pointer to the Ide Channel number. Primary or secondary.
1301 @param[out] IdeDevice Pointer to the Ide Device number. Master or slave.
1303 @retval EFI_SUCCESS IdeChannel and IdeDevice are valid.
1304 @retval EFI_UNSUPPORTED This is not an IDE device.
1309 AtaDiskInfoWhichIde (
1310 IN EFI_DISK_INFO_PROTOCOL
*This
,
1311 OUT UINT32
*IdeChannel
,
1312 OUT UINT32
*IdeDevice
1315 ATA_DEVICE
*AtaDevice
;
1317 AtaDevice
= ATA_DEVICE_FROM_DISK_INFO (This
);
1318 *IdeChannel
= AtaDevice
->Port
;
1319 *IdeDevice
= AtaDevice
->PortMultiplierPort
;
1326 The user Entry Point for module AtaBus. The user code starts with this function.
1328 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1329 @param[in] SystemTable A pointer to the EFI System Table.
1331 @retval EFI_SUCCESS The entry point is executed successfully.
1332 @retval other Some error occurs when executing this entry point.
1338 IN EFI_HANDLE ImageHandle
,
1339 IN EFI_SYSTEM_TABLE
*SystemTable
1345 // Install driver model protocol(s).
1347 Status
= EfiLibInstallDriverBindingComponentName2 (
1350 &gAtaBusDriverBinding
,
1352 &gAtaBusComponentName
,
1353 &gAtaBusComponentName2
1355 ASSERT_EFI_ERROR (Status
);