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