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