]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBus.c
Introduce tow non-blocking task lists to AtaBus. One maintains the sub-task which...
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AtaBusDxe / AtaBus.c
CommitLineData
ad86a50a 1/** @file\r
2 This file implements protocol interfaces for ATA bus driver.\r
58727f29 3\r
ad86a50a 4 This file implements protocol interfaces: Driver Binding protocol,\r
5 Block IO protocol and DiskInfo protocol.\r
58727f29 6\r
7 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
cd5ebaa0 8 This program and the accompanying materials\r
ad86a50a 9 are licensed and made available under the terms and conditions of the BSD License\r
10 which accompanies this distribution. The full text of the license may be found at\r
11 http://opensource.org/licenses/bsd-license.php\r
12\r
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16\r
17**/\r
18\r
19#include "AtaBus.h"\r
20\r
21//\r
22// ATA Bus Driver Binding Protocol Instance\r
23//\r
24EFI_DRIVER_BINDING_PROTOCOL gAtaBusDriverBinding = {\r
25 AtaBusDriverBindingSupported,\r
26 AtaBusDriverBindingStart,\r
27 AtaBusDriverBindingStop,\r
28 0x10,\r
29 NULL,\r
30 NULL\r
31};\r
32\r
33//\r
34// Template for ATA Child Device.\r
35//\r
36ATA_DEVICE gAtaDeviceTemplate = {\r
05a44e91 37 ATA_DEVICE_SIGNATURE, // Signature\r
38 NULL, // Handle\r
ad86a50a 39 { // BlockIo\r
40 EFI_BLOCK_IO_PROTOCOL_REVISION,\r
41 NULL,\r
42 AtaBlockIoReset,\r
43 AtaBlockIoReadBlocks,\r
44 AtaBlockIoWriteBlocks,\r
45 AtaBlockIoFlushBlocks\r
46 },\r
490b5ea1 47 { // BlockIo2\r
48 NULL,\r
49 AtaBlockIoResetEx,\r
50 AtaBlockIoReadBlocksEx,\r
51 AtaBlockIoWriteBlocksEx,\r
52 AtaBlockIoFlushBlocksEx\r
53 },\r
ad86a50a 54 { // BlockMedia\r
55 0, // MediaId\r
56 FALSE, // RemovableMedia\r
57 TRUE, // MediaPresent\r
58 FALSE, // LogicPartition\r
59 FALSE, // ReadOnly\r
60 FALSE, // WritingCache\r
58727f29 61 0x200, // BlockSize\r
907c1a00 62 0, // IoAlign\r
3bfa77f0 63 0, // LastBlock\r
64 0, // LowestAlignedLba\r
65 1 // LogicalBlocksPerPhysicalBlock\r
ad86a50a 66 },\r
67 { // DiskInfo\r
68 EFI_DISK_INFO_IDE_INTERFACE_GUID,\r
69 AtaDiskInfoInquiry,\r
70 AtaDiskInfoIdentify,\r
71 AtaDiskInfoSenseData,\r
72 AtaDiskInfoWhichIde\r
73 },\r
05a44e91 74 NULL, // DevicePath\r
c24097a5 75 {\r
76 AtaStorageSecurityReceiveData,\r
77 AtaStorageSecuritySendData\r
78 },\r
05a44e91 79 NULL, // AtaBusDriverData\r
80 0, // Port\r
81 0, // PortMultiplierPort\r
ad86a50a 82 { 0, }, // Packet\r
83 {{ 0}, }, // Acb\r
84 NULL, // Asb\r
85 FALSE, // UdmaValid\r
86 FALSE, // Lba48Bit\r
87 NULL, // IdentifyData\r
88 NULL, // ControllerNameTable\r
490b5ea1 89 {L'\0', }, // ModelName\r
58727f29 90 {NULL, NULL}, // AtaTaskList\r
91 {NULL, NULL} // AtaSubTaskList\r
ad86a50a 92};\r
93\r
94/**\r
95 Allocates an aligned buffer for ATA device.\r
96\r
97 This function allocates an aligned buffer for the ATA device to perform\r
98 ATA pass through operations. The alignment requirement is from ATA pass\r
99 through interface.\r
100\r
101 @param AtaDevice The ATA child device involved for the operation.\r
102 @param BufferSize The request buffer size.\r
103\r
104 @return A pointer to the aligned buffer or NULL if the allocation fails.\r
105\r
106**/\r
107VOID *\r
108AllocateAlignedBuffer (\r
109 IN ATA_DEVICE *AtaDevice,\r
110 IN UINTN BufferSize\r
111 )\r
112{\r
113 return AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), AtaDevice->AtaBusDriverData->AtaPassThru->Mode->IoAlign);\r
114}\r
115\r
116/**\r
117 Frees an aligned buffer for ATA device.\r
118\r
119 This function frees an aligned buffer for the ATA device to perform\r
120 ATA pass through operations.\r
121\r
05a44e91 122 @param Buffer The aligned buffer to be freed.\r
ad86a50a 123 @param BufferSize The request buffer size.\r
124\r
125**/\r
126VOID\r
127FreeAlignedBuffer (\r
128 IN VOID *Buffer,\r
129 IN UINTN BufferSize\r
130 )\r
131{\r
132 if (Buffer != NULL) {\r
957fe093 133 FreeAlignedPages (Buffer, EFI_SIZE_TO_PAGES (BufferSize));\r
ad86a50a 134 }\r
135}\r
136\r
137\r
138/**\r
139 Release all the resources allocated for the ATA device.\r
140\r
141 This function releases all the resources allocated for the ATA device.\r
142\r
143 @param AtaDevice The ATA child device involved for the operation.\r
144\r
145**/\r
146VOID\r
147ReleaseAtaResources (\r
148 IN ATA_DEVICE *AtaDevice\r
149 )\r
150{\r
58727f29 151 ATA_BUS_ASYN_SUB_TASK *SubTask;\r
152 ATA_BUS_ASYN_TASK *AtaTask;\r
153 LIST_ENTRY *Entry;\r
154 LIST_ENTRY *DelEntry;\r
155 EFI_TPL OldTpl;\r
490b5ea1 156\r
ad86a50a 157 FreeUnicodeStringTable (AtaDevice->ControllerNameTable);\r
3c063fed 158 FreeAlignedBuffer (AtaDevice->Asb, sizeof (EFI_ATA_STATUS_BLOCK));\r
159 FreeAlignedBuffer (AtaDevice->IdentifyData, sizeof (ATA_IDENTIFY_DATA));\r
ad86a50a 160 if (AtaDevice->DevicePath != NULL) {\r
161 FreePool (AtaDevice->DevicePath);\r
162 }\r
490b5ea1 163 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
58727f29 164 if (!IsListEmpty (&AtaDevice->AtaSubTaskList)) {\r
165 //\r
166 // Free the Subtask list.\r
167 //\r
168 for(Entry = AtaDevice->AtaSubTaskList.ForwardLink;\r
169 Entry != (&AtaDevice->AtaSubTaskList);\r
170 ) {\r
171 DelEntry = Entry;\r
172 Entry = Entry->ForwardLink;\r
173 SubTask = ATA_AYNS_SUB_TASK_FROM_ENTRY (DelEntry);\r
174\r
175 RemoveEntryList (DelEntry);\r
176 FreeAtaSubTask (SubTask);\r
177 }\r
178 }\r
490b5ea1 179 if (!IsListEmpty (&AtaDevice->AtaTaskList)) {\r
180 //\r
181 // Free the Subtask list.\r
182 //\r
58727f29 183 for(Entry = AtaDevice->AtaTaskList.ForwardLink;\r
490b5ea1 184 Entry != (&AtaDevice->AtaTaskList);\r
185 ) {\r
186 DelEntry = Entry;\r
187 Entry = Entry->ForwardLink;\r
58727f29 188 AtaTask = ATA_AYNS_TASK_FROM_ENTRY (DelEntry);\r
189\r
490b5ea1 190 RemoveEntryList (DelEntry);\r
58727f29 191 FreePool (AtaTask);\r
490b5ea1 192 }\r
193 }\r
194 gBS->RestoreTPL (OldTpl);\r
ad86a50a 195 FreePool (AtaDevice);\r
196}\r
197\r
198\r
199/**\r
200 Registers an ATA device.\r
201\r
202 This function allocates an ATA device structure for the ATA device specified by\r
58727f29 203 Port and PortMultiplierPort if the ATA device is identified as a valid one.\r
ad86a50a 204 Then it will create child handle and install Block IO and Disk Info protocol on\r
205 it.\r
206\r
05a44e91 207 @param AtaBusDriverData The parent ATA bus driver data structure.\r
ad86a50a 208 @param Port The port number of the ATA device.\r
209 @param PortMultiplierPort The port multiplier port number of the ATA device.\r
210\r
211 @retval EFI_SUCCESS The ATA device is successfully registered.\r
212 @retval EFI_OUT_OF_RESOURCES There is not enough memory to allocate the ATA device\r
213 and related data structures.\r
214 @return Others Some error occurs when registering the ATA device.\r
215**/\r
216EFI_STATUS\r
217RegisterAtaDevice (\r
218 IN OUT ATA_BUS_DRIVER_DATA *AtaBusDriverData,\r
219 IN UINT16 Port,\r
220 IN UINT16 PortMultiplierPort\r
221 )\r
222{\r
223 EFI_STATUS Status;\r
224 ATA_DEVICE *AtaDevice;\r
225 EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;\r
226 EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;\r
e519983a 227 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
228 EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;\r
229 EFI_HANDLE DeviceHandle;\r
ad86a50a 230\r
e519983a 231 AtaDevice = NULL;\r
ad86a50a 232 NewDevicePathNode = NULL;\r
e519983a 233 DevicePath = NULL;\r
234 RemainingDevicePath = NULL;\r
235\r
236 //\r
58727f29 237 // Build device path\r
e519983a 238 //\r
239 AtaPassThru = AtaBusDriverData->AtaPassThru;\r
240 Status = AtaPassThru->BuildDevicePath (AtaPassThru, Port, PortMultiplierPort, &NewDevicePathNode);\r
241 if (EFI_ERROR (Status)) {\r
242 goto Done;\r
243 }\r
244\r
245 DevicePath = AppendDevicePathNode (AtaBusDriverData->ParentDevicePath, NewDevicePathNode);\r
246 if (DevicePath == NULL) {\r
e70ae46c 247 Status = EFI_OUT_OF_RESOURCES;\r
e519983a 248 goto Done;\r
249 }\r
250\r
251 DeviceHandle = NULL;\r
e70ae46c 252 RemainingDevicePath = DevicePath;\r
e519983a 253 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);\r
254 if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) {\r
255 Status = EFI_ALREADY_STARTED;\r
e70ae46c 256 FreePool (DevicePath);\r
e519983a 257 goto Done;\r
258 }\r
ad86a50a 259\r
260 //\r
261 // Allocate ATA device from the template.\r
262 //\r
3c063fed 263 AtaDevice = AllocateCopyPool (sizeof (ATA_DEVICE), &gAtaDeviceTemplate);\r
ad86a50a 264 if (AtaDevice == NULL) {\r
e519983a 265 Status = EFI_OUT_OF_RESOURCES;\r
266 goto Done;\r
ad86a50a 267 }\r
268\r
269 //\r
270 // Initializes ATA device structures and allocates the required buffer.\r
271 //\r
490b5ea1 272 AtaDevice->BlockIo.Media = &AtaDevice->BlockMedia;\r
273 AtaDevice->BlockIo2.Media = &AtaDevice->BlockMedia;\r
274 AtaDevice->AtaBusDriverData = AtaBusDriverData;\r
275 AtaDevice->DevicePath = DevicePath;\r
276 AtaDevice->Port = Port;\r
ad86a50a 277 AtaDevice->PortMultiplierPort = PortMultiplierPort;\r
3c063fed 278 AtaDevice->Asb = AllocateAlignedBuffer (AtaDevice, sizeof (EFI_ATA_STATUS_BLOCK));\r
ad86a50a 279 if (AtaDevice->Asb == NULL) {\r
280 Status = EFI_OUT_OF_RESOURCES;\r
281 goto Done;\r
282 }\r
3c063fed 283 AtaDevice->IdentifyData = AllocateAlignedBuffer (AtaDevice, sizeof (ATA_IDENTIFY_DATA));\r
ad86a50a 284 if (AtaDevice->IdentifyData == NULL) {\r
285 Status = EFI_OUT_OF_RESOURCES;\r
286 goto Done;\r
287 }\r
288\r
490b5ea1 289 //\r
290 // Initial Ata Task List\r
291 //\r
292 InitializeListHead (&AtaDevice->AtaTaskList);\r
58727f29 293 InitializeListHead (&AtaDevice->AtaSubTaskList);\r
490b5ea1 294\r
ad86a50a 295 //\r
58727f29 296 // Try to identify the ATA device via the ATA pass through command.\r
ad86a50a 297 //\r
298 Status = DiscoverAtaDevice (AtaDevice);\r
299 if (EFI_ERROR (Status)) {\r
300 goto Done;\r
301 }\r
490b5ea1 302\r
ad86a50a 303 //\r
304 // Build controller name for Component Name (2) protocol.\r
305 //\r
306 Status = AddUnicodeString2 (\r
307 "eng",\r
308 gAtaBusComponentName.SupportedLanguages,\r
309 &AtaDevice->ControllerNameTable,\r
310 AtaDevice->ModelName,\r
311 TRUE\r
312 );\r
313 if (EFI_ERROR (Status)) {\r
314 goto Done;\r
315 }\r
316\r
317 Status = AddUnicodeString2 (\r
318 "en",\r
319 gAtaBusComponentName2.SupportedLanguages,\r
320 &AtaDevice->ControllerNameTable,\r
321 AtaDevice->ModelName,\r
322 FALSE\r
323 );\r
324 if (EFI_ERROR (Status)) {\r
325 goto Done;\r
326 }\r
327\r
ad86a50a 328 //\r
329 // Update to AHCI interface GUID based on device path node. The default one\r
330 // is IDE interface GUID copied from template.\r
331 //\r
332 if (NewDevicePathNode->SubType == MSG_SATA_DP) {\r
333 CopyGuid (&AtaDevice->DiskInfo.Interface, &gEfiDiskInfoAhciInterfaceGuid);\r
334 }\r
335\r
ad86a50a 336 Status = gBS->InstallMultipleProtocolInterfaces (\r
337 &AtaDevice->Handle,\r
338 &gEfiDevicePathProtocolGuid,\r
339 AtaDevice->DevicePath,\r
340 &gEfiBlockIoProtocolGuid,\r
341 &AtaDevice->BlockIo,\r
490b5ea1 342 &gEfiBlockIo2ProtocolGuid,\r
343 &AtaDevice->BlockIo2,\r
ad86a50a 344 &gEfiDiskInfoProtocolGuid,\r
345 &AtaDevice->DiskInfo,\r
346 NULL\r
347 );\r
348 if (EFI_ERROR (Status)) {\r
349 goto Done;\r
350 }\r
351\r
c24097a5 352 //\r
353 // See if the ata device support trust computing feature or not.\r
354 // If yes, then install Storage Security Protocol at the ata device handle.\r
355 //\r
356 if ((AtaDevice->IdentifyData->trusted_computing_support & BIT0) != 0) {\r
357 DEBUG ((EFI_D_INFO, "Found TCG support in Port %x PortMultiplierPort %x\n", Port, PortMultiplierPort));\r
358 Status = gBS->InstallProtocolInterface (\r
359 &AtaDevice->Handle,\r
360 &gEfiStorageSecurityCommandProtocolGuid,\r
361 EFI_NATIVE_INTERFACE,\r
362 &AtaDevice->StorageSecurity\r
363 );\r
364 if (EFI_ERROR (Status)) {\r
365 goto Done;\r
366 }\r
367 }\r
368\r
ad86a50a 369 gBS->OpenProtocol (\r
370 AtaBusDriverData->Controller,\r
371 &gEfiAtaPassThruProtocolGuid,\r
372 (VOID **) &AtaPassThru,\r
373 AtaBusDriverData->DriverBindingHandle,\r
374 AtaDevice->Handle,\r
375 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
376 );\r
e519983a 377\r
ad86a50a 378Done:\r
379 if (NewDevicePathNode != NULL) {\r
380 FreePool (NewDevicePathNode);\r
381 }\r
382\r
e519983a 383 if (EFI_ERROR (Status) && (AtaDevice != NULL)) {\r
58727f29 384 ReleaseAtaResources (AtaDevice);\r
25dd150b 385 DEBUG ((EFI_D_ERROR | EFI_D_INIT, "Failed to initialize Port %x PortMultiplierPort %x, status = %r\n", Port, PortMultiplierPort, Status));\r
ad86a50a 386 }\r
387 return Status;\r
388}\r
389\r
390\r
391/**\r
392 Unregisters an ATA device.\r
393\r
58727f29 394 This function removes the protocols installed on the controller handle and\r
395 frees the resources allocated for the ATA device.\r
ad86a50a 396\r
05a44e91 397 @param This The pointer to EFI_DRIVER_BINDING_PROTOCOL instance.\r
ad86a50a 398 @param Controller The controller handle of the ATA device.\r
399 @param Handle The child handle.\r
400\r
401 @retval EFI_SUCCESS The ATA device is successfully unregistered.\r
402 @return Others Some error occurs when unregistering the ATA device.\r
403\r
404**/\r
405EFI_STATUS\r
406UnregisterAtaDevice (\r
407 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
408 IN EFI_HANDLE Controller,\r
409 IN EFI_HANDLE Handle\r
410 )\r
411{\r
c24097a5 412 EFI_STATUS Status;\r
413 EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
414 EFI_BLOCK_IO2_PROTOCOL *BlockIo2;\r
415 ATA_DEVICE *AtaDevice;\r
416 EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;\r
417 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *StorageSecurity;\r
418\r
419 BlockIo2 = NULL;\r
420 BlockIo = NULL;\r
ad86a50a 421\r
422 Status = gBS->OpenProtocol (\r
423 Handle,\r
424 &gEfiBlockIoProtocolGuid,\r
425 (VOID **) &BlockIo,\r
426 This->DriverBindingHandle,\r
427 Controller,\r
428 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
429 );\r
430 if (EFI_ERROR (Status)) {\r
490b5ea1 431 //\r
432 // Locate BlockIo2 protocol\r
433 //\r
434 Status = gBS->OpenProtocol (\r
435 Handle,\r
436 &gEfiBlockIo2ProtocolGuid,\r
437 (VOID **) &BlockIo2,\r
438 This->DriverBindingHandle,\r
439 Controller,\r
440 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
441 );\r
442 if (EFI_ERROR (Status)) {\r
443 return Status;\r
444 }\r
ad86a50a 445 }\r
446\r
490b5ea1 447 //\r
448 // Get AtaDevice data.\r
449 //\r
450 if (BlockIo != NULL) {\r
451 AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (BlockIo);\r
452 } else {\r
453 AtaDevice = ATA_DEVICE_FROM_BLOCK_IO2 (BlockIo2);\r
58727f29 454 }\r
ad86a50a 455\r
456 //\r
457 // Close the child handle\r
458 //\r
459 gBS->CloseProtocol (\r
460 Controller,\r
461 &gEfiAtaPassThruProtocolGuid,\r
462 This->DriverBindingHandle,\r
463 Handle\r
464 );\r
465\r
490b5ea1 466 //\r
467 // The Ata Bus driver installs the BlockIo and BlockIo2 in the DriverBindingStart().\r
468 // Here should uninstall both of them.\r
469 //\r
ad86a50a 470 Status = gBS->UninstallMultipleProtocolInterfaces (\r
471 Handle,\r
472 &gEfiDevicePathProtocolGuid,\r
473 AtaDevice->DevicePath,\r
474 &gEfiBlockIoProtocolGuid,\r
475 &AtaDevice->BlockIo,\r
490b5ea1 476 &gEfiBlockIo2ProtocolGuid,\r
477 &AtaDevice->BlockIo2,\r
ad86a50a 478 &gEfiDiskInfoProtocolGuid,\r
479 &AtaDevice->DiskInfo,\r
480 NULL\r
481 );\r
482\r
483 if (EFI_ERROR (Status)) {\r
484 gBS->OpenProtocol (\r
485 Controller,\r
486 &gEfiAtaPassThruProtocolGuid,\r
487 (VOID **) &AtaPassThru,\r
488 This->DriverBindingHandle,\r
489 Handle,\r
490 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
491 );\r
492 return Status;\r
493 }\r
494\r
c24097a5 495 //\r
496 // If Storage Security Command Protocol is installed, then uninstall this protocol.\r
497 //\r
498 Status = gBS->OpenProtocol (\r
499 Handle,\r
500 &gEfiStorageSecurityCommandProtocolGuid,\r
501 (VOID **) &StorageSecurity,\r
502 This->DriverBindingHandle,\r
503 Controller,\r
504 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
505 );\r
506\r
507 if (!EFI_ERROR (Status)) {\r
508 Status = gBS->UninstallProtocolInterface (\r
509 Handle,\r
510 &gEfiStorageSecurityCommandProtocolGuid,\r
511 &AtaDevice->StorageSecurity\r
512 );\r
513 if (EFI_ERROR (Status)) {\r
514 gBS->OpenProtocol (\r
515 Controller,\r
516 &gEfiAtaPassThruProtocolGuid,\r
517 (VOID **) &AtaPassThru,\r
518 This->DriverBindingHandle,\r
519 Handle,\r
520 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
521 );\r
3c063fed 522 return Status;\r
c24097a5 523 }\r
524 }\r
525\r
ad86a50a 526 ReleaseAtaResources (AtaDevice);\r
7f070be5 527 return EFI_SUCCESS;\r
ad86a50a 528}\r
529\r
530\r
531\r
532/**\r
58727f29 533 Tests to see if this driver supports a given controller. If a child device is provided,\r
ad86a50a 534 it further tests to see if this driver supports creating a handle for the specified child device.\r
535\r
58727f29 536 This function checks to see if the driver specified by This supports the device specified by\r
537 ControllerHandle. Drivers will typically use the device path attached to\r
538 ControllerHandle and/or the services from the bus I/O abstraction attached to\r
539 ControllerHandle to determine if the driver supports ControllerHandle. This function\r
540 may be called many times during platform initialization. In order to reduce boot times, the tests\r
541 performed by this function must be very small, and take as little time as possible to execute. This\r
542 function must not change the state of any hardware devices, and this function must be aware that the\r
543 device specified by ControllerHandle may already be managed by the same driver or a\r
544 different driver. This function must match its calls to AllocatePages() with FreePages(),\r
545 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().\r
546 Since ControllerHandle may have been previously started by the same driver, if a protocol is\r
547 already in the opened state, then it must not be closed with CloseProtocol(). This is required\r
ad86a50a 548 to guarantee the state of ControllerHandle is not modified by this function.\r
549\r
550 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
58727f29 551 @param[in] ControllerHandle The handle of the controller to test. This handle\r
552 must support a protocol interface that supplies\r
ad86a50a 553 an I/O abstraction to the driver.\r
58727f29 554 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
555 parameter is ignored by device drivers, and is optional for bus\r
556 drivers. For bus drivers, if this parameter is not NULL, then\r
557 the bus driver must determine if the bus controller specified\r
558 by ControllerHandle and the child controller specified\r
559 by RemainingDevicePath are both supported by this\r
ad86a50a 560 bus driver.\r
561\r
562 @retval EFI_SUCCESS The device specified by ControllerHandle and\r
563 RemainingDevicePath is supported by the driver specified by This.\r
564 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
565 RemainingDevicePath is already being managed by the driver\r
566 specified by This.\r
567 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
568 RemainingDevicePath is already being managed by a different\r
569 driver or an application that requires exclusive access.\r
570 Currently not implemented.\r
571 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r
572 RemainingDevicePath is not supported by the driver specified by This.\r
573**/\r
574EFI_STATUS\r
575EFIAPI\r
576AtaBusDriverBindingSupported (\r
577 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
578 IN EFI_HANDLE Controller,\r
579 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
580 )\r
581{\r
582 EFI_STATUS Status;\r
583 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
584 EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;\r
585 UINT16 Port;\r
586 UINT16 PortMultiplierPort;\r
490b5ea1 587\r
ad86a50a 588 //\r
589 // Test EFI_ATA_PASS_THRU_PROTOCOL on controller handle.\r
590 //\r
591 Status = gBS->OpenProtocol (\r
592 Controller,\r
593 &gEfiAtaPassThruProtocolGuid,\r
594 (VOID **) &AtaPassThru,\r
595 This->DriverBindingHandle,\r
596 Controller,\r
597 EFI_OPEN_PROTOCOL_BY_DRIVER\r
598 );\r
599\r
600 if (Status == EFI_ALREADY_STARTED) {\r
601 return EFI_SUCCESS;\r
602 }\r
603\r
604 if (EFI_ERROR (Status)) {\r
605 return Status;\r
606 }\r
607\r
608 //\r
609 // Test RemainingDevicePath is valid or not.\r
610 //\r
611 if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {\r
612 Status = AtaPassThru->GetDevice (AtaPassThru, RemainingDevicePath, &Port, &PortMultiplierPort);\r
613 if (EFI_ERROR (Status)) {\r
614 return Status;\r
615 }\r
616 }\r
617\r
618 //\r
619 // Close the I/O Abstraction(s) used to perform the supported test\r
620 //\r
621 gBS->CloseProtocol (\r
622 Controller,\r
623 &gEfiAtaPassThruProtocolGuid,\r
624 This->DriverBindingHandle,\r
625 Controller\r
626 );\r
627\r
628 //\r
629 // Open the EFI Device Path protocol needed to perform the supported test\r
630 //\r
631 Status = gBS->OpenProtocol (\r
632 Controller,\r
633 &gEfiDevicePathProtocolGuid,\r
634 (VOID **) &ParentDevicePath,\r
635 This->DriverBindingHandle,\r
636 Controller,\r
637 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
638 );\r
639 return Status;\r
640}\r
641\r
642\r
643/**\r
644 Starts a device controller or a bus controller.\r
645\r
646 The Start() function is designed to be invoked from the EFI boot service ConnectController().\r
58727f29 647 As a result, much of the error checking on the parameters to Start() has been moved into this\r
648 common boot service. It is legal to call Start() from other locations,\r
ad86a50a 649 but the following calling restrictions must be followed or the system behavior will not be deterministic.\r
650 1. ControllerHandle must be a valid EFI_HANDLE.\r
651 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned\r
652 EFI_DEVICE_PATH_PROTOCOL.\r
653 3. Prior to calling Start(), the Supported() function for the driver specified by This must\r
58727f29 654 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.\r
ad86a50a 655\r
656 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
58727f29 657 @param[in] ControllerHandle The handle of the controller to start. This handle\r
658 must support a protocol interface that supplies\r
ad86a50a 659 an I/O abstraction to the driver.\r
58727f29 660 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
661 parameter is ignored by device drivers, and is optional for bus\r
662 drivers. For a bus driver, if this parameter is NULL, then handles\r
490b5ea1 663 for all the children of Controller are created by this driver.\r
58727f29 664 If this parameter is not NULL and the first Device Path Node is\r
665 not the End of Device Path Node, then only the handle for the\r
666 child device specified by the first Device Path Node of\r
ad86a50a 667 RemainingDevicePath is created by this driver.\r
58727f29 668 If the first Device Path Node of RemainingDevicePath is\r
ad86a50a 669 the End of Device Path Node, no child handle is created by this\r
670 driver.\r
671\r
672 @retval EFI_SUCCESS The device was started.\r
673 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.\r
674 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
675 @retval Others The driver failded to start the device.\r
676\r
677**/\r
678EFI_STATUS\r
679EFIAPI\r
680AtaBusDriverBindingStart (\r
681 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
682 IN EFI_HANDLE Controller,\r
683 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
684 )\r
685{\r
686 EFI_STATUS Status;\r
687 EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;\r
688 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
689 ATA_BUS_DRIVER_DATA *AtaBusDriverData;\r
690 UINT16 Port;\r
691 UINT16 PortMultiplierPort;\r
692\r
693 AtaBusDriverData = NULL;\r
694\r
695 Status = gBS->OpenProtocol (\r
696 Controller,\r
697 &gEfiDevicePathProtocolGuid,\r
698 (VOID **) &ParentDevicePath,\r
699 This->DriverBindingHandle,\r
700 Controller,\r
701 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
702 );\r
703 if (EFI_ERROR (Status)) {\r
704 return Status;\r
705 }\r
706\r
707 Status = gBS->OpenProtocol (\r
708 Controller,\r
709 &gEfiAtaPassThruProtocolGuid,\r
710 (VOID **) &AtaPassThru,\r
711 This->DriverBindingHandle,\r
712 Controller,\r
713 EFI_OPEN_PROTOCOL_BY_DRIVER\r
714 );\r
715 if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {\r
716 goto ErrorExit;\r
717 }\r
718\r
719 //\r
720 // Check EFI_ALREADY_STARTED to reuse the original ATA_BUS_DRIVER_DATA.\r
721 //\r
722 if (Status != EFI_ALREADY_STARTED) {\r
723 AtaBusDriverData = AllocateZeroPool (sizeof (ATA_BUS_DRIVER_DATA));\r
724 if (AtaBusDriverData == NULL) {\r
725 Status = EFI_OUT_OF_RESOURCES;\r
726 goto ErrorExit;\r
727 }\r
728\r
729 AtaBusDriverData->AtaPassThru = AtaPassThru;\r
490b5ea1 730 AtaBusDriverData->Controller = Controller;\r
ad86a50a 731 AtaBusDriverData->ParentDevicePath = ParentDevicePath;\r
732 AtaBusDriverData->DriverBindingHandle = This->DriverBindingHandle;\r
733\r
734 Status = gBS->InstallMultipleProtocolInterfaces (\r
735 &Controller,\r
736 &gEfiCallerIdGuid,\r
737 AtaBusDriverData,\r
738 NULL\r
739 );\r
740 if (EFI_ERROR (Status)) {\r
741 goto ErrorExit;\r
742 }\r
743\r
744 } else {\r
745 Status = gBS->OpenProtocol (\r
746 Controller,\r
747 &gEfiCallerIdGuid,\r
748 (VOID **) &AtaBusDriverData,\r
749 This->DriverBindingHandle,\r
750 Controller,\r
751 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
752 );\r
753 if (EFI_ERROR (Status)) {\r
754 AtaBusDriverData = NULL;\r
755 goto ErrorExit;\r
756 }\r
757 }\r
758\r
759 if (RemainingDevicePath == NULL) {\r
760 Port = 0xFFFF;\r
761 while (TRUE) {\r
762 Status = AtaPassThru->GetNextPort (AtaPassThru, &Port);\r
763 if (EFI_ERROR (Status)) {\r
764 //\r
765 // We cannot find more legal port then we are done.\r
766 //\r
767 break;\r
768 }\r
490b5ea1 769\r
ad86a50a 770 PortMultiplierPort = 0xFFFF;\r
771 while (TRUE) {\r
772 Status = AtaPassThru->GetNextDevice (AtaPassThru, Port, &PortMultiplierPort);\r
773 if (EFI_ERROR (Status)) {\r
774 //\r
775 // We cannot find more legal port multiplier port number for ATA device\r
776 // on the port, then we are done.\r
777 //\r
778 break;\r
779 }\r
780 RegisterAtaDevice (AtaBusDriverData, Port, PortMultiplierPort);\r
781 }\r
782 }\r
783 Status = EFI_SUCCESS;\r
784 } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
785 Status = AtaPassThru->GetDevice (AtaPassThru, RemainingDevicePath, &Port, &PortMultiplierPort);\r
786 if (!EFI_ERROR (Status)) {\r
787 Status = RegisterAtaDevice (AtaBusDriverData,Port, PortMultiplierPort);\r
788 }\r
789 }\r
490b5ea1 790\r
ad86a50a 791 return Status;\r
792\r
793ErrorExit:\r
794\r
795 if (AtaBusDriverData != NULL) {\r
796 gBS->UninstallMultipleProtocolInterfaces (\r
797 Controller,\r
798 &gEfiCallerIdGuid,\r
799 AtaBusDriverData,\r
800 NULL\r
801 );\r
802 FreePool (AtaBusDriverData);\r
803 }\r
804\r
805 gBS->CloseProtocol (\r
806 Controller,\r
807 &gEfiAtaPassThruProtocolGuid,\r
808 This->DriverBindingHandle,\r
809 Controller\r
810 );\r
811\r
812 return Status;\r
813\r
814}\r
815\r
816\r
817/**\r
818 Stops a device controller or a bus controller.\r
58727f29 819\r
820 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().\r
821 As a result, much of the error checking on the parameters to Stop() has been moved\r
822 into this common boot service. It is legal to call Stop() from other locations,\r
ad86a50a 823 but the following calling restrictions must be followed or the system behavior will not be deterministic.\r
824 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
825 same driver's Start() function.\r
826 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
827 EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
828 Start() function, and the Start() function must have called OpenProtocol() on\r
829 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
58727f29 830\r
ad86a50a 831 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
58727f29 832 @param[in] ControllerHandle A handle to the device being stopped. The handle must\r
833 support a bus specific I/O protocol for the driver\r
ad86a50a 834 to use to stop the device.\r
835 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
58727f29 836 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL\r
ad86a50a 837 if NumberOfChildren is 0.\r
838\r
839 @retval EFI_SUCCESS The device was stopped.\r
840 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
841\r
842**/\r
843EFI_STATUS\r
844EFIAPI\r
845AtaBusDriverBindingStop (\r
846 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
847 IN EFI_HANDLE Controller,\r
848 IN UINTN NumberOfChildren,\r
849 IN EFI_HANDLE *ChildHandleBuffer\r
850 )\r
851{\r
852 EFI_STATUS Status;\r
853 BOOLEAN AllChildrenStopped;\r
854 UINTN Index;\r
855 ATA_BUS_DRIVER_DATA *AtaBusDriverData;\r
856\r
857 if (NumberOfChildren == 0) {\r
858 Status = gBS->OpenProtocol (\r
859 Controller,\r
860 &gEfiCallerIdGuid,\r
861 (VOID **) &AtaBusDriverData,\r
862 This->DriverBindingHandle,\r
863 Controller,\r
864 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
865 );\r
866 if (!EFI_ERROR (Status)) {\r
867 gBS->UninstallMultipleProtocolInterfaces (\r
868 Controller,\r
869 &gEfiCallerIdGuid,\r
870 AtaBusDriverData,\r
871 NULL\r
872 );\r
873 FreePool (AtaBusDriverData);\r
874 }\r
875\r
876 gBS->CloseProtocol (\r
877 Controller,\r
878 &gEfiAtaPassThruProtocolGuid,\r
879 This->DriverBindingHandle,\r
880 Controller\r
881 );\r
882\r
883 return EFI_SUCCESS;\r
884 }\r
885\r
886 AllChildrenStopped = TRUE;\r
887\r
888 for (Index = 0; Index < NumberOfChildren; Index++) {\r
889\r
890 Status = UnregisterAtaDevice (This, Controller, ChildHandleBuffer[Index]);\r
891 if (EFI_ERROR (Status)) {\r
892 AllChildrenStopped = FALSE;\r
893 }\r
894 }\r
895\r
896 if (!AllChildrenStopped) {\r
897 return EFI_DEVICE_ERROR;\r
898 }\r
899\r
900 return EFI_SUCCESS;\r
901}\r
902\r
903\r
904/**\r
905 Reset the Block Device.\r
906\r
907 @param This Indicates a pointer to the calling context.\r
908 @param ExtendedVerification Driver may perform diagnostics on reset.\r
909\r
910 @retval EFI_SUCCESS The device was reset.\r
911 @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
912 not be reset.\r
913\r
914**/\r
915EFI_STATUS\r
916EFIAPI\r
917AtaBlockIoReset (\r
918 IN EFI_BLOCK_IO_PROTOCOL *This,\r
919 IN BOOLEAN ExtendedVerification\r
920 )\r
921{\r
922 EFI_STATUS Status;\r
923 ATA_DEVICE *AtaDevice;\r
924 EFI_TPL OldTpl;\r
925\r
926 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
927\r
928 AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (This);\r
929\r
490b5ea1 930 Status = ResetAtaDevice (AtaDevice);\r
ad86a50a 931\r
c6e797ae 932 if (EFI_ERROR (Status)) {\r
933 Status = EFI_DEVICE_ERROR;\r
934 }\r
935\r
ad86a50a 936 gBS->RestoreTPL (OldTpl);\r
937 return Status;\r
938}\r
939\r
940\r
941/**\r
942 Read/Write BufferSize bytes from Lba from/into Buffer.\r
943\r
490b5ea1 944 @param[in] This Indicates a pointer to the calling context. Either be\r
58727f29 945 block I/O or block I/O2.\r
490b5ea1 946 @param[in] MediaId The media ID that the read/write request is for.\r
947 @param[in] Lba The starting logical block address to be read/written.\r
948 The caller is responsible for reading/writing to only\r
949 legitimate locations.\r
950 @param[in, out] Token A pointer to the token associated with the transaction.\r
951 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.\r
952 @param[out] Buffer A pointer to the destination/source buffer for the data.\r
953 @param[in] IsBlockIo2 Indicate the calling is from BlockIO or BlockIO2. TURE is\r
954 from BlockIO2, FALSE is for BlockIO.\r
955 @param[in] IsWrite Indicates whether it is a write operation.\r
ad86a50a 956\r
957 @retval EFI_SUCCESS The data was read/written correctly to the device.\r
958 @retval EFI_WRITE_PROTECTED The device can not be read/written to.\r
959 @retval EFI_DEVICE_ERROR The device reported an error while performing the read/write.\r
960 @retval EFI_NO_MEDIA There is no media in the device.\r
961 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.\r
962 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
58727f29 963 @retval EFI_INVALID_PARAMETER The read/write request contains LBAs that are not valid,\r
ad86a50a 964 or the buffer is not on proper alignment.\r
965\r
966**/\r
967EFI_STATUS\r
968BlockIoReadWrite (\r
490b5ea1 969 IN VOID *This,\r
970 IN UINT32 MediaId,\r
971 IN EFI_LBA Lba,\r
972 IN OUT EFI_BLOCK_IO2_TOKEN *Token,\r
973 IN UINTN BufferSize,\r
974 OUT VOID *Buffer,\r
975 IN BOOLEAN IsBlockIo2,\r
976 IN BOOLEAN IsWrite\r
ad86a50a 977 )\r
978{\r
979 ATA_DEVICE *AtaDevice;\r
980 EFI_STATUS Status;\r
981 EFI_TPL OldTpl;\r
982 EFI_BLOCK_IO_MEDIA *Media;\r
983 UINTN BlockSize;\r
984 UINTN NumberOfBlocks;\r
985 UINTN IoAlign;\r
986\r
490b5ea1 987 if (IsBlockIo2) {\r
988 Media = ((EFI_BLOCK_IO2_PROTOCOL *) This)->Media;\r
989 AtaDevice = ATA_DEVICE_FROM_BLOCK_IO2 (This);\r
990 } else {\r
991 Media = ((EFI_BLOCK_IO_PROTOCOL *) This)->Media;\r
992 AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (This);\r
993 }\r
994\r
fcf5e49d
RN
995 if (MediaId != Media->MediaId) {\r
996 return EFI_MEDIA_CHANGED;\r
997 }\r
998\r
490b5ea1 999 //\r
1000 // Check parameters.\r
1001 //\r
ad86a50a 1002 if (Buffer == NULL) {\r
1003 return EFI_INVALID_PARAMETER;\r
1004 }\r
1005\r
1006 if (BufferSize == 0) {\r
1007 return EFI_SUCCESS;\r
58727f29 1008 }\r
ad86a50a 1009\r
ad86a50a 1010 BlockSize = Media->BlockSize;\r
1011 if ((BufferSize % BlockSize) != 0) {\r
1012 return EFI_BAD_BUFFER_SIZE;\r
1013 }\r
58727f29 1014\r
ad86a50a 1015 NumberOfBlocks = BufferSize / BlockSize;\r
1016 if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {\r
1017 return EFI_INVALID_PARAMETER;\r
1018 }\r
1019\r
1020 IoAlign = Media->IoAlign;\r
1021 if (IoAlign > 0 && (((UINTN) Buffer & (IoAlign - 1)) != 0)) {\r
1022 return EFI_INVALID_PARAMETER;\r
1023 }\r
1024\r
1025 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
58727f29 1026\r
ad86a50a 1027 //\r
1028 // Invoke low level AtaDevice Access Routine.\r
1029 //\r
490b5ea1 1030 Status = AccessAtaDevice (AtaDevice, Buffer, Lba, NumberOfBlocks, IsWrite, Token);\r
58727f29 1031\r
ad86a50a 1032 gBS->RestoreTPL (OldTpl);\r
1033\r
1034 return Status;\r
1035}\r
1036\r
1037\r
1038/**\r
1039 Read BufferSize bytes from Lba into Buffer.\r
1040\r
1041 @param This Indicates a pointer to the calling context.\r
1042 @param MediaId Id of the media, changes every time the media is replaced.\r
1043 @param Lba The starting Logical Block Address to read from\r
1044 @param BufferSize Size of Buffer, must be a multiple of device block size.\r
1045 @param Buffer A pointer to the destination buffer for the data. The caller is\r
1046 responsible for either having implicit or explicit ownership of the buffer.\r
1047\r
1048 @retval EFI_SUCCESS The data was read correctly from the device.\r
1049 @retval EFI_DEVICE_ERROR The device reported an error while performing the read.\r
1050 @retval EFI_NO_MEDIA There is no media in the device.\r
1051 @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.\r
1052 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
58727f29 1053 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,\r
ad86a50a 1054 or the buffer is not on proper alignment.\r
1055\r
1056**/\r
1057EFI_STATUS\r
1058EFIAPI\r
1059AtaBlockIoReadBlocks (\r
1060 IN EFI_BLOCK_IO_PROTOCOL *This,\r
1061 IN UINT32 MediaId,\r
1062 IN EFI_LBA Lba,\r
1063 IN UINTN BufferSize,\r
1064 OUT VOID *Buffer\r
1065 )\r
1066{\r
490b5ea1 1067 return BlockIoReadWrite ((VOID *) This, MediaId, Lba, NULL, BufferSize, Buffer, FALSE, FALSE);\r
ad86a50a 1068}\r
1069\r
1070\r
1071/**\r
1072 Write BufferSize bytes from Lba into Buffer.\r
1073\r
1074 @param This Indicates a pointer to the calling context.\r
1075 @param MediaId The media ID that the write request is for.\r
1076 @param Lba The starting logical block address to be written. The caller is\r
1077 responsible for writing to only legitimate locations.\r
1078 @param BufferSize Size of Buffer, must be a multiple of device block size.\r
1079 @param Buffer A pointer to the source buffer for the data.\r
1080\r
1081 @retval EFI_SUCCESS The data was written correctly to the device.\r
1082 @retval EFI_WRITE_PROTECTED The device can not be written to.\r
1083 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.\r
1084 @retval EFI_NO_MEDIA There is no media in the device.\r
1085 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.\r
1086 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
58727f29 1087 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,\r
ad86a50a 1088 or the buffer is not on proper alignment.\r
1089\r
1090**/\r
1091EFI_STATUS\r
1092EFIAPI\r
1093AtaBlockIoWriteBlocks (\r
1094 IN EFI_BLOCK_IO_PROTOCOL *This,\r
1095 IN UINT32 MediaId,\r
1096 IN EFI_LBA Lba,\r
1097 IN UINTN BufferSize,\r
1098 IN VOID *Buffer\r
1099 )\r
1100{\r
490b5ea1 1101 return BlockIoReadWrite ((VOID *) This, MediaId, Lba, NULL, BufferSize, Buffer, FALSE, TRUE);\r
ad86a50a 1102}\r
1103\r
1104\r
1105/**\r
1106 Flush the Block Device.\r
1107\r
1108 @param This Indicates a pointer to the calling context.\r
1109\r
1110 @retval EFI_SUCCESS All outstanding data was written to the device\r
1111 @retval EFI_DEVICE_ERROR The device reported an error while writing back the data\r
1112 @retval EFI_NO_MEDIA There is no media in the device.\r
1113\r
1114**/\r
1115EFI_STATUS\r
1116EFIAPI\r
1117AtaBlockIoFlushBlocks (\r
1118 IN EFI_BLOCK_IO_PROTOCOL *This\r
1119 )\r
1120{\r
1121 //\r
1122 // return directly\r
1123 //\r
1124 return EFI_SUCCESS;\r
1125}\r
1126\r
490b5ea1 1127/**\r
1128 Reset the Block Device.\r
1129\r
1130 @param[in] This Indicates a pointer to the calling context.\r
1131 @param[in] ExtendedVerification Driver may perform diagnostics on reset.\r
1132\r
1133 @retval EFI_SUCCESS The device was reset.\r
1134 @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
1135 not be reset.\r
1136\r
1137**/\r
1138EFI_STATUS\r
1139EFIAPI\r
1140AtaBlockIoResetEx (\r
1141 IN EFI_BLOCK_IO2_PROTOCOL *This,\r
1142 IN BOOLEAN ExtendedVerification\r
1143 )\r
1144{\r
1145 EFI_STATUS Status;\r
1146 ATA_DEVICE *AtaDevice;\r
1147 EFI_TPL OldTpl;\r
1148\r
1149 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1150\r
1151 AtaDevice = ATA_DEVICE_FROM_BLOCK_IO2 (This);\r
1152\r
1153 Status = ResetAtaDevice (AtaDevice);\r
1154\r
1155 if (EFI_ERROR (Status)) {\r
1156 Status = EFI_DEVICE_ERROR;\r
1157 }\r
1158\r
1159 gBS->RestoreTPL (OldTpl);\r
1160 return Status;\r
1161}\r
1162\r
1163/**\r
1164 Read BufferSize bytes from Lba into Buffer.\r
1165\r
1166 @param[in] This Indicates a pointer to the calling context.\r
1167 @param[in] MediaId Id of the media, changes every time the media is replaced.\r
1168 @param[in] Lba The starting Logical Block Address to read from.\r
1169 @param[in, out] Token A pointer to the token associated with the transaction.\r
1170 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.\r
1171 @param[out] Buffer A pointer to the destination buffer for the data. The caller is\r
1172 responsible for either having implicit or explicit ownership of the buffer.\r
1173\r
1174 @retval EFI_SUCCESS The read request was queued if Event is not NULL.\r
1175 The data was read correctly from the device if\r
1176 the Event is NULL.\r
1177 @retval EFI_DEVICE_ERROR The device reported an error while performing\r
1178 the read.\r
1179 @retval EFI_NO_MEDIA There is no media in the device.\r
1180 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.\r
1181 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the\r
1182 intrinsic block size of the device.\r
58727f29 1183 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,\r
490b5ea1 1184 or the buffer is not on proper alignment.\r
1185 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
1186 of resources.\r
1187\r
1188**/\r
1189EFI_STATUS\r
1190EFIAPI\r
1191AtaBlockIoReadBlocksEx (\r
1192 IN EFI_BLOCK_IO2_PROTOCOL *This,\r
1193 IN UINT32 MediaId,\r
1194 IN EFI_LBA Lba,\r
1195 IN OUT EFI_BLOCK_IO2_TOKEN *Token,\r
1196 IN UINTN BufferSize,\r
1197 OUT VOID *Buffer\r
1198 )\r
1199{\r
1200 return BlockIoReadWrite ((VOID *) This, MediaId, Lba, Token, BufferSize, Buffer, TRUE, FALSE);\r
1201}\r
1202\r
1203\r
1204/**\r
1205 Write BufferSize bytes from Lba into Buffer.\r
1206\r
1207 @param[in] This Indicates a pointer to the calling context.\r
1208 @param[in] MediaId The media ID that the write request is for.\r
1209 @param[in] Lba The starting logical block address to be written. The\r
1210 caller is responsible for writing to only legitimate\r
1211 locations.\r
1212 @param[in, out] Token A pointer to the token associated with the transaction.\r
1213 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.\r
1214 @param[in] Buffer A pointer to the source buffer for the data.\r
ad86a50a 1215\r
490b5ea1 1216 @retval EFI_SUCCESS The data was written correctly to the device.\r
1217 @retval EFI_WRITE_PROTECTED The device can not be written to.\r
1218 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.\r
1219 @retval EFI_NO_MEDIA There is no media in the device.\r
1220 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.\r
1221 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
58727f29 1222 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,\r
490b5ea1 1223 or the buffer is not on proper alignment.\r
1224\r
1225**/\r
1226EFI_STATUS\r
1227EFIAPI\r
1228AtaBlockIoWriteBlocksEx (\r
1229 IN EFI_BLOCK_IO2_PROTOCOL *This,\r
1230 IN UINT32 MediaId,\r
1231 IN EFI_LBA Lba,\r
1232 IN OUT EFI_BLOCK_IO2_TOKEN *Token,\r
1233 IN UINTN BufferSize,\r
1234 IN VOID *Buffer\r
1235 )\r
1236{\r
1237 return BlockIoReadWrite ((VOID *) This, MediaId, Lba, Token, BufferSize, Buffer, TRUE, TRUE);\r
1238}\r
1239\r
1240\r
1241/**\r
1242 Flush the Block Device.\r
1243\r
1244 @param[in] This Indicates a pointer to the calling context.\r
1245 @param[in, out] Token A pointer to the token associated with the transaction.\r
1246\r
1247 @retval EFI_SUCCESS All outstanding data was written to the device\r
1248 @retval EFI_DEVICE_ERROR The device reported an error while writing back the data\r
1249 @retval EFI_NO_MEDIA There is no media in the device.\r
1250\r
1251**/\r
1252EFI_STATUS\r
1253EFIAPI\r
1254AtaBlockIoFlushBlocksEx (\r
1255 IN EFI_BLOCK_IO2_PROTOCOL *This,\r
1256 IN OUT EFI_BLOCK_IO2_TOKEN *Token\r
1257 )\r
1258{\r
1259 //\r
3c063fed 1260 // Signal event and return directly.\r
490b5ea1 1261 //\r
1262 if (Token != NULL && Token->Event != NULL) {\r
1263 Token->TransactionStatus = EFI_SUCCESS;\r
1264 gBS->SignalEvent (Token->Event);\r
1265 }\r
1266 return EFI_SUCCESS;\r
1267}\r
ad86a50a 1268/**\r
1269 Provides inquiry information for the controller type.\r
58727f29 1270\r
ad86a50a 1271 This function is used by the IDE bus driver to get inquiry data. Data format\r
1272 of Identify data is defined by the Interface GUID.\r
1273\r
05a44e91 1274 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
1275 @param[in, out] InquiryData Pointer to a buffer for the inquiry data.\r
1276 @param[in, out] InquiryDataSize Pointer to the value for the inquiry data size.\r
ad86a50a 1277\r
1278 @retval EFI_SUCCESS The command was accepted without any errors.\r
58727f29 1279 @retval EFI_NOT_FOUND Device does not support this data class\r
1280 @retval EFI_DEVICE_ERROR Error reading InquiryData from device\r
1281 @retval EFI_BUFFER_TOO_SMALL InquiryDataSize not big enough\r
ad86a50a 1282\r
1283**/\r
1284EFI_STATUS\r
1285EFIAPI\r
1286AtaDiskInfoInquiry (\r
1287 IN EFI_DISK_INFO_PROTOCOL *This,\r
1288 IN OUT VOID *InquiryData,\r
1289 IN OUT UINT32 *InquiryDataSize\r
1290 )\r
1291{\r
1292 return EFI_NOT_FOUND;\r
1293}\r
1294\r
1295\r
1296/**\r
1297 Provides identify information for the controller type.\r
1298\r
1299 This function is used by the IDE bus driver to get identify data. Data format\r
1300 of Identify data is defined by the Interface GUID.\r
1301\r
58727f29 1302 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL\r
ad86a50a 1303 instance.\r
05a44e91 1304 @param[in, out] IdentifyData Pointer to a buffer for the identify data.\r
1305 @param[in, out] IdentifyDataSize Pointer to the value for the identify data\r
ad86a50a 1306 size.\r
1307\r
1308 @retval EFI_SUCCESS The command was accepted without any errors.\r
58727f29 1309 @retval EFI_NOT_FOUND Device does not support this data class\r
1310 @retval EFI_DEVICE_ERROR Error reading IdentifyData from device\r
1311 @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough\r
ad86a50a 1312\r
1313**/\r
1314EFI_STATUS\r
1315EFIAPI\r
1316AtaDiskInfoIdentify (\r
1317 IN EFI_DISK_INFO_PROTOCOL *This,\r
1318 IN OUT VOID *IdentifyData,\r
1319 IN OUT UINT32 *IdentifyDataSize\r
1320 )\r
1321{\r
1322 EFI_STATUS Status;\r
1323 ATA_DEVICE *AtaDevice;\r
1324\r
1325 AtaDevice = ATA_DEVICE_FROM_DISK_INFO (This);\r
1326\r
1327 Status = EFI_BUFFER_TOO_SMALL;\r
3c063fed 1328 if (*IdentifyDataSize >= sizeof (ATA_IDENTIFY_DATA)) {\r
ad86a50a 1329 Status = EFI_SUCCESS;\r
3c063fed 1330 CopyMem (IdentifyData, AtaDevice->IdentifyData, sizeof (ATA_IDENTIFY_DATA));\r
ad86a50a 1331 }\r
3c063fed 1332 *IdentifyDataSize = sizeof (ATA_IDENTIFY_DATA);\r
ad86a50a 1333\r
1334 return Status;\r
1335}\r
1336\r
1337\r
1338/**\r
1339 Provides sense data information for the controller type.\r
58727f29 1340\r
1341 This function is used by the IDE bus driver to get sense data.\r
ad86a50a 1342 Data format of Sense data is defined by the Interface GUID.\r
1343\r
05a44e91 1344 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
1345 @param[in, out] SenseData Pointer to the SenseData.\r
1346 @param[in, out] SenseDataSize Size of SenseData in bytes.\r
1347 @param[out] SenseDataNumber Pointer to the value for the sense data size.\r
ad86a50a 1348\r
1349 @retval EFI_SUCCESS The command was accepted without any errors.\r
1350 @retval EFI_NOT_FOUND Device does not support this data class.\r
1351 @retval EFI_DEVICE_ERROR Error reading SenseData from device.\r
1352 @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough.\r
1353\r
1354**/\r
1355EFI_STATUS\r
1356EFIAPI\r
1357AtaDiskInfoSenseData (\r
1358 IN EFI_DISK_INFO_PROTOCOL *This,\r
1359 IN OUT VOID *SenseData,\r
1360 IN OUT UINT32 *SenseDataSize,\r
1361 OUT UINT8 *SenseDataNumber\r
1362 )\r
1363{\r
1364 return EFI_NOT_FOUND;\r
1365}\r
1366\r
1367\r
1368/**\r
1369 This function is used by the IDE bus driver to get controller information.\r
1370\r
58727f29 1371 @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
ad86a50a 1372 @param[out] IdeChannel Pointer to the Ide Channel number. Primary or secondary.\r
1373 @param[out] IdeDevice Pointer to the Ide Device number. Master or slave.\r
1374\r
1375 @retval EFI_SUCCESS IdeChannel and IdeDevice are valid.\r
1376 @retval EFI_UNSUPPORTED This is not an IDE device.\r
1377\r
1378**/\r
1379EFI_STATUS\r
1380EFIAPI\r
1381AtaDiskInfoWhichIde (\r
1382 IN EFI_DISK_INFO_PROTOCOL *This,\r
1383 OUT UINT32 *IdeChannel,\r
1384 OUT UINT32 *IdeDevice\r
1385 )\r
1386{\r
1387 ATA_DEVICE *AtaDevice;\r
1388\r
1389 AtaDevice = ATA_DEVICE_FROM_DISK_INFO (This);\r
1390 *IdeChannel = AtaDevice->Port;\r
1391 *IdeDevice = AtaDevice->PortMultiplierPort;\r
1392\r
1393 return EFI_SUCCESS;\r
1394}\r
1395\r
c24097a5 1396/**\r
1397 Send a security protocol command to a device that receives data and/or the result\r
1398 of one or more commands sent by SendData.\r
1399\r
1400 The ReceiveData function sends a security protocol command to the given MediaId.\r
1401 The security protocol command sent is defined by SecurityProtocolId and contains\r
1402 the security protocol specific data SecurityProtocolSpecificData. The function\r
1403 returns the data from the security protocol command in PayloadBuffer.\r
1404\r
1405 For devices supporting the SCSI command set, the security protocol command is sent\r
1406 using the SECURITY PROTOCOL IN command defined in SPC-4.\r
1407\r
1408 For devices supporting the ATA command set, the security protocol command is sent\r
1409 using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize\r
1410 is non-zero.\r
1411\r
1412 If the PayloadBufferSize is zero, the security protocol command is sent using the\r
1413 Trusted Non-Data command defined in ATA8-ACS.\r
1414\r
1415 If PayloadBufferSize is too small to store the available data from the security\r
1416 protocol command, the function shall copy PayloadBufferSize bytes into the\r
1417 PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.\r
1418\r
1419 If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero,\r
1420 the function shall return EFI_INVALID_PARAMETER.\r
1421\r
1422 If the given MediaId does not support security protocol commands, the function shall\r
1423 return EFI_UNSUPPORTED. If there is no media in the device, the function returns\r
1424 EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device,\r
1425 the function returns EFI_MEDIA_CHANGED.\r
1426\r
1427 If the security protocol fails to complete within the Timeout period, the function\r
1428 shall return EFI_TIMEOUT.\r
1429\r
1430 If the security protocol command completes without an error, the function shall\r
1431 return EFI_SUCCESS. If the security protocol command completes with an error, the\r
1432 function shall return EFI_DEVICE_ERROR.\r
1433\r
1434 @param This Indicates a pointer to the calling context.\r
1435 @param MediaId ID of the medium to receive data from.\r
1436 @param Timeout The timeout, in 100ns units, to use for the execution\r
1437 of the security protocol command. A Timeout value of 0\r
1438 means that this function will wait indefinitely for the\r
1439 security protocol command to execute. If Timeout is greater\r
1440 than zero, then this function will return EFI_TIMEOUT\r
1441 if the time required to execute the receive data command\r
1442 is greater than Timeout.\r
1443 @param SecurityProtocolId The value of the "Security Protocol" parameter of\r
1444 the security protocol command to be sent.\r
1445 @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter\r
1446 of the security protocol command to be sent.\r
1447 @param PayloadBufferSize Size in bytes of the payload data buffer.\r
1448 @param PayloadBuffer A pointer to a destination buffer to store the security\r
1449 protocol command specific payload data for the security\r
1450 protocol command. The caller is responsible for having\r
1451 either implicit or explicit ownership of the buffer.\r
1452 @param PayloadTransferSize A pointer to a buffer to store the size in bytes of the\r
1453 data written to the payload data buffer.\r
1454\r
1455 @retval EFI_SUCCESS The security protocol command completed successfully.\r
1456 @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available\r
1457 data from the device. The PayloadBuffer contains the truncated data.\r
1458 @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands.\r
1459 @retval EFI_DEVICE_ERROR The security protocol command completed with an error.\r
1460 @retval EFI_NO_MEDIA There is no media in the device.\r
1461 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.\r
1462 @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and\r
1463 PayloadBufferSize is non-zero.\r
1464 @retval EFI_TIMEOUT A timeout occurred while waiting for the security\r
1465 protocol command to execute.\r
1466\r
1467**/\r
1468EFI_STATUS\r
1469EFIAPI\r
1470AtaStorageSecurityReceiveData (\r
1471 IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,\r
1472 IN UINT32 MediaId,\r
1473 IN UINT64 Timeout,\r
1474 IN UINT8 SecurityProtocolId,\r
1475 IN UINT16 SecurityProtocolSpecificData,\r
1476 IN UINTN PayloadBufferSize,\r
1477 OUT VOID *PayloadBuffer,\r
1478 OUT UINTN *PayloadTransferSize\r
1479 )\r
1480{\r
1481 EFI_STATUS Status;\r
1482 ATA_DEVICE *Private;\r
3c063fed 1483 EFI_TPL OldTpl;\r
c24097a5 1484\r
1485 DEBUG ((EFI_D_INFO, "EFI Storage Security Protocol - Read"));\r
1486 if ((PayloadBuffer == NULL || PayloadTransferSize == NULL) && PayloadBufferSize != 0) {\r
1487 return EFI_INVALID_PARAMETER;\r
1488 }\r
1489\r
1490 Status = EFI_SUCCESS;\r
1491 Private = ATA_DEVICE_FROM_STORAGE_SECURITY (This);\r
1492\r
1493 if (MediaId != Private->BlockIo.Media->MediaId) {\r
1494 return EFI_MEDIA_CHANGED;\r
1495 }\r
1496\r
1497 if (!Private->BlockIo.Media->MediaPresent) {\r
1498 return EFI_NO_MEDIA;\r
1499 }\r
1500\r
3c063fed 1501 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1502\r
c24097a5 1503 Status = TrustTransferAtaDevice (\r
1504 Private,\r
1505 PayloadBuffer,\r
1506 SecurityProtocolId,\r
1507 SecurityProtocolSpecificData,\r
1508 PayloadBufferSize,\r
1509 FALSE,\r
1510 Timeout,\r
1511 PayloadTransferSize\r
1512 );\r
1513\r
3c063fed 1514 gBS->RestoreTPL (OldTpl);\r
c24097a5 1515 return Status;\r
1516}\r
1517\r
1518/**\r
1519 Send a security protocol command to a device.\r
1520\r
1521 The SendData function sends a security protocol command containing the payload\r
1522 PayloadBuffer to the given MediaId. The security protocol command sent is\r
1523 defined by SecurityProtocolId and contains the security protocol specific data\r
1524 SecurityProtocolSpecificData. If the underlying protocol command requires a\r
1525 specific padding for the command payload, the SendData function shall add padding\r
1526 bytes to the command payload to satisfy the padding requirements.\r
1527\r
1528 For devices supporting the SCSI command set, the security protocol command is sent\r
1529 using the SECURITY PROTOCOL OUT command defined in SPC-4.\r
1530\r
1531 For devices supporting the ATA command set, the security protocol command is sent\r
1532 using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize\r
1533 is non-zero. If the PayloadBufferSize is zero, the security protocol command is\r
1534 sent using the Trusted Non-Data command defined in ATA8-ACS.\r
1535\r
1536 If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall\r
1537 return EFI_INVALID_PARAMETER.\r
1538\r
1539 If the given MediaId does not support security protocol commands, the function\r
1540 shall return EFI_UNSUPPORTED. If there is no media in the device, the function\r
1541 returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the\r
1542 device, the function returns EFI_MEDIA_CHANGED.\r
1543\r
1544 If the security protocol fails to complete within the Timeout period, the function\r
1545 shall return EFI_TIMEOUT.\r
1546\r
1547 If the security protocol command completes without an error, the function shall return\r
1548 EFI_SUCCESS. If the security protocol command completes with an error, the function\r
1549 shall return EFI_DEVICE_ERROR.\r
1550\r
1551 @param This Indicates a pointer to the calling context.\r
1552 @param MediaId ID of the medium to receive data from.\r
1553 @param Timeout The timeout, in 100ns units, to use for the execution\r
1554 of the security protocol command. A Timeout value of 0\r
1555 means that this function will wait indefinitely for the\r
1556 security protocol command to execute. If Timeout is greater\r
1557 than zero, then this function will return EFI_TIMEOUT\r
1558 if the time required to execute the receive data command\r
1559 is greater than Timeout.\r
1560 @param SecurityProtocolId The value of the "Security Protocol" parameter of\r
1561 the security protocol command to be sent.\r
1562 @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter\r
1563 of the security protocol command to be sent.\r
1564 @param PayloadBufferSize Size in bytes of the payload data buffer.\r
1565 @param PayloadBuffer A pointer to a destination buffer to store the security\r
1566 protocol command specific payload data for the security\r
1567 protocol command.\r
1568\r
1569 @retval EFI_SUCCESS The security protocol command completed successfully.\r
1570 @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands.\r
1571 @retval EFI_DEVICE_ERROR The security protocol command completed with an error.\r
1572 @retval EFI_NO_MEDIA There is no media in the device.\r
1573 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.\r
1574 @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and PayloadBufferSize is non-zero.\r
1575 @retval EFI_TIMEOUT A timeout occurred while waiting for the security\r
1576 protocol command to execute.\r
1577\r
1578**/\r
1579EFI_STATUS\r
1580EFIAPI\r
1581AtaStorageSecuritySendData (\r
1582 IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,\r
1583 IN UINT32 MediaId,\r
1584 IN UINT64 Timeout,\r
1585 IN UINT8 SecurityProtocolId,\r
1586 IN UINT16 SecurityProtocolSpecificData,\r
1587 IN UINTN PayloadBufferSize,\r
1588 IN VOID *PayloadBuffer\r
1589 )\r
1590{\r
1591 EFI_STATUS Status;\r
1592 ATA_DEVICE *Private;\r
3c063fed 1593 EFI_TPL OldTpl;\r
c24097a5 1594\r
1595 DEBUG ((EFI_D_INFO, "EFI Storage Security Protocol - Send"));\r
1596 if ((PayloadBuffer == NULL) && (PayloadBufferSize != 0)) {\r
1597 return EFI_INVALID_PARAMETER;\r
1598 }\r
1599\r
1600 Status = EFI_SUCCESS;\r
1601 Private = ATA_DEVICE_FROM_STORAGE_SECURITY (This);\r
1602\r
1603 if (MediaId != Private->BlockIo.Media->MediaId) {\r
1604 return EFI_MEDIA_CHANGED;\r
1605 }\r
1606\r
3c063fed 1607 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
c24097a5 1608 Status = TrustTransferAtaDevice (\r
1609 Private,\r
1610 PayloadBuffer,\r
1611 SecurityProtocolId,\r
1612 SecurityProtocolSpecificData,\r
1613 PayloadBufferSize,\r
1614 TRUE,\r
1615 Timeout,\r
1616 NULL\r
1617 );\r
1618\r
3c063fed 1619 gBS->RestoreTPL (OldTpl);\r
c24097a5 1620 return Status;\r
1621}\r
ad86a50a 1622\r
1623/**\r
1624 The user Entry Point for module AtaBus. The user code starts with this function.\r
1625\r
1626 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
1627 @param[in] SystemTable A pointer to the EFI System Table.\r
1628\r
1629 @retval EFI_SUCCESS The entry point is executed successfully.\r
1630 @retval other Some error occurs when executing this entry point.\r
1631\r
1632**/\r
1633EFI_STATUS\r
1634EFIAPI\r
1635InitializeAtaBus(\r
1636 IN EFI_HANDLE ImageHandle,\r
1637 IN EFI_SYSTEM_TABLE *SystemTable\r
1638 )\r
1639{\r
1640 EFI_STATUS Status;\r
1641\r
1642 //\r
1643 // Install driver model protocol(s).\r
1644 //\r
1645 Status = EfiLibInstallDriverBindingComponentName2 (\r
1646 ImageHandle,\r
1647 SystemTable,\r
1648 &gAtaBusDriverBinding,\r
1649 ImageHandle,\r
1650 &gAtaBusComponentName,\r
1651 &gAtaBusComponentName2\r
1652 );\r
1653 ASSERT_EFI_ERROR (Status);\r
1654\r
1655 return Status;\r
1656}\r