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