• 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   EFI_PCI_IO_PROTOCOL               *PciIo;
574   UINT64                            OriginalPciAttributes;
575 
576   //
577   // Open the produced protocol
578   //
579   Status = gBS->OpenProtocol (
580                   Controller,
581                   &gEfiIdeControllerInitProtocolGuid,
582                   (VOID **) &IdeInit,
583                   This->DriverBindingHandle,
584                   Controller,
585                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
586                   );
587   if (EFI_ERROR (Status)) {
588     return EFI_UNSUPPORTED;
589   }
590 
591   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (IdeInit);
592   ASSERT (SataPrivateData != NULL);
593 
594   PciIo                 = SataPrivateData->PciIo;
595   OriginalPciAttributes = SataPrivateData->OriginalPciAttributes;
596 
597   //
598   // Uninstall the IDE Controller Init Protocol from this instance
599   //
600   Status = gBS->UninstallMultipleProtocolInterfaces (
601                   Controller,
602                   &gEfiIdeControllerInitProtocolGuid,
603                   &(SataPrivateData->IdeInit),
604                   NULL
605                   );
606   if (EFI_ERROR (Status)) {
607     return Status;
608   }
609 
610   if (SataPrivateData->DisqualifiedModes != NULL) {
611     FreePool (SataPrivateData->DisqualifiedModes);
612   }
613   if (SataPrivateData->IdentifyData != NULL) {
614     FreePool (SataPrivateData->IdentifyData);
615   }
616   if (SataPrivateData->IdentifyValid != NULL) {
617     FreePool (SataPrivateData->IdentifyValid);
618   }
619   FreePool (SataPrivateData);
620 
621   //
622   // Restore original PCI attributes
623   //
624   PciIo->Attributes (
625            PciIo,
626            EfiPciIoAttributeOperationSet,
627            OriginalPciAttributes,
628            NULL
629            );
630 
631   //
632   // Close protocols opened by Sata Controller driver
633   //
634   return gBS->CloseProtocol (
635                 Controller,
636                 &gEfiPciIoProtocolGuid,
637                 This->DriverBindingHandle,
638                 Controller
639                 );
640 }
641 
642 /**
643   Calculate the flat array subscript of a (Channel, Device) pair.
644 
645   @param[in] SataPrivateData  The private data structure corresponding to the
646                               SATA controller that attaches the device for
647                               which the flat array subscript is being
648                               calculated.
649 
650   @param[in] Channel          The channel (ie. port) number on the SATA
651                               controller that the device is attached to.
652 
653   @param[in] Device           The device number on the channel.
654 
655   @return  The flat array subscript suitable for indexing DisqualifiedModes,
656            IdentifyData, and IdentifyValid.
657 **/
658 STATIC
659 UINTN
FlatDeviceIndex(IN CONST EFI_SATA_CONTROLLER_PRIVATE_DATA * SataPrivateData,IN UINTN Channel,IN UINTN Device)660 FlatDeviceIndex (
661   IN CONST EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData,
662   IN UINTN                                   Channel,
663   IN UINTN                                   Device
664   )
665 {
666   ASSERT (SataPrivateData != NULL);
667   ASSERT (Channel < SataPrivateData->IdeInit.ChannelCount);
668   ASSERT (Device < SataPrivateData->DeviceCount);
669 
670   return Channel * SataPrivateData->DeviceCount + Device;
671 }
672 
673 //
674 // Interface functions of IDE_CONTROLLER_INIT protocol
675 //
676 /**
677   Returns the information about the specified IDE channel.
678 
679   This function can be used to obtain information about a particular IDE channel.
680   The driver entity uses this information during the enumeration process.
681 
682   If Enabled is set to FALSE, the driver entity will not scan the channel. Note
683   that it will not prevent an operating system driver from scanning the channel.
684 
685   For most of today's controllers, MaxDevices will either be 1 or 2. For SATA
686   controllers, this value will always be 1. SATA configurations can contain SATA
687   port multipliers. SATA port multipliers behave like SATA bridges and can support
688   up to 16 devices on the other side. If a SATA port out of the IDE controller
689   is connected to a port multiplier, MaxDevices will be set to the number of SATA
690   devices that the port multiplier supports. Because today's port multipliers
691   support up to fifteen SATA devices, this number can be as large as fifteen. The IDE
692   bus driver is required to scan for the presence of port multipliers behind an SATA
693   controller and enumerate up to MaxDevices number of devices behind the port
694   multiplier.
695 
696   In this context, the devices behind a port multiplier constitute a channel.
697 
698   @param[in]  This         The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
699   @param[in]  Channel      Zero-based channel number.
700   @param[out] Enabled      TRUE if this channel is enabled.  Disabled channels
701                            are not scanned to see if any devices are present.
702   @param[out] MaxDevices   The maximum number of IDE devices that the bus driver
703                            can expect on this channel.  For the ATA/ATAPI
704                            specification, version 6, this number will either be
705                            one or two. For Serial ATA (SATA) configurations with a
706                            port multiplier, this number can be as large as fifteen.
707 
708   @retval EFI_SUCCESS             Information was returned without any errors.
709   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
710 
711 **/
712 EFI_STATUS
713 EFIAPI
IdeInitGetChannelInfo(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,OUT BOOLEAN * Enabled,OUT UINT8 * MaxDevices)714 IdeInitGetChannelInfo (
715   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
716   IN UINT8                              Channel,
717   OUT BOOLEAN                           *Enabled,
718   OUT UINT8                             *MaxDevices
719   )
720 {
721   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
722   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
723   ASSERT (SataPrivateData != NULL);
724 
725   if (Channel < This->ChannelCount) {
726     *Enabled = TRUE;
727     *MaxDevices = SataPrivateData->DeviceCount;
728     return EFI_SUCCESS;
729   }
730 
731   *Enabled = FALSE;
732   return EFI_INVALID_PARAMETER;
733 }
734 
735 /**
736   The notifications from the driver entity that it is about to enter a certain
737   phase of the IDE channel enumeration process.
738 
739   This function can be used to notify the IDE controller driver to perform
740   specific actions, including any chipset-specific initialization, so that the
741   chipset is ready to enter the next phase. Seven notification points are defined
742   at this time.
743 
744   More synchronization points may be added as required in the future.
745 
746   @param[in] This      The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
747   @param[in] Phase     The phase during enumeration.
748   @param[in] Channel   Zero-based channel number.
749 
750   @retval EFI_SUCCESS             The notification was accepted without any errors.
751   @retval EFI_UNSUPPORTED         Phase is not supported.
752   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
753   @retval EFI_NOT_READY           This phase cannot be entered at this time; for
754                                   example, an attempt was made to enter a Phase
755                                   without having entered one or more previous
756                                   Phase.
757 
758 **/
759 EFI_STATUS
760 EFIAPI
IdeInitNotifyPhase(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase,IN UINT8 Channel)761 IdeInitNotifyPhase (
762   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
763   IN EFI_IDE_CONTROLLER_ENUM_PHASE      Phase,
764   IN UINT8                              Channel
765   )
766 {
767   return EFI_SUCCESS;
768 }
769 
770 /**
771   Submits the device information to the IDE controller driver.
772 
773   This function is used by the driver entity to pass detailed information about
774   a particular device to the IDE controller driver. The driver entity obtains
775   this information by issuing an ATA or ATAPI IDENTIFY_DEVICE command. IdentifyData
776   is the pointer to the response data buffer. The IdentifyData buffer is owned
777   by the driver entity, and the IDE controller driver must make a local copy
778   of the entire buffer or parts of the buffer as needed. The original IdentifyData
779   buffer pointer may not be valid when
780 
781     - EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() or
782     - EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() is called at a later point.
783 
784   The IDE controller driver may consult various fields of EFI_IDENTIFY_DATA to
785   compute the optimum mode for the device. These fields are not limited to the
786   timing information. For example, an implementation of the IDE controller driver
787   may examine the vendor and type/mode field to match known bad drives.
788 
789   The driver entity may submit drive information in any order, as long as it
790   submits information for all the devices belonging to the enumeration group
791   before EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() is called for any device
792   in that enumeration group. If a device is absent, EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
793   should be called with IdentifyData set to NULL.  The IDE controller driver may
794   not have any other mechanism to know whether a device is present or not. Therefore,
795   setting IdentifyData to NULL does not constitute an error condition.
796   EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() can be called only once for a
797   given (Channel, Device) pair.
798 
799   @param[in] This           A pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
800   @param[in] Channel        Zero-based channel number.
801   @param[in] Device         Zero-based device number on the Channel.
802   @param[in] IdentifyData   The device's response to the ATA IDENTIFY_DEVICE command.
803 
804   @retval EFI_SUCCESS             The information was accepted without any errors.
805   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
806   @retval EFI_INVALID_PARAMETER   Device is invalid.
807 
808 **/
809 EFI_STATUS
810 EFIAPI
IdeInitSubmitData(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,IN UINT8 Device,IN EFI_IDENTIFY_DATA * IdentifyData)811 IdeInitSubmitData (
812   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
813   IN UINT8                              Channel,
814   IN UINT8                              Device,
815   IN EFI_IDENTIFY_DATA                  *IdentifyData
816   )
817 {
818   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
819   UINTN                             DeviceIndex;
820 
821   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
822   ASSERT (SataPrivateData != NULL);
823 
824   if ((Channel >= This->ChannelCount) || (Device >= SataPrivateData->DeviceCount)) {
825     return EFI_INVALID_PARAMETER;
826   }
827 
828   DeviceIndex = FlatDeviceIndex (SataPrivateData, Channel, Device);
829 
830   //
831   // Make a local copy of device's IdentifyData and mark the valid flag
832   //
833   if (IdentifyData != NULL) {
834     CopyMem (
835       &(SataPrivateData->IdentifyData[DeviceIndex]),
836       IdentifyData,
837       sizeof (EFI_IDENTIFY_DATA)
838       );
839 
840     SataPrivateData->IdentifyValid[DeviceIndex] = TRUE;
841   } else {
842     SataPrivateData->IdentifyValid[DeviceIndex] = FALSE;
843   }
844 
845   return EFI_SUCCESS;
846 }
847 
848 /**
849   Disqualifies specific modes for an IDE device.
850 
851   This function allows the driver entity or other drivers (such as platform
852   drivers) to reject certain timing modes and request the IDE controller driver
853   to recalculate modes. This function allows the driver entity and the IDE
854   controller driver to negotiate the timings on a per-device basis. This function
855   is useful in the case of drives that lie about their capabilities. An example
856   is when the IDE device fails to accept the timing modes that are calculated
857   by the IDE controller driver based on the response to the Identify Drive command.
858 
859   If the driver entity does not want to limit the ATA timing modes and leave that
860   decision to the IDE controller driver, it can either not call this function for
861   the given device or call this function and set the Valid flag to FALSE for all
862   modes that are listed in EFI_ATA_COLLECTIVE_MODE.
863 
864   The driver entity may disqualify modes for a device in any order and any number
865   of times.
866 
867   This function can be called multiple times to invalidate multiple modes of the
868   same type (e.g., Programmed Input/Output [PIO] modes 3 and 4). See the ATA/ATAPI
869   specification for more information on PIO modes.
870 
871   For Serial ATA (SATA) controllers, this member function can be used to disqualify
872   a higher transfer rate mode on a given channel. For example, a platform driver
873   may inform the IDE controller driver to not use second-generation (Gen2) speeds
874   for a certain SATA drive.
875 
876   @param[in] This       The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
877   @param[in] Channel    The zero-based channel number.
878   @param[in] Device     The zero-based device number on the Channel.
879   @param[in] BadModes   The modes that the device does not support and that
880                         should be disqualified.
881 
882   @retval EFI_SUCCESS             The modes were accepted without any errors.
883   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
884   @retval EFI_INVALID_PARAMETER   Device is invalid.
885   @retval EFI_INVALID_PARAMETER   IdentifyData is NULL.
886 
887 **/
888 EFI_STATUS
889 EFIAPI
IdeInitDisqualifyMode(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,IN UINT8 Device,IN EFI_ATA_COLLECTIVE_MODE * BadModes)890 IdeInitDisqualifyMode (
891   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
892   IN UINT8                              Channel,
893   IN UINT8                              Device,
894   IN EFI_ATA_COLLECTIVE_MODE            *BadModes
895   )
896 {
897   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
898   UINTN                             DeviceIndex;
899 
900   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
901   ASSERT (SataPrivateData != NULL);
902 
903   if ((Channel >= This->ChannelCount) || (BadModes == NULL) || (Device >= SataPrivateData->DeviceCount)) {
904     return EFI_INVALID_PARAMETER;
905   }
906 
907   DeviceIndex = FlatDeviceIndex (SataPrivateData, Channel, Device);
908 
909   //
910   // Record the disqualified modes per channel per device. From ATA/ATAPI spec,
911   // if a mode is not supported, the modes higher than it is also not supported.
912   //
913   CopyMem (
914     &(SataPrivateData->DisqualifiedModes[DeviceIndex]),
915     BadModes,
916     sizeof (EFI_ATA_COLLECTIVE_MODE)
917     );
918 
919   return EFI_SUCCESS;
920 }
921 
922 /**
923   Returns the information about the optimum modes for the specified IDE device.
924 
925   This function is used by the driver entity to obtain the optimum ATA modes for
926   a specific device.  The IDE controller driver takes into account the following
927   while calculating the mode:
928     - The IdentifyData inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
929     - The BadModes inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode()
930 
931   The driver entity is required to call EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
932   for all the devices that belong to an enumeration group before calling
933   EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() for any device in the same group.
934 
935   The IDE controller driver will use controller- and possibly platform-specific
936   algorithms to arrive at SupportedModes.  The IDE controller may base its
937   decision on user preferences and other considerations as well. This function
938   may be called multiple times because the driver entity may renegotiate the mode
939   with the IDE controller driver using EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode().
940 
941   The driver entity may collect timing information for various devices in any
942   order. The driver entity is responsible for making sure that all the dependencies
943   are satisfied. For example, the SupportedModes information for device A that
944   was previously returned may become stale after a call to
945   EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() for device B.
946 
947   The buffer SupportedModes is allocated by the callee because the caller does
948   not necessarily know the size of the buffer. The type EFI_ATA_COLLECTIVE_MODE
949   is defined in a way that allows for future extensibility and can be of variable
950   length. This memory pool should be deallocated by the caller when it is no
951   longer necessary.
952 
953   The IDE controller driver for a Serial ATA (SATA) controller can use this
954   member function to force a lower speed (first-generation [Gen1] speeds on a
955   second-generation [Gen2]-capable hardware).  The IDE controller driver can
956   also allow the driver entity to stay with the speed that has been negotiated
957   by the physical layer.
958 
959   @param[in]  This             The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
960   @param[in]  Channel          A zero-based channel number.
961   @param[in]  Device           A zero-based device number on the Channel.
962   @param[out] SupportedModes   The optimum modes for the device.
963 
964   @retval EFI_SUCCESS             SupportedModes was returned.
965   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
966   @retval EFI_INVALID_PARAMETER   Device is invalid.
967   @retval EFI_INVALID_PARAMETER   SupportedModes is NULL.
968   @retval EFI_NOT_READY           Modes cannot be calculated due to a lack of
969                                   data.  This error may happen if
970                                   EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
971                                   and EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyData()
972                                   were not called for at least one drive in the
973                                   same enumeration group.
974 
975 **/
976 EFI_STATUS
977 EFIAPI
IdeInitCalculateMode(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,IN UINT8 Device,OUT EFI_ATA_COLLECTIVE_MODE ** SupportedModes)978 IdeInitCalculateMode (
979   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
980   IN UINT8                              Channel,
981   IN UINT8                              Device,
982   OUT EFI_ATA_COLLECTIVE_MODE           **SupportedModes
983   )
984 {
985   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
986   EFI_IDENTIFY_DATA                 *IdentifyData;
987   BOOLEAN                           IdentifyValid;
988   EFI_ATA_COLLECTIVE_MODE           *DisqualifiedModes;
989   UINT16                            SelectedMode;
990   EFI_STATUS                        Status;
991   UINTN                             DeviceIndex;
992 
993   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
994   ASSERT (SataPrivateData != NULL);
995 
996   if ((Channel >= This->ChannelCount) || (SupportedModes == NULL) || (Device >= SataPrivateData->DeviceCount)) {
997     return EFI_INVALID_PARAMETER;
998   }
999 
1000   *SupportedModes = AllocateZeroPool (sizeof (EFI_ATA_COLLECTIVE_MODE));
1001   if (*SupportedModes == NULL) {
1002     ASSERT (*SupportedModes != NULL);
1003     return EFI_OUT_OF_RESOURCES;
1004   }
1005 
1006   DeviceIndex = FlatDeviceIndex (SataPrivateData, Channel, Device);
1007 
1008   IdentifyData = &(SataPrivateData->IdentifyData[DeviceIndex]);
1009   IdentifyValid = SataPrivateData->IdentifyValid[DeviceIndex];
1010   DisqualifiedModes = &(SataPrivateData->DisqualifiedModes[DeviceIndex]);
1011 
1012   //
1013   // Make sure we've got the valid identify data of the device from SubmitData()
1014   //
1015   if (!IdentifyValid) {
1016     FreePool (*SupportedModes);
1017     return EFI_NOT_READY;
1018   }
1019 
1020   Status = CalculateBestPioMode (
1021             IdentifyData,
1022             (DisqualifiedModes->PioMode.Valid ? ((UINT16 *) &(DisqualifiedModes->PioMode.Mode)) : NULL),
1023             &SelectedMode
1024             );
1025   if (!EFI_ERROR (Status)) {
1026     (*SupportedModes)->PioMode.Valid = TRUE;
1027     (*SupportedModes)->PioMode.Mode = SelectedMode;
1028 
1029   } else {
1030     (*SupportedModes)->PioMode.Valid = FALSE;
1031   }
1032   DEBUG ((EFI_D_INFO, "IdeInitCalculateMode: PioMode = %x\n", (*SupportedModes)->PioMode.Mode));
1033 
1034   Status = CalculateBestUdmaMode (
1035             IdentifyData,
1036             (DisqualifiedModes->UdmaMode.Valid ? ((UINT16 *) &(DisqualifiedModes->UdmaMode.Mode)) : NULL),
1037             &SelectedMode
1038             );
1039 
1040   if (!EFI_ERROR (Status)) {
1041     (*SupportedModes)->UdmaMode.Valid = TRUE;
1042     (*SupportedModes)->UdmaMode.Mode  = SelectedMode;
1043 
1044   } else {
1045     (*SupportedModes)->UdmaMode.Valid = FALSE;
1046   }
1047   DEBUG ((EFI_D_INFO, "IdeInitCalculateMode: UdmaMode = %x\n", (*SupportedModes)->UdmaMode.Mode));
1048 
1049   //
1050   // The modes other than PIO and UDMA are not supported
1051   //
1052   return EFI_SUCCESS;
1053 }
1054 
1055 /**
1056   Commands the IDE controller driver to program the IDE controller hardware
1057   so that the specified device can operate at the specified mode.
1058 
1059   This function is used by the driver entity to instruct the IDE controller
1060   driver to program the IDE controller hardware to the specified modes. This
1061   function can be called only once for a particular device. For a Serial ATA
1062   (SATA) Advanced Host Controller Interface (AHCI) controller, no controller-
1063   specific programming may be required.
1064 
1065   @param[in] This      Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
1066   @param[in] Channel   Zero-based channel number.
1067   @param[in] Device    Zero-based device number on the Channel.
1068   @param[in] Modes     The modes to set.
1069 
1070   @retval EFI_SUCCESS             The command was accepted without any errors.
1071   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
1072   @retval EFI_INVALID_PARAMETER   Device is invalid.
1073   @retval EFI_NOT_READY           Modes cannot be set at this time due to lack of data.
1074   @retval EFI_DEVICE_ERROR        Modes cannot be set due to hardware failure.
1075                                   The driver entity should not use this device.
1076 
1077 **/
1078 EFI_STATUS
1079 EFIAPI
IdeInitSetTiming(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,IN UINT8 Device,IN EFI_ATA_COLLECTIVE_MODE * Modes)1080 IdeInitSetTiming (
1081   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
1082   IN UINT8                              Channel,
1083   IN UINT8                              Device,
1084   IN EFI_ATA_COLLECTIVE_MODE            *Modes
1085   )
1086 {
1087   return EFI_SUCCESS;
1088 }
1089