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