]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AtaAtapiPassThru / AhciMode.c
1 /** @file
2 The file for AHCI mode of ATA host controller.
3
4 Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "AtaAtapiPassThru.h"
11
12 /**
13 Read AHCI Operation register.
14
15 @param PciIo The PCI IO protocol instance.
16 @param Offset The operation register offset.
17
18 @return The register content read.
19
20 **/
21 UINT32
22 EFIAPI
23 AhciReadReg (
24 IN EFI_PCI_IO_PROTOCOL *PciIo,
25 IN UINT32 Offset
26 )
27 {
28 UINT32 Data;
29
30 ASSERT (PciIo != NULL);
31
32 Data = 0;
33
34 PciIo->Mem.Read (
35 PciIo,
36 EfiPciIoWidthUint32,
37 EFI_AHCI_BAR_INDEX,
38 (UINT64)Offset,
39 1,
40 &Data
41 );
42
43 return Data;
44 }
45
46 /**
47 Write AHCI Operation register.
48
49 @param PciIo The PCI IO protocol instance.
50 @param Offset The operation register offset.
51 @param Data The data used to write down.
52
53 **/
54 VOID
55 EFIAPI
56 AhciWriteReg (
57 IN EFI_PCI_IO_PROTOCOL *PciIo,
58 IN UINT32 Offset,
59 IN UINT32 Data
60 )
61 {
62 ASSERT (PciIo != NULL);
63
64 PciIo->Mem.Write (
65 PciIo,
66 EfiPciIoWidthUint32,
67 EFI_AHCI_BAR_INDEX,
68 (UINT64)Offset,
69 1,
70 &Data
71 );
72
73 return;
74 }
75
76 /**
77 Do AND operation with the value of AHCI Operation register.
78
79 @param PciIo The PCI IO protocol instance.
80 @param Offset The operation register offset.
81 @param AndData The data used to do AND operation.
82
83 **/
84 VOID
85 EFIAPI
86 AhciAndReg (
87 IN EFI_PCI_IO_PROTOCOL *PciIo,
88 IN UINT32 Offset,
89 IN UINT32 AndData
90 )
91 {
92 UINT32 Data;
93
94 ASSERT (PciIo != NULL);
95
96 Data = AhciReadReg (PciIo, Offset);
97
98 Data &= AndData;
99
100 AhciWriteReg (PciIo, Offset, Data);
101 }
102
103 /**
104 Do OR operation with the value of AHCI Operation register.
105
106 @param PciIo The PCI IO protocol instance.
107 @param Offset The operation register offset.
108 @param OrData The data used to do OR operation.
109
110 **/
111 VOID
112 EFIAPI
113 AhciOrReg (
114 IN EFI_PCI_IO_PROTOCOL *PciIo,
115 IN UINT32 Offset,
116 IN UINT32 OrData
117 )
118 {
119 UINT32 Data;
120
121 ASSERT (PciIo != NULL);
122
123 Data = AhciReadReg (PciIo, Offset);
124
125 Data |= OrData;
126
127 AhciWriteReg (PciIo, Offset, Data);
128 }
129
130 /**
131 Wait for the value of the specified MMIO register set to the test value.
132
133 @param PciIo The PCI IO protocol instance.
134 @param Offset The MMIO address to test.
135 @param MaskValue The mask value of memory.
136 @param TestValue The test value of memory.
137 @param Timeout The time out value for wait memory set, uses 100ns as a unit.
138
139 @retval EFI_TIMEOUT The MMIO setting is time out.
140 @retval EFI_SUCCESS The MMIO is correct set.
141
142 **/
143 EFI_STATUS
144 EFIAPI
145 AhciWaitMmioSet (
146 IN EFI_PCI_IO_PROTOCOL *PciIo,
147 IN UINTN Offset,
148 IN UINT32 MaskValue,
149 IN UINT32 TestValue,
150 IN UINT64 Timeout
151 )
152 {
153 UINT32 Value;
154 UINT64 Delay;
155 BOOLEAN InfiniteWait;
156
157 if (Timeout == 0) {
158 InfiniteWait = TRUE;
159 } else {
160 InfiniteWait = FALSE;
161 }
162
163 Delay = DivU64x32 (Timeout, 1000) + 1;
164
165 do {
166 //
167 // Access PCI MMIO space to see if the value is the tested one.
168 //
169 Value = AhciReadReg (PciIo, (UINT32)Offset) & MaskValue;
170
171 if (Value == TestValue) {
172 return EFI_SUCCESS;
173 }
174
175 //
176 // Stall for 100 microseconds.
177 //
178 MicroSecondDelay (100);
179
180 Delay--;
181 } while (InfiniteWait || (Delay > 0));
182
183 return EFI_TIMEOUT;
184 }
185
186 /**
187 Wait for the value of the specified system memory set to the test value.
188
189 @param Address The system memory address to test.
190 @param MaskValue The mask value of memory.
191 @param TestValue The test value of memory.
192 @param Timeout The time out value for wait memory set, uses 100ns as a unit.
193
194 @retval EFI_TIMEOUT The system memory setting is time out.
195 @retval EFI_SUCCESS The system memory is correct set.
196
197 **/
198 EFI_STATUS
199 EFIAPI
200 AhciWaitMemSet (
201 IN EFI_PHYSICAL_ADDRESS Address,
202 IN UINT32 MaskValue,
203 IN UINT32 TestValue,
204 IN UINT64 Timeout
205 )
206 {
207 UINT32 Value;
208 UINT64 Delay;
209 BOOLEAN InfiniteWait;
210
211 if (Timeout == 0) {
212 InfiniteWait = TRUE;
213 } else {
214 InfiniteWait = FALSE;
215 }
216
217 Delay = DivU64x32 (Timeout, 1000) + 1;
218
219 do {
220 //
221 // Access system memory to see if the value is the tested one.
222 //
223 // The system memory pointed by Address will be updated by the
224 // SATA Host Controller, "volatile" is introduced to prevent
225 // compiler from optimizing the access to the memory address
226 // to only read once.
227 //
228 Value = *(volatile UINT32 *)(UINTN)Address;
229 Value &= MaskValue;
230
231 if (Value == TestValue) {
232 return EFI_SUCCESS;
233 }
234
235 //
236 // Stall for 100 microseconds.
237 //
238 MicroSecondDelay (100);
239
240 Delay--;
241 } while (InfiniteWait || (Delay > 0));
242
243 return EFI_TIMEOUT;
244 }
245
246 /**
247 Check the memory status to the test value.
248
249 @param[in] Address The memory address to test.
250 @param[in] MaskValue The mask value of memory.
251 @param[in] TestValue The test value of memory.
252
253 @retval EFI_NOT_READY The memory is not set.
254 @retval EFI_SUCCESS The memory is correct set.
255 **/
256 EFI_STATUS
257 EFIAPI
258 AhciCheckMemSet (
259 IN UINTN Address,
260 IN UINT32 MaskValue,
261 IN UINT32 TestValue
262 )
263 {
264 UINT32 Value;
265
266 Value = *(volatile UINT32 *)Address;
267 Value &= MaskValue;
268
269 if (Value == TestValue) {
270 return EFI_SUCCESS;
271 }
272
273 return EFI_NOT_READY;
274 }
275
276 /**
277
278 Clear the port interrupt and error status. It will also clear
279 HBA interrupt status.
280
281 @param PciIo The PCI IO protocol instance.
282 @param Port The number of port.
283
284 **/
285 VOID
286 EFIAPI
287 AhciClearPortStatus (
288 IN EFI_PCI_IO_PROTOCOL *PciIo,
289 IN UINT8 Port
290 )
291 {
292 UINT32 Offset;
293
294 //
295 // Clear any error status
296 //
297 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR;
298 AhciWriteReg (PciIo, Offset, AhciReadReg (PciIo, Offset));
299
300 //
301 // Clear any port interrupt status
302 //
303 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
304 AhciWriteReg (PciIo, Offset, AhciReadReg (PciIo, Offset));
305
306 //
307 // Clear any HBA interrupt status
308 //
309 AhciWriteReg (PciIo, EFI_AHCI_IS_OFFSET, AhciReadReg (PciIo, EFI_AHCI_IS_OFFSET));
310 }
311
312 /**
313 This function is used to dump the Status Registers and if there is ERR bit set
314 in the Status Register, the Error Register's value is also be dumped.
315
316 @param PciIo The PCI IO protocol instance.
317 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
318 @param Port The number of port.
319 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
320
321 **/
322 VOID
323 EFIAPI
324 AhciDumpPortStatus (
325 IN EFI_PCI_IO_PROTOCOL *PciIo,
326 IN EFI_AHCI_REGISTERS *AhciRegisters,
327 IN UINT8 Port,
328 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
329 )
330 {
331 UINTN Offset;
332 UINT32 Data;
333 UINTN FisBaseAddr;
334 EFI_STATUS Status;
335
336 ASSERT (PciIo != NULL);
337
338 if (AtaStatusBlock != NULL) {
339 ZeroMem (AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
340
341 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS);
342 Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET;
343
344 Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, EFI_AHCI_FIS_REGISTER_D2H);
345 if (!EFI_ERROR (Status)) {
346 //
347 // If D2H FIS is received, update StatusBlock with its content.
348 //
349 CopyMem (AtaStatusBlock, (UINT8 *)Offset, sizeof (EFI_ATA_STATUS_BLOCK));
350 } else {
351 //
352 // If D2H FIS is not received, only update Status & Error field through PxTFD
353 // as there is no other way to get the content of the Shadow Register Block.
354 //
355 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
356 Data = AhciReadReg (PciIo, (UINT32)Offset);
357
358 AtaStatusBlock->AtaStatus = (UINT8)Data;
359 if ((AtaStatusBlock->AtaStatus & BIT0) != 0) {
360 AtaStatusBlock->AtaError = (UINT8)(Data >> 8);
361 }
362 }
363 }
364 }
365
366 /**
367 Enable the FIS running for giving port.
368
369 @param PciIo The PCI IO protocol instance.
370 @param Port The number of port.
371 @param Timeout The timeout value of enabling FIS, uses 100ns as a unit.
372
373 @retval EFI_DEVICE_ERROR The FIS enable setting fails.
374 @retval EFI_TIMEOUT The FIS enable setting is time out.
375 @retval EFI_SUCCESS The FIS enable successfully.
376
377 **/
378 EFI_STATUS
379 EFIAPI
380 AhciEnableFisReceive (
381 IN EFI_PCI_IO_PROTOCOL *PciIo,
382 IN UINT8 Port,
383 IN UINT64 Timeout
384 )
385 {
386 UINT32 Offset;
387
388 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
389 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_FRE);
390
391 return EFI_SUCCESS;
392 }
393
394 /**
395 Disable the FIS running for giving port.
396
397 @param PciIo The PCI IO protocol instance.
398 @param Port The number of port.
399 @param Timeout The timeout value of disabling FIS, uses 100ns as a unit.
400
401 @retval EFI_DEVICE_ERROR The FIS disable setting fails.
402 @retval EFI_TIMEOUT The FIS disable setting is time out.
403 @retval EFI_UNSUPPORTED The port is in running state.
404 @retval EFI_SUCCESS The FIS disable successfully.
405
406 **/
407 EFI_STATUS
408 EFIAPI
409 AhciDisableFisReceive (
410 IN EFI_PCI_IO_PROTOCOL *PciIo,
411 IN UINT8 Port,
412 IN UINT64 Timeout
413 )
414 {
415 UINT32 Offset;
416 UINT32 Data;
417
418 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
419 Data = AhciReadReg (PciIo, Offset);
420
421 //
422 // Before disabling Fis receive, the DMA engine of the port should NOT be in running status.
423 //
424 if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) != 0) {
425 return EFI_UNSUPPORTED;
426 }
427
428 //
429 // Check if the Fis receive DMA engine for the port is running.
430 //
431 if ((Data & EFI_AHCI_PORT_CMD_FR) != EFI_AHCI_PORT_CMD_FR) {
432 return EFI_SUCCESS;
433 }
434
435 AhciAndReg (PciIo, Offset, (UINT32) ~(EFI_AHCI_PORT_CMD_FRE));
436
437 return AhciWaitMmioSet (
438 PciIo,
439 Offset,
440 EFI_AHCI_PORT_CMD_FR,
441 0,
442 Timeout
443 );
444 }
445
446 /**
447 Build the command list, command table and prepare the fis receiver.
448
449 @param PciIo The PCI IO protocol instance.
450 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
451 @param Port The number of port.
452 @param PortMultiplier The timeout value of stop.
453 @param CommandFis The control fis will be used for the transfer.
454 @param CommandList The command list will be used for the transfer.
455 @param AtapiCommand The atapi command will be used for the transfer.
456 @param AtapiCommandLength The length of the atapi command.
457 @param CommandSlotNumber The command slot will be used for the transfer.
458 @param DataPhysicalAddr The pointer to the data buffer pci bus master address.
459 @param DataLength The data count to be transferred.
460
461 **/
462 VOID
463 EFIAPI
464 AhciBuildCommand (
465 IN EFI_PCI_IO_PROTOCOL *PciIo,
466 IN EFI_AHCI_REGISTERS *AhciRegisters,
467 IN UINT8 Port,
468 IN UINT8 PortMultiplier,
469 IN EFI_AHCI_COMMAND_FIS *CommandFis,
470 IN EFI_AHCI_COMMAND_LIST *CommandList,
471 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
472 IN UINT8 AtapiCommandLength,
473 IN UINT8 CommandSlotNumber,
474 IN OUT VOID *DataPhysicalAddr,
475 IN UINT32 DataLength
476 )
477 {
478 UINT64 BaseAddr;
479 UINT32 PrdtNumber;
480 UINT32 PrdtIndex;
481 UINTN RemainedData;
482 UINTN MemAddr;
483 DATA_64 Data64;
484 UINT32 Offset;
485
486 //
487 // Filling the PRDT
488 //
489 PrdtNumber = (UINT32)DivU64x32 (((UINT64)DataLength + EFI_AHCI_MAX_DATA_PER_PRDT - 1), EFI_AHCI_MAX_DATA_PER_PRDT);
490
491 //
492 // According to AHCI 1.3 spec, a PRDT entry can point to a maximum 4MB data block.
493 // It also limits that the maximum amount of the PRDT entry in the command table
494 // is 65535.
495 //
496 ASSERT (PrdtNumber <= 65535);
497
498 Data64.Uint64 = (UINTN)(AhciRegisters->AhciRFis) + sizeof (EFI_AHCI_RECEIVED_FIS) * Port;
499
500 BaseAddr = Data64.Uint64;
501
502 ZeroMem ((VOID *)((UINTN)BaseAddr), sizeof (EFI_AHCI_RECEIVED_FIS));
503
504 ZeroMem (AhciRegisters->AhciCommandTable, sizeof (EFI_AHCI_COMMAND_TABLE));
505
506 CommandFis->AhciCFisPmNum = PortMultiplier;
507
508 CopyMem (&AhciRegisters->AhciCommandTable->CommandFis, CommandFis, sizeof (EFI_AHCI_COMMAND_FIS));
509
510 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
511 if (AtapiCommand != NULL) {
512 CopyMem (
513 &AhciRegisters->AhciCommandTable->AtapiCmd,
514 AtapiCommand,
515 AtapiCommandLength
516 );
517
518 CommandList->AhciCmdA = 1;
519 CommandList->AhciCmdP = 1;
520
521 AhciOrReg (PciIo, Offset, (EFI_AHCI_PORT_CMD_DLAE | EFI_AHCI_PORT_CMD_ATAPI));
522 } else {
523 AhciAndReg (PciIo, Offset, (UINT32) ~(EFI_AHCI_PORT_CMD_DLAE | EFI_AHCI_PORT_CMD_ATAPI));
524 }
525
526 RemainedData = (UINTN)DataLength;
527 MemAddr = (UINTN)DataPhysicalAddr;
528 CommandList->AhciCmdPrdtl = PrdtNumber;
529
530 for (PrdtIndex = 0; PrdtIndex < PrdtNumber; PrdtIndex++) {
531 if (RemainedData < EFI_AHCI_MAX_DATA_PER_PRDT) {
532 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = (UINT32)RemainedData - 1;
533 } else {
534 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = EFI_AHCI_MAX_DATA_PER_PRDT - 1;
535 }
536
537 Data64.Uint64 = (UINT64)MemAddr;
538 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDba = Data64.Uint32.Lower32;
539 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbau = Data64.Uint32.Upper32;
540 RemainedData -= EFI_AHCI_MAX_DATA_PER_PRDT;
541 MemAddr += EFI_AHCI_MAX_DATA_PER_PRDT;
542 }
543
544 //
545 // Set the last PRDT to Interrupt On Complete
546 //
547 if (PrdtNumber > 0) {
548 AhciRegisters->AhciCommandTable->PrdtTable[PrdtNumber - 1].AhciPrdtIoc = 1;
549 }
550
551 CopyMem (
552 (VOID *)((UINTN)AhciRegisters->AhciCmdList + (UINTN)CommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST)),
553 CommandList,
554 sizeof (EFI_AHCI_COMMAND_LIST)
555 );
556
557 Data64.Uint64 = (UINT64)(UINTN)AhciRegisters->AhciCommandTablePciAddr;
558 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtba = Data64.Uint32.Lower32;
559 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtbau = Data64.Uint32.Upper32;
560 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdPmp = PortMultiplier;
561 }
562
563 /**
564 Build a command FIS.
565
566 @param CmdFis A pointer to the EFI_AHCI_COMMAND_FIS data structure.
567 @param AtaCommandBlock A pointer to the AhciBuildCommandFis data structure.
568
569 **/
570 VOID
571 EFIAPI
572 AhciBuildCommandFis (
573 IN OUT EFI_AHCI_COMMAND_FIS *CmdFis,
574 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock
575 )
576 {
577 ZeroMem (CmdFis, sizeof (EFI_AHCI_COMMAND_FIS));
578
579 CmdFis->AhciCFisType = EFI_AHCI_FIS_REGISTER_H2D;
580 //
581 // Indicator it's a command
582 //
583 CmdFis->AhciCFisCmdInd = 0x1;
584 CmdFis->AhciCFisCmd = AtaCommandBlock->AtaCommand;
585
586 CmdFis->AhciCFisFeature = AtaCommandBlock->AtaFeatures;
587 CmdFis->AhciCFisFeatureExp = AtaCommandBlock->AtaFeaturesExp;
588
589 CmdFis->AhciCFisSecNum = AtaCommandBlock->AtaSectorNumber;
590 CmdFis->AhciCFisSecNumExp = AtaCommandBlock->AtaSectorNumberExp;
591
592 CmdFis->AhciCFisClyLow = AtaCommandBlock->AtaCylinderLow;
593 CmdFis->AhciCFisClyLowExp = AtaCommandBlock->AtaCylinderLowExp;
594
595 CmdFis->AhciCFisClyHigh = AtaCommandBlock->AtaCylinderHigh;
596 CmdFis->AhciCFisClyHighExp = AtaCommandBlock->AtaCylinderHighExp;
597
598 CmdFis->AhciCFisSecCount = AtaCommandBlock->AtaSectorCount;
599 CmdFis->AhciCFisSecCountExp = AtaCommandBlock->AtaSectorCountExp;
600
601 CmdFis->AhciCFisDevHead = (UINT8)(AtaCommandBlock->AtaDeviceHead | 0xE0);
602 }
603
604 /**
605 Wait until SATA device reports it is ready for operation.
606
607 @param[in] PciIo Pointer to AHCI controller PciIo.
608 @param[in] Port SATA port index on which to reset.
609
610 @retval EFI_SUCCESS Device ready for operation.
611 @retval EFI_TIMEOUT Device failed to get ready within required period.
612 **/
613 EFI_STATUS
614 AhciWaitDeviceReady (
615 IN EFI_PCI_IO_PROTOCOL *PciIo,
616 IN UINT8 Port
617 )
618 {
619 UINT32 PhyDetectDelay;
620 UINT32 Data;
621 UINT32 Offset;
622
623 //
624 // According to SATA1.0a spec section 5.2, we need to wait for PxTFD.BSY and PxTFD.DRQ
625 // and PxTFD.ERR to be zero. The maximum wait time is 16s which is defined at ATA spec.
626 //
627 PhyDetectDelay = 16 * 1000;
628 do {
629 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR;
630 if (AhciReadReg (PciIo, Offset) != 0) {
631 AhciWriteReg (PciIo, Offset, AhciReadReg (PciIo, Offset));
632 }
633
634 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
635
636 Data = AhciReadReg (PciIo, Offset) & EFI_AHCI_PORT_TFD_MASK;
637 if (Data == 0) {
638 break;
639 }
640
641 MicroSecondDelay (1000);
642 PhyDetectDelay--;
643 } while (PhyDetectDelay > 0);
644
645 if (PhyDetectDelay == 0) {
646 DEBUG ((DEBUG_ERROR, "Port %d Device not ready (TFD=0x%X)\n", Port, Data));
647 return EFI_TIMEOUT;
648 } else {
649 return EFI_SUCCESS;
650 }
651 }
652
653 /**
654 Reset the SATA port. Algorithm follows AHCI spec 1.3.1 section 10.4.2
655
656 @param[in] PciIo Pointer to AHCI controller PciIo.
657 @param[in] Port SATA port index on which to reset.
658
659 @retval EFI_SUCCESS Port reset.
660 @retval Others Failed to reset the port.
661 **/
662 EFI_STATUS
663 AhciResetPort (
664 IN EFI_PCI_IO_PROTOCOL *PciIo,
665 IN UINT8 Port
666 )
667 {
668 UINT32 Offset;
669 EFI_STATUS Status;
670
671 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SCTL;
672 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_SCTL_DET_INIT);
673 //
674 // SW is required to keep DET set to 0x1 at least for 1 milisecond to ensure that
675 // at least one COMRESET signal is sent.
676 //
677 MicroSecondDelay (1000);
678 AhciAndReg (PciIo, Offset, ~(UINT32)EFI_AHCI_PORT_SSTS_DET_MASK);
679
680 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS;
681 Status = AhciWaitMmioSet (PciIo, Offset, EFI_AHCI_PORT_SSTS_DET_MASK, EFI_AHCI_PORT_SSTS_DET_PCE, ATA_ATAPI_TIMEOUT);
682 if (EFI_ERROR (Status)) {
683 return Status;
684 }
685
686 return AhciWaitDeviceReady (PciIo, Port);
687 }
688
689 /**
690 Recovers the SATA port from error condition.
691 This function implements algorithm described in
692 AHCI spec 1.3.1 section 6.2.2
693
694 @param[in] PciIo Pointer to AHCI controller PciIo.
695 @param[in] Port SATA port index on which to check.
696
697 @retval EFI_SUCCESS Port recovered.
698 @retval Others Failed to recover port.
699 **/
700 EFI_STATUS
701 AhciRecoverPortError (
702 IN EFI_PCI_IO_PROTOCOL *PciIo,
703 IN UINT8 Port
704 )
705 {
706 UINT32 Offset;
707 UINT32 PortInterrupt;
708 UINT32 PortTfd;
709 EFI_STATUS Status;
710
711 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
712 PortInterrupt = AhciReadReg (PciIo, Offset);
713 if ((PortInterrupt & EFI_AHCI_PORT_IS_FATAL_ERROR_MASK) == 0) {
714 //
715 // No fatal error detected. Exit with success as port should still be operational.
716 // No need to clear IS as it will be cleared when the next command starts.
717 //
718 return EFI_SUCCESS;
719 }
720
721 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
722 AhciAndReg (PciIo, Offset, ~(UINT32)EFI_AHCI_PORT_CMD_ST);
723
724 Status = AhciWaitMmioSet (PciIo, Offset, EFI_AHCI_PORT_CMD_CR, 0, ATA_ATAPI_TIMEOUT);
725 if (EFI_ERROR (Status)) {
726 DEBUG ((DEBUG_ERROR, "Ahci port %d is in hung state, aborting recovery\n", Port));
727 return Status;
728 }
729
730 //
731 // If TFD.BSY or TFD.DRQ is still set it means that drive is hung and software has
732 // to reset it before sending any additional commands.
733 //
734 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
735 PortTfd = AhciReadReg (PciIo, Offset);
736 if ((PortTfd & (EFI_AHCI_PORT_TFD_BSY | EFI_AHCI_PORT_TFD_DRQ)) != 0) {
737 Status = AhciResetPort (PciIo, Port);
738 if (EFI_ERROR (Status)) {
739 DEBUG ((DEBUG_ERROR, "Failed to reset the port %d\n", Port));
740 }
741 }
742
743 return EFI_SUCCESS;
744 }
745
746 /**
747 Checks if specified FIS has been received.
748
749 @param[in] PciIo Pointer to AHCI controller PciIo.
750 @param[in] Port SATA port index on which to check.
751 @param[in] FisType FIS type for which to check.
752
753 @retval EFI_SUCCESS FIS received.
754 @retval EFI_NOT_READY FIS not received yet.
755 @retval EFI_DEVICE_ERROR AHCI controller reported an error on port.
756 **/
757 EFI_STATUS
758 AhciCheckFisReceived (
759 IN EFI_PCI_IO_PROTOCOL *PciIo,
760 IN UINT8 Port,
761 IN SATA_FIS_TYPE FisType
762 )
763 {
764 UINT32 Offset;
765 UINT32 PortInterrupt;
766 UINT32 PortTfd;
767
768 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
769 PortInterrupt = AhciReadReg (PciIo, Offset);
770 if ((PortInterrupt & EFI_AHCI_PORT_IS_ERROR_MASK) != 0) {
771 DEBUG ((DEBUG_ERROR, "AHCI: Error interrupt reported PxIS: %X\n", PortInterrupt));
772 return EFI_DEVICE_ERROR;
773 }
774
775 //
776 // For PIO setup FIS - According to SATA 2.6 spec section 11.7, D2h FIS means an error encountered.
777 // But Qemu and Marvel 9230 sata controller may just receive a D2h FIS from device
778 // after the transaction is finished successfully.
779 // To get better device compatibilities, we further check if the PxTFD's ERR bit is set.
780 // By this way, we can know if there is a real error happened.
781 //
782 if (((FisType == SataFisD2H) && ((PortInterrupt & EFI_AHCI_PORT_IS_DHRS) != 0)) ||
783 ((FisType == SataFisPioSetup) && ((PortInterrupt & (EFI_AHCI_PORT_IS_PSS | EFI_AHCI_PORT_IS_DHRS)) != 0)) ||
784 ((FisType == SataFisDmaSetup) && ((PortInterrupt & (EFI_AHCI_PORT_IS_DSS | EFI_AHCI_PORT_IS_DHRS)) != 0)))
785 {
786 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
787 PortTfd = AhciReadReg (PciIo, (UINT32)Offset);
788 if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) {
789 return EFI_DEVICE_ERROR;
790 } else {
791 return EFI_SUCCESS;
792 }
793 }
794
795 return EFI_NOT_READY;
796 }
797
798 /**
799 Waits until specified FIS has been received.
800
801 @param[in] PciIo Pointer to AHCI controller PciIo.
802 @param[in] Port SATA port index on which to check.
803 @param[in] Timeout Time after which function should stop polling.
804 @param[in] FisType FIS type for which to check.
805
806 @retval EFI_SUCCESS FIS received.
807 @retval EFI_TIMEOUT FIS failed to arrive within a specified time period.
808 @retval EFI_DEVICE_ERROR AHCI controller reported an error on port.
809 **/
810 EFI_STATUS
811 AhciWaitUntilFisReceived (
812 IN EFI_PCI_IO_PROTOCOL *PciIo,
813 IN UINT8 Port,
814 IN UINT64 Timeout,
815 IN SATA_FIS_TYPE FisType
816 )
817 {
818 EFI_STATUS Status;
819 BOOLEAN InfiniteWait;
820 UINT64 Delay;
821
822 Delay = DivU64x32 (Timeout, 1000) + 1;
823 if (Timeout == 0) {
824 InfiniteWait = TRUE;
825 } else {
826 InfiniteWait = FALSE;
827 }
828
829 do {
830 Status = AhciCheckFisReceived (PciIo, Port, FisType);
831 if (Status != EFI_NOT_READY) {
832 return Status;
833 }
834
835 //
836 // Stall for 100 microseconds.
837 //
838 MicroSecondDelay (100);
839 Delay--;
840 } while (InfiniteWait || (Delay > 0));
841
842 return EFI_TIMEOUT;
843 }
844
845 /**
846 Prints contents of the ATA command block into the debug port.
847
848 @param[in] AtaCommandBlock AtaCommandBlock to print.
849 @param[in] DebugLevel Debug level on which to print.
850 **/
851 VOID
852 AhciPrintCommandBlock (
853 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
854 IN UINT32 DebugLevel
855 )
856 {
857 DEBUG ((DebugLevel, "ATA COMMAND BLOCK:\n"));
858 DEBUG ((DebugLevel, "AtaCommand: %d\n", AtaCommandBlock->AtaCommand));
859 DEBUG ((DebugLevel, "AtaFeatures: %X\n", AtaCommandBlock->AtaFeatures));
860 DEBUG ((DebugLevel, "AtaSectorNumber: %d\n", AtaCommandBlock->AtaSectorNumber));
861 DEBUG ((DebugLevel, "AtaCylinderLow: %X\n", AtaCommandBlock->AtaCylinderHigh));
862 DEBUG ((DebugLevel, "AtaCylinderHigh: %X\n", AtaCommandBlock->AtaCylinderHigh));
863 DEBUG ((DebugLevel, "AtaDeviceHead: %d\n", AtaCommandBlock->AtaDeviceHead));
864 DEBUG ((DebugLevel, "AtaSectorNumberExp: %d\n", AtaCommandBlock->AtaSectorNumberExp));
865 DEBUG ((DebugLevel, "AtaCylinderLowExp: %X\n", AtaCommandBlock->AtaCylinderLowExp));
866 DEBUG ((DebugLevel, "AtaCylinderHighExp: %X\n", AtaCommandBlock->AtaCylinderHighExp));
867 DEBUG ((DebugLevel, "AtaFeaturesExp: %X\n", AtaCommandBlock->AtaFeaturesExp));
868 DEBUG ((DebugLevel, "AtaSectorCount: %d\n", AtaCommandBlock->AtaSectorCount));
869 DEBUG ((DebugLevel, "AtaSectorCountExp: %d\n", AtaCommandBlock->AtaSectorCountExp));
870 }
871
872 /**
873 Prints contents of the ATA status block into the debug port.
874
875 @param[in] AtaStatusBlock AtaStatusBlock to print.
876 @param[in] DebugLevel Debug level on which to print.
877 **/
878 VOID
879 AhciPrintStatusBlock (
880 IN EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
881 IN UINT32 DebugLevel
882 )
883 {
884 //
885 // Skip NULL pointer
886 //
887 if (AtaStatusBlock == NULL) {
888 return;
889 }
890
891 //
892 // Only print status and error since we have all of the rest printed as
893 // a part of command block print.
894 //
895 DEBUG ((DebugLevel, "ATA STATUS BLOCK:\n"));
896 DEBUG ((DebugLevel, "AtaStatus: %d\n", AtaStatusBlock->AtaStatus));
897 DEBUG ((DebugLevel, "AtaError: %d\n", AtaStatusBlock->AtaError));
898 }
899
900 /**
901 Start a PIO data transfer on specific port.
902
903 @param[in] PciIo The PCI IO protocol instance.
904 @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
905 @param[in] Port The number of port.
906 @param[in] PortMultiplier The timeout value of stop.
907 @param[in] AtapiCommand The atapi command will be used for the
908 transfer.
909 @param[in] AtapiCommandLength The length of the atapi command.
910 @param[in] Read The transfer direction.
911 @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
912 @param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
913 @param[in, out] MemoryAddr The pointer to the data buffer.
914 @param[in] DataCount The data count to be transferred.
915 @param[in] Timeout The timeout value of non data transfer, uses 100ns as a unit.
916 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
917 used by non-blocking mode.
918
919 @retval EFI_DEVICE_ERROR The PIO data transfer abort with error occurs.
920 @retval EFI_TIMEOUT The operation is time out.
921 @retval EFI_UNSUPPORTED The device is not ready for transfer.
922 @retval EFI_SUCCESS The PIO data transfer executes successfully.
923
924 **/
925 EFI_STATUS
926 EFIAPI
927 AhciPioTransfer (
928 IN EFI_PCI_IO_PROTOCOL *PciIo,
929 IN EFI_AHCI_REGISTERS *AhciRegisters,
930 IN UINT8 Port,
931 IN UINT8 PortMultiplier,
932 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
933 IN UINT8 AtapiCommandLength,
934 IN BOOLEAN Read,
935 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
936 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
937 IN OUT VOID *MemoryAddr,
938 IN UINT32 DataCount,
939 IN UINT64 Timeout,
940 IN ATA_NONBLOCK_TASK *Task
941 )
942 {
943 EFI_STATUS Status;
944 EFI_PHYSICAL_ADDRESS PhyAddr;
945 VOID *Map;
946 UINTN MapLength;
947 EFI_PCI_IO_PROTOCOL_OPERATION Flag;
948 EFI_AHCI_COMMAND_FIS CFis;
949 EFI_AHCI_COMMAND_LIST CmdList;
950 UINT32 PrdCount;
951 UINT32 Retry;
952 EFI_STATUS RecoveryStatus;
953
954 if (Read) {
955 Flag = EfiPciIoOperationBusMasterWrite;
956 } else {
957 Flag = EfiPciIoOperationBusMasterRead;
958 }
959
960 //
961 // construct command list and command table with pci bus address
962 //
963 MapLength = DataCount;
964 Status = PciIo->Map (
965 PciIo,
966 Flag,
967 MemoryAddr,
968 &MapLength,
969 &PhyAddr,
970 &Map
971 );
972
973 if (EFI_ERROR (Status) || (DataCount != MapLength)) {
974 return EFI_BAD_BUFFER_SIZE;
975 }
976
977 //
978 // Package read needed
979 //
980 AhciBuildCommandFis (&CFis, AtaCommandBlock);
981
982 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
983
984 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
985 CmdList.AhciCmdW = Read ? 0 : 1;
986
987 for (Retry = 0; Retry < AHCI_COMMAND_RETRIES; Retry++) {
988 AhciBuildCommand (
989 PciIo,
990 AhciRegisters,
991 Port,
992 PortMultiplier,
993 &CFis,
994 &CmdList,
995 AtapiCommand,
996 AtapiCommandLength,
997 0,
998 (VOID *)(UINTN)PhyAddr,
999 DataCount
1000 );
1001
1002 DEBUG ((DEBUG_VERBOSE, "Starting command for PIO transfer:\n"));
1003 AhciPrintCommandBlock (AtaCommandBlock, DEBUG_VERBOSE);
1004 Status = AhciStartCommand (
1005 PciIo,
1006 Port,
1007 0,
1008 Timeout
1009 );
1010 if (EFI_ERROR (Status)) {
1011 break;
1012 }
1013
1014 if (Read && (AtapiCommand == 0)) {
1015 Status = AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisPioSetup);
1016 if (Status == EFI_SUCCESS) {
1017 PrdCount = *(volatile UINT32 *)(&(AhciRegisters->AhciCmdList[0].AhciCmdPrdbc));
1018 if (PrdCount == DataCount) {
1019 Status = EFI_SUCCESS;
1020 } else {
1021 Status = EFI_DEVICE_ERROR;
1022 }
1023 }
1024 } else {
1025 Status = AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2H);
1026 }
1027
1028 if (Status == EFI_DEVICE_ERROR) {
1029 DEBUG ((DEBUG_ERROR, "PIO command failed at retry %d\n", Retry));
1030 RecoveryStatus = AhciRecoverPortError (PciIo, Port);
1031 if (EFI_ERROR (RecoveryStatus)) {
1032 break;
1033 }
1034 } else {
1035 break;
1036 }
1037 }
1038
1039 AhciStopCommand (
1040 PciIo,
1041 Port,
1042 Timeout
1043 );
1044
1045 AhciDisableFisReceive (
1046 PciIo,
1047 Port,
1048 Timeout
1049 );
1050
1051 PciIo->Unmap (
1052 PciIo,
1053 Map
1054 );
1055
1056 AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock);
1057
1058 if (Status == EFI_DEVICE_ERROR) {
1059 DEBUG ((DEBUG_ERROR, "Failed to execute command for PIO transfer:\n"));
1060 //
1061 // Repeat command block here to make sure it is printed on
1062 // device error debug level.
1063 //
1064 AhciPrintCommandBlock (AtaCommandBlock, DEBUG_ERROR);
1065 AhciPrintStatusBlock (AtaStatusBlock, DEBUG_ERROR);
1066 } else {
1067 AhciPrintStatusBlock (AtaStatusBlock, DEBUG_VERBOSE);
1068 }
1069
1070 return Status;
1071 }
1072
1073 /**
1074 Start a DMA data transfer on specific port
1075
1076 @param[in] Instance The ATA_ATAPI_PASS_THRU_INSTANCE protocol instance.
1077 @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1078 @param[in] Port The number of port.
1079 @param[in] PortMultiplier The timeout value of stop.
1080 @param[in] AtapiCommand The atapi command will be used for the
1081 transfer.
1082 @param[in] AtapiCommandLength The length of the atapi command.
1083 @param[in] Read The transfer direction.
1084 @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
1085 @param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
1086 @param[in, out] MemoryAddr The pointer to the data buffer.
1087 @param[in] DataCount The data count to be transferred.
1088 @param[in] Timeout The timeout value of non data transfer, uses 100ns as a unit.
1089 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1090 used by non-blocking mode.
1091
1092 @retval EFI_DEVICE_ERROR The DMA data transfer abort with error occurs.
1093 @retval EFI_TIMEOUT The operation is time out.
1094 @retval EFI_UNSUPPORTED The device is not ready for transfer.
1095 @retval EFI_SUCCESS The DMA data transfer executes successfully.
1096
1097 **/
1098 EFI_STATUS
1099 EFIAPI
1100 AhciDmaTransfer (
1101 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
1102 IN EFI_AHCI_REGISTERS *AhciRegisters,
1103 IN UINT8 Port,
1104 IN UINT8 PortMultiplier,
1105 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
1106 IN UINT8 AtapiCommandLength,
1107 IN BOOLEAN Read,
1108 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
1109 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
1110 IN OUT VOID *MemoryAddr,
1111 IN UINT32 DataCount,
1112 IN UINT64 Timeout,
1113 IN ATA_NONBLOCK_TASK *Task
1114 )
1115 {
1116 EFI_STATUS Status;
1117 EFI_PHYSICAL_ADDRESS PhyAddr;
1118 VOID *Map;
1119 UINTN MapLength;
1120 EFI_PCI_IO_PROTOCOL_OPERATION Flag;
1121 EFI_AHCI_COMMAND_FIS CFis;
1122 EFI_AHCI_COMMAND_LIST CmdList;
1123 EFI_PCI_IO_PROTOCOL *PciIo;
1124 EFI_TPL OldTpl;
1125 UINT32 Retry;
1126 EFI_STATUS RecoveryStatus;
1127
1128 Map = NULL;
1129 PciIo = Instance->PciIo;
1130
1131 if (PciIo == NULL) {
1132 return EFI_INVALID_PARAMETER;
1133 }
1134
1135 //
1136 // Set Status to suppress incorrect compiler/analyzer warnings
1137 //
1138 Status = EFI_SUCCESS;
1139
1140 //
1141 // DMA buffer allocation. Needs to be done only once for both sync and async
1142 // DMA transfers irrespective of number of retries.
1143 //
1144 if ((Task == NULL) || ((Task != NULL) && (Task->Map == NULL))) {
1145 if (Read) {
1146 Flag = EfiPciIoOperationBusMasterWrite;
1147 } else {
1148 Flag = EfiPciIoOperationBusMasterRead;
1149 }
1150
1151 MapLength = DataCount;
1152 Status = PciIo->Map (
1153 PciIo,
1154 Flag,
1155 MemoryAddr,
1156 &MapLength,
1157 &PhyAddr,
1158 &Map
1159 );
1160
1161 if (EFI_ERROR (Status) || (DataCount != MapLength)) {
1162 return EFI_BAD_BUFFER_SIZE;
1163 }
1164
1165 if (Task != NULL) {
1166 Task->Map = Map;
1167 }
1168 }
1169
1170 if ((Task == NULL) || ((Task != NULL) && !Task->IsStart)) {
1171 AhciBuildCommandFis (&CFis, AtaCommandBlock);
1172
1173 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
1174
1175 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
1176 CmdList.AhciCmdW = Read ? 0 : 1;
1177 }
1178
1179 if (Task == NULL) {
1180 //
1181 // Before starting the Blocking BlockIO operation, push to finish all non-blocking
1182 // BlockIO tasks.
1183 // Delay 100us to simulate the blocking time out checking.
1184 //
1185 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1186 while (!IsListEmpty (&Instance->NonBlockingTaskList)) {
1187 AsyncNonBlockingTransferRoutine (NULL, Instance);
1188 //
1189 // Stall for 100us.
1190 //
1191 MicroSecondDelay (100);
1192 }
1193
1194 gBS->RestoreTPL (OldTpl);
1195 for (Retry = 0; Retry < AHCI_COMMAND_RETRIES; Retry++) {
1196 AhciBuildCommand (
1197 PciIo,
1198 AhciRegisters,
1199 Port,
1200 PortMultiplier,
1201 &CFis,
1202 &CmdList,
1203 AtapiCommand,
1204 AtapiCommandLength,
1205 0,
1206 (VOID *)(UINTN)PhyAddr,
1207 DataCount
1208 );
1209
1210 DEBUG ((DEBUG_VERBOSE, "Starting command for sync DMA transfer:\n"));
1211 AhciPrintCommandBlock (AtaCommandBlock, DEBUG_VERBOSE);
1212 Status = AhciStartCommand (
1213 PciIo,
1214 Port,
1215 0,
1216 Timeout
1217 );
1218 if (EFI_ERROR (Status)) {
1219 break;
1220 }
1221
1222 Status = AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2H);
1223 if (Status == EFI_DEVICE_ERROR) {
1224 DEBUG ((DEBUG_ERROR, "DMA command failed at retry: %d\n", Retry));
1225 RecoveryStatus = AhciRecoverPortError (PciIo, Port);
1226 if (EFI_ERROR (RecoveryStatus)) {
1227 break;
1228 }
1229 } else {
1230 break;
1231 }
1232 }
1233 } else {
1234 if (!Task->IsStart) {
1235 AhciBuildCommand (
1236 PciIo,
1237 AhciRegisters,
1238 Port,
1239 PortMultiplier,
1240 &CFis,
1241 &CmdList,
1242 AtapiCommand,
1243 AtapiCommandLength,
1244 0,
1245 (VOID *)(UINTN)PhyAddr,
1246 DataCount
1247 );
1248
1249 DEBUG ((DEBUG_VERBOSE, "Starting command for async DMA transfer:\n"));
1250 AhciPrintCommandBlock (AtaCommandBlock, DEBUG_VERBOSE);
1251 Status = AhciStartCommand (
1252 PciIo,
1253 Port,
1254 0,
1255 Timeout
1256 );
1257 if (!EFI_ERROR (Status)) {
1258 Task->IsStart = TRUE;
1259 }
1260 }
1261
1262 if (Task->IsStart) {
1263 Status = AhciCheckFisReceived (PciIo, Port, SataFisD2H);
1264 if (Status == EFI_DEVICE_ERROR) {
1265 DEBUG ((DEBUG_ERROR, "DMA command failed at retry: %d\n", Task->RetryTimes));
1266 RecoveryStatus = AhciRecoverPortError (PciIo, Port);
1267 //
1268 // If recovery passed mark the Task as not started and change the status
1269 // to EFI_NOT_READY. This will make the higher level call this function again
1270 // and on next call the command will be re-issued due to IsStart being FALSE.
1271 // This also makes the next condition decrement the RetryTimes.
1272 //
1273 if (RecoveryStatus == EFI_SUCCESS) {
1274 Task->IsStart = FALSE;
1275 Status = EFI_NOT_READY;
1276 }
1277 }
1278
1279 if (Status == EFI_NOT_READY) {
1280 if (!Task->InfiniteWait && (Task->RetryTimes == 0)) {
1281 Status = EFI_TIMEOUT;
1282 } else {
1283 Task->RetryTimes--;
1284 }
1285 }
1286 }
1287 }
1288
1289 //
1290 // For Blocking mode, the command should be stopped, the Fis should be disabled
1291 // and the PciIo should be unmapped.
1292 // For non-blocking mode, only when a error is happened (if the return status is
1293 // EFI_NOT_READY that means the command doesn't finished, try again.), first do the
1294 // context cleanup, then set the packet's Asb status.
1295 //
1296 if ((Task == NULL) ||
1297 ((Task != NULL) && (Status != EFI_NOT_READY))
1298 )
1299 {
1300 AhciStopCommand (
1301 PciIo,
1302 Port,
1303 Timeout
1304 );
1305
1306 AhciDisableFisReceive (
1307 PciIo,
1308 Port,
1309 Timeout
1310 );
1311
1312 PciIo->Unmap (
1313 PciIo,
1314 (Task != NULL) ? Task->Map : Map
1315 );
1316
1317 if (Task != NULL) {
1318 Task->Packet->Asb->AtaStatus = 0x01;
1319 }
1320 }
1321
1322 AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock);
1323
1324 if (Status == EFI_DEVICE_ERROR) {
1325 DEBUG ((DEBUG_ERROR, "Failed to execute command for DMA transfer:\n"));
1326 //
1327 // Repeat command block here to make sure it is printed on
1328 // device error debug level.
1329 //
1330 AhciPrintCommandBlock (AtaCommandBlock, DEBUG_ERROR);
1331 AhciPrintStatusBlock (AtaStatusBlock, DEBUG_ERROR);
1332 } else {
1333 AhciPrintStatusBlock (AtaStatusBlock, DEBUG_VERBOSE);
1334 }
1335
1336 return Status;
1337 }
1338
1339 /**
1340 Start a non data transfer on specific port.
1341
1342 @param[in] PciIo The PCI IO protocol instance.
1343 @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1344 @param[in] Port The number of port.
1345 @param[in] PortMultiplier The timeout value of stop.
1346 @param[in] AtapiCommand The atapi command will be used for the
1347 transfer.
1348 @param[in] AtapiCommandLength The length of the atapi command.
1349 @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
1350 @param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
1351 @param[in] Timeout The timeout value of non data transfer, uses 100ns as a unit.
1352 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1353 used by non-blocking mode.
1354
1355 @retval EFI_DEVICE_ERROR The non data transfer abort with error occurs.
1356 @retval EFI_TIMEOUT The operation is time out.
1357 @retval EFI_UNSUPPORTED The device is not ready for transfer.
1358 @retval EFI_SUCCESS The non data transfer executes successfully.
1359
1360 **/
1361 EFI_STATUS
1362 EFIAPI
1363 AhciNonDataTransfer (
1364 IN EFI_PCI_IO_PROTOCOL *PciIo,
1365 IN EFI_AHCI_REGISTERS *AhciRegisters,
1366 IN UINT8 Port,
1367 IN UINT8 PortMultiplier,
1368 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
1369 IN UINT8 AtapiCommandLength,
1370 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
1371 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
1372 IN UINT64 Timeout,
1373 IN ATA_NONBLOCK_TASK *Task
1374 )
1375 {
1376 EFI_STATUS Status;
1377 EFI_AHCI_COMMAND_FIS CFis;
1378 EFI_AHCI_COMMAND_LIST CmdList;
1379 UINT32 Retry;
1380 EFI_STATUS RecoveryStatus;
1381
1382 //
1383 // Package read needed
1384 //
1385 AhciBuildCommandFis (&CFis, AtaCommandBlock);
1386
1387 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
1388
1389 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
1390
1391 for (Retry = 0; Retry < AHCI_COMMAND_RETRIES; Retry++) {
1392 AhciBuildCommand (
1393 PciIo,
1394 AhciRegisters,
1395 Port,
1396 PortMultiplier,
1397 &CFis,
1398 &CmdList,
1399 AtapiCommand,
1400 AtapiCommandLength,
1401 0,
1402 NULL,
1403 0
1404 );
1405
1406 DEBUG ((DEBUG_VERBOSE, "Starting command for non data transfer:\n"));
1407 AhciPrintCommandBlock (AtaCommandBlock, DEBUG_VERBOSE);
1408 Status = AhciStartCommand (
1409 PciIo,
1410 Port,
1411 0,
1412 Timeout
1413 );
1414 if (EFI_ERROR (Status)) {
1415 break;
1416 }
1417
1418 Status = AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2H);
1419 if (Status == EFI_DEVICE_ERROR) {
1420 DEBUG ((DEBUG_ERROR, "Non data transfer failed at retry %d\n", Retry));
1421 RecoveryStatus = AhciRecoverPortError (PciIo, Port);
1422 if (EFI_ERROR (RecoveryStatus)) {
1423 break;
1424 }
1425 } else {
1426 break;
1427 }
1428 }
1429
1430 AhciStopCommand (
1431 PciIo,
1432 Port,
1433 Timeout
1434 );
1435
1436 AhciDisableFisReceive (
1437 PciIo,
1438 Port,
1439 Timeout
1440 );
1441
1442 AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock);
1443
1444 if (Status == EFI_DEVICE_ERROR) {
1445 DEBUG ((DEBUG_ERROR, "Failed to execute command for non data transfer:\n"));
1446 //
1447 // Repeat command block here to make sure it is printed on
1448 // device error debug level.
1449 //
1450 AhciPrintCommandBlock (AtaCommandBlock, DEBUG_ERROR);
1451 AhciPrintStatusBlock (AtaStatusBlock, DEBUG_ERROR);
1452 } else {
1453 AhciPrintStatusBlock (AtaStatusBlock, DEBUG_VERBOSE);
1454 }
1455
1456 return Status;
1457 }
1458
1459 /**
1460 Stop command running for giving port
1461
1462 @param PciIo The PCI IO protocol instance.
1463 @param Port The number of port.
1464 @param Timeout The timeout value of stop, uses 100ns as a unit.
1465
1466 @retval EFI_DEVICE_ERROR The command stop unsuccessfully.
1467 @retval EFI_TIMEOUT The operation is time out.
1468 @retval EFI_SUCCESS The command stop successfully.
1469
1470 **/
1471 EFI_STATUS
1472 EFIAPI
1473 AhciStopCommand (
1474 IN EFI_PCI_IO_PROTOCOL *PciIo,
1475 IN UINT8 Port,
1476 IN UINT64 Timeout
1477 )
1478 {
1479 UINT32 Offset;
1480 UINT32 Data;
1481
1482 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1483 Data = AhciReadReg (PciIo, Offset);
1484
1485 if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) == 0) {
1486 return EFI_SUCCESS;
1487 }
1488
1489 if ((Data & EFI_AHCI_PORT_CMD_ST) != 0) {
1490 AhciAndReg (PciIo, Offset, (UINT32) ~(EFI_AHCI_PORT_CMD_ST));
1491 }
1492
1493 return AhciWaitMmioSet (
1494 PciIo,
1495 Offset,
1496 EFI_AHCI_PORT_CMD_CR,
1497 0,
1498 Timeout
1499 );
1500 }
1501
1502 /**
1503 Start command for give slot on specific port.
1504
1505 @param PciIo The PCI IO protocol instance.
1506 @param Port The number of port.
1507 @param CommandSlot The number of Command Slot.
1508 @param Timeout The timeout value of start, uses 100ns as a unit.
1509
1510 @retval EFI_DEVICE_ERROR The command start unsuccessfully.
1511 @retval EFI_TIMEOUT The operation is time out.
1512 @retval EFI_SUCCESS The command start successfully.
1513
1514 **/
1515 EFI_STATUS
1516 EFIAPI
1517 AhciStartCommand (
1518 IN EFI_PCI_IO_PROTOCOL *PciIo,
1519 IN UINT8 Port,
1520 IN UINT8 CommandSlot,
1521 IN UINT64 Timeout
1522 )
1523 {
1524 UINT32 CmdSlotBit;
1525 EFI_STATUS Status;
1526 UINT32 PortStatus;
1527 UINT32 StartCmd;
1528 UINT32 PortTfd;
1529 UINT32 Offset;
1530 UINT32 Capability;
1531
1532 //
1533 // Collect AHCI controller information
1534 //
1535 Capability = AhciReadReg (PciIo, EFI_AHCI_CAPABILITY_OFFSET);
1536
1537 CmdSlotBit = (UINT32)(1 << CommandSlot);
1538
1539 AhciClearPortStatus (
1540 PciIo,
1541 Port
1542 );
1543
1544 Status = AhciEnableFisReceive (
1545 PciIo,
1546 Port,
1547 Timeout
1548 );
1549
1550 if (EFI_ERROR (Status)) {
1551 return Status;
1552 }
1553
1554 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1555 PortStatus = AhciReadReg (PciIo, Offset);
1556
1557 StartCmd = 0;
1558 if ((PortStatus & EFI_AHCI_PORT_CMD_ALPE) != 0) {
1559 StartCmd = AhciReadReg (PciIo, Offset);
1560 StartCmd &= ~EFI_AHCI_PORT_CMD_ICC_MASK;
1561 StartCmd |= EFI_AHCI_PORT_CMD_ACTIVE;
1562 }
1563
1564 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
1565 PortTfd = AhciReadReg (PciIo, Offset);
1566
1567 if ((PortTfd & (EFI_AHCI_PORT_TFD_BSY | EFI_AHCI_PORT_TFD_DRQ)) != 0) {
1568 if ((Capability & BIT24) != 0) {
1569 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1570 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_CLO);
1571
1572 AhciWaitMmioSet (
1573 PciIo,
1574 Offset,
1575 EFI_AHCI_PORT_CMD_CLO,
1576 0,
1577 Timeout
1578 );
1579 }
1580 }
1581
1582 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1583 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_ST | StartCmd);
1584
1585 //
1586 // Setting the command
1587 //
1588 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;
1589 AhciAndReg (PciIo, Offset, 0);
1590 AhciOrReg (PciIo, Offset, CmdSlotBit);
1591
1592 return EFI_SUCCESS;
1593 }
1594
1595 /**
1596 Do AHCI HBA reset.
1597
1598 @param PciIo The PCI IO protocol instance.
1599 @param Timeout The timeout value of reset, uses 100ns as a unit.
1600
1601 @retval EFI_DEVICE_ERROR AHCI controller is failed to complete hardware reset.
1602 @retval EFI_TIMEOUT The reset operation is time out.
1603 @retval EFI_SUCCESS AHCI controller is reset successfully.
1604
1605 **/
1606 EFI_STATUS
1607 EFIAPI
1608 AhciReset (
1609 IN EFI_PCI_IO_PROTOCOL *PciIo,
1610 IN UINT64 Timeout
1611 )
1612 {
1613 UINT64 Delay;
1614 UINT32 Value;
1615
1616 //
1617 // Make sure that GHC.AE bit is set before accessing any AHCI registers.
1618 //
1619 Value = AhciReadReg (PciIo, EFI_AHCI_GHC_OFFSET);
1620
1621 if ((Value & EFI_AHCI_GHC_ENABLE) == 0) {
1622 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE);
1623 }
1624
1625 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_RESET);
1626
1627 Delay = DivU64x32 (Timeout, 1000) + 1;
1628
1629 do {
1630 Value = AhciReadReg (PciIo, EFI_AHCI_GHC_OFFSET);
1631
1632 if ((Value & EFI_AHCI_GHC_RESET) == 0) {
1633 break;
1634 }
1635
1636 //
1637 // Stall for 100 microseconds.
1638 //
1639 MicroSecondDelay (100);
1640
1641 Delay--;
1642 } while (Delay > 0);
1643
1644 if (Delay == 0) {
1645 return EFI_TIMEOUT;
1646 }
1647
1648 return EFI_SUCCESS;
1649 }
1650
1651 /**
1652 Send SMART Return Status command to check if the execution of SMART cmd is successful or not.
1653
1654 @param PciIo The PCI IO protocol instance.
1655 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1656 @param Port The number of port.
1657 @param PortMultiplier The port multiplier port number.
1658 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1659
1660 @retval EFI_SUCCESS Successfully get the return status of S.M.A.R.T command execution.
1661 @retval Others Fail to get return status data.
1662
1663 **/
1664 EFI_STATUS
1665 EFIAPI
1666 AhciAtaSmartReturnStatusCheck (
1667 IN EFI_PCI_IO_PROTOCOL *PciIo,
1668 IN EFI_AHCI_REGISTERS *AhciRegisters,
1669 IN UINT8 Port,
1670 IN UINT8 PortMultiplier,
1671 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
1672 )
1673 {
1674 EFI_STATUS Status;
1675 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1676 UINT8 LBAMid;
1677 UINT8 LBAHigh;
1678 UINTN FisBaseAddr;
1679 UINT32 Value;
1680
1681 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1682
1683 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
1684 AtaCommandBlock.AtaFeatures = ATA_SMART_RETURN_STATUS;
1685 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
1686 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
1687
1688 //
1689 // Send S.M.A.R.T Read Return Status command to device
1690 //
1691 Status = AhciNonDataTransfer (
1692 PciIo,
1693 AhciRegisters,
1694 (UINT8)Port,
1695 (UINT8)PortMultiplier,
1696 NULL,
1697 0,
1698 &AtaCommandBlock,
1699 AtaStatusBlock,
1700 ATA_ATAPI_TIMEOUT,
1701 NULL
1702 );
1703
1704 if (EFI_ERROR (Status)) {
1705 REPORT_STATUS_CODE (
1706 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1707 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)
1708 );
1709 return EFI_DEVICE_ERROR;
1710 }
1711
1712 REPORT_STATUS_CODE (
1713 EFI_PROGRESS_CODE,
1714 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)
1715 );
1716
1717 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS);
1718
1719 Value = *(UINT32 *)(FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET);
1720
1721 if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_REGISTER_D2H) {
1722 LBAMid = ((UINT8 *)(UINTN)(FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET))[5];
1723 LBAHigh = ((UINT8 *)(UINTN)(FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET))[6];
1724
1725 if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {
1726 //
1727 // The threshold exceeded condition is not detected by the device
1728 //
1729 DEBUG ((DEBUG_INFO, "The S.M.A.R.T threshold exceeded condition is not detected\n"));
1730 REPORT_STATUS_CODE (
1731 EFI_PROGRESS_CODE,
1732 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)
1733 );
1734 } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {
1735 //
1736 // The threshold exceeded condition is detected by the device
1737 //
1738 DEBUG ((DEBUG_INFO, "The S.M.A.R.T threshold exceeded condition is detected\n"));
1739 REPORT_STATUS_CODE (
1740 EFI_PROGRESS_CODE,
1741 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)
1742 );
1743 }
1744 }
1745
1746 return EFI_SUCCESS;
1747 }
1748
1749 /**
1750 Enable SMART command of the disk if supported.
1751
1752 @param PciIo The PCI IO protocol instance.
1753 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1754 @param Port The number of port.
1755 @param PortMultiplier The port multiplier port number.
1756 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
1757 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1758
1759 **/
1760 VOID
1761 EFIAPI
1762 AhciAtaSmartSupport (
1763 IN EFI_PCI_IO_PROTOCOL *PciIo,
1764 IN EFI_AHCI_REGISTERS *AhciRegisters,
1765 IN UINT8 Port,
1766 IN UINT8 PortMultiplier,
1767 IN EFI_IDENTIFY_DATA *IdentifyData,
1768 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
1769 )
1770 {
1771 EFI_STATUS Status;
1772 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1773
1774 //
1775 // Detect if the device supports S.M.A.R.T.
1776 //
1777 if ((IdentifyData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {
1778 //
1779 // S.M.A.R.T is not supported by the device
1780 //
1781 DEBUG ((
1782 DEBUG_INFO,
1783 "S.M.A.R.T feature is not supported at port [%d] PortMultiplier [%d]!\n",
1784 Port,
1785 PortMultiplier
1786 ));
1787 REPORT_STATUS_CODE (
1788 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1789 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)
1790 );
1791 } else {
1792 //
1793 // Check if the feature is enabled. If not, then enable S.M.A.R.T.
1794 //
1795 if ((IdentifyData->AtaData.command_set_feature_enb_85 & 0x0001) != 0x0001) {
1796 REPORT_STATUS_CODE (
1797 EFI_PROGRESS_CODE,
1798 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLE)
1799 );
1800
1801 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1802
1803 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
1804 AtaCommandBlock.AtaFeatures = ATA_SMART_ENABLE_OPERATION;
1805 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
1806 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
1807
1808 //
1809 // Send S.M.A.R.T Enable command to device
1810 //
1811 Status = AhciNonDataTransfer (
1812 PciIo,
1813 AhciRegisters,
1814 (UINT8)Port,
1815 (UINT8)PortMultiplier,
1816 NULL,
1817 0,
1818 &AtaCommandBlock,
1819 AtaStatusBlock,
1820 ATA_ATAPI_TIMEOUT,
1821 NULL
1822 );
1823
1824 if (!EFI_ERROR (Status)) {
1825 //
1826 // Send S.M.A.R.T AutoSave command to device
1827 //
1828 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1829
1830 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
1831 AtaCommandBlock.AtaFeatures = 0xD2;
1832 AtaCommandBlock.AtaSectorCount = 0xF1;
1833 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
1834 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
1835
1836 Status = AhciNonDataTransfer (
1837 PciIo,
1838 AhciRegisters,
1839 (UINT8)Port,
1840 (UINT8)PortMultiplier,
1841 NULL,
1842 0,
1843 &AtaCommandBlock,
1844 AtaStatusBlock,
1845 ATA_ATAPI_TIMEOUT,
1846 NULL
1847 );
1848 }
1849 }
1850
1851 AhciAtaSmartReturnStatusCheck (
1852 PciIo,
1853 AhciRegisters,
1854 (UINT8)Port,
1855 (UINT8)PortMultiplier,
1856 AtaStatusBlock
1857 );
1858
1859 DEBUG ((
1860 DEBUG_INFO,
1861 "Enabled S.M.A.R.T feature at port [%d] PortMultiplier [%d]!\n",
1862 Port,
1863 PortMultiplier
1864 ));
1865 }
1866
1867 return;
1868 }
1869
1870 /**
1871 Send Buffer cmd to specific device.
1872
1873 @param PciIo The PCI IO protocol instance.
1874 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1875 @param Port The number of port.
1876 @param PortMultiplier The port multiplier port number.
1877 @param Buffer The data buffer to store IDENTIFY PACKET data.
1878
1879 @retval EFI_DEVICE_ERROR The cmd abort with error occurs.
1880 @retval EFI_TIMEOUT The operation is time out.
1881 @retval EFI_UNSUPPORTED The device is not ready for executing.
1882 @retval EFI_SUCCESS The cmd executes successfully.
1883
1884 **/
1885 EFI_STATUS
1886 EFIAPI
1887 AhciIdentify (
1888 IN EFI_PCI_IO_PROTOCOL *PciIo,
1889 IN EFI_AHCI_REGISTERS *AhciRegisters,
1890 IN UINT8 Port,
1891 IN UINT8 PortMultiplier,
1892 IN OUT EFI_IDENTIFY_DATA *Buffer
1893 )
1894 {
1895 EFI_STATUS Status;
1896 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1897 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
1898
1899 if ((PciIo == NULL) || (AhciRegisters == NULL) || (Buffer == NULL)) {
1900 return EFI_INVALID_PARAMETER;
1901 }
1902
1903 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1904 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
1905
1906 AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
1907 AtaCommandBlock.AtaSectorCount = 1;
1908
1909 Status = AhciPioTransfer (
1910 PciIo,
1911 AhciRegisters,
1912 Port,
1913 PortMultiplier,
1914 NULL,
1915 0,
1916 TRUE,
1917 &AtaCommandBlock,
1918 &AtaStatusBlock,
1919 Buffer,
1920 sizeof (EFI_IDENTIFY_DATA),
1921 ATA_ATAPI_TIMEOUT,
1922 NULL
1923 );
1924
1925 return Status;
1926 }
1927
1928 /**
1929 Send Buffer cmd to specific device.
1930
1931 @param PciIo The PCI IO protocol instance.
1932 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1933 @param Port The number of port.
1934 @param PortMultiplier The port multiplier port number.
1935 @param Buffer The data buffer to store IDENTIFY PACKET data.
1936
1937 @retval EFI_DEVICE_ERROR The cmd abort with error occurs.
1938 @retval EFI_TIMEOUT The operation is time out.
1939 @retval EFI_UNSUPPORTED The device is not ready for executing.
1940 @retval EFI_SUCCESS The cmd executes successfully.
1941
1942 **/
1943 EFI_STATUS
1944 EFIAPI
1945 AhciIdentifyPacket (
1946 IN EFI_PCI_IO_PROTOCOL *PciIo,
1947 IN EFI_AHCI_REGISTERS *AhciRegisters,
1948 IN UINT8 Port,
1949 IN UINT8 PortMultiplier,
1950 IN OUT EFI_IDENTIFY_DATA *Buffer
1951 )
1952 {
1953 EFI_STATUS Status;
1954 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1955 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
1956
1957 if ((PciIo == NULL) || (AhciRegisters == NULL)) {
1958 return EFI_INVALID_PARAMETER;
1959 }
1960
1961 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1962 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
1963
1964 AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DEVICE;
1965 AtaCommandBlock.AtaSectorCount = 1;
1966
1967 Status = AhciPioTransfer (
1968 PciIo,
1969 AhciRegisters,
1970 Port,
1971 PortMultiplier,
1972 NULL,
1973 0,
1974 TRUE,
1975 &AtaCommandBlock,
1976 &AtaStatusBlock,
1977 Buffer,
1978 sizeof (EFI_IDENTIFY_DATA),
1979 ATA_ATAPI_TIMEOUT,
1980 NULL
1981 );
1982
1983 return Status;
1984 }
1985
1986 /**
1987 Send SET FEATURE cmd on specific device.
1988
1989 @param PciIo The PCI IO protocol instance.
1990 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1991 @param Port The number of port.
1992 @param PortMultiplier The port multiplier port number.
1993 @param Feature The data to send Feature register.
1994 @param FeatureSpecificData The specific data for SET FEATURE cmd.
1995 @param Timeout The timeout value of SET FEATURE cmd, uses 100ns as a unit.
1996
1997 @retval EFI_DEVICE_ERROR The cmd abort with error occurs.
1998 @retval EFI_TIMEOUT The operation is time out.
1999 @retval EFI_UNSUPPORTED The device is not ready for executing.
2000 @retval EFI_SUCCESS The cmd executes successfully.
2001
2002 **/
2003 EFI_STATUS
2004 EFIAPI
2005 AhciDeviceSetFeature (
2006 IN EFI_PCI_IO_PROTOCOL *PciIo,
2007 IN EFI_AHCI_REGISTERS *AhciRegisters,
2008 IN UINT8 Port,
2009 IN UINT8 PortMultiplier,
2010 IN UINT16 Feature,
2011 IN UINT32 FeatureSpecificData,
2012 IN UINT64 Timeout
2013 )
2014 {
2015 EFI_STATUS Status;
2016 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2017 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
2018
2019 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2020 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
2021
2022 AtaCommandBlock.AtaCommand = ATA_CMD_SET_FEATURES;
2023 AtaCommandBlock.AtaFeatures = (UINT8)Feature;
2024 AtaCommandBlock.AtaFeaturesExp = (UINT8)(Feature >> 8);
2025 AtaCommandBlock.AtaSectorCount = (UINT8)FeatureSpecificData;
2026 AtaCommandBlock.AtaSectorNumber = (UINT8)(FeatureSpecificData >> 8);
2027 AtaCommandBlock.AtaCylinderLow = (UINT8)(FeatureSpecificData >> 16);
2028 AtaCommandBlock.AtaCylinderHigh = (UINT8)(FeatureSpecificData >> 24);
2029
2030 Status = AhciNonDataTransfer (
2031 PciIo,
2032 AhciRegisters,
2033 (UINT8)Port,
2034 (UINT8)PortMultiplier,
2035 NULL,
2036 0,
2037 &AtaCommandBlock,
2038 &AtaStatusBlock,
2039 Timeout,
2040 NULL
2041 );
2042
2043 return Status;
2044 }
2045
2046 /**
2047 This function is used to send out ATAPI commands conforms to the Packet Command
2048 with PIO Protocol.
2049
2050 @param PciIo The PCI IO protocol instance.
2051 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
2052 @param Port The number of port.
2053 @param PortMultiplier The number of port multiplier.
2054 @param Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET structure.
2055
2056 @retval EFI_SUCCESS send out the ATAPI packet command successfully
2057 and device sends data successfully.
2058 @retval EFI_DEVICE_ERROR the device failed to send data.
2059
2060 **/
2061 EFI_STATUS
2062 EFIAPI
2063 AhciPacketCommandExecute (
2064 IN EFI_PCI_IO_PROTOCOL *PciIo,
2065 IN EFI_AHCI_REGISTERS *AhciRegisters,
2066 IN UINT8 Port,
2067 IN UINT8 PortMultiplier,
2068 IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
2069 )
2070 {
2071 EFI_STATUS Status;
2072 VOID *Buffer;
2073 UINT32 Length;
2074 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2075 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
2076 BOOLEAN Read;
2077
2078 if ((Packet == NULL) || (Packet->Cdb == NULL)) {
2079 return EFI_INVALID_PARAMETER;
2080 }
2081
2082 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2083 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
2084 AtaCommandBlock.AtaCommand = ATA_CMD_PACKET;
2085 //
2086 // No OVL; No DMA
2087 //
2088 AtaCommandBlock.AtaFeatures = 0x00;
2089 //
2090 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
2091 // determine how many data should be transferred.
2092 //
2093 AtaCommandBlock.AtaCylinderLow = (UINT8)(ATAPI_MAX_BYTE_COUNT & 0x00ff);
2094 AtaCommandBlock.AtaCylinderHigh = (UINT8)(ATAPI_MAX_BYTE_COUNT >> 8);
2095
2096 if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
2097 Buffer = Packet->InDataBuffer;
2098 Length = Packet->InTransferLength;
2099 Read = TRUE;
2100 } else {
2101 Buffer = Packet->OutDataBuffer;
2102 Length = Packet->OutTransferLength;
2103 Read = FALSE;
2104 }
2105
2106 if (Length == 0) {
2107 Status = AhciNonDataTransfer (
2108 PciIo,
2109 AhciRegisters,
2110 Port,
2111 PortMultiplier,
2112 Packet->Cdb,
2113 Packet->CdbLength,
2114 &AtaCommandBlock,
2115 &AtaStatusBlock,
2116 Packet->Timeout,
2117 NULL
2118 );
2119 } else {
2120 Status = AhciPioTransfer (
2121 PciIo,
2122 AhciRegisters,
2123 Port,
2124 PortMultiplier,
2125 Packet->Cdb,
2126 Packet->CdbLength,
2127 Read,
2128 &AtaCommandBlock,
2129 &AtaStatusBlock,
2130 Buffer,
2131 Length,
2132 Packet->Timeout,
2133 NULL
2134 );
2135 }
2136
2137 return Status;
2138 }
2139
2140 /**
2141 Allocate transfer-related data struct which is used at AHCI mode.
2142
2143 @param PciIo The PCI IO protocol instance.
2144 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
2145
2146 **/
2147 EFI_STATUS
2148 EFIAPI
2149 AhciCreateTransferDescriptor (
2150 IN EFI_PCI_IO_PROTOCOL *PciIo,
2151 IN OUT EFI_AHCI_REGISTERS *AhciRegisters
2152 )
2153 {
2154 EFI_STATUS Status;
2155 UINTN Bytes;
2156 VOID *Buffer;
2157
2158 UINT32 Capability;
2159 UINT32 PortImplementBitMap;
2160 UINT8 MaxPortNumber;
2161 UINT8 MaxCommandSlotNumber;
2162 BOOLEAN Support64Bit;
2163 UINT64 MaxReceiveFisSize;
2164 UINT64 MaxCommandListSize;
2165 UINT64 MaxCommandTableSize;
2166 EFI_PHYSICAL_ADDRESS AhciRFisPciAddr;
2167 EFI_PHYSICAL_ADDRESS AhciCmdListPciAddr;
2168 EFI_PHYSICAL_ADDRESS AhciCommandTablePciAddr;
2169
2170 Buffer = NULL;
2171 //
2172 // Collect AHCI controller information
2173 //
2174 Capability = AhciReadReg (PciIo, EFI_AHCI_CAPABILITY_OFFSET);
2175 //
2176 // Get the number of command slots per port supported by this HBA.
2177 //
2178 MaxCommandSlotNumber = (UINT8)(((Capability & 0x1F00) >> 8) + 1);
2179 Support64Bit = (BOOLEAN)(((Capability & BIT31) != 0) ? TRUE : FALSE);
2180
2181 PortImplementBitMap = AhciReadReg (PciIo, EFI_AHCI_PI_OFFSET);
2182 //
2183 // Get the highest bit of implemented ports which decides how many bytes are allocated for received FIS.
2184 //
2185 MaxPortNumber = (UINT8)(UINTN)(HighBitSet32 (PortImplementBitMap) + 1);
2186 if (MaxPortNumber == 0) {
2187 return EFI_DEVICE_ERROR;
2188 }
2189
2190 MaxReceiveFisSize = MaxPortNumber * sizeof (EFI_AHCI_RECEIVED_FIS);
2191 Status = PciIo->AllocateBuffer (
2192 PciIo,
2193 AllocateAnyPages,
2194 EfiBootServicesData,
2195 EFI_SIZE_TO_PAGES ((UINTN)MaxReceiveFisSize),
2196 &Buffer,
2197 0
2198 );
2199
2200 if (EFI_ERROR (Status)) {
2201 return EFI_OUT_OF_RESOURCES;
2202 }
2203
2204 ZeroMem (Buffer, (UINTN)MaxReceiveFisSize);
2205
2206 AhciRegisters->AhciRFis = Buffer;
2207 AhciRegisters->MaxReceiveFisSize = MaxReceiveFisSize;
2208 Bytes = (UINTN)MaxReceiveFisSize;
2209
2210 Status = PciIo->Map (
2211 PciIo,
2212 EfiPciIoOperationBusMasterCommonBuffer,
2213 Buffer,
2214 &Bytes,
2215 &AhciRFisPciAddr,
2216 &AhciRegisters->MapRFis
2217 );
2218
2219 if (EFI_ERROR (Status) || (Bytes != MaxReceiveFisSize)) {
2220 //
2221 // Map error or unable to map the whole RFis buffer into a contiguous region.
2222 //
2223 Status = EFI_OUT_OF_RESOURCES;
2224 goto Error6;
2225 }
2226
2227 if ((!Support64Bit) && (AhciRFisPciAddr > 0x100000000ULL)) {
2228 //
2229 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address.
2230 //
2231 Status = EFI_DEVICE_ERROR;
2232 goto Error5;
2233 }
2234
2235 AhciRegisters->AhciRFisPciAddr = (EFI_AHCI_RECEIVED_FIS *)(UINTN)AhciRFisPciAddr;
2236
2237 //
2238 // Allocate memory for command list
2239 // Note that the implementation is a single task model which only use a command list for all ports.
2240 //
2241 Buffer = NULL;
2242 MaxCommandListSize = MaxCommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST);
2243 Status = PciIo->AllocateBuffer (
2244 PciIo,
2245 AllocateAnyPages,
2246 EfiBootServicesData,
2247 EFI_SIZE_TO_PAGES ((UINTN)MaxCommandListSize),
2248 &Buffer,
2249 0
2250 );
2251
2252 if (EFI_ERROR (Status)) {
2253 //
2254 // Free mapped resource.
2255 //
2256 Status = EFI_OUT_OF_RESOURCES;
2257 goto Error5;
2258 }
2259
2260 ZeroMem (Buffer, (UINTN)MaxCommandListSize);
2261
2262 AhciRegisters->AhciCmdList = Buffer;
2263 AhciRegisters->MaxCommandListSize = MaxCommandListSize;
2264 Bytes = (UINTN)MaxCommandListSize;
2265
2266 Status = PciIo->Map (
2267 PciIo,
2268 EfiPciIoOperationBusMasterCommonBuffer,
2269 Buffer,
2270 &Bytes,
2271 &AhciCmdListPciAddr,
2272 &AhciRegisters->MapCmdList
2273 );
2274
2275 if (EFI_ERROR (Status) || (Bytes != MaxCommandListSize)) {
2276 //
2277 // Map error or unable to map the whole cmd list buffer into a contiguous region.
2278 //
2279 Status = EFI_OUT_OF_RESOURCES;
2280 goto Error4;
2281 }
2282
2283 if ((!Support64Bit) && (AhciCmdListPciAddr > 0x100000000ULL)) {
2284 //
2285 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address.
2286 //
2287 Status = EFI_DEVICE_ERROR;
2288 goto Error3;
2289 }
2290
2291 AhciRegisters->AhciCmdListPciAddr = (EFI_AHCI_COMMAND_LIST *)(UINTN)AhciCmdListPciAddr;
2292
2293 //
2294 // Allocate memory for command table
2295 // According to AHCI 1.3 spec, a PRD table can contain maximum 65535 entries.
2296 //
2297 Buffer = NULL;
2298 MaxCommandTableSize = sizeof (EFI_AHCI_COMMAND_TABLE);
2299
2300 Status = PciIo->AllocateBuffer (
2301 PciIo,
2302 AllocateAnyPages,
2303 EfiBootServicesData,
2304 EFI_SIZE_TO_PAGES ((UINTN)MaxCommandTableSize),
2305 &Buffer,
2306 0
2307 );
2308
2309 if (EFI_ERROR (Status)) {
2310 //
2311 // Free mapped resource.
2312 //
2313 Status = EFI_OUT_OF_RESOURCES;
2314 goto Error3;
2315 }
2316
2317 ZeroMem (Buffer, (UINTN)MaxCommandTableSize);
2318
2319 AhciRegisters->AhciCommandTable = Buffer;
2320 AhciRegisters->MaxCommandTableSize = MaxCommandTableSize;
2321 Bytes = (UINTN)MaxCommandTableSize;
2322
2323 Status = PciIo->Map (
2324 PciIo,
2325 EfiPciIoOperationBusMasterCommonBuffer,
2326 Buffer,
2327 &Bytes,
2328 &AhciCommandTablePciAddr,
2329 &AhciRegisters->MapCommandTable
2330 );
2331
2332 if (EFI_ERROR (Status) || (Bytes != MaxCommandTableSize)) {
2333 //
2334 // Map error or unable to map the whole cmd list buffer into a contiguous region.
2335 //
2336 Status = EFI_OUT_OF_RESOURCES;
2337 goto Error2;
2338 }
2339
2340 if ((!Support64Bit) && (AhciCommandTablePciAddr > 0x100000000ULL)) {
2341 //
2342 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address.
2343 //
2344 Status = EFI_DEVICE_ERROR;
2345 goto Error1;
2346 }
2347
2348 AhciRegisters->AhciCommandTablePciAddr = (EFI_AHCI_COMMAND_TABLE *)(UINTN)AhciCommandTablePciAddr;
2349
2350 return EFI_SUCCESS;
2351 //
2352 // Map error or unable to map the whole CmdList buffer into a contiguous region.
2353 //
2354 Error1:
2355 PciIo->Unmap (
2356 PciIo,
2357 AhciRegisters->MapCommandTable
2358 );
2359 Error2:
2360 PciIo->FreeBuffer (
2361 PciIo,
2362 EFI_SIZE_TO_PAGES ((UINTN)MaxCommandTableSize),
2363 AhciRegisters->AhciCommandTable
2364 );
2365 Error3:
2366 PciIo->Unmap (
2367 PciIo,
2368 AhciRegisters->MapCmdList
2369 );
2370 Error4:
2371 PciIo->FreeBuffer (
2372 PciIo,
2373 EFI_SIZE_TO_PAGES ((UINTN)MaxCommandListSize),
2374 AhciRegisters->AhciCmdList
2375 );
2376 Error5:
2377 PciIo->Unmap (
2378 PciIo,
2379 AhciRegisters->MapRFis
2380 );
2381 Error6:
2382 PciIo->FreeBuffer (
2383 PciIo,
2384 EFI_SIZE_TO_PAGES ((UINTN)MaxReceiveFisSize),
2385 AhciRegisters->AhciRFis
2386 );
2387
2388 return Status;
2389 }
2390
2391 /**
2392 Read logs from SATA device.
2393
2394 @param PciIo The PCI IO protocol instance.
2395 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
2396 @param Port The number of port.
2397 @param PortMultiplier The multiplier of port.
2398 @param Buffer The data buffer to store SATA logs.
2399 @param LogNumber The address of the log.
2400 @param PageNumber The page number of the log.
2401
2402 @retval EFI_INVALID_PARAMETER PciIo, AhciRegisters or Buffer is NULL.
2403 @retval others Return status of AhciPioTransfer().
2404 **/
2405 EFI_STATUS
2406 AhciReadLogExt (
2407 IN EFI_PCI_IO_PROTOCOL *PciIo,
2408 IN EFI_AHCI_REGISTERS *AhciRegisters,
2409 IN UINT8 Port,
2410 IN UINT8 PortMultiplier,
2411 IN OUT UINT8 *Buffer,
2412 IN UINT8 LogNumber,
2413 IN UINT8 PageNumber
2414 )
2415 {
2416 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2417 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
2418
2419 if ((PciIo == NULL) || (AhciRegisters == NULL) || (Buffer == NULL)) {
2420 return EFI_INVALID_PARAMETER;
2421 }
2422
2423 ///
2424 /// Read log from device
2425 ///
2426 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2427 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
2428 ZeroMem (Buffer, 512);
2429
2430 AtaCommandBlock.AtaCommand = ATA_CMD_READ_LOG_EXT;
2431 AtaCommandBlock.AtaSectorCount = 1;
2432 AtaCommandBlock.AtaSectorNumber = LogNumber;
2433 AtaCommandBlock.AtaCylinderLow = PageNumber;
2434
2435 return AhciPioTransfer (
2436 PciIo,
2437 AhciRegisters,
2438 Port,
2439 PortMultiplier,
2440 NULL,
2441 0,
2442 TRUE,
2443 &AtaCommandBlock,
2444 &AtaStatusBlock,
2445 Buffer,
2446 512,
2447 ATA_ATAPI_TIMEOUT,
2448 NULL
2449 );
2450 }
2451
2452 /**
2453 Enable DEVSLP of the disk if supported.
2454
2455 @param PciIo The PCI IO protocol instance.
2456 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
2457 @param Port The number of port.
2458 @param PortMultiplier The multiplier of port.
2459 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
2460
2461 @retval EFI_SUCCESS The DEVSLP is enabled per policy successfully.
2462 @retval EFI_UNSUPPORTED The DEVSLP isn't supported by the controller/device and policy requires to enable it.
2463 **/
2464 EFI_STATUS
2465 AhciEnableDevSlp (
2466 IN EFI_PCI_IO_PROTOCOL *PciIo,
2467 IN EFI_AHCI_REGISTERS *AhciRegisters,
2468 IN UINT8 Port,
2469 IN UINT8 PortMultiplier,
2470 IN EFI_IDENTIFY_DATA *IdentifyData
2471 )
2472 {
2473 EFI_STATUS Status;
2474 UINT32 Offset;
2475 UINT32 Capability2;
2476 UINT8 LogData[512];
2477 DEVSLP_TIMING_VARIABLES DevSlpTiming;
2478 UINT32 PortCmd;
2479 UINT32 PortDevSlp;
2480
2481 if (mAtaAtapiPolicy->DeviceSleepEnable != 1) {
2482 return EFI_SUCCESS;
2483 }
2484
2485 //
2486 // Do not enable DevSlp if DevSlp is not supported.
2487 //
2488 Capability2 = AhciReadReg (PciIo, AHCI_CAPABILITY2_OFFSET);
2489 DEBUG ((DEBUG_INFO, "AHCI CAPABILITY2 = %08x\n", Capability2));
2490 if ((Capability2 & AHCI_CAP2_SDS) == 0) {
2491 return EFI_UNSUPPORTED;
2492 }
2493
2494 //
2495 // Do not enable DevSlp if DevSlp is not present
2496 // Do not enable DevSlp if Hot Plug or Mechanical Presence Switch is supported
2497 //
2498 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH;
2499 PortCmd = AhciReadReg (PciIo, Offset + EFI_AHCI_PORT_CMD);
2500 PortDevSlp = AhciReadReg (PciIo, Offset + AHCI_PORT_DEVSLP);
2501 DEBUG ((DEBUG_INFO, "Port CMD/DEVSLP = %08x / %08x\n", PortCmd, PortDevSlp));
2502 if (((PortDevSlp & AHCI_PORT_DEVSLP_DSP) == 0) ||
2503 ((PortCmd & (EFI_AHCI_PORT_CMD_HPCP | EFI_AHCI_PORT_CMD_MPSP)) != 0)
2504 )
2505 {
2506 return EFI_UNSUPPORTED;
2507 }
2508
2509 //
2510 // Do not enable DevSlp if the device doesn't support DevSlp
2511 //
2512 DEBUG ((
2513 DEBUG_INFO,
2514 "IDENTIFY DEVICE: [77] = %04x, [78] = %04x, [79] = %04x\n",
2515 IdentifyData->AtaData.reserved_77,
2516 IdentifyData->AtaData.serial_ata_features_supported,
2517 IdentifyData->AtaData.serial_ata_features_enabled
2518 ));
2519 if ((IdentifyData->AtaData.serial_ata_features_supported & BIT8) == 0) {
2520 DEBUG ((
2521 DEBUG_INFO,
2522 "DevSlp feature is not supported for device at port [%d] PortMultiplier [%d]!\n",
2523 Port,
2524 PortMultiplier
2525 ));
2526 return EFI_UNSUPPORTED;
2527 }
2528
2529 //
2530 // Enable DevSlp when it is not enabled.
2531 //
2532 if ((IdentifyData->AtaData.serial_ata_features_enabled & BIT8) != 0) {
2533 Status = AhciDeviceSetFeature (
2534 PciIo,
2535 AhciRegisters,
2536 Port,
2537 0,
2538 ATA_SUB_CMD_ENABLE_SATA_FEATURE,
2539 0x09,
2540 ATA_ATAPI_TIMEOUT
2541 );
2542 DEBUG ((
2543 DEBUG_INFO,
2544 "DevSlp set feature for device at port [%d] PortMultiplier [%d] - %r\n",
2545 Port,
2546 PortMultiplier,
2547 Status
2548 ));
2549 if (EFI_ERROR (Status)) {
2550 return Status;
2551 }
2552 }
2553
2554 Status = AhciReadLogExt (PciIo, AhciRegisters, Port, PortMultiplier, LogData, 0x30, 0x08);
2555
2556 //
2557 // Clear PxCMD.ST and PxDEVSLP.ADSE before updating PxDEVSLP.DITO and PxDEVSLP.MDAT.
2558 //
2559 AhciWriteReg (PciIo, Offset + EFI_AHCI_PORT_CMD, PortCmd & ~EFI_AHCI_PORT_CMD_ST);
2560 PortDevSlp &= ~AHCI_PORT_DEVSLP_ADSE;
2561 AhciWriteReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2562
2563 //
2564 // Set PxDEVSLP.DETO and PxDEVSLP.MDAT to 0.
2565 //
2566 PortDevSlp &= ~AHCI_PORT_DEVSLP_DETO_MASK;
2567 PortDevSlp &= ~AHCI_PORT_DEVSLP_MDAT_MASK;
2568 AhciWriteReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2569 DEBUG ((DEBUG_INFO, "Read Log Ext at port [%d] PortMultiplier [%d] - %r\n", Port, PortMultiplier, Status));
2570 if (EFI_ERROR (Status)) {
2571 //
2572 // Assume DEVSLP TIMING VARIABLES is not supported if the Identify Device Data log (30h, 8) fails
2573 //
2574 ZeroMem (&DevSlpTiming, sizeof (DevSlpTiming));
2575 } else {
2576 CopyMem (&DevSlpTiming, &LogData[48], sizeof (DevSlpTiming));
2577 DEBUG ((
2578 DEBUG_INFO,
2579 "DevSlpTiming: Supported(%d), Deto(%d), Madt(%d)\n",
2580 DevSlpTiming.Supported,
2581 DevSlpTiming.Deto,
2582 DevSlpTiming.Madt
2583 ));
2584 }
2585
2586 //
2587 // Use 20ms as default DETO when DEVSLP TIMING VARIABLES is not supported or the DETO is 0.
2588 //
2589 if ((DevSlpTiming.Supported == 0) || (DevSlpTiming.Deto == 0)) {
2590 DevSlpTiming.Deto = 20;
2591 }
2592
2593 //
2594 // Use 10ms as default MADT when DEVSLP TIMING VARIABLES is not supported or the MADT is 0.
2595 //
2596 if ((DevSlpTiming.Supported == 0) || (DevSlpTiming.Madt == 0)) {
2597 DevSlpTiming.Madt = 10;
2598 }
2599
2600 PortDevSlp |= DevSlpTiming.Deto << 2;
2601 PortDevSlp |= DevSlpTiming.Madt << 10;
2602 AhciOrReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2603
2604 if (mAtaAtapiPolicy->AggressiveDeviceSleepEnable == 1) {
2605 if ((Capability2 & AHCI_CAP2_SADM) != 0) {
2606 PortDevSlp &= ~AHCI_PORT_DEVSLP_DITO_MASK;
2607 PortDevSlp |= (625 << 15);
2608 AhciWriteReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2609
2610 PortDevSlp |= AHCI_PORT_DEVSLP_ADSE;
2611 AhciWriteReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2612 }
2613 }
2614
2615 AhciWriteReg (PciIo, Offset + EFI_AHCI_PORT_CMD, PortCmd);
2616
2617 DEBUG ((
2618 DEBUG_INFO,
2619 "Enabled DevSlp feature at port [%d] PortMultiplier [%d], Port CMD/DEVSLP = %08x / %08x\n",
2620 Port,
2621 PortMultiplier,
2622 PortCmd,
2623 PortDevSlp
2624 ));
2625
2626 return EFI_SUCCESS;
2627 }
2628
2629 /**
2630 Spin-up disk if IDD was incomplete or PUIS feature is enabled
2631
2632 @param PciIo The PCI IO protocol instance.
2633 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
2634 @param Port The number of port.
2635 @param PortMultiplier The multiplier of port.
2636 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
2637
2638 **/
2639 EFI_STATUS
2640 AhciSpinUpDisk (
2641 IN EFI_PCI_IO_PROTOCOL *PciIo,
2642 IN EFI_AHCI_REGISTERS *AhciRegisters,
2643 IN UINT8 Port,
2644 IN UINT8 PortMultiplier,
2645 IN OUT EFI_IDENTIFY_DATA *IdentifyData
2646 )
2647 {
2648 EFI_STATUS Status;
2649 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2650 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
2651 UINT8 Buffer[512];
2652
2653 if (IdentifyData->AtaData.specific_config == ATA_SPINUP_CFG_REQUIRED_IDD_INCOMPLETE) {
2654 //
2655 // Use SET_FEATURE subcommand to spin up the device.
2656 //
2657 Status = AhciDeviceSetFeature (
2658 PciIo,
2659 AhciRegisters,
2660 Port,
2661 PortMultiplier,
2662 ATA_SUB_CMD_PUIS_SET_DEVICE_SPINUP,
2663 0x00,
2664 ATA_SPINUP_TIMEOUT
2665 );
2666 DEBUG ((
2667 DEBUG_INFO,
2668 "CMD_PUIS_SET_DEVICE_SPINUP for device at port [%d] PortMultiplier [%d] - %r!\n",
2669 Port,
2670 PortMultiplier,
2671 Status
2672 ));
2673 if (EFI_ERROR (Status)) {
2674 return Status;
2675 }
2676 } else {
2677 ASSERT (IdentifyData->AtaData.specific_config == ATA_SPINUP_CFG_NOT_REQUIRED_IDD_INCOMPLETE);
2678
2679 //
2680 // Use READ_SECTORS to spin up the device if SpinUp SET FEATURE subcommand is not supported
2681 //
2682 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2683 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
2684 //
2685 // Perform READ SECTORS PIO Data-In command to Read LBA 0
2686 //
2687 AtaCommandBlock.AtaCommand = ATA_CMD_READ_SECTORS;
2688 AtaCommandBlock.AtaSectorCount = 0x1;
2689
2690 Status = AhciPioTransfer (
2691 PciIo,
2692 AhciRegisters,
2693 Port,
2694 PortMultiplier,
2695 NULL,
2696 0,
2697 TRUE,
2698 &AtaCommandBlock,
2699 &AtaStatusBlock,
2700 &Buffer,
2701 sizeof (Buffer),
2702 ATA_SPINUP_TIMEOUT,
2703 NULL
2704 );
2705 DEBUG ((
2706 DEBUG_INFO,
2707 "Read LBA 0 for device at port [%d] PortMultiplier [%d] - %r!\n",
2708 Port,
2709 PortMultiplier,
2710 Status
2711 ));
2712 if (EFI_ERROR (Status)) {
2713 return Status;
2714 }
2715 }
2716
2717 //
2718 // Read the complete IDENTIFY DEVICE data.
2719 //
2720 ZeroMem (IdentifyData, sizeof (*IdentifyData));
2721 Status = AhciIdentify (PciIo, AhciRegisters, Port, PortMultiplier, IdentifyData);
2722 if (EFI_ERROR (Status)) {
2723 DEBUG ((
2724 DEBUG_ERROR,
2725 "Read IDD failed for device at port [%d] PortMultiplier [%d] - %r!\n",
2726 Port,
2727 PortMultiplier,
2728 Status
2729 ));
2730 return Status;
2731 }
2732
2733 DEBUG ((
2734 DEBUG_INFO,
2735 "IDENTIFY DEVICE: [0] = %016x, [2] = %016x, [83] = %016x, [86] = %016x\n",
2736 IdentifyData->AtaData.config,
2737 IdentifyData->AtaData.specific_config,
2738 IdentifyData->AtaData.command_set_supported_83,
2739 IdentifyData->AtaData.command_set_feature_enb_86
2740 ));
2741 //
2742 // Check if IDD is incomplete
2743 //
2744 if ((IdentifyData->AtaData.config & BIT2) != 0) {
2745 return EFI_DEVICE_ERROR;
2746 }
2747
2748 return EFI_SUCCESS;
2749 }
2750
2751 /**
2752 Enable/disable/skip PUIS of the disk according to policy.
2753
2754 @param PciIo The PCI IO protocol instance.
2755 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
2756 @param Port The number of port.
2757 @param PortMultiplier The multiplier of port.
2758
2759 **/
2760 EFI_STATUS
2761 AhciPuisEnable (
2762 IN EFI_PCI_IO_PROTOCOL *PciIo,
2763 IN EFI_AHCI_REGISTERS *AhciRegisters,
2764 IN UINT8 Port,
2765 IN UINT8 PortMultiplier
2766 )
2767 {
2768 EFI_STATUS Status;
2769
2770 Status = EFI_SUCCESS;
2771 if (mAtaAtapiPolicy->PuisEnable == 0) {
2772 Status = AhciDeviceSetFeature (PciIo, AhciRegisters, Port, PortMultiplier, ATA_SUB_CMD_DISABLE_PUIS, 0x00, ATA_ATAPI_TIMEOUT);
2773 } else if (mAtaAtapiPolicy->PuisEnable == 1) {
2774 Status = AhciDeviceSetFeature (PciIo, AhciRegisters, Port, PortMultiplier, ATA_SUB_CMD_ENABLE_PUIS, 0x00, ATA_ATAPI_TIMEOUT);
2775 }
2776
2777 DEBUG ((
2778 DEBUG_INFO,
2779 "%a PUIS feature at port [%d] PortMultiplier [%d] - %r!\n",
2780 (mAtaAtapiPolicy->PuisEnable == 0) ? "Disable" : (
2781 (mAtaAtapiPolicy->PuisEnable == 1) ? "Enable" : "Skip"
2782 ),
2783 Port,
2784 PortMultiplier,
2785 Status
2786 ));
2787 return Status;
2788 }
2789
2790 /**
2791 Initialize ATA host controller at AHCI mode.
2792
2793 The function is designed to initialize ATA host controller.
2794
2795 @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
2796
2797 **/
2798 EFI_STATUS
2799 EFIAPI
2800 AhciModeInitialization (
2801 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
2802 )
2803 {
2804 EFI_STATUS Status;
2805 EFI_PCI_IO_PROTOCOL *PciIo;
2806 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;
2807 UINT32 Capability;
2808 UINT8 MaxPortNumber;
2809 UINT32 PortImplementBitMap;
2810
2811 EFI_AHCI_REGISTERS *AhciRegisters;
2812
2813 UINT8 Port;
2814 DATA_64 Data64;
2815 UINT32 Offset;
2816 UINT32 Data;
2817 EFI_IDENTIFY_DATA Buffer;
2818 EFI_ATA_DEVICE_TYPE DeviceType;
2819 EFI_ATA_COLLECTIVE_MODE *SupportedModes;
2820 EFI_ATA_TRANSFER_MODE TransferMode;
2821 UINT32 PhyDetectDelay;
2822 UINT32 Value;
2823
2824 if (Instance == NULL) {
2825 return EFI_INVALID_PARAMETER;
2826 }
2827
2828 PciIo = Instance->PciIo;
2829 IdeInit = Instance->IdeControllerInit;
2830
2831 Status = AhciReset (PciIo, EFI_AHCI_BUS_RESET_TIMEOUT);
2832
2833 if (EFI_ERROR (Status)) {
2834 return EFI_DEVICE_ERROR;
2835 }
2836
2837 //
2838 // Collect AHCI controller information
2839 //
2840 Capability = AhciReadReg (PciIo, EFI_AHCI_CAPABILITY_OFFSET);
2841
2842 //
2843 // Make sure that GHC.AE bit is set before accessing any AHCI registers.
2844 //
2845 Value = AhciReadReg (PciIo, EFI_AHCI_GHC_OFFSET);
2846
2847 if ((Value & EFI_AHCI_GHC_ENABLE) == 0) {
2848 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE);
2849 }
2850
2851 //
2852 // Enable 64-bit DMA support in the PCI layer if this controller
2853 // supports it.
2854 //
2855 if ((Capability & EFI_AHCI_CAP_S64A) != 0) {
2856 Status = PciIo->Attributes (
2857 PciIo,
2858 EfiPciIoAttributeOperationEnable,
2859 EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE,
2860 NULL
2861 );
2862 if (EFI_ERROR (Status)) {
2863 DEBUG ((
2864 DEBUG_WARN,
2865 "AhciModeInitialization: failed to enable 64-bit DMA on 64-bit capable controller (%r)\n",
2866 Status
2867 ));
2868 }
2869 }
2870
2871 //
2872 // Get the number of command slots per port supported by this HBA.
2873 //
2874 MaxPortNumber = (UINT8)((Capability & 0x1F) + 1);
2875
2876 //
2877 // Get the bit map of those ports exposed by this HBA.
2878 // It indicates which ports that the HBA supports are available for software to use.
2879 //
2880 PortImplementBitMap = AhciReadReg (PciIo, EFI_AHCI_PI_OFFSET);
2881
2882 AhciRegisters = &Instance->AhciRegisters;
2883 Status = AhciCreateTransferDescriptor (PciIo, AhciRegisters);
2884
2885 if (EFI_ERROR (Status)) {
2886 return EFI_OUT_OF_RESOURCES;
2887 }
2888
2889 for (Port = 0; Port < EFI_AHCI_MAX_PORTS; Port++) {
2890 if ((PortImplementBitMap & (((UINT32)BIT0) << Port)) != 0) {
2891 //
2892 // According to AHCI spec, MaxPortNumber should be equal or greater than the number of implemented ports.
2893 //
2894 if ((MaxPortNumber--) == 0) {
2895 //
2896 // Should never be here.
2897 //
2898 ASSERT (FALSE);
2899 return EFI_SUCCESS;
2900 }
2901
2902 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, Port);
2903
2904 //
2905 // Initialize FIS Base Address Register and Command List Base Address Register for use.
2906 //
2907 Data64.Uint64 = (UINTN)(AhciRegisters->AhciRFisPciAddr) + sizeof (EFI_AHCI_RECEIVED_FIS) * Port;
2908 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FB;
2909 AhciWriteReg (PciIo, Offset, Data64.Uint32.Lower32);
2910 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FBU;
2911 AhciWriteReg (PciIo, Offset, Data64.Uint32.Upper32);
2912
2913 Data64.Uint64 = (UINTN)(AhciRegisters->AhciCmdListPciAddr);
2914 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLB;
2915 AhciWriteReg (PciIo, Offset, Data64.Uint32.Lower32);
2916 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLBU;
2917 AhciWriteReg (PciIo, Offset, Data64.Uint32.Upper32);
2918
2919 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
2920 Data = AhciReadReg (PciIo, Offset);
2921 if ((Data & EFI_AHCI_PORT_CMD_CPD) != 0) {
2922 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_POD);
2923 }
2924
2925 if ((Capability & EFI_AHCI_CAP_SSS) != 0) {
2926 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_SUD);
2927 }
2928
2929 //
2930 // Disable aggressive power management.
2931 //
2932 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SCTL;
2933 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_SCTL_IPM_INIT);
2934 //
2935 // Disable the reporting of the corresponding interrupt to system software.
2936 //
2937 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IE;
2938 AhciAndReg (PciIo, Offset, 0);
2939
2940 //
2941 // Now inform the IDE Controller Init Module.
2942 //
2943 IdeInit->NotifyPhase (IdeInit, EfiIdeBusBeforeDevicePresenceDetection, Port);
2944
2945 //
2946 // Enable FIS Receive DMA engine for the first D2H FIS.
2947 //
2948 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
2949 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_FRE);
2950
2951 //
2952 // Wait for the Phy to detect the presence of a device.
2953 //
2954 PhyDetectDelay = EFI_AHCI_BUS_PHY_DETECT_TIMEOUT;
2955 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS;
2956 do {
2957 Data = AhciReadReg (PciIo, Offset) & EFI_AHCI_PORT_SSTS_DET_MASK;
2958 if ((Data == EFI_AHCI_PORT_SSTS_DET_PCE) || (Data == EFI_AHCI_PORT_SSTS_DET)) {
2959 break;
2960 }
2961
2962 MicroSecondDelay (1000);
2963 PhyDetectDelay--;
2964 } while (PhyDetectDelay > 0);
2965
2966 if (PhyDetectDelay == 0) {
2967 //
2968 // No device detected at this port.
2969 // Clear PxCMD.SUD for those ports at which there are no device present.
2970 //
2971 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
2972 AhciAndReg (PciIo, Offset, (UINT32) ~(EFI_AHCI_PORT_CMD_SUD));
2973 continue;
2974 }
2975
2976 Status = AhciWaitDeviceReady (PciIo, Port);
2977 if (EFI_ERROR (Status)) {
2978 continue;
2979 }
2980
2981 //
2982 // When the first D2H register FIS is received, the content of PxSIG register is updated.
2983 //
2984 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SIG;
2985 Status = AhciWaitMmioSet (
2986 PciIo,
2987 Offset,
2988 0x0000FFFF,
2989 0x00000101,
2990 EFI_TIMER_PERIOD_SECONDS (16)
2991 );
2992 if (EFI_ERROR (Status)) {
2993 continue;
2994 }
2995
2996 Data = AhciReadReg (PciIo, Offset);
2997 if ((Data & EFI_AHCI_ATAPI_SIG_MASK) == EFI_AHCI_ATAPI_DEVICE_SIG) {
2998 Status = AhciIdentifyPacket (PciIo, AhciRegisters, Port, 0, &Buffer);
2999
3000 if (EFI_ERROR (Status)) {
3001 continue;
3002 }
3003
3004 DeviceType = EfiIdeCdrom;
3005 } else if ((Data & EFI_AHCI_ATAPI_SIG_MASK) == EFI_AHCI_ATA_DEVICE_SIG) {
3006 Status = AhciIdentify (PciIo, AhciRegisters, Port, 0, &Buffer);
3007
3008 if (EFI_ERROR (Status)) {
3009 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_EC_NOT_DETECTED));
3010 continue;
3011 }
3012
3013 DEBUG ((
3014 DEBUG_INFO,
3015 "IDENTIFY DEVICE: [0] = %016x, [2] = %016x, [83] = %016x, [86] = %016x\n",
3016 Buffer.AtaData.config,
3017 Buffer.AtaData.specific_config,
3018 Buffer.AtaData.command_set_supported_83,
3019 Buffer.AtaData.command_set_feature_enb_86
3020 ));
3021 if ((Buffer.AtaData.config & BIT2) != 0) {
3022 //
3023 // SpinUp disk if device reported incomplete IDENTIFY DEVICE.
3024 //
3025 Status = AhciSpinUpDisk (
3026 PciIo,
3027 AhciRegisters,
3028 Port,
3029 0,
3030 &Buffer
3031 );
3032 if (EFI_ERROR (Status)) {
3033 DEBUG ((DEBUG_ERROR, "Spin up standby device failed - %r\n", Status));
3034 continue;
3035 }
3036 }
3037
3038 DeviceType = EfiIdeHarddisk;
3039 } else {
3040 continue;
3041 }
3042
3043 DEBUG ((
3044 DEBUG_INFO,
3045 "port [%d] port multitplier [%d] has a [%a]\n",
3046 Port,
3047 0,
3048 DeviceType == EfiIdeCdrom ? "cdrom" : "harddisk"
3049 ));
3050
3051 //
3052 // If the device is a hard disk, then try to enable S.M.A.R.T feature
3053 //
3054 if ((DeviceType == EfiIdeHarddisk) && PcdGetBool (PcdAtaSmartEnable)) {
3055 AhciAtaSmartSupport (
3056 PciIo,
3057 AhciRegisters,
3058 Port,
3059 0,
3060 &Buffer,
3061 NULL
3062 );
3063 }
3064
3065 //
3066 // Submit identify data to IDE controller init driver
3067 //
3068 IdeInit->SubmitData (IdeInit, Port, 0, &Buffer);
3069
3070 //
3071 // Now start to config ide device parameter and transfer mode.
3072 //
3073 Status = IdeInit->CalculateMode (
3074 IdeInit,
3075 Port,
3076 0,
3077 &SupportedModes
3078 );
3079 if (EFI_ERROR (Status)) {
3080 DEBUG ((DEBUG_ERROR, "Calculate Mode Fail, Status = %r\n", Status));
3081 continue;
3082 }
3083
3084 //
3085 // Set best supported PIO mode on this IDE device
3086 //
3087 if (SupportedModes->PioMode.Mode <= EfiAtaPioMode2) {
3088 TransferMode.ModeCategory = EFI_ATA_MODE_DEFAULT_PIO;
3089 } else {
3090 TransferMode.ModeCategory = EFI_ATA_MODE_FLOW_PIO;
3091 }
3092
3093 TransferMode.ModeNumber = (UINT8)(SupportedModes->PioMode.Mode);
3094
3095 //
3096 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA can't
3097 // be set together. Only one DMA mode can be set to a device. If setting
3098 // DMA mode operation fails, we can continue moving on because we only use
3099 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
3100 //
3101 if (SupportedModes->UdmaMode.Valid) {
3102 TransferMode.ModeCategory = EFI_ATA_MODE_UDMA;
3103 TransferMode.ModeNumber = (UINT8)(SupportedModes->UdmaMode.Mode);
3104 } else if (SupportedModes->MultiWordDmaMode.Valid) {
3105 TransferMode.ModeCategory = EFI_ATA_MODE_MDMA;
3106 TransferMode.ModeNumber = (UINT8)SupportedModes->MultiWordDmaMode.Mode;
3107 }
3108
3109 Status = AhciDeviceSetFeature (PciIo, AhciRegisters, Port, 0, 0x03, (UINT32)(*(UINT8 *)&TransferMode), ATA_ATAPI_TIMEOUT);
3110 if (EFI_ERROR (Status)) {
3111 DEBUG ((DEBUG_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
3112 continue;
3113 }
3114
3115 //
3116 // Found a ATA or ATAPI device, add it into the device list.
3117 //
3118 CreateNewDeviceInfo (Instance, Port, 0xFFFF, DeviceType, &Buffer);
3119 if (DeviceType == EfiIdeHarddisk) {
3120 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_ENABLE));
3121 AhciEnableDevSlp (
3122 PciIo,
3123 AhciRegisters,
3124 Port,
3125 0,
3126 &Buffer
3127 );
3128 }
3129
3130 //
3131 // Enable/disable PUIS according to policy setting if PUIS is capable (Word[83].BIT5 is set).
3132 //
3133 if ((Buffer.AtaData.command_set_supported_83 & BIT5) != 0) {
3134 Status = AhciPuisEnable (
3135 PciIo,
3136 AhciRegisters,
3137 Port,
3138 0
3139 );
3140 if (EFI_ERROR (Status)) {
3141 DEBUG ((DEBUG_ERROR, "PUIS enable/disable failed, Status = %r\n", Status));
3142 continue;
3143 }
3144 }
3145 }
3146 }
3147
3148 return EFI_SUCCESS;
3149 }