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
AhciReadReg(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT32 Offset)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
CalculateBestPioMode(IN EFI_IDENTIFY_DATA * IdentifyData,IN UINT16 * DisPioMode OPTIONAL,OUT UINT16 * SelectedMode)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
CalculateBestUdmaMode(IN EFI_IDENTIFY_DATA * IdentifyData,IN UINT16 * DisUDmaMode OPTIONAL,OUT UINT16 * SelectedMode)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
InitializeSataControllerDriver(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)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
SataControllerSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)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
SataControllerStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)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
SataControllerStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)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
FlatDeviceIndex(IN CONST EFI_SATA_CONTROLLER_PRIVATE_DATA * Private,IN UINTN Channel,IN UINTN Device)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
IdeInitGetChannelInfo(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,OUT BOOLEAN * Enabled,OUT UINT8 * MaxDevices)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
IdeInitNotifyPhase(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase,IN UINT8 Channel)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
IdeInitSubmitData(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,IN UINT8 Device,IN EFI_IDENTIFY_DATA * IdentifyData)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
IdeInitDisqualifyMode(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,IN UINT8 Device,IN EFI_ATA_COLLECTIVE_MODE * BadModes)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
IdeInitCalculateMode(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,IN UINT8 Device,OUT EFI_ATA_COLLECTIVE_MODE ** SupportedModes)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
IdeInitSetTiming(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,IN UINT8 Device,IN EFI_ATA_COLLECTIVE_MODE * Modes)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 
1109