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 - 2014, 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.
24 // ATA Bus Driver Binding Protocol Instance
26 EFI_DRIVER_BINDING_PROTOCOL gAtaBusDriverBinding
= {
27 AtaBusDriverBindingSupported
,
28 AtaBusDriverBindingStart
,
29 AtaBusDriverBindingStop
,
36 // Template for ATA Child Device.
38 ATA_DEVICE gAtaDeviceTemplate
= {
39 ATA_DEVICE_SIGNATURE
, // Signature
42 EFI_BLOCK_IO_PROTOCOL_REVISION
,
46 AtaBlockIoWriteBlocks
,
52 AtaBlockIoReadBlocksEx
,
53 AtaBlockIoWriteBlocksEx
,
54 AtaBlockIoFlushBlocksEx
58 FALSE
, // RemovableMedia
60 FALSE
, // LogicPartition
62 FALSE
, // WritingCache
66 0, // LowestAlignedLba
67 1 // LogicalBlocksPerPhysicalBlock
70 EFI_DISK_INFO_IDE_INTERFACE_GUID
,
78 AtaStorageSecurityReceiveData
,
79 AtaStorageSecuritySendData
81 NULL
, // AtaBusDriverData
83 0, // PortMultiplierPort
90 NULL
, // ControllerNameTable
91 {L
'\0', }, // ModelName
92 {NULL
, NULL
}, // AtaTaskList
93 {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_ASYN_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_ASYN_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 // Report Status Code to indicate the ATA device will be enabled
301 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
303 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_PC_ENABLE
),
304 AtaBusDriverData
->ParentDevicePath
308 // Try to identify the ATA device via the ATA pass through command.
310 Status
= DiscoverAtaDevice (AtaDevice
);
311 if (EFI_ERROR (Status
)) {
316 // Build controller name for Component Name (2) protocol.
318 Status
= AddUnicodeString2 (
320 gAtaBusComponentName
.SupportedLanguages
,
321 &AtaDevice
->ControllerNameTable
,
322 AtaDevice
->ModelName
,
325 if (EFI_ERROR (Status
)) {
329 Status
= AddUnicodeString2 (
331 gAtaBusComponentName2
.SupportedLanguages
,
332 &AtaDevice
->ControllerNameTable
,
333 AtaDevice
->ModelName
,
336 if (EFI_ERROR (Status
)) {
341 // Update to AHCI interface GUID based on device path node. The default one
342 // is IDE interface GUID copied from template.
344 if (NewDevicePathNode
->SubType
== MSG_SATA_DP
) {
345 CopyGuid (&AtaDevice
->DiskInfo
.Interface
, &gEfiDiskInfoAhciInterfaceGuid
);
348 Status
= gBS
->InstallMultipleProtocolInterfaces (
350 &gEfiDevicePathProtocolGuid
,
351 AtaDevice
->DevicePath
,
352 &gEfiBlockIoProtocolGuid
,
354 &gEfiBlockIo2ProtocolGuid
,
355 &AtaDevice
->BlockIo2
,
356 &gEfiDiskInfoProtocolGuid
,
357 &AtaDevice
->DiskInfo
,
360 if (EFI_ERROR (Status
)) {
365 // See if the ata device support trust computing feature or not.
366 // If yes, then install Storage Security Protocol at the ata device handle.
368 if ((AtaDevice
->IdentifyData
->trusted_computing_support
& BIT0
) != 0) {
369 DEBUG ((EFI_D_INFO
, "Found TCG support in Port %x PortMultiplierPort %x\n", Port
, PortMultiplierPort
));
370 Status
= gBS
->InstallProtocolInterface (
372 &gEfiStorageSecurityCommandProtocolGuid
,
373 EFI_NATIVE_INTERFACE
,
374 &AtaDevice
->StorageSecurity
376 if (EFI_ERROR (Status
)) {
379 DEBUG ((EFI_D_INFO
, "Successfully Install Storage Security Protocol on the ATA device\n"));
383 if (((mMorControl
& 0x01) == 0x01) && ((AtaDevice
->IdentifyData
->trusted_computing_support
& BIT0
) != 0)) {
385 "mMorControl = %x, AtaDevice->IdentifyData->trusted_computing_support & BIT0 = %x\n",
387 (AtaDevice
->IdentifyData
->trusted_computing_support
& BIT0
)
389 DEBUG ((EFI_D_INFO
, "Try to lock device by sending TPer Reset command...\n"));
390 InitiateTPerReset(AtaDevice
);
394 AtaBusDriverData
->Controller
,
395 &gEfiAtaPassThruProtocolGuid
,
396 (VOID
**) &AtaPassThru
,
397 AtaBusDriverData
->DriverBindingHandle
,
399 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
403 if (NewDevicePathNode
!= NULL
) {
404 FreePool (NewDevicePathNode
);
407 if (EFI_ERROR (Status
) && (AtaDevice
!= NULL
)) {
408 ReleaseAtaResources (AtaDevice
);
409 DEBUG ((EFI_D_ERROR
| EFI_D_INIT
, "Failed to initialize Port %x PortMultiplierPort %x, status = %r\n", Port
, PortMultiplierPort
, Status
));
416 Unregisters an ATA device.
418 This function removes the protocols installed on the controller handle and
419 frees the resources allocated for the ATA device.
421 @param This The pointer to EFI_DRIVER_BINDING_PROTOCOL instance.
422 @param Controller The controller handle of the ATA device.
423 @param Handle The child handle.
425 @retval EFI_SUCCESS The ATA device is successfully unregistered.
426 @return Others Some error occurs when unregistering the ATA device.
430 UnregisterAtaDevice (
431 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
432 IN EFI_HANDLE Controller
,
437 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
438 EFI_BLOCK_IO2_PROTOCOL
*BlockIo2
;
439 ATA_DEVICE
*AtaDevice
;
440 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
441 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
*StorageSecurity
;
446 Status
= gBS
->OpenProtocol (
448 &gEfiBlockIoProtocolGuid
,
450 This
->DriverBindingHandle
,
452 EFI_OPEN_PROTOCOL_GET_PROTOCOL
454 if (EFI_ERROR (Status
)) {
456 // Locate BlockIo2 protocol
458 Status
= gBS
->OpenProtocol (
460 &gEfiBlockIo2ProtocolGuid
,
462 This
->DriverBindingHandle
,
464 EFI_OPEN_PROTOCOL_GET_PROTOCOL
466 if (EFI_ERROR (Status
)) {
472 // Get AtaDevice data.
474 if (BlockIo
!= NULL
) {
475 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO (BlockIo
);
477 ASSERT (BlockIo2
!= NULL
);
478 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO2 (BlockIo2
);
482 // Close the child handle
486 &gEfiAtaPassThruProtocolGuid
,
487 This
->DriverBindingHandle
,
492 // The Ata Bus driver installs the BlockIo and BlockIo2 in the DriverBindingStart().
493 // Here should uninstall both of them.
495 Status
= gBS
->UninstallMultipleProtocolInterfaces (
497 &gEfiDevicePathProtocolGuid
,
498 AtaDevice
->DevicePath
,
499 &gEfiBlockIoProtocolGuid
,
501 &gEfiBlockIo2ProtocolGuid
,
502 &AtaDevice
->BlockIo2
,
503 &gEfiDiskInfoProtocolGuid
,
504 &AtaDevice
->DiskInfo
,
508 if (EFI_ERROR (Status
)) {
511 &gEfiAtaPassThruProtocolGuid
,
512 (VOID
**) &AtaPassThru
,
513 This
->DriverBindingHandle
,
515 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
521 // If Storage Security Command Protocol is installed, then uninstall this protocol.
523 Status
= gBS
->OpenProtocol (
525 &gEfiStorageSecurityCommandProtocolGuid
,
526 (VOID
**) &StorageSecurity
,
527 This
->DriverBindingHandle
,
529 EFI_OPEN_PROTOCOL_GET_PROTOCOL
532 if (!EFI_ERROR (Status
)) {
533 Status
= gBS
->UninstallProtocolInterface (
535 &gEfiStorageSecurityCommandProtocolGuid
,
536 &AtaDevice
->StorageSecurity
538 if (EFI_ERROR (Status
)) {
541 &gEfiAtaPassThruProtocolGuid
,
542 (VOID
**) &AtaPassThru
,
543 This
->DriverBindingHandle
,
545 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
551 ReleaseAtaResources (AtaDevice
);
558 Tests to see if this driver supports a given controller. If a child device is provided,
559 it further tests to see if this driver supports creating a handle for the specified child device.
561 This function checks to see if the driver specified by This supports the device specified by
562 ControllerHandle. Drivers will typically use the device path attached to
563 ControllerHandle and/or the services from the bus I/O abstraction attached to
564 ControllerHandle to determine if the driver supports ControllerHandle. This function
565 may be called many times during platform initialization. In order to reduce boot times, the tests
566 performed by this function must be very small, and take as little time as possible to execute. This
567 function must not change the state of any hardware devices, and this function must be aware that the
568 device specified by ControllerHandle may already be managed by the same driver or a
569 different driver. This function must match its calls to AllocatePages() with FreePages(),
570 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
571 Since ControllerHandle may have been previously started by the same driver, if a protocol is
572 already in the opened state, then it must not be closed with CloseProtocol(). This is required
573 to guarantee the state of ControllerHandle is not modified by this function.
575 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
576 @param[in] ControllerHandle The handle of the controller to test. This handle
577 must support a protocol interface that supplies
578 an I/O abstraction to the driver.
579 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
580 parameter is ignored by device drivers, and is optional for bus
581 drivers. For bus drivers, if this parameter is not NULL, then
582 the bus driver must determine if the bus controller specified
583 by ControllerHandle and the child controller specified
584 by RemainingDevicePath are both supported by this
587 @retval EFI_SUCCESS The device specified by ControllerHandle and
588 RemainingDevicePath is supported by the driver specified by This.
589 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
590 RemainingDevicePath is already being managed by the driver
592 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
593 RemainingDevicePath is already being managed by a different
594 driver or an application that requires exclusive access.
595 Currently not implemented.
596 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
597 RemainingDevicePath is not supported by the driver specified by This.
601 AtaBusDriverBindingSupported (
602 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
603 IN EFI_HANDLE Controller
,
604 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
608 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
609 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
611 UINT16 PortMultiplierPort
;
614 // Test EFI_ATA_PASS_THRU_PROTOCOL on controller handle.
616 Status
= gBS
->OpenProtocol (
618 &gEfiAtaPassThruProtocolGuid
,
619 (VOID
**) &AtaPassThru
,
620 This
->DriverBindingHandle
,
622 EFI_OPEN_PROTOCOL_BY_DRIVER
625 if (Status
== EFI_ALREADY_STARTED
) {
629 if (EFI_ERROR (Status
)) {
634 // Test to see if this ATA Pass Thru Protocol is for a LOGICAL channel
636 if ((AtaPassThru
->Mode
->Attributes
& EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL
) == 0) {
638 // Close the I/O Abstraction(s) used to perform the supported test
642 &gEfiAtaPassThruProtocolGuid
,
643 This
->DriverBindingHandle
,
646 return EFI_UNSUPPORTED
;
650 // Test RemainingDevicePath is valid or not.
652 if ((RemainingDevicePath
!= NULL
) && !IsDevicePathEnd (RemainingDevicePath
)) {
653 Status
= AtaPassThru
->GetDevice (AtaPassThru
, RemainingDevicePath
, &Port
, &PortMultiplierPort
);
654 if (EFI_ERROR (Status
)) {
656 // Close the I/O Abstraction(s) used to perform the supported test
660 &gEfiAtaPassThruProtocolGuid
,
661 This
->DriverBindingHandle
,
669 // Close the I/O Abstraction(s) used to perform the supported test
673 &gEfiAtaPassThruProtocolGuid
,
674 This
->DriverBindingHandle
,
679 // Open the EFI Device Path protocol needed to perform the supported test
681 Status
= gBS
->OpenProtocol (
683 &gEfiDevicePathProtocolGuid
,
684 (VOID
**) &ParentDevicePath
,
685 This
->DriverBindingHandle
,
687 EFI_OPEN_PROTOCOL_GET_PROTOCOL
694 Starts a device controller or a bus controller.
696 The Start() function is designed to be invoked from the EFI boot service ConnectController().
697 As a result, much of the error checking on the parameters to Start() has been moved into this
698 common boot service. It is legal to call Start() from other locations,
699 but the following calling restrictions must be followed or the system behavior will not be deterministic.
700 1. ControllerHandle must be a valid EFI_HANDLE.
701 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
702 EFI_DEVICE_PATH_PROTOCOL.
703 3. Prior to calling Start(), the Supported() function for the driver specified by This must
704 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
706 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
707 @param[in] ControllerHandle The handle of the controller to start. This handle
708 must support a protocol interface that supplies
709 an I/O abstraction to the driver.
710 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
711 parameter is ignored by device drivers, and is optional for bus
712 drivers. For a bus driver, if this parameter is NULL, then handles
713 for all the children of Controller are created by this driver.
714 If this parameter is not NULL and the first Device Path Node is
715 not the End of Device Path Node, then only the handle for the
716 child device specified by the first Device Path Node of
717 RemainingDevicePath is created by this driver.
718 If the first Device Path Node of RemainingDevicePath is
719 the End of Device Path Node, no child handle is created by this
722 @retval EFI_SUCCESS The device was started.
723 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
724 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
725 @retval Others The driver failded to start the device.
730 AtaBusDriverBindingStart (
731 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
732 IN EFI_HANDLE Controller
,
733 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
737 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
738 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
739 ATA_BUS_DRIVER_DATA
*AtaBusDriverData
;
741 UINT16 PortMultiplierPort
;
743 AtaBusDriverData
= NULL
;
745 Status
= gBS
->OpenProtocol (
747 &gEfiDevicePathProtocolGuid
,
748 (VOID
**) &ParentDevicePath
,
749 This
->DriverBindingHandle
,
751 EFI_OPEN_PROTOCOL_GET_PROTOCOL
753 if (EFI_ERROR (Status
)) {
758 // Report Status Code to indicate ATA bus starts
760 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
762 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_PC_INIT
),
766 Status
= gBS
->OpenProtocol (
768 &gEfiAtaPassThruProtocolGuid
,
769 (VOID
**) &AtaPassThru
,
770 This
->DriverBindingHandle
,
772 EFI_OPEN_PROTOCOL_BY_DRIVER
774 if ((EFI_ERROR (Status
)) && (Status
!= EFI_ALREADY_STARTED
)) {
779 // Check EFI_ALREADY_STARTED to reuse the original ATA_BUS_DRIVER_DATA.
781 if (Status
!= EFI_ALREADY_STARTED
) {
782 AtaBusDriverData
= AllocateZeroPool (sizeof (ATA_BUS_DRIVER_DATA
));
783 if (AtaBusDriverData
== NULL
) {
784 Status
= EFI_OUT_OF_RESOURCES
;
788 AtaBusDriverData
->AtaPassThru
= AtaPassThru
;
789 AtaBusDriverData
->Controller
= Controller
;
790 AtaBusDriverData
->ParentDevicePath
= ParentDevicePath
;
791 AtaBusDriverData
->DriverBindingHandle
= This
->DriverBindingHandle
;
793 Status
= gBS
->InstallMultipleProtocolInterfaces (
799 if (EFI_ERROR (Status
)) {
804 Status
= gBS
->OpenProtocol (
807 (VOID
**) &AtaBusDriverData
,
808 This
->DriverBindingHandle
,
810 EFI_OPEN_PROTOCOL_GET_PROTOCOL
812 if (EFI_ERROR (Status
)) {
813 AtaBusDriverData
= NULL
;
819 // Report Status Code to indicate detecting devices on bus
821 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
823 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_PC_DETECT
),
827 if (RemainingDevicePath
== NULL
) {
830 Status
= AtaPassThru
->GetNextPort (AtaPassThru
, &Port
);
831 if (EFI_ERROR (Status
)) {
833 // We cannot find more legal port then we are done.
838 PortMultiplierPort
= 0xFFFF;
840 Status
= AtaPassThru
->GetNextDevice (AtaPassThru
, Port
, &PortMultiplierPort
);
841 if (EFI_ERROR (Status
)) {
843 // We cannot find more legal port multiplier port number for ATA device
844 // on the port, then we are done.
848 RegisterAtaDevice (AtaBusDriverData
, Port
, PortMultiplierPort
);
851 Status
= EFI_SUCCESS
;
852 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
853 Status
= AtaPassThru
->GetDevice (AtaPassThru
, RemainingDevicePath
, &Port
, &PortMultiplierPort
);
854 if (!EFI_ERROR (Status
)) {
855 Status
= RegisterAtaDevice (AtaBusDriverData
,Port
, PortMultiplierPort
);
863 if (AtaBusDriverData
!= NULL
) {
864 gBS
->UninstallMultipleProtocolInterfaces (
870 FreePool (AtaBusDriverData
);
875 &gEfiAtaPassThruProtocolGuid
,
876 This
->DriverBindingHandle
,
886 Stops a device controller or a bus controller.
888 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
889 As a result, much of the error checking on the parameters to Stop() has been moved
890 into this common boot service. It is legal to call Stop() from other locations,
891 but the following calling restrictions must be followed or the system behavior will not be deterministic.
892 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
893 same driver's Start() function.
894 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
895 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
896 Start() function, and the Start() function must have called OpenProtocol() on
897 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
899 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
900 @param[in] ControllerHandle A handle to the device being stopped. The handle must
901 support a bus specific I/O protocol for the driver
902 to use to stop the device.
903 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
904 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
905 if NumberOfChildren is 0.
907 @retval EFI_SUCCESS The device was stopped.
908 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
913 AtaBusDriverBindingStop (
914 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
915 IN EFI_HANDLE Controller
,
916 IN UINTN NumberOfChildren
,
917 IN EFI_HANDLE
*ChildHandleBuffer
921 BOOLEAN AllChildrenStopped
;
923 ATA_BUS_DRIVER_DATA
*AtaBusDriverData
;
925 if (NumberOfChildren
== 0) {
926 Status
= gBS
->OpenProtocol (
929 (VOID
**) &AtaBusDriverData
,
930 This
->DriverBindingHandle
,
932 EFI_OPEN_PROTOCOL_GET_PROTOCOL
934 if (!EFI_ERROR (Status
)) {
935 gBS
->UninstallMultipleProtocolInterfaces (
941 FreePool (AtaBusDriverData
);
946 &gEfiAtaPassThruProtocolGuid
,
947 This
->DriverBindingHandle
,
954 AllChildrenStopped
= TRUE
;
956 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
958 Status
= UnregisterAtaDevice (This
, Controller
, ChildHandleBuffer
[Index
]);
959 if (EFI_ERROR (Status
)) {
960 AllChildrenStopped
= FALSE
;
964 if (!AllChildrenStopped
) {
965 return EFI_DEVICE_ERROR
;
973 Reset the Block Device.
975 @param This Indicates a pointer to the calling context.
976 @param ExtendedVerification Driver may perform diagnostics on reset.
978 @retval EFI_SUCCESS The device was reset.
979 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
986 IN EFI_BLOCK_IO_PROTOCOL
*This
,
987 IN BOOLEAN ExtendedVerification
991 ATA_DEVICE
*AtaDevice
;
994 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
996 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO (This
);
998 Status
= ResetAtaDevice (AtaDevice
);
1000 if (EFI_ERROR (Status
)) {
1001 Status
= EFI_DEVICE_ERROR
;
1004 gBS
->RestoreTPL (OldTpl
);
1010 Read/Write BufferSize bytes from Lba from/into Buffer.
1012 @param[in] This Indicates a pointer to the calling context. Either be
1013 block I/O or block I/O2.
1014 @param[in] MediaId The media ID that the read/write request is for.
1015 @param[in] Lba The starting logical block address to be read/written.
1016 The caller is responsible for reading/writing to only
1017 legitimate locations.
1018 @param[in, out] Token A pointer to the token associated with the transaction.
1019 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
1020 @param[out] Buffer A pointer to the destination/source buffer for the data.
1021 @param[in] IsBlockIo2 Indicate the calling is from BlockIO or BlockIO2. TURE is
1022 from BlockIO2, FALSE is for BlockIO.
1023 @param[in] IsWrite Indicates whether it is a write operation.
1025 @retval EFI_SUCCESS The data was read/written correctly to the device.
1026 @retval EFI_WRITE_PROTECTED The device can not be read/written to.
1027 @retval EFI_DEVICE_ERROR The device reported an error while performing the read/write.
1028 @retval EFI_NO_MEDIA There is no media in the device.
1029 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
1030 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
1031 @retval EFI_INVALID_PARAMETER The read/write request contains LBAs that are not valid,
1032 or the buffer is not on proper alignment.
1040 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
,
1041 IN UINTN BufferSize
,
1043 IN BOOLEAN IsBlockIo2
,
1047 ATA_DEVICE
*AtaDevice
;
1050 EFI_BLOCK_IO_MEDIA
*Media
;
1052 UINTN NumberOfBlocks
;
1056 Media
= ((EFI_BLOCK_IO2_PROTOCOL
*) This
)->Media
;
1057 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO2 (This
);
1059 Media
= ((EFI_BLOCK_IO_PROTOCOL
*) This
)->Media
;
1060 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO (This
);
1063 if (MediaId
!= Media
->MediaId
) {
1064 return EFI_MEDIA_CHANGED
;
1068 // Check parameters.
1070 if (Buffer
== NULL
) {
1071 return EFI_INVALID_PARAMETER
;
1074 if (BufferSize
== 0) {
1075 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
1076 Token
->TransactionStatus
= EFI_SUCCESS
;
1077 gBS
->SignalEvent (Token
->Event
);
1082 BlockSize
= Media
->BlockSize
;
1083 if ((BufferSize
% BlockSize
) != 0) {
1084 return EFI_BAD_BUFFER_SIZE
;
1087 NumberOfBlocks
= BufferSize
/ BlockSize
;
1088 if ((Lba
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1089 return EFI_INVALID_PARAMETER
;
1092 IoAlign
= Media
->IoAlign
;
1093 if (IoAlign
> 0 && (((UINTN
) Buffer
& (IoAlign
- 1)) != 0)) {
1094 return EFI_INVALID_PARAMETER
;
1097 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1100 // Invoke low level AtaDevice Access Routine.
1102 Status
= AccessAtaDevice (AtaDevice
, Buffer
, Lba
, NumberOfBlocks
, IsWrite
, Token
);
1104 gBS
->RestoreTPL (OldTpl
);
1111 Read BufferSize bytes from Lba into Buffer.
1113 @param This Indicates a pointer to the calling context.
1114 @param MediaId Id of the media, changes every time the media is replaced.
1115 @param Lba The starting Logical Block Address to read from
1116 @param BufferSize Size of Buffer, must be a multiple of device block size.
1117 @param Buffer A pointer to the destination buffer for the data. The caller is
1118 responsible for either having implicit or explicit ownership of the buffer.
1120 @retval EFI_SUCCESS The data was read correctly from the device.
1121 @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
1122 @retval EFI_NO_MEDIA There is no media in the device.
1123 @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
1124 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
1125 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
1126 or the buffer is not on proper alignment.
1131 AtaBlockIoReadBlocks (
1132 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1135 IN UINTN BufferSize
,
1139 return BlockIoReadWrite ((VOID
*) This
, MediaId
, Lba
, NULL
, BufferSize
, Buffer
, FALSE
, FALSE
);
1144 Write BufferSize bytes from Lba into Buffer.
1146 @param This Indicates a pointer to the calling context.
1147 @param MediaId The media ID that the write request is for.
1148 @param Lba The starting logical block address to be written. The caller is
1149 responsible for writing to only legitimate locations.
1150 @param BufferSize Size of Buffer, must be a multiple of device block size.
1151 @param Buffer A pointer to the source buffer for the data.
1153 @retval EFI_SUCCESS The data was written correctly to the device.
1154 @retval EFI_WRITE_PROTECTED The device can not be written to.
1155 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
1156 @retval EFI_NO_MEDIA There is no media in the device.
1157 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
1158 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
1159 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
1160 or the buffer is not on proper alignment.
1165 AtaBlockIoWriteBlocks (
1166 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1169 IN UINTN BufferSize
,
1173 return BlockIoReadWrite ((VOID
*) This
, MediaId
, Lba
, NULL
, BufferSize
, Buffer
, FALSE
, TRUE
);
1178 Flush the Block Device.
1180 @param This Indicates a pointer to the calling context.
1182 @retval EFI_SUCCESS All outstanding data was written to the device
1183 @retval EFI_DEVICE_ERROR The device reported an error while writing back the data
1184 @retval EFI_NO_MEDIA There is no media in the device.
1189 AtaBlockIoFlushBlocks (
1190 IN EFI_BLOCK_IO_PROTOCOL
*This
1200 Reset the Block Device.
1202 @param[in] This Indicates a pointer to the calling context.
1203 @param[in] ExtendedVerification Driver may perform diagnostics on reset.
1205 @retval EFI_SUCCESS The device was reset.
1206 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
1213 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
1214 IN BOOLEAN ExtendedVerification
1218 ATA_DEVICE
*AtaDevice
;
1221 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1223 AtaDevice
= ATA_DEVICE_FROM_BLOCK_IO2 (This
);
1225 AtaTerminateNonBlockingTask (AtaDevice
);
1227 Status
= ResetAtaDevice (AtaDevice
);
1229 if (EFI_ERROR (Status
)) {
1230 Status
= EFI_DEVICE_ERROR
;
1233 gBS
->RestoreTPL (OldTpl
);
1238 Read BufferSize bytes from Lba into Buffer.
1240 @param[in] This Indicates a pointer to the calling context.
1241 @param[in] MediaId Id of the media, changes every time the media is replaced.
1242 @param[in] Lba The starting Logical Block Address to read from.
1243 @param[in, out] Token A pointer to the token associated with the transaction.
1244 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
1245 @param[out] Buffer A pointer to the destination buffer for the data. The caller is
1246 responsible for either having implicit or explicit ownership of the buffer.
1248 @retval EFI_SUCCESS The read request was queued if Event is not NULL.
1249 The data was read correctly from the device if
1251 @retval EFI_DEVICE_ERROR The device reported an error while performing
1253 @retval EFI_NO_MEDIA There is no media in the device.
1254 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
1255 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
1256 intrinsic block size of the device.
1257 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
1258 or the buffer is not on proper alignment.
1259 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
1265 AtaBlockIoReadBlocksEx (
1266 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
1269 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
,
1270 IN UINTN BufferSize
,
1274 return BlockIoReadWrite ((VOID
*) This
, MediaId
, Lba
, Token
, BufferSize
, Buffer
, TRUE
, FALSE
);
1279 Write BufferSize bytes from Lba into Buffer.
1281 @param[in] This Indicates a pointer to the calling context.
1282 @param[in] MediaId The media ID that the write request is for.
1283 @param[in] Lba The starting logical block address to be written. The
1284 caller is responsible for writing to only legitimate
1286 @param[in, out] Token A pointer to the token associated with the transaction.
1287 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
1288 @param[in] Buffer A pointer to the source buffer for the data.
1290 @retval EFI_SUCCESS The data was written correctly to the device.
1291 @retval EFI_WRITE_PROTECTED The device can not be written to.
1292 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
1293 @retval EFI_NO_MEDIA There is no media in the device.
1294 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
1295 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
1296 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
1297 or the buffer is not on proper alignment.
1302 AtaBlockIoWriteBlocksEx (
1303 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
1306 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
,
1307 IN UINTN BufferSize
,
1311 return BlockIoReadWrite ((VOID
*) This
, MediaId
, Lba
, Token
, BufferSize
, Buffer
, TRUE
, TRUE
);
1316 Flush the Block Device.
1318 @param[in] This Indicates a pointer to the calling context.
1319 @param[in, out] Token A pointer to the token associated with the transaction.
1321 @retval EFI_SUCCESS All outstanding data was written to the device
1322 @retval EFI_DEVICE_ERROR The device reported an error while writing back the data
1323 @retval EFI_NO_MEDIA There is no media in the device.
1328 AtaBlockIoFlushBlocksEx (
1329 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
1330 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
1334 // Signal event and return directly.
1336 if (Token
!= NULL
&& Token
->Event
!= NULL
) {
1337 Token
->TransactionStatus
= EFI_SUCCESS
;
1338 gBS
->SignalEvent (Token
->Event
);
1343 Provides inquiry information for the controller type.
1345 This function is used by the IDE bus driver to get inquiry data. Data format
1346 of Identify data is defined by the Interface GUID.
1348 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1349 @param[in, out] InquiryData Pointer to a buffer for the inquiry data.
1350 @param[in, out] InquiryDataSize Pointer to the value for the inquiry data size.
1352 @retval EFI_SUCCESS The command was accepted without any errors.
1353 @retval EFI_NOT_FOUND Device does not support this data class
1354 @retval EFI_DEVICE_ERROR Error reading InquiryData from device
1355 @retval EFI_BUFFER_TOO_SMALL InquiryDataSize not big enough
1360 AtaDiskInfoInquiry (
1361 IN EFI_DISK_INFO_PROTOCOL
*This
,
1362 IN OUT VOID
*InquiryData
,
1363 IN OUT UINT32
*InquiryDataSize
1366 return EFI_NOT_FOUND
;
1371 Provides identify information for the controller type.
1373 This function is used by the IDE bus driver to get identify data. Data format
1374 of Identify data is defined by the Interface GUID.
1376 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL
1378 @param[in, out] IdentifyData Pointer to a buffer for the identify data.
1379 @param[in, out] IdentifyDataSize Pointer to the value for the identify data
1382 @retval EFI_SUCCESS The command was accepted without any errors.
1383 @retval EFI_NOT_FOUND Device does not support this data class
1384 @retval EFI_DEVICE_ERROR Error reading IdentifyData from device
1385 @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough
1390 AtaDiskInfoIdentify (
1391 IN EFI_DISK_INFO_PROTOCOL
*This
,
1392 IN OUT VOID
*IdentifyData
,
1393 IN OUT UINT32
*IdentifyDataSize
1397 ATA_DEVICE
*AtaDevice
;
1399 AtaDevice
= ATA_DEVICE_FROM_DISK_INFO (This
);
1401 Status
= EFI_BUFFER_TOO_SMALL
;
1402 if (*IdentifyDataSize
>= sizeof (ATA_IDENTIFY_DATA
)) {
1403 Status
= EFI_SUCCESS
;
1404 CopyMem (IdentifyData
, AtaDevice
->IdentifyData
, sizeof (ATA_IDENTIFY_DATA
));
1406 *IdentifyDataSize
= sizeof (ATA_IDENTIFY_DATA
);
1413 Provides sense data information for the controller type.
1415 This function is used by the IDE bus driver to get sense data.
1416 Data format of Sense data is defined by the Interface GUID.
1418 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1419 @param[in, out] SenseData Pointer to the SenseData.
1420 @param[in, out] SenseDataSize Size of SenseData in bytes.
1421 @param[out] SenseDataNumber Pointer to the value for the sense data size.
1423 @retval EFI_SUCCESS The command was accepted without any errors.
1424 @retval EFI_NOT_FOUND Device does not support this data class.
1425 @retval EFI_DEVICE_ERROR Error reading SenseData from device.
1426 @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough.
1431 AtaDiskInfoSenseData (
1432 IN EFI_DISK_INFO_PROTOCOL
*This
,
1433 IN OUT VOID
*SenseData
,
1434 IN OUT UINT32
*SenseDataSize
,
1435 OUT UINT8
*SenseDataNumber
1438 return EFI_NOT_FOUND
;
1443 This function is used by the IDE bus driver to get controller information.
1445 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1446 @param[out] IdeChannel Pointer to the Ide Channel number. Primary or secondary.
1447 @param[out] IdeDevice Pointer to the Ide Device number. Master or slave.
1449 @retval EFI_SUCCESS IdeChannel and IdeDevice are valid.
1450 @retval EFI_UNSUPPORTED This is not an IDE device.
1455 AtaDiskInfoWhichIde (
1456 IN EFI_DISK_INFO_PROTOCOL
*This
,
1457 OUT UINT32
*IdeChannel
,
1458 OUT UINT32
*IdeDevice
1461 ATA_DEVICE
*AtaDevice
;
1463 AtaDevice
= ATA_DEVICE_FROM_DISK_INFO (This
);
1464 *IdeChannel
= AtaDevice
->Port
;
1465 *IdeDevice
= AtaDevice
->PortMultiplierPort
;
1471 Send a security protocol command to a device that receives data and/or the result
1472 of one or more commands sent by SendData.
1474 The ReceiveData function sends a security protocol command to the given MediaId.
1475 The security protocol command sent is defined by SecurityProtocolId and contains
1476 the security protocol specific data SecurityProtocolSpecificData. The function
1477 returns the data from the security protocol command in PayloadBuffer.
1479 For devices supporting the SCSI command set, the security protocol command is sent
1480 using the SECURITY PROTOCOL IN command defined in SPC-4.
1482 For devices supporting the ATA command set, the security protocol command is sent
1483 using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize
1486 If the PayloadBufferSize is zero, the security protocol command is sent using the
1487 Trusted Non-Data command defined in ATA8-ACS.
1489 If PayloadBufferSize is too small to store the available data from the security
1490 protocol command, the function shall copy PayloadBufferSize bytes into the
1491 PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.
1493 If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero,
1494 the function shall return EFI_INVALID_PARAMETER.
1496 If the given MediaId does not support security protocol commands, the function shall
1497 return EFI_UNSUPPORTED. If there is no media in the device, the function returns
1498 EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device,
1499 the function returns EFI_MEDIA_CHANGED.
1501 If the security protocol fails to complete within the Timeout period, the function
1502 shall return EFI_TIMEOUT.
1504 If the security protocol command completes without an error, the function shall
1505 return EFI_SUCCESS. If the security protocol command completes with an error, the
1506 function shall return EFI_DEVICE_ERROR.
1508 @param This Indicates a pointer to the calling context.
1509 @param MediaId ID of the medium to receive data from.
1510 @param Timeout The timeout, in 100ns units, to use for the execution
1511 of the security protocol command. A Timeout value of 0
1512 means that this function will wait indefinitely for the
1513 security protocol command to execute. If Timeout is greater
1514 than zero, then this function will return EFI_TIMEOUT
1515 if the time required to execute the receive data command
1516 is greater than Timeout.
1517 @param SecurityProtocolId The value of the "Security Protocol" parameter of
1518 the security protocol command to be sent.
1519 @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
1520 of the security protocol command to be sent.
1521 @param PayloadBufferSize Size in bytes of the payload data buffer.
1522 @param PayloadBuffer A pointer to a destination buffer to store the security
1523 protocol command specific payload data for the security
1524 protocol command. The caller is responsible for having
1525 either implicit or explicit ownership of the buffer.
1526 @param PayloadTransferSize A pointer to a buffer to store the size in bytes of the
1527 data written to the payload data buffer.
1529 @retval EFI_SUCCESS The security protocol command completed successfully.
1530 @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available
1531 data from the device. The PayloadBuffer contains the truncated data.
1532 @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands.
1533 @retval EFI_DEVICE_ERROR The security protocol command completed with an error.
1534 @retval EFI_NO_MEDIA There is no media in the device.
1535 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
1536 @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and
1537 PayloadBufferSize is non-zero.
1538 @retval EFI_TIMEOUT A timeout occurred while waiting for the security
1539 protocol command to execute.
1544 AtaStorageSecurityReceiveData (
1545 IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
*This
,
1548 IN UINT8 SecurityProtocolId
,
1549 IN UINT16 SecurityProtocolSpecificData
,
1550 IN UINTN PayloadBufferSize
,
1551 OUT VOID
*PayloadBuffer
,
1552 OUT UINTN
*PayloadTransferSize
1556 ATA_DEVICE
*Private
;
1559 DEBUG ((EFI_D_INFO
, "EFI Storage Security Protocol - Read"));
1560 if ((PayloadBuffer
== NULL
|| PayloadTransferSize
== NULL
) && PayloadBufferSize
!= 0) {
1561 return EFI_INVALID_PARAMETER
;
1564 Status
= EFI_SUCCESS
;
1565 Private
= ATA_DEVICE_FROM_STORAGE_SECURITY (This
);
1567 if (MediaId
!= Private
->BlockIo
.Media
->MediaId
) {
1568 return EFI_MEDIA_CHANGED
;
1571 if (!Private
->BlockIo
.Media
->MediaPresent
) {
1572 return EFI_NO_MEDIA
;
1575 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1577 Status
= TrustTransferAtaDevice (
1581 SecurityProtocolSpecificData
,
1588 gBS
->RestoreTPL (OldTpl
);
1593 Send a security protocol command to a device.
1595 The SendData function sends a security protocol command containing the payload
1596 PayloadBuffer to the given MediaId. The security protocol command sent is
1597 defined by SecurityProtocolId and contains the security protocol specific data
1598 SecurityProtocolSpecificData. If the underlying protocol command requires a
1599 specific padding for the command payload, the SendData function shall add padding
1600 bytes to the command payload to satisfy the padding requirements.
1602 For devices supporting the SCSI command set, the security protocol command is sent
1603 using the SECURITY PROTOCOL OUT command defined in SPC-4.
1605 For devices supporting the ATA command set, the security protocol command is sent
1606 using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize
1607 is non-zero. If the PayloadBufferSize is zero, the security protocol command is
1608 sent using the Trusted Non-Data command defined in ATA8-ACS.
1610 If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall
1611 return EFI_INVALID_PARAMETER.
1613 If the given MediaId does not support security protocol commands, the function
1614 shall return EFI_UNSUPPORTED. If there is no media in the device, the function
1615 returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the
1616 device, the function returns EFI_MEDIA_CHANGED.
1618 If the security protocol fails to complete within the Timeout period, the function
1619 shall return EFI_TIMEOUT.
1621 If the security protocol command completes without an error, the function shall return
1622 EFI_SUCCESS. If the security protocol command completes with an error, the function
1623 shall return EFI_DEVICE_ERROR.
1625 @param This Indicates a pointer to the calling context.
1626 @param MediaId ID of the medium to receive data from.
1627 @param Timeout The timeout, in 100ns units, to use for the execution
1628 of the security protocol command. A Timeout value of 0
1629 means that this function will wait indefinitely for the
1630 security protocol command to execute. If Timeout is greater
1631 than zero, then this function will return EFI_TIMEOUT
1632 if the time required to execute the receive data command
1633 is greater than Timeout.
1634 @param SecurityProtocolId The value of the "Security Protocol" parameter of
1635 the security protocol command to be sent.
1636 @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
1637 of the security protocol command to be sent.
1638 @param PayloadBufferSize Size in bytes of the payload data buffer.
1639 @param PayloadBuffer A pointer to a destination buffer to store the security
1640 protocol command specific payload data for the security
1643 @retval EFI_SUCCESS The security protocol command completed successfully.
1644 @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands.
1645 @retval EFI_DEVICE_ERROR The security protocol command completed with an error.
1646 @retval EFI_NO_MEDIA There is no media in the device.
1647 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
1648 @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and PayloadBufferSize is non-zero.
1649 @retval EFI_TIMEOUT A timeout occurred while waiting for the security
1650 protocol command to execute.
1655 AtaStorageSecuritySendData (
1656 IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
*This
,
1659 IN UINT8 SecurityProtocolId
,
1660 IN UINT16 SecurityProtocolSpecificData
,
1661 IN UINTN PayloadBufferSize
,
1662 IN VOID
*PayloadBuffer
1666 ATA_DEVICE
*Private
;
1669 DEBUG ((EFI_D_INFO
, "EFI Storage Security Protocol - Send"));
1670 if ((PayloadBuffer
== NULL
) && (PayloadBufferSize
!= 0)) {
1671 return EFI_INVALID_PARAMETER
;
1674 Status
= EFI_SUCCESS
;
1675 Private
= ATA_DEVICE_FROM_STORAGE_SECURITY (This
);
1677 if (MediaId
!= Private
->BlockIo
.Media
->MediaId
) {
1678 return EFI_MEDIA_CHANGED
;
1681 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1682 Status
= TrustTransferAtaDevice (
1686 SecurityProtocolSpecificData
,
1693 gBS
->RestoreTPL (OldTpl
);
1698 The user Entry Point for module AtaBus. The user code starts with this function.
1700 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1701 @param[in] SystemTable A pointer to the EFI System Table.
1703 @retval EFI_SUCCESS The entry point is executed successfully.
1704 @retval other Some error occurs when executing this entry point.
1710 IN EFI_HANDLE ImageHandle
,
1711 IN EFI_SYSTEM_TABLE
*SystemTable
1718 // Install driver model protocol(s).
1720 Status
= EfiLibInstallDriverBindingComponentName2 (
1723 &gAtaBusDriverBinding
,
1725 &gAtaBusComponentName
,
1726 &gAtaBusComponentName2
1728 ASSERT_EFI_ERROR (Status
);
1731 // Get the MorControl bit.
1733 DataSize
= sizeof (mMorControl
);
1734 Status
= gRT
->GetVariable (
1735 MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME
,
1736 &gEfiMemoryOverwriteControlDataGuid
,
1742 if (EFI_ERROR (Status
)) {
1743 DEBUG ((EFI_D_INFO
, "AtaBus:gEfiMemoryOverwriteControlDataGuid doesn't exist!!***\n"));
1745 Status
= EFI_SUCCESS
;
1747 DEBUG ((EFI_D_INFO
, "AtaBus:Get the gEfiMemoryOverwriteControlDataGuid = %x!!***\n", mMorControl
));
1754 Send TPer Reset command to reset eDrive to lock all protected bands.
1755 Typically, there are 2 mechanism for resetting eDrive. They are:
1756 1. TPer Reset through IEEE 1667 protocol.
1757 2. TPer Reset through native TCG protocol.
1758 This routine will detect what protocol the attached eDrive comform to, TCG or
1759 IEEE 1667 protocol. Then send out TPer Reset command separately.
1761 @param[in] AtaDevice ATA_DEVICE pointer.
1766 IN ATA_DEVICE
*AtaDevice
1777 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
1778 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
*Ssp
;
1779 SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA
*Data
;
1784 Ssp
= &AtaDevice
->StorageSecurity
;
1785 BlockIo
= &AtaDevice
->BlockIo
;
1788 // ATA8-ACS 7.57.6.1 indicates the Transfer Length field requirements a multiple of 512.
1789 // If the length of the TRUSTED RECEIVE parameter data is greater than the Transfer Length,
1790 // then the device shall return the TRUSTED RECEIVE parameter data truncated to the requested Transfer Length.
1792 Len
= ROUNDUP512(sizeof(SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA
));
1793 Buffer
= AllocateZeroPool(Len
);
1795 if (Buffer
== NULL
) {
1800 // When the Security Protocol field is set to 00h, and SP Specific is set to 0000h in a TRUSTED RECEIVE
1801 // command, the device basic information data shall be returned.
1803 Status
= Ssp
->ReceiveData (
1805 BlockIo
->Media
->MediaId
,
1806 100000000, // Timeout 10-sec
1807 0, // SecurityProtocol
1808 0, // SecurityProtocolSpecifcData
1809 Len
, // PayloadBufferSize,
1810 Buffer
, // PayloadBuffer
1813 if (EFI_ERROR (Status
)) {
1818 // In returned data, the ListLength field indicates the total length, in bytes,
1819 // of the supported security protocol list.
1821 Data
= (SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA
*)Buffer
;
1822 Len
= ROUNDUP512(sizeof (SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA
) +
1823 (Data
->SupportedSecurityListLength
[0] << 8) +
1824 (Data
->SupportedSecurityListLength
[1])
1828 // Free original buffer and allocate new buffer.
1831 Buffer
= AllocateZeroPool(Len
);
1832 if (Buffer
== NULL
) {
1837 // Read full supported security protocol list from device.
1839 Status
= Ssp
->ReceiveData (
1841 BlockIo
->Media
->MediaId
,
1842 100000000, // Timeout 10-sec
1843 0, // SecurityProtocol
1844 0, // SecurityProtocolSpecifcData
1845 Len
, // PayloadBufferSize,
1846 Buffer
, // PayloadBuffer
1850 if (EFI_ERROR (Status
)) {
1854 Data
= (SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA
*)Buffer
;
1855 Len
= (Data
->SupportedSecurityListLength
[0] << 8) + Data
->SupportedSecurityListLength
[1];
1858 // Iterate full supported security protocol list to check if TCG or IEEE 1667 protocol
1861 for (Index
= 0; Index
< Len
; Index
++) {
1862 if (Data
->SupportedSecurityProtocol
[Index
] == SECURITY_PROTOCOL_TCG
) {
1864 // Found a TCG device.
1867 DEBUG ((EFI_D_INFO
, "This device is a TCG protocol device\n"));
1871 if (Data
->SupportedSecurityProtocol
[Index
] == SECURITY_PROTOCOL_IEEE1667
) {
1873 // Found a IEEE 1667 device.
1876 DEBUG ((EFI_D_INFO
, "This device is a IEEE 1667 protocol device\n"));
1881 if (!TcgFlag
&& !IeeeFlag
) {
1882 DEBUG ((EFI_D_INFO
, "Neither a TCG nor IEEE 1667 protocol device is found\n"));
1888 // As long as TCG protocol is supported, send out a TPer Reset
1889 // TCG command to the device via the TrustedSend command with a non-zero Transfer Length.
1891 Status
= Ssp
->SendData (
1893 BlockIo
->Media
->MediaId
,
1894 100000000, // Timeout 10-sec
1895 SECURITY_PROTOCOL_TCG
, // SecurityProtocol
1896 0x0400, // SecurityProtocolSpecifcData
1897 512, // PayloadBufferSize,
1898 Buffer
// PayloadBuffer
1901 if (!EFI_ERROR (Status
)) {
1902 DEBUG ((EFI_D_INFO
, "Send TPer Reset Command Successfully !\n"));
1904 DEBUG ((EFI_D_INFO
, "Send TPer Reset Command Fail !\n"));
1910 // TBD : Perform a TPer Reset via IEEE 1667 Protocol
1912 DEBUG ((EFI_D_INFO
, "IEEE 1667 Protocol didn't support yet!\n"));
1917 if (Buffer
!= NULL
) {