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