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