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