TianoCore EDK2 master
Loading...
Searching...
No Matches
AtapiPeim.c
Go to the documentation of this file.
1
15#include "AtapiPeim.h"
16
28EFIAPI
30 IN EFI_PEI_FILE_HANDLE FileHandle,
31 IN CONST EFI_PEI_SERVICES **PeiServices
32 )
33{
34 PEI_ATA_CONTROLLER_PPI *AtaControllerPpi;
35 EFI_STATUS Status;
36 ATAPI_BLK_IO_DEV *AtapiBlkIoDev;
37
38 Status = PeiServicesRegisterForShadow (FileHandle);
39 if (!EFI_ERROR (Status)) {
40 return Status;
41 }
42
43 Status = PeiServicesLocatePpi (
44 &gPeiAtaControllerPpiGuid,
45 0,
46 NULL,
47 (VOID **)&AtaControllerPpi
48 );
49 ASSERT_EFI_ERROR (Status);
50
51 AtapiBlkIoDev = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (*AtapiBlkIoDev)));
52 if (AtapiBlkIoDev == NULL) {
53 return EFI_OUT_OF_RESOURCES;
54 }
55
56 AtapiBlkIoDev->Signature = ATAPI_BLK_IO_DEV_SIGNATURE;
57 AtapiBlkIoDev->AtaControllerPpi = AtaControllerPpi;
58
59 //
60 // atapi device enumeration and build private data
61 //
62 AtapiEnumerateDevices (AtapiBlkIoDev);
63
64 AtapiBlkIoDev->AtapiBlkIo.GetNumberOfBlockDevices = AtapiGetNumberOfBlockDevices;
65 AtapiBlkIoDev->AtapiBlkIo.GetBlockDeviceMediaInfo = AtapiGetBlockDeviceMediaInfo;
66 AtapiBlkIoDev->AtapiBlkIo.ReadBlocks = AtapiReadBlocks;
67 AtapiBlkIoDev->AtapiBlkIo2.Revision = EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION;
68 AtapiBlkIoDev->AtapiBlkIo2.GetNumberOfBlockDevices = AtapiGetNumberOfBlockDevices2;
69 AtapiBlkIoDev->AtapiBlkIo2.GetBlockDeviceMediaInfo = AtapiGetBlockDeviceMediaInfo2;
70 AtapiBlkIoDev->AtapiBlkIo2.ReadBlocks = AtapiReadBlocks2;
71
72 AtapiBlkIoDev->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI;
73 AtapiBlkIoDev->PpiDescriptor.Guid = &gEfiPeiVirtualBlockIoPpiGuid;
74 AtapiBlkIoDev->PpiDescriptor.Ppi = &AtapiBlkIoDev->AtapiBlkIo;
75
76 AtapiBlkIoDev->PpiDescriptor2.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
77 AtapiBlkIoDev->PpiDescriptor2.Guid = &gEfiPeiVirtualBlockIo2PpiGuid;
78 AtapiBlkIoDev->PpiDescriptor2.Ppi = &AtapiBlkIoDev->AtapiBlkIo2;
79
80 DEBUG ((DEBUG_INFO, "Atatpi Device Count is %d\n", AtapiBlkIoDev->DeviceCount));
81 if (AtapiBlkIoDev->DeviceCount != 0) {
82 Status = PeiServicesInstallPpi (&AtapiBlkIoDev->PpiDescriptor);
83 if (EFI_ERROR (Status)) {
84 return EFI_OUT_OF_RESOURCES;
85 }
86 }
87
88 return EFI_SUCCESS;
89}
90
111EFIAPI
113 IN EFI_PEI_SERVICES **PeiServices,
115 OUT UINTN *NumberBlockDevices
116 )
117{
118 ATAPI_BLK_IO_DEV *AtapiBlkIoDev;
119
120 AtapiBlkIoDev = NULL;
121
122 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO_THIS (This);
123
124 *NumberBlockDevices = AtapiBlkIoDev->DeviceCount;
125
126 return EFI_SUCCESS;
127}
128
158EFIAPI
160 IN EFI_PEI_SERVICES **PeiServices,
162 IN UINTN DeviceIndex,
163 OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo
164 )
165{
166 UINTN DeviceCount;
167 ATAPI_BLK_IO_DEV *AtapiBlkIoDev;
168 EFI_STATUS Status;
169 UINTN Index;
170
171 AtapiBlkIoDev = NULL;
172
173 if ((This == NULL) || (MediaInfo == NULL)) {
174 return EFI_INVALID_PARAMETER;
175 }
176
177 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO_THIS (This);
178
179 DeviceCount = AtapiBlkIoDev->DeviceCount;
180
181 //
182 // DeviceIndex is a value from 1 to NumberBlockDevices.
183 //
184 if ((DeviceIndex < 1) || (DeviceIndex > DeviceCount) || (DeviceIndex > MAX_IDE_DEVICES)) {
185 return EFI_INVALID_PARAMETER;
186 }
187
188 Index = DeviceIndex - 1;
189
190 //
191 // probe media and retrieve latest media information
192 //
193 DEBUG ((DEBUG_INFO, "Atatpi GetInfo DevicePosition is %d\n", AtapiBlkIoDev->DeviceInfo[Index].DevicePosition));
194 DEBUG ((DEBUG_INFO, "Atatpi GetInfo DeviceType is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.DeviceType));
195 DEBUG ((DEBUG_INFO, "Atatpi GetInfo MediaPresent is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.MediaPresent));
196 DEBUG ((DEBUG_INFO, "Atatpi GetInfo BlockSize is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.BlockSize));
197 DEBUG ((DEBUG_INFO, "Atatpi GetInfo LastBlock is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.LastBlock));
198
199 Status = DetectMedia (
200 AtapiBlkIoDev,
201 AtapiBlkIoDev->DeviceInfo[Index].DevicePosition,
202 &AtapiBlkIoDev->DeviceInfo[Index].MediaInfo,
203 &AtapiBlkIoDev->DeviceInfo[Index].MediaInfo2
204 );
205 if (Status != EFI_SUCCESS) {
206 return EFI_DEVICE_ERROR;
207 }
208
209 DEBUG ((DEBUG_INFO, "Atatpi GetInfo DevicePosition is %d\n", AtapiBlkIoDev->DeviceInfo[Index].DevicePosition));
210 DEBUG ((DEBUG_INFO, "Atatpi GetInfo DeviceType is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.DeviceType));
211 DEBUG ((DEBUG_INFO, "Atatpi GetInfo MediaPresent is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.MediaPresent));
212 DEBUG ((DEBUG_INFO, "Atatpi GetInfo BlockSize is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.BlockSize));
213 DEBUG ((DEBUG_INFO, "Atatpi GetInfo LastBlock is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.LastBlock));
214
215 //
216 // Get media info from AtapiBlkIoDev
217 //
218 CopyMem (MediaInfo, &AtapiBlkIoDev->DeviceInfo[Index].MediaInfo, sizeof (EFI_PEI_BLOCK_IO_MEDIA));
219
220 return EFI_SUCCESS;
221}
222
258EFIAPI
260 IN EFI_PEI_SERVICES **PeiServices,
262 IN UINTN DeviceIndex,
263 IN EFI_PEI_LBA StartLBA,
264 IN UINTN BufferSize,
265 OUT VOID *Buffer
266 )
267{
268 EFI_PEI_BLOCK_IO_MEDIA MediaInfo;
269 EFI_STATUS Status;
270 UINTN NumberOfBlocks;
271 UINTN BlockSize;
272 ATAPI_BLK_IO_DEV *AtapiBlkIoDev;
273
274 AtapiBlkIoDev = NULL;
275
276 if (This == NULL) {
277 return EFI_INVALID_PARAMETER;
278 }
279
280 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO_THIS (This);
281
282 if (Buffer == NULL) {
283 return EFI_INVALID_PARAMETER;
284 }
285
286 if (BufferSize == 0) {
287 return EFI_SUCCESS;
288 }
289
291 PeiServices,
292 This,
293 DeviceIndex,
294 &MediaInfo
295 );
296 if (Status != EFI_SUCCESS) {
297 return EFI_DEVICE_ERROR;
298 }
299
300 if (!MediaInfo.MediaPresent) {
301 return EFI_NO_MEDIA;
302 }
303
304 BlockSize = MediaInfo.BlockSize;
305
306 if (BufferSize % BlockSize != 0) {
307 return EFI_BAD_BUFFER_SIZE;
308 }
309
310 NumberOfBlocks = BufferSize / BlockSize;
311
312 if ((StartLBA + NumberOfBlocks - 1) > AtapiBlkIoDev->DeviceInfo[DeviceIndex - 1].MediaInfo2.LastBlock) {
313 return EFI_INVALID_PARAMETER;
314 }
315
316 Status = ReadSectors (
317 AtapiBlkIoDev,
318 AtapiBlkIoDev->DeviceInfo[DeviceIndex - 1].DevicePosition,
319 Buffer,
320 StartLBA,
321 NumberOfBlocks,
322 BlockSize
323 );
324 if (EFI_ERROR (Status)) {
325 return EFI_DEVICE_ERROR;
326 }
327
328 return EFI_SUCCESS;
329}
330
351EFIAPI
353 IN EFI_PEI_SERVICES **PeiServices,
355 OUT UINTN *NumberBlockDevices
356 )
357{
358 EFI_STATUS Status;
359 ATAPI_BLK_IO_DEV *AtapiBlkIoDev;
360
361 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO2_THIS (This);
362
364 PeiServices,
365 &AtapiBlkIoDev->AtapiBlkIo,
366 NumberBlockDevices
367 );
368
369 return Status;
370}
371
401EFIAPI
403 IN EFI_PEI_SERVICES **PeiServices,
405 IN UINTN DeviceIndex,
407 )
408{
409 ATAPI_BLK_IO_DEV *AtapiBlkIoDev;
410 EFI_STATUS Status;
412
413 AtapiBlkIoDev = NULL;
414
415 if ((This == NULL) || (MediaInfo == NULL)) {
416 return EFI_INVALID_PARAMETER;
417 }
418
419 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO2_THIS (This);
420
422 PeiServices,
423 &AtapiBlkIoDev->AtapiBlkIo,
424 DeviceIndex,
425 &Media
426 );
427 if (EFI_ERROR (Status)) {
428 return Status;
429 }
430
431 //
432 // Get media info from AtapiBlkIoDev
433 //
434 CopyMem (MediaInfo, &AtapiBlkIoDev->DeviceInfo[DeviceIndex - 1].MediaInfo2, sizeof (EFI_PEI_BLOCK_IO2_MEDIA));
435
436 return EFI_SUCCESS;
437}
438
474EFIAPI
476 IN EFI_PEI_SERVICES **PeiServices,
478 IN UINTN DeviceIndex,
479 IN EFI_PEI_LBA StartLBA,
480 IN UINTN BufferSize,
481 OUT VOID *Buffer
482 )
483{
484 EFI_STATUS Status;
485 ATAPI_BLK_IO_DEV *AtapiBlkIoDev;
486
487 AtapiBlkIoDev = NULL;
488
489 if (This == NULL) {
490 return EFI_INVALID_PARAMETER;
491 }
492
493 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO2_THIS (This);
494
495 Status = AtapiReadBlocks (
496 PeiServices,
497 &AtapiBlkIoDev->AtapiBlkIo,
498 DeviceIndex,
499 StartLBA,
500 BufferSize,
501 Buffer
502 );
503
504 return Status;
505}
506
515VOID
517 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev
518 )
519{
520 UINT8 Index1;
521 UINT8 Index2;
522 UINTN DevicePosition;
523 EFI_PEI_BLOCK_IO_MEDIA MediaInfo;
524 EFI_PEI_BLOCK_IO2_MEDIA MediaInfo2;
525 EFI_STATUS Status;
526 UINTN DeviceCount;
527 UINT16 CommandBlockBaseAddr;
528 UINT16 ControlBlockBaseAddr;
529 UINT32 IdeEnabledNumber;
530 IDE_REGS_BASE_ADDR IdeRegsBaseAddr[MAX_IDE_CHANNELS];
531
532 DeviceCount = 0;
533 DevicePosition = 0;
534
535 //
536 // Scan IDE bus for ATAPI devices
537 //
538
539 //
540 // Enable Sata and IDE controller.
541 //
542 AtapiBlkIoDev->AtaControllerPpi->EnableAtaChannel (
544 AtapiBlkIoDev->AtaControllerPpi,
546 );
547
548 //
549 // Allow SATA Devices to spin-up. This is needed if
550 // SEC and PEI phase is too short, for example Release Build.
551 //
552 DEBUG ((DEBUG_INFO, "Delay for %d seconds for SATA devices to spin-up\n", PcdGet16 (PcdSataSpinUpDelayInSecForRecoveryPath)));
553 MicroSecondDelay (PcdGet16 (PcdSataSpinUpDelayInSecForRecoveryPath) * 1000 * 1000); //
554
555 //
556 // Get four channels (primary or secondary Pata, Sata Channel) Command and Control Regs Base address.
557 //
558 IdeEnabledNumber = AtapiBlkIoDev->AtaControllerPpi->GetIdeRegsBaseAddr (
560 AtapiBlkIoDev->AtaControllerPpi,
561 IdeRegsBaseAddr
562 );
563
564 //
565 // Using Command and Control Regs Base Address to fill other registers.
566 //
567 for (Index1 = 0; Index1 < IdeEnabledNumber; Index1++) {
568 CommandBlockBaseAddr = IdeRegsBaseAddr[Index1].CommandBlockBaseAddr;
569 AtapiBlkIoDev->IdeIoPortReg[Index1].Data = CommandBlockBaseAddr;
570 AtapiBlkIoDev->IdeIoPortReg[Index1].Reg1.Feature = (UINT16)(CommandBlockBaseAddr + 0x1);
571 AtapiBlkIoDev->IdeIoPortReg[Index1].SectorCount = (UINT16)(CommandBlockBaseAddr + 0x2);
572 AtapiBlkIoDev->IdeIoPortReg[Index1].SectorNumber = (UINT16)(CommandBlockBaseAddr + 0x3);
573 AtapiBlkIoDev->IdeIoPortReg[Index1].CylinderLsb = (UINT16)(CommandBlockBaseAddr + 0x4);
574 AtapiBlkIoDev->IdeIoPortReg[Index1].CylinderMsb = (UINT16)(CommandBlockBaseAddr + 0x5);
575 AtapiBlkIoDev->IdeIoPortReg[Index1].Head = (UINT16)(CommandBlockBaseAddr + 0x6);
576 AtapiBlkIoDev->IdeIoPortReg[Index1].Reg.Command = (UINT16)(CommandBlockBaseAddr + 0x7);
577
578 ControlBlockBaseAddr = IdeRegsBaseAddr[Index1].ControlBlockBaseAddr;
579 AtapiBlkIoDev->IdeIoPortReg[Index1].Alt.DeviceControl = ControlBlockBaseAddr;
580 AtapiBlkIoDev->IdeIoPortReg[Index1].DriveAddress = (UINT16)(ControlBlockBaseAddr + 0x1);
581
582 //
583 // Scan IDE bus for ATAPI devices IDE or Sata device
584 //
585 for (Index2 = IdeMaster; Index2 < IdeMaxDevice; Index2++) {
586 //
587 // Pata & Sata, Primary & Secondary channel, Master & Slave device
588 //
589 DevicePosition = Index1 * 2 + Index2;
590
591 if (DiscoverAtapiDevice (AtapiBlkIoDev, DevicePosition, &MediaInfo, &MediaInfo2)) {
592 //
593 // ATAPI Device at DevicePosition is found.
594 //
595 AtapiBlkIoDev->DeviceInfo[DeviceCount].DevicePosition = DevicePosition;
596 //
597 // Retrieve Media Info
598 //
599 Status = DetectMedia (AtapiBlkIoDev, DevicePosition, &MediaInfo, &MediaInfo2);
600 CopyMem (&(AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo), &MediaInfo, sizeof (MediaInfo));
601 CopyMem (&(AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo2), &MediaInfo2, sizeof (MediaInfo2));
602
603 DEBUG ((DEBUG_INFO, "Atatpi Device Position is %d\n", DevicePosition));
604 DEBUG ((DEBUG_INFO, "Atatpi DeviceType is %d\n", MediaInfo.DeviceType));
605 DEBUG ((DEBUG_INFO, "Atatpi MediaPresent is %d\n", MediaInfo.MediaPresent));
606 DEBUG ((DEBUG_INFO, "Atatpi BlockSize is 0x%x\n", MediaInfo.BlockSize));
607
608 if (EFI_ERROR (Status)) {
609 AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo.MediaPresent = FALSE;
610 AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo.LastBlock = 0;
611 AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo2.MediaPresent = FALSE;
612 AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo2.LastBlock = 0;
613 }
614
615 DeviceCount += 1;
616 }
617 }
618 }
619
620 AtapiBlkIoDev->DeviceCount = DeviceCount;
621}
622
635BOOLEAN
637 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
638 IN UINTN DevicePosition,
639 OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo,
640 OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2
641 )
642{
643 EFI_STATUS Status;
644
645 if (!DetectIDEController (AtapiBlkIoDev, DevicePosition)) {
646 return FALSE;
647 }
648
649 //
650 // test if it is an ATAPI device (only supported device)
651 //
652 if (ATAPIIdentify (AtapiBlkIoDev, DevicePosition) == EFI_SUCCESS) {
653 Status = Inquiry (AtapiBlkIoDev, DevicePosition, MediaInfo, MediaInfo2);
654 if (!EFI_ERROR (Status)) {
655 return TRUE;
656 }
657 }
658
659 return FALSE;
660}
661
677 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
678 IN UINTN DevicePosition,
679 IN UINT8 AtaCommand
680 )
681{
682 UINT8 Channel;
683 UINT8 Device;
684 UINT16 StatusRegister;
685 UINT16 HeadRegister;
686 UINT16 CommandRegister;
687 UINT16 ErrorRegister;
688 UINT16 SectorCountRegister;
689 EFI_STATUS Status;
690 UINT8 StatusValue;
691 UINT8 ErrorValue;
692 UINT8 SectorCountValue;
693
694 Channel = (UINT8)(DevicePosition / 2);
695 Device = (UINT8)(DevicePosition % 2);
696
697 ASSERT (Channel < MAX_IDE_CHANNELS);
698
699 StatusRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Status;
700 HeadRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Head;
701 CommandRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command;
702 ErrorRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg1.Error;
703 SectorCountRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].SectorCount;
704
705 //
706 // select device
707 //
708 IoWrite8 (HeadRegister, (UINT8)((Device << 4) | 0xe0));
709
710 //
711 // refresh the SectorCount register
712 //
713 SectorCountValue = 0x55;
714 IoWrite8 (SectorCountRegister, SectorCountValue);
715
716 //
717 // select device
718 //
719 IoWrite8 (HeadRegister, (UINT8)((Device << 4) | 0xe0));
720
721 Status = DRDYReady (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 100);
722
723 //
724 // select device
725 //
726 IoWrite8 (HeadRegister, (UINT8)((Device << 4) | 0xe0));
727 //
728 // send 'check power' commandd via Command Register
729 //
730 IoWrite8 (CommandRegister, AtaCommand);
731
732 Status = WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 3000);
733 if (EFI_ERROR (Status)) {
734 return EFI_TIMEOUT;
735 }
736
737 StatusValue = IoRead8 (StatusRegister);
738
739 //
740 // command returned status is DRDY, indicating device supports the command,
741 // so device is present.
742 //
743 if ((StatusValue & ATA_STSREG_DRDY) == ATA_STSREG_DRDY) {
744 return EFI_SUCCESS;
745 }
746
747 SectorCountValue = IoRead8 (SectorCountRegister);
748
749 //
750 // command returned status is ERR & ABRT_ERR, indicating device does not support
751 // the command, so device is present.
752 //
753 if ((StatusValue & ATA_STSREG_ERR) == ATA_STSREG_ERR) {
754 ErrorValue = IoRead8 (ErrorRegister);
755 if ((ErrorValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
756 return EFI_ABORTED;
757 } else {
758 //
759 // According to spec, no other error code is valid
760 //
761 return EFI_NOT_FOUND;
762 }
763 }
764
765 if ((SectorCountValue == 0x00) || (SectorCountValue == 0x80) || (SectorCountValue == 0xff)) {
766 //
767 // Write SectorCount 0x55 but return valid state value. Maybe no device
768 // exists or some slow kind of ATAPI device exists.
769 //
770 IoWrite8 (HeadRegister, (UINT8)((Device << 4) | 0xe0));
771
772 //
773 // write 0x55 and 0xaa to SectorCounter register,
774 // if the data could be written into the register,
775 // indicating the device is present, otherwise the device is not present.
776 //
777 SectorCountValue = 0x55;
778 IoWrite8 (SectorCountRegister, SectorCountValue);
779 MicroSecondDelay (10000);
780
781 SectorCountValue = IoRead8 (SectorCountRegister);
782 if (SectorCountValue != 0x55) {
783 return EFI_NOT_FOUND;
784 }
785
786 //
787 // Send a "ATAPI TEST UNIT READY" command ... slow but accurate
788 //
789 Status = TestUnitReady (AtapiBlkIoDev, DevicePosition);
790 return Status;
791 }
792
793 return EFI_NOT_FOUND;
794}
795
806BOOLEAN
808 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
809 IN UINTN DevicePosition
810 )
811{
812 UINT8 Channel;
813 EFI_STATUS Status;
814 UINT8 AtaCommand;
815
816 Channel = (UINT8)(DevicePosition / 2);
817
818 ASSERT (Channel < MAX_IDE_CHANNELS);
819 //
820 // Wait 31 seconds for BSY clear
821 //
822 Status = WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 31000);
823 if (EFI_ERROR (Status)) {
824 return FALSE;
825 }
826
827 //
828 // Send 'check power' command for IDE device
829 //
830 AtaCommand = 0xE5;
831 Status = CheckPowerMode (AtapiBlkIoDev, DevicePosition, AtaCommand);
832 if ((Status == EFI_ABORTED) || (Status == EFI_SUCCESS)) {
833 return TRUE;
834 }
835
836 return FALSE;
837}
838
852 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
853 IN IDE_BASE_REGISTERS *IdeIoRegisters,
854 IN UINTN TimeoutInMilliSeconds
855 )
856{
857 UINTN Delay;
858 UINT16 StatusRegister;
859 UINT8 StatusValue;
860
861 StatusValue = 0;
862
863 StatusRegister = IdeIoRegisters->Reg.Status;
864
865 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1;
866 do {
867 StatusValue = IoRead8 (StatusRegister);
868 if ((StatusValue & ATA_STSREG_BSY) == 0x00) {
869 break;
870 }
871
872 MicroSecondDelay (250);
873
874 Delay--;
875 } while (Delay != 0);
876
877 if (Delay == 0) {
878 return EFI_TIMEOUT;
879 }
880
881 return EFI_SUCCESS;
882}
883
897 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
898 IN IDE_BASE_REGISTERS *IdeIoRegisters,
899 IN UINTN TimeoutInMilliSeconds
900 )
901{
902 UINTN Delay;
903 UINT16 StatusRegister;
904 UINT8 StatusValue;
905 UINT8 ErrValue;
906
907 StatusValue = 0;
908
909 StatusRegister = IdeIoRegisters->Reg.Status;
910
911 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1;
912 do {
913 StatusValue = IoRead8 (StatusRegister);
914 //
915 // BSY == 0 , DRDY == 1
916 //
917 if ((StatusValue & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) {
918 break;
919 }
920
921 if ((StatusValue & (ATA_STSREG_ERR | ATA_STSREG_BSY)) == ATA_STSREG_ERR) {
922 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error);
923 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
924 return EFI_ABORTED;
925 }
926 }
927
928 MicroSecondDelay (250);
929
930 Delay--;
931 } while (Delay != 0);
932
933 if (Delay == 0) {
934 return EFI_TIMEOUT;
935 }
936
937 return EFI_SUCCESS;
938}
939
953 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
954 IN IDE_BASE_REGISTERS *IdeIoRegisters,
955 IN UINTN TimeoutInMilliSeconds
956 )
957{
958 UINTN Delay;
959 UINT16 StatusRegister;
960 UINT8 StatusValue;
961 UINT8 ErrValue;
962
963 StatusValue = 0;
964
965 StatusRegister = IdeIoRegisters->Reg.Status;
966
967 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1;
968 do {
969 StatusValue = IoRead8 (StatusRegister);
970
971 //
972 // wait for BSY == 0 and DRQ == 0
973 //
974 if ((StatusValue & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) {
975 break;
976 }
977
978 if ((StatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {
979 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error);
980 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
981 return EFI_ABORTED;
982 }
983 }
984
985 MicroSecondDelay (250);
986
987 Delay--;
988 } while (Delay != 0);
989
990 if (Delay == 0) {
991 return EFI_TIMEOUT;
992 }
993
994 return EFI_SUCCESS;
995}
996
1010 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1011 IN IDE_BASE_REGISTERS *IdeIoRegisters,
1012 IN UINTN TimeoutInMilliSeconds
1013 )
1014{
1015 UINTN Delay;
1016 UINT16 AltStatusRegister;
1017 UINT8 AltStatusValue;
1018 UINT8 ErrValue;
1019
1020 AltStatusValue = 0;
1021
1022 AltStatusRegister = IdeIoRegisters->Alt.AltStatus;
1023
1024 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1;
1025 do {
1026 AltStatusValue = IoRead8 (AltStatusRegister);
1027
1028 //
1029 // wait for BSY == 0 and DRQ == 0
1030 //
1031 if ((AltStatusValue & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) {
1032 break;
1033 }
1034
1035 if ((AltStatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {
1036 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error);
1037 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
1038 return EFI_ABORTED;
1039 }
1040 }
1041
1042 MicroSecondDelay (250);
1043
1044 Delay--;
1045 } while (Delay != 0);
1046
1047 if (Delay == 0) {
1048 return EFI_TIMEOUT;
1049 }
1050
1051 return EFI_SUCCESS;
1052}
1053
1068 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1069 IN IDE_BASE_REGISTERS *IdeIoRegisters,
1070 IN UINTN TimeoutInMilliSeconds
1071 )
1072{
1073 UINTN Delay;
1074 UINT16 StatusRegister;
1075 UINT8 StatusValue;
1076 UINT8 ErrValue;
1077
1078 StatusValue = 0;
1079 ErrValue = 0;
1080
1081 StatusRegister = IdeIoRegisters->Reg.Status;
1082
1083 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1;
1084 do {
1085 //
1086 // read Status Register will clear interrupt
1087 //
1088 StatusValue = IoRead8 (StatusRegister);
1089
1090 //
1091 // BSY==0,DRQ==1
1092 //
1093 if ((StatusValue & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
1094 break;
1095 }
1096
1097 if ((StatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {
1098 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error);
1099 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
1100 return EFI_ABORTED;
1101 }
1102 }
1103
1104 MicroSecondDelay (250);
1105
1106 Delay--;
1107 } while (Delay != 0);
1108
1109 if (Delay == 0) {
1110 return EFI_TIMEOUT;
1111 }
1112
1113 return EFI_SUCCESS;
1114}
1115
1130 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1131 IN IDE_BASE_REGISTERS *IdeIoRegisters,
1132 IN UINTN TimeoutInMilliSeconds
1133 )
1134{
1135 UINTN Delay;
1136 UINT16 AltStatusRegister;
1137 UINT8 AltStatusValue;
1138 UINT8 ErrValue;
1139
1140 AltStatusValue = 0;
1141
1142 AltStatusRegister = IdeIoRegisters->Alt.AltStatus;
1143
1144 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1;
1145 do {
1146 AltStatusValue = IoRead8 (AltStatusRegister);
1147
1148 //
1149 // BSY==0,DRQ==1
1150 //
1151 if ((AltStatusValue & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
1152 break;
1153 }
1154
1155 if ((AltStatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {
1156 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error);
1157 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
1158 return EFI_ABORTED;
1159 }
1160 }
1161
1162 MicroSecondDelay (250);
1163
1164 Delay--;
1165 } while (Delay != 0);
1166
1167 if (Delay == 0) {
1168 return EFI_TIMEOUT;
1169 }
1170
1171 return EFI_SUCCESS;
1172}
1173
1186 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1187 IN UINT16 StatusReg
1188 )
1189{
1190 UINT8 StatusValue;
1191
1192 StatusValue = IoRead8 (StatusReg);
1193
1194 if ((StatusValue & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) {
1195 return EFI_SUCCESS;
1196 }
1197
1198 return EFI_DEVICE_ERROR;
1199}
1200
1213 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1214 IN UINTN DevicePosition
1215 )
1216{
1217 ATAPI_IDENTIFY_DATA AtapiIdentifyData;
1218 UINT8 Channel;
1219 UINT8 Device;
1220 UINT16 StatusReg;
1221 UINT16 HeadReg;
1222 UINT16 CommandReg;
1223 UINT16 DataReg;
1224 UINT16 SectorCountReg;
1225 UINT16 SectorNumberReg;
1226 UINT16 CylinderLsbReg;
1227 UINT16 CylinderMsbReg;
1228
1229 UINT32 WordCount;
1230 UINT32 Increment;
1231 UINT32 Index;
1232 UINT32 ByteCount;
1233 UINT16 *Buffer16;
1234
1235 EFI_STATUS Status;
1236
1237 ByteCount = sizeof (AtapiIdentifyData);
1238 Buffer16 = (UINT16 *)&AtapiIdentifyData;
1239
1240 Channel = (UINT8)(DevicePosition / 2);
1241 Device = (UINT8)(DevicePosition % 2);
1242
1243 ASSERT (Channel < MAX_IDE_CHANNELS);
1244
1245 StatusReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Status;
1246 HeadReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Head;
1247 CommandReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command;
1248 DataReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Data;
1249 SectorCountReg = AtapiBlkIoDev->IdeIoPortReg[Channel].SectorCount;
1250 SectorNumberReg = AtapiBlkIoDev->IdeIoPortReg[Channel].SectorNumber;
1251 CylinderLsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderLsb;
1252 CylinderMsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderMsb;
1253
1254 //
1255 // Send ATAPI Identify Command to get IDENTIFY data.
1256 //
1257 if (WaitForBSYClear (
1258 AtapiBlkIoDev,
1259 &(AtapiBlkIoDev->IdeIoPortReg[Channel]),
1260 ATATIMEOUT
1261 ) != EFI_SUCCESS)
1262 {
1263 return EFI_DEVICE_ERROR;
1264 }
1265
1266 //
1267 // select device via Head/Device register.
1268 // Before write Head/Device register, BSY and DRQ must be 0.
1269 //
1270 if (DRQClear2 (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), ATATIMEOUT) != EFI_SUCCESS) {
1271 return EFI_DEVICE_ERROR;
1272 }
1273
1274 //
1275 // e0:1110,0000-- bit7 and bit5 are reserved bits.
1276 // bit6 set means LBA mode
1277 //
1278 IoWrite8 (HeadReg, (UINT8)((Device << 4) | 0xe0));
1279
1280 //
1281 // set all the command parameters
1282 // Before write to all the following registers, BSY and DRQ must be 0.
1283 //
1284 if (DRQClear2 (
1285 AtapiBlkIoDev,
1286 &(AtapiBlkIoDev->IdeIoPortReg[Channel]),
1287 ATATIMEOUT
1288 ) != EFI_SUCCESS)
1289 {
1290 return EFI_DEVICE_ERROR;
1291 }
1292
1293 IoWrite8 (SectorCountReg, 0);
1294 IoWrite8 (SectorNumberReg, 0);
1295 IoWrite8 (CylinderLsbReg, 0);
1296 IoWrite8 (CylinderMsbReg, 0);
1297
1298 //
1299 // send command via Command Register
1300 //
1301 IoWrite8 (CommandReg, ATA_CMD_IDENTIFY_DEVICE);
1302
1303 //
1304 // According to PIO data in protocol, host can perform a series of reads to the
1305 // data register after each time device set DRQ ready;
1306 // The data size of "a series of read" is command specific.
1307 // For most ATA command, data size received from device will not exceed 1 sector,
1308 // hense the data size for "a series of read" can be the whole data size of one command request.
1309 // For ATA command such as Read Sector command, whole data size of one ATA command request is often larger
1310 // than 1 sector, according to the Read Sector command, the data size of "a series of read" is exactly
1311 // 1 sector.
1312 // Here for simplification reason, we specify the data size for "a series of read" to
1313 // 1 sector (256 words) if whole data size of one ATA commmand request is larger than 256 words.
1314 //
1315 Increment = 256;
1316 //
1317 // 256 words
1318 //
1319 WordCount = 0;
1320 //
1321 // WordCount is used to record bytes of currently transfered data
1322 //
1323 while (WordCount < ByteCount / 2) {
1324 //
1325 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1326 //
1327 Status = DRQReady2 (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), ATATIMEOUT);
1328 if (Status != EFI_SUCCESS) {
1329 return Status;
1330 }
1331
1332 if (CheckErrorStatus (AtapiBlkIoDev, StatusReg) != EFI_SUCCESS) {
1333 return EFI_DEVICE_ERROR;
1334 }
1335
1336 //
1337 // Get the byte count for one series of read
1338 //
1339 if ((WordCount + Increment) > ByteCount / 2) {
1340 Increment = ByteCount / 2 - WordCount;
1341 }
1342
1343 //
1344 // perform a series of read without check DRQ ready
1345 //
1346 for (Index = 0; Index < Increment; Index++) {
1347 *Buffer16++ = IoRead16 (DataReg);
1348 }
1349
1350 WordCount += Increment;
1351 }
1352
1353 //
1354 // while
1355 //
1356 if (DRQClear (
1357 AtapiBlkIoDev,
1358 &(AtapiBlkIoDev->IdeIoPortReg[Channel]),
1359 ATATIMEOUT
1360 ) != EFI_SUCCESS)
1361 {
1362 return CheckErrorStatus (AtapiBlkIoDev, StatusReg);
1363 }
1364
1365 return EFI_SUCCESS;
1366}
1367
1381 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1382 IN UINTN DevicePosition
1383 )
1384{
1385 ATAPI_PACKET_COMMAND Packet;
1386 EFI_STATUS Status;
1387
1388 //
1389 // fill command packet
1390 //
1391 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
1392 Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY;
1393
1394 //
1395 // send command packet
1396 //
1397 Status = AtapiPacketCommandIn (AtapiBlkIoDev, DevicePosition, &Packet, NULL, 0, ATAPITIMEOUT);
1398 return Status;
1399}
1400
1417 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1418 IN UINTN DevicePosition,
1419 IN ATAPI_PACKET_COMMAND *Packet,
1420 IN UINT16 *Buffer,
1421 IN UINT32 ByteCount,
1422 IN UINTN TimeoutInMilliSeconds
1423 )
1424{
1425 UINT8 Channel;
1426 UINT8 Device;
1427 UINT16 StatusReg;
1428 UINT16 HeadReg;
1429 UINT16 CommandReg;
1430 UINT16 FeatureReg;
1431 UINT16 CylinderLsbReg;
1432 UINT16 CylinderMsbReg;
1433 UINT16 DeviceControlReg;
1434 UINT16 DataReg;
1435 EFI_STATUS Status;
1436 UINT32 Count;
1437 UINT16 *CommandIndex;
1438 UINT16 *PtrBuffer;
1439 UINT32 Index;
1440 UINT8 StatusValue;
1441 UINT32 WordCount;
1442
1443 //
1444 // required transfer data in word unit.
1445 //
1446 UINT32 RequiredWordCount;
1447
1448 //
1449 // actual transfer data in word unit.
1450 //
1451 UINT32 ActualWordCount;
1452
1453 Channel = (UINT8)(DevicePosition / 2);
1454 Device = (UINT8)(DevicePosition % 2);
1455
1456 ASSERT (Channel < MAX_IDE_CHANNELS);
1457
1458 StatusReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Status;
1459 HeadReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Head;
1460 CommandReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command;
1461 FeatureReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg1.Feature;
1462 CylinderLsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderLsb;
1463 CylinderMsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderMsb;
1464 DeviceControlReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Alt.DeviceControl;
1465 DataReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Data;
1466
1467 //
1468 // Set all the command parameters by fill related registers.
1469 // Before write to all the following registers, BSY and DRQ must be 0.
1470 //
1471 if (DRQClear2 (
1472 AtapiBlkIoDev,
1473 &(AtapiBlkIoDev->IdeIoPortReg[Channel]),
1474 ATATIMEOUT
1475 ) != EFI_SUCCESS)
1476 {
1477 return EFI_DEVICE_ERROR;
1478 }
1479
1480 //
1481 // Select device via Device/Head Register.
1482 // DEFAULT_CMD: 0xa0 (1010,0000)
1483 //
1484 IoWrite8 (HeadReg, (UINT8)((Device << 4) | ATA_DEFAULT_CMD));
1485
1486 //
1487 // No OVL; No DMA
1488 //
1489 IoWrite8 (FeatureReg, 0x00);
1490
1491 //
1492 // set the transfersize to MAX_ATAPI_BYTE_COUNT to let the device
1493 // determine how many data should be transfered.
1494 //
1495 IoWrite8 (CylinderLsbReg, (UINT8)(ATAPI_MAX_BYTE_COUNT & 0x00ff));
1496 IoWrite8 (CylinderMsbReg, (UINT8)(ATAPI_MAX_BYTE_COUNT >> 8));
1497
1498 //
1499 // DEFAULT_CTL:0x0a (0000,1010)
1500 // Disable interrupt
1501 //
1502 IoWrite8 (DeviceControlReg, ATA_DEFAULT_CTL);
1503
1504 //
1505 // Send Packet command to inform device
1506 // that the following data bytes are command packet.
1507 //
1508 IoWrite8 (CommandReg, ATA_CMD_PACKET);
1509
1510 Status = DRQReady (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), TimeoutInMilliSeconds);
1511 if (Status != EFI_SUCCESS) {
1512 return Status;
1513 }
1514
1515 //
1516 // Send out command packet
1517 //
1518 CommandIndex = Packet->Data16;
1519 for (Count = 0; Count < 6; Count++, CommandIndex++) {
1520 IoWrite16 (DataReg, *CommandIndex);
1521 MicroSecondDelay (10);
1522 }
1523
1524 StatusValue = IoRead8 (StatusReg);
1525 if ((StatusValue & ATA_STSREG_ERR) == ATA_STSREG_ERR) {
1526 //
1527 // Trouble! Something's wrong here... Wait some time and return. 3 second is
1528 // supposed to be long enough for a device reset latency or error recovery
1529 //
1530 MicroSecondDelay (3000000);
1531 return EFI_DEVICE_ERROR;
1532 }
1533
1534 if ((Buffer == NULL) || (ByteCount == 0)) {
1535 return EFI_SUCCESS;
1536 }
1537
1538 //
1539 // call PioReadWriteData() function to get
1540 // requested transfer data form device.
1541 //
1542 PtrBuffer = Buffer;
1543 RequiredWordCount = ByteCount / 2;
1544 //
1545 // ActuralWordCount means the word count of data really transfered.
1546 //
1547 ActualWordCount = 0;
1548
1549 Status = EFI_SUCCESS;
1550 while ((Status == EFI_SUCCESS) && (ActualWordCount < RequiredWordCount)) {
1551 //
1552 // before each data transfer stream, the host should poll DRQ bit ready,
1553 // which informs device is ready to transfer data.
1554 //
1555 if (DRQReady2 (
1556 AtapiBlkIoDev,
1557 &(AtapiBlkIoDev->IdeIoPortReg[Channel]),
1558 TimeoutInMilliSeconds
1559 ) != EFI_SUCCESS)
1560 {
1561 return CheckErrorStatus (AtapiBlkIoDev, StatusReg);
1562 }
1563
1564 //
1565 // read Status Register will clear interrupt
1566 //
1567 StatusValue = IoRead8 (StatusReg);
1568
1569 //
1570 // get current data transfer size from Cylinder Registers.
1571 //
1572 WordCount = IoRead8 (CylinderMsbReg) << 8;
1573 WordCount = WordCount | IoRead8 (CylinderLsbReg);
1574 WordCount = WordCount & 0xffff;
1575 WordCount /= 2;
1576
1577 //
1578 // perform a series data In/Out.
1579 //
1580 for (Index = 0; (Index < WordCount) && (ActualWordCount < RequiredWordCount); Index++, ActualWordCount++) {
1581 *PtrBuffer = IoRead16 (DataReg);
1582
1583 PtrBuffer++;
1584 }
1585
1586 if ((((ATAPI_REQUEST_SENSE_CMD *)Packet)->opcode == ATA_CMD_REQUEST_SENSE) && (ActualWordCount >= 4)) {
1587 RequiredWordCount = MIN (
1588 RequiredWordCount,
1589 (UINT32)(4 + (((ATAPI_REQUEST_SENSE_DATA *)Buffer)->addnl_sense_length / 2))
1590 );
1591 }
1592 }
1593
1594 //
1595 // After data transfer is completed, normally, DRQ bit should clear.
1596 //
1597 Status = DRQClear2 (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), TimeoutInMilliSeconds);
1598 if (Status != EFI_SUCCESS) {
1599 return EFI_DEVICE_ERROR;
1600 }
1601
1602 //
1603 // read status register to check whether error happens.
1604 //
1605 Status = CheckErrorStatus (AtapiBlkIoDev, StatusReg);
1606 return Status;
1607}
1608
1625 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1626 IN UINTN DevicePosition,
1627 OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo,
1628 OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2
1629 )
1630{
1631 ATAPI_PACKET_COMMAND Packet;
1632 EFI_STATUS Status;
1633 ATAPI_INQUIRY_DATA Idata;
1634
1635 //
1636 // prepare command packet for the ATAPI Inquiry Packet Command.
1637 //
1638 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
1639 ZeroMem (&Idata, sizeof (ATAPI_INQUIRY_DATA));
1640
1641 Packet.Inquiry.opcode = ATA_CMD_INQUIRY;
1642 Packet.Inquiry.page_code = 0;
1643 Packet.Inquiry.allocation_length = (UINT8)sizeof (ATAPI_INQUIRY_DATA);
1644
1645 //
1646 // Send command packet and get requested Inquiry data.
1647 //
1648 Status = AtapiPacketCommandIn (
1649 AtapiBlkIoDev,
1650 DevicePosition,
1651 &Packet,
1652 (UINT16 *)(&Idata),
1653 sizeof (ATAPI_INQUIRY_DATA),
1654 ATAPITIMEOUT
1655 // 50
1656 );
1657
1658 if (Status != EFI_SUCCESS) {
1659 return EFI_DEVICE_ERROR;
1660 }
1661
1662 //
1663 // Identify device type via INQUIRY data.
1664 //
1665 switch (Idata.peripheral_type & 0x1f) {
1666 case 0x00:
1667 //
1668 // Magnetic Disk
1669 //
1670 MediaInfo->DeviceType = IdeLS120;
1671 MediaInfo->MediaPresent = FALSE;
1672 MediaInfo->LastBlock = 0;
1673 MediaInfo->BlockSize = 0x200;
1674 MediaInfo2->InterfaceType = MSG_ATAPI_DP;
1675 MediaInfo2->RemovableMedia = TRUE;
1676 MediaInfo2->MediaPresent = FALSE;
1677 MediaInfo2->ReadOnly = FALSE;
1678 MediaInfo2->BlockSize = 0x200;
1679 MediaInfo2->LastBlock = 0;
1680 break;
1681
1682 case 0x05:
1683 //
1684 // CD-ROM
1685 //
1686 MediaInfo->DeviceType = IdeCDROM;
1687 MediaInfo->MediaPresent = FALSE;
1688 MediaInfo->LastBlock = 0;
1689 MediaInfo->BlockSize = 0x800;
1690 MediaInfo2->InterfaceType = MSG_ATAPI_DP;
1691 MediaInfo2->RemovableMedia = TRUE;
1692 MediaInfo2->MediaPresent = FALSE;
1693 MediaInfo2->ReadOnly = TRUE;
1694 MediaInfo2->BlockSize = 0x200;
1695 MediaInfo2->LastBlock = 0;
1696 break;
1697
1698 default:
1699 return EFI_UNSUPPORTED;
1700 }
1701
1702 return EFI_SUCCESS;
1703}
1704
1722 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1723 IN UINTN DevicePosition,
1724 IN OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo,
1725 IN OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2
1726 )
1727{
1728 UINTN Index;
1729 UINTN RetryNum;
1730 UINTN MaxRetryNum;
1731 ATAPI_REQUEST_SENSE_DATA *SenseBuffers;
1732 BOOLEAN NeedReadCapacity;
1733 BOOLEAN NeedRetry;
1734 EFI_STATUS Status;
1735 UINT8 SenseCounts;
1736
1737 SenseBuffers = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (*SenseBuffers)));
1738 if (SenseBuffers == NULL) {
1739 return EFI_OUT_OF_RESOURCES;
1740 }
1741
1742 //
1743 // Test Unit Ready command is used to detect whether device is accessible,
1744 // the device will produce corresponding Sense data.
1745 //
1746 for (Index = 0; Index < 2; Index++) {
1747 Status = TestUnitReady (AtapiBlkIoDev, DevicePosition);
1748 if (Status != EFI_SUCCESS) {
1749 Status = ResetDevice (AtapiBlkIoDev, DevicePosition, FALSE);
1750
1751 if (Status != EFI_SUCCESS) {
1752 ResetDevice (AtapiBlkIoDev, DevicePosition, TRUE);
1753 }
1754 } else {
1755 break;
1756 }
1757 }
1758
1759 SenseCounts = MAX_SENSE_KEY_COUNT;
1760 Status = EFI_SUCCESS;
1761 NeedReadCapacity = TRUE;
1762
1763 for (Index = 0; Index < 5; Index++) {
1764 SenseCounts = MAX_SENSE_KEY_COUNT;
1765 Status = RequestSense (
1766 AtapiBlkIoDev,
1767 DevicePosition,
1768 SenseBuffers,
1769 &SenseCounts
1770 );
1771 DEBUG ((DEBUG_INFO, "Atapi Request Sense Count is %d\n", SenseCounts));
1772 if (IsDeviceStateUnclear (SenseBuffers, SenseCounts) || IsNoMedia (SenseBuffers, SenseCounts)) {
1773 //
1774 // We are not sure whether the media is present or not, try again
1775 //
1776 TestUnitReady (AtapiBlkIoDev, DevicePosition);
1777 } else {
1778 break;
1779 }
1780 }
1781
1782 if (Status == EFI_SUCCESS) {
1783 if (IsNoMedia (SenseBuffers, SenseCounts)) {
1784 NeedReadCapacity = FALSE;
1785 MediaInfo->MediaPresent = FALSE;
1786 MediaInfo->LastBlock = 0;
1787 MediaInfo2->MediaPresent = FALSE;
1788 MediaInfo2->LastBlock = 0;
1789 }
1790
1791 if (IsMediaError (SenseBuffers, SenseCounts)) {
1792 return EFI_DEVICE_ERROR;
1793 }
1794 }
1795
1796 if (NeedReadCapacity) {
1797 //
1798 // at most retry 5 times
1799 //
1800 MaxRetryNum = 5;
1801 RetryNum = 1;
1802 //
1803 // initial retry once
1804 //
1805 for (Index = 0; (Index < RetryNum) && (Index < MaxRetryNum); Index++) {
1806 Status = ReadCapacity (AtapiBlkIoDev, DevicePosition, MediaInfo, MediaInfo2);
1807 MicroSecondDelay (200000);
1808 SenseCounts = MAX_SENSE_KEY_COUNT;
1809
1810 if (Status != EFI_SUCCESS) {
1811 Status = RequestSense (AtapiBlkIoDev, DevicePosition, SenseBuffers, &SenseCounts);
1812 //
1813 // If Request Sense data failed, reset the device and retry.
1814 //
1815 if (Status != EFI_SUCCESS) {
1816 Status = ResetDevice (AtapiBlkIoDev, DevicePosition, FALSE);
1817 //
1818 // if ATAPI soft reset fail,
1819 // use stronger reset mechanism -- ATA soft reset.
1820 //
1821 if (Status != EFI_SUCCESS) {
1822 ResetDevice (AtapiBlkIoDev, DevicePosition, TRUE);
1823 }
1824
1825 RetryNum++;
1826 //
1827 // retry once more
1828 //
1829 continue;
1830 }
1831
1832 //
1833 // No Media
1834 //
1835 if (IsNoMedia (SenseBuffers, SenseCounts)) {
1836 MediaInfo->MediaPresent = FALSE;
1837 MediaInfo->LastBlock = 0;
1838 MediaInfo2->MediaPresent = FALSE;
1839 MediaInfo2->LastBlock = 0;
1840 break;
1841 }
1842
1843 if (IsMediaError (SenseBuffers, SenseCounts)) {
1844 return EFI_DEVICE_ERROR;
1845 }
1846
1847 if (!IsDriveReady (SenseBuffers, SenseCounts, &NeedRetry)) {
1848 //
1849 // Drive not ready: if NeedRetry, then retry once more;
1850 // else return error
1851 //
1852 if (NeedRetry) {
1853 RetryNum++;
1854 continue;
1855 } else {
1856 return EFI_DEVICE_ERROR;
1857 }
1858 }
1859
1860 //
1861 // if read capacity fail not for above reasons, retry once more
1862 //
1863 RetryNum++;
1864 }
1865 }
1866 }
1867
1868 return EFI_SUCCESS;
1869}
1870
1884 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1885 IN UINTN DevicePosition,
1886 IN BOOLEAN Extensive
1887 )
1888{
1889 UINT8 DevControl;
1890 UINT8 Command;
1891 UINT8 DeviceSelect;
1892 UINT16 DeviceControlReg;
1893 UINT16 CommandReg;
1894 UINT16 HeadReg;
1895 UINT8 Channel;
1896 UINT8 Device;
1897
1898 Channel = (UINT8)(DevicePosition / 2);
1899 Device = (UINT8)(DevicePosition % 2);
1900
1901 ASSERT (Channel < MAX_IDE_CHANNELS);
1902
1903 DeviceControlReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Alt.DeviceControl;
1904 CommandReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command;
1905 HeadReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Head;
1906
1907 if (Extensive) {
1908 DevControl = 0;
1909 DevControl |= ATA_CTLREG_SRST;
1910 //
1911 // set SRST bit to initiate soft reset
1912 //
1913 DevControl |= BIT1;
1914 //
1915 // disable Interrupt
1916 //
1917 IoWrite8 (DeviceControlReg, DevControl);
1918
1919 //
1920 // Wait 10us
1921 //
1922 MicroSecondDelay (10);
1923
1924 //
1925 // Clear SRST bit
1926 //
1927 DevControl &= 0xfb;
1928 //
1929 // 0xfb:1111,1011
1930 //
1931 IoWrite8 (DeviceControlReg, DevControl);
1932
1933 //
1934 // slave device needs at most 31s to clear BSY
1935 //
1936 if (WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 31000) == EFI_TIMEOUT) {
1937 return EFI_DEVICE_ERROR;
1938 }
1939 } else {
1940 //
1941 // for ATAPI device, no need to wait DRDY ready after device selecting.
1942 // bit7 and bit5 are both set to 1 for backward compatibility
1943 //
1944 DeviceSelect = (UINT8)(((BIT7 | BIT5) | (Device << 4)));
1945 IoWrite8 (HeadReg, DeviceSelect);
1946
1947 Command = ATA_CMD_SOFT_RESET;
1948 IoWrite8 (CommandReg, Command);
1949
1950 //
1951 // BSY cleared is the only status return to the host by the device when reset is completed
1952 // slave device needs at most 31s to clear BSY
1953 //
1954 if (WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 31000) != EFI_SUCCESS) {
1955 return EFI_DEVICE_ERROR;
1956 }
1957
1958 //
1959 // stall 5 seconds to make the device status stable
1960 //
1961 MicroSecondDelay (STALL_1_SECONDS * 5);
1962 }
1963
1964 return EFI_SUCCESS;
1965}
1966
1981 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1982 IN UINTN DevicePosition,
1983 IN ATAPI_REQUEST_SENSE_DATA *SenseBuffers,
1984 IN OUT UINT8 *SenseCounts
1985 )
1986{
1987 EFI_STATUS Status;
1989 UINT16 *Ptr;
1990 BOOLEAN SenseReq;
1991 ATAPI_PACKET_COMMAND Packet;
1992
1993 ZeroMem (SenseBuffers, sizeof (ATAPI_REQUEST_SENSE_DATA) * (*SenseCounts));
1994 //
1995 // fill command packet for Request Sense Packet Command
1996 //
1997 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
1998 Packet.RequestSence.opcode = ATA_CMD_REQUEST_SENSE;
1999 Packet.RequestSence.allocation_length = (UINT8)sizeof (ATAPI_REQUEST_SENSE_DATA);
2000
2001 Ptr = (UINT16 *)SenseBuffers;
2002 //
2003 // initialize pointer
2004 //
2005 *SenseCounts = 0;
2006 //
2007 // request sense data from device continiously until no sense data exists in the device.
2008 //
2009 for (SenseReq = TRUE; SenseReq;) {
2010 Sense = (ATAPI_REQUEST_SENSE_DATA *)Ptr;
2011
2012 //
2013 // send out Request Sense Packet Command and get one Sense data form device
2014 //
2015 Status = AtapiPacketCommandIn (
2016 AtapiBlkIoDev,
2017 DevicePosition,
2018 &Packet,
2019 Ptr,
2020 sizeof (ATAPI_REQUEST_SENSE_DATA),
2021 ATAPITIMEOUT
2022 );
2023 //
2024 // failed to get Sense data
2025 //
2026 if (Status != EFI_SUCCESS) {
2027 if (*SenseCounts == 0) {
2028 return EFI_DEVICE_ERROR;
2029 } else {
2030 return EFI_SUCCESS;
2031 }
2032 }
2033
2034 (*SenseCounts)++;
2035
2036 if (*SenseCounts > MAX_SENSE_KEY_COUNT) {
2037 return EFI_SUCCESS;
2038 }
2039
2040 //
2041 // We limit MAX sense data count to 20 in order to avoid dead loop. Some
2042 // incompatible ATAPI devices don't retrive NO_SENSE when there is no media.
2043 // In this case, dead loop occurs if we don't have a gatekeeper. 20 is
2044 // supposed to be large enough for any ATAPI device.
2045 //
2046 if ((Sense->sense_key != ATA_SK_NO_SENSE) && ((*SenseCounts) < 20)) {
2047 Ptr += sizeof (ATAPI_REQUEST_SENSE_DATA) / 2;
2048 //
2049 // Ptr is word based pointer
2050 //
2051 } else {
2052 //
2053 // when no sense key, skip out the loop
2054 //
2055 SenseReq = FALSE;
2056 }
2057 }
2058
2059 return EFI_SUCCESS;
2060}
2061
2078 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
2079 IN UINTN DevicePosition,
2080 IN OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo,
2081 IN OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2
2082 )
2083{
2084 EFI_STATUS Status;
2085 ATAPI_PACKET_COMMAND Packet;
2086
2087 //
2088 // used for capacity data returned from ATAPI device
2089 //
2092
2093 ZeroMem (&Data, sizeof (Data));
2094 ZeroMem (&FormatData, sizeof (FormatData));
2095
2096 if (MediaInfo->DeviceType == IdeCDROM) {
2097 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
2098 Packet.Inquiry.opcode = ATA_CMD_READ_CAPACITY;
2099 Status = AtapiPacketCommandIn (
2100 AtapiBlkIoDev,
2101 DevicePosition,
2102 &Packet,
2103 (UINT16 *)(&Data),
2104 sizeof (ATAPI_READ_CAPACITY_DATA),
2105 ATAPITIMEOUT
2106 );
2107 } else {
2108 //
2109 // DeviceType == IdeLS120
2110 //
2111 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
2112 Packet.ReadFormatCapacity.opcode = ATA_CMD_READ_FORMAT_CAPACITY;
2113 Packet.ReadFormatCapacity.allocation_length_lo = 12;
2114 Status = AtapiPacketCommandIn (
2115 AtapiBlkIoDev,
2116 DevicePosition,
2117 &Packet,
2118 (UINT16 *)(&FormatData),
2120 ATAPITIMEOUT*10
2121 );
2122 }
2123
2124 if (Status == EFI_SUCCESS) {
2125 if (MediaInfo->DeviceType == IdeCDROM) {
2126 MediaInfo->LastBlock = ((UINT32)Data.LastLba3 << 24) | (Data.LastLba2 << 16) | (Data.LastLba1 << 8) | Data.LastLba0;
2127 MediaInfo->MediaPresent = TRUE;
2128 //
2129 // Because the user data portion in the sector of the Data CD supported
2130 // is always 800h
2131 //
2132 MediaInfo->BlockSize = 0x800;
2133
2134 MediaInfo2->LastBlock = MediaInfo->LastBlock;
2135 MediaInfo2->MediaPresent = MediaInfo->MediaPresent;
2136 MediaInfo2->BlockSize = (UINT32)MediaInfo->BlockSize;
2137 }
2138
2139 if (MediaInfo->DeviceType == IdeLS120) {
2140 if (FormatData.DesCode == 3) {
2141 MediaInfo->MediaPresent = FALSE;
2142 MediaInfo->LastBlock = 0;
2143 MediaInfo2->MediaPresent = FALSE;
2144 MediaInfo2->LastBlock = 0;
2145 } else {
2146 MediaInfo->LastBlock = ((UINT32)FormatData.LastLba3 << 24) |
2147 (FormatData.LastLba2 << 16) |
2148 (FormatData.LastLba1 << 8) |
2149 FormatData.LastLba0;
2150 MediaInfo->LastBlock--;
2151
2152 MediaInfo->MediaPresent = TRUE;
2153
2154 MediaInfo->BlockSize = 0x200;
2155
2156 MediaInfo2->LastBlock = MediaInfo->LastBlock;
2157 MediaInfo2->MediaPresent = MediaInfo->MediaPresent;
2158 MediaInfo2->BlockSize = (UINT32)MediaInfo->BlockSize;
2159 }
2160 }
2161
2162 return EFI_SUCCESS;
2163 } else {
2164 return EFI_DEVICE_ERROR;
2165 }
2166}
2167
2184 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
2185 IN UINTN DevicePosition,
2186 IN VOID *Buffer,
2187 IN EFI_PEI_LBA StartLba,
2188 IN UINTN NumberOfBlocks,
2189 IN UINTN BlockSize
2190 )
2191{
2192 ATAPI_PACKET_COMMAND Packet;
2193 ATAPI_READ10_CMD *Read10Packet;
2194 EFI_STATUS Status;
2195 UINTN BlocksRemaining;
2196 UINT32 Lba32;
2197 UINT32 ByteCount;
2198 UINT16 SectorCount;
2199 VOID *PtrBuffer;
2200 UINT16 MaxBlock;
2201
2202 //
2203 // fill command packet for Read(10) command
2204 //
2205 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
2206 Read10Packet = &Packet.Read10;
2207 Lba32 = (UINT32)StartLba;
2208 PtrBuffer = Buffer;
2209
2210 //
2211 // limit the data bytes that can be transfered by one Read(10) Command
2212 //
2213 MaxBlock = (UINT16)(0x10000 / BlockSize);
2214 //
2215 // (64k bytes)
2216 //
2217 BlocksRemaining = NumberOfBlocks;
2218
2219 Status = EFI_SUCCESS;
2220 while (BlocksRemaining > 0) {
2221 if (BlocksRemaining <= MaxBlock) {
2222 SectorCount = (UINT16)BlocksRemaining;
2223 } else {
2224 SectorCount = MaxBlock;
2225 }
2226
2227 //
2228 // fill the Packet data sturcture
2229 //
2230 Read10Packet->opcode = ATA_CMD_READ_10;
2231
2232 //
2233 // Lba0 ~ Lba3 specify the start logical block address of the data transfer.
2234 // Lba0 is MSB, Lba3 is LSB
2235 //
2236 Read10Packet->Lba3 = (UINT8)(Lba32 & 0xff);
2237 Read10Packet->Lba2 = (UINT8)(Lba32 >> 8);
2238 Read10Packet->Lba1 = (UINT8)(Lba32 >> 16);
2239 Read10Packet->Lba0 = (UINT8)(Lba32 >> 24);
2240
2241 //
2242 // TranLen0 ~ TranLen1 specify the transfer length in block unit.
2243 // TranLen0 is MSB, TranLen is LSB
2244 //
2245 Read10Packet->TranLen1 = (UINT8)(SectorCount & 0xff);
2246 Read10Packet->TranLen0 = (UINT8)(SectorCount >> 8);
2247
2248 ByteCount = (UINT32)(SectorCount * BlockSize);
2249
2250 Status = AtapiPacketCommandIn (
2251 AtapiBlkIoDev,
2252 DevicePosition,
2253 &Packet,
2254 (UINT16 *)PtrBuffer,
2255 ByteCount,
2256 ATAPILONGTIMEOUT
2257 );
2258 if (Status != EFI_SUCCESS) {
2259 return Status;
2260 }
2261
2262 Lba32 += SectorCount;
2263 PtrBuffer = (UINT8 *)PtrBuffer + SectorCount * BlockSize;
2264 BlocksRemaining -= SectorCount;
2265 }
2266
2267 return Status;
2268}
2269
2280BOOLEAN
2282 IN ATAPI_REQUEST_SENSE_DATA *SenseData,
2283 IN UINTN SenseCounts
2284 )
2285{
2286 ATAPI_REQUEST_SENSE_DATA *SensePtr;
2287 UINTN Index;
2288 BOOLEAN IsNoMedia;
2289
2290 IsNoMedia = FALSE;
2291
2292 SensePtr = SenseData;
2293
2294 for (Index = 0; Index < SenseCounts; Index++) {
2295 if ((SensePtr->sense_key == ATA_SK_NOT_READY) && (SensePtr->addnl_sense_code == ATA_ASC_NO_MEDIA)) {
2296 IsNoMedia = TRUE;
2297 }
2298
2299 SensePtr++;
2300 }
2301
2302 return IsNoMedia;
2303}
2304
2315BOOLEAN
2317 IN ATAPI_REQUEST_SENSE_DATA *SenseData,
2318 IN UINTN SenseCounts
2319 )
2320{
2321 ATAPI_REQUEST_SENSE_DATA *SensePtr;
2322 UINTN Index;
2323 BOOLEAN Unclear;
2324
2325 Unclear = FALSE;
2326
2327 SensePtr = SenseData;
2328
2329 for (Index = 0; Index < SenseCounts; Index++) {
2330 if (SensePtr->sense_key == 0x06) {
2331 //
2332 // Sense key is 0x06 means the device is just be reset or media just
2333 // changed. The current state of the device is unclear.
2334 //
2335 Unclear = TRUE;
2336 break;
2337 }
2338
2339 SensePtr++;
2340 }
2341
2342 return Unclear;
2343}
2344
2355BOOLEAN
2357 IN ATAPI_REQUEST_SENSE_DATA *SenseData,
2358 IN UINTN SenseCounts
2359 )
2360{
2361 ATAPI_REQUEST_SENSE_DATA *SensePtr;
2362 UINTN Index;
2363 BOOLEAN IsError;
2364
2365 IsError = FALSE;
2366
2367 SensePtr = SenseData;
2368
2369 for (Index = 0; Index < SenseCounts; Index++) {
2370 switch (SensePtr->sense_key) {
2371 case ATA_SK_MEDIUM_ERROR:
2372 switch (SensePtr->addnl_sense_code) {
2373 case ATA_ASC_MEDIA_ERR1:
2374 //
2375 // fall through
2376 //
2377 case ATA_ASC_MEDIA_ERR2:
2378 //
2379 // fall through
2380 //
2381 case ATA_ASC_MEDIA_ERR3:
2382 //
2383 // fall through
2384 //
2385 case ATA_ASC_MEDIA_ERR4:
2386 IsError = TRUE;
2387 break;
2388
2389 default:
2390 break;
2391 }
2392
2393 break;
2394
2395 case ATA_SK_NOT_READY:
2396 switch (SensePtr->addnl_sense_code) {
2397 case ATA_ASC_MEDIA_UPSIDE_DOWN:
2398 IsError = TRUE;
2399 break;
2400
2401 default:
2402 break;
2403 }
2404
2405 break;
2406
2407 default:
2408 break;
2409 }
2410
2411 SensePtr++;
2412 }
2413
2414 return IsError;
2415}
2416
2428BOOLEAN
2430 IN ATAPI_REQUEST_SENSE_DATA *SenseData,
2431 IN UINTN SenseCounts,
2432 OUT BOOLEAN *NeedRetry
2433 )
2434{
2435 ATAPI_REQUEST_SENSE_DATA *SensePtr;
2436 UINTN Index;
2437 BOOLEAN IsReady;
2438
2439 IsReady = TRUE;
2440 *NeedRetry = FALSE;
2441
2442 SensePtr = SenseData;
2443
2444 for (Index = 0; Index < SenseCounts; Index++) {
2445 switch (SensePtr->sense_key) {
2446 case ATA_SK_NOT_READY:
2447 switch (SensePtr->addnl_sense_code) {
2448 case ATA_ASC_NOT_READY:
2449 switch (SensePtr->addnl_sense_code_qualifier) {
2450 case ATA_ASCQ_IN_PROGRESS:
2451 IsReady = FALSE;
2452 *NeedRetry = TRUE;
2453 break;
2454
2455 default:
2456 IsReady = FALSE;
2457 *NeedRetry = FALSE;
2458 break;
2459 }
2460
2461 break;
2462
2463 default:
2464 break;
2465 }
2466
2467 break;
2468
2469 default:
2470 break;
2471 }
2472
2473 SensePtr++;
2474 }
2475
2476 return IsReady;
2477}
UINT64 UINTN
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
CONST EFI_PEI_SERVICES **EFIAPI GetPeiServicesTablePointer(VOID)
#define PEI_ICH_IDE_SECONDARY
Definition: AtaController.h:49
#define PEI_ICH_IDE_PRIMARY
Definition: AtaController.h:41
#define ATA_CMD_TEST_UNIT_READY
defined from ATA-1
Definition: Atapi.h:490
#define ATA_STSREG_BSY
Controller Busy defined from ATA-1.
Definition: Atapi.h:834
#define ATA_ERRREG_ABRT
Aborted Command defined from ATA-1.
Definition: Atapi.h:827
#define ATA_STSREG_DRQ
Data Request defined from ATA-1.
Definition: Atapi.h:839
#define ATA_CMD_REQUEST_SENSE
defined from ATA-4
Definition: Atapi.h:491
#define ATA_STSREG_DWF
Drive Write Fault defined from ATA-1, obsoleted from ATA-4.
Definition: Atapi.h:836
#define ATA_DEFAULT_CTL
Definition: Atapi.h:761
#define ATA_CMD_READ_10
defined in ATAPI Removable Rewritable Media Devices
Definition: Atapi.h:495
#define ATA_STSREG_ERR
Error defined from ATA-1.
Definition: Atapi.h:842
#define ATA_DEFAULT_CMD
Definition: Atapi.h:766
#define ATA_CMD_READ_CAPACITY
defined in ATAPI Removable Rewritable Media Devices
Definition: Atapi.h:494
#define ATA_CTLREG_SRST
Software Reset.
Definition: Atapi.h:847
#define ATA_STSREG_CORR
Corrected Data defined from ATA-1, obsoleted from ATA-4.
Definition: Atapi.h:840
#define ATA_STSREG_DRDY
Drive Ready defined from ATA-1.
Definition: Atapi.h:835
#define ATA_CMD_READ_FORMAT_CAPACITY
defined in ATAPI Removable Rewritable Media Devices
Definition: Atapi.h:493
#define ATA_CMD_IDENTIFY_DEVICE
defined from ATA-3
Definition: Atapi.h:488
#define ATA_CMD_SOFT_RESET
defined from ATA-3
Definition: Atapi.h:486
#define ATA_CMD_PACKET
defined from ATA-3
Definition: Atapi.h:487
#define ATA_CMD_INQUIRY
defined in ATAPI Removable Rewritable Media Devices
Definition: Atapi.h:492
EFI_STATUS EFIAPI AtapiReadBlocks(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, IN UINTN DeviceIndex, IN EFI_PEI_LBA StartLBA, IN UINTN BufferSize, OUT VOID *Buffer)
Definition: AtapiPeim.c:259
EFI_STATUS EFIAPI AtapiGetBlockDeviceMediaInfo(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, IN UINTN DeviceIndex, OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo)
Definition: AtapiPeim.c:159
EFI_STATUS ReadCapacity(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN UINTN DevicePosition, IN OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, IN OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2)
Definition: AtapiPeim.c:2077
EFI_STATUS EFIAPI AtapiPeimEntry(IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices)
Definition: AtapiPeim.c:29
EFI_STATUS DRDYReady(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN IDE_BASE_REGISTERS *IdeIoRegisters, IN UINTN TimeoutInMilliSeconds)
Definition: AtapiPeim.c:896
EFI_STATUS DRQReady(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN IDE_BASE_REGISTERS *IdeIoRegisters, IN UINTN TimeoutInMilliSeconds)
Definition: AtapiPeim.c:1067
EFI_STATUS TestUnitReady(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN UINTN DevicePosition)
Definition: AtapiPeim.c:1380
VOID AtapiEnumerateDevices(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev)
Definition: AtapiPeim.c:516
EFI_STATUS CheckPowerMode(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN UINTN DevicePosition, IN UINT8 AtaCommand)
Definition: AtapiPeim.c:676
BOOLEAN DiscoverAtapiDevice(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN UINTN DevicePosition, OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2)
Definition: AtapiPeim.c:636
EFI_STATUS EFIAPI AtapiGetNumberOfBlockDevices2(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, OUT UINTN *NumberBlockDevices)
Definition: AtapiPeim.c:352
EFI_STATUS AtapiPacketCommandIn(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN UINTN DevicePosition, IN ATAPI_PACKET_COMMAND *Packet, IN UINT16 *Buffer, IN UINT32 ByteCount, IN UINTN TimeoutInMilliSeconds)
Definition: AtapiPeim.c:1416
EFI_STATUS DRQClear(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN IDE_BASE_REGISTERS *IdeIoRegisters, IN UINTN TimeoutInMilliSeconds)
Definition: AtapiPeim.c:952
EFI_STATUS ReadSectors(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN UINTN DevicePosition, IN VOID *Buffer, IN EFI_PEI_LBA StartLba, IN UINTN NumberOfBlocks, IN UINTN BlockSize)
Definition: AtapiPeim.c:2183
BOOLEAN DetectIDEController(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN UINTN DevicePosition)
Definition: AtapiPeim.c:807
EFI_STATUS ATAPIIdentify(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN UINTN DevicePosition)
Definition: AtapiPeim.c:1212
EFI_STATUS RequestSense(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN UINTN DevicePosition, IN ATAPI_REQUEST_SENSE_DATA *SenseBuffers, IN OUT UINT8 *SenseCounts)
Definition: AtapiPeim.c:1980
EFI_STATUS WaitForBSYClear(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN IDE_BASE_REGISTERS *IdeIoRegisters, IN UINTN TimeoutInMilliSeconds)
Definition: AtapiPeim.c:851
EFI_STATUS CheckErrorStatus(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN UINT16 StatusReg)
Definition: AtapiPeim.c:1185
EFI_STATUS DetectMedia(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN UINTN DevicePosition, IN OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, IN OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2)
Definition: AtapiPeim.c:1721
BOOLEAN IsNoMedia(IN ATAPI_REQUEST_SENSE_DATA *SenseData, IN UINTN SenseCounts)
Definition: AtapiPeim.c:2281
BOOLEAN IsDriveReady(IN ATAPI_REQUEST_SENSE_DATA *SenseData, IN UINTN SenseCounts, OUT BOOLEAN *NeedRetry)
Definition: AtapiPeim.c:2429
EFI_STATUS DRQReady2(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN IDE_BASE_REGISTERS *IdeIoRegisters, IN UINTN TimeoutInMilliSeconds)
Definition: AtapiPeim.c:1129
BOOLEAN IsMediaError(IN ATAPI_REQUEST_SENSE_DATA *SenseData, IN UINTN SenseCounts)
Definition: AtapiPeim.c:2356
BOOLEAN IsDeviceStateUnclear(IN ATAPI_REQUEST_SENSE_DATA *SenseData, IN UINTN SenseCounts)
Definition: AtapiPeim.c:2316
EFI_STATUS EFIAPI AtapiReadBlocks2(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, IN UINTN DeviceIndex, IN EFI_PEI_LBA StartLBA, IN UINTN BufferSize, OUT VOID *Buffer)
Definition: AtapiPeim.c:475
EFI_STATUS EFIAPI AtapiGetBlockDeviceMediaInfo2(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, IN UINTN DeviceIndex, OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo)
Definition: AtapiPeim.c:402
EFI_STATUS ResetDevice(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN UINTN DevicePosition, IN BOOLEAN Extensive)
Definition: AtapiPeim.c:1883
EFI_STATUS DRQClear2(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN IDE_BASE_REGISTERS *IdeIoRegisters, IN UINTN TimeoutInMilliSeconds)
Definition: AtapiPeim.c:1009
EFI_STATUS Inquiry(IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, IN UINTN DevicePosition, OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2)
Definition: AtapiPeim.c:1624
EFI_STATUS EFIAPI AtapiGetNumberOfBlockDevices(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, OUT UINTN *NumberBlockDevices)
Definition: AtapiPeim.c:112
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define MSG_ATAPI_DP
Definition: DevicePath.h:326
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
EFI_STATUS EFIAPI PeiServicesRegisterForShadow(IN EFI_PEI_FILE_HANDLE FileHandle)
UINT8 EFIAPI IoWrite8(IN UINTN Port, IN UINT8 Value)
Definition: IoLibArmVirt.c:200
UINT8 EFIAPI IoRead8(IN UINTN Port)
Definition: IoLibArmVirt.c:175
UINT16 EFIAPI IoRead16(IN UINTN Port)
Definition: IoLibArmVirt.c:225
UINT16 EFIAPI IoWrite16(IN UINTN Port, IN UINT16 Value)
Definition: IoLibArmVirt.c:250
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define MIN(a, b)
Definition: Base.h:1007
#define VOID
Definition: Base.h:269
#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 ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:463
#define DEBUG(Expression)
Definition: DebugLib.h:435
@ IdeLS120
The recovery device is an IDE LS-120.
Definition: BlockIo.h:49
@ IdeCDROM
The recovery device is an IDE CD-ROM.
Definition: BlockIo.h:48
UINT64 EFI_PEI_LBA
Definition: BlockIo.h:41
#define PcdGet16(TokenName)
Definition: PcdLib.h:349
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
VOID *EFIAPI AllocatePages(IN UINTN Pages)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_PEI_READ_BLOCKS2 ReadBlocks
Definition: BlockIo2.h:212
EFI_PEI_GET_DEVICE_MEDIA_INFORMATION2 GetBlockDeviceMediaInfo
Definition: BlockIo2.h:207
EFI_PEI_GET_NUMBER_BLOCK_DEVICES2 GetNumberOfBlockDevices
Definition: BlockIo2.h:202
EFI_PEI_READ_BLOCKS ReadBlocks
Definition: BlockIo.h:227
EFI_PEI_GET_NUMBER_BLOCK_DEVICES GetNumberOfBlockDevices
Definition: BlockIo.h:217
EFI_PEI_GET_DEVICE_MEDIA_INFORMATION GetBlockDeviceMediaInfo
Definition: BlockIo.h:222
UINT8 page_code
defined in SFF8090i, V6
Definition: Atapi.h:363
UINT8 addnl_sense_code
mandatory
Definition: Atapi.h:295
UINT8 addnl_sense_code_qualifier
mandatory
Definition: Atapi.h:296
EFI_PEI_LBA LastBlock
Definition: BlockIo2.h:64
EFI_PEI_BLOCK_DEVICE_TYPE DeviceType
Definition: BlockIo.h:71
BOOLEAN MediaPresent
Definition: BlockIo.h:76
UINT16 CommandBlockBaseAddr
Definition: AtaController.h:82
UINT16 ControlBlockBaseAddr
Definition: AtaController.h:86