1ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/** @file
2ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  This file implements protocol interfaces for ATA bus driver.
358727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang
4ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  This file implements protocol interfaces: Driver Binding protocol,
5ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Block IO protocol and DiskInfo protocol.
658727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang
7857ce453d4c5fa18b03a334e9bf043276b8f6dd4Tian Feng  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
8cd5ebaa06dca3e6ef3c464081e6defe00d358c69hhtian  This program and the accompanying materials
9ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  are licensed and made available under the terms and conditions of the BSD License
10ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  which accompanies this distribution.  The full text of the license may be found at
11ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  http://opensource.org/licenses/bsd-license.php
12ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
13ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
16ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
17ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
18ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
19ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang#include "AtaBus.h"
20ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
21ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang//
22ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang// ATA Bus Driver Binding Protocol Instance
23ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang//
24ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_DRIVER_BINDING_PROTOCOL gAtaBusDriverBinding = {
25ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  AtaBusDriverBindingSupported,
26ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  AtaBusDriverBindingStart,
27ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  AtaBusDriverBindingStop,
28ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  0x10,
29ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  NULL,
30ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  NULL
31ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang};
32ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
33ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang//
34ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang// Template for ATA Child Device.
35ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang//
36ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangATA_DEVICE gAtaDeviceTemplate = {
3705a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  ATA_DEVICE_SIGNATURE,        // Signature
3805a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  NULL,                        // Handle
39ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  {                            // BlockIo
40ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    EFI_BLOCK_IO_PROTOCOL_REVISION,
41ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    NULL,
42ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    AtaBlockIoReset,
43ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    AtaBlockIoReadBlocks,
44ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    AtaBlockIoWriteBlocks,
45ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    AtaBlockIoFlushBlocks
46ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  },
47490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  {                            // BlockIo2
48490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    NULL,
49490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    AtaBlockIoResetEx,
50490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    AtaBlockIoReadBlocksEx,
51490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    AtaBlockIoWriteBlocksEx,
52490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    AtaBlockIoFlushBlocksEx
53490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  },
54ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  {                            // BlockMedia
55ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    0,                         // MediaId
56ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    FALSE,                     // RemovableMedia
57ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    TRUE,                      // MediaPresent
58ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    FALSE,                     // LogicPartition
59ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    FALSE,                     // ReadOnly
60ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    FALSE,                     // WritingCache
6158727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang    0x200,                     // BlockSize
62907c1a003937905217bf80f577671ef48d153725qhuang    0,                         // IoAlign
633bfa77f0f6dc52dc867318b86ddd23bcf504818fqhuang    0,                         // LastBlock
643bfa77f0f6dc52dc867318b86ddd23bcf504818fqhuang    0,                         // LowestAlignedLba
653bfa77f0f6dc52dc867318b86ddd23bcf504818fqhuang    1                          // LogicalBlocksPerPhysicalBlock
66ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  },
67ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  {                            // DiskInfo
68ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    EFI_DISK_INFO_IDE_INTERFACE_GUID,
69ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    AtaDiskInfoInquiry,
70ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    AtaDiskInfoIdentify,
71ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    AtaDiskInfoSenseData,
72ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    AtaDiskInfoWhichIde
73ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  },
7405a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  NULL,                        // DevicePath
75c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  {
76c24097a59ffb10d63c805c4da65476ed6e297c5chhuan    AtaStorageSecurityReceiveData,
77c24097a59ffb10d63c805c4da65476ed6e297c5chhuan    AtaStorageSecuritySendData
78c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  },
7905a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  NULL,                        // AtaBusDriverData
8005a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  0,                           // Port
8105a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  0,                           // PortMultiplierPort
82ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  { 0, },                      // Packet
83ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  {{ 0}, },                    // Acb
84ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  NULL,                        // Asb
85ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  FALSE,                       // UdmaValid
86ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  FALSE,                       // Lba48Bit
87ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  NULL,                        // IdentifyData
88ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  NULL,                        // ControllerNameTable
89490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  {L'\0', },                   // ModelName
9058727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  {NULL, NULL},                // AtaTaskList
9171fd9fae8bda10f41a9c6445f01eed82b99883daTian, Feng  {NULL, NULL},                // AtaSubTaskList
9271fd9fae8bda10f41a9c6445f01eed82b99883daTian, Feng  FALSE                        // Abort
93ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang};
94ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
95ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
96ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Allocates an aligned buffer for ATA device.
97ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
98ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  This function allocates an aligned buffer for the ATA device to perform
99ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  ATA pass through operations. The alignment requirement is from ATA pass
100ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  through interface.
101ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
102ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  AtaDevice         The ATA child device involved for the operation.
103ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  BufferSize        The request buffer size.
104ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
105ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @return A pointer to the aligned buffer or NULL if the allocation fails.
106ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
107ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
108ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangVOID *
109ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangAllocateAlignedBuffer (
110ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN ATA_DEVICE               *AtaDevice,
111ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN UINTN                    BufferSize
112ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
113ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
114ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  return AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), AtaDevice->AtaBusDriverData->AtaPassThru->Mode->IoAlign);
115ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
116ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
117ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
118ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Frees an aligned buffer for ATA device.
119ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
120ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  This function frees an aligned buffer for the ATA device to perform
121ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  ATA pass through operations.
122ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
12305a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  @param  Buffer            The aligned buffer to be freed.
124ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  BufferSize        The request buffer size.
125ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
126ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
127ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangVOID
128ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangFreeAlignedBuffer (
129ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN VOID                     *Buffer,
130ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN UINTN                    BufferSize
131ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
132ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
133ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (Buffer != NULL) {
134957fe0935329fd9dd195401e07855a2ba432d364lzeng    FreeAlignedPages (Buffer, EFI_SIZE_TO_PAGES (BufferSize));
135ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
136ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
137ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
138ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
139ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
140ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Release all the resources allocated for the ATA device.
141ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
142ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  This function releases all the resources allocated for the ATA device.
143ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
144ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  AtaDevice         The ATA child device involved for the operation.
145ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
146ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
147ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangVOID
148ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangReleaseAtaResources (
149ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN ATA_DEVICE  *AtaDevice
150ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
151ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
15258727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  ATA_BUS_ASYN_SUB_TASK *SubTask;
15358727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  ATA_BUS_ASYN_TASK     *AtaTask;
15458727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  LIST_ENTRY            *Entry;
15558727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  LIST_ENTRY            *DelEntry;
15658727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  EFI_TPL               OldTpl;
157490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
158ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  FreeUnicodeStringTable (AtaDevice->ControllerNameTable);
1593c063fedc4bd816ef427065003dca41ba1f885d2erictian  FreeAlignedBuffer (AtaDevice->Asb, sizeof (EFI_ATA_STATUS_BLOCK));
1603c063fedc4bd816ef427065003dca41ba1f885d2erictian  FreeAlignedBuffer (AtaDevice->IdentifyData, sizeof (ATA_IDENTIFY_DATA));
161ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (AtaDevice->DevicePath != NULL) {
162ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    FreePool (AtaDevice->DevicePath);
163ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
164490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
16558727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  if (!IsListEmpty (&AtaDevice->AtaSubTaskList)) {
16658727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang    //
16758727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang    // Free the Subtask list.
16858727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang    //
16958727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang    for(Entry = AtaDevice->AtaSubTaskList.ForwardLink;
17058727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang        Entry != (&AtaDevice->AtaSubTaskList);
17158727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang       ) {
17258727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang      DelEntry = Entry;
17358727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang      Entry    = Entry->ForwardLink;
17471fd9fae8bda10f41a9c6445f01eed82b99883daTian, Feng      SubTask  = ATA_ASYN_SUB_TASK_FROM_ENTRY (DelEntry);
17558727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang
17658727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang      RemoveEntryList (DelEntry);
17758727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang      FreeAtaSubTask (SubTask);
17858727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang    }
17958727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  }
180490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  if (!IsListEmpty (&AtaDevice->AtaTaskList)) {
181490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    //
182490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    // Free the Subtask list.
183490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    //
18458727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang    for(Entry = AtaDevice->AtaTaskList.ForwardLink;
185490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang        Entry != (&AtaDevice->AtaTaskList);
186490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang       ) {
187490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang      DelEntry = Entry;
188490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang      Entry    = Entry->ForwardLink;
18971fd9fae8bda10f41a9c6445f01eed82b99883daTian, Feng      AtaTask  = ATA_ASYN_TASK_FROM_ENTRY (DelEntry);
19058727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang
191490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang      RemoveEntryList (DelEntry);
19258727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang      FreePool (AtaTask);
193490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    }
194490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  }
195490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  gBS->RestoreTPL (OldTpl);
196ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  FreePool (AtaDevice);
197ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
198ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
199ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
200ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
201ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Registers an ATA device.
202ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
203ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  This function allocates an ATA device structure for the ATA device specified by
20458727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  Port and PortMultiplierPort if the ATA device is identified as a valid one.
205ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Then it will create child handle and install Block IO and Disk Info protocol on
206ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  it.
207ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
20805a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  @param  AtaBusDriverData      The parent ATA bus driver data structure.
209ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  Port                  The port number of the ATA device.
210ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  PortMultiplierPort    The port multiplier port number of the ATA device.
211ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
212ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS           The ATA device is successfully registered.
213ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_OUT_OF_RESOURCES  There is not enough memory to allocate the ATA device
214ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                and related data structures.
215ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @return Others                Some error occurs when registering the ATA device.
216ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
217ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
218ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangRegisterAtaDevice (
219ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN OUT ATA_BUS_DRIVER_DATA        *AtaBusDriverData,
220ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN     UINT16                     Port,
221ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN     UINT16                     PortMultiplierPort
222ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
223ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
224ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_STATUS                        Status;
225ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  ATA_DEVICE                        *AtaDevice;
226ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_ATA_PASS_THRU_PROTOCOL        *AtaPassThru;
227ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_DEVICE_PATH_PROTOCOL          *NewDevicePathNode;
228e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
229e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  EFI_DEVICE_PATH_PROTOCOL          *RemainingDevicePath;
230e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  EFI_HANDLE                        DeviceHandle;
231ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
232e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  AtaDevice         = NULL;
233ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  NewDevicePathNode = NULL;
234e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  DevicePath        = NULL;
235e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  RemainingDevicePath = NULL;
236e519983a6cba0f410299ab9e2e970bb369e67bc6erictian
237e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  //
23858727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  // Build device path
239e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  //
240e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  AtaPassThru = AtaBusDriverData->AtaPassThru;
241e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  Status = AtaPassThru->BuildDevicePath (AtaPassThru, Port, PortMultiplierPort, &NewDevicePathNode);
242e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  if (EFI_ERROR (Status)) {
243e519983a6cba0f410299ab9e2e970bb369e67bc6erictian    goto Done;
244e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  }
245e519983a6cba0f410299ab9e2e970bb369e67bc6erictian
246e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  DevicePath = AppendDevicePathNode (AtaBusDriverData->ParentDevicePath, NewDevicePathNode);
247e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  if (DevicePath == NULL) {
248e70ae46c0009d8e51b184aacf09817748082cce6erictian    Status = EFI_OUT_OF_RESOURCES;
249e519983a6cba0f410299ab9e2e970bb369e67bc6erictian    goto Done;
250e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  }
251e519983a6cba0f410299ab9e2e970bb369e67bc6erictian
252e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  DeviceHandle = NULL;
253e70ae46c0009d8e51b184aacf09817748082cce6erictian  RemainingDevicePath = DevicePath;
254e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);
255e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) {
256e519983a6cba0f410299ab9e2e970bb369e67bc6erictian    Status = EFI_ALREADY_STARTED;
257e70ae46c0009d8e51b184aacf09817748082cce6erictian    FreePool (DevicePath);
258e519983a6cba0f410299ab9e2e970bb369e67bc6erictian    goto Done;
259e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  }
260ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
261ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
262ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  // Allocate ATA device from the template.
263ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
2643c063fedc4bd816ef427065003dca41ba1f885d2erictian  AtaDevice = AllocateCopyPool (sizeof (ATA_DEVICE), &gAtaDeviceTemplate);
265ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (AtaDevice == NULL) {
266e519983a6cba0f410299ab9e2e970bb369e67bc6erictian    Status = EFI_OUT_OF_RESOURCES;
267e519983a6cba0f410299ab9e2e970bb369e67bc6erictian    goto Done;
268ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
269ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
270ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
271ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  // Initializes ATA device structures and allocates the required buffer.
272ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
273490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  AtaDevice->BlockIo.Media      = &AtaDevice->BlockMedia;
274490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  AtaDevice->BlockIo2.Media     = &AtaDevice->BlockMedia;
275490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  AtaDevice->AtaBusDriverData   = AtaBusDriverData;
276490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  AtaDevice->DevicePath         = DevicePath;
277490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  AtaDevice->Port               = Port;
278ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  AtaDevice->PortMultiplierPort = PortMultiplierPort;
2793c063fedc4bd816ef427065003dca41ba1f885d2erictian  AtaDevice->Asb = AllocateAlignedBuffer (AtaDevice, sizeof (EFI_ATA_STATUS_BLOCK));
280ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (AtaDevice->Asb == NULL) {
281ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    Status = EFI_OUT_OF_RESOURCES;
282ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    goto Done;
283ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
2843c063fedc4bd816ef427065003dca41ba1f885d2erictian  AtaDevice->IdentifyData = AllocateAlignedBuffer (AtaDevice, sizeof (ATA_IDENTIFY_DATA));
285ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (AtaDevice->IdentifyData == NULL) {
286ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    Status = EFI_OUT_OF_RESOURCES;
287ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    goto Done;
288ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
289ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
290ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
291490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  // Initial Ata Task List
292490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  //
293490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  InitializeListHead (&AtaDevice->AtaTaskList);
29458727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  InitializeListHead (&AtaDevice->AtaSubTaskList);
295490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
296490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  //
29737623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin  // Report Status Code to indicate the ATA device will be enabled
29837623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin  //
29937623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
30037623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    EFI_PROGRESS_CODE,
30137623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_ENABLE),
30237623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    AtaBusDriverData->ParentDevicePath
30337623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    );
30437623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin
30537623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin  //
30658727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  // Try to identify the ATA device via the ATA pass through command.
307ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
308ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Status = DiscoverAtaDevice (AtaDevice);
309ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (EFI_ERROR (Status)) {
310ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    goto Done;
311ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
312490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
313ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
314ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  // Build controller name for Component Name (2) protocol.
315ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
316ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Status = AddUnicodeString2 (
317ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             "eng",
318ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             gAtaBusComponentName.SupportedLanguages,
319ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             &AtaDevice->ControllerNameTable,
320ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             AtaDevice->ModelName,
321ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             TRUE
322ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             );
323ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (EFI_ERROR (Status)) {
324ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    goto Done;
325ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
326ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
327ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Status = AddUnicodeString2 (
328ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             "en",
329ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             gAtaBusComponentName2.SupportedLanguages,
330ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             &AtaDevice->ControllerNameTable,
331ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             AtaDevice->ModelName,
332ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             FALSE
333ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             );
334ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (EFI_ERROR (Status)) {
335ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    goto Done;
336ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
337ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
338ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
339ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  // Update to AHCI interface GUID based on device path node. The default one
340ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  // is IDE interface GUID copied from template.
341ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
342ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (NewDevicePathNode->SubType == MSG_SATA_DP) {
343ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    CopyGuid (&AtaDevice->DiskInfo.Interface, &gEfiDiskInfoAhciInterfaceGuid);
344ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
345ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
346ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Status = gBS->InstallMultipleProtocolInterfaces (
347ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &AtaDevice->Handle,
348ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &gEfiDevicePathProtocolGuid,
349ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  AtaDevice->DevicePath,
350ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &gEfiBlockIoProtocolGuid,
351ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &AtaDevice->BlockIo,
352490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                  &gEfiBlockIo2ProtocolGuid,
353490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                  &AtaDevice->BlockIo2,
354ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &gEfiDiskInfoProtocolGuid,
355ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &AtaDevice->DiskInfo,
356ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  NULL
357ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  );
358ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (EFI_ERROR (Status)) {
359ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    goto Done;
360ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
361ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
362c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  //
363c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  // See if the ata device support trust computing feature or not.
364c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  // If yes, then install Storage Security Protocol at the ata device handle.
365c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  //
366c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  if ((AtaDevice->IdentifyData->trusted_computing_support & BIT0) != 0) {
367c24097a59ffb10d63c805c4da65476ed6e297c5chhuan    DEBUG ((EFI_D_INFO, "Found TCG support in Port %x PortMultiplierPort %x\n", Port, PortMultiplierPort));
368c24097a59ffb10d63c805c4da65476ed6e297c5chhuan    Status = gBS->InstallProtocolInterface (
369c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                    &AtaDevice->Handle,
370c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                    &gEfiStorageSecurityCommandProtocolGuid,
371c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                    EFI_NATIVE_INTERFACE,
372c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                    &AtaDevice->StorageSecurity
373c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                    );
374c24097a59ffb10d63c805c4da65476ed6e297c5chhuan    if (EFI_ERROR (Status)) {
375c24097a59ffb10d63c805c4da65476ed6e297c5chhuan      goto Done;
376c24097a59ffb10d63c805c4da65476ed6e297c5chhuan    }
37790398d5558431b733a97ba7e3a2fddcd5f0858f5qianouyang    DEBUG ((EFI_D_INFO, "Successfully Install Storage Security Protocol on the ATA device\n"));
37890398d5558431b733a97ba7e3a2fddcd5f0858f5qianouyang  }
37990398d5558431b733a97ba7e3a2fddcd5f0858f5qianouyang
380ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  gBS->OpenProtocol (
381ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang         AtaBusDriverData->Controller,
382ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang         &gEfiAtaPassThruProtocolGuid,
383ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang         (VOID **) &AtaPassThru,
384ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang         AtaBusDriverData->DriverBindingHandle,
385ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang         AtaDevice->Handle,
386ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang         EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
387ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang         );
388e519983a6cba0f410299ab9e2e970bb369e67bc6erictian
389ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangDone:
390ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (NewDevicePathNode != NULL) {
391ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    FreePool (NewDevicePathNode);
392ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
393ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
394e519983a6cba0f410299ab9e2e970bb369e67bc6erictian  if (EFI_ERROR (Status) && (AtaDevice != NULL)) {
39558727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang    ReleaseAtaResources (AtaDevice);
39625dd150b585f0bc498482dc00325cf9b67362665lzeng    DEBUG ((EFI_D_ERROR | EFI_D_INIT, "Failed to initialize Port %x PortMultiplierPort %x, status = %r\n", Port, PortMultiplierPort, Status));
397ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
398ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  return Status;
399ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
400ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
401ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
402ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
403ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Unregisters an ATA device.
404ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
40558727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  This function removes the protocols installed on the controller handle and
40658727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  frees the resources allocated for the ATA device.
407ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
40805a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  @param  This                  The pointer to EFI_DRIVER_BINDING_PROTOCOL instance.
409ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  Controller            The controller handle of the ATA device.
410ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  Handle                The child handle.
411ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
412ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS           The ATA device is successfully unregistered.
413ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @return Others                Some error occurs when unregistering the ATA device.
414ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
415ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
416ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
417ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangUnregisterAtaDevice (
418ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
419ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  EFI_HANDLE                     Controller,
420ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  EFI_HANDLE                     Handle
421ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
422ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
423c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  EFI_STATUS                               Status;
424c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  EFI_BLOCK_IO_PROTOCOL                    *BlockIo;
425c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  EFI_BLOCK_IO2_PROTOCOL                   *BlockIo2;
426c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  ATA_DEVICE                               *AtaDevice;
427c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  EFI_ATA_PASS_THRU_PROTOCOL               *AtaPassThru;
428c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  EFI_STORAGE_SECURITY_COMMAND_PROTOCOL    *StorageSecurity;
429c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
430c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  BlockIo2             =     NULL;
431c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  BlockIo              =     NULL;
432ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
433ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Status = gBS->OpenProtocol (
434ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  Handle,
435ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &gEfiBlockIoProtocolGuid,
436ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  (VOID **) &BlockIo,
437ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  This->DriverBindingHandle,
438ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  Controller,
439ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
440ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  );
441ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (EFI_ERROR (Status)) {
442490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    //
443490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    // Locate BlockIo2 protocol
444490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    //
445490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    Status = gBS->OpenProtocol (
446490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                    Handle,
447490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                    &gEfiBlockIo2ProtocolGuid,
448490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                    (VOID **) &BlockIo2,
449490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                    This->DriverBindingHandle,
450490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                    Controller,
451490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
452490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                    );
453490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    if (EFI_ERROR (Status)) {
454490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang      return Status;
455490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    }
456ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
457ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
458490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  //
459490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  // Get AtaDevice data.
460490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  //
461490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  if (BlockIo != NULL) {
462490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (BlockIo);
463490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  } else {
4643d267c70b2f69118fe06fcec753fd62a049669ebydong    ASSERT (BlockIo2 != NULL);
465490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    AtaDevice = ATA_DEVICE_FROM_BLOCK_IO2 (BlockIo2);
46658727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  }
467ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
468ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
469ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  // Close the child handle
470ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
471ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  gBS->CloseProtocol (
472ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang         Controller,
473ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang         &gEfiAtaPassThruProtocolGuid,
474ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang         This->DriverBindingHandle,
475ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang         Handle
476ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang         );
477ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
478490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  //
479490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  // The Ata Bus driver installs the BlockIo and BlockIo2 in the DriverBindingStart().
480490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  // Here should uninstall both of them.
481490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  //
482ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Status = gBS->UninstallMultipleProtocolInterfaces (
483ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  Handle,
484ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &gEfiDevicePathProtocolGuid,
485ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  AtaDevice->DevicePath,
486ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &gEfiBlockIoProtocolGuid,
487ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &AtaDevice->BlockIo,
488490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                  &gEfiBlockIo2ProtocolGuid,
489490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                  &AtaDevice->BlockIo2,
490ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &gEfiDiskInfoProtocolGuid,
491ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &AtaDevice->DiskInfo,
492ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  NULL
493ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  );
494ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
495ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (EFI_ERROR (Status)) {
496ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    gBS->OpenProtocol (
497ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          Controller,
498ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          &gEfiAtaPassThruProtocolGuid,
499ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          (VOID **) &AtaPassThru,
500ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          This->DriverBindingHandle,
501ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          Handle,
502ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
503ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          );
504ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    return Status;
505ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
506ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
507c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  //
508c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  // If Storage Security Command Protocol is installed, then uninstall this protocol.
509c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  //
510c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  Status = gBS->OpenProtocol (
511c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                  Handle,
512c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                  &gEfiStorageSecurityCommandProtocolGuid,
513c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                  (VOID **) &StorageSecurity,
514c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                  This->DriverBindingHandle,
515c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                  Controller,
516c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
517c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                  );
518c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
519c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  if (!EFI_ERROR (Status)) {
520c24097a59ffb10d63c805c4da65476ed6e297c5chhuan    Status = gBS->UninstallProtocolInterface (
521c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                    Handle,
522c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                    &gEfiStorageSecurityCommandProtocolGuid,
523c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                    &AtaDevice->StorageSecurity
524c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                    );
525c24097a59ffb10d63c805c4da65476ed6e297c5chhuan    if (EFI_ERROR (Status)) {
526c24097a59ffb10d63c805c4da65476ed6e297c5chhuan      gBS->OpenProtocol (
527c24097a59ffb10d63c805c4da65476ed6e297c5chhuan        Controller,
528c24097a59ffb10d63c805c4da65476ed6e297c5chhuan        &gEfiAtaPassThruProtocolGuid,
529c24097a59ffb10d63c805c4da65476ed6e297c5chhuan        (VOID **) &AtaPassThru,
530c24097a59ffb10d63c805c4da65476ed6e297c5chhuan        This->DriverBindingHandle,
531c24097a59ffb10d63c805c4da65476ed6e297c5chhuan        Handle,
532c24097a59ffb10d63c805c4da65476ed6e297c5chhuan        EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
533c24097a59ffb10d63c805c4da65476ed6e297c5chhuan        );
5343c063fedc4bd816ef427065003dca41ba1f885d2erictian      return Status;
535c24097a59ffb10d63c805c4da65476ed6e297c5chhuan    }
536c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  }
537c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
538ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  ReleaseAtaResources (AtaDevice);
5397f070be5c98b39842f5d692d28406216f7e726fberictian  return EFI_SUCCESS;
540ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
541ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
542ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
543ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
544ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
54558727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  Tests to see if this driver supports a given controller. If a child device is provided,
546ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  it further tests to see if this driver supports creating a handle for the specified child device.
547ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
54858727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  This function checks to see if the driver specified by This supports the device specified by
54958727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  ControllerHandle. Drivers will typically use the device path attached to
55058727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  ControllerHandle and/or the services from the bus I/O abstraction attached to
55158727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  ControllerHandle to determine if the driver supports ControllerHandle. This function
55258727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  may be called many times during platform initialization. In order to reduce boot times, the tests
55358727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  performed by this function must be very small, and take as little time as possible to execute. This
55458727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  function must not change the state of any hardware devices, and this function must be aware that the
55558727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  device specified by ControllerHandle may already be managed by the same driver or a
55658727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  different driver. This function must match its calls to AllocatePages() with FreePages(),
55758727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
55858727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  Since ControllerHandle may have been previously started by the same driver, if a protocol is
55958727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  already in the opened state, then it must not be closed with CloseProtocol(). This is required
560ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  to guarantee the state of ControllerHandle is not modified by this function.
561ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
562ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
56358727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @param[in]  ControllerHandle     The handle of the controller to test. This handle
56458727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                                   must support a protocol interface that supplies
565ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                   an I/O abstraction to the driver.
56658727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
56758727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                                   parameter is ignored by device drivers, and is optional for bus
56858727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                                   drivers. For bus drivers, if this parameter is not NULL, then
56958727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                                   the bus driver must determine if the bus controller specified
57058727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                                   by ControllerHandle and the child controller specified
57158727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                                   by RemainingDevicePath are both supported by this
572ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                   bus driver.
573ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
574ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS              The device specified by ControllerHandle and
575ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                   RemainingDevicePath is supported by the driver specified by This.
576ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
577ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                   RemainingDevicePath is already being managed by the driver
578ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                   specified by This.
579ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
580ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                   RemainingDevicePath is already being managed by a different
581ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                   driver or an application that requires exclusive access.
582ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                   Currently not implemented.
583ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
584ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                   RemainingDevicePath is not supported by the driver specified by This.
585ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
586ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
587ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFIAPI
588ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangAtaBusDriverBindingSupported (
589ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
590ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN EFI_HANDLE                   Controller,
591ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
592ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
593ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
594ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_STATUS                        Status;
595ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;
596ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_ATA_PASS_THRU_PROTOCOL        *AtaPassThru;
597ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  UINT16                            Port;
598ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  UINT16                            PortMultiplierPort;
599490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
600ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
601ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  // Test EFI_ATA_PASS_THRU_PROTOCOL on controller handle.
602ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
603ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Status = gBS->OpenProtocol (
604ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  Controller,
605ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &gEfiAtaPassThruProtocolGuid,
606ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  (VOID **) &AtaPassThru,
607ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  This->DriverBindingHandle,
608ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  Controller,
609ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  EFI_OPEN_PROTOCOL_BY_DRIVER
610ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  );
611ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
612ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (Status == EFI_ALREADY_STARTED) {
613ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    return EFI_SUCCESS;
614ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
615ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
616ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (EFI_ERROR (Status)) {
617ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    return Status;
618ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
619ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
620ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
6218908e764fe81677bd87a9cbad9dba6e16a15a450erictian  // Test to see if this ATA Pass Thru Protocol is for a LOGICAL channel
6228908e764fe81677bd87a9cbad9dba6e16a15a450erictian  //
6238908e764fe81677bd87a9cbad9dba6e16a15a450erictian  if ((AtaPassThru->Mode->Attributes & EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL) == 0) {
6248908e764fe81677bd87a9cbad9dba6e16a15a450erictian    //
6258908e764fe81677bd87a9cbad9dba6e16a15a450erictian    // Close the I/O Abstraction(s) used to perform the supported test
6268908e764fe81677bd87a9cbad9dba6e16a15a450erictian    //
6278908e764fe81677bd87a9cbad9dba6e16a15a450erictian    gBS->CloseProtocol (
6288908e764fe81677bd87a9cbad9dba6e16a15a450erictian          Controller,
6298908e764fe81677bd87a9cbad9dba6e16a15a450erictian          &gEfiAtaPassThruProtocolGuid,
6308908e764fe81677bd87a9cbad9dba6e16a15a450erictian          This->DriverBindingHandle,
6318908e764fe81677bd87a9cbad9dba6e16a15a450erictian          Controller
6328908e764fe81677bd87a9cbad9dba6e16a15a450erictian          );
6338908e764fe81677bd87a9cbad9dba6e16a15a450erictian    return EFI_UNSUPPORTED;
6348908e764fe81677bd87a9cbad9dba6e16a15a450erictian  }
6358908e764fe81677bd87a9cbad9dba6e16a15a450erictian
6368908e764fe81677bd87a9cbad9dba6e16a15a450erictian  //
637ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  // Test RemainingDevicePath is valid or not.
638ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
639ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {
640ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    Status = AtaPassThru->GetDevice (AtaPassThru, RemainingDevicePath, &Port, &PortMultiplierPort);
641ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    if (EFI_ERROR (Status)) {
6428908e764fe81677bd87a9cbad9dba6e16a15a450erictian      //
6438908e764fe81677bd87a9cbad9dba6e16a15a450erictian      // Close the I/O Abstraction(s) used to perform the supported test
6448908e764fe81677bd87a9cbad9dba6e16a15a450erictian      //
6458908e764fe81677bd87a9cbad9dba6e16a15a450erictian      gBS->CloseProtocol (
6468908e764fe81677bd87a9cbad9dba6e16a15a450erictian            Controller,
6478908e764fe81677bd87a9cbad9dba6e16a15a450erictian            &gEfiAtaPassThruProtocolGuid,
6488908e764fe81677bd87a9cbad9dba6e16a15a450erictian            This->DriverBindingHandle,
6498908e764fe81677bd87a9cbad9dba6e16a15a450erictian            Controller
6508908e764fe81677bd87a9cbad9dba6e16a15a450erictian            );
651ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      return Status;
652ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    }
653ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
654ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
655ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
656ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  // Close the I/O Abstraction(s) used to perform the supported test
657ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
658ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  gBS->CloseProtocol (
659ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        Controller,
660ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        &gEfiAtaPassThruProtocolGuid,
661ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        This->DriverBindingHandle,
662ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        Controller
663ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        );
664ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
665ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
666ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  // Open the EFI Device Path protocol needed to perform the supported test
667ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
668ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Status = gBS->OpenProtocol (
669ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  Controller,
670ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &gEfiDevicePathProtocolGuid,
671ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  (VOID **) &ParentDevicePath,
672ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  This->DriverBindingHandle,
673ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  Controller,
674ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
675ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  );
676ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  return Status;
677ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
678ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
679ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
680ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
681ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Starts a device controller or a bus controller.
682ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
683ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  The Start() function is designed to be invoked from the EFI boot service ConnectController().
68458727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  As a result, much of the error checking on the parameters to Start() has been moved into this
68558727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  common boot service. It is legal to call Start() from other locations,
686ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  but the following calling restrictions must be followed or the system behavior will not be deterministic.
687ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  1. ControllerHandle must be a valid EFI_HANDLE.
688ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
689ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang     EFI_DEVICE_PATH_PROTOCOL.
690ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  3. Prior to calling Start(), the Supported() function for the driver specified by This must
69158727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
692ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
693ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
69458727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @param[in]  ControllerHandle     The handle of the controller to start. This handle
69558727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                                   must support a protocol interface that supplies
696ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                   an I/O abstraction to the driver.
69758727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
69858727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                                   parameter is ignored by device drivers, and is optional for bus
69958727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                                   drivers. For a bus driver, if this parameter is NULL, then handles
700490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                                   for all the children of Controller are created by this driver.
70158727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                                   If this parameter is not NULL and the first Device Path Node is
70258727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                                   not the End of Device Path Node, then only the handle for the
70358727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                                   child device specified by the first Device Path Node of
704ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                   RemainingDevicePath is created by this driver.
70558727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                                   If the first Device Path Node of RemainingDevicePath is
706ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                   the End of Device Path Node, no child handle is created by this
707ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                   driver.
708ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
709ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS              The device was started.
710ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
711ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
712ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval Others                   The driver failded to start the device.
713ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
714ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
715ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
716ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFIAPI
717ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangAtaBusDriverBindingStart (
718ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
719ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN EFI_HANDLE                   Controller,
720ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
721ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
722ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
723ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_STATUS                        Status;
724ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_ATA_PASS_THRU_PROTOCOL        *AtaPassThru;
725ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;
726ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  ATA_BUS_DRIVER_DATA               *AtaBusDriverData;
727ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  UINT16                            Port;
728ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  UINT16                            PortMultiplierPort;
729ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
730ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  AtaBusDriverData = NULL;
731ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
732ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Status = gBS->OpenProtocol (
733ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  Controller,
734ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &gEfiDevicePathProtocolGuid,
735ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  (VOID **) &ParentDevicePath,
736ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  This->DriverBindingHandle,
737ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  Controller,
738ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
739ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  );
740ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (EFI_ERROR (Status)) {
741ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    return Status;
742ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
743ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
74437623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin  //
74537623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin  // Report Status Code to indicate ATA bus starts
74637623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin  //
74737623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
74837623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    EFI_PROGRESS_CODE,
74937623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_INIT),
75037623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    ParentDevicePath
75137623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    );
75237623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin
753ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Status = gBS->OpenProtocol (
754ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  Controller,
755ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  &gEfiAtaPassThruProtocolGuid,
756ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  (VOID **) &AtaPassThru,
757ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  This->DriverBindingHandle,
758ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  Controller,
759ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  EFI_OPEN_PROTOCOL_BY_DRIVER
760ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                  );
761ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
762ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    goto ErrorExit;
763ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
764ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
765ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
766ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  // Check EFI_ALREADY_STARTED to reuse the original ATA_BUS_DRIVER_DATA.
767ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
768ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (Status != EFI_ALREADY_STARTED) {
769ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    AtaBusDriverData = AllocateZeroPool (sizeof (ATA_BUS_DRIVER_DATA));
770ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    if (AtaBusDriverData == NULL) {
771ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      Status = EFI_OUT_OF_RESOURCES;
772ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      goto ErrorExit;
773ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    }
774ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
775ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    AtaBusDriverData->AtaPassThru = AtaPassThru;
776490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    AtaBusDriverData->Controller  = Controller;
777ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    AtaBusDriverData->ParentDevicePath = ParentDevicePath;
778ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    AtaBusDriverData->DriverBindingHandle = This->DriverBindingHandle;
779ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
780ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    Status = gBS->InstallMultipleProtocolInterfaces (
781ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    &Controller,
782ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    &gEfiCallerIdGuid,
783ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    AtaBusDriverData,
784ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    NULL
785ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    );
786ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    if (EFI_ERROR (Status)) {
787ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      goto ErrorExit;
788ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    }
789ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
790ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  } else {
791ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    Status = gBS->OpenProtocol (
792ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    Controller,
793ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    &gEfiCallerIdGuid,
794ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    (VOID **) &AtaBusDriverData,
795ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    This->DriverBindingHandle,
796ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    Controller,
797ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
798ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    );
799ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    if (EFI_ERROR (Status)) {
800ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      AtaBusDriverData = NULL;
801ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      goto ErrorExit;
802ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    }
803ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
804ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
80537623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin  //
80637623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin  // Report Status Code to indicate detecting devices on bus
80737623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin  //
80837623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
80937623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    EFI_PROGRESS_CODE,
81037623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_DETECT),
81137623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    ParentDevicePath
81237623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    );
81337623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin
814ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (RemainingDevicePath == NULL) {
815ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    Port = 0xFFFF;
816ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    while (TRUE) {
817ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      Status = AtaPassThru->GetNextPort (AtaPassThru, &Port);
818ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      if (EFI_ERROR (Status)) {
819ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        //
820ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        // We cannot find more legal port then we are done.
821ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        //
822ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        break;
823ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      }
824490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
825ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      PortMultiplierPort = 0xFFFF;
826ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      while (TRUE) {
827ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        Status = AtaPassThru->GetNextDevice (AtaPassThru, Port, &PortMultiplierPort);
828ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        if (EFI_ERROR (Status)) {
829ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          //
830ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          // We cannot find more legal port multiplier port number for ATA device
831ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          // on the port, then we are done.
832ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          //
833ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          break;
834ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        }
835ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        RegisterAtaDevice (AtaBusDriverData, Port, PortMultiplierPort);
836ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      }
837ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    }
838ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    Status = EFI_SUCCESS;
839ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  } else if (!IsDevicePathEnd (RemainingDevicePath)) {
840ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    Status = AtaPassThru->GetDevice (AtaPassThru, RemainingDevicePath, &Port, &PortMultiplierPort);
841ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    if (!EFI_ERROR (Status)) {
842ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      Status = RegisterAtaDevice (AtaBusDriverData,Port, PortMultiplierPort);
843ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    }
844ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
845490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
846ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  return Status;
847ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
848ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangErrorExit:
849ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
850ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (AtaBusDriverData != NULL) {
851ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    gBS->UninstallMultipleProtocolInterfaces (
852ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang           Controller,
853ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang           &gEfiCallerIdGuid,
854ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang           AtaBusDriverData,
855ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang           NULL
856ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang           );
857ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    FreePool (AtaBusDriverData);
858ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
859ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
860ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  gBS->CloseProtocol (
861ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        Controller,
862ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        &gEfiAtaPassThruProtocolGuid,
863ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        This->DriverBindingHandle,
864ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        Controller
865ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang        );
866ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
867ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  return Status;
868ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
869ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
870ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
871ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
872ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
873ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Stops a device controller or a bus controller.
87458727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang
87558727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
87658727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  As a result, much of the error checking on the parameters to Stop() has been moved
87758727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  into this common boot service. It is legal to call Stop() from other locations,
878ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  but the following calling restrictions must be followed or the system behavior will not be deterministic.
879ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
880ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang     same driver's Start() function.
881ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
882ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang     EFI_HANDLE. In addition, all of these handles must have been created in this driver's
883ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang     Start() function, and the Start() function must have called OpenProtocol() on
884ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
88558727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang
886ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
88758727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
88858727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                                support a bus specific I/O protocol for the driver
889ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                to use to stop the device.
890ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
89158727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
892ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                if NumberOfChildren is 0.
893ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
894ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS           The device was stopped.
895ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
896ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
897ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
898ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
899ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFIAPI
900ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangAtaBusDriverBindingStop (
901ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
902ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  EFI_HANDLE                      Controller,
903ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  UINTN                           NumberOfChildren,
904ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  EFI_HANDLE                      *ChildHandleBuffer
905ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
906ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
907ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_STATUS                  Status;
908ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  BOOLEAN                     AllChildrenStopped;
909ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  UINTN                       Index;
910ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  ATA_BUS_DRIVER_DATA         *AtaBusDriverData;
911ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
912ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (NumberOfChildren == 0) {
913ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    Status = gBS->OpenProtocol (
914ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    Controller,
915ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    &gEfiCallerIdGuid,
916ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    (VOID **) &AtaBusDriverData,
917ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    This->DriverBindingHandle,
918ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    Controller,
919ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
920ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                    );
921ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    if (!EFI_ERROR (Status)) {
922ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      gBS->UninstallMultipleProtocolInterfaces (
923ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang            Controller,
924ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang            &gEfiCallerIdGuid,
925ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang            AtaBusDriverData,
926ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang            NULL
927ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang            );
928ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      FreePool (AtaBusDriverData);
929ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    }
930ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
931ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    gBS->CloseProtocol (
932ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          Controller,
933ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          &gEfiAtaPassThruProtocolGuid,
934ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          This->DriverBindingHandle,
935ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          Controller
936ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang          );
937ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
938ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    return EFI_SUCCESS;
939ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
940ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
941ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  AllChildrenStopped = TRUE;
942ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
943ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  for (Index = 0; Index < NumberOfChildren; Index++) {
944ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
945ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    Status = UnregisterAtaDevice (This, Controller, ChildHandleBuffer[Index]);
946ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    if (EFI_ERROR (Status)) {
947ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang      AllChildrenStopped = FALSE;
948ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    }
949ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
950ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
951ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (!AllChildrenStopped) {
952ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    return EFI_DEVICE_ERROR;
953ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
954ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
955ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  return EFI_SUCCESS;
956ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
957ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
958ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
959ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
960ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Reset the Block Device.
961ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
962ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  This                 Indicates a pointer to the calling context.
963ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  ExtendedVerification Driver may perform diagnostics on reset.
964ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
965ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS          The device was reset.
966ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could
967ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                               not be reset.
968ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
969ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
970ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
971ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFIAPI
972ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangAtaBlockIoReset (
973ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  EFI_BLOCK_IO_PROTOCOL   *This,
974ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  BOOLEAN                 ExtendedVerification
975ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
976ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
977ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_STATUS      Status;
978ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  ATA_DEVICE      *AtaDevice;
979ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_TPL         OldTpl;
980ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
981ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
982ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
983ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (This);
984ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
985490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  Status = ResetAtaDevice (AtaDevice);
986ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
987c6e797aedafc09b241339587116f3fe51c41131aerictian  if (EFI_ERROR (Status)) {
988c6e797aedafc09b241339587116f3fe51c41131aerictian    Status = EFI_DEVICE_ERROR;
989c6e797aedafc09b241339587116f3fe51c41131aerictian  }
990c6e797aedafc09b241339587116f3fe51c41131aerictian
991ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  gBS->RestoreTPL (OldTpl);
992ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  return Status;
993ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
994ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
995ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
996ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
997ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Read/Write BufferSize bytes from Lba from/into Buffer.
998ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
999490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       This       Indicates a pointer to the calling context. Either be
100058727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang                              block I/O or block I/O2.
1001490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       MediaId    The media ID that the read/write request is for.
1002490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       Lba        The starting logical block address to be read/written.
1003490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                              The caller is responsible for reading/writing to only
1004490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                              legitimate locations.
1005490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in, out]  Token      A pointer to the token associated with the transaction.
1006490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       BufferSize Size of Buffer, must be a multiple of device block size.
1007490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[out]      Buffer     A pointer to the destination/source buffer for the data.
1008490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       IsBlockIo2 Indicate the calling is from BlockIO or BlockIO2. TURE is
1009490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                              from BlockIO2, FALSE is for BlockIO.
1010490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       IsWrite    Indicates whether it is a write operation.
1011ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1012ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS           The data was read/written correctly to the device.
1013ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_WRITE_PROTECTED   The device can not be read/written to.
1014ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_DEVICE_ERROR      The device reported an error while performing the read/write.
1015ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_NO_MEDIA          There is no media in the device.
1016ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.
1017ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
101858727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @retval EFI_INVALID_PARAMETER The read/write request contains LBAs that are not valid,
1019ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                or the buffer is not on proper alignment.
1020ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1021ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
1022ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
1023ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangBlockIoReadWrite (
1024490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN     VOID                    *This,
1025490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN     UINT32                  MediaId,
1026490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN     EFI_LBA                 Lba,
1027490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN OUT EFI_BLOCK_IO2_TOKEN     *Token,
1028490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN     UINTN                   BufferSize,
1029490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  OUT    VOID                    *Buffer,
1030490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN     BOOLEAN                 IsBlockIo2,
1031490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN     BOOLEAN                 IsWrite
1032ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
1033ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
1034ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  ATA_DEVICE                        *AtaDevice;
1035ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_STATUS                        Status;
1036ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_TPL                           OldTpl;
1037ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_BLOCK_IO_MEDIA                *Media;
1038ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  UINTN                             BlockSize;
1039ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  UINTN                             NumberOfBlocks;
1040ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  UINTN                             IoAlign;
1041ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1042490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  if (IsBlockIo2) {
1043490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang   Media     = ((EFI_BLOCK_IO2_PROTOCOL *) This)->Media;
1044490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang   AtaDevice = ATA_DEVICE_FROM_BLOCK_IO2 (This);
1045490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  } else {
1046490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang   Media     = ((EFI_BLOCK_IO_PROTOCOL *) This)->Media;
1047490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang   AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (This);
1048490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  }
1049490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1050fcf5e49dc912f27b77b50ddea3c6b7a4ba28717cniruiyu  if (MediaId != Media->MediaId) {
1051fcf5e49dc912f27b77b50ddea3c6b7a4ba28717cniruiyu    return EFI_MEDIA_CHANGED;
1052fcf5e49dc912f27b77b50ddea3c6b7a4ba28717cniruiyu  }
1053fcf5e49dc912f27b77b50ddea3c6b7a4ba28717cniruiyu
1054490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  //
1055490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  // Check parameters.
1056490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  //
1057ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (Buffer == NULL) {
1058ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    return EFI_INVALID_PARAMETER;
1059ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
1060ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1061ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (BufferSize == 0) {
1062bf5a9493fa9d7013015ac511714d4efdca23ae34Ruiyu Ni    if ((Token != NULL) && (Token->Event != NULL)) {
1063bf5a9493fa9d7013015ac511714d4efdca23ae34Ruiyu Ni      Token->TransactionStatus = EFI_SUCCESS;
1064bf5a9493fa9d7013015ac511714d4efdca23ae34Ruiyu Ni      gBS->SignalEvent (Token->Event);
1065bf5a9493fa9d7013015ac511714d4efdca23ae34Ruiyu Ni    }
1066ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    return EFI_SUCCESS;
106758727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  }
1068ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1069ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  BlockSize = Media->BlockSize;
1070ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if ((BufferSize % BlockSize) != 0) {
1071ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    return EFI_BAD_BUFFER_SIZE;
1072ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
107358727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang
1074ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  NumberOfBlocks  = BufferSize / BlockSize;
1075ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
1076ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    return EFI_INVALID_PARAMETER;
1077ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
1078ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1079ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IoAlign = Media->IoAlign;
1080ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  if (IoAlign > 0 && (((UINTN) Buffer & (IoAlign - 1)) != 0)) {
1081ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    return EFI_INVALID_PARAMETER;
1082ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
1083ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1084ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
108558727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang
1086ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
1087ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  // Invoke low level AtaDevice Access Routine.
1088ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
1089490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  Status = AccessAtaDevice (AtaDevice, Buffer, Lba, NumberOfBlocks, IsWrite, Token);
109058727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang
1091ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  gBS->RestoreTPL (OldTpl);
1092ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1093ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  return Status;
1094ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
1095ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1096ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1097ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
1098ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Read BufferSize bytes from Lba into Buffer.
1099ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1100ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  This       Indicates a pointer to the calling context.
1101ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  MediaId    Id of the media, changes every time the media is replaced.
1102ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  Lba        The starting Logical Block Address to read from
1103ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  BufferSize Size of Buffer, must be a multiple of device block size.
1104ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  Buffer     A pointer to the destination buffer for the data. The caller is
1105ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                     responsible for either having implicit or explicit ownership of the buffer.
1106ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1107ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS           The data was read correctly from the device.
1108ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_DEVICE_ERROR      The device reported an error while performing the read.
1109ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_NO_MEDIA          There is no media in the device.
1110ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_MEDIA_CHANGED     The MediaId does not matched the current device.
1111ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
111258727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
1113ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                or the buffer is not on proper alignment.
1114ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1115ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
1116ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
1117ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFIAPI
1118ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangAtaBlockIoReadBlocks (
1119ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  EFI_BLOCK_IO_PROTOCOL   *This,
1120ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  UINT32                  MediaId,
1121ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  EFI_LBA                 Lba,
1122ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  UINTN                   BufferSize,
1123ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  OUT VOID                    *Buffer
1124ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
1125ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
1126490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  return BlockIoReadWrite ((VOID *) This, MediaId, Lba, NULL, BufferSize, Buffer, FALSE, FALSE);
1127ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
1128ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1129ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1130ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
1131ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Write BufferSize bytes from Lba into Buffer.
1132ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1133ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  This       Indicates a pointer to the calling context.
1134ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  MediaId    The media ID that the write request is for.
1135ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  Lba        The starting logical block address to be written. The caller is
1136ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                     responsible for writing to only legitimate locations.
1137ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  BufferSize Size of Buffer, must be a multiple of device block size.
1138ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  Buffer     A pointer to the source buffer for the data.
1139ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1140ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS           The data was written correctly to the device.
1141ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_WRITE_PROTECTED   The device can not be written to.
1142ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
1143ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_NO_MEDIA          There is no media in the device.
1144ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.
1145ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
114658727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
1147ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                or the buffer is not on proper alignment.
1148ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1149ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
1150ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
1151ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFIAPI
1152ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangAtaBlockIoWriteBlocks (
1153ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  EFI_BLOCK_IO_PROTOCOL   *This,
1154ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  UINT32                  MediaId,
1155ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  EFI_LBA                 Lba,
1156ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  UINTN                   BufferSize,
1157ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  VOID                    *Buffer
1158ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
1159ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
1160490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  return BlockIoReadWrite ((VOID *) This, MediaId, Lba, NULL, BufferSize, Buffer, FALSE, TRUE);
1161ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
1162ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1163ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1164ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
1165ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Flush the Block Device.
1166ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1167ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param  This              Indicates a pointer to the calling context.
1168ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1169ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS       All outstanding data was written to the device
1170ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_DEVICE_ERROR  The device reported an error while writing back the data
1171ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_NO_MEDIA      There is no media in the device.
1172ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1173ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
1174ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
1175ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFIAPI
1176ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangAtaBlockIoFlushBlocks (
1177ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  EFI_BLOCK_IO_PROTOCOL   *This
1178ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
1179ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
1180ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
1181ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  // return directly
1182ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
1183ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  return EFI_SUCCESS;
1184ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
1185ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1186490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang/**
1187490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  Reset the Block Device.
1188490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1189490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]  This                 Indicates a pointer to the calling context.
1190490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]  ExtendedVerification Driver may perform diagnostics on reset.
1191490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1192490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_SUCCESS          The device was reset.
1193490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could
1194490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                               not be reset.
1195490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1196490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang**/
1197490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyangEFI_STATUS
1198490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyangEFIAPI
1199490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyangAtaBlockIoResetEx (
1200490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN  EFI_BLOCK_IO2_PROTOCOL  *This,
1201490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN  BOOLEAN                 ExtendedVerification
1202490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  )
1203490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang{
1204490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  EFI_STATUS      Status;
1205490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  ATA_DEVICE      *AtaDevice;
1206490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  EFI_TPL         OldTpl;
1207490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1208490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1209490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1210490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  AtaDevice = ATA_DEVICE_FROM_BLOCK_IO2 (This);
1211490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
121271fd9fae8bda10f41a9c6445f01eed82b99883daTian, Feng  AtaTerminateNonBlockingTask (AtaDevice);
121371fd9fae8bda10f41a9c6445f01eed82b99883daTian, Feng
1214490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  Status = ResetAtaDevice (AtaDevice);
1215490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1216490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  if (EFI_ERROR (Status)) {
1217490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    Status = EFI_DEVICE_ERROR;
1218490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  }
1219490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1220490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  gBS->RestoreTPL (OldTpl);
1221490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  return Status;
1222490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang}
1223490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1224490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang/**
1225490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  Read BufferSize bytes from Lba into Buffer.
1226490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1227490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       This       Indicates a pointer to the calling context.
1228490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       MediaId    Id of the media, changes every time the media is replaced.
1229490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       Lba        The starting Logical Block Address to read from.
1230490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in, out]  Token      A pointer to the token associated with the transaction.
1231490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       BufferSize Size of Buffer, must be a multiple of device block size.
1232490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[out]      Buffer     A pointer to the destination buffer for the data. The caller is
1233490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                              responsible for either having implicit or explicit ownership of the buffer.
1234490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1235490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_SUCCESS           The read request was queued if Event is not NULL.
1236490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                                The data was read correctly from the device if
1237490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                                the Event is NULL.
1238490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_DEVICE_ERROR      The device reported an error while performing
1239490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                                the read.
1240490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_NO_MEDIA          There is no media in the device.
1241490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_MEDIA_CHANGED     The MediaId is not for the current media.
1242490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_BAD_BUFFER_SIZE   The BufferSize parameter is not a multiple of the
1243490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                                intrinsic block size of the device.
124458727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
1245490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                                or the buffer is not on proper alignment.
1246490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack
1247490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                                of resources.
1248490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1249490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang**/
1250490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyangEFI_STATUS
1251490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyangEFIAPI
1252490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyangAtaBlockIoReadBlocksEx (
1253490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN  EFI_BLOCK_IO2_PROTOCOL  *This,
1254490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN  UINT32                  MediaId,
1255490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN  EFI_LBA                 Lba,
1256490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN OUT EFI_BLOCK_IO2_TOKEN  *Token,
1257490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN  UINTN                   BufferSize,
1258490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  OUT VOID                    *Buffer
1259490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  )
1260490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang{
1261490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  return BlockIoReadWrite ((VOID *) This, MediaId, Lba, Token, BufferSize, Buffer, TRUE, FALSE);
1262490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang}
1263490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1264490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1265490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang/**
1266490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  Write BufferSize bytes from Lba into Buffer.
1267490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1268490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       This       Indicates a pointer to the calling context.
1269490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       MediaId    The media ID that the write request is for.
1270490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       Lba        The starting logical block address to be written. The
1271490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                              caller is responsible for writing to only legitimate
1272490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                              locations.
1273490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in, out]  Token      A pointer to the token associated with the transaction.
1274490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       BufferSize Size of Buffer, must be a multiple of device block size.
1275490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       Buffer     A pointer to the source buffer for the data.
1276ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1277490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_SUCCESS           The data was written correctly to the device.
1278490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_WRITE_PROTECTED   The device can not be written to.
1279490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
1280490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_NO_MEDIA          There is no media in the device.
1281490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.
1282490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
128358727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
1284490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang                                or the buffer is not on proper alignment.
1285490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1286490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang**/
1287490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyangEFI_STATUS
1288490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyangEFIAPI
1289490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyangAtaBlockIoWriteBlocksEx (
1290490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN  EFI_BLOCK_IO2_PROTOCOL  *This,
1291490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN  UINT32                  MediaId,
1292490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN  EFI_LBA                 Lba,
1293490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN OUT EFI_BLOCK_IO2_TOKEN  *Token,
1294490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN  UINTN                   BufferSize,
1295490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN  VOID                    *Buffer
1296490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  )
1297490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang{
1298490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  return BlockIoReadWrite ((VOID *) This, MediaId, Lba, Token, BufferSize, Buffer, TRUE, TRUE);
1299490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang}
1300490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1301490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1302490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang/**
1303490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  Flush the Block Device.
1304490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1305490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in]       This       Indicates a pointer to the calling context.
1306490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @param[in, out]  Token      A pointer to the token associated with the transaction.
1307490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1308490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_SUCCESS       All outstanding data was written to the device
1309490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_DEVICE_ERROR  The device reported an error while writing back the data
1310490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  @retval EFI_NO_MEDIA      There is no media in the device.
1311490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang
1312490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang**/
1313490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyangEFI_STATUS
1314490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyangEFIAPI
1315490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyangAtaBlockIoFlushBlocksEx (
1316490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN  EFI_BLOCK_IO2_PROTOCOL  *This,
1317490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  IN OUT EFI_BLOCK_IO2_TOKEN  *Token
1318490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  )
1319490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang{
1320490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  //
13213c063fedc4bd816ef427065003dca41ba1f885d2erictian  // Signal event and return directly.
1322490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  //
1323490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  if (Token != NULL && Token->Event != NULL) {
1324490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    Token->TransactionStatus = EFI_SUCCESS;
1325490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang    gBS->SignalEvent (Token->Event);
1326490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  }
1327490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang  return EFI_SUCCESS;
1328490b5ea10bcdab3579d4c12056b177cea52d6f8eqianouyang}
1329ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
1330ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Provides inquiry information for the controller type.
133158727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang
1332ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  This function is used by the IDE bus driver to get inquiry data.  Data format
1333ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  of Identify data is defined by the Interface GUID.
1334ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
133505a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  @param[in]      This             Pointer to the EFI_DISK_INFO_PROTOCOL instance.
133605a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  @param[in, out] InquiryData      Pointer to a buffer for the inquiry data.
133705a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  @param[in, out] InquiryDataSize  Pointer to the value for the inquiry data size.
1338ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1339ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS            The command was accepted without any errors.
134058727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @retval EFI_NOT_FOUND          Device does not support this data class
134158727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @retval EFI_DEVICE_ERROR       Error reading InquiryData from device
134258727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @retval EFI_BUFFER_TOO_SMALL   InquiryDataSize not big enough
1343ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1344ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
1345ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
1346ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFIAPI
1347ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangAtaDiskInfoInquiry (
1348ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN     EFI_DISK_INFO_PROTOCOL   *This,
1349ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN OUT VOID                     *InquiryData,
1350ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN OUT UINT32                   *InquiryDataSize
1351ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
1352ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
1353ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  return EFI_NOT_FOUND;
1354ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
1355ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1356ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1357ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
1358ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Provides identify information for the controller type.
1359ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1360ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  This function is used by the IDE bus driver to get identify data.  Data format
1361ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  of Identify data is defined by the Interface GUID.
1362ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
136358727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @param[in]      This              Pointer to the EFI_DISK_INFO_PROTOCOL
1364ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                    instance.
136505a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  @param[in, out] IdentifyData      Pointer to a buffer for the identify data.
136605a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  @param[in, out] IdentifyDataSize  Pointer to the value for the identify data
1367ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang                                    size.
1368ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1369ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS            The command was accepted without any errors.
137058727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @retval EFI_NOT_FOUND          Device does not support this data class
137158727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @retval EFI_DEVICE_ERROR       Error reading IdentifyData from device
137258727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @retval EFI_BUFFER_TOO_SMALL   IdentifyDataSize not big enough
1373ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1374ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
1375ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
1376ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFIAPI
1377ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangAtaDiskInfoIdentify (
1378ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN     EFI_DISK_INFO_PROTOCOL   *This,
1379ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN OUT VOID                     *IdentifyData,
1380ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN OUT UINT32                   *IdentifyDataSize
1381ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
1382ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
1383ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_STATUS                      Status;
1384ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  ATA_DEVICE                      *AtaDevice;
1385ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1386ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  AtaDevice = ATA_DEVICE_FROM_DISK_INFO (This);
1387ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1388ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Status = EFI_BUFFER_TOO_SMALL;
13893c063fedc4bd816ef427065003dca41ba1f885d2erictian  if (*IdentifyDataSize >= sizeof (ATA_IDENTIFY_DATA)) {
1390ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang    Status = EFI_SUCCESS;
13913c063fedc4bd816ef427065003dca41ba1f885d2erictian    CopyMem (IdentifyData, AtaDevice->IdentifyData, sizeof (ATA_IDENTIFY_DATA));
1392ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  }
13933c063fedc4bd816ef427065003dca41ba1f885d2erictian  *IdentifyDataSize = sizeof (ATA_IDENTIFY_DATA);
1394ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1395ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  return Status;
1396ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
1397ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1398ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1399ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
1400ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Provides sense data information for the controller type.
140158727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang
140258727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  This function is used by the IDE bus driver to get sense data.
1403ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Data format of Sense data is defined by the Interface GUID.
1404ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
140505a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  @param[in]      This             Pointer to the EFI_DISK_INFO_PROTOCOL instance.
140605a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  @param[in, out] SenseData        Pointer to the SenseData.
140705a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  @param[in, out] SenseDataSize    Size of SenseData in bytes.
140805a44e91fe0158ebd043cf878ca3c5320a07dcbaqhuang  @param[out]     SenseDataNumber  Pointer to the value for the sense data size.
1409ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1410ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS            The command was accepted without any errors.
1411ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_NOT_FOUND          Device does not support this data class.
1412ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_DEVICE_ERROR       Error reading SenseData from device.
1413ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_BUFFER_TOO_SMALL   SenseDataSize not big enough.
1414ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1415ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
1416ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
1417ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFIAPI
1418ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangAtaDiskInfoSenseData (
1419ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN     EFI_DISK_INFO_PROTOCOL   *This,
1420ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN OUT VOID                     *SenseData,
1421ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN OUT UINT32                   *SenseDataSize,
1422ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  OUT    UINT8                    *SenseDataNumber
1423ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
1424ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
1425ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  return EFI_NOT_FOUND;
1426ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
1427ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1428ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1429ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
1430ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  This function is used by the IDE bus driver to get controller information.
1431ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
143258727f29ea4da2618e18a0c0d5c819f29badaf26qianouyang  @param[in]  This         Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1433ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param[out] IdeChannel   Pointer to the Ide Channel number.  Primary or secondary.
1434ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param[out] IdeDevice    Pointer to the Ide Device number.  Master or slave.
1435ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1436ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS       IdeChannel and IdeDevice are valid.
1437ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_UNSUPPORTED   This is not an IDE device.
1438ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1439ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
1440ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
1441ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFIAPI
1442ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangAtaDiskInfoWhichIde (
1443ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN  EFI_DISK_INFO_PROTOCOL   *This,
1444ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  OUT UINT32                   *IdeChannel,
1445ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  OUT UINT32                   *IdeDevice
1446ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
1447ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
1448ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  ATA_DEVICE                   *AtaDevice;
1449ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1450ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  AtaDevice       = ATA_DEVICE_FROM_DISK_INFO (This);
1451ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  *IdeChannel     = AtaDevice->Port;
1452ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  *IdeDevice      = AtaDevice->PortMultiplierPort;
1453ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1454ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  return EFI_SUCCESS;
1455ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
1456ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1457c24097a59ffb10d63c805c4da65476ed6e297c5chhuan/**
1458c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  Send a security protocol command to a device that receives data and/or the result
1459c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  of one or more commands sent by SendData.
1460c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1461c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  The ReceiveData function sends a security protocol command to the given MediaId.
1462c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  The security protocol command sent is defined by SecurityProtocolId and contains
1463c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  the security protocol specific data SecurityProtocolSpecificData. The function
1464c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  returns the data from the security protocol command in PayloadBuffer.
1465c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1466c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  For devices supporting the SCSI command set, the security protocol command is sent
1467c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  using the SECURITY PROTOCOL IN command defined in SPC-4.
1468c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1469c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  For devices supporting the ATA command set, the security protocol command is sent
1470c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize
1471c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  is non-zero.
1472c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1473c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  If the PayloadBufferSize is zero, the security protocol command is sent using the
1474c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  Trusted Non-Data command defined in ATA8-ACS.
1475c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1476c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  If PayloadBufferSize is too small to store the available data from the security
1477c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  protocol command, the function shall copy PayloadBufferSize bytes into the
1478c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.
1479c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1480c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero,
1481c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  the function shall return EFI_INVALID_PARAMETER.
1482c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1483c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  If the given MediaId does not support security protocol commands, the function shall
1484c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  return EFI_UNSUPPORTED. If there is no media in the device, the function returns
1485c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device,
1486c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  the function returns EFI_MEDIA_CHANGED.
1487c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1488c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  If the security protocol fails to complete within the Timeout period, the function
1489c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  shall return EFI_TIMEOUT.
1490c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1491c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  If the security protocol command completes without an error, the function shall
1492c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  return EFI_SUCCESS. If the security protocol command completes with an error, the
1493c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  function shall return EFI_DEVICE_ERROR.
1494c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1495c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  This                         Indicates a pointer to the calling context.
1496c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  MediaId                      ID of the medium to receive data from.
1497c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  Timeout                      The timeout, in 100ns units, to use for the execution
1498c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       of the security protocol command. A Timeout value of 0
1499c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       means that this function will wait indefinitely for the
1500c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       security protocol command to execute. If Timeout is greater
1501c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       than zero, then this function will return EFI_TIMEOUT
1502c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       if the time required to execute the receive data command
1503c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       is greater than Timeout.
1504c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  SecurityProtocolId           The value of the "Security Protocol" parameter of
1505c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       the security protocol command to be sent.
1506c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
1507c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       of the security protocol command to be sent.
1508c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  PayloadBufferSize            Size in bytes of the payload data buffer.
1509c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  PayloadBuffer                A pointer to a destination buffer to store the security
1510c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       protocol command specific payload data for the security
1511c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       protocol command. The caller is responsible for having
1512c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       either implicit or explicit ownership of the buffer.
1513c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  PayloadTransferSize          A pointer to a buffer to store the size in bytes of the
1514c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       data written to the payload data buffer.
1515c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1516c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_SUCCESS                  The security protocol command completed successfully.
1517c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_WARN_BUFFER_TOO_SMALL    The PayloadBufferSize was too small to store the available
1518c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       data from the device. The PayloadBuffer contains the truncated data.
1519c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_UNSUPPORTED              The given MediaId does not support security protocol commands.
1520c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_DEVICE_ERROR             The security protocol command completed with an error.
1521c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_NO_MEDIA                 There is no media in the device.
1522c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_MEDIA_CHANGED            The MediaId is not for the current media.
1523c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_INVALID_PARAMETER        The PayloadBuffer or PayloadTransferSize is NULL and
1524c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       PayloadBufferSize is non-zero.
1525c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_TIMEOUT                  A timeout occurred while waiting for the security
1526c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       protocol command to execute.
1527c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1528c24097a59ffb10d63c805c4da65476ed6e297c5chhuan**/
1529c24097a59ffb10d63c805c4da65476ed6e297c5chhuanEFI_STATUS
1530c24097a59ffb10d63c805c4da65476ed6e297c5chhuanEFIAPI
1531c24097a59ffb10d63c805c4da65476ed6e297c5chhuanAtaStorageSecurityReceiveData (
1532c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL    *This,
1533c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  IN UINT32                                   MediaId,
1534c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  IN UINT64                                   Timeout,
1535c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  IN UINT8                                    SecurityProtocolId,
1536c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  IN UINT16                                   SecurityProtocolSpecificData,
1537c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  IN UINTN                                    PayloadBufferSize,
1538c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  OUT VOID                                    *PayloadBuffer,
1539c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  OUT UINTN                                   *PayloadTransferSize
1540c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  )
1541c24097a59ffb10d63c805c4da65476ed6e297c5chhuan{
1542c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  EFI_STATUS                       Status;
1543c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  ATA_DEVICE                       *Private;
15443c063fedc4bd816ef427065003dca41ba1f885d2erictian  EFI_TPL                          OldTpl;
1545c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1546857ce453d4c5fa18b03a334e9bf043276b8f6dd4Tian Feng  DEBUG ((EFI_D_INFO, "EFI Storage Security Protocol - Read\n"));
1547c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  if ((PayloadBuffer == NULL || PayloadTransferSize == NULL) && PayloadBufferSize != 0) {
1548c24097a59ffb10d63c805c4da65476ed6e297c5chhuan    return EFI_INVALID_PARAMETER;
1549c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  }
1550c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1551c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  Status  = EFI_SUCCESS;
1552c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  Private = ATA_DEVICE_FROM_STORAGE_SECURITY (This);
1553c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1554c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  if (MediaId != Private->BlockIo.Media->MediaId) {
1555c24097a59ffb10d63c805c4da65476ed6e297c5chhuan    return EFI_MEDIA_CHANGED;
1556c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  }
1557c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1558c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  if (!Private->BlockIo.Media->MediaPresent) {
1559c24097a59ffb10d63c805c4da65476ed6e297c5chhuan    return EFI_NO_MEDIA;
1560c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  }
1561c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
15623c063fedc4bd816ef427065003dca41ba1f885d2erictian  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
15633c063fedc4bd816ef427065003dca41ba1f885d2erictian
1564c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  Status = TrustTransferAtaDevice (
1565c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             Private,
1566c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             PayloadBuffer,
1567c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             SecurityProtocolId,
1568c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             SecurityProtocolSpecificData,
1569c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             PayloadBufferSize,
1570c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             FALSE,
1571c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             Timeout,
1572c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             PayloadTransferSize
1573c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             );
1574c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
15753c063fedc4bd816ef427065003dca41ba1f885d2erictian  gBS->RestoreTPL (OldTpl);
1576c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  return Status;
1577c24097a59ffb10d63c805c4da65476ed6e297c5chhuan}
1578c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1579c24097a59ffb10d63c805c4da65476ed6e297c5chhuan/**
1580c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  Send a security protocol command to a device.
1581c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1582c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  The SendData function sends a security protocol command containing the payload
1583c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  PayloadBuffer to the given MediaId. The security protocol command sent is
1584c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  defined by SecurityProtocolId and contains the security protocol specific data
1585c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  SecurityProtocolSpecificData. If the underlying protocol command requires a
1586c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  specific padding for the command payload, the SendData function shall add padding
1587c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  bytes to the command payload to satisfy the padding requirements.
1588c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1589c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  For devices supporting the SCSI command set, the security protocol command is sent
1590c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  using the SECURITY PROTOCOL OUT command defined in SPC-4.
1591c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1592c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  For devices supporting the ATA command set, the security protocol command is sent
1593c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize
1594c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  is non-zero. If the PayloadBufferSize is zero, the security protocol command is
1595c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  sent using the Trusted Non-Data command defined in ATA8-ACS.
1596c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1597c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall
1598c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  return EFI_INVALID_PARAMETER.
1599c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1600c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  If the given MediaId does not support security protocol commands, the function
1601c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  shall return EFI_UNSUPPORTED. If there is no media in the device, the function
1602c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the
1603c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  device, the function returns EFI_MEDIA_CHANGED.
1604c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1605c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  If the security protocol fails to complete within the Timeout period, the function
1606c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  shall return EFI_TIMEOUT.
1607c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1608c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  If the security protocol command completes without an error, the function shall return
1609c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  EFI_SUCCESS. If the security protocol command completes with an error, the function
1610c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  shall return EFI_DEVICE_ERROR.
1611c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1612c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  This                         Indicates a pointer to the calling context.
1613c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  MediaId                      ID of the medium to receive data from.
1614c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  Timeout                      The timeout, in 100ns units, to use for the execution
1615c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       of the security protocol command. A Timeout value of 0
1616c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       means that this function will wait indefinitely for the
1617c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       security protocol command to execute. If Timeout is greater
1618c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       than zero, then this function will return EFI_TIMEOUT
1619c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       if the time required to execute the receive data command
1620c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       is greater than Timeout.
1621c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  SecurityProtocolId           The value of the "Security Protocol" parameter of
1622c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       the security protocol command to be sent.
1623c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
1624c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       of the security protocol command to be sent.
1625c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  PayloadBufferSize            Size in bytes of the payload data buffer.
1626c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @param  PayloadBuffer                A pointer to a destination buffer to store the security
1627c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       protocol command specific payload data for the security
1628c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       protocol command.
1629c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1630c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_SUCCESS                  The security protocol command completed successfully.
1631c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_UNSUPPORTED              The given MediaId does not support security protocol commands.
1632c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_DEVICE_ERROR             The security protocol command completed with an error.
1633c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_NO_MEDIA                 There is no media in the device.
1634c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_MEDIA_CHANGED            The MediaId is not for the current media.
1635c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_INVALID_PARAMETER        The PayloadBuffer is NULL and PayloadBufferSize is non-zero.
1636c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  @retval EFI_TIMEOUT                  A timeout occurred while waiting for the security
1637c24097a59ffb10d63c805c4da65476ed6e297c5chhuan                                       protocol command to execute.
1638c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1639c24097a59ffb10d63c805c4da65476ed6e297c5chhuan**/
1640c24097a59ffb10d63c805c4da65476ed6e297c5chhuanEFI_STATUS
1641c24097a59ffb10d63c805c4da65476ed6e297c5chhuanEFIAPI
1642c24097a59ffb10d63c805c4da65476ed6e297c5chhuanAtaStorageSecuritySendData (
1643c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL    *This,
1644c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  IN UINT32                                   MediaId,
1645c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  IN UINT64                                   Timeout,
1646c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  IN UINT8                                    SecurityProtocolId,
1647c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  IN UINT16                                   SecurityProtocolSpecificData,
1648c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  IN UINTN                                    PayloadBufferSize,
1649c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  IN VOID                                     *PayloadBuffer
1650c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  )
1651c24097a59ffb10d63c805c4da65476ed6e297c5chhuan{
1652c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  EFI_STATUS                       Status;
1653c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  ATA_DEVICE                       *Private;
16543c063fedc4bd816ef427065003dca41ba1f885d2erictian  EFI_TPL                          OldTpl;
1655c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1656857ce453d4c5fa18b03a334e9bf043276b8f6dd4Tian Feng  DEBUG ((EFI_D_INFO, "EFI Storage Security Protocol - Send\n"));
1657c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  if ((PayloadBuffer == NULL) && (PayloadBufferSize != 0)) {
1658c24097a59ffb10d63c805c4da65476ed6e297c5chhuan    return EFI_INVALID_PARAMETER;
1659c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  }
1660c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1661c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  Status  = EFI_SUCCESS;
1662c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  Private = ATA_DEVICE_FROM_STORAGE_SECURITY (This);
1663c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
1664c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  if (MediaId != Private->BlockIo.Media->MediaId) {
1665c24097a59ffb10d63c805c4da65476ed6e297c5chhuan    return EFI_MEDIA_CHANGED;
1666c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  }
1667c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
16683c063fedc4bd816ef427065003dca41ba1f885d2erictian  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1669c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  Status = TrustTransferAtaDevice (
1670c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             Private,
1671c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             PayloadBuffer,
1672c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             SecurityProtocolId,
1673c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             SecurityProtocolSpecificData,
1674c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             PayloadBufferSize,
1675c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             TRUE,
1676c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             Timeout,
1677c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             NULL
1678c24097a59ffb10d63c805c4da65476ed6e297c5chhuan             );
1679c24097a59ffb10d63c805c4da65476ed6e297c5chhuan
16803c063fedc4bd816ef427065003dca41ba1f885d2erictian  gBS->RestoreTPL (OldTpl);
1681c24097a59ffb10d63c805c4da65476ed6e297c5chhuan  return Status;
1682c24097a59ffb10d63c805c4da65476ed6e297c5chhuan}
1683ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1684ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang/**
1685ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  The user Entry Point for module AtaBus. The user code starts with this function.
1686ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1687ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
1688ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @param[in] SystemTable    A pointer to the EFI System Table.
1689ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1690ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval EFI_SUCCESS       The entry point is executed successfully.
1691ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  @retval other             Some error occurs when executing this entry point.
1692ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1693ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang**/
1694ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFI_STATUS
1695ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangEFIAPI
1696ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuangInitializeAtaBus(
1697ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN EFI_HANDLE           ImageHandle,
1698ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  IN EFI_SYSTEM_TABLE     *SystemTable
1699ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  )
1700ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang{
1701ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  EFI_STATUS              Status;
1702ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1703ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
1704ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  // Install driver model protocol(s).
1705ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  //
1706ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  Status = EfiLibInstallDriverBindingComponentName2 (
1707ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             ImageHandle,
1708ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             SystemTable,
1709ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             &gAtaBusDriverBinding,
1710ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             ImageHandle,
1711ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             &gAtaBusComponentName,
1712ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             &gAtaBusComponentName2
1713ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang             );
1714ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  ASSERT_EFI_ERROR (Status);
1715ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang
1716ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang  return Status;
1717ad86a50ae7fb2ef9db89b22e0b94d54748ffb24fqhuang}
171890398d5558431b733a97ba7e3a2fddcd5f0858f5qianouyang
1719