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 - 2012, 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.
25 // ATA Bus Driver Binding Protocol Instance
27 EFI_DRIVER_BINDING_PROTOCOL gAtaBusDriverBinding
= {
28 AtaBusDriverBindingSupported
,
29 AtaBusDriverBindingStart
,
30 AtaBusDriverBindingStop
,
37 // Template for ATA Child Device.
39 ATA_DEVICE gAtaDeviceTemplate
= {
40 ATA_DEVICE_SIGNATURE
, // Signature
43 EFI_BLOCK_IO_PROTOCOL_REVISION
,
47 AtaBlockIoWriteBlocks
,
53 AtaBlockIoReadBlocksEx
,
54 AtaBlockIoWriteBlocksEx
,
55 AtaBlockIoFlushBlocksEx
59 FALSE
, // RemovableMedia
61 FALSE
, // LogicPartition
63 FALSE
, // WritingCache
67 0, // LowestAlignedLba
68 1 // LogicalBlocksPerPhysicalBlock
71 EFI_DISK_INFO_IDE_INTERFACE_GUID
,
79 AtaStorageSecurityReceiveData
,
80 AtaStorageSecuritySendData
82 NULL
, // AtaBusDriverData
84 0, // PortMultiplierPort
91 NULL
, // ControllerNameTable
92 {L
'\0', }, // ModelName
93 {NULL
, NULL
}, // AtaTaskList
94 {NULL
, NULL
} // AtaSubTaskList
98 Allocates an aligned buffer for ATA device.
100 This function allocates an aligned buffer for the ATA device to perform
101 ATA pass through operations. The alignment requirement is from ATA pass
104 @param AtaDevice The ATA child device involved for the operation.
105 @param BufferSize The request buffer size.
107 @return A pointer to the aligned buffer or NULL if the allocation fails.
111 AllocateAlignedBuffer (
112 IN ATA_DEVICE
*AtaDevice
,
116 return AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize
), AtaDevice
->AtaBusDriverData
->AtaPassThru
->Mode
->IoAlign
);
120 Frees an aligned buffer for ATA device.
122 This function frees an aligned buffer for the ATA device to perform
123 ATA pass through operations.
125 @param Buffer The aligned buffer to be freed.
126 @param BufferSize The request buffer size.
135 if (Buffer
!= NULL
) {
136 FreeAlignedPages (Buffer
, EFI_SIZE_TO_PAGES (BufferSize
));
142 Release all the resources allocated for the ATA device.
144 This function releases all the resources allocated for the ATA device.
146 @param AtaDevice The ATA child device involved for the operation.
150 ReleaseAtaResources (
151 IN ATA_DEVICE
*AtaDevice
154 ATA_BUS_ASYN_SUB_TASK
*SubTask
;
155 ATA_BUS_ASYN_TASK
*AtaTask
;
157 LIST_ENTRY
*DelEntry
;
160 FreeUnicodeStringTable (AtaDevice
->ControllerNameTable
);
161 FreeAlignedBuffer (AtaDevice
->Asb
, sizeof (EFI_ATA_STATUS_BLOCK
));
162 FreeAlignedBuffer (AtaDevice
->IdentifyData
, sizeof (ATA_IDENTIFY_DATA
));
163 if (AtaDevice
->DevicePath
!= NULL
) {
164 FreePool (AtaDevice
->DevicePath
);
166 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
167 if (!IsListEmpty (&AtaDevice
->AtaSubTaskList
)) {
169 // Free the Subtask list.
171 for(Entry
= AtaDevice
->AtaSubTaskList
.ForwardLink
;
172 Entry
!= (&AtaDevice
->AtaSubTaskList
);
175 Entry
= Entry
->ForwardLink
;
176 SubTask
= ATA_AYNS_SUB_TASK_FROM_ENTRY (DelEntry
);
178 RemoveEntryList (DelEntry
);
179 FreeAtaSubTask (SubTask
);
182 if (!IsListEmpty (&AtaDevice
->AtaTaskList
)) {
184 // Free the Subtask list.
186 for(Entry
= AtaDevice
->AtaTaskList
.ForwardLink
;
187 Entry
!= (&AtaDevice
->AtaTaskList
);
190 Entry
= Entry
->ForwardLink
;
191 AtaTask
= ATA_AYNS_TASK_FROM_ENTRY (DelEntry
);
193 RemoveEntryList (DelEntry
);
197 gBS
->RestoreTPL (OldTpl
);
198 FreePool (AtaDevice
);
203 Registers an ATA device.
205 This function allocates an ATA device structure for the ATA device specified by
206 Port and PortMultiplierPort if the ATA device is identified as a valid one.
207 Then it will create child handle and install Block IO and Disk Info protocol on
210 @param AtaBusDriverData The parent ATA bus driver data structure.
211 @param Port The port number of the ATA device.
212 @param PortMultiplierPort The port multiplier port number of the ATA device.
214 @retval EFI_SUCCESS The ATA device is successfully registered.
215 @retval EFI_OUT_OF_RESOURCES There is not enough memory to allocate the ATA device
216 and related data structures.
217 @return Others Some error occurs when registering the ATA device.
221 IN OUT ATA_BUS_DRIVER_DATA
*AtaBusDriverData
,
223 IN UINT16 PortMultiplierPort
227 ATA_DEVICE
*AtaDevice
;
228 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
229 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePathNode
;
230 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
231 EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
;
232 EFI_HANDLE DeviceHandle
;
235 NewDevicePathNode
= NULL
;
237 RemainingDevicePath
= NULL
;
242 AtaPassThru
= AtaBusDriverData
->AtaPassThru
;
243 Status
= AtaPassThru
->BuildDevicePath (AtaPassThru
, Port
, PortMultiplierPort
, &NewDevicePathNode
);
244 if (EFI_ERROR (Status
)) {
248 DevicePath
= AppendDevicePathNode (AtaBusDriverData
->ParentDevicePath
, NewDevicePathNode
);
249 if (DevicePath
== NULL
) {
250 Status
= EFI_OUT_OF_RESOURCES
;
255 RemainingDevicePath
= DevicePath
;
256 Status
= gBS
->LocateDevicePath (&gEfiDevicePathProtocolGuid
, &RemainingDevicePath
, &DeviceHandle
);
257 if (!EFI_ERROR (Status
) && (DeviceHandle
!= NULL
) && IsDevicePathEnd(RemainingDevicePath
)) {
258 Status
= EFI_ALREADY_STARTED
;
259 FreePool (DevicePath
);
264 // Allocate ATA device from the template.
266 AtaDevice
= AllocateCopyPool (sizeof (ATA_DEVICE
), &gAtaDeviceTemplate
);
267 if (AtaDevice
== NULL
) {
268 Status
= EFI_OUT_OF_RESOURCES
;
273 // Initializes ATA device structures and allocates the required buffer.
275 AtaDevice
->BlockIo
.Media
= &AtaDevice
->BlockMedia
;
276 AtaDevice
->BlockIo2
.Media
= &AtaDevice
->BlockMedia
;
277 AtaDevice
->AtaBusDriverData
= AtaBusDriverData
;
278 AtaDevice
->DevicePath
= DevicePath
;
279 AtaDevice
->Port
= Port
;
280 AtaDevice
->PortMultiplierPort
= PortMultiplierPort
;
281 AtaDevice
->Asb
= AllocateAlignedBuffer (AtaDevice
, sizeof (EFI_ATA_STATUS_BLOCK
));
282 if (AtaDevice
->Asb
== NULL
) {
283 Status
= EFI_OUT_OF_RESOURCES
;
286 AtaDevice
->IdentifyData
= AllocateAlignedBuffer (AtaDevice
, sizeof (ATA_IDENTIFY_DATA
));
287 if (AtaDevice
->IdentifyData
== NULL
) {
288 Status
= EFI_OUT_OF_RESOURCES
;
293 // Initial Ata Task List
295 InitializeListHead (&AtaDevice
->AtaTaskList
);
296 InitializeListHead (&AtaDevice
->AtaSubTaskList
);
299 // Try to identify the ATA device via the ATA pass through command.
301 Status
= DiscoverAtaDevice (AtaDevice
);
302 if (EFI_ERROR (Status
)) {
307 // Build controller name for Component Name (2) protocol.
309 Status
= AddUnicodeString2 (
311 gAtaBusComponentName
.SupportedLanguages
,
312 &AtaDevice
->ControllerNameTable
,
313 AtaDevice
->ModelName
,
316 if (EFI_ERROR (Status
)) {
320 Status
= AddUnicodeString2 (
322 gAtaBusComponentName2
.SupportedLanguages
,
323 &AtaDevice
->ControllerNameTable
,
324 AtaDevice
->ModelName
,
327 if (EFI_ERROR (Status
)) {
332 // Update to AHCI interface GUID based on device path node. The default one
333 // is IDE interface GUID copied from template.
335 if (NewDevicePathNode
->SubType
== MSG_SATA_DP
) {
336 CopyGuid (&AtaDevice
->DiskInfo
.Interface
, &gEfiDiskInfoAhciInterfaceGuid
);
339 Status
= gBS
->InstallMultipleProtocolInterfaces (
341 &gEfiDevicePathProtocolGuid
,
342 AtaDevice
->DevicePath
,
343 &gEfiBlockIoProtocolGuid
,
345 &gEfiBlockIo2ProtocolGuid
,
346 &AtaDevice
->BlockIo2
,
347 &gEfiDiskInfoProtocolGuid
,
348 &AtaDevice
->DiskInfo
,
351 if (EFI_ERROR (Status
)) {
356 // See if the ata device support trust computing feature or not.
357 // If yes, then install Storage Security Protocol at the ata device handle.
359 if ((AtaDevice
->IdentifyData
->trusted_computing_support
& BIT0
) != 0) {
360 DEBUG ((EFI_D_INFO
, "Found TCG support in Port %x PortMultiplierPort %x\n", Port
, PortMultiplierPort
));
361 Status
= gBS
->InstallProtocolInterface (
363 &gEfiStorageSecurityCommandProtocolGuid
,
364 EFI_NATIVE_INTERFACE
,
365 &AtaDevice
->StorageSecurity
367 if (EFI_ERROR (Status
)) {
370 DEBUG ((EFI_D_INFO
, "Successfully Install Storage Security Protocol on the ATA device\n"));
374 if (((mMorControl
& 0x01) == 0x01) && ((AtaDevice
->IdentifyData
->trusted_computing_support
& BIT0
) != 0)) {
376 "mMorControl = %x, AtaDevice->IdentifyData->trusted_computing_support & BIT0 = %x\n",
378 (AtaDevice
->IdentifyData
->trusted_computing_support
& BIT0
)
380 DEBUG ((EFI_D_INFO
, "Try to lock device by sending TPer Reset command...\n"));
381 InitiateTPerReset(AtaDevice
);
386 AtaBusDriverData
->Controller
,
387 &gEfiAtaPassThruProtocolGuid
,
388 (VOID
**) &AtaPassThru
,
389 AtaBusDriverData
->DriverBindingHandle
,
391 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
395 if (NewDevicePathNode
!= NULL
) {
396 FreePool (NewDevicePathNode
);
399 if (EFI_ERROR (Status
) && (AtaDevice
!= NULL
)) {
400 ReleaseAtaResources (AtaDevice
);
401 DEBUG ((EFI_D_ERROR
| EFI_D_INIT
, "Failed to initialize Port %x PortMultiplierPort %x, status = %r\n", Port
, PortMultiplierPort
, Status
));
408 Unregisters an ATA device.
410 This function removes the protocols installed on the controller handle and
411 frees the resources allocated for the ATA device.
413 @param This The pointer to EFI_DRIVER_BINDING_PROTOCOL instance.
414 @param Controller The controller handle of the ATA device.
415 @param Handle The child handle.
417 @retval EFI_SUCCESS The ATA device is successfully unregistered.
418 @return Others Some error occurs when unregistering the ATA device.
422 UnregisterAtaDevice (
423 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
424 IN EFI_HANDLE Controller
,
429 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
430 EFI_BLOCK_IO2_PROTOCOL
*BlockIo2
;
431 ATA_DEVICE
*AtaDevice
;
432 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
433 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
*StorageSecurity
;
438 Status
= gBS
->OpenProtocol (
440 &gEfiBlockIoProtocolGuid
,
442 This
->DriverBindingHandle
,
444 EFI_OPEN_PROTOCOL_GET_PROTOCOL
446 if (EFI_ERROR (Status
)) {
448 // Locate BlockIo2 protocol
450 Status
= gBS
->OpenProtocol (
452 &gEfiBlockIo2ProtocolGuid
,
454 This
->DriverBindingHandle
,
456 EFI_OPEN_PROTOCOL_GET_PROTOCOL
458 if (EFI_ERROR (Status
)) {
464 // Get AtaDevice data.
466 if (BlockIo
!= NULL
) {
467 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO (BlockIo
);
469 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO2 (BlockIo2
);
473 // Close the child handle
477 &gEfiAtaPassThruProtocolGuid
,
478 This
->DriverBindingHandle
,
483 // The Ata Bus driver installs the BlockIo and BlockIo2 in the DriverBindingStart().
484 // Here should uninstall both of them.
486 Status
= gBS
->UninstallMultipleProtocolInterfaces (
488 &gEfiDevicePathProtocolGuid
,
489 AtaDevice
->DevicePath
,
490 &gEfiBlockIoProtocolGuid
,
492 &gEfiBlockIo2ProtocolGuid
,
493 &AtaDevice
->BlockIo2
,
494 &gEfiDiskInfoProtocolGuid
,
495 &AtaDevice
->DiskInfo
,
499 if (EFI_ERROR (Status
)) {
502 &gEfiAtaPassThruProtocolGuid
,
503 (VOID
**) &AtaPassThru
,
504 This
->DriverBindingHandle
,
506 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
512 // If Storage Security Command Protocol is installed, then uninstall this protocol.
514 Status
= gBS
->OpenProtocol (
516 &gEfiStorageSecurityCommandProtocolGuid
,
517 (VOID
**) &StorageSecurity
,
518 This
->DriverBindingHandle
,
520 EFI_OPEN_PROTOCOL_GET_PROTOCOL
523 if (!EFI_ERROR (Status
)) {
524 Status
= gBS
->UninstallProtocolInterface (
526 &gEfiStorageSecurityCommandProtocolGuid
,
527 &AtaDevice
->StorageSecurity
529 if (EFI_ERROR (Status
)) {
532 &gEfiAtaPassThruProtocolGuid
,
533 (VOID
**) &AtaPassThru
,
534 This
->DriverBindingHandle
,
536 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
542 ReleaseAtaResources (AtaDevice
);
549 Tests to see if this driver supports a given controller. If a child device is provided,
550 it further tests to see if this driver supports creating a handle for the specified child device.
552 This function checks to see if the driver specified by This supports the device specified by
553 ControllerHandle. Drivers will typically use the device path attached to
554 ControllerHandle and/or the services from the bus I/O abstraction attached to
555 ControllerHandle to determine if the driver supports ControllerHandle. This function
556 may be called many times during platform initialization. In order to reduce boot times, the tests
557 performed by this function must be very small, and take as little time as possible to execute. This
558 function must not change the state of any hardware devices, and this function must be aware that the
559 device specified by ControllerHandle may already be managed by the same driver or a
560 different driver. This function must match its calls to AllocatePages() with FreePages(),
561 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
562 Since ControllerHandle may have been previously started by the same driver, if a protocol is
563 already in the opened state, then it must not be closed with CloseProtocol(). This is required
564 to guarantee the state of ControllerHandle is not modified by this function.
566 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
567 @param[in] ControllerHandle The handle of the controller to test. This handle
568 must support a protocol interface that supplies
569 an I/O abstraction to the driver.
570 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
571 parameter is ignored by device drivers, and is optional for bus
572 drivers. For bus drivers, if this parameter is not NULL, then
573 the bus driver must determine if the bus controller specified
574 by ControllerHandle and the child controller specified
575 by RemainingDevicePath are both supported by this
578 @retval EFI_SUCCESS The device specified by ControllerHandle and
579 RemainingDevicePath is supported by the driver specified by This.
580 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
581 RemainingDevicePath is already being managed by the driver
583 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
584 RemainingDevicePath is already being managed by a different
585 driver or an application that requires exclusive access.
586 Currently not implemented.
587 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
588 RemainingDevicePath is not supported by the driver specified by This.
592 AtaBusDriverBindingSupported (
593 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
594 IN EFI_HANDLE Controller
,
595 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
599 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
600 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
602 UINT16 PortMultiplierPort
;
605 // Test EFI_ATA_PASS_THRU_PROTOCOL on controller handle.
607 Status
= gBS
->OpenProtocol (
609 &gEfiAtaPassThruProtocolGuid
,
610 (VOID
**) &AtaPassThru
,
611 This
->DriverBindingHandle
,
613 EFI_OPEN_PROTOCOL_BY_DRIVER
616 if (Status
== EFI_ALREADY_STARTED
) {
620 if (EFI_ERROR (Status
)) {
625 // Test RemainingDevicePath is valid or not.
627 if ((RemainingDevicePath
!= NULL
) && !IsDevicePathEnd (RemainingDevicePath
)) {
628 Status
= AtaPassThru
->GetDevice (AtaPassThru
, RemainingDevicePath
, &Port
, &PortMultiplierPort
);
629 if (EFI_ERROR (Status
)) {
635 // Close the I/O Abstraction(s) used to perform the supported test
639 &gEfiAtaPassThruProtocolGuid
,
640 This
->DriverBindingHandle
,
645 // Open the EFI Device Path protocol needed to perform the supported test
647 Status
= gBS
->OpenProtocol (
649 &gEfiDevicePathProtocolGuid
,
650 (VOID
**) &ParentDevicePath
,
651 This
->DriverBindingHandle
,
653 EFI_OPEN_PROTOCOL_GET_PROTOCOL
660 Starts a device controller or a bus controller.
662 The Start() function is designed to be invoked from the EFI boot service ConnectController().
663 As a result, much of the error checking on the parameters to Start() has been moved into this
664 common boot service. It is legal to call Start() from other locations,
665 but the following calling restrictions must be followed or the system behavior will not be deterministic.
666 1. ControllerHandle must be a valid EFI_HANDLE.
667 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
668 EFI_DEVICE_PATH_PROTOCOL.
669 3. Prior to calling Start(), the Supported() function for the driver specified by This must
670 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
672 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
673 @param[in] ControllerHandle The handle of the controller to start. This handle
674 must support a protocol interface that supplies
675 an I/O abstraction to the driver.
676 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
677 parameter is ignored by device drivers, and is optional for bus
678 drivers. For a bus driver, if this parameter is NULL, then handles
679 for all the children of Controller are created by this driver.
680 If this parameter is not NULL and the first Device Path Node is
681 not the End of Device Path Node, then only the handle for the
682 child device specified by the first Device Path Node of
683 RemainingDevicePath is created by this driver.
684 If the first Device Path Node of RemainingDevicePath is
685 the End of Device Path Node, no child handle is created by this
688 @retval EFI_SUCCESS The device was started.
689 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
690 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
691 @retval Others The driver failded to start the device.
696 AtaBusDriverBindingStart (
697 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
698 IN EFI_HANDLE Controller
,
699 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
703 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
704 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
705 ATA_BUS_DRIVER_DATA
*AtaBusDriverData
;
707 UINT16 PortMultiplierPort
;
709 AtaBusDriverData
= NULL
;
711 Status
= gBS
->OpenProtocol (
713 &gEfiDevicePathProtocolGuid
,
714 (VOID
**) &ParentDevicePath
,
715 This
->DriverBindingHandle
,
717 EFI_OPEN_PROTOCOL_GET_PROTOCOL
719 if (EFI_ERROR (Status
)) {
723 Status
= gBS
->OpenProtocol (
725 &gEfiAtaPassThruProtocolGuid
,
726 (VOID
**) &AtaPassThru
,
727 This
->DriverBindingHandle
,
729 EFI_OPEN_PROTOCOL_BY_DRIVER
731 if ((EFI_ERROR (Status
)) && (Status
!= EFI_ALREADY_STARTED
)) {
736 // Check EFI_ALREADY_STARTED to reuse the original ATA_BUS_DRIVER_DATA.
738 if (Status
!= EFI_ALREADY_STARTED
) {
739 AtaBusDriverData
= AllocateZeroPool (sizeof (ATA_BUS_DRIVER_DATA
));
740 if (AtaBusDriverData
== NULL
) {
741 Status
= EFI_OUT_OF_RESOURCES
;
745 AtaBusDriverData
->AtaPassThru
= AtaPassThru
;
746 AtaBusDriverData
->Controller
= Controller
;
747 AtaBusDriverData
->ParentDevicePath
= ParentDevicePath
;
748 AtaBusDriverData
->DriverBindingHandle
= This
->DriverBindingHandle
;
750 Status
= gBS
->InstallMultipleProtocolInterfaces (
756 if (EFI_ERROR (Status
)) {
761 Status
= gBS
->OpenProtocol (
764 (VOID
**) &AtaBusDriverData
,
765 This
->DriverBindingHandle
,
767 EFI_OPEN_PROTOCOL_GET_PROTOCOL
769 if (EFI_ERROR (Status
)) {
770 AtaBusDriverData
= NULL
;
775 if (RemainingDevicePath
== NULL
) {
778 Status
= AtaPassThru
->GetNextPort (AtaPassThru
, &Port
);
779 if (EFI_ERROR (Status
)) {
781 // We cannot find more legal port then we are done.
786 PortMultiplierPort
= 0xFFFF;
788 Status
= AtaPassThru
->GetNextDevice (AtaPassThru
, Port
, &PortMultiplierPort
);
789 if (EFI_ERROR (Status
)) {
791 // We cannot find more legal port multiplier port number for ATA device
792 // on the port, then we are done.
796 RegisterAtaDevice (AtaBusDriverData
, Port
, PortMultiplierPort
);
799 Status
= EFI_SUCCESS
;
800 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
801 Status
= AtaPassThru
->GetDevice (AtaPassThru
, RemainingDevicePath
, &Port
, &PortMultiplierPort
);
802 if (!EFI_ERROR (Status
)) {
803 Status
= RegisterAtaDevice (AtaBusDriverData
,Port
, PortMultiplierPort
);
811 if (AtaBusDriverData
!= NULL
) {
812 gBS
->UninstallMultipleProtocolInterfaces (
818 FreePool (AtaBusDriverData
);
823 &gEfiAtaPassThruProtocolGuid
,
824 This
->DriverBindingHandle
,
834 Stops a device controller or a bus controller.
836 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
837 As a result, much of the error checking on the parameters to Stop() has been moved
838 into this common boot service. It is legal to call Stop() from other locations,
839 but the following calling restrictions must be followed or the system behavior will not be deterministic.
840 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
841 same driver's Start() function.
842 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
843 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
844 Start() function, and the Start() function must have called OpenProtocol() on
845 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
847 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
848 @param[in] ControllerHandle A handle to the device being stopped. The handle must
849 support a bus specific I/O protocol for the driver
850 to use to stop the device.
851 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
852 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
853 if NumberOfChildren is 0.
855 @retval EFI_SUCCESS The device was stopped.
856 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
861 AtaBusDriverBindingStop (
862 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
863 IN EFI_HANDLE Controller
,
864 IN UINTN NumberOfChildren
,
865 IN EFI_HANDLE
*ChildHandleBuffer
869 BOOLEAN AllChildrenStopped
;
871 ATA_BUS_DRIVER_DATA
*AtaBusDriverData
;
873 if (NumberOfChildren
== 0) {
874 Status
= gBS
->OpenProtocol (
877 (VOID
**) &AtaBusDriverData
,
878 This
->DriverBindingHandle
,
880 EFI_OPEN_PROTOCOL_GET_PROTOCOL
882 if (!EFI_ERROR (Status
)) {
883 gBS
->UninstallMultipleProtocolInterfaces (
889 FreePool (AtaBusDriverData
);
894 &gEfiAtaPassThruProtocolGuid
,
895 This
->DriverBindingHandle
,
902 AllChildrenStopped
= TRUE
;
904 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
906 Status
= UnregisterAtaDevice (This
, Controller
, ChildHandleBuffer
[Index
]);
907 if (EFI_ERROR (Status
)) {
908 AllChildrenStopped
= FALSE
;
912 if (!AllChildrenStopped
) {
913 return EFI_DEVICE_ERROR
;
921 Reset the Block Device.
923 @param This Indicates a pointer to the calling context.
924 @param ExtendedVerification Driver may perform diagnostics on reset.
926 @retval EFI_SUCCESS The device was reset.
927 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
934 IN EFI_BLOCK_IO_PROTOCOL
*This
,
935 IN BOOLEAN ExtendedVerification
939 ATA_DEVICE
*AtaDevice
;
942 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
944 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO (This
);
946 Status
= ResetAtaDevice (AtaDevice
);
948 if (EFI_ERROR (Status
)) {
949 Status
= EFI_DEVICE_ERROR
;
952 gBS
->RestoreTPL (OldTpl
);
958 Read/Write BufferSize bytes from Lba from/into Buffer.
960 @param[in] This Indicates a pointer to the calling context. Either be
961 block I/O or block I/O2.
962 @param[in] MediaId The media ID that the read/write request is for.
963 @param[in] Lba The starting logical block address to be read/written.
964 The caller is responsible for reading/writing to only
965 legitimate locations.
966 @param[in, out] Token A pointer to the token associated with the transaction.
967 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
968 @param[out] Buffer A pointer to the destination/source buffer for the data.
969 @param[in] IsBlockIo2 Indicate the calling is from BlockIO or BlockIO2. TURE is
970 from BlockIO2, FALSE is for BlockIO.
971 @param[in] IsWrite Indicates whether it is a write operation.
973 @retval EFI_SUCCESS The data was read/written correctly to the device.
974 @retval EFI_WRITE_PROTECTED The device can not be read/written to.
975 @retval EFI_DEVICE_ERROR The device reported an error while performing the read/write.
976 @retval EFI_NO_MEDIA There is no media in the device.
977 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
978 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
979 @retval EFI_INVALID_PARAMETER The read/write request contains LBAs that are not valid,
980 or the buffer is not on proper alignment.
988 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
,
991 IN BOOLEAN IsBlockIo2
,
995 ATA_DEVICE
*AtaDevice
;
998 EFI_BLOCK_IO_MEDIA
*Media
;
1000 UINTN NumberOfBlocks
;
1004 Media
= ((EFI_BLOCK_IO2_PROTOCOL
*) This
)->Media
;
1005 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO2 (This
);
1007 Media
= ((EFI_BLOCK_IO_PROTOCOL
*) This
)->Media
;
1008 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO (This
);
1011 if (MediaId
!= Media
->MediaId
) {
1012 return EFI_MEDIA_CHANGED
;
1016 // Check parameters.
1018 if (Buffer
== NULL
) {
1019 return EFI_INVALID_PARAMETER
;
1022 if (BufferSize
== 0) {
1026 BlockSize
= Media
->BlockSize
;
1027 if ((BufferSize
% BlockSize
) != 0) {
1028 return EFI_BAD_BUFFER_SIZE
;
1031 NumberOfBlocks
= BufferSize
/ BlockSize
;
1032 if ((Lba
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1033 return EFI_INVALID_PARAMETER
;
1036 IoAlign
= Media
->IoAlign
;
1037 if (IoAlign
> 0 && (((UINTN
) Buffer
& (IoAlign
- 1)) != 0)) {
1038 return EFI_INVALID_PARAMETER
;
1041 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1044 // Invoke low level AtaDevice Access Routine.
1046 Status
= AccessAtaDevice (AtaDevice
, Buffer
, Lba
, NumberOfBlocks
, IsWrite
, Token
);
1048 gBS
->RestoreTPL (OldTpl
);
1055 Read BufferSize bytes from Lba into Buffer.
1057 @param This Indicates a pointer to the calling context.
1058 @param MediaId Id of the media, changes every time the media is replaced.
1059 @param Lba The starting Logical Block Address to read from
1060 @param BufferSize Size of Buffer, must be a multiple of device block size.
1061 @param Buffer A pointer to the destination buffer for the data. The caller is
1062 responsible for either having implicit or explicit ownership of the buffer.
1064 @retval EFI_SUCCESS The data was read correctly from the device.
1065 @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
1066 @retval EFI_NO_MEDIA There is no media in the device.
1067 @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
1068 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
1069 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
1070 or the buffer is not on proper alignment.
1075 AtaBlockIoReadBlocks (
1076 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1079 IN UINTN BufferSize
,
1083 return BlockIoReadWrite ((VOID
*) This
, MediaId
, Lba
, NULL
, BufferSize
, Buffer
, FALSE
, FALSE
);
1088 Write BufferSize bytes from Lba into Buffer.
1090 @param This Indicates a pointer to the calling context.
1091 @param MediaId The media ID that the write request is for.
1092 @param Lba The starting logical block address to be written. The caller is
1093 responsible for writing to only legitimate locations.
1094 @param BufferSize Size of Buffer, must be a multiple of device block size.
1095 @param Buffer A pointer to the source buffer for the data.
1097 @retval EFI_SUCCESS The data was written correctly to the device.
1098 @retval EFI_WRITE_PROTECTED The device can not be written to.
1099 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
1100 @retval EFI_NO_MEDIA There is no media in the device.
1101 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
1102 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
1103 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
1104 or the buffer is not on proper alignment.
1109 AtaBlockIoWriteBlocks (
1110 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1113 IN UINTN BufferSize
,
1117 return BlockIoReadWrite ((VOID
*) This
, MediaId
, Lba
, NULL
, BufferSize
, Buffer
, FALSE
, TRUE
);
1122 Flush the Block Device.
1124 @param This Indicates a pointer to the calling context.
1126 @retval EFI_SUCCESS All outstanding data was written to the device
1127 @retval EFI_DEVICE_ERROR The device reported an error while writing back the data
1128 @retval EFI_NO_MEDIA There is no media in the device.
1133 AtaBlockIoFlushBlocks (
1134 IN EFI_BLOCK_IO_PROTOCOL
*This
1144 Reset the Block Device.
1146 @param[in] This Indicates a pointer to the calling context.
1147 @param[in] ExtendedVerification Driver may perform diagnostics on reset.
1149 @retval EFI_SUCCESS The device was reset.
1150 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
1157 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
1158 IN BOOLEAN ExtendedVerification
1162 ATA_DEVICE
*AtaDevice
;
1165 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1167 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO2 (This
);
1169 Status
= ResetAtaDevice (AtaDevice
);
1171 if (EFI_ERROR (Status
)) {
1172 Status
= EFI_DEVICE_ERROR
;
1175 gBS
->RestoreTPL (OldTpl
);
1180 Read BufferSize bytes from Lba into Buffer.
1182 @param[in] This Indicates a pointer to the calling context.
1183 @param[in] MediaId Id of the media, changes every time the media is replaced.
1184 @param[in] Lba The starting Logical Block Address to read from.
1185 @param[in, out] Token A pointer to the token associated with the transaction.
1186 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
1187 @param[out] Buffer A pointer to the destination buffer for the data. The caller is
1188 responsible for either having implicit or explicit ownership of the buffer.
1190 @retval EFI_SUCCESS The read request was queued if Event is not NULL.
1191 The data was read correctly from the device if
1193 @retval EFI_DEVICE_ERROR The device reported an error while performing
1195 @retval EFI_NO_MEDIA There is no media in the device.
1196 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
1197 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
1198 intrinsic block size of the device.
1199 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
1200 or the buffer is not on proper alignment.
1201 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
1207 AtaBlockIoReadBlocksEx (
1208 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
1211 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
,
1212 IN UINTN BufferSize
,
1216 return BlockIoReadWrite ((VOID
*) This
, MediaId
, Lba
, Token
, BufferSize
, Buffer
, TRUE
, FALSE
);
1221 Write BufferSize bytes from Lba into Buffer.
1223 @param[in] This Indicates a pointer to the calling context.
1224 @param[in] MediaId The media ID that the write request is for.
1225 @param[in] Lba The starting logical block address to be written. The
1226 caller is responsible for writing to only legitimate
1228 @param[in, out] Token A pointer to the token associated with the transaction.
1229 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
1230 @param[in] Buffer A pointer to the source buffer for the data.
1232 @retval EFI_SUCCESS The data was written correctly to the device.
1233 @retval EFI_WRITE_PROTECTED The device can not be written to.
1234 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
1235 @retval EFI_NO_MEDIA There is no media in the device.
1236 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
1237 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
1238 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
1239 or the buffer is not on proper alignment.
1244 AtaBlockIoWriteBlocksEx (
1245 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
1248 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
,
1249 IN UINTN BufferSize
,
1253 return BlockIoReadWrite ((VOID
*) This
, MediaId
, Lba
, Token
, BufferSize
, Buffer
, TRUE
, TRUE
);
1258 Flush the Block Device.
1260 @param[in] This Indicates a pointer to the calling context.
1261 @param[in, out] Token A pointer to the token associated with the transaction.
1263 @retval EFI_SUCCESS All outstanding data was written to the device
1264 @retval EFI_DEVICE_ERROR The device reported an error while writing back the data
1265 @retval EFI_NO_MEDIA There is no media in the device.
1270 AtaBlockIoFlushBlocksEx (
1271 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
1272 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
1276 // Signal event and return directly.
1278 if (Token
!= NULL
&& Token
->Event
!= NULL
) {
1279 Token
->TransactionStatus
= EFI_SUCCESS
;
1280 gBS
->SignalEvent (Token
->Event
);
1285 Provides inquiry information for the controller type.
1287 This function is used by the IDE bus driver to get inquiry data. Data format
1288 of Identify data is defined by the Interface GUID.
1290 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1291 @param[in, out] InquiryData Pointer to a buffer for the inquiry data.
1292 @param[in, out] InquiryDataSize Pointer to the value for the inquiry data size.
1294 @retval EFI_SUCCESS The command was accepted without any errors.
1295 @retval EFI_NOT_FOUND Device does not support this data class
1296 @retval EFI_DEVICE_ERROR Error reading InquiryData from device
1297 @retval EFI_BUFFER_TOO_SMALL InquiryDataSize not big enough
1302 AtaDiskInfoInquiry (
1303 IN EFI_DISK_INFO_PROTOCOL
*This
,
1304 IN OUT VOID
*InquiryData
,
1305 IN OUT UINT32
*InquiryDataSize
1308 return EFI_NOT_FOUND
;
1313 Provides identify information for the controller type.
1315 This function is used by the IDE bus driver to get identify data. Data format
1316 of Identify data is defined by the Interface GUID.
1318 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL
1320 @param[in, out] IdentifyData Pointer to a buffer for the identify data.
1321 @param[in, out] IdentifyDataSize Pointer to the value for the identify data
1324 @retval EFI_SUCCESS The command was accepted without any errors.
1325 @retval EFI_NOT_FOUND Device does not support this data class
1326 @retval EFI_DEVICE_ERROR Error reading IdentifyData from device
1327 @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough
1332 AtaDiskInfoIdentify (
1333 IN EFI_DISK_INFO_PROTOCOL
*This
,
1334 IN OUT VOID
*IdentifyData
,
1335 IN OUT UINT32
*IdentifyDataSize
1339 ATA_DEVICE
*AtaDevice
;
1341 AtaDevice
= ATA_DEVICE_FROM_DISK_INFO (This
);
1343 Status
= EFI_BUFFER_TOO_SMALL
;
1344 if (*IdentifyDataSize
>= sizeof (ATA_IDENTIFY_DATA
)) {
1345 Status
= EFI_SUCCESS
;
1346 CopyMem (IdentifyData
, AtaDevice
->IdentifyData
, sizeof (ATA_IDENTIFY_DATA
));
1348 *IdentifyDataSize
= sizeof (ATA_IDENTIFY_DATA
);
1355 Provides sense data information for the controller type.
1357 This function is used by the IDE bus driver to get sense data.
1358 Data format of Sense data is defined by the Interface GUID.
1360 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1361 @param[in, out] SenseData Pointer to the SenseData.
1362 @param[in, out] SenseDataSize Size of SenseData in bytes.
1363 @param[out] SenseDataNumber Pointer to the value for the sense data size.
1365 @retval EFI_SUCCESS The command was accepted without any errors.
1366 @retval EFI_NOT_FOUND Device does not support this data class.
1367 @retval EFI_DEVICE_ERROR Error reading SenseData from device.
1368 @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough.
1373 AtaDiskInfoSenseData (
1374 IN EFI_DISK_INFO_PROTOCOL
*This
,
1375 IN OUT VOID
*SenseData
,
1376 IN OUT UINT32
*SenseDataSize
,
1377 OUT UINT8
*SenseDataNumber
1380 return EFI_NOT_FOUND
;
1385 This function is used by the IDE bus driver to get controller information.
1387 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1388 @param[out] IdeChannel Pointer to the Ide Channel number. Primary or secondary.
1389 @param[out] IdeDevice Pointer to the Ide Device number. Master or slave.
1391 @retval EFI_SUCCESS IdeChannel and IdeDevice are valid.
1392 @retval EFI_UNSUPPORTED This is not an IDE device.
1397 AtaDiskInfoWhichIde (
1398 IN EFI_DISK_INFO_PROTOCOL
*This
,
1399 OUT UINT32
*IdeChannel
,
1400 OUT UINT32
*IdeDevice
1403 ATA_DEVICE
*AtaDevice
;
1405 AtaDevice
= ATA_DEVICE_FROM_DISK_INFO (This
);
1406 *IdeChannel
= AtaDevice
->Port
;
1407 *IdeDevice
= AtaDevice
->PortMultiplierPort
;
1413 Send a security protocol command to a device that receives data and/or the result
1414 of one or more commands sent by SendData.
1416 The ReceiveData function sends a security protocol command to the given MediaId.
1417 The security protocol command sent is defined by SecurityProtocolId and contains
1418 the security protocol specific data SecurityProtocolSpecificData. The function
1419 returns the data from the security protocol command in PayloadBuffer.
1421 For devices supporting the SCSI command set, the security protocol command is sent
1422 using the SECURITY PROTOCOL IN command defined in SPC-4.
1424 For devices supporting the ATA command set, the security protocol command is sent
1425 using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize
1428 If the PayloadBufferSize is zero, the security protocol command is sent using the
1429 Trusted Non-Data command defined in ATA8-ACS.
1431 If PayloadBufferSize is too small to store the available data from the security
1432 protocol command, the function shall copy PayloadBufferSize bytes into the
1433 PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.
1435 If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero,
1436 the function shall return EFI_INVALID_PARAMETER.
1438 If the given MediaId does not support security protocol commands, the function shall
1439 return EFI_UNSUPPORTED. If there is no media in the device, the function returns
1440 EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device,
1441 the function returns EFI_MEDIA_CHANGED.
1443 If the security protocol fails to complete within the Timeout period, the function
1444 shall return EFI_TIMEOUT.
1446 If the security protocol command completes without an error, the function shall
1447 return EFI_SUCCESS. If the security protocol command completes with an error, the
1448 function shall return EFI_DEVICE_ERROR.
1450 @param This Indicates a pointer to the calling context.
1451 @param MediaId ID of the medium to receive data from.
1452 @param Timeout The timeout, in 100ns units, to use for the execution
1453 of the security protocol command. A Timeout value of 0
1454 means that this function will wait indefinitely for the
1455 security protocol command to execute. If Timeout is greater
1456 than zero, then this function will return EFI_TIMEOUT
1457 if the time required to execute the receive data command
1458 is greater than Timeout.
1459 @param SecurityProtocolId The value of the "Security Protocol" parameter of
1460 the security protocol command to be sent.
1461 @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
1462 of the security protocol command to be sent.
1463 @param PayloadBufferSize Size in bytes of the payload data buffer.
1464 @param PayloadBuffer A pointer to a destination buffer to store the security
1465 protocol command specific payload data for the security
1466 protocol command. The caller is responsible for having
1467 either implicit or explicit ownership of the buffer.
1468 @param PayloadTransferSize A pointer to a buffer to store the size in bytes of the
1469 data written to the payload data buffer.
1471 @retval EFI_SUCCESS The security protocol command completed successfully.
1472 @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available
1473 data from the device. The PayloadBuffer contains the truncated data.
1474 @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands.
1475 @retval EFI_DEVICE_ERROR The security protocol command completed with an error.
1476 @retval EFI_NO_MEDIA There is no media in the device.
1477 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
1478 @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and
1479 PayloadBufferSize is non-zero.
1480 @retval EFI_TIMEOUT A timeout occurred while waiting for the security
1481 protocol command to execute.
1486 AtaStorageSecurityReceiveData (
1487 IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
*This
,
1490 IN UINT8 SecurityProtocolId
,
1491 IN UINT16 SecurityProtocolSpecificData
,
1492 IN UINTN PayloadBufferSize
,
1493 OUT VOID
*PayloadBuffer
,
1494 OUT UINTN
*PayloadTransferSize
1498 ATA_DEVICE
*Private
;
1501 DEBUG ((EFI_D_INFO
, "EFI Storage Security Protocol - Read"));
1502 if ((PayloadBuffer
== NULL
|| PayloadTransferSize
== NULL
) && PayloadBufferSize
!= 0) {
1503 return EFI_INVALID_PARAMETER
;
1506 Status
= EFI_SUCCESS
;
1507 Private
= ATA_DEVICE_FROM_STORAGE_SECURITY (This
);
1509 if (MediaId
!= Private
->BlockIo
.Media
->MediaId
) {
1510 return EFI_MEDIA_CHANGED
;
1513 if (!Private
->BlockIo
.Media
->MediaPresent
) {
1514 return EFI_NO_MEDIA
;
1517 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1519 Status
= TrustTransferAtaDevice (
1523 SecurityProtocolSpecificData
,
1530 gBS
->RestoreTPL (OldTpl
);
1535 Send a security protocol command to a device.
1537 The SendData function sends a security protocol command containing the payload
1538 PayloadBuffer to the given MediaId. The security protocol command sent is
1539 defined by SecurityProtocolId and contains the security protocol specific data
1540 SecurityProtocolSpecificData. If the underlying protocol command requires a
1541 specific padding for the command payload, the SendData function shall add padding
1542 bytes to the command payload to satisfy the padding requirements.
1544 For devices supporting the SCSI command set, the security protocol command is sent
1545 using the SECURITY PROTOCOL OUT command defined in SPC-4.
1547 For devices supporting the ATA command set, the security protocol command is sent
1548 using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize
1549 is non-zero. If the PayloadBufferSize is zero, the security protocol command is
1550 sent using the Trusted Non-Data command defined in ATA8-ACS.
1552 If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall
1553 return EFI_INVALID_PARAMETER.
1555 If the given MediaId does not support security protocol commands, the function
1556 shall return EFI_UNSUPPORTED. If there is no media in the device, the function
1557 returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the
1558 device, the function returns EFI_MEDIA_CHANGED.
1560 If the security protocol fails to complete within the Timeout period, the function
1561 shall return EFI_TIMEOUT.
1563 If the security protocol command completes without an error, the function shall return
1564 EFI_SUCCESS. If the security protocol command completes with an error, the function
1565 shall return EFI_DEVICE_ERROR.
1567 @param This Indicates a pointer to the calling context.
1568 @param MediaId ID of the medium to receive data from.
1569 @param Timeout The timeout, in 100ns units, to use for the execution
1570 of the security protocol command. A Timeout value of 0
1571 means that this function will wait indefinitely for the
1572 security protocol command to execute. If Timeout is greater
1573 than zero, then this function will return EFI_TIMEOUT
1574 if the time required to execute the receive data command
1575 is greater than Timeout.
1576 @param SecurityProtocolId The value of the "Security Protocol" parameter of
1577 the security protocol command to be sent.
1578 @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
1579 of the security protocol command to be sent.
1580 @param PayloadBufferSize Size in bytes of the payload data buffer.
1581 @param PayloadBuffer A pointer to a destination buffer to store the security
1582 protocol command specific payload data for the security
1585 @retval EFI_SUCCESS The security protocol command completed successfully.
1586 @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands.
1587 @retval EFI_DEVICE_ERROR The security protocol command completed with an error.
1588 @retval EFI_NO_MEDIA There is no media in the device.
1589 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
1590 @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and PayloadBufferSize is non-zero.
1591 @retval EFI_TIMEOUT A timeout occurred while waiting for the security
1592 protocol command to execute.
1597 AtaStorageSecuritySendData (
1598 IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
*This
,
1601 IN UINT8 SecurityProtocolId
,
1602 IN UINT16 SecurityProtocolSpecificData
,
1603 IN UINTN PayloadBufferSize
,
1604 IN VOID
*PayloadBuffer
1608 ATA_DEVICE
*Private
;
1611 DEBUG ((EFI_D_INFO
, "EFI Storage Security Protocol - Send"));
1612 if ((PayloadBuffer
== NULL
) && (PayloadBufferSize
!= 0)) {
1613 return EFI_INVALID_PARAMETER
;
1616 Status
= EFI_SUCCESS
;
1617 Private
= ATA_DEVICE_FROM_STORAGE_SECURITY (This
);
1619 if (MediaId
!= Private
->BlockIo
.Media
->MediaId
) {
1620 return EFI_MEDIA_CHANGED
;
1623 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1624 Status
= TrustTransferAtaDevice (
1628 SecurityProtocolSpecificData
,
1635 gBS
->RestoreTPL (OldTpl
);
1640 The user Entry Point for module AtaBus. The user code starts with this function.
1642 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1643 @param[in] SystemTable A pointer to the EFI System Table.
1645 @retval EFI_SUCCESS The entry point is executed successfully.
1646 @retval other Some error occurs when executing this entry point.
1652 IN EFI_HANDLE ImageHandle
,
1653 IN EFI_SYSTEM_TABLE
*SystemTable
1660 // Install driver model protocol(s).
1662 Status
= EfiLibInstallDriverBindingComponentName2 (
1665 &gAtaBusDriverBinding
,
1667 &gAtaBusComponentName
,
1668 &gAtaBusComponentName2
1670 ASSERT_EFI_ERROR (Status
);
1673 // Get the MorControl bit.
1675 DataSize
= sizeof (mMorControl
);
1676 Status
= gRT
->GetVariable (
1677 MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME
,
1678 &gEfiMemoryOverwriteControlDataGuid
,
1684 if (EFI_ERROR (Status
)) {
1685 DEBUG ((EFI_D_INFO
, "AtaBus:gEfiMemoryOverwriteControlDataGuid doesn't exist!!***\n"));
1688 Status
= EFI_SUCCESS
;
1690 DEBUG ((EFI_D_INFO
, "AtaBus:Get the gEfiMemoryOverwriteControlDataGuid = %x!!***\n", mMorControl
));
1698 Send TPer Reset command to reset eDrive to lock all protected bands.
1699 Typically, there are 2 mechanism for resetting eDrive. They are:
1700 1. TPer Reset through IEEE 1667 protocol.
1701 2. TPer Reset through native TCG protocol.
1702 This routine will detect what protocol the attached eDrive comform to, TCG or
1703 IEEE 1667 protocol. Then send out TPer Reset command separately.
1705 @param[in] AtaDevice ATA_DEVICE pointer.
1710 IN ATA_DEVICE
*AtaDevice
1721 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
1722 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
*Ssp
;
1723 SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA
*Data
;
1728 Ssp
= &AtaDevice
->StorageSecurity
;
1729 BlockIo
= &AtaDevice
->BlockIo
;
1732 // ATA8-ACS 7.57.6.1 indicates the Transfer Length field requirements a multiple of 512.
1733 // If the length of the TRUSTED RECEIVE parameter data is greater than the Transfer Length,
1734 // then the device shall return the TRUSTED RECEIVE parameter data truncated to the requested Transfer Length.
1736 Len
= ROUNDUP512(sizeof(SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA
));
1737 Buffer
= AllocateZeroPool(Len
);
1739 if (Buffer
== NULL
) {
1744 // When the Security Protocol field is set to 00h, and SP Specific is set to 0000h in a TRUSTED RECEIVE
1745 // command, the device basic information data shall be returned.
1747 Status
= Ssp
->ReceiveData (
1749 BlockIo
->Media
->MediaId
,
1750 100000000, // Timeout 10-sec
1751 0, // SecurityProtocol
1752 0, // SecurityProtocolSpecifcData
1753 Len
, // PayloadBufferSize,
1754 Buffer
, // PayloadBuffer
1757 if (EFI_ERROR (Status
)) {
1762 // In returned data, the ListLength field indicates the total length, in bytes,
1763 // of the supported security protocol list.
1765 Data
= (SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA
*)Buffer
;
1766 Len
= ROUNDUP512(sizeof (SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA
) +
1767 (Data
->SupportedSecurityListLength
[0] << 8) +
1768 (Data
->SupportedSecurityListLength
[1])
1772 // Free original buffer and allocate new buffer.
1775 Buffer
= AllocateZeroPool(Len
);
1776 if (Buffer
== NULL
) {
1781 // Read full supported security protocol list from device.
1783 Status
= Ssp
->ReceiveData (
1785 BlockIo
->Media
->MediaId
,
1786 100000000, // Timeout 10-sec
1787 0, // SecurityProtocol
1788 0, // SecurityProtocolSpecifcData
1789 Len
, // PayloadBufferSize,
1790 Buffer
, // PayloadBuffer
1794 if (EFI_ERROR (Status
)) {
1798 Data
= (SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA
*)Buffer
;
1799 Len
= (Data
->SupportedSecurityListLength
[0] << 8) + Data
->SupportedSecurityListLength
[1];
1802 // Iterate full supported security protocol list to check if TCG or IEEE 1667 protocol
1805 for (Index
= 0; Index
< Len
; Index
++) {
1806 if (Data
->SupportedSecurityProtocol
[Index
] == SECURITY_PROTOCOL_TCG
) {
1808 // Found a TCG device.
1811 DEBUG ((EFI_D_INFO
, "This device is a TCG protocol device\n"));
1815 if (Data
->SupportedSecurityProtocol
[Index
] == SECURITY_PROTOCOL_IEEE1667
) {
1817 // Found a IEEE 1667 device.
1820 DEBUG ((EFI_D_INFO
, "This device is a IEEE 1667 protocol device\n"));
1825 if (!TcgFlag
&& !IeeeFlag
) {
1826 DEBUG ((EFI_D_INFO
, "Neither a TCG nor IEEE 1667 protocol device is found\n"));
1832 // As long as TCG protocol is supported, send out a TPer Reset
1833 // TCG command to the device via the TrustedSend command with a non-zero Transfer Length.
1835 Status
= Ssp
->SendData (
1837 BlockIo
->Media
->MediaId
,
1838 100000000, // Timeout 10-sec
1839 SECURITY_PROTOCOL_TCG
, // SecurityProtocol
1840 0x0400, // SecurityProtocolSpecifcData
1841 512, // PayloadBufferSize,
1842 Buffer
// PayloadBuffer
1845 if (!EFI_ERROR (Status
)) {
1846 DEBUG ((EFI_D_INFO
, "Send TPer Reset Command Successfully !\n"));
1848 DEBUG ((EFI_D_INFO
, "Send TPer Reset Command Fail !\n"));
1854 // TBD : Perform a TPer Reset via IEEE 1667 Protocol
1856 DEBUG ((EFI_D_INFO
, "IEEE 1667 Protocol didn't support yet!\n"));
1861 if (Buffer
!= NULL
) {