]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Pci/SataControllerDxe/SataController.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / SataControllerDxe / SataController.c
1 /** @file
2 This driver module produces IDE_CONTROLLER_INIT protocol for Sata Controllers.
3
4 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2018, ARM Ltd. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "SataController.h"
11
12 ///
13 /// EFI_DRIVER_BINDING_PROTOCOL instance
14 ///
15 EFI_DRIVER_BINDING_PROTOCOL gSataControllerDriverBinding = {
16 SataControllerSupported,
17 SataControllerStart,
18 SataControllerStop,
19 0xa,
20 NULL,
21 NULL
22 };
23
24 /**
25 Read AHCI Operation register.
26
27 @param PciIo The PCI IO protocol instance.
28 @param Offset The operation register offset.
29
30 @return The register content read.
31
32 **/
33 UINT32
34 EFIAPI
35 AhciReadReg (
36 IN EFI_PCI_IO_PROTOCOL *PciIo,
37 IN UINT32 Offset
38 )
39 {
40 UINT32 Data;
41
42 ASSERT (PciIo != NULL);
43
44 Data = 0;
45
46 PciIo->Mem.Read (
47 PciIo,
48 EfiPciIoWidthUint32,
49 AHCI_BAR_INDEX,
50 (UINT64)Offset,
51 1,
52 &Data
53 );
54
55 return Data;
56 }
57
58 /**
59 This function is used to calculate the best PIO mode supported by specific IDE device
60
61 @param IdentifyData The identify data of specific IDE device.
62 @param DisPioMode Disqualified PIO modes collection.
63 @param SelectedMode Available PIO modes collection.
64
65 @retval EFI_SUCCESS Best PIO modes are returned.
66 @retval EFI_UNSUPPORTED The device doesn't support PIO mode,
67 or all supported modes have been disqualified.
68 **/
69 EFI_STATUS
70 CalculateBestPioMode (
71 IN EFI_IDENTIFY_DATA *IdentifyData,
72 IN UINT16 *DisPioMode OPTIONAL,
73 OUT UINT16 *SelectedMode
74 )
75 {
76 UINT16 PioMode;
77 UINT16 AdvancedPioMode;
78 UINT16 Temp;
79 UINT16 Index;
80 UINT16 MinimumPioCycleTime;
81
82 Temp = 0xff;
83
84 PioMode = (UINT8)(((ATA5_IDENTIFY_DATA *)(&(IdentifyData->AtaData)))->pio_cycle_timing >> 8);
85
86 //
87 // See whether Identify Data word 64 - 70 are valid
88 //
89 if ((IdentifyData->AtaData.field_validity & 0x02) == 0x02) {
90 AdvancedPioMode = IdentifyData->AtaData.advanced_pio_modes;
91 DEBUG ((DEBUG_INFO, "CalculateBestPioMode: AdvancedPioMode = %x\n", AdvancedPioMode));
92
93 for (Index = 0; Index < 8; Index++) {
94 if ((AdvancedPioMode & 0x01) != 0) {
95 Temp = Index;
96 }
97
98 AdvancedPioMode >>= 1;
99 }
100
101 //
102 // If Temp is modified, mean the advanced_pio_modes is not zero;
103 // if Temp is not modified, mean there is no advanced PIO mode supported,
104 // the best PIO Mode is the value in pio_cycle_timing.
105 //
106 if (Temp != 0xff) {
107 AdvancedPioMode = (UINT16)(Temp + 3);
108 } else {
109 AdvancedPioMode = PioMode;
110 }
111
112 //
113 // Limit the PIO mode to at most PIO4.
114 //
115 PioMode = (UINT16)MIN (AdvancedPioMode, 4);
116
117 MinimumPioCycleTime = IdentifyData->AtaData.min_pio_cycle_time_with_flow_control;
118
119 if (MinimumPioCycleTime <= 120) {
120 PioMode = (UINT16)MIN (4, PioMode);
121 } else if (MinimumPioCycleTime <= 180) {
122 PioMode = (UINT16)MIN (3, PioMode);
123 } else if (MinimumPioCycleTime <= 240) {
124 PioMode = (UINT16)MIN (2, PioMode);
125 } else {
126 PioMode = 0;
127 }
128
129 //
130 // Degrade the PIO mode if the mode has been disqualified
131 //
132 if (DisPioMode != NULL) {
133 if (*DisPioMode < 2) {
134 return EFI_UNSUPPORTED; // no mode below ATA_PIO_MODE_BELOW_2
135 }
136
137 if (PioMode >= *DisPioMode) {
138 PioMode = (UINT16)(*DisPioMode - 1);
139 }
140 }
141
142 if (PioMode < 2) {
143 *SelectedMode = 1; // ATA_PIO_MODE_BELOW_2;
144 } else {
145 *SelectedMode = PioMode; // ATA_PIO_MODE_2 to ATA_PIO_MODE_4;
146 }
147 } else {
148 //
149 // Identify Data word 64 - 70 are not valid
150 // Degrade the PIO mode if the mode has been disqualified
151 //
152 if (DisPioMode != NULL) {
153 if (*DisPioMode < 2) {
154 return EFI_UNSUPPORTED; // no mode below ATA_PIO_MODE_BELOW_2
155 }
156
157 if (PioMode == *DisPioMode) {
158 PioMode--;
159 }
160 }
161
162 if (PioMode < 2) {
163 *SelectedMode = 1; // ATA_PIO_MODE_BELOW_2;
164 } else {
165 *SelectedMode = 2; // ATA_PIO_MODE_2;
166 }
167 }
168
169 return EFI_SUCCESS;
170 }
171
172 /**
173 This function is used to calculate the best UDMA mode supported by specific IDE device
174
175 @param IdentifyData The identify data of specific IDE device.
176 @param DisUDmaMode Disqualified UDMA modes collection.
177 @param SelectedMode Available UDMA modes collection.
178
179 @retval EFI_SUCCESS Best UDMA modes are returned.
180 @retval EFI_UNSUPPORTED The device doesn't support UDMA mode,
181 or all supported modes have been disqualified.
182 **/
183 EFI_STATUS
184 CalculateBestUdmaMode (
185 IN EFI_IDENTIFY_DATA *IdentifyData,
186 IN UINT16 *DisUDmaMode OPTIONAL,
187 OUT UINT16 *SelectedMode
188 )
189 {
190 UINT16 TempMode;
191 UINT16 DeviceUDmaMode;
192
193 DeviceUDmaMode = 0;
194
195 //
196 // Check whether the WORD 88 (supported UltraDMA by drive) is valid
197 //
198 if ((IdentifyData->AtaData.field_validity & 0x04) == 0x00) {
199 return EFI_UNSUPPORTED;
200 }
201
202 DeviceUDmaMode = IdentifyData->AtaData.ultra_dma_mode;
203 DEBUG ((DEBUG_INFO, "CalculateBestUdmaMode: DeviceUDmaMode = %x\n", DeviceUDmaMode));
204 DeviceUDmaMode &= 0x3f;
205 TempMode = 0; // initialize it to UDMA-0
206
207 while ((DeviceUDmaMode >>= 1) != 0) {
208 TempMode++;
209 }
210
211 //
212 // Degrade the UDMA mode if the mode has been disqualified
213 //
214 if (DisUDmaMode != NULL) {
215 if (*DisUDmaMode == 0) {
216 *SelectedMode = 0;
217 return EFI_UNSUPPORTED; // no mode below ATA_UDMA_MODE_0
218 }
219
220 if (TempMode >= *DisUDmaMode) {
221 TempMode = (UINT16)(*DisUDmaMode - 1);
222 }
223 }
224
225 //
226 // Possible returned mode is between ATA_UDMA_MODE_0 and ATA_UDMA_MODE_5
227 //
228 *SelectedMode = TempMode;
229
230 return EFI_SUCCESS;
231 }
232
233 /**
234 The Entry Point of module. It follows the standard UEFI driver model.
235
236 @param[in] ImageHandle The firmware allocated handle for the EFI image.
237 @param[in] SystemTable A pointer to the EFI System Table.
238
239 @retval EFI_SUCCESS The entry point is executed successfully.
240 @retval other Some error occurs when executing this entry point.
241
242 **/
243 EFI_STATUS
244 EFIAPI
245 InitializeSataControllerDriver (
246 IN EFI_HANDLE ImageHandle,
247 IN EFI_SYSTEM_TABLE *SystemTable
248 )
249 {
250 EFI_STATUS Status;
251
252 //
253 // Install driver model protocol(s).
254 //
255 Status = EfiLibInstallDriverBindingComponentName2 (
256 ImageHandle,
257 SystemTable,
258 &gSataControllerDriverBinding,
259 ImageHandle,
260 &gSataControllerComponentName,
261 &gSataControllerComponentName2
262 );
263 ASSERT_EFI_ERROR (Status);
264
265 return Status;
266 }
267
268 /**
269 Supported function of Driver Binding protocol for this driver.
270 Test to see if this driver supports ControllerHandle.
271
272 @param This Protocol instance pointer.
273 @param Controller Handle of device to test.
274 @param RemainingDevicePath A pointer to the device path.
275 it should be ignored by device driver.
276
277 @retval EFI_SUCCESS This driver supports this device.
278 @retval EFI_ALREADY_STARTED This driver is already running on this device.
279 @retval other This driver does not support this device.
280
281 **/
282 EFI_STATUS
283 EFIAPI
284 SataControllerSupported (
285 IN EFI_DRIVER_BINDING_PROTOCOL *This,
286 IN EFI_HANDLE Controller,
287 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
288 )
289 {
290 EFI_STATUS Status;
291 EFI_PCI_IO_PROTOCOL *PciIo;
292 PCI_TYPE00 PciData;
293
294 //
295 // Attempt to open PCI I/O Protocol
296 //
297 Status = gBS->OpenProtocol (
298 Controller,
299 &gEfiPciIoProtocolGuid,
300 (VOID **)&PciIo,
301 This->DriverBindingHandle,
302 Controller,
303 EFI_OPEN_PROTOCOL_GET_PROTOCOL
304 );
305 if (EFI_ERROR (Status)) {
306 return Status;
307 }
308
309 //
310 // Now further check the PCI header: Base Class (offset 0x0B) and
311 // Sub Class (offset 0x0A). This controller should be an SATA controller
312 //
313 Status = PciIo->Pci.Read (
314 PciIo,
315 EfiPciIoWidthUint8,
316 PCI_CLASSCODE_OFFSET,
317 sizeof (PciData.Hdr.ClassCode),
318 PciData.Hdr.ClassCode
319 );
320 if (EFI_ERROR (Status)) {
321 return EFI_UNSUPPORTED;
322 }
323
324 if (IS_PCI_IDE (&PciData) || IS_PCI_SATADPA (&PciData)) {
325 return EFI_SUCCESS;
326 }
327
328 return EFI_UNSUPPORTED;
329 }
330
331 /**
332 This routine is called right after the .Supported() called and
333 Start this driver on ControllerHandle.
334
335 @param This Protocol instance pointer.
336 @param Controller Handle of device to bind driver to.
337 @param RemainingDevicePath A pointer to the device path.
338 it should be ignored by device driver.
339
340 @retval EFI_SUCCESS This driver is added to this device.
341 @retval EFI_ALREADY_STARTED This driver is already running on this device.
342 @retval other Some error occurs when binding this driver to this device.
343
344 **/
345 EFI_STATUS
346 EFIAPI
347 SataControllerStart (
348 IN EFI_DRIVER_BINDING_PROTOCOL *This,
349 IN EFI_HANDLE Controller,
350 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
351 )
352 {
353 EFI_STATUS Status;
354 EFI_PCI_IO_PROTOCOL *PciIo;
355 PCI_TYPE00 PciData;
356 EFI_SATA_CONTROLLER_PRIVATE_DATA *Private;
357 UINT32 Data32;
358 UINTN TotalCount;
359 UINT64 Supports;
360 UINT8 MaxPortNumber;
361
362 DEBUG ((DEBUG_INFO, "SataControllerStart start\n"));
363
364 Private = NULL;
365
366 //
367 // Now test and open PCI I/O Protocol
368 //
369 Status = gBS->OpenProtocol (
370 Controller,
371 &gEfiPciIoProtocolGuid,
372 (VOID **)&PciIo,
373 This->DriverBindingHandle,
374 Controller,
375 EFI_OPEN_PROTOCOL_BY_DRIVER
376 );
377 if (EFI_ERROR (Status)) {
378 DEBUG ((DEBUG_ERROR, "SataControllerStart error. return status = %r\n", Status));
379 return Status;
380 }
381
382 //
383 // Allocate Sata Private Data structure
384 //
385 Private = AllocateZeroPool (sizeof (EFI_SATA_CONTROLLER_PRIVATE_DATA));
386 if (Private == NULL) {
387 Status = EFI_OUT_OF_RESOURCES;
388 goto Done;
389 }
390
391 //
392 // Initialize Sata Private Data
393 //
394 Private->Signature = SATA_CONTROLLER_SIGNATURE;
395 Private->PciIo = PciIo;
396 Private->IdeInit.GetChannelInfo = IdeInitGetChannelInfo;
397 Private->IdeInit.NotifyPhase = IdeInitNotifyPhase;
398 Private->IdeInit.SubmitData = IdeInitSubmitData;
399 Private->IdeInit.DisqualifyMode = IdeInitDisqualifyMode;
400 Private->IdeInit.CalculateMode = IdeInitCalculateMode;
401 Private->IdeInit.SetTiming = IdeInitSetTiming;
402 Private->IdeInit.EnumAll = SATA_ENUMER_ALL;
403 Private->PciAttributesChanged = FALSE;
404
405 //
406 // Save original PCI attributes
407 //
408 Status = PciIo->Attributes (
409 PciIo,
410 EfiPciIoAttributeOperationGet,
411 0,
412 &Private->OriginalPciAttributes
413 );
414 if (EFI_ERROR (Status)) {
415 goto Done;
416 }
417
418 DEBUG ((
419 DEBUG_INFO,
420 "Original PCI Attributes = 0x%llx\n",
421 Private->OriginalPciAttributes
422 ));
423
424 Status = PciIo->Attributes (
425 PciIo,
426 EfiPciIoAttributeOperationSupported,
427 0,
428 &Supports
429 );
430 if (EFI_ERROR (Status)) {
431 goto Done;
432 }
433
434 DEBUG ((DEBUG_INFO, "Supported PCI Attributes = 0x%llx\n", Supports));
435
436 Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
437 Status = PciIo->Attributes (
438 PciIo,
439 EfiPciIoAttributeOperationEnable,
440 Supports,
441 NULL
442 );
443 if (EFI_ERROR (Status)) {
444 goto Done;
445 }
446
447 DEBUG ((DEBUG_INFO, "Enabled PCI Attributes = 0x%llx\n", Supports));
448 Private->PciAttributesChanged = TRUE;
449
450 Status = PciIo->Pci.Read (
451 PciIo,
452 EfiPciIoWidthUint8,
453 PCI_CLASSCODE_OFFSET,
454 sizeof (PciData.Hdr.ClassCode),
455 PciData.Hdr.ClassCode
456 );
457 if (EFI_ERROR (Status)) {
458 ASSERT (FALSE);
459 goto Done;
460 }
461
462 if (IS_PCI_IDE (&PciData)) {
463 Private->IdeInit.ChannelCount = IDE_MAX_CHANNEL;
464 Private->DeviceCount = IDE_MAX_DEVICES;
465 } else if (IS_PCI_SATADPA (&PciData)) {
466 //
467 // Read Ports Implemented(PI) to calculate max port number (0 based).
468 //
469 Data32 = AhciReadReg (PciIo, R_AHCI_PI);
470 DEBUG ((DEBUG_INFO, "Ports Implemented(PI) = 0x%x\n", Data32));
471 if (Data32 == 0) {
472 Status = EFI_UNSUPPORTED;
473 goto Done;
474 }
475
476 MaxPortNumber = 31;
477 while (MaxPortNumber > 0) {
478 if ((Data32 & ((UINT32)1 << MaxPortNumber)) != 0) {
479 break;
480 }
481
482 MaxPortNumber--;
483 }
484
485 //
486 // Make the ChannelCount equal to the max port number (0 based) plus 1.
487 //
488 Private->IdeInit.ChannelCount = MaxPortNumber + 1;
489
490 //
491 // Read HBA Capabilities(CAP) to get Supports Port Multiplier(SPM).
492 //
493 Data32 = AhciReadReg (PciIo, R_AHCI_CAP);
494 DEBUG ((DEBUG_INFO, "HBA Capabilities(CAP) = 0x%x\n", Data32));
495 Private->DeviceCount = AHCI_MAX_DEVICES;
496 if ((Data32 & B_AHCI_CAP_SPM) == B_AHCI_CAP_SPM) {
497 Private->DeviceCount = AHCI_MULTI_MAX_DEVICES;
498 }
499 }
500
501 TotalCount = (UINTN)(Private->IdeInit.ChannelCount) * (UINTN)(Private->DeviceCount);
502 Private->DisqualifiedModes = AllocateZeroPool ((sizeof (EFI_ATA_COLLECTIVE_MODE)) * TotalCount);
503 if (Private->DisqualifiedModes == NULL) {
504 Status = EFI_OUT_OF_RESOURCES;
505 goto Done;
506 }
507
508 Private->IdentifyData = AllocateZeroPool ((sizeof (EFI_IDENTIFY_DATA)) * TotalCount);
509 if (Private->IdentifyData == NULL) {
510 Status = EFI_OUT_OF_RESOURCES;
511 goto Done;
512 }
513
514 Private->IdentifyValid = AllocateZeroPool ((sizeof (BOOLEAN)) * TotalCount);
515 if (Private->IdentifyValid == NULL) {
516 Status = EFI_OUT_OF_RESOURCES;
517 goto Done;
518 }
519
520 //
521 // Install IDE Controller Init Protocol to this instance
522 //
523 Status = gBS->InstallMultipleProtocolInterfaces (
524 &Controller,
525 &gEfiIdeControllerInitProtocolGuid,
526 &(Private->IdeInit),
527 NULL
528 );
529
530 Done:
531 if (EFI_ERROR (Status)) {
532 gBS->CloseProtocol (
533 Controller,
534 &gEfiPciIoProtocolGuid,
535 This->DriverBindingHandle,
536 Controller
537 );
538 if (Private != NULL) {
539 if (Private->DisqualifiedModes != NULL) {
540 FreePool (Private->DisqualifiedModes);
541 }
542
543 if (Private->IdentifyData != NULL) {
544 FreePool (Private->IdentifyData);
545 }
546
547 if (Private->IdentifyValid != NULL) {
548 FreePool (Private->IdentifyValid);
549 }
550
551 if (Private->PciAttributesChanged) {
552 //
553 // Restore original PCI attributes
554 //
555 PciIo->Attributes (
556 PciIo,
557 EfiPciIoAttributeOperationSet,
558 Private->OriginalPciAttributes,
559 NULL
560 );
561 }
562
563 FreePool (Private);
564 }
565 }
566
567 DEBUG ((DEBUG_INFO, "SataControllerStart end with %r\n", Status));
568
569 return Status;
570 }
571
572 /**
573 Stop this driver on ControllerHandle.
574
575 @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
576 @param Controller A handle to the device being stopped.
577 @param NumberOfChildren The number of child device handles in ChildHandleBuffer.
578 @param ChildHandleBuffer An array of child handles to be freed.
579
580 @retval EFI_SUCCESS This driver is removed from this device.
581 @retval other Some error occurs when removing this driver from this device.
582
583 **/
584 EFI_STATUS
585 EFIAPI
586 SataControllerStop (
587 IN EFI_DRIVER_BINDING_PROTOCOL *This,
588 IN EFI_HANDLE Controller,
589 IN UINTN NumberOfChildren,
590 IN EFI_HANDLE *ChildHandleBuffer
591 )
592 {
593 EFI_STATUS Status;
594 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;
595 EFI_SATA_CONTROLLER_PRIVATE_DATA *Private;
596
597 //
598 // Open the produced protocol
599 //
600 Status = gBS->OpenProtocol (
601 Controller,
602 &gEfiIdeControllerInitProtocolGuid,
603 (VOID **)&IdeInit,
604 This->DriverBindingHandle,
605 Controller,
606 EFI_OPEN_PROTOCOL_GET_PROTOCOL
607 );
608 if (EFI_ERROR (Status)) {
609 return EFI_UNSUPPORTED;
610 }
611
612 Private = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (IdeInit);
613 ASSERT (Private != NULL);
614
615 //
616 // Uninstall the IDE Controller Init Protocol from this instance
617 //
618 Status = gBS->UninstallMultipleProtocolInterfaces (
619 Controller,
620 &gEfiIdeControllerInitProtocolGuid,
621 &(Private->IdeInit),
622 NULL
623 );
624 if (EFI_ERROR (Status)) {
625 return Status;
626 }
627
628 if (Private != NULL) {
629 if (Private->DisqualifiedModes != NULL) {
630 FreePool (Private->DisqualifiedModes);
631 }
632
633 if (Private->IdentifyData != NULL) {
634 FreePool (Private->IdentifyData);
635 }
636
637 if (Private->IdentifyValid != NULL) {
638 FreePool (Private->IdentifyValid);
639 }
640
641 if (Private->PciAttributesChanged) {
642 //
643 // Restore original PCI attributes
644 //
645 Private->PciIo->Attributes (
646 Private->PciIo,
647 EfiPciIoAttributeOperationSet,
648 Private->OriginalPciAttributes,
649 NULL
650 );
651 }
652
653 FreePool (Private);
654 }
655
656 //
657 // Close protocols opened by Sata Controller driver
658 //
659 return gBS->CloseProtocol (
660 Controller,
661 &gEfiPciIoProtocolGuid,
662 This->DriverBindingHandle,
663 Controller
664 );
665 }
666
667 /**
668 Calculate the flat array subscript of a (Channel, Device) pair.
669
670 @param[in] Private The private data structure corresponding to the
671 SATA controller that attaches the device for
672 which the flat array subscript is being
673 calculated.
674
675 @param[in] Channel The channel (ie. port) number on the SATA
676 controller that the device is attached to.
677
678 @param[in] Device The device number on the channel.
679
680 @return The flat array subscript suitable for indexing DisqualifiedModes,
681 IdentifyData, and IdentifyValid.
682 **/
683 STATIC
684 UINTN
685 FlatDeviceIndex (
686 IN CONST EFI_SATA_CONTROLLER_PRIVATE_DATA *Private,
687 IN UINTN Channel,
688 IN UINTN Device
689 )
690 {
691 ASSERT (Private != NULL);
692 ASSERT (Channel < Private->IdeInit.ChannelCount);
693 ASSERT (Device < Private->DeviceCount);
694
695 return Channel * Private->DeviceCount + Device;
696 }
697
698 //
699 // Interface functions of IDE_CONTROLLER_INIT protocol
700 //
701
702 /**
703 Returns the information about the specified IDE channel.
704
705 This function can be used to obtain information about a particular IDE channel.
706 The driver entity uses this information during the enumeration process.
707
708 If Enabled is set to FALSE, the driver entity will not scan the channel. Note
709 that it will not prevent an operating system driver from scanning the channel.
710
711 For most of today's controllers, MaxDevices will either be 1 or 2. For SATA
712 controllers, this value will always be 1. SATA configurations can contain SATA
713 port multipliers. SATA port multipliers behave like SATA bridges and can support
714 up to 16 devices on the other side. If a SATA port out of the IDE controller
715 is connected to a port multiplier, MaxDevices will be set to the number of SATA
716 devices that the port multiplier supports. Because today's port multipliers
717 support up to fifteen SATA devices, this number can be as large as fifteen. The IDE
718 bus driver is required to scan for the presence of port multipliers behind an SATA
719 controller and enumerate up to MaxDevices number of devices behind the port
720 multiplier.
721
722 In this context, the devices behind a port multiplier constitute a channel.
723
724 @param[in] This The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
725 @param[in] Channel Zero-based channel number.
726 @param[out] Enabled TRUE if this channel is enabled. Disabled channels
727 are not scanned to see if any devices are present.
728 @param[out] MaxDevices The maximum number of IDE devices that the bus driver
729 can expect on this channel. For the ATA/ATAPI
730 specification, version 6, this number will either be
731 one or two. For Serial ATA (SATA) configurations with a
732 port multiplier, this number can be as large as fifteen.
733
734 @retval EFI_SUCCESS Information was returned without any errors.
735 @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount).
736
737 **/
738 EFI_STATUS
739 EFIAPI
740 IdeInitGetChannelInfo (
741 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
742 IN UINT8 Channel,
743 OUT BOOLEAN *Enabled,
744 OUT UINT8 *MaxDevices
745 )
746 {
747 EFI_SATA_CONTROLLER_PRIVATE_DATA *Private;
748
749 Private = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
750 ASSERT (Private != NULL);
751
752 if (Channel < This->ChannelCount) {
753 *Enabled = TRUE;
754 *MaxDevices = Private->DeviceCount;
755 return EFI_SUCCESS;
756 }
757
758 *Enabled = FALSE;
759 return EFI_INVALID_PARAMETER;
760 }
761
762 /**
763 The notifications from the driver entity that it is about to enter a certain
764 phase of the IDE channel enumeration process.
765
766 This function can be used to notify the IDE controller driver to perform
767 specific actions, including any chipset-specific initialization, so that the
768 chipset is ready to enter the next phase. Seven notification points are defined
769 at this time.
770
771 More synchronization points may be added as required in the future.
772
773 @param[in] This The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL
774 instance.
775 @param[in] Phase The phase during enumeration.
776 @param[in] Channel Zero-based channel number.
777
778 @retval EFI_SUCCESS The notification was accepted without any errors.
779 @retval EFI_UNSUPPORTED Phase is not supported.
780 @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount).
781 @retval EFI_NOT_READY This phase cannot be entered at this time; for
782 example, an attempt was made to enter a Phase
783 without having entered one or more previous
784 Phase.
785
786 **/
787 EFI_STATUS
788 EFIAPI
789 IdeInitNotifyPhase (
790 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
791 IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase,
792 IN UINT8 Channel
793 )
794 {
795 return EFI_SUCCESS;
796 }
797
798 /**
799 Submits the device information to the IDE controller driver.
800
801 This function is used by the driver entity to pass detailed information about
802 a particular device to the IDE controller driver. The driver entity obtains
803 this information by issuing an ATA or ATAPI IDENTIFY_DEVICE command. IdentifyData
804 is the pointer to the response data buffer. The IdentifyData buffer is owned
805 by the driver entity, and the IDE controller driver must make a local copy
806 of the entire buffer or parts of the buffer as needed. The original IdentifyData
807 buffer pointer may not be valid when
808
809 - EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() or
810 - EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() is called at a later point.
811
812 The IDE controller driver may consult various fields of EFI_IDENTIFY_DATA to
813 compute the optimum mode for the device. These fields are not limited to the
814 timing information. For example, an implementation of the IDE controller driver
815 may examine the vendor and type/mode field to match known bad drives.
816
817 The driver entity may submit drive information in any order, as long as it
818 submits information for all the devices belonging to the enumeration group
819 before EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() is called for any device
820 in that enumeration group. If a device is absent, EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
821 should be called with IdentifyData set to NULL. The IDE controller driver may
822 not have any other mechanism to know whether a device is present or not. Therefore,
823 setting IdentifyData to NULL does not constitute an error condition.
824 EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() can be called only once for a
825 given (Channel, Device) pair.
826
827 @param[in] This A pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
828 @param[in] Channel Zero-based channel number.
829 @param[in] Device Zero-based device number on the Channel.
830 @param[in] IdentifyData The device's response to the ATA IDENTIFY_DEVICE command.
831
832 @retval EFI_SUCCESS The information was accepted without any errors.
833 @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount).
834 @retval EFI_INVALID_PARAMETER Device is invalid.
835
836 **/
837 EFI_STATUS
838 EFIAPI
839 IdeInitSubmitData (
840 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
841 IN UINT8 Channel,
842 IN UINT8 Device,
843 IN EFI_IDENTIFY_DATA *IdentifyData
844 )
845 {
846 EFI_SATA_CONTROLLER_PRIVATE_DATA *Private;
847 UINTN DeviceIndex;
848
849 Private = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
850 ASSERT (Private != NULL);
851
852 if ((Channel >= This->ChannelCount) || (Device >= Private->DeviceCount)) {
853 return EFI_INVALID_PARAMETER;
854 }
855
856 DeviceIndex = FlatDeviceIndex (Private, Channel, Device);
857
858 //
859 // Make a local copy of device's IdentifyData and mark the valid flag
860 //
861 if (IdentifyData != NULL) {
862 CopyMem (
863 &(Private->IdentifyData[DeviceIndex]),
864 IdentifyData,
865 sizeof (EFI_IDENTIFY_DATA)
866 );
867
868 Private->IdentifyValid[DeviceIndex] = TRUE;
869 } else {
870 Private->IdentifyValid[DeviceIndex] = FALSE;
871 }
872
873 return EFI_SUCCESS;
874 }
875
876 /**
877 Disqualifies specific modes for an IDE device.
878
879 This function allows the driver entity or other drivers (such as platform
880 drivers) to reject certain timing modes and request the IDE controller driver
881 to recalculate modes. This function allows the driver entity and the IDE
882 controller driver to negotiate the timings on a per-device basis. This function
883 is useful in the case of drives that lie about their capabilities. An example
884 is when the IDE device fails to accept the timing modes that are calculated
885 by the IDE controller driver based on the response to the Identify Drive command.
886
887 If the driver entity does not want to limit the ATA timing modes and leave that
888 decision to the IDE controller driver, it can either not call this function for
889 the given device or call this function and set the Valid flag to FALSE for all
890 modes that are listed in EFI_ATA_COLLECTIVE_MODE.
891
892 The driver entity may disqualify modes for a device in any order and any number
893 of times.
894
895 This function can be called multiple times to invalidate multiple modes of the
896 same type (e.g., Programmed Input/Output [PIO] modes 3 and 4). See the ATA/ATAPI
897 specification for more information on PIO modes.
898
899 For Serial ATA (SATA) controllers, this member function can be used to disqualify
900 a higher transfer rate mode on a given channel. For example, a platform driver
901 may inform the IDE controller driver to not use second-generation (Gen2) speeds
902 for a certain SATA drive.
903
904 @param[in] This The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
905 @param[in] Channel The zero-based channel number.
906 @param[in] Device The zero-based device number on the Channel.
907 @param[in] BadModes The modes that the device does not support and that
908 should be disqualified.
909
910 @retval EFI_SUCCESS The modes were accepted without any errors.
911 @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount).
912 @retval EFI_INVALID_PARAMETER Device is invalid.
913 @retval EFI_INVALID_PARAMETER IdentifyData is NULL.
914
915 **/
916 EFI_STATUS
917 EFIAPI
918 IdeInitDisqualifyMode (
919 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
920 IN UINT8 Channel,
921 IN UINT8 Device,
922 IN EFI_ATA_COLLECTIVE_MODE *BadModes
923 )
924 {
925 EFI_SATA_CONTROLLER_PRIVATE_DATA *Private;
926 UINTN DeviceIndex;
927
928 Private = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
929 ASSERT (Private != NULL);
930
931 if ((Channel >= This->ChannelCount) || (BadModes == NULL) || (Device >= Private->DeviceCount)) {
932 return EFI_INVALID_PARAMETER;
933 }
934
935 DeviceIndex = FlatDeviceIndex (Private, Channel, Device);
936
937 //
938 // Record the disqualified modes per channel per device. From ATA/ATAPI spec,
939 // if a mode is not supported, the modes higher than it is also not supported.
940 //
941 CopyMem (
942 &(Private->DisqualifiedModes[DeviceIndex]),
943 BadModes,
944 sizeof (EFI_ATA_COLLECTIVE_MODE)
945 );
946
947 return EFI_SUCCESS;
948 }
949
950 /**
951 Returns the information about the optimum modes for the specified IDE device.
952
953 This function is used by the driver entity to obtain the optimum ATA modes for
954 a specific device. The IDE controller driver takes into account the following
955 while calculating the mode:
956 - The IdentifyData inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
957 - The BadModes inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode()
958
959 The driver entity is required to call EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
960 for all the devices that belong to an enumeration group before calling
961 EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() for any device in the same group.
962
963 The IDE controller driver will use controller- and possibly platform-specific
964 algorithms to arrive at SupportedModes. The IDE controller may base its
965 decision on user preferences and other considerations as well. This function
966 may be called multiple times because the driver entity may renegotiate the mode
967 with the IDE controller driver using EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode().
968
969 The driver entity may collect timing information for various devices in any
970 order. The driver entity is responsible for making sure that all the dependencies
971 are satisfied. For example, the SupportedModes information for device A that
972 was previously returned may become stale after a call to
973 EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() for device B.
974
975 The buffer SupportedModes is allocated by the callee because the caller does
976 not necessarily know the size of the buffer. The type EFI_ATA_COLLECTIVE_MODE
977 is defined in a way that allows for future extensibility and can be of variable
978 length. This memory pool should be deallocated by the caller when it is no
979 longer necessary.
980
981 The IDE controller driver for a Serial ATA (SATA) controller can use this
982 member function to force a lower speed (first-generation [Gen1] speeds on a
983 second-generation [Gen2]-capable hardware). The IDE controller driver can
984 also allow the driver entity to stay with the speed that has been negotiated
985 by the physical layer.
986
987 @param[in] This The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
988 @param[in] Channel A zero-based channel number.
989 @param[in] Device A zero-based device number on the Channel.
990 @param[out] SupportedModes The optimum modes for the device.
991
992 @retval EFI_SUCCESS SupportedModes was returned.
993 @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount).
994 @retval EFI_INVALID_PARAMETER Device is invalid.
995 @retval EFI_INVALID_PARAMETER SupportedModes is NULL.
996 @retval EFI_NOT_READY Modes cannot be calculated due to a lack of
997 data. This error may happen if
998 EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
999 and EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyData()
1000 were not called for at least one drive in the
1001 same enumeration group.
1002
1003 **/
1004 EFI_STATUS
1005 EFIAPI
1006 IdeInitCalculateMode (
1007 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
1008 IN UINT8 Channel,
1009 IN UINT8 Device,
1010 OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes
1011 )
1012 {
1013 EFI_SATA_CONTROLLER_PRIVATE_DATA *Private;
1014 EFI_IDENTIFY_DATA *IdentifyData;
1015 BOOLEAN IdentifyValid;
1016 EFI_ATA_COLLECTIVE_MODE *DisqualifiedModes;
1017 UINT16 SelectedMode;
1018 EFI_STATUS Status;
1019 UINTN DeviceIndex;
1020
1021 Private = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
1022 ASSERT (Private != NULL);
1023
1024 if ((Channel >= This->ChannelCount) || (SupportedModes == NULL) || (Device >= Private->DeviceCount)) {
1025 return EFI_INVALID_PARAMETER;
1026 }
1027
1028 *SupportedModes = AllocateZeroPool (sizeof (EFI_ATA_COLLECTIVE_MODE));
1029 if (*SupportedModes == NULL) {
1030 ASSERT (*SupportedModes != NULL);
1031 return EFI_OUT_OF_RESOURCES;
1032 }
1033
1034 DeviceIndex = FlatDeviceIndex (Private, Channel, Device);
1035
1036 IdentifyData = &(Private->IdentifyData[DeviceIndex]);
1037 IdentifyValid = Private->IdentifyValid[DeviceIndex];
1038 DisqualifiedModes = &(Private->DisqualifiedModes[DeviceIndex]);
1039
1040 //
1041 // Make sure we've got the valid identify data of the device from SubmitData()
1042 //
1043 if (!IdentifyValid) {
1044 FreePool (*SupportedModes);
1045 return EFI_NOT_READY;
1046 }
1047
1048 Status = CalculateBestPioMode (
1049 IdentifyData,
1050 (DisqualifiedModes->PioMode.Valid ? ((UINT16 *)&(DisqualifiedModes->PioMode.Mode)) : NULL),
1051 &SelectedMode
1052 );
1053 if (!EFI_ERROR (Status)) {
1054 (*SupportedModes)->PioMode.Valid = TRUE;
1055 (*SupportedModes)->PioMode.Mode = SelectedMode;
1056 } else {
1057 (*SupportedModes)->PioMode.Valid = FALSE;
1058 }
1059
1060 DEBUG ((DEBUG_INFO, "IdeInitCalculateMode: PioMode = %x\n", (*SupportedModes)->PioMode.Mode));
1061
1062 Status = CalculateBestUdmaMode (
1063 IdentifyData,
1064 (DisqualifiedModes->UdmaMode.Valid ? ((UINT16 *)&(DisqualifiedModes->UdmaMode.Mode)) : NULL),
1065 &SelectedMode
1066 );
1067
1068 if (!EFI_ERROR (Status)) {
1069 (*SupportedModes)->UdmaMode.Valid = TRUE;
1070 (*SupportedModes)->UdmaMode.Mode = SelectedMode;
1071 } else {
1072 (*SupportedModes)->UdmaMode.Valid = FALSE;
1073 }
1074
1075 DEBUG ((DEBUG_INFO, "IdeInitCalculateMode: UdmaMode = %x\n", (*SupportedModes)->UdmaMode.Mode));
1076
1077 //
1078 // The modes other than PIO and UDMA are not supported
1079 //
1080 return EFI_SUCCESS;
1081 }
1082
1083 /**
1084 Commands the IDE controller driver to program the IDE controller hardware
1085 so that the specified device can operate at the specified mode.
1086
1087 This function is used by the driver entity to instruct the IDE controller
1088 driver to program the IDE controller hardware to the specified modes. This
1089 function can be called only once for a particular device. For a Serial ATA
1090 (SATA) Advanced Host Controller Interface (AHCI) controller, no controller-
1091 specific programming may be required.
1092
1093 @param[in] This Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
1094 @param[in] Channel Zero-based channel number.
1095 @param[in] Device Zero-based device number on the Channel.
1096 @param[in] Modes The modes to set.
1097
1098 @retval EFI_SUCCESS The command was accepted without any errors.
1099 @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount).
1100 @retval EFI_INVALID_PARAMETER Device is invalid.
1101 @retval EFI_NOT_READY Modes cannot be set at this time due to lack of data.
1102 @retval EFI_DEVICE_ERROR Modes cannot be set due to hardware failure.
1103 The driver entity should not use this device.
1104
1105 **/
1106 EFI_STATUS
1107 EFIAPI
1108 IdeInitSetTiming (
1109 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
1110 IN UINT8 Channel,
1111 IN UINT8 Device,
1112 IN EFI_ATA_COLLECTIVE_MODE *Modes
1113 )
1114 {
1115 return EFI_SUCCESS;
1116 }