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