TianoCore EDK2 master
Loading...
Searching...
No Matches
IdeMode.c
Go to the documentation of this file.
1
9#include "AtaAtapiPassThru.h"
10
19UINT8
20EFIAPI
23 IN UINT16 Port
24 )
25{
26 UINT8 Data;
27
28 ASSERT (PciIo != NULL);
29
30 Data = 0;
31 //
32 // perform 1-byte data read from register
33 //
34 PciIo->Io.Read (
35 PciIo,
36 EfiPciIoWidthUint8,
38 (UINT64)Port,
39 1,
40 &Data
41 );
42 return Data;
43}
44
52VOID
53EFIAPI
56 IN UINT16 Port,
57 IN UINT8 Data
58 )
59{
60 ASSERT (PciIo != NULL);
61
62 //
63 // perform 1-byte data write to register
64 //
65 PciIo->Io.Write (
66 PciIo,
67 EfiPciIoWidthUint8,
69 (UINT64)Port,
70 1,
71 &Data
72 );
73}
74
82VOID
83EFIAPI
86 IN UINT16 Port,
87 IN UINT16 Data
88 )
89{
90 ASSERT (PciIo != NULL);
91
92 //
93 // perform 1-word data write to register
94 //
95 PciIo->Io.Write (
96 PciIo,
97 EfiPciIoWidthUint16,
99 (UINT64)Port,
100 1,
101 &Data
102 );
103}
104
112VOID
113EFIAPI
115 IN EFI_PCI_IO_PROTOCOL *PciIo,
116 IN UINT16 Port,
117 IN UINT32 Data
118 )
119{
120 ASSERT (PciIo != NULL);
121
122 //
123 // perform 2-word data write to register
124 //
125 PciIo->Io.Write (
126 PciIo,
127 EfiPciIoWidthUint32,
129 (UINT64)Port,
130 1,
131 &Data
132 );
133}
134
146VOID
147EFIAPI
149 IN EFI_PCI_IO_PROTOCOL *PciIo,
150 IN UINT16 Port,
151 IN UINTN Count,
152 IN VOID *Buffer
153 )
154{
155 ASSERT (PciIo != NULL);
156 ASSERT (Buffer != NULL);
157
158 //
159 // perform UINT16 data write to the FIFO
160 //
161 PciIo->Io.Write (
162 PciIo,
163 EfiPciIoWidthFifoUint16,
165 (UINT64)Port,
166 Count,
167 (UINT16 *)Buffer
168 );
169}
170
182VOID
183EFIAPI
185 IN EFI_PCI_IO_PROTOCOL *PciIo,
186 IN UINT16 Port,
187 IN UINTN Count,
188 IN VOID *Buffer
189 )
190{
191 ASSERT (PciIo != NULL);
192 ASSERT (Buffer != NULL);
193
194 //
195 // Perform UINT16 data read from FIFO
196 //
197 PciIo->Io.Read (
198 PciIo,
199 EfiPciIoWidthFifoUint16,
201 (UINT64)Port,
202 Count,
203 (UINT16 *)Buffer
204 );
205}
206
217VOID
218EFIAPI
220 IN EFI_PCI_IO_PROTOCOL *PciIo,
221 IN EFI_IDE_REGISTERS *IdeRegisters,
222 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
223 )
224{
225 EFI_ATA_STATUS_BLOCK StatusBlock;
226
227 ASSERT (PciIo != NULL);
228 ASSERT (IdeRegisters != NULL);
229
230 ZeroMem (&StatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
231
232 StatusBlock.AtaStatus = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
233 StatusBlock.AtaError = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);
234 StatusBlock.AtaSectorCount = IdeReadPortB (PciIo, IdeRegisters->SectorCount);
235 StatusBlock.AtaSectorCountExp = IdeReadPortB (PciIo, IdeRegisters->SectorCount);
236 StatusBlock.AtaSectorNumber = IdeReadPortB (PciIo, IdeRegisters->SectorNumber);
237 StatusBlock.AtaSectorNumberExp = IdeReadPortB (PciIo, IdeRegisters->SectorNumber);
238 StatusBlock.AtaCylinderLow = IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
239 StatusBlock.AtaCylinderLowExp = IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
240 StatusBlock.AtaCylinderHigh = IdeReadPortB (PciIo, IdeRegisters->CylinderMsb);
241 StatusBlock.AtaCylinderHighExp = IdeReadPortB (PciIo, IdeRegisters->CylinderMsb);
242 StatusBlock.AtaDeviceHead = IdeReadPortB (PciIo, IdeRegisters->Head);
243
244 if (AtaStatusBlock != NULL) {
245 //
246 // Dump the content of all ATA registers.
247 //
248 CopyMem (AtaStatusBlock, &StatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
249 }
250
252 if ((StatusBlock.AtaStatus & ATA_STSREG_DWF) != 0) {
253 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Write Fault\n", StatusBlock.AtaStatus));
254 }
255
256 if ((StatusBlock.AtaStatus & ATA_STSREG_CORR) != 0) {
257 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Corrected Data\n", StatusBlock.AtaStatus));
258 }
259
260 if ((StatusBlock.AtaStatus & ATA_STSREG_ERR) != 0) {
261 if ((StatusBlock.AtaError & ATA_ERRREG_BBK) != 0) {
262 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Bad Block Detected\n", StatusBlock.AtaError));
263 }
264
265 if ((StatusBlock.AtaError & ATA_ERRREG_UNC) != 0) {
266 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Uncorrectable Data\n", StatusBlock.AtaError));
267 }
268
269 if ((StatusBlock.AtaError & ATA_ERRREG_MC) != 0) {
270 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Media Change\n", StatusBlock.AtaError));
271 }
272
273 if ((StatusBlock.AtaError & ATA_ERRREG_ABRT) != 0) {
274 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Abort\n", StatusBlock.AtaError));
275 }
276
277 if ((StatusBlock.AtaError & ATA_ERRREG_TK0NF) != 0) {
278 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Track 0 Not Found\n", StatusBlock.AtaError));
279 }
280
281 if ((StatusBlock.AtaError & ATA_ERRREG_AMNF) != 0) {
282 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Address Mark Not Found\n", StatusBlock.AtaError));
283 }
284 }
285
287}
288
301EFIAPI
303 IN EFI_PCI_IO_PROTOCOL *PciIo,
304 IN EFI_IDE_REGISTERS *IdeRegisters
305 )
306{
307 UINT8 StatusRegister;
308
309 ASSERT (PciIo != NULL);
310 ASSERT (IdeRegisters != NULL);
311
312 StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
313
314 if ((StatusRegister & ATA_STSREG_BSY) == 0) {
315 if ((StatusRegister & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) {
316 return EFI_SUCCESS;
317 } else {
318 return EFI_DEVICE_ERROR;
319 }
320 }
321
322 return EFI_SUCCESS;
323}
324
343EFIAPI
345 IN EFI_PCI_IO_PROTOCOL *PciIo,
346 IN EFI_IDE_REGISTERS *IdeRegisters,
347 IN UINT64 Timeout
348 )
349{
350 UINT64 Delay;
351 UINT8 StatusRegister;
352 BOOLEAN InfiniteWait;
353
354 ASSERT (PciIo != NULL);
355 ASSERT (IdeRegisters != NULL);
356
357 if (Timeout == 0) {
358 InfiniteWait = TRUE;
359 } else {
360 InfiniteWait = FALSE;
361 }
362
363 Delay = DivU64x32 (Timeout, 1000) + 1;
364 do {
365 StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
366
367 //
368 // Wait for BSY == 0, then judge if DRQ is clear
369 //
370 if ((StatusRegister & ATA_STSREG_BSY) == 0) {
371 if ((StatusRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {
372 return EFI_DEVICE_ERROR;
373 } else {
374 return EFI_SUCCESS;
375 }
376 }
377
378 //
379 // Stall for 100 microseconds.
380 //
381 MicroSecondDelay (100);
382
383 Delay--;
384 } while (InfiniteWait || (Delay > 0));
385
386 return EFI_TIMEOUT;
387}
388
406EFIAPI
408 IN EFI_PCI_IO_PROTOCOL *PciIo,
409 IN EFI_IDE_REGISTERS *IdeRegisters,
410 IN UINT64 Timeout
411 )
412{
413 UINT64 Delay;
414 UINT8 AltRegister;
415 BOOLEAN InfiniteWait;
416
417 ASSERT (PciIo != NULL);
418 ASSERT (IdeRegisters != NULL);
419
420 if (Timeout == 0) {
421 InfiniteWait = TRUE;
422 } else {
423 InfiniteWait = FALSE;
424 }
425
426 Delay = DivU64x32 (Timeout, 1000) + 1;
427 do {
428 AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
429
430 //
431 // Wait for BSY == 0, then judge if DRQ is clear
432 //
433 if ((AltRegister & ATA_STSREG_BSY) == 0) {
434 if ((AltRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {
435 return EFI_DEVICE_ERROR;
436 } else {
437 return EFI_SUCCESS;
438 }
439 }
440
441 //
442 // Stall for 100 microseconds.
443 //
444 MicroSecondDelay (100);
445
446 Delay--;
447 } while (InfiniteWait || (Delay > 0));
448
449 return EFI_TIMEOUT;
450}
451
480EFIAPI
482 IN EFI_PCI_IO_PROTOCOL *PciIo,
483 IN EFI_IDE_REGISTERS *IdeRegisters,
484 IN UINT64 Timeout
485 )
486{
487 UINT64 Delay;
488 UINT8 StatusRegister;
489 UINT8 ErrorRegister;
490 BOOLEAN InfiniteWait;
491
492 ASSERT (PciIo != NULL);
493 ASSERT (IdeRegisters != NULL);
494
495 if (Timeout == 0) {
496 InfiniteWait = TRUE;
497 } else {
498 InfiniteWait = FALSE;
499 }
500
501 Delay = DivU64x32 (Timeout, 1000) + 1;
502 do {
503 //
504 // Read Status Register will clear interrupt
505 //
506 StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
507
508 //
509 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
510 //
511 if ((StatusRegister & ATA_STSREG_BSY) == 0) {
512 if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {
513 ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);
514
515 if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
516 return EFI_ABORTED;
517 }
518
519 return EFI_DEVICE_ERROR;
520 }
521
522 if ((StatusRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {
523 return EFI_SUCCESS;
524 } else {
525 return EFI_NOT_READY;
526 }
527 }
528
529 //
530 // Stall for 100 microseconds.
531 //
532 MicroSecondDelay (100);
533
534 Delay--;
535 } while (InfiniteWait || (Delay > 0));
536
537 return EFI_TIMEOUT;
538}
539
566EFIAPI
568 IN EFI_PCI_IO_PROTOCOL *PciIo,
569 IN EFI_IDE_REGISTERS *IdeRegisters,
570 IN UINT64 Timeout
571 )
572{
573 UINT64 Delay;
574 UINT8 AltRegister;
575 UINT8 ErrorRegister;
576 BOOLEAN InfiniteWait;
577
578 ASSERT (PciIo != NULL);
579 ASSERT (IdeRegisters != NULL);
580
581 if (Timeout == 0) {
582 InfiniteWait = TRUE;
583 } else {
584 InfiniteWait = FALSE;
585 }
586
587 Delay = DivU64x32 (Timeout, 1000) + 1;
588
589 do {
590 //
591 // Read Alternate Status Register will not clear interrupt status
592 //
593 AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
594 //
595 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
596 //
597 if ((AltRegister & ATA_STSREG_BSY) == 0) {
598 if ((AltRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {
599 ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);
600
601 if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
602 return EFI_ABORTED;
603 }
604
605 return EFI_DEVICE_ERROR;
606 }
607
608 if ((AltRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {
609 return EFI_SUCCESS;
610 } else {
611 return EFI_NOT_READY;
612 }
613 }
614
615 //
616 // Stall for 100 microseconds.
617 //
618 MicroSecondDelay (100);
619
620 Delay--;
621 } while (InfiniteWait || (Delay > 0));
622
623 return EFI_TIMEOUT;
624}
625
640EFIAPI
642 IN EFI_PCI_IO_PROTOCOL *PciIo,
643 IN EFI_IDE_REGISTERS *IdeRegisters,
644 IN UINT64 Timeout
645 )
646{
647 UINT64 Delay;
648 UINT8 StatusRegister;
649 BOOLEAN InfiniteWait;
650
651 ASSERT (PciIo != NULL);
652 ASSERT (IdeRegisters != NULL);
653
654 if (Timeout == 0) {
655 InfiniteWait = TRUE;
656 } else {
657 InfiniteWait = FALSE;
658 }
659
660 Delay = DivU64x32 (Timeout, 1000) + 1;
661 do {
662 StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
663
664 if ((StatusRegister & ATA_STSREG_BSY) == 0x00) {
665 return EFI_SUCCESS;
666 }
667
668 //
669 // Stall for 100 microseconds.
670 //
671 MicroSecondDelay (100);
672
673 Delay--;
674 } while (InfiniteWait || (Delay > 0));
675
676 return EFI_TIMEOUT;
677}
678
727EFIAPI
729 IN EFI_PCI_IO_PROTOCOL *PciIo,
730 IN OUT EFI_IDE_REGISTERS *IdeRegisters
731 )
732{
733 EFI_STATUS Status;
734 PCI_TYPE00 PciData;
735 UINT16 CommandBlockBaseAddr;
736 UINT16 ControlBlockBaseAddr;
737 UINT16 BusMasterBaseAddr;
738
739 if ((PciIo == NULL) || (IdeRegisters == NULL)) {
740 return EFI_INVALID_PARAMETER;
741 }
742
743 Status = PciIo->Pci.Read (
744 PciIo,
745 EfiPciIoWidthUint8,
746 0,
747 sizeof (PciData),
748 &PciData
749 );
750
751 if (EFI_ERROR (Status)) {
752 return Status;
753 }
754
755 BusMasterBaseAddr = (UINT16)((PciData.Device.Bar[4] & 0x0000fff0));
756
757 if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) {
758 CommandBlockBaseAddr = 0x1f0;
759 ControlBlockBaseAddr = 0x3f6;
760 } else {
761 //
762 // The BARs should be of IO type
763 //
764 if (((PciData.Device.Bar[0] & BIT0) == 0) ||
765 ((PciData.Device.Bar[1] & BIT0) == 0))
766 {
767 return EFI_UNSUPPORTED;
768 }
769
770 CommandBlockBaseAddr = (UINT16)(PciData.Device.Bar[0] & 0x0000fff8);
771 ControlBlockBaseAddr = (UINT16)((PciData.Device.Bar[1] & 0x0000fffc) + 2);
772 }
773
774 //
775 // Calculate IDE primary channel I/O register base address.
776 //
777 IdeRegisters[EfiIdePrimary].Data = CommandBlockBaseAddr;
778 IdeRegisters[EfiIdePrimary].ErrOrFeature = (UINT16)(CommandBlockBaseAddr + 0x01);
779 IdeRegisters[EfiIdePrimary].SectorCount = (UINT16)(CommandBlockBaseAddr + 0x02);
780 IdeRegisters[EfiIdePrimary].SectorNumber = (UINT16)(CommandBlockBaseAddr + 0x03);
781 IdeRegisters[EfiIdePrimary].CylinderLsb = (UINT16)(CommandBlockBaseAddr + 0x04);
782 IdeRegisters[EfiIdePrimary].CylinderMsb = (UINT16)(CommandBlockBaseAddr + 0x05);
783 IdeRegisters[EfiIdePrimary].Head = (UINT16)(CommandBlockBaseAddr + 0x06);
784 IdeRegisters[EfiIdePrimary].CmdOrStatus = (UINT16)(CommandBlockBaseAddr + 0x07);
785 IdeRegisters[EfiIdePrimary].AltOrDev = ControlBlockBaseAddr;
786 IdeRegisters[EfiIdePrimary].BusMasterBaseAddr = BusMasterBaseAddr;
787
788 if ((PciData.Hdr.ClassCode[0] & IDE_SECONDARY_OPERATING_MODE) == 0) {
789 CommandBlockBaseAddr = 0x170;
790 ControlBlockBaseAddr = 0x376;
791 } else {
792 //
793 // The BARs should be of IO type
794 //
795 if (((PciData.Device.Bar[2] & BIT0) == 0) ||
796 ((PciData.Device.Bar[3] & BIT0) == 0))
797 {
798 return EFI_UNSUPPORTED;
799 }
800
801 CommandBlockBaseAddr = (UINT16)(PciData.Device.Bar[2] & 0x0000fff8);
802 ControlBlockBaseAddr = (UINT16)((PciData.Device.Bar[3] & 0x0000fffc) + 2);
803 }
804
805 //
806 // Calculate IDE secondary channel I/O register base address.
807 //
808 IdeRegisters[EfiIdeSecondary].Data = CommandBlockBaseAddr;
809 IdeRegisters[EfiIdeSecondary].ErrOrFeature = (UINT16)(CommandBlockBaseAddr + 0x01);
810 IdeRegisters[EfiIdeSecondary].SectorCount = (UINT16)(CommandBlockBaseAddr + 0x02);
811 IdeRegisters[EfiIdeSecondary].SectorNumber = (UINT16)(CommandBlockBaseAddr + 0x03);
812 IdeRegisters[EfiIdeSecondary].CylinderLsb = (UINT16)(CommandBlockBaseAddr + 0x04);
813 IdeRegisters[EfiIdeSecondary].CylinderMsb = (UINT16)(CommandBlockBaseAddr + 0x05);
814 IdeRegisters[EfiIdeSecondary].Head = (UINT16)(CommandBlockBaseAddr + 0x06);
815 IdeRegisters[EfiIdeSecondary].CmdOrStatus = (UINT16)(CommandBlockBaseAddr + 0x07);
816 IdeRegisters[EfiIdeSecondary].AltOrDev = ControlBlockBaseAddr;
817 IdeRegisters[EfiIdeSecondary].BusMasterBaseAddr = (UINT16)(BusMasterBaseAddr + 0x8);
818
819 return EFI_SUCCESS;
820}
821
835EFIAPI
837 IN EFI_PCI_IO_PROTOCOL *PciIo,
838 IN EFI_IDE_REGISTERS *IdeRegisters,
839 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
840 IN UINT64 Timeout
841 )
842{
843 EFI_STATUS Status;
844 UINT8 DeviceHead;
845 UINT8 AtaCommand;
846
847 ASSERT (PciIo != NULL);
848 ASSERT (IdeRegisters != NULL);
849 ASSERT (AtaCommandBlock != NULL);
850
851 DeviceHead = AtaCommandBlock->AtaDeviceHead;
852 AtaCommand = AtaCommandBlock->AtaCommand;
853
854 Status = WaitForBSYClear (PciIo, IdeRegisters, Timeout);
855 if (EFI_ERROR (Status)) {
856 return EFI_DEVICE_ERROR;
857 }
858
859 //
860 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
861 //
862 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | DeviceHead));
863
864 //
865 // set all the command parameters
866 // Before write to all the following registers, BSY and DRQ must be 0.
867 //
868 Status = DRQClear2 (PciIo, IdeRegisters, Timeout);
869 if (EFI_ERROR (Status)) {
870 return EFI_DEVICE_ERROR;
871 }
872
873 //
874 // Fill the feature register, which is a two-byte FIFO. Need write twice.
875 //
876 IdeWritePortB (PciIo, IdeRegisters->ErrOrFeature, AtaCommandBlock->AtaFeaturesExp);
877 IdeWritePortB (PciIo, IdeRegisters->ErrOrFeature, AtaCommandBlock->AtaFeatures);
878
879 //
880 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
881 //
882 IdeWritePortB (PciIo, IdeRegisters->SectorCount, AtaCommandBlock->AtaSectorCountExp);
883 IdeWritePortB (PciIo, IdeRegisters->SectorCount, AtaCommandBlock->AtaSectorCount);
884
885 //
886 // Fill the start LBA registers, which are also two-byte FIFO
887 //
888 IdeWritePortB (PciIo, IdeRegisters->SectorNumber, AtaCommandBlock->AtaSectorNumberExp);
889 IdeWritePortB (PciIo, IdeRegisters->SectorNumber, AtaCommandBlock->AtaSectorNumber);
890
891 IdeWritePortB (PciIo, IdeRegisters->CylinderLsb, AtaCommandBlock->AtaCylinderLowExp);
892 IdeWritePortB (PciIo, IdeRegisters->CylinderLsb, AtaCommandBlock->AtaCylinderLow);
893
894 IdeWritePortB (PciIo, IdeRegisters->CylinderMsb, AtaCommandBlock->AtaCylinderHighExp);
895 IdeWritePortB (PciIo, IdeRegisters->CylinderMsb, AtaCommandBlock->AtaCylinderHigh);
896
897 //
898 // Send command via Command Register
899 //
900 IdeWritePortB (PciIo, IdeRegisters->CmdOrStatus, AtaCommand);
901
902 //
903 // Stall at least 400 microseconds.
904 //
905 MicroSecondDelay (400);
906
907 return EFI_SUCCESS;
908}
909
933EFIAPI
935 IN EFI_PCI_IO_PROTOCOL *PciIo,
936 IN EFI_IDE_REGISTERS *IdeRegisters,
937 IN OUT VOID *Buffer,
938 IN UINT64 ByteCount,
939 IN BOOLEAN Read,
940 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
941 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
942 IN UINT64 Timeout,
944 )
945{
946 UINTN WordCount;
947 UINTN Increment;
948 UINT16 *Buffer16;
949 EFI_STATUS Status;
950
951 if ((PciIo == NULL) || (IdeRegisters == NULL) || (Buffer == NULL) || (AtaCommandBlock == NULL)) {
952 return EFI_INVALID_PARAMETER;
953 }
954
955 //
956 // Issue ATA command
957 //
958 Status = AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
959 if (EFI_ERROR (Status)) {
960 Status = EFI_DEVICE_ERROR;
961 goto Exit;
962 }
963
964 Buffer16 = (UINT16 *)Buffer;
965
966 //
967 // According to PIO data in protocol, host can perform a series of reads to
968 // the data register after each time device set DRQ ready;
969 // The data size of "a series of read" is command specific.
970 // For most ATA command, data size received from device will not exceed
971 // 1 sector, hence the data size for "a series of read" can be the whole data
972 // size of one command request.
973 // For ATA command such as Read Sector command, the data size of one ATA
974 // command request is often larger than 1 sector, according to the
975 // Read Sector command, the data size of "a series of read" is exactly 1
976 // sector.
977 // Here for simplification reason, we specify the data size for
978 // "a series of read" to 1 sector (256 words) if data size of one ATA command
979 // request is larger than 256 words.
980 //
981 Increment = 256;
982
983 //
984 // used to record bytes of currently transferred data
985 //
986 WordCount = 0;
987
988 while (WordCount < RShiftU64 (ByteCount, 1)) {
989 //
990 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready
991 //
992 Status = DRQReady2 (PciIo, IdeRegisters, Timeout);
993 if (EFI_ERROR (Status)) {
994 Status = EFI_DEVICE_ERROR;
995 goto Exit;
996 }
997
998 //
999 // Get the byte count for one series of read
1000 //
1001 if ((WordCount + Increment) > RShiftU64 (ByteCount, 1)) {
1002 Increment = (UINTN)(RShiftU64 (ByteCount, 1) - WordCount);
1003 }
1004
1005 if (Read) {
1007 PciIo,
1008 IdeRegisters->Data,
1009 Increment,
1010 Buffer16
1011 );
1012 } else {
1014 PciIo,
1015 IdeRegisters->Data,
1016 Increment,
1017 Buffer16
1018 );
1019 }
1020
1021 Status = CheckStatusRegister (PciIo, IdeRegisters);
1022 if (EFI_ERROR (Status)) {
1023 Status = EFI_DEVICE_ERROR;
1024 goto Exit;
1025 }
1026
1027 WordCount += Increment;
1028 Buffer16 += Increment;
1029 }
1030
1031 Status = DRQClear (PciIo, IdeRegisters, Timeout);
1032 if (EFI_ERROR (Status)) {
1033 Status = EFI_DEVICE_ERROR;
1034 goto Exit;
1035 }
1036
1037Exit:
1038 //
1039 // Dump All Ide registers to ATA_STATUS_BLOCK
1040 //
1041 DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
1042
1043 //
1044 // Not support the Non-blocking now,just do the blocking process.
1045 //
1046 return Status;
1047}
1048
1068EFIAPI
1070 IN EFI_PCI_IO_PROTOCOL *PciIo,
1071 IN EFI_IDE_REGISTERS *IdeRegisters,
1072 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
1073 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
1074 IN UINT64 Timeout,
1075 IN ATA_NONBLOCK_TASK *Task
1076 )
1077{
1078 EFI_STATUS Status;
1079
1080 if ((PciIo == NULL) || (IdeRegisters == NULL) || (AtaCommandBlock == NULL)) {
1081 return EFI_INVALID_PARAMETER;
1082 }
1083
1084 //
1085 // Issue ATA command
1086 //
1087 Status = AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
1088 if (EFI_ERROR (Status)) {
1089 Status = EFI_DEVICE_ERROR;
1090 goto Exit;
1091 }
1092
1093 //
1094 // Wait for command completion
1095 //
1096 Status = WaitForBSYClear (PciIo, IdeRegisters, Timeout);
1097 if (EFI_ERROR (Status)) {
1098 Status = EFI_DEVICE_ERROR;
1099 goto Exit;
1100 }
1101
1102 Status = CheckStatusRegister (PciIo, IdeRegisters);
1103 if (EFI_ERROR (Status)) {
1104 Status = EFI_DEVICE_ERROR;
1105 goto Exit;
1106 }
1107
1108Exit:
1109 //
1110 // Dump All Ide registers to ATA_STATUS_BLOCK
1111 //
1112 DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
1113
1114 //
1115 // Not support the Non-blocking now,just do the blocking process.
1116 //
1117 return Status;
1118}
1119
1134 IN EFI_PCI_IO_PROTOCOL *PciIo,
1135 IN EFI_IDE_REGISTERS *IdeRegisters,
1136 IN UINT64 Timeout
1137 )
1138{
1139 UINT8 RegisterValue;
1140 EFI_STATUS Status;
1141 UINT16 IoPortForBmis;
1142 UINT64 Delay;
1143 BOOLEAN InfiniteWait;
1144
1145 if (Timeout == 0) {
1146 InfiniteWait = TRUE;
1147 } else {
1148 InfiniteWait = FALSE;
1149 }
1150
1151 Delay = DivU64x32 (Timeout, 1000) + 1;
1152
1153 do {
1154 Status = CheckStatusRegister (PciIo, IdeRegisters);
1155 if (EFI_ERROR (Status)) {
1156 Status = EFI_DEVICE_ERROR;
1157 break;
1158 }
1159
1160 IoPortForBmis = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
1161 RegisterValue = IdeReadPortB (PciIo, IoPortForBmis);
1162 if (((RegisterValue & BMIS_ERROR) != 0) || (Timeout == 0)) {
1163 DEBUG ((DEBUG_ERROR, "ATA UDMA operation fails\n"));
1164 Status = EFI_DEVICE_ERROR;
1165 break;
1166 }
1167
1168 if ((RegisterValue & BMIS_INTERRUPT) != 0) {
1169 Status = EFI_SUCCESS;
1170 break;
1171 }
1172
1173 //
1174 // Stall for 100 microseconds.
1175 //
1176 MicroSecondDelay (100);
1177 Delay--;
1178 } while (InfiniteWait || (Delay > 0));
1179
1180 return Status;
1181}
1182
1199 IN EFI_PCI_IO_PROTOCOL *PciIo,
1200 IN ATA_NONBLOCK_TASK *Task,
1201 IN EFI_IDE_REGISTERS *IdeRegisters
1202 )
1203{
1204 UINT8 RegisterValue;
1205 UINT16 IoPortForBmis;
1206 EFI_STATUS Status;
1207
1208 Task->RetryTimes--;
1209
1210 Status = CheckStatusRegister (PciIo, IdeRegisters);
1211 if (EFI_ERROR (Status)) {
1212 return EFI_DEVICE_ERROR;
1213 }
1214
1215 IoPortForBmis = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
1216 RegisterValue = IdeReadPortB (PciIo, IoPortForBmis);
1217
1218 if ((RegisterValue & BMIS_ERROR) != 0) {
1219 DEBUG ((DEBUG_ERROR, "ATA UDMA operation fails\n"));
1220 return EFI_DEVICE_ERROR;
1221 }
1222
1223 if ((RegisterValue & BMIS_INTERRUPT) != 0) {
1224 return EFI_SUCCESS;
1225 }
1226
1227 if (!Task->InfiniteWait && (Task->RetryTimes == 0)) {
1228 return EFI_TIMEOUT;
1229 } else {
1230 //
1231 // The memory is not set.
1232 //
1233 return EFI_NOT_READY;
1234 }
1235}
1236
1262EFIAPI
1265 IN EFI_IDE_REGISTERS *IdeRegisters,
1266 IN BOOLEAN Read,
1267 IN VOID *DataBuffer,
1268 IN UINT64 DataLength,
1269 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
1270 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
1271 IN UINT64 Timeout,
1272 IN ATA_NONBLOCK_TASK *Task
1273 )
1274{
1275 EFI_STATUS Status;
1276 UINT16 IoPortForBmic;
1277 UINT16 IoPortForBmis;
1278 UINT16 IoPortForBmid;
1279
1280 UINTN PrdTableSize;
1281 EFI_PHYSICAL_ADDRESS PrdTableMapAddr;
1282 VOID *PrdTableMap;
1283 EFI_PHYSICAL_ADDRESS PrdTableBaseAddr;
1284 EFI_ATA_DMA_PRD *TempPrdBaseAddr;
1285 UINTN PrdTableNum;
1286
1287 UINT8 RegisterValue;
1288 UINTN PageCount;
1289 UINTN ByteCount;
1290 UINTN ByteRemaining;
1291 UINT8 DeviceControl;
1292
1293 VOID *BufferMap;
1294 EFI_PHYSICAL_ADDRESS BufferMapAddress;
1295 EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation;
1296
1297 UINT8 DeviceHead;
1298 EFI_PCI_IO_PROTOCOL *PciIo;
1299 EFI_TPL OldTpl;
1300
1301 UINTN AlignmentMask;
1302 UINTN RealPageCount;
1303 EFI_PHYSICAL_ADDRESS BaseAddr;
1304 EFI_PHYSICAL_ADDRESS BaseMapAddr;
1305
1306 Status = EFI_SUCCESS;
1307 PrdTableMap = NULL;
1308 BufferMap = NULL;
1309 PageCount = 0;
1310 RealPageCount = 0;
1311 BaseAddr = 0;
1312 PciIo = Instance->PciIo;
1313
1314 if ((PciIo == NULL) || (IdeRegisters == NULL) || (DataBuffer == NULL) || (AtaCommandBlock == NULL)) {
1315 return EFI_INVALID_PARAMETER;
1316 }
1317
1318 //
1319 // Before starting the Blocking BlockIO operation, push to finish all non-blocking
1320 // BlockIO tasks.
1321 // Delay 1ms to simulate the blocking time out checking.
1322 //
1323 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1324 while ((Task == NULL) && (!IsListEmpty (&Instance->NonBlockingTaskList))) {
1326 //
1327 // Stall for 1 milliseconds.
1328 //
1329 MicroSecondDelay (1000);
1330 }
1331
1332 gBS->RestoreTPL (OldTpl);
1333
1334 //
1335 // The data buffer should be even alignment
1336 //
1337 if (((UINTN)DataBuffer & 0x1) != 0) {
1338 return EFI_INVALID_PARAMETER;
1339 }
1340
1341 //
1342 // Set relevant IO Port address.
1343 //
1344 IoPortForBmic = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIC_OFFSET);
1345 IoPortForBmis = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
1346 IoPortForBmid = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMID_OFFSET);
1347
1348 //
1349 // For Blocking mode, start the command.
1350 // For non-blocking mode, when the command is not started, start it, otherwise
1351 // go to check the status.
1352 //
1353 if (((Task != NULL) && (!Task->IsStart)) || (Task == NULL)) {
1354 //
1355 // Calculate the number of PRD entry.
1356 // Every entry in PRD table can specify a 64K memory region.
1357 //
1358 PrdTableNum = (UINTN)(RShiftU64 (DataLength, 16) + 1);
1359
1360 //
1361 // Make sure that the memory region of PRD table is not cross 64K boundary
1362 //
1363 PrdTableSize = PrdTableNum * sizeof (EFI_ATA_DMA_PRD);
1364 if (PrdTableSize > 0x10000) {
1365 return EFI_INVALID_PARAMETER;
1366 }
1367
1368 //
1369 // Allocate buffer for PRD table initialization.
1370 // Note Ide Bus Master spec said the descriptor table must be aligned on a 4 byte
1371 // boundary and the table cannot cross a 64K boundary in memory.
1372 //
1373 PageCount = EFI_SIZE_TO_PAGES (PrdTableSize);
1374 RealPageCount = PageCount + EFI_SIZE_TO_PAGES (SIZE_64KB);
1375
1376 //
1377 // Make sure that PageCount plus EFI_SIZE_TO_PAGES (SIZE_64KB) does not overflow.
1378 //
1379 ASSERT (RealPageCount > PageCount);
1380
1381 Status = PciIo->AllocateBuffer (
1382 PciIo,
1385 RealPageCount,
1386 (VOID **)&BaseAddr,
1387 0
1388 );
1389 if (EFI_ERROR (Status)) {
1390 return EFI_OUT_OF_RESOURCES;
1391 }
1392
1393 ByteCount = EFI_PAGES_TO_SIZE (RealPageCount);
1394 Status = PciIo->Map (
1395 PciIo,
1397 (VOID *)(UINTN)BaseAddr,
1398 &ByteCount,
1399 &BaseMapAddr,
1400 &PrdTableMap
1401 );
1402 if (EFI_ERROR (Status) || (ByteCount != EFI_PAGES_TO_SIZE (RealPageCount))) {
1403 //
1404 // If the data length actually mapped is not equal to the requested amount,
1405 // it means the DMA operation may be broken into several discontinuous smaller chunks.
1406 // Can't handle this case.
1407 //
1408 PciIo->FreeBuffer (PciIo, RealPageCount, (VOID *)(UINTN)BaseAddr);
1409 return EFI_OUT_OF_RESOURCES;
1410 }
1411
1412 ZeroMem ((VOID *)((UINTN)BaseAddr), ByteCount);
1413
1414 //
1415 // Calculate the 64K align address as PRD Table base address.
1416 //
1417 AlignmentMask = SIZE_64KB - 1;
1418 PrdTableBaseAddr = ((UINTN)BaseAddr + AlignmentMask) & ~AlignmentMask;
1419 PrdTableMapAddr = ((UINTN)BaseMapAddr + AlignmentMask) & ~AlignmentMask;
1420
1421 //
1422 // Map the host address of DataBuffer to DMA master address.
1423 //
1424 if (Read) {
1425 PciIoOperation = EfiPciIoOperationBusMasterWrite;
1426 } else {
1427 PciIoOperation = EfiPciIoOperationBusMasterRead;
1428 }
1429
1430 ByteCount = (UINTN)DataLength;
1431 Status = PciIo->Map (
1432 PciIo,
1433 PciIoOperation,
1434 DataBuffer,
1435 &ByteCount,
1436 &BufferMapAddress,
1437 &BufferMap
1438 );
1439 if (EFI_ERROR (Status) || (ByteCount != DataLength)) {
1440 PciIo->Unmap (PciIo, PrdTableMap);
1441 PciIo->FreeBuffer (PciIo, RealPageCount, (VOID *)(UINTN)BaseAddr);
1442 return EFI_OUT_OF_RESOURCES;
1443 }
1444
1445 //
1446 // According to Ata spec, it requires the buffer address and size to be even.
1447 //
1448 ASSERT ((BufferMapAddress & 0x1) == 0);
1449 ASSERT ((ByteCount & 0x1) == 0);
1450
1451 //
1452 // Fill the PRD table with appropriate bus master address of data buffer and data length.
1453 //
1454 ByteRemaining = ByteCount;
1455 TempPrdBaseAddr = (EFI_ATA_DMA_PRD *)(UINTN)PrdTableBaseAddr;
1456 while (ByteRemaining != 0) {
1457 if (ByteRemaining <= 0x10000) {
1458 TempPrdBaseAddr->RegionBaseAddr = (UINT32)((UINTN)BufferMapAddress);
1459 TempPrdBaseAddr->ByteCount = (UINT16)ByteRemaining;
1460 TempPrdBaseAddr->EndOfTable = 0x8000;
1461 break;
1462 }
1463
1464 TempPrdBaseAddr->RegionBaseAddr = (UINT32)((UINTN)BufferMapAddress);
1465 TempPrdBaseAddr->ByteCount = (UINT16)0x0;
1466
1467 ByteRemaining -= 0x10000;
1468 BufferMapAddress += 0x10000;
1469 TempPrdBaseAddr++;
1470 }
1471
1472 //
1473 // Start to enable the DMA operation
1474 //
1475 DeviceHead = AtaCommandBlock->AtaDeviceHead;
1476
1477 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | DeviceHead));
1478
1479 //
1480 // Enable interrupt to support UDMA
1481 //
1482 DeviceControl = 0;
1483 IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
1484
1485 //
1486 // Read BMIS register and clear ERROR and INTR bit
1487 //
1488 RegisterValue = IdeReadPortB (PciIo, IoPortForBmis);
1489 RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
1490 IdeWritePortB (PciIo, IoPortForBmis, RegisterValue);
1491
1492 //
1493 // Set the base address to BMID register
1494 //
1495 IdeWritePortDW (PciIo, IoPortForBmid, (UINT32)PrdTableMapAddr);
1496
1497 //
1498 // Set BMIC register to identify the operation direction
1499 //
1500 RegisterValue = IdeReadPortB (PciIo, IoPortForBmic);
1501 if (Read) {
1502 RegisterValue |= BMIC_NREAD;
1503 } else {
1504 RegisterValue &= ~((UINT8)BMIC_NREAD);
1505 }
1506
1507 IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);
1508
1509 if (Task != NULL) {
1510 Task->Map = BufferMap;
1511 Task->TableMap = PrdTableMap;
1512 Task->MapBaseAddress = (EFI_ATA_DMA_PRD *)(UINTN)BaseAddr;
1513 Task->PageCount = RealPageCount;
1514 Task->IsStart = TRUE;
1515 }
1516
1517 //
1518 // Issue ATA command
1519 //
1520 Status = AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
1521
1522 if (EFI_ERROR (Status)) {
1523 Status = EFI_DEVICE_ERROR;
1524 goto Exit;
1525 }
1526
1527 Status = CheckStatusRegister (PciIo, IdeRegisters);
1528 if (EFI_ERROR (Status)) {
1529 Status = EFI_DEVICE_ERROR;
1530 goto Exit;
1531 }
1532
1533 //
1534 // Set START bit of BMIC register
1535 //
1536 RegisterValue = IdeReadPortB (PciIo, IoPortForBmic);
1537 RegisterValue |= BMIC_START;
1538 IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);
1539 }
1540
1541 //
1542 // Check the INTERRUPT and ERROR bit of BMIS
1543 //
1544 if (Task != NULL) {
1545 Status = AtaUdmStatusCheck (PciIo, Task, IdeRegisters);
1546 } else {
1547 Status = AtaUdmStatusWait (PciIo, IdeRegisters, Timeout);
1548 }
1549
1550 //
1551 // For blocking mode, clear registers and free buffers.
1552 // For non blocking mode, when the related registers have been set or time
1553 // out, or a error has been happened, it needs to clear the register and free
1554 // buffer.
1555 //
1556 if ((Task == NULL) || (Status != EFI_NOT_READY)) {
1557 //
1558 // Read BMIS register and clear ERROR and INTR bit
1559 //
1560 RegisterValue = IdeReadPortB (PciIo, IoPortForBmis);
1561 RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
1562 IdeWritePortB (PciIo, IoPortForBmis, RegisterValue);
1563
1564 //
1565 // Read Status Register of IDE device to clear interrupt
1566 //
1567 RegisterValue = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
1568
1569 //
1570 // Clear START bit of BMIC register
1571 //
1572 RegisterValue = IdeReadPortB (PciIo, IoPortForBmic);
1573 RegisterValue &= ~((UINT8)BMIC_START);
1574 IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);
1575
1576 //
1577 // Disable interrupt of Select device
1578 //
1579 DeviceControl = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1580 DeviceControl |= ATA_CTLREG_IEN_L;
1581 IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
1582 //
1583 // Stall for 10 milliseconds.
1584 //
1585 MicroSecondDelay (10000);
1586 }
1587
1588Exit:
1589 //
1590 // Free all allocated resource
1591 //
1592 if ((Task == NULL) || (Status != EFI_NOT_READY)) {
1593 if (Task != NULL) {
1594 PciIo->Unmap (PciIo, Task->TableMap);
1595 PciIo->FreeBuffer (PciIo, Task->PageCount, Task->MapBaseAddress);
1596 PciIo->Unmap (PciIo, Task->Map);
1597 } else {
1598 PciIo->Unmap (PciIo, PrdTableMap);
1599 PciIo->FreeBuffer (PciIo, RealPageCount, (VOID *)(UINTN)BaseAddr);
1600 PciIo->Unmap (PciIo, BufferMap);
1601 }
1602
1603 //
1604 // Dump All Ide registers to ATA_STATUS_BLOCK
1605 //
1606 DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
1607 }
1608
1609 return Status;
1610}
1611
1623EFIAPI
1625 IN EFI_PCI_IO_PROTOCOL *PciIo,
1626 IN EFI_IDE_REGISTERS *IdeRegisters
1627 )
1628{
1629 UINT8 AltRegister;
1630 UINT16 TempWordBuffer;
1631
1632 AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1633 if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) {
1634 return EFI_NOT_READY;
1635 }
1636
1637 if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
1638 TempWordBuffer = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1639 while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
1641 PciIo,
1642 IdeRegisters->Data,
1643 1,
1644 &TempWordBuffer
1645 );
1646 TempWordBuffer = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1647 }
1648 }
1649
1650 return EFI_SUCCESS;
1651}
1652
1672EFIAPI
1674 IN EFI_PCI_IO_PROTOCOL *PciIo,
1675 IN EFI_IDE_REGISTERS *IdeRegisters,
1676 IN OUT VOID *Buffer,
1677 IN OUT UINT32 *ByteCount,
1678 IN BOOLEAN Read,
1679 IN UINT64 Timeout
1680 )
1681{
1682 UINT32 RequiredWordCount;
1683 UINT32 ActualWordCount;
1684 UINT32 WordCount;
1685 EFI_STATUS Status;
1686 UINT16 *PtrBuffer;
1687
1688 PtrBuffer = Buffer;
1689 RequiredWordCount = *ByteCount >> 1;
1690
1691 //
1692 // No data transfer is permitted.
1693 //
1694 if (RequiredWordCount == 0) {
1695 return EFI_SUCCESS;
1696 }
1697
1698 //
1699 // ActualWordCount means the word count of data really transferred.
1700 //
1701 ActualWordCount = 0;
1702
1703 while (ActualWordCount < RequiredWordCount) {
1704 //
1705 // before each data transfer stream, the host should poll DRQ bit ready,
1706 // to see whether indicates device is ready to transfer data.
1707 //
1708 Status = DRQReady2 (PciIo, IdeRegisters, Timeout);
1709 if (EFI_ERROR (Status)) {
1710 if (Status == EFI_NOT_READY) {
1711 //
1712 // Device provided less data than we intended to read, or wanted less
1713 // data than we intended to write, but it may still be successful.
1714 //
1715 break;
1716 } else {
1717 return Status;
1718 }
1719 }
1720
1721 //
1722 // get current data transfer size from Cylinder Registers.
1723 //
1724 WordCount = IdeReadPortB (PciIo, IdeRegisters->CylinderMsb) << 8;
1725 WordCount = WordCount | IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
1726 WordCount = WordCount & 0xffff;
1727 WordCount /= 2;
1728
1729 WordCount = MIN (WordCount, (RequiredWordCount - ActualWordCount));
1730
1731 if (Read) {
1733 PciIo,
1734 IdeRegisters->Data,
1735 WordCount,
1736 PtrBuffer
1737 );
1738 } else {
1740 PciIo,
1741 IdeRegisters->Data,
1742 WordCount,
1743 PtrBuffer
1744 );
1745 }
1746
1747 //
1748 // read status register to check whether error happens.
1749 //
1750 Status = CheckStatusRegister (PciIo, IdeRegisters);
1751 if (EFI_ERROR (Status)) {
1752 return EFI_DEVICE_ERROR;
1753 }
1754
1755 PtrBuffer += WordCount;
1756 ActualWordCount += WordCount;
1757 }
1758
1759 if (Read) {
1760 //
1761 // In the case where the drive wants to send more data than we need to read,
1762 // the DRQ bit will be set and cause delays from DRQClear2().
1763 // We need to read data from the drive until it clears DRQ so we can move on.
1764 //
1765 AtaPacketReadPendingData (PciIo, IdeRegisters);
1766 }
1767
1768 //
1769 // read status register to check whether error happens.
1770 //
1771 Status = CheckStatusRegister (PciIo, IdeRegisters);
1772 if (EFI_ERROR (Status)) {
1773 return EFI_DEVICE_ERROR;
1774 }
1775
1776 //
1777 // After data transfer is completed, normally, DRQ bit should clear.
1778 //
1779 Status = DRQClear (PciIo, IdeRegisters, Timeout);
1780 if (EFI_ERROR (Status)) {
1781 return EFI_DEVICE_ERROR;
1782 }
1783
1784 *ByteCount = ActualWordCount << 1;
1785 return Status;
1786}
1787
1805EFIAPI
1807 IN EFI_PCI_IO_PROTOCOL *PciIo,
1808 IN EFI_IDE_REGISTERS *IdeRegisters,
1809 IN UINT8 Channel,
1810 IN UINT8 Device,
1812 )
1813{
1814 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1815 EFI_STATUS Status;
1816 UINT8 Count;
1817 UINT8 PacketCommand[12];
1818
1819 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1820
1821 //
1822 // Fill ATAPI Command Packet according to CDB.
1823 // For Atapi cmd, its length should be less than or equal to 12 bytes.
1824 //
1825 if (Packet->CdbLength > 12) {
1826 return EFI_INVALID_PARAMETER;
1827 }
1828
1829 ZeroMem (PacketCommand, 12);
1830 CopyMem (PacketCommand, Packet->Cdb, Packet->CdbLength);
1831
1832 //
1833 // No OVL; No DMA
1834 //
1835 AtaCommandBlock.AtaFeatures = 0x00;
1836 //
1837 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
1838 // determine how many data should be transferred.
1839 //
1840 AtaCommandBlock.AtaCylinderLow = (UINT8)(ATAPI_MAX_BYTE_COUNT & 0x00ff);
1841 AtaCommandBlock.AtaCylinderHigh = (UINT8)(ATAPI_MAX_BYTE_COUNT >> 8);
1842 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
1843 AtaCommandBlock.AtaCommand = ATA_CMD_PACKET;
1844
1845 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | (Device << 0x4)));
1846 //
1847 // Disable interrupt
1848 //
1849 IdeWritePortB (PciIo, IdeRegisters->AltOrDev, ATA_DEFAULT_CTL);
1850
1851 //
1852 // Issue ATA PACKET command firstly
1853 //
1854 Status = AtaIssueCommand (PciIo, IdeRegisters, &AtaCommandBlock, Packet->Timeout);
1855 if (EFI_ERROR (Status)) {
1856 return Status;
1857 }
1858
1859 Status = DRQReady (PciIo, IdeRegisters, Packet->Timeout);
1860 if (EFI_ERROR (Status)) {
1861 return Status;
1862 }
1863
1864 //
1865 // Send out ATAPI command packet
1866 //
1867 for (Count = 0; Count < 6; Count++) {
1868 IdeWritePortW (PciIo, IdeRegisters->Data, *((UINT16 *)PacketCommand + Count));
1869 //
1870 // Stall for 10 microseconds.
1871 //
1872 MicroSecondDelay (10);
1873 }
1874
1875 //
1876 // Read/Write the data of ATAPI Command
1877 //
1878 if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
1879 Status = AtaPacketReadWrite (
1880 PciIo,
1881 IdeRegisters,
1882 Packet->InDataBuffer,
1883 &Packet->InTransferLength,
1884 TRUE,
1885 Packet->Timeout
1886 );
1887 } else {
1888 Status = AtaPacketReadWrite (
1889 PciIo,
1890 IdeRegisters,
1891 Packet->OutDataBuffer,
1892 &Packet->OutTransferLength,
1893 FALSE,
1894 Packet->Timeout
1895 );
1896 }
1897
1898 return Status;
1899}
1900
1916EFIAPI
1919 IN UINT8 Channel,
1920 IN UINT8 Device,
1921 IN EFI_ATA_TRANSFER_MODE *TransferMode,
1922 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
1923 )
1924{
1925 EFI_STATUS Status;
1926 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1927
1928 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1929
1930 AtaCommandBlock.AtaCommand = ATA_CMD_SET_FEATURES;
1931 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
1932 AtaCommandBlock.AtaFeatures = 0x03;
1933 AtaCommandBlock.AtaSectorCount = *((UINT8 *)TransferMode);
1934
1935 //
1936 // Send SET FEATURE command (sub command 0x03) to set pio mode.
1937 //
1938 Status = AtaNonDataCommandIn (
1939 Instance->PciIo,
1940 &Instance->IdeRegisters[Channel],
1941 &AtaCommandBlock,
1942 AtaStatusBlock,
1943 ATA_ATAPI_TIMEOUT,
1944 NULL
1945 );
1946
1947 return Status;
1948}
1949
1965EFIAPI
1968 IN UINT8 Channel,
1969 IN UINT8 Device,
1970 IN EFI_ATA_DRIVE_PARMS *DriveParameters,
1971 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
1972 )
1973{
1974 EFI_STATUS Status;
1975 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1976
1977 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1978
1979 AtaCommandBlock.AtaCommand = ATA_CMD_INIT_DRIVE_PARAM;
1980 AtaCommandBlock.AtaSectorCount = DriveParameters->Sector;
1981 AtaCommandBlock.AtaDeviceHead = (UINT8)((Device << 0x4) + DriveParameters->Heads);
1982
1983 //
1984 // Send Init drive parameters
1985 //
1986 Status = AtaNonDataCommandIn (
1987 Instance->PciIo,
1988 &Instance->IdeRegisters[Channel],
1989 &AtaCommandBlock,
1990 AtaStatusBlock,
1991 ATA_ATAPI_TIMEOUT,
1992 NULL
1993 );
1994
1995 if (EFI_ERROR (Status)) {
1996 DEBUG ((DEBUG_WARN, "Init Drive Parameters Fail, Status = %r\n", Status));
1997 }
1998
1999 //
2000 // Send Set Multiple parameters
2001 //
2002 AtaCommandBlock.AtaCommand = ATA_CMD_SET_MULTIPLE_MODE;
2003 AtaCommandBlock.AtaSectorCount = DriveParameters->MultipleSector;
2004 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
2005
2006 Status = AtaNonDataCommandIn (
2007 Instance->PciIo,
2008 &Instance->IdeRegisters[Channel],
2009 &AtaCommandBlock,
2010 AtaStatusBlock,
2011 ATA_ATAPI_TIMEOUT,
2012 NULL
2013 );
2014
2015 if (EFI_ERROR (Status)) {
2016 DEBUG ((DEBUG_WARN, "Set Multiple Mode Parameters Fail, Status = %r\n", Status));
2017 }
2018
2019 return Status;
2020}
2021
2035EFIAPI
2038 IN UINT8 Channel,
2039 IN UINT8 Device,
2040 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
2041 )
2042{
2043 EFI_STATUS Status;
2044 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2045 UINT8 LBAMid;
2046 UINT8 LBAHigh;
2047
2048 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2049
2050 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
2051 AtaCommandBlock.AtaFeatures = ATA_SMART_RETURN_STATUS;
2052 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
2053 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
2054 AtaCommandBlock.AtaDeviceHead = (UINT8)((Device << 0x4) | 0xe0);
2055
2056 //
2057 // Send S.M.A.R.T Read Return Status command to device
2058 //
2059 Status = AtaNonDataCommandIn (
2060 Instance->PciIo,
2061 &Instance->IdeRegisters[Channel],
2062 &AtaCommandBlock,
2063 AtaStatusBlock,
2064 ATA_ATAPI_TIMEOUT,
2065 NULL
2066 );
2067
2068 if (EFI_ERROR (Status)) {
2070 EFI_ERROR_CODE | EFI_ERROR_MINOR,
2071 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)
2072 );
2073 return EFI_DEVICE_ERROR;
2074 }
2075
2078 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)
2079 );
2080
2081 LBAMid = IdeReadPortB (Instance->PciIo, Instance->IdeRegisters[Channel].CylinderLsb);
2082 LBAHigh = IdeReadPortB (Instance->PciIo, Instance->IdeRegisters[Channel].CylinderMsb);
2083
2084 if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {
2085 //
2086 // The threshold exceeded condition is not detected by the device
2087 //
2088 DEBUG ((DEBUG_INFO, "The S.M.A.R.T threshold exceeded condition is not detected\n"));
2091 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)
2092 );
2093 } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {
2094 //
2095 // The threshold exceeded condition is detected by the device
2096 //
2097 DEBUG ((DEBUG_INFO, "The S.M.A.R.T threshold exceeded condition is detected\n"));
2100 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)
2101 );
2102 }
2103
2104 return EFI_SUCCESS;
2105}
2106
2117VOID
2118EFIAPI
2121 IN UINT8 Channel,
2122 IN UINT8 Device,
2123 IN EFI_IDENTIFY_DATA *IdentifyData,
2124 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
2125 )
2126{
2127 EFI_STATUS Status;
2128 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2129
2130 //
2131 // Detect if the device supports S.M.A.R.T.
2132 //
2133 if ((IdentifyData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {
2134 //
2135 // S.M.A.R.T is not supported by the device
2136 //
2137 DEBUG ((
2138 DEBUG_INFO,
2139 "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n",
2140 (Channel == 1) ? "secondary" : "primary",
2141 (Device == 1) ? "slave" : "master"
2142 ));
2144 EFI_ERROR_CODE | EFI_ERROR_MINOR,
2145 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)
2146 );
2147 } else {
2148 //
2149 // Check if the feature is enabled. If not, then enable S.M.A.R.T.
2150 //
2151 if ((IdentifyData->AtaData.command_set_feature_enb_85 & 0x0001) != 0x0001) {
2154 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLE)
2155 );
2156
2157 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2158
2159 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
2160 AtaCommandBlock.AtaFeatures = ATA_SMART_ENABLE_OPERATION;
2161 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
2162 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
2163 AtaCommandBlock.AtaDeviceHead = (UINT8)((Device << 0x4) | 0xe0);
2164
2165 //
2166 // Send S.M.A.R.T Enable command to device
2167 //
2168 Status = AtaNonDataCommandIn (
2169 Instance->PciIo,
2170 &Instance->IdeRegisters[Channel],
2171 &AtaCommandBlock,
2172 AtaStatusBlock,
2173 ATA_ATAPI_TIMEOUT,
2174 NULL
2175 );
2176
2177 if (!EFI_ERROR (Status)) {
2178 //
2179 // Send S.M.A.R.T AutoSave command to device
2180 //
2181 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2182
2183 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
2184 AtaCommandBlock.AtaFeatures = 0xD2;
2185 AtaCommandBlock.AtaSectorCount = 0xF1;
2186 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
2187 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
2188 AtaCommandBlock.AtaDeviceHead = (UINT8)((Device << 0x4) | 0xe0);
2189
2190 Status = AtaNonDataCommandIn (
2191 Instance->PciIo,
2192 &Instance->IdeRegisters[Channel],
2193 &AtaCommandBlock,
2194 AtaStatusBlock,
2195 ATA_ATAPI_TIMEOUT,
2196 NULL
2197 );
2198 if (!EFI_ERROR (Status)) {
2200 Instance,
2201 Channel,
2202 Device,
2203 AtaStatusBlock
2204 );
2205 }
2206 }
2207 }
2208
2209 DEBUG ((
2210 DEBUG_INFO,
2211 "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n",
2212 (Channel == 1) ? "secondary" : "primary",
2213 (Device == 1) ? "slave" : "master"
2214 ));
2215 }
2216
2217 return;
2218}
2219
2243EFIAPI
2246 IN UINT8 Channel,
2247 IN UINT8 Device,
2248 IN OUT EFI_IDENTIFY_DATA *Buffer,
2249 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
2250 )
2251{
2252 EFI_STATUS Status;
2253 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2254
2255 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2256
2257 AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
2258 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
2259
2260 Status = AtaPioDataInOut (
2261 Instance->PciIo,
2262 &Instance->IdeRegisters[Channel],
2263 Buffer,
2264 sizeof (EFI_IDENTIFY_DATA),
2265 TRUE,
2266 &AtaCommandBlock,
2267 AtaStatusBlock,
2268 ATA_ATAPI_TIMEOUT,
2269 NULL
2270 );
2271
2272 return Status;
2273}
2274
2308EFIAPI
2311 IN UINT8 Channel,
2312 IN UINT8 Device,
2313 IN OUT EFI_IDENTIFY_DATA *Buffer,
2314 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
2315 )
2316{
2317 EFI_STATUS Status;
2318 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2319
2320 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2321
2322 AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DEVICE;
2323 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
2324
2325 //
2326 // Send ATAPI Identify Command to get IDENTIFY data.
2327 //
2328 Status = AtaPioDataInOut (
2329 Instance->PciIo,
2330 &Instance->IdeRegisters[Channel],
2331 (VOID *)Buffer,
2332 sizeof (EFI_IDENTIFY_DATA),
2333 TRUE,
2334 &AtaCommandBlock,
2335 AtaStatusBlock,
2336 ATA_ATAPI_TIMEOUT,
2337 NULL
2338 );
2339
2340 return Status;
2341}
2342
2366EFIAPI
2369 IN UINT8 IdeChannel
2370 )
2371{
2372 EFI_STATUS Status;
2373 UINT8 SectorCountReg;
2374 UINT8 LBALowReg;
2375 UINT8 LBAMidReg;
2376 UINT8 LBAHighReg;
2377 EFI_ATA_DEVICE_TYPE DeviceType;
2378 UINT8 IdeDevice;
2379 EFI_IDE_REGISTERS *IdeRegisters;
2380 EFI_IDENTIFY_DATA Buffer;
2381
2383 EFI_PCI_IO_PROTOCOL *PciIo;
2384
2385 EFI_ATA_COLLECTIVE_MODE *SupportedModes;
2386 EFI_ATA_TRANSFER_MODE TransferMode;
2387 EFI_ATA_DRIVE_PARMS DriveParameters;
2388
2389 IdeRegisters = &Instance->IdeRegisters[IdeChannel];
2390 IdeInit = Instance->IdeControllerInit;
2391 PciIo = Instance->PciIo;
2392
2393 for (IdeDevice = 0; IdeDevice < EfiIdeMaxDevice; IdeDevice++) {
2394 //
2395 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2396 //
2397 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)((IdeDevice << 4) | 0xe0));
2398
2399 //
2400 // Send ATA Device Execut Diagnostic command.
2401 // This command should work no matter DRDY is ready or not
2402 //
2403 IdeWritePortB (PciIo, IdeRegisters->CmdOrStatus, ATA_CMD_EXEC_DRIVE_DIAG);
2404
2405 Status = WaitForBSYClear (PciIo, IdeRegisters, 350000000);
2406 if (EFI_ERROR (Status)) {
2407 DEBUG ((DEBUG_ERROR, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status));
2408 continue;
2409 }
2410
2411 //
2412 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2413 //
2414 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)((IdeDevice << 4) | 0xe0));
2415 //
2416 // Stall for 1 milliseconds.
2417 //
2418 MicroSecondDelay (1000);
2419
2420 SectorCountReg = IdeReadPortB (PciIo, IdeRegisters->SectorCount);
2421 LBALowReg = IdeReadPortB (PciIo, IdeRegisters->SectorNumber);
2422 LBAMidReg = IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
2423 LBAHighReg = IdeReadPortB (PciIo, IdeRegisters->CylinderMsb);
2424
2425 //
2426 // Refer to ATA/ATAPI 4 Spec, section 9.1
2427 //
2428 if ((SectorCountReg == 0x1) && (LBALowReg == 0x1) && (LBAMidReg == 0x0) && (LBAHighReg == 0x0)) {
2429 DeviceType = EfiIdeHarddisk;
2430 } else if ((LBAMidReg == 0x14) && (LBAHighReg == 0xeb)) {
2431 DeviceType = EfiIdeCdrom;
2432 } else {
2433 continue;
2434 }
2435
2436 //
2437 // Send IDENTIFY cmd to the device to test if it is really attached.
2438 //
2439 if (DeviceType == EfiIdeHarddisk) {
2440 Status = AtaIdentify (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
2441 //
2442 // if identifying ata device is failure, then try to send identify packet cmd.
2443 //
2444 if (EFI_ERROR (Status)) {
2445 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_EC_NOT_DETECTED));
2446
2447 DeviceType = EfiIdeCdrom;
2448 Status = AtaIdentifyPacket (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
2449 }
2450 } else {
2451 Status = AtaIdentifyPacket (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
2452 //
2453 // if identifying atapi device is failure, then try to send identify cmd.
2454 //
2455 if (EFI_ERROR (Status)) {
2456 DeviceType = EfiIdeHarddisk;
2457 Status = AtaIdentify (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
2458 }
2459 }
2460
2461 if (EFI_ERROR (Status)) {
2462 //
2463 // No device is found at this port
2464 //
2465 continue;
2466 }
2467
2468 DEBUG ((
2469 DEBUG_INFO,
2470 "[%a] channel [%a] [%a] device\n",
2471 (IdeChannel == 1) ? "secondary" : "primary ",
2472 (IdeDevice == 1) ? "slave " : "master",
2473 DeviceType == EfiIdeCdrom ? "cdrom " : "harddisk"
2474 ));
2475 //
2476 // If the device is a hard disk, then try to enable S.M.A.R.T feature
2477 //
2478 if ((DeviceType == EfiIdeHarddisk) && PcdGetBool (PcdAtaSmartEnable)) {
2480 Instance,
2481 IdeChannel,
2482 IdeDevice,
2483 &Buffer,
2484 NULL
2485 );
2486 }
2487
2488 //
2489 // Submit identify data to IDE controller init driver
2490 //
2491 IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &Buffer);
2492
2493 //
2494 // Now start to config ide device parameter and transfer mode.
2495 //
2496 Status = IdeInit->CalculateMode (
2497 IdeInit,
2498 IdeChannel,
2499 IdeDevice,
2500 &SupportedModes
2501 );
2502 if (EFI_ERROR (Status)) {
2503 DEBUG ((DEBUG_ERROR, "Calculate Mode Fail, Status = %r\n", Status));
2504 continue;
2505 }
2506
2507 //
2508 // Set best supported PIO mode on this IDE device
2509 //
2510 if (SupportedModes->PioMode.Mode <= EfiAtaPioMode2) {
2511 TransferMode.ModeCategory = EFI_ATA_MODE_DEFAULT_PIO;
2512 } else {
2513 TransferMode.ModeCategory = EFI_ATA_MODE_FLOW_PIO;
2514 }
2515
2516 TransferMode.ModeNumber = (UINT8)(SupportedModes->PioMode.Mode);
2517
2518 if (SupportedModes->ExtModeCount == 0) {
2519 Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
2520
2521 if (EFI_ERROR (Status)) {
2522 DEBUG ((DEBUG_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
2523 continue;
2524 }
2525 }
2526
2527 //
2528 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA can't
2529 // be set together. Only one DMA mode can be set to a device. If setting
2530 // DMA mode operation fails, we can continue moving on because we only use
2531 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
2532 //
2533 if (SupportedModes->UdmaMode.Valid) {
2534 TransferMode.ModeCategory = EFI_ATA_MODE_UDMA;
2535 TransferMode.ModeNumber = (UINT8)(SupportedModes->UdmaMode.Mode);
2536 Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
2537
2538 if (EFI_ERROR (Status)) {
2539 DEBUG ((DEBUG_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
2540 continue;
2541 }
2542 } else if (SupportedModes->MultiWordDmaMode.Valid) {
2543 TransferMode.ModeCategory = EFI_ATA_MODE_MDMA;
2544 TransferMode.ModeNumber = (UINT8)SupportedModes->MultiWordDmaMode.Mode;
2545 Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
2546
2547 if (EFI_ERROR (Status)) {
2548 DEBUG ((DEBUG_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
2549 continue;
2550 }
2551 }
2552
2553 //
2554 // Set Parameters for the device:
2555 // 1) Init
2556 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
2557 //
2558 if (DeviceType == EfiIdeHarddisk) {
2559 //
2560 // Init drive parameters
2561 //
2562 DriveParameters.Sector = (UINT8)((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->sectors_per_track;
2563 DriveParameters.Heads = (UINT8)(((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->heads - 1);
2564 DriveParameters.MultipleSector = (UINT8)((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->multi_sector_cmd_max_sct_cnt;
2565
2566 SetDriveParameters (Instance, IdeChannel, IdeDevice, &DriveParameters, NULL);
2567 }
2568
2569 //
2570 // Set IDE controller Timing Blocks in the PCI Configuration Space
2571 //
2572 IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);
2573
2574 //
2575 // IDE controller and IDE device timing is configured successfully.
2576 // Now insert the device into device list.
2577 //
2578 Status = CreateNewDeviceInfo (Instance, IdeChannel, IdeDevice, DeviceType, &Buffer);
2579 if (EFI_ERROR (Status)) {
2580 continue;
2581 }
2582
2583 if (DeviceType == EfiIdeHarddisk) {
2584 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_ENABLE));
2585 }
2586 }
2587
2588 return EFI_SUCCESS;
2589}
2590
2600EFIAPI
2603 )
2604{
2605 EFI_STATUS Status;
2607 EFI_PCI_IO_PROTOCOL *PciIo;
2608 UINT8 Channel;
2609 UINT8 IdeChannel;
2610 BOOLEAN ChannelEnabled;
2611 UINT8 MaxDevices;
2612
2613 IdeInit = Instance->IdeControllerInit;
2614 PciIo = Instance->PciIo;
2615 Channel = IdeInit->ChannelCount;
2616
2617 //
2618 // Obtain IDE IO port registers' base addresses
2619 //
2620 Status = GetIdeRegisterIoAddr (PciIo, Instance->IdeRegisters);
2621 if (EFI_ERROR (Status)) {
2622 goto ErrorExit;
2623 }
2624
2625 for (IdeChannel = 0; IdeChannel < Channel; IdeChannel++) {
2626 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);
2627
2628 //
2629 // now obtain channel information fron IdeControllerInit protocol.
2630 //
2631 Status = IdeInit->GetChannelInfo (
2632 IdeInit,
2633 IdeChannel,
2634 &ChannelEnabled,
2635 &MaxDevices
2636 );
2637 if (EFI_ERROR (Status)) {
2638 DEBUG ((DEBUG_ERROR, "[GetChannel, Status=%x]", Status));
2639 continue;
2640 }
2641
2642 if (!ChannelEnabled) {
2643 continue;
2644 }
2645
2646 ASSERT (MaxDevices <= 2);
2647 //
2648 // Now inform the IDE Controller Init Module.
2649 //
2650 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);
2651
2652 //
2653 // No reset channel function implemented.
2654 //
2655 IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);
2656
2657 //
2658 // Now inform the IDE Controller Init Module.
2659 //
2660 IdeInit->NotifyPhase (IdeInit, EfiIdeBusBeforeDevicePresenceDetection, IdeChannel);
2661
2662 //
2663 // Detect all attached ATA devices and set the transfer mode for each device.
2664 //
2665 DetectAndConfigIdeDevice (Instance, IdeChannel);
2666 }
2667
2668 //
2669 // All configurations done! Notify IdeController to do post initialization
2670 // work such as saving IDE controller PCI settings for S3 resume
2671 //
2672 IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);
2673
2674ErrorExit:
2675 return Status;
2676}
UINT64 UINTN
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
VOID EFIAPI AsyncNonBlockingTransferRoutine(EFI_EVENT Event, VOID *Context)
EFI_STATUS EFIAPI CreateNewDeviceInfo(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT16 Port, IN UINT16 PortMultiplier, IN EFI_ATA_DEVICE_TYPE DeviceType, IN EFI_IDENTIFY_DATA *IdentifyData)
#define ATA_SMART_ENABLE_OPERATION
reserved
Definition: Atapi.h:655
#define ATA_CMD_SET_FEATURES
defined from ATA-1
Definition: Atapi.h:589
#define ATA_CTLREG_IEN_L
Interrupt Enable #.
Definition: Atapi.h:847
#define ATA_SMART_RETURN_STATUS
defined from ATA-3
Definition: Atapi.h:657
#define ATA_CONSTANT_C2
reserved
Definition: Atapi.h:632
#define ATA_STSREG_BSY
Controller Busy defined from ATA-1.
Definition: Atapi.h:833
#define ATA_ERRREG_ABRT
Aborted Command defined from ATA-1.
Definition: Atapi.h:826
#define ATA_STSREG_DRQ
Data Request defined from ATA-1.
Definition: Atapi.h:838
#define ATA_CMD_SMART
defined from ATA-3
Definition: Atapi.h:631
#define ATA_STSREG_DWF
Drive Write Fault defined from ATA-1, obsoleted from ATA-4.
Definition: Atapi.h:835
#define ATA_DEFAULT_CTL
Definition: Atapi.h:760
#define ATA_STSREG_ERR
Error defined from ATA-1.
Definition: Atapi.h:841
#define ATA_ERRREG_MC
Media Change defined from ATA-1, obsoleted from ATA-4.
Definition: Atapi.h:823
#define ATA_CMD_IDENTIFY_DRIVE
defined from ATA-3
Definition: Atapi.h:542
#define ATA_ERRREG_TK0NF
Track 0 Not Found defined from ATA-1, obsoleted from ATA-4.
Definition: Atapi.h:827
#define ATA_CMD_EXEC_DRIVE_DIAG
defined from ATA-1
Definition: Atapi.h:577
#define ATA_ERRREG_UNC
Uncorrectable Data defined from ATA-1, obsoleted from ATA-4.
Definition: Atapi.h:822
#define ATA_ERRREG_AMNF
Address Mark Not Found defined from ATA-1, obsoleted from ATA-4.
Definition: Atapi.h:828
#define ATA_CMD_INIT_DRIVE_PARAM
defined from ATA-1, obsoleted from ATA-6
Definition: Atapi.h:582
#define ATA_CMD_SET_MULTIPLE_MODE
defined from ATA-2
Definition: Atapi.h:585
#define ATA_STSREG_CORR
Corrected Data defined from ATA-1, obsoleted from ATA-4.
Definition: Atapi.h:839
#define ATA_CONSTANT_4F
reserved
Definition: Atapi.h:633
#define ATA_ERRREG_BBK
Bad block detected defined from ATA-1, obsoleted from ATA-2.
Definition: Atapi.h:821
#define ATA_CMD_IDENTIFY_DEVICE
defined from ATA-3
Definition: Atapi.h:488
#define ATA_CMD_PACKET
defined from ATA-3
Definition: Atapi.h:487
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
@ EfiIdeBeforeChannelReset
@ EfiIdeAfterChannelReset
@ EfiIdeBeforeChannelEnumeration
@ EfiIdeBusBeforeDevicePresenceDetection
EFI_STATUS EFIAPI DetectAndConfigIdeDevice(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT8 IdeChannel)
Definition: IdeMode.c:2367
VOID EFIAPI IdeWritePortDW(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT16 Port, IN UINT32 Data)
Definition: IdeMode.c:114
EFI_STATUS EFIAPI AtaPioDataInOut(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN OUT VOID *Buffer, IN UINT64 ByteCount, IN BOOLEAN Read, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN UINT64 Timeout, IN ATA_NONBLOCK_TASK *Task)
Definition: IdeMode.c:934
EFI_STATUS EFIAPI AtaIdentifyPacket(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT8 Channel, IN UINT8 Device, IN OUT EFI_IDENTIFY_DATA *Buffer, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock)
Definition: IdeMode.c:2309
EFI_STATUS EFIAPI AtaPacketReadPendingData(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters)
Definition: IdeMode.c:1624
VOID EFIAPI IdeAtaSmartSupport(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT8 Channel, IN UINT8 Device, IN EFI_IDENTIFY_DATA *IdentifyData, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock)
Definition: IdeMode.c:2119
EFI_STATUS EFIAPI DRQReady(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT64 Timeout)
Definition: IdeMode.c:481
UINT8 EFIAPI IdeReadPortB(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT16 Port)
Definition: IdeMode.c:21
EFI_STATUS EFIAPI GetIdeRegisterIoAddr(IN EFI_PCI_IO_PROTOCOL *PciIo, IN OUT EFI_IDE_REGISTERS *IdeRegisters)
Definition: IdeMode.c:728
EFI_STATUS EFIAPI DRQReady2(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT64 Timeout)
Definition: IdeMode.c:567
EFI_STATUS EFIAPI AtaPacketCommandExecute(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT8 Channel, IN UINT8 Device, IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet)
Definition: IdeMode.c:1806
EFI_STATUS EFIAPI WaitForBSYClear(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT64 Timeout)
Definition: IdeMode.c:641
EFI_STATUS EFIAPI SetDeviceTransferMode(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT8 Channel, IN UINT8 Device, IN EFI_ATA_TRANSFER_MODE *TransferMode, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock)
Definition: IdeMode.c:1917
EFI_STATUS EFIAPI AtaNonDataCommandIn(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN UINT64 Timeout, IN ATA_NONBLOCK_TASK *Task)
Definition: IdeMode.c:1069
VOID EFIAPI IdeWritePortWMultiple(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT16 Port, IN UINTN Count, IN VOID *Buffer)
Definition: IdeMode.c:148
VOID EFIAPI IdeWritePortB(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT16 Port, IN UINT8 Data)
Definition: IdeMode.c:54
EFI_STATUS EFIAPI IdeAtaSmartReturnStatusCheck(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT8 Channel, IN UINT8 Device, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock)
Definition: IdeMode.c:2036
EFI_STATUS EFIAPI AtaIdentify(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT8 Channel, IN UINT8 Device, IN OUT EFI_IDENTIFY_DATA *Buffer, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock)
Definition: IdeMode.c:2244
EFI_STATUS EFIAPI DRQClear2(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT64 Timeout)
Definition: IdeMode.c:407
EFI_STATUS AtaUdmStatusCheck(IN EFI_PCI_IO_PROTOCOL *PciIo, IN ATA_NONBLOCK_TASK *Task, IN EFI_IDE_REGISTERS *IdeRegisters)
Definition: IdeMode.c:1198
VOID EFIAPI DumpAllIdeRegisters(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock)
Definition: IdeMode.c:219
VOID EFIAPI IdeReadPortWMultiple(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT16 Port, IN UINTN Count, IN VOID *Buffer)
Definition: IdeMode.c:184
EFI_STATUS EFIAPI AtaIssueCommand(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN UINT64 Timeout)
Definition: IdeMode.c:836
EFI_STATUS EFIAPI AtaUdmaInOut(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN EFI_IDE_REGISTERS *IdeRegisters, IN BOOLEAN Read, IN VOID *DataBuffer, IN UINT64 DataLength, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN UINT64 Timeout, IN ATA_NONBLOCK_TASK *Task)
Definition: IdeMode.c:1263
EFI_STATUS EFIAPI AtaPacketReadWrite(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN OUT VOID *Buffer, IN OUT UINT32 *ByteCount, IN BOOLEAN Read, IN UINT64 Timeout)
Definition: IdeMode.c:1673
EFI_STATUS EFIAPI SetDriveParameters(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT8 Channel, IN UINT8 Device, IN EFI_ATA_DRIVE_PARMS *DriveParameters, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock)
Definition: IdeMode.c:1966
EFI_STATUS EFIAPI IdeModeInitialization(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance)
Definition: IdeMode.c:2601
EFI_STATUS EFIAPI DRQClear(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT64 Timeout)
Definition: IdeMode.c:344
EFI_STATUS AtaUdmStatusWait(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT64 Timeout)
Definition: IdeMode.c:1133
EFI_STATUS EFIAPI CheckStatusRegister(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters)
Definition: IdeMode.c:302
VOID EFIAPI IdeWritePortW(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT16 Port, IN UINT16 Data)
Definition: IdeMode.c:84
#define NULL
Definition: Base.h:319
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
#define REPORT_STATUS_CODE(Type, Value)
#define EFI_PCI_IO_PASS_THROUGH_BAR
Special BAR that passes a memory or I/O cycle through unchanged.
Definition: PciIo.h:47
EFI_PCI_IO_PROTOCOL_OPERATION
Definition: PciIo.h:77
@ EfiPciIoOperationBusMasterWrite
Definition: PciIo.h:85
@ EfiPciIoOperationBusMasterRead
Definition: PciIo.h:81
@ EfiPciIoOperationBusMasterCommonBuffer
Definition: PciIo.h:90
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
#define EFI_ERROR_MINOR
Definition: PiStatusCode.h:58
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:43
VOID EFIAPI Exit(IN EFI_STATUS Status)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
UINTN EFI_TPL
Definition: UefiBaseType.h:41
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EfiBootServicesData
@ AllocateAnyPages
Definition: UefiSpec.h:33
EFI_IDE_CONTROLLER_SUBMIT_DATA SubmitData
EFI_IDE_CONTROLLER_SET_TIMING SetTiming
EFI_IDE_CONTROLLER_CALCULATE_MODE CalculateMode
EFI_IDE_CONTROLLER_NOTIFY_PHASE NotifyPhase
EFI_IDE_CONTROLLER_GET_CHANNEL_INFO GetChannelInfo
UINT32 Mode
The actual ATA mode. This field is not a bit map.
BOOLEAN Valid
TRUE if Mode is valid.
EFI_ATA_IDENTIFY_DATA AtaData