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