• 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   PCI_TYPE00                        PciData;
394   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
395   UINT32                            Data32;
396   UINTN                             ChannelDeviceCount;
397 
398   DEBUG ((EFI_D_INFO, "SataControllerStart START\n"));
399 
400   SataPrivateData = NULL;
401 
402   //
403   // Now test and open PCI I/O Protocol
404   //
405   Status = gBS->OpenProtocol (
406                   Controller,
407                   &gEfiPciIoProtocolGuid,
408                   (VOID **) &PciIo,
409                   This->DriverBindingHandle,
410                   Controller,
411                   EFI_OPEN_PROTOCOL_BY_DRIVER
412                   );
413   if (EFI_ERROR (Status)) {
414     DEBUG ((EFI_D_ERROR, "SataControllerStart error return status = %r\n", Status));
415     return Status;
416   }
417 
418   //
419   // Allocate Sata Private Data structure
420   //
421   SataPrivateData = AllocateZeroPool (sizeof (EFI_SATA_CONTROLLER_PRIVATE_DATA));
422   if (SataPrivateData == NULL) {
423     Status = EFI_OUT_OF_RESOURCES;
424     goto Done;
425   }
426 
427   //
428   // Initialize Sata Private Data
429   //
430   SataPrivateData->Signature = SATA_CONTROLLER_SIGNATURE;
431   SataPrivateData->PciIo = PciIo;
432   SataPrivateData->IdeInit.GetChannelInfo = IdeInitGetChannelInfo;
433   SataPrivateData->IdeInit.NotifyPhase = IdeInitNotifyPhase;
434   SataPrivateData->IdeInit.SubmitData = IdeInitSubmitData;
435   SataPrivateData->IdeInit.DisqualifyMode = IdeInitDisqualifyMode;
436   SataPrivateData->IdeInit.CalculateMode = IdeInitCalculateMode;
437   SataPrivateData->IdeInit.SetTiming = IdeInitSetTiming;
438   SataPrivateData->IdeInit.EnumAll = SATA_ENUMER_ALL;
439 
440   Status = PciIo->Pci.Read (
441                         PciIo,
442                         EfiPciIoWidthUint8,
443                         PCI_CLASSCODE_OFFSET,
444                         sizeof (PciData.Hdr.ClassCode),
445                         PciData.Hdr.ClassCode
446                         );
447   ASSERT_EFI_ERROR (Status);
448 
449   if (IS_PCI_IDE (&PciData)) {
450     SataPrivateData->IdeInit.ChannelCount = IDE_MAX_CHANNEL;
451     SataPrivateData->DeviceCount = IDE_MAX_DEVICES;
452   } else if (IS_PCI_SATADPA (&PciData)) {
453     //
454     // Read Host Capability Register(CAP) to get Number of Ports(NPS) and Supports Port Multiplier(SPM)
455     //   NPS is 0's based value indicating the maximum number of ports supported by the HBA silicon.
456     //   A maximum of 32 ports can be supported. A value of '0h', indicating one port, is the minimum requirement.
457     //
458     Data32 = AhciReadReg (PciIo, R_AHCI_CAP);
459     SataPrivateData->IdeInit.ChannelCount = (UINT8) ((Data32 & B_AHCI_CAP_NPS) + 1);
460     SataPrivateData->DeviceCount = AHCI_MAX_DEVICES;
461     if ((Data32 & B_AHCI_CAP_SPM) == B_AHCI_CAP_SPM) {
462       SataPrivateData->DeviceCount = AHCI_MULTI_MAX_DEVICES;
463     }
464   }
465 
466   ChannelDeviceCount = (UINTN) (SataPrivateData->IdeInit.ChannelCount) * (UINTN) (SataPrivateData->DeviceCount);
467   SataPrivateData->DisqualifiedModes = AllocateZeroPool ((sizeof (EFI_ATA_COLLECTIVE_MODE)) * ChannelDeviceCount);
468   if (SataPrivateData->DisqualifiedModes == NULL) {
469     Status = EFI_OUT_OF_RESOURCES;
470     goto Done;
471   }
472 
473   SataPrivateData->IdentifyData = AllocateZeroPool ((sizeof (EFI_IDENTIFY_DATA)) * ChannelDeviceCount);
474   if (SataPrivateData->IdentifyData == NULL) {
475     Status = EFI_OUT_OF_RESOURCES;
476     goto Done;
477   }
478 
479   SataPrivateData->IdentifyValid = AllocateZeroPool ((sizeof (BOOLEAN)) * ChannelDeviceCount);
480   if (SataPrivateData->IdentifyValid == NULL) {
481     Status = EFI_OUT_OF_RESOURCES;
482     goto Done;
483   }
484 
485   //
486   // Install IDE Controller Init Protocol to this instance
487   //
488   Status = gBS->InstallMultipleProtocolInterfaces (
489                   &Controller,
490                   &gEfiIdeControllerInitProtocolGuid,
491                   &(SataPrivateData->IdeInit),
492                   NULL
493                   );
494 
495 Done:
496   if (EFI_ERROR (Status)) {
497 
498     gBS->CloseProtocol (
499           Controller,
500           &gEfiPciIoProtocolGuid,
501           This->DriverBindingHandle,
502           Controller
503           );
504     if (SataPrivateData != NULL) {
505       if (SataPrivateData->DisqualifiedModes != NULL) {
506         FreePool (SataPrivateData->DisqualifiedModes);
507       }
508       if (SataPrivateData->IdentifyData != NULL) {
509         FreePool (SataPrivateData->IdentifyData);
510       }
511       if (SataPrivateData->IdentifyValid != NULL) {
512         FreePool (SataPrivateData->IdentifyValid);
513       }
514       FreePool (SataPrivateData);
515     }
516   }
517 
518   DEBUG ((EFI_D_INFO, "SataControllerStart END status = %r\n", Status));
519 
520   return Status;
521 }
522 
523 /**
524   Stop this driver on ControllerHandle.
525 
526   @param This               Protocol instance pointer.
527   @param Controller         Handle of device to stop driver on.
528   @param NumberOfChildren   Not used.
529   @param ChildHandleBuffer  Not used.
530 
531   @retval EFI_SUCCESS   This driver is removed from this device.
532   @retval other         Some error occurs when removing this driver from this device.
533 
534 **/
535 EFI_STATUS
536 EFIAPI
SataControllerStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)537 SataControllerStop (
538   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
539   IN EFI_HANDLE                     Controller,
540   IN UINTN                          NumberOfChildren,
541   IN EFI_HANDLE                     *ChildHandleBuffer
542   )
543 {
544   EFI_STATUS                        Status;
545   EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;
546   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
547 
548   //
549   // Open the produced protocol
550   //
551   Status = gBS->OpenProtocol (
552                   Controller,
553                   &gEfiIdeControllerInitProtocolGuid,
554                   (VOID **) &IdeInit,
555                   This->DriverBindingHandle,
556                   Controller,
557                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
558                   );
559   if (EFI_ERROR (Status)) {
560     return EFI_UNSUPPORTED;
561   }
562 
563   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (IdeInit);
564   ASSERT (SataPrivateData != NULL);
565 
566   //
567   // Uninstall the IDE Controller Init Protocol from this instance
568   //
569   Status = gBS->UninstallMultipleProtocolInterfaces (
570                   Controller,
571                   &gEfiIdeControllerInitProtocolGuid,
572                   &(SataPrivateData->IdeInit),
573                   NULL
574                   );
575   if (EFI_ERROR (Status)) {
576     return Status;
577   }
578 
579   if (SataPrivateData != NULL) {
580     if (SataPrivateData->DisqualifiedModes != NULL) {
581       FreePool (SataPrivateData->DisqualifiedModes);
582     }
583     if (SataPrivateData->IdentifyData != NULL) {
584       FreePool (SataPrivateData->IdentifyData);
585     }
586     if (SataPrivateData->IdentifyValid != NULL) {
587       FreePool (SataPrivateData->IdentifyValid);
588     }
589     FreePool (SataPrivateData);
590   }
591 
592   //
593   // Close protocols opened by Sata Controller driver
594   //
595   return gBS->CloseProtocol (
596                 Controller,
597                 &gEfiPciIoProtocolGuid,
598                 This->DriverBindingHandle,
599                 Controller
600                 );
601 }
602 
603 /**
604   Calculate the flat array subscript of a (Channel, Device) pair.
605 
606   @param[in] SataPrivateData  The private data structure corresponding to the
607                               SATA controller that attaches the device for
608                               which the flat array subscript is being
609                               calculated.
610 
611   @param[in] Channel          The channel (ie. port) number on the SATA
612                               controller that the device is attached to.
613 
614   @param[in] Device           The device number on the channel.
615 
616   @return  The flat array subscript suitable for indexing DisqualifiedModes,
617            IdentifyData, and IdentifyValid.
618 **/
619 STATIC
620 UINTN
FlatDeviceIndex(IN CONST EFI_SATA_CONTROLLER_PRIVATE_DATA * SataPrivateData,IN UINTN Channel,IN UINTN Device)621 FlatDeviceIndex (
622   IN CONST EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData,
623   IN UINTN                                   Channel,
624   IN UINTN                                   Device
625   )
626 {
627   ASSERT (SataPrivateData != NULL);
628   ASSERT (Channel < SataPrivateData->IdeInit.ChannelCount);
629   ASSERT (Device < SataPrivateData->DeviceCount);
630 
631   return Channel * SataPrivateData->DeviceCount + Device;
632 }
633 
634 //
635 // Interface functions of IDE_CONTROLLER_INIT protocol
636 //
637 /**
638   Returns the information about the specified IDE channel.
639 
640   This function can be used to obtain information about a particular IDE channel.
641   The driver entity uses this information during the enumeration process.
642 
643   If Enabled is set to FALSE, the driver entity will not scan the channel. Note
644   that it will not prevent an operating system driver from scanning the channel.
645 
646   For most of today's controllers, MaxDevices will either be 1 or 2. For SATA
647   controllers, this value will always be 1. SATA configurations can contain SATA
648   port multipliers. SATA port multipliers behave like SATA bridges and can support
649   up to 16 devices on the other side. If a SATA port out of the IDE controller
650   is connected to a port multiplier, MaxDevices will be set to the number of SATA
651   devices that the port multiplier supports. Because today's port multipliers
652   support up to fifteen SATA devices, this number can be as large as fifteen. The IDE
653   bus driver is required to scan for the presence of port multipliers behind an SATA
654   controller and enumerate up to MaxDevices number of devices behind the port
655   multiplier.
656 
657   In this context, the devices behind a port multiplier constitute a channel.
658 
659   @param[in]  This         The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
660   @param[in]  Channel      Zero-based channel number.
661   @param[out] Enabled      TRUE if this channel is enabled.  Disabled channels
662                            are not scanned to see if any devices are present.
663   @param[out] MaxDevices   The maximum number of IDE devices that the bus driver
664                            can expect on this channel.  For the ATA/ATAPI
665                            specification, version 6, this number will either be
666                            one or two. For Serial ATA (SATA) configurations with a
667                            port multiplier, this number can be as large as fifteen.
668 
669   @retval EFI_SUCCESS             Information was returned without any errors.
670   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
671 
672 **/
673 EFI_STATUS
674 EFIAPI
IdeInitGetChannelInfo(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,OUT BOOLEAN * Enabled,OUT UINT8 * MaxDevices)675 IdeInitGetChannelInfo (
676   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
677   IN UINT8                              Channel,
678   OUT BOOLEAN                           *Enabled,
679   OUT UINT8                             *MaxDevices
680   )
681 {
682   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
683   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
684   ASSERT (SataPrivateData != NULL);
685 
686   if (Channel < This->ChannelCount) {
687     *Enabled = TRUE;
688     *MaxDevices = SataPrivateData->DeviceCount;
689     return EFI_SUCCESS;
690   }
691 
692   *Enabled = FALSE;
693   return EFI_INVALID_PARAMETER;
694 }
695 
696 /**
697   The notifications from the driver entity that it is about to enter a certain
698   phase of the IDE channel enumeration process.
699 
700   This function can be used to notify the IDE controller driver to perform
701   specific actions, including any chipset-specific initialization, so that the
702   chipset is ready to enter the next phase. Seven notification points are defined
703   at this time.
704 
705   More synchronization points may be added as required in the future.
706 
707   @param[in] This      The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
708   @param[in] Phase     The phase during enumeration.
709   @param[in] Channel   Zero-based channel number.
710 
711   @retval EFI_SUCCESS             The notification was accepted without any errors.
712   @retval EFI_UNSUPPORTED         Phase is not supported.
713   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
714   @retval EFI_NOT_READY           This phase cannot be entered at this time; for
715                                   example, an attempt was made to enter a Phase
716                                   without having entered one or more previous
717                                   Phase.
718 
719 **/
720 EFI_STATUS
721 EFIAPI
IdeInitNotifyPhase(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase,IN UINT8 Channel)722 IdeInitNotifyPhase (
723   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
724   IN EFI_IDE_CONTROLLER_ENUM_PHASE      Phase,
725   IN UINT8                              Channel
726   )
727 {
728   return EFI_SUCCESS;
729 }
730 
731 /**
732   Submits the device information to the IDE controller driver.
733 
734   This function is used by the driver entity to pass detailed information about
735   a particular device to the IDE controller driver. The driver entity obtains
736   this information by issuing an ATA or ATAPI IDENTIFY_DEVICE command. IdentifyData
737   is the pointer to the response data buffer. The IdentifyData buffer is owned
738   by the driver entity, and the IDE controller driver must make a local copy
739   of the entire buffer or parts of the buffer as needed. The original IdentifyData
740   buffer pointer may not be valid when
741 
742     - EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() or
743     - EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() is called at a later point.
744 
745   The IDE controller driver may consult various fields of EFI_IDENTIFY_DATA to
746   compute the optimum mode for the device. These fields are not limited to the
747   timing information. For example, an implementation of the IDE controller driver
748   may examine the vendor and type/mode field to match known bad drives.
749 
750   The driver entity may submit drive information in any order, as long as it
751   submits information for all the devices belonging to the enumeration group
752   before EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() is called for any device
753   in that enumeration group. If a device is absent, EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
754   should be called with IdentifyData set to NULL.  The IDE controller driver may
755   not have any other mechanism to know whether a device is present or not. Therefore,
756   setting IdentifyData to NULL does not constitute an error condition.
757   EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() can be called only once for a
758   given (Channel, Device) pair.
759 
760   @param[in] This           A pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
761   @param[in] Channel        Zero-based channel number.
762   @param[in] Device         Zero-based device number on the Channel.
763   @param[in] IdentifyData   The device's response to the ATA IDENTIFY_DEVICE command.
764 
765   @retval EFI_SUCCESS             The information was accepted without any errors.
766   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
767   @retval EFI_INVALID_PARAMETER   Device is invalid.
768 
769 **/
770 EFI_STATUS
771 EFIAPI
IdeInitSubmitData(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,IN UINT8 Device,IN EFI_IDENTIFY_DATA * IdentifyData)772 IdeInitSubmitData (
773   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
774   IN UINT8                              Channel,
775   IN UINT8                              Device,
776   IN EFI_IDENTIFY_DATA                  *IdentifyData
777   )
778 {
779   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
780   UINTN                             DeviceIndex;
781 
782   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
783   ASSERT (SataPrivateData != NULL);
784 
785   if ((Channel >= This->ChannelCount) || (Device >= SataPrivateData->DeviceCount)) {
786     return EFI_INVALID_PARAMETER;
787   }
788 
789   DeviceIndex = FlatDeviceIndex (SataPrivateData, Channel, Device);
790 
791   //
792   // Make a local copy of device's IdentifyData and mark the valid flag
793   //
794   if (IdentifyData != NULL) {
795     CopyMem (
796       &(SataPrivateData->IdentifyData[DeviceIndex]),
797       IdentifyData,
798       sizeof (EFI_IDENTIFY_DATA)
799       );
800 
801     SataPrivateData->IdentifyValid[DeviceIndex] = TRUE;
802   } else {
803     SataPrivateData->IdentifyValid[DeviceIndex] = FALSE;
804   }
805 
806   return EFI_SUCCESS;
807 }
808 
809 /**
810   Disqualifies specific modes for an IDE device.
811 
812   This function allows the driver entity or other drivers (such as platform
813   drivers) to reject certain timing modes and request the IDE controller driver
814   to recalculate modes. This function allows the driver entity and the IDE
815   controller driver to negotiate the timings on a per-device basis. This function
816   is useful in the case of drives that lie about their capabilities. An example
817   is when the IDE device fails to accept the timing modes that are calculated
818   by the IDE controller driver based on the response to the Identify Drive command.
819 
820   If the driver entity does not want to limit the ATA timing modes and leave that
821   decision to the IDE controller driver, it can either not call this function for
822   the given device or call this function and set the Valid flag to FALSE for all
823   modes that are listed in EFI_ATA_COLLECTIVE_MODE.
824 
825   The driver entity may disqualify modes for a device in any order and any number
826   of times.
827 
828   This function can be called multiple times to invalidate multiple modes of the
829   same type (e.g., Programmed Input/Output [PIO] modes 3 and 4). See the ATA/ATAPI
830   specification for more information on PIO modes.
831 
832   For Serial ATA (SATA) controllers, this member function can be used to disqualify
833   a higher transfer rate mode on a given channel. For example, a platform driver
834   may inform the IDE controller driver to not use second-generation (Gen2) speeds
835   for a certain SATA drive.
836 
837   @param[in] This       The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
838   @param[in] Channel    The zero-based channel number.
839   @param[in] Device     The zero-based device number on the Channel.
840   @param[in] BadModes   The modes that the device does not support and that
841                         should be disqualified.
842 
843   @retval EFI_SUCCESS             The modes were accepted without any errors.
844   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
845   @retval EFI_INVALID_PARAMETER   Device is invalid.
846   @retval EFI_INVALID_PARAMETER   IdentifyData is NULL.
847 
848 **/
849 EFI_STATUS
850 EFIAPI
IdeInitDisqualifyMode(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,IN UINT8 Device,IN EFI_ATA_COLLECTIVE_MODE * BadModes)851 IdeInitDisqualifyMode (
852   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
853   IN UINT8                              Channel,
854   IN UINT8                              Device,
855   IN EFI_ATA_COLLECTIVE_MODE            *BadModes
856   )
857 {
858   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
859   UINTN                             DeviceIndex;
860 
861   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
862   ASSERT (SataPrivateData != NULL);
863 
864   if ((Channel >= This->ChannelCount) || (BadModes == NULL) || (Device >= SataPrivateData->DeviceCount)) {
865     return EFI_INVALID_PARAMETER;
866   }
867 
868   DeviceIndex = FlatDeviceIndex (SataPrivateData, Channel, Device);
869 
870   //
871   // Record the disqualified modes per channel per device. From ATA/ATAPI spec,
872   // if a mode is not supported, the modes higher than it is also not supported.
873   //
874   CopyMem (
875     &(SataPrivateData->DisqualifiedModes[DeviceIndex]),
876     BadModes,
877     sizeof (EFI_ATA_COLLECTIVE_MODE)
878     );
879 
880   return EFI_SUCCESS;
881 }
882 
883 /**
884   Returns the information about the optimum modes for the specified IDE device.
885 
886   This function is used by the driver entity to obtain the optimum ATA modes for
887   a specific device.  The IDE controller driver takes into account the following
888   while calculating the mode:
889     - The IdentifyData inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
890     - The BadModes inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode()
891 
892   The driver entity is required to call EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
893   for all the devices that belong to an enumeration group before calling
894   EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() for any device in the same group.
895 
896   The IDE controller driver will use controller- and possibly platform-specific
897   algorithms to arrive at SupportedModes.  The IDE controller may base its
898   decision on user preferences and other considerations as well. This function
899   may be called multiple times because the driver entity may renegotiate the mode
900   with the IDE controller driver using EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode().
901 
902   The driver entity may collect timing information for various devices in any
903   order. The driver entity is responsible for making sure that all the dependencies
904   are satisfied. For example, the SupportedModes information for device A that
905   was previously returned may become stale after a call to
906   EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() for device B.
907 
908   The buffer SupportedModes is allocated by the callee because the caller does
909   not necessarily know the size of the buffer. The type EFI_ATA_COLLECTIVE_MODE
910   is defined in a way that allows for future extensibility and can be of variable
911   length. This memory pool should be deallocated by the caller when it is no
912   longer necessary.
913 
914   The IDE controller driver for a Serial ATA (SATA) controller can use this
915   member function to force a lower speed (first-generation [Gen1] speeds on a
916   second-generation [Gen2]-capable hardware).  The IDE controller driver can
917   also allow the driver entity to stay with the speed that has been negotiated
918   by the physical layer.
919 
920   @param[in]  This             The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
921   @param[in]  Channel          A zero-based channel number.
922   @param[in]  Device           A zero-based device number on the Channel.
923   @param[out] SupportedModes   The optimum modes for the device.
924 
925   @retval EFI_SUCCESS             SupportedModes was returned.
926   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
927   @retval EFI_INVALID_PARAMETER   Device is invalid.
928   @retval EFI_INVALID_PARAMETER   SupportedModes is NULL.
929   @retval EFI_NOT_READY           Modes cannot be calculated due to a lack of
930                                   data.  This error may happen if
931                                   EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
932                                   and EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyData()
933                                   were not called for at least one drive in the
934                                   same enumeration group.
935 
936 **/
937 EFI_STATUS
938 EFIAPI
IdeInitCalculateMode(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,IN UINT8 Device,OUT EFI_ATA_COLLECTIVE_MODE ** SupportedModes)939 IdeInitCalculateMode (
940   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
941   IN UINT8                              Channel,
942   IN UINT8                              Device,
943   OUT EFI_ATA_COLLECTIVE_MODE           **SupportedModes
944   )
945 {
946   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
947   EFI_IDENTIFY_DATA                 *IdentifyData;
948   BOOLEAN                           IdentifyValid;
949   EFI_ATA_COLLECTIVE_MODE           *DisqualifiedModes;
950   UINT16                            SelectedMode;
951   EFI_STATUS                        Status;
952   UINTN                             DeviceIndex;
953 
954   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
955   ASSERT (SataPrivateData != NULL);
956 
957   if ((Channel >= This->ChannelCount) || (SupportedModes == NULL) || (Device >= SataPrivateData->DeviceCount)) {
958     return EFI_INVALID_PARAMETER;
959   }
960 
961   *SupportedModes = AllocateZeroPool (sizeof (EFI_ATA_COLLECTIVE_MODE));
962   if (*SupportedModes == NULL) {
963     ASSERT (*SupportedModes != NULL);
964     return EFI_OUT_OF_RESOURCES;
965   }
966 
967   DeviceIndex = FlatDeviceIndex (SataPrivateData, Channel, Device);
968 
969   IdentifyData = &(SataPrivateData->IdentifyData[DeviceIndex]);
970   IdentifyValid = SataPrivateData->IdentifyValid[DeviceIndex];
971   DisqualifiedModes = &(SataPrivateData->DisqualifiedModes[DeviceIndex]);
972 
973   //
974   // Make sure we've got the valid identify data of the device from SubmitData()
975   //
976   if (!IdentifyValid) {
977     FreePool (*SupportedModes);
978     return EFI_NOT_READY;
979   }
980 
981   Status = CalculateBestPioMode (
982             IdentifyData,
983             (DisqualifiedModes->PioMode.Valid ? ((UINT16 *) &(DisqualifiedModes->PioMode.Mode)) : NULL),
984             &SelectedMode
985             );
986   if (!EFI_ERROR (Status)) {
987     (*SupportedModes)->PioMode.Valid = TRUE;
988     (*SupportedModes)->PioMode.Mode = SelectedMode;
989 
990   } else {
991     (*SupportedModes)->PioMode.Valid = FALSE;
992   }
993   DEBUG ((EFI_D_INFO, "IdeInitCalculateMode: PioMode = %x\n", (*SupportedModes)->PioMode.Mode));
994 
995   Status = CalculateBestUdmaMode (
996             IdentifyData,
997             (DisqualifiedModes->UdmaMode.Valid ? ((UINT16 *) &(DisqualifiedModes->UdmaMode.Mode)) : NULL),
998             &SelectedMode
999             );
1000 
1001   if (!EFI_ERROR (Status)) {
1002     (*SupportedModes)->UdmaMode.Valid = TRUE;
1003     (*SupportedModes)->UdmaMode.Mode  = SelectedMode;
1004 
1005   } else {
1006     (*SupportedModes)->UdmaMode.Valid = FALSE;
1007   }
1008   DEBUG ((EFI_D_INFO, "IdeInitCalculateMode: UdmaMode = %x\n", (*SupportedModes)->UdmaMode.Mode));
1009 
1010   //
1011   // The modes other than PIO and UDMA are not supported
1012   //
1013   return EFI_SUCCESS;
1014 }
1015 
1016 /**
1017   Commands the IDE controller driver to program the IDE controller hardware
1018   so that the specified device can operate at the specified mode.
1019 
1020   This function is used by the driver entity to instruct the IDE controller
1021   driver to program the IDE controller hardware to the specified modes. This
1022   function can be called only once for a particular device. For a Serial ATA
1023   (SATA) Advanced Host Controller Interface (AHCI) controller, no controller-
1024   specific programming may be required.
1025 
1026   @param[in] This      Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
1027   @param[in] Channel   Zero-based channel number.
1028   @param[in] Device    Zero-based device number on the Channel.
1029   @param[in] Modes     The modes to set.
1030 
1031   @retval EFI_SUCCESS             The command was accepted without any errors.
1032   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
1033   @retval EFI_INVALID_PARAMETER   Device is invalid.
1034   @retval EFI_NOT_READY           Modes cannot be set at this time due to lack of data.
1035   @retval EFI_DEVICE_ERROR        Modes cannot be set due to hardware failure.
1036                                   The driver entity should not use this device.
1037 
1038 **/
1039 EFI_STATUS
1040 EFIAPI
IdeInitSetTiming(IN EFI_IDE_CONTROLLER_INIT_PROTOCOL * This,IN UINT8 Channel,IN UINT8 Device,IN EFI_ATA_COLLECTIVE_MODE * Modes)1041 IdeInitSetTiming (
1042   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
1043   IN UINT8                              Channel,
1044   IN UINT8                              Device,
1045   IN EFI_ATA_COLLECTIVE_MODE            *Modes
1046   )
1047 {
1048   return EFI_SUCCESS;
1049 }
1050