1 /** @file 2 PEIM to produce gEfiPeiVirtualBlockIoPpiGuid & gEfiPeiVirtualBlockIo2PpiGuid PPI for 3 ATA controllers in the platform. 4 5 This PPI can be consumed by PEIM which produce gEfiPeiDeviceRecoveryModulePpiGuid 6 for Atapi CD ROM device. 7 8 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR> 9 10 This program and the accompanying materials 11 are licensed and made available under the terms and conditions 12 of the BSD License which accompanies this distribution. The 13 full text of the license may be found at 14 http://opensource.org/licenses/bsd-license.php 15 16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 17 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 18 19 **/ 20 21 #include "AtapiPeim.h" 22 23 /** 24 Initializes the Atapi Block Io PPI. 25 26 @param[in] FileHandle Handle of the file being invoked. 27 @param[in] PeiServices Describes the list of possible PEI Services. 28 29 @retval EFI_SUCCESS Operation performed successfully. 30 @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate. 31 32 **/ 33 EFI_STATUS 34 EFIAPI 35 AtapiPeimEntry ( 36 IN EFI_PEI_FILE_HANDLE FileHandle, 37 IN CONST EFI_PEI_SERVICES **PeiServices 38 ) 39 { 40 PEI_ATA_CONTROLLER_PPI *AtaControllerPpi; 41 EFI_STATUS Status; 42 ATAPI_BLK_IO_DEV *AtapiBlkIoDev; 43 44 Status = PeiServicesRegisterForShadow (FileHandle); 45 if (!EFI_ERROR (Status)) { 46 return Status; 47 } 48 49 Status = PeiServicesLocatePpi ( 50 &gPeiAtaControllerPpiGuid, 51 0, 52 NULL, 53 (VOID **) &AtaControllerPpi 54 ); 55 ASSERT_EFI_ERROR (Status); 56 57 AtapiBlkIoDev = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (*AtapiBlkIoDev))); 58 if (AtapiBlkIoDev == NULL) { 59 return EFI_OUT_OF_RESOURCES; 60 } 61 62 AtapiBlkIoDev->Signature = ATAPI_BLK_IO_DEV_SIGNATURE; 63 AtapiBlkIoDev->AtaControllerPpi = AtaControllerPpi; 64 65 // 66 // atapi device enumeration and build private data 67 // 68 AtapiEnumerateDevices (AtapiBlkIoDev); 69 70 AtapiBlkIoDev->AtapiBlkIo.GetNumberOfBlockDevices = AtapiGetNumberOfBlockDevices; 71 AtapiBlkIoDev->AtapiBlkIo.GetBlockDeviceMediaInfo = AtapiGetBlockDeviceMediaInfo; 72 AtapiBlkIoDev->AtapiBlkIo.ReadBlocks = AtapiReadBlocks; 73 AtapiBlkIoDev->AtapiBlkIo2.Revision = EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION; 74 AtapiBlkIoDev->AtapiBlkIo2.GetNumberOfBlockDevices = AtapiGetNumberOfBlockDevices2; 75 AtapiBlkIoDev->AtapiBlkIo2.GetBlockDeviceMediaInfo = AtapiGetBlockDeviceMediaInfo2; 76 AtapiBlkIoDev->AtapiBlkIo2.ReadBlocks = AtapiReadBlocks2; 77 78 AtapiBlkIoDev->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI; 79 AtapiBlkIoDev->PpiDescriptor.Guid = &gEfiPeiVirtualBlockIoPpiGuid; 80 AtapiBlkIoDev->PpiDescriptor.Ppi = &AtapiBlkIoDev->AtapiBlkIo; 81 82 AtapiBlkIoDev->PpiDescriptor2.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); 83 AtapiBlkIoDev->PpiDescriptor2.Guid = &gEfiPeiVirtualBlockIo2PpiGuid; 84 AtapiBlkIoDev->PpiDescriptor2.Ppi = &AtapiBlkIoDev->AtapiBlkIo2; 85 86 DEBUG ((EFI_D_INFO, "Atatpi Device Count is %d\n", AtapiBlkIoDev->DeviceCount)); 87 if (AtapiBlkIoDev->DeviceCount != 0) { 88 Status = PeiServicesInstallPpi (&AtapiBlkIoDev->PpiDescriptor); 89 if (EFI_ERROR (Status)) { 90 return EFI_OUT_OF_RESOURCES; 91 } 92 } 93 94 return EFI_SUCCESS; 95 } 96 97 /** 98 Gets the count of block I/O devices that one specific block driver detects. 99 100 This function is used for getting the count of block I/O devices that one 101 specific block driver detects. To the PEI ATAPI driver, it returns the number 102 of all the detected ATAPI devices it detects during the enumeration process. 103 To the PEI legacy floppy driver, it returns the number of all the legacy 104 devices it finds during its enumeration process. If no device is detected, 105 then the function will return zero. 106 107 @param[in] PeiServices General-purpose services that are available 108 to every PEIM. 109 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI 110 instance. 111 @param[out] NumberBlockDevices The number of block I/O devices discovered. 112 113 @retval EFI_SUCCESS Operation performed successfully. 114 115 **/ 116 EFI_STATUS 117 EFIAPI 118 AtapiGetNumberOfBlockDevices ( 119 IN EFI_PEI_SERVICES **PeiServices, 120 IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, 121 OUT UINTN *NumberBlockDevices 122 ) 123 { 124 ATAPI_BLK_IO_DEV *AtapiBlkIoDev; 125 126 AtapiBlkIoDev = NULL; 127 128 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO_THIS (This); 129 130 *NumberBlockDevices = AtapiBlkIoDev->DeviceCount; 131 132 return EFI_SUCCESS; 133 } 134 135 /** 136 Gets a block device's media information. 137 138 This function will provide the caller with the specified block device's media 139 information. If the media changes, calling this function will update the media 140 information accordingly. 141 142 @param[in] PeiServices General-purpose services that are available to every 143 PEIM 144 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. 145 @param[in] DeviceIndex Specifies the block device to which the function wants 146 to talk. Because the driver that implements Block I/O 147 PPIs will manage multiple block devices, the PPIs that 148 want to talk to a single device must specify the 149 device index that was assigned during the enumeration 150 process. This index is a number from one to 151 NumberBlockDevices. 152 @param[out] MediaInfo The media information of the specified block media. 153 The caller is responsible for the ownership of this 154 data structure. 155 156 @retval EFI_SUCCESS Media information about the specified block device 157 was obtained successfully. 158 @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware 159 error. 160 @retval Others Other failure occurs. 161 162 **/ 163 EFI_STATUS 164 EFIAPI 165 AtapiGetBlockDeviceMediaInfo ( 166 IN EFI_PEI_SERVICES **PeiServices, 167 IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, 168 IN UINTN DeviceIndex, 169 OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo 170 ) 171 { 172 UINTN DeviceCount; 173 ATAPI_BLK_IO_DEV *AtapiBlkIoDev; 174 EFI_STATUS Status; 175 UINTN Index; 176 177 AtapiBlkIoDev = NULL; 178 179 if (This == NULL || MediaInfo == NULL) { 180 return EFI_INVALID_PARAMETER; 181 } 182 183 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO_THIS (This); 184 185 DeviceCount = AtapiBlkIoDev->DeviceCount; 186 187 // 188 // DeviceIndex is a value from 1 to NumberBlockDevices. 189 // 190 if ((DeviceIndex < 1) || (DeviceIndex > DeviceCount) || (DeviceIndex > MAX_IDE_DEVICES)) { 191 return EFI_INVALID_PARAMETER; 192 } 193 194 Index = DeviceIndex - 1; 195 196 // 197 // probe media and retrieve latest media information 198 // 199 DEBUG ((EFI_D_INFO, "Atatpi GetInfo DevicePosition is %d\n", AtapiBlkIoDev->DeviceInfo[Index].DevicePosition)); 200 DEBUG ((EFI_D_INFO, "Atatpi GetInfo DeviceType is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.DeviceType)); 201 DEBUG ((EFI_D_INFO, "Atatpi GetInfo MediaPresent is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.MediaPresent)); 202 DEBUG ((EFI_D_INFO, "Atatpi GetInfo BlockSize is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.BlockSize)); 203 DEBUG ((EFI_D_INFO, "Atatpi GetInfo LastBlock is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.LastBlock)); 204 205 Status = DetectMedia ( 206 AtapiBlkIoDev, 207 AtapiBlkIoDev->DeviceInfo[Index].DevicePosition, 208 &AtapiBlkIoDev->DeviceInfo[Index].MediaInfo, 209 &AtapiBlkIoDev->DeviceInfo[Index].MediaInfo2 210 ); 211 if (Status != EFI_SUCCESS) { 212 return EFI_DEVICE_ERROR; 213 } 214 215 DEBUG ((EFI_D_INFO, "Atatpi GetInfo DevicePosition is %d\n", AtapiBlkIoDev->DeviceInfo[Index].DevicePosition)); 216 DEBUG ((EFI_D_INFO, "Atatpi GetInfo DeviceType is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.DeviceType)); 217 DEBUG ((EFI_D_INFO, "Atatpi GetInfo MediaPresent is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.MediaPresent)); 218 DEBUG ((EFI_D_INFO, "Atatpi GetInfo BlockSize is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.BlockSize)); 219 DEBUG ((EFI_D_INFO, "Atatpi GetInfo LastBlock is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.LastBlock)); 220 221 // 222 // Get media info from AtapiBlkIoDev 223 // 224 CopyMem (MediaInfo, &AtapiBlkIoDev->DeviceInfo[Index].MediaInfo, sizeof(EFI_PEI_BLOCK_IO_MEDIA)); 225 226 return EFI_SUCCESS; 227 } 228 229 /** 230 Reads the requested number of blocks from the specified block device. 231 232 The function reads the requested number of blocks from the device. All the 233 blocks are read, or an error is returned. If there is no media in the device, 234 the function returns EFI_NO_MEDIA. 235 236 @param[in] PeiServices General-purpose services that are available to 237 every PEIM. 238 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. 239 @param[in] DeviceIndex Specifies the block device to which the function wants 240 to talk. Because the driver that implements Block I/O 241 PPIs will manage multiple block devices, the PPIs that 242 want to talk to a single device must specify the device 243 index that was assigned during the enumeration process. 244 This index is a number from one to NumberBlockDevices. 245 @param[in] StartLBA The starting logical block address (LBA) to read from 246 on the device 247 @param[in] BufferSize The size of the Buffer in bytes. This number must be 248 a multiple of the intrinsic block size of the device. 249 @param[out] Buffer A pointer to the destination buffer for the data. 250 The caller is responsible for the ownership of the 251 buffer. 252 253 @retval EFI_SUCCESS The data was read correctly from the device. 254 @retval EFI_DEVICE_ERROR The device reported an error while attempting 255 to perform the read operation. 256 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not 257 valid, or the buffer is not properly aligned. 258 @retval EFI_NO_MEDIA There is no media in the device. 259 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of 260 the intrinsic block size of the device. 261 262 **/ 263 EFI_STATUS 264 EFIAPI 265 AtapiReadBlocks ( 266 IN EFI_PEI_SERVICES **PeiServices, 267 IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, 268 IN UINTN DeviceIndex, 269 IN EFI_PEI_LBA StartLBA, 270 IN UINTN BufferSize, 271 OUT VOID *Buffer 272 ) 273 { 274 275 EFI_PEI_BLOCK_IO_MEDIA MediaInfo; 276 EFI_STATUS Status; 277 UINTN NumberOfBlocks; 278 UINTN BlockSize; 279 ATAPI_BLK_IO_DEV *AtapiBlkIoDev; 280 281 AtapiBlkIoDev = NULL; 282 283 if (This == NULL) { 284 return EFI_INVALID_PARAMETER; 285 } 286 287 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO_THIS (This); 288 289 if (Buffer == NULL) { 290 return EFI_INVALID_PARAMETER; 291 } 292 293 if (BufferSize == 0) { 294 return EFI_SUCCESS; 295 } 296 297 Status = AtapiGetBlockDeviceMediaInfo ( 298 PeiServices, 299 This, 300 DeviceIndex, 301 &MediaInfo 302 ); 303 if (Status != EFI_SUCCESS) { 304 return EFI_DEVICE_ERROR; 305 } 306 307 if (!MediaInfo.MediaPresent) { 308 return EFI_NO_MEDIA; 309 } 310 311 BlockSize = MediaInfo.BlockSize; 312 313 if (BufferSize % BlockSize != 0) { 314 return EFI_BAD_BUFFER_SIZE; 315 } 316 317 NumberOfBlocks = BufferSize / BlockSize; 318 319 if ((StartLBA + NumberOfBlocks - 1) > AtapiBlkIoDev->DeviceInfo[DeviceIndex - 1].MediaInfo2.LastBlock) { 320 return EFI_INVALID_PARAMETER; 321 } 322 323 Status = ReadSectors ( 324 AtapiBlkIoDev, 325 AtapiBlkIoDev->DeviceInfo[DeviceIndex - 1].DevicePosition, 326 Buffer, 327 StartLBA, 328 NumberOfBlocks, 329 BlockSize 330 ); 331 if (EFI_ERROR (Status)) { 332 return EFI_DEVICE_ERROR; 333 } 334 335 return EFI_SUCCESS; 336 } 337 338 /** 339 Gets the count of block I/O devices that one specific block driver detects. 340 341 This function is used for getting the count of block I/O devices that one 342 specific block driver detects. To the PEI ATAPI driver, it returns the number 343 of all the detected ATAPI devices it detects during the enumeration process. 344 To the PEI legacy floppy driver, it returns the number of all the legacy 345 devices it finds during its enumeration process. If no device is detected, 346 then the function will return zero. 347 348 @param[in] PeiServices General-purpose services that are available 349 to every PEIM. 350 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI 351 instance. 352 @param[out] NumberBlockDevices The number of block I/O devices discovered. 353 354 @retval EFI_SUCCESS Operation performed successfully. 355 356 **/ 357 EFI_STATUS 358 EFIAPI 359 AtapiGetNumberOfBlockDevices2 ( 360 IN EFI_PEI_SERVICES **PeiServices, 361 IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, 362 OUT UINTN *NumberBlockDevices 363 ) 364 { 365 EFI_STATUS Status; 366 ATAPI_BLK_IO_DEV *AtapiBlkIoDev; 367 368 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO2_THIS (This); 369 370 Status = AtapiGetNumberOfBlockDevices ( 371 PeiServices, 372 &AtapiBlkIoDev->AtapiBlkIo, 373 NumberBlockDevices 374 ); 375 376 return Status; 377 } 378 379 /** 380 Gets a block device's media information. 381 382 This function will provide the caller with the specified block device's media 383 information. If the media changes, calling this function will update the media 384 information accordingly. 385 386 @param[in] PeiServices General-purpose services that are available to every 387 PEIM 388 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance. 389 @param[in] DeviceIndex Specifies the block device to which the function wants 390 to talk. Because the driver that implements Block I/O 391 PPIs will manage multiple block devices, the PPIs that 392 want to talk to a single device must specify the 393 device index that was assigned during the enumeration 394 process. This index is a number from one to 395 NumberBlockDevices. 396 @param[out] MediaInfo The media information of the specified block media. 397 The caller is responsible for the ownership of this 398 data structure. 399 400 @retval EFI_SUCCESS Media information about the specified block device 401 was obtained successfully. 402 @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware 403 error. 404 @retval Others Other failure occurs. 405 406 **/ 407 EFI_STATUS 408 EFIAPI 409 AtapiGetBlockDeviceMediaInfo2 ( 410 IN EFI_PEI_SERVICES **PeiServices, 411 IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, 412 IN UINTN DeviceIndex, 413 OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo 414 ) 415 { 416 ATAPI_BLK_IO_DEV *AtapiBlkIoDev; 417 EFI_STATUS Status; 418 EFI_PEI_BLOCK_IO_MEDIA Media; 419 420 AtapiBlkIoDev = NULL; 421 422 if (This == NULL || MediaInfo == NULL) { 423 return EFI_INVALID_PARAMETER; 424 } 425 426 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO2_THIS (This); 427 428 Status = AtapiGetBlockDeviceMediaInfo ( 429 PeiServices, 430 &AtapiBlkIoDev->AtapiBlkIo, 431 DeviceIndex, 432 &Media 433 ); 434 if (EFI_ERROR (Status)) { 435 return Status; 436 } 437 // 438 // Get media info from AtapiBlkIoDev 439 // 440 CopyMem (MediaInfo, &AtapiBlkIoDev->DeviceInfo[DeviceIndex - 1].MediaInfo2, sizeof(EFI_PEI_BLOCK_IO2_MEDIA)); 441 442 return EFI_SUCCESS; 443 } 444 445 /** 446 Reads the requested number of blocks from the specified block device. 447 448 The function reads the requested number of blocks from the device. All the 449 blocks are read, or an error is returned. If there is no media in the device, 450 the function returns EFI_NO_MEDIA. 451 452 @param[in] PeiServices General-purpose services that are available to 453 every PEIM. 454 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance. 455 @param[in] DeviceIndex Specifies the block device to which the function wants 456 to talk. Because the driver that implements Block I/O 457 PPIs will manage multiple block devices, the PPIs that 458 want to talk to a single device must specify the device 459 index that was assigned during the enumeration process. 460 This index is a number from one to NumberBlockDevices. 461 @param[in] StartLBA The starting logical block address (LBA) to read from 462 on the device 463 @param[in] BufferSize The size of the Buffer in bytes. This number must be 464 a multiple of the intrinsic block size of the device. 465 @param[out] Buffer A pointer to the destination buffer for the data. 466 The caller is responsible for the ownership of the 467 buffer. 468 469 @retval EFI_SUCCESS The data was read correctly from the device. 470 @retval EFI_DEVICE_ERROR The device reported an error while attempting 471 to perform the read operation. 472 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not 473 valid, or the buffer is not properly aligned. 474 @retval EFI_NO_MEDIA There is no media in the device. 475 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of 476 the intrinsic block size of the device. 477 478 **/ 479 EFI_STATUS 480 EFIAPI 481 AtapiReadBlocks2 ( 482 IN EFI_PEI_SERVICES **PeiServices, 483 IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, 484 IN UINTN DeviceIndex, 485 IN EFI_PEI_LBA StartLBA, 486 IN UINTN BufferSize, 487 OUT VOID *Buffer 488 ) 489 { 490 EFI_STATUS Status; 491 ATAPI_BLK_IO_DEV *AtapiBlkIoDev; 492 493 AtapiBlkIoDev = NULL; 494 495 if (This == NULL) { 496 return EFI_INVALID_PARAMETER; 497 } 498 499 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO2_THIS (This); 500 501 Status = AtapiReadBlocks ( 502 PeiServices, 503 &AtapiBlkIoDev->AtapiBlkIo, 504 DeviceIndex, 505 StartLBA, 506 BufferSize, 507 Buffer 508 ); 509 510 return Status; 511 } 512 513 514 /** 515 Enumerate Atapi devices. 516 517 This function is used to enumerate Atatpi device in Ide channel. 518 519 @param[in] AtapiBlkIoDev A pointer to atapi block IO device 520 521 **/ 522 VOID 523 AtapiEnumerateDevices ( 524 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev 525 ) 526 { 527 UINT8 Index1; 528 UINT8 Index2; 529 UINTN DevicePosition; 530 EFI_PEI_BLOCK_IO_MEDIA MediaInfo; 531 EFI_PEI_BLOCK_IO2_MEDIA MediaInfo2; 532 EFI_STATUS Status; 533 UINTN DeviceCount; 534 UINT16 CommandBlockBaseAddr; 535 UINT16 ControlBlockBaseAddr; 536 UINT32 IdeEnabledNumber; 537 IDE_REGS_BASE_ADDR IdeRegsBaseAddr[MAX_IDE_CHANNELS]; 538 539 DeviceCount = 0; 540 DevicePosition = 0; 541 542 // 543 // Scan IDE bus for ATAPI devices 544 // 545 546 // 547 // Enable Sata and IDE controller. 548 // 549 AtapiBlkIoDev->AtaControllerPpi->EnableAtaChannel ( 550 (EFI_PEI_SERVICES **) GetPeiServicesTablePointer(), 551 AtapiBlkIoDev->AtaControllerPpi, 552 PEI_ICH_IDE_PRIMARY | PEI_ICH_IDE_SECONDARY 553 ); 554 555 // 556 // Allow SATA Devices to spin-up. This is needed if 557 // SEC and PEI phase is too short, for example Release Build. 558 // 559 DEBUG ((EFI_D_INFO, "Delay for %d seconds for SATA devices to spin-up\n", PcdGet16 (PcdSataSpinUpDelayInSecForRecoveryPath))); 560 MicroSecondDelay (PcdGet16 (PcdSataSpinUpDelayInSecForRecoveryPath) * 1000 * 1000); // 561 562 // 563 // Get four channels (primary or secondary Pata, Sata Channel) Command and Control Regs Base address. 564 // 565 IdeEnabledNumber = AtapiBlkIoDev->AtaControllerPpi->GetIdeRegsBaseAddr ( 566 (EFI_PEI_SERVICES **) GetPeiServicesTablePointer(), 567 AtapiBlkIoDev->AtaControllerPpi, 568 IdeRegsBaseAddr 569 ); 570 571 // 572 // Using Command and Control Regs Base Address to fill other registers. 573 // 574 for (Index1 = 0; Index1 < IdeEnabledNumber; Index1 ++) { 575 CommandBlockBaseAddr = IdeRegsBaseAddr[Index1].CommandBlockBaseAddr; 576 AtapiBlkIoDev->IdeIoPortReg[Index1].Data = CommandBlockBaseAddr; 577 AtapiBlkIoDev->IdeIoPortReg[Index1].Reg1.Feature = (UINT16) (CommandBlockBaseAddr + 0x1); 578 AtapiBlkIoDev->IdeIoPortReg[Index1].SectorCount = (UINT16) (CommandBlockBaseAddr + 0x2); 579 AtapiBlkIoDev->IdeIoPortReg[Index1].SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x3); 580 AtapiBlkIoDev->IdeIoPortReg[Index1].CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x4); 581 AtapiBlkIoDev->IdeIoPortReg[Index1].CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x5); 582 AtapiBlkIoDev->IdeIoPortReg[Index1].Head = (UINT16) (CommandBlockBaseAddr + 0x6); 583 AtapiBlkIoDev->IdeIoPortReg[Index1].Reg.Command = (UINT16) (CommandBlockBaseAddr + 0x7); 584 585 ControlBlockBaseAddr = IdeRegsBaseAddr[Index1].ControlBlockBaseAddr; 586 AtapiBlkIoDev->IdeIoPortReg[Index1].Alt.DeviceControl = ControlBlockBaseAddr; 587 AtapiBlkIoDev->IdeIoPortReg[Index1].DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x1); 588 589 // 590 // Scan IDE bus for ATAPI devices IDE or Sata device 591 // 592 for (Index2 = IdeMaster; Index2 < IdeMaxDevice; Index2++) { 593 // 594 // Pata & Sata, Primary & Secondary channel, Master & Slave device 595 // 596 DevicePosition = (UINTN) (Index1 * 2 + Index2); 597 598 if (DiscoverAtapiDevice (AtapiBlkIoDev, DevicePosition, &MediaInfo, &MediaInfo2)) { 599 // 600 // ATAPI Device at DevicePosition is found. 601 // 602 AtapiBlkIoDev->DeviceInfo[DeviceCount].DevicePosition = DevicePosition; 603 // 604 // Retrieve Media Info 605 // 606 Status = DetectMedia (AtapiBlkIoDev, DevicePosition, &MediaInfo, &MediaInfo2); 607 CopyMem (&(AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo), &MediaInfo, sizeof (MediaInfo)); 608 CopyMem (&(AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo2), &MediaInfo2, sizeof (MediaInfo2)); 609 610 DEBUG ((EFI_D_INFO, "Atatpi Device Position is %d\n", DevicePosition)); 611 DEBUG ((EFI_D_INFO, "Atatpi DeviceType is %d\n", MediaInfo.DeviceType)); 612 DEBUG ((EFI_D_INFO, "Atatpi MediaPresent is %d\n", MediaInfo.MediaPresent)); 613 DEBUG ((EFI_D_INFO, "Atatpi BlockSize is 0x%x\n", MediaInfo.BlockSize)); 614 615 if (EFI_ERROR (Status)) { 616 AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo.MediaPresent = FALSE; 617 AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo.LastBlock = 0; 618 AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo2.MediaPresent = FALSE; 619 AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo2.LastBlock = 0; 620 } 621 DeviceCount += 1; 622 } 623 } 624 } 625 626 AtapiBlkIoDev->DeviceCount = DeviceCount; 627 } 628 629 /** 630 Detect Atapi devices. 631 632 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 633 @param[in] DevicePosition An integer to signify device position. 634 @param[out] MediaInfo The media information of the specified block media. 635 @param[out] MediaInfo2 The media information 2 of the specified block media. 636 637 @retval TRUE Atapi device exists in specified position. 638 @retval FALSE Atapi device does not exist in specified position. 639 640 **/ 641 BOOLEAN 642 DiscoverAtapiDevice ( 643 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 644 IN UINTN DevicePosition, 645 OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, 646 OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2 647 ) 648 { 649 EFI_STATUS Status; 650 651 if (!DetectIDEController (AtapiBlkIoDev, DevicePosition)) { 652 return FALSE; 653 } 654 // 655 // test if it is an ATAPI device (only supported device) 656 // 657 if (ATAPIIdentify (AtapiBlkIoDev, DevicePosition) == EFI_SUCCESS) { 658 659 Status = Inquiry (AtapiBlkIoDev, DevicePosition, MediaInfo, MediaInfo2); 660 if (!EFI_ERROR (Status)) { 661 return TRUE; 662 } 663 } 664 665 return FALSE; 666 } 667 668 /** 669 Check power mode of Atapi devices. 670 671 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 672 @param[in] DevicePosition An integer to signify device position. 673 @param[in] AtaCommand The Ata Command passed in. 674 675 @retval EFI_SUCCESS The Atapi device support power mode. 676 @retval EFI_NOT_FOUND The Atapi device not found. 677 @retval EFI_TIMEOUT Atapi command transaction is time out. 678 @retval EFI_ABORTED Atapi command abort. 679 680 **/ 681 EFI_STATUS 682 CheckPowerMode ( 683 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 684 IN UINTN DevicePosition, 685 IN UINT8 AtaCommand 686 ) 687 { 688 UINT8 Channel; 689 UINT8 Device; 690 UINT16 StatusRegister; 691 UINT16 HeadRegister; 692 UINT16 CommandRegister; 693 UINT16 ErrorRegister; 694 UINT16 SectorCountRegister; 695 EFI_STATUS Status; 696 UINT8 StatusValue; 697 UINT8 ErrorValue; 698 UINT8 SectorCountValue; 699 700 Channel = (UINT8) (DevicePosition / 2); 701 Device = (UINT8) (DevicePosition % 2); 702 703 ASSERT (Channel < MAX_IDE_CHANNELS); 704 705 StatusRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Status; 706 HeadRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Head; 707 CommandRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command; 708 ErrorRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg1.Error; 709 SectorCountRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].SectorCount; 710 711 // 712 // select device 713 // 714 IoWrite8 (HeadRegister, (UINT8) ((Device << 4) | 0xe0)); 715 716 // 717 // refresh the SectorCount register 718 // 719 SectorCountValue = 0x55; 720 IoWrite8 (SectorCountRegister, SectorCountValue); 721 722 // 723 // select device 724 // 725 IoWrite8 (HeadRegister, (UINT8) ((Device << 4) | 0xe0)); 726 727 Status = DRDYReady (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 100); 728 729 // 730 // select device 731 // 732 IoWrite8 (HeadRegister, (UINT8) ((Device << 4) | 0xe0)); 733 // 734 // send 'check power' commandd via Command Register 735 // 736 IoWrite8 (CommandRegister, AtaCommand); 737 738 Status = WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 3000); 739 if (EFI_ERROR (Status)) { 740 return EFI_TIMEOUT; 741 } 742 743 StatusValue = IoRead8 (StatusRegister); 744 745 // 746 // command returned status is DRDY, indicating device supports the command, 747 // so device is present. 748 // 749 if ((StatusValue & ATA_STSREG_DRDY) == ATA_STSREG_DRDY) { 750 return EFI_SUCCESS; 751 } 752 753 SectorCountValue = IoRead8 (SectorCountRegister); 754 755 // 756 // command returned status is ERR & ABRT_ERR, indicating device does not support 757 // the command, so device is present. 758 // 759 if ((StatusValue & ATA_STSREG_ERR) == ATA_STSREG_ERR) { 760 ErrorValue = IoRead8 (ErrorRegister); 761 if ((ErrorValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { 762 return EFI_ABORTED; 763 } else { 764 // 765 // According to spec, no other error code is valid 766 // 767 return EFI_NOT_FOUND; 768 } 769 } 770 771 if ((SectorCountValue == 0x00) || (SectorCountValue == 0x80) || (SectorCountValue == 0xff)) { 772 // 773 // Write SectorCount 0x55 but return valid state value. Maybe no device 774 // exists or some slow kind of ATAPI device exists. 775 // 776 IoWrite8 (HeadRegister, (UINT8) ((Device << 4) | 0xe0)); 777 778 // 779 // write 0x55 and 0xaa to SectorCounter register, 780 // if the data could be written into the register, 781 // indicating the device is present, otherwise the device is not present. 782 // 783 SectorCountValue = 0x55; 784 IoWrite8 (SectorCountRegister, SectorCountValue); 785 MicroSecondDelay (10000); 786 787 SectorCountValue = IoRead8 (SectorCountRegister); 788 if (SectorCountValue != 0x55) { 789 return EFI_NOT_FOUND; 790 } 791 // 792 // Send a "ATAPI TEST UNIT READY" command ... slow but accurate 793 // 794 Status = TestUnitReady (AtapiBlkIoDev, DevicePosition); 795 return Status; 796 } 797 798 return EFI_NOT_FOUND; 799 } 800 801 /** 802 Detect if an IDE controller exists in specified position. 803 804 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 805 @param[in] DevicePosition An integer to signify device position. 806 807 @retval TRUE The Atapi device exists. 808 @retval FALSE The Atapi device does not present. 809 810 **/ 811 BOOLEAN 812 DetectIDEController ( 813 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 814 IN UINTN DevicePosition 815 ) 816 { 817 UINT8 Channel; 818 EFI_STATUS Status; 819 UINT8 AtaCommand; 820 821 Channel = (UINT8) (DevicePosition / 2); 822 823 ASSERT (Channel < MAX_IDE_CHANNELS); 824 // 825 // Wait 31 seconds for BSY clear 826 // 827 Status = WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 31000); 828 if (EFI_ERROR (Status)) { 829 return FALSE; 830 } 831 // 832 // Send 'check power' command for IDE device 833 // 834 AtaCommand = 0xE5; 835 Status = CheckPowerMode (AtapiBlkIoDev, DevicePosition, AtaCommand); 836 if ((Status == EFI_ABORTED) || (Status == EFI_SUCCESS)) { 837 return TRUE; 838 } 839 840 return FALSE; 841 } 842 843 /** 844 Wait specified time interval to poll for BSY bit clear in the Status Register. 845 846 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 847 @param[in] IdeIoRegisters A pointer to IDE IO registers. 848 @param[in] TimeoutInMilliSeconds Time specified in milliseconds. 849 850 @retval EFI_SUCCESS BSY bit is cleared in the specified time interval. 851 @retval EFI_TIMEOUT BSY bit is not cleared in the specified time interval. 852 853 **/ 854 EFI_STATUS 855 WaitForBSYClear ( 856 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 857 IN IDE_BASE_REGISTERS *IdeIoRegisters, 858 IN UINTN TimeoutInMilliSeconds 859 ) 860 { 861 UINTN Delay; 862 UINT16 StatusRegister; 863 UINT8 StatusValue; 864 865 StatusValue = 0; 866 867 StatusRegister = IdeIoRegisters->Reg.Status; 868 869 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1; 870 do { 871 StatusValue = IoRead8 (StatusRegister); 872 if ((StatusValue & ATA_STSREG_BSY) == 0x00) { 873 break; 874 } 875 MicroSecondDelay (250); 876 877 Delay--; 878 879 } while (Delay != 0); 880 881 if (Delay == 0) { 882 return EFI_TIMEOUT; 883 } 884 885 return EFI_SUCCESS; 886 } 887 888 /** 889 Wait specified time interval to poll for DRDY bit set in the Status register. 890 891 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 892 @param[in] IdeIoRegisters A pointer to IDE IO registers. 893 @param[in] TimeoutInMilliSeconds Time specified in milliseconds. 894 895 @retval EFI_SUCCESS DRDY bit is set in the specified time interval. 896 @retval EFI_TIMEOUT DRDY bit is not set in the specified time interval. 897 898 **/ 899 EFI_STATUS 900 DRDYReady ( 901 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 902 IN IDE_BASE_REGISTERS *IdeIoRegisters, 903 IN UINTN TimeoutInMilliSeconds 904 ) 905 { 906 UINTN Delay; 907 UINT16 StatusRegister; 908 UINT8 StatusValue; 909 UINT8 ErrValue; 910 911 StatusValue = 0; 912 913 StatusRegister = IdeIoRegisters->Reg.Status; 914 915 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1; 916 do { 917 StatusValue = IoRead8 (StatusRegister); 918 // 919 // BSY == 0 , DRDY == 1 920 // 921 if ((StatusValue & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) { 922 break; 923 } 924 925 if ((StatusValue & (ATA_STSREG_ERR | ATA_STSREG_BSY)) == ATA_STSREG_ERR) { 926 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error); 927 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { 928 return EFI_ABORTED; 929 } 930 } 931 932 MicroSecondDelay (250); 933 934 Delay--; 935 936 } while (Delay != 0); 937 938 if (Delay == 0) { 939 return EFI_TIMEOUT; 940 } 941 942 return EFI_SUCCESS; 943 } 944 945 /** 946 Wait specified time interval to poll for DRQ bit clear in the Status Register. 947 948 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 949 @param[in] IdeIoRegisters A pointer to IDE IO registers. 950 @param[in] TimeoutInMilliSeconds Time specified in milliseconds. 951 952 @retval EFI_SUCCESS DRQ bit is cleared in the specified time interval. 953 @retval EFI_TIMEOUT DRQ bit is not cleared in the specified time interval. 954 955 **/ 956 EFI_STATUS 957 DRQClear ( 958 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 959 IN IDE_BASE_REGISTERS *IdeIoRegisters, 960 IN UINTN TimeoutInMilliSeconds 961 ) 962 { 963 UINTN Delay; 964 UINT16 StatusRegister; 965 UINT8 StatusValue; 966 UINT8 ErrValue; 967 968 StatusValue = 0; 969 970 StatusRegister = IdeIoRegisters->Reg.Status; 971 972 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1; 973 do { 974 975 StatusValue = IoRead8 (StatusRegister); 976 977 // 978 // wait for BSY == 0 and DRQ == 0 979 // 980 if ((StatusValue & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) { 981 break; 982 } 983 984 if ((StatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { 985 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error); 986 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { 987 return EFI_ABORTED; 988 } 989 } 990 991 MicroSecondDelay (250); 992 993 Delay--; 994 } while (Delay != 0); 995 996 if (Delay == 0) { 997 return EFI_TIMEOUT; 998 } 999 1000 return EFI_SUCCESS; 1001 } 1002 1003 /** 1004 Wait specified time interval to poll for DRQ bit clear in the Alternate Status Register. 1005 1006 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 1007 @param[in] IdeIoRegisters A pointer to IDE IO registers. 1008 @param[in] TimeoutInMilliSeconds Time specified in milliseconds. 1009 1010 @retval EFI_SUCCESS DRQ bit is cleared in the specified time interval. 1011 @retval EFI_TIMEOUT DRQ bit is not cleared in the specified time interval. 1012 1013 **/ 1014 EFI_STATUS 1015 DRQClear2 ( 1016 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 1017 IN IDE_BASE_REGISTERS *IdeIoRegisters, 1018 IN UINTN TimeoutInMilliSeconds 1019 ) 1020 { 1021 UINTN Delay; 1022 UINT16 AltStatusRegister; 1023 UINT8 AltStatusValue; 1024 UINT8 ErrValue; 1025 1026 AltStatusValue = 0; 1027 1028 AltStatusRegister = IdeIoRegisters->Alt.AltStatus; 1029 1030 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1; 1031 do { 1032 1033 AltStatusValue = IoRead8 (AltStatusRegister); 1034 1035 // 1036 // wait for BSY == 0 and DRQ == 0 1037 // 1038 if ((AltStatusValue & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) { 1039 break; 1040 } 1041 1042 if ((AltStatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { 1043 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error); 1044 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { 1045 return EFI_ABORTED; 1046 } 1047 } 1048 1049 MicroSecondDelay (250); 1050 1051 Delay--; 1052 } while (Delay != 0); 1053 1054 if (Delay == 0) { 1055 return EFI_TIMEOUT; 1056 } 1057 1058 return EFI_SUCCESS; 1059 } 1060 1061 /** 1062 Wait specified time interval to poll for DRQ bit set in the Status Register. 1063 1064 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 1065 @param[in] IdeIoRegisters A pointer to IDE IO registers. 1066 @param[in] TimeoutInMilliSeconds Time specified in milliseconds. 1067 1068 @retval EFI_SUCCESS DRQ bit is set in the specified time interval. 1069 @retval EFI_TIMEOUT DRQ bit is not set in the specified time interval. 1070 @retval EFI_ABORTED Operation Aborted. 1071 1072 **/ 1073 EFI_STATUS 1074 DRQReady ( 1075 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 1076 IN IDE_BASE_REGISTERS *IdeIoRegisters, 1077 IN UINTN TimeoutInMilliSeconds 1078 ) 1079 { 1080 UINTN Delay; 1081 UINT16 StatusRegister; 1082 UINT8 StatusValue; 1083 UINT8 ErrValue; 1084 1085 StatusValue = 0; 1086 ErrValue = 0; 1087 1088 StatusRegister = IdeIoRegisters->Reg.Status; 1089 1090 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1; 1091 do { 1092 // 1093 // read Status Register will clear interrupt 1094 // 1095 StatusValue = IoRead8 (StatusRegister); 1096 1097 // 1098 // BSY==0,DRQ==1 1099 // 1100 if ((StatusValue & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { 1101 break; 1102 } 1103 1104 if ((StatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { 1105 1106 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error); 1107 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { 1108 return EFI_ABORTED; 1109 } 1110 } 1111 MicroSecondDelay (250); 1112 1113 Delay--; 1114 } while (Delay != 0); 1115 1116 if (Delay == 0) { 1117 return EFI_TIMEOUT; 1118 } 1119 1120 return EFI_SUCCESS; 1121 } 1122 1123 /** 1124 Wait specified time interval to poll for DRQ bit set in the Alternate Status Register. 1125 1126 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 1127 @param[in] IdeIoRegisters A pointer to IDE IO registers. 1128 @param[in] TimeoutInMilliSeconds Time specified in milliseconds. 1129 1130 @retval EFI_SUCCESS DRQ bit is set in the specified time interval. 1131 @retval EFI_TIMEOUT DRQ bit is not set in the specified time interval. 1132 @retval EFI_ABORTED Operation Aborted. 1133 1134 **/ 1135 EFI_STATUS 1136 DRQReady2 ( 1137 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 1138 IN IDE_BASE_REGISTERS *IdeIoRegisters, 1139 IN UINTN TimeoutInMilliSeconds 1140 ) 1141 { 1142 UINTN Delay; 1143 UINT16 AltStatusRegister; 1144 UINT8 AltStatusValue; 1145 UINT8 ErrValue; 1146 1147 AltStatusValue = 0; 1148 1149 AltStatusRegister = IdeIoRegisters->Alt.AltStatus; 1150 1151 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1; 1152 do { 1153 1154 AltStatusValue = IoRead8 (AltStatusRegister); 1155 1156 // 1157 // BSY==0,DRQ==1 1158 // 1159 if ((AltStatusValue & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { 1160 break; 1161 } 1162 1163 if ((AltStatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { 1164 1165 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error); 1166 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { 1167 return EFI_ABORTED; 1168 } 1169 } 1170 MicroSecondDelay (250); 1171 1172 Delay--; 1173 } while (Delay != 0); 1174 1175 if (Delay == 0) { 1176 return EFI_TIMEOUT; 1177 } 1178 1179 return EFI_SUCCESS; 1180 } 1181 1182 /** 1183 Check if there is an error in Status Register. 1184 1185 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 1186 @param[in] StatusReg The address to IDE IO registers. 1187 1188 @retval EFI_SUCCESS Operation success. 1189 @retval EFI_DEVICE_ERROR Device error. 1190 1191 **/ 1192 EFI_STATUS 1193 CheckErrorStatus ( 1194 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 1195 IN UINT16 StatusReg 1196 ) 1197 { 1198 UINT8 StatusValue; 1199 1200 StatusValue = IoRead8 (StatusReg); 1201 1202 if ((StatusValue & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) { 1203 1204 return EFI_SUCCESS; 1205 } 1206 1207 return EFI_DEVICE_ERROR; 1208 1209 } 1210 1211 /** 1212 Idendify Atapi devices. 1213 1214 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 1215 @param[in] DevicePosition An integer to signify device position. 1216 1217 @retval EFI_SUCCESS Identify successfully. 1218 @retval EFI_DEVICE_ERROR Device cannot be identified successfully. 1219 1220 **/ 1221 EFI_STATUS 1222 ATAPIIdentify ( 1223 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 1224 IN UINTN DevicePosition 1225 ) 1226 { 1227 ATAPI_IDENTIFY_DATA AtapiIdentifyData; 1228 UINT8 Channel; 1229 UINT8 Device; 1230 UINT16 StatusReg; 1231 UINT16 HeadReg; 1232 UINT16 CommandReg; 1233 UINT16 DataReg; 1234 UINT16 SectorCountReg; 1235 UINT16 SectorNumberReg; 1236 UINT16 CylinderLsbReg; 1237 UINT16 CylinderMsbReg; 1238 1239 UINT32 WordCount; 1240 UINT32 Increment; 1241 UINT32 Index; 1242 UINT32 ByteCount; 1243 UINT16 *Buffer16; 1244 1245 EFI_STATUS Status; 1246 1247 ByteCount = sizeof (AtapiIdentifyData); 1248 Buffer16 = (UINT16 *) &AtapiIdentifyData; 1249 1250 Channel = (UINT8) (DevicePosition / 2); 1251 Device = (UINT8) (DevicePosition % 2); 1252 1253 ASSERT (Channel < MAX_IDE_CHANNELS); 1254 1255 StatusReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Status; 1256 HeadReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Head; 1257 CommandReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command; 1258 DataReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Data; 1259 SectorCountReg = AtapiBlkIoDev->IdeIoPortReg[Channel].SectorCount; 1260 SectorNumberReg = AtapiBlkIoDev->IdeIoPortReg[Channel].SectorNumber; 1261 CylinderLsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderLsb; 1262 CylinderMsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderMsb; 1263 1264 // 1265 // Send ATAPI Identify Command to get IDENTIFY data. 1266 // 1267 if (WaitForBSYClear ( 1268 AtapiBlkIoDev, 1269 &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 1270 ATATIMEOUT 1271 ) != EFI_SUCCESS) { 1272 return EFI_DEVICE_ERROR; 1273 } 1274 // 1275 // select device via Head/Device register. 1276 // Before write Head/Device register, BSY and DRQ must be 0. 1277 // 1278 if (DRQClear2 (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), ATATIMEOUT) != EFI_SUCCESS) { 1279 return EFI_DEVICE_ERROR; 1280 } 1281 // 1282 // e0:1110,0000-- bit7 and bit5 are reserved bits. 1283 // bit6 set means LBA mode 1284 // 1285 IoWrite8 (HeadReg, (UINT8) ((Device << 4) | 0xe0)); 1286 1287 // 1288 // set all the command parameters 1289 // Before write to all the following registers, BSY and DRQ must be 0. 1290 // 1291 if (DRQClear2 ( 1292 AtapiBlkIoDev, 1293 &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 1294 ATATIMEOUT 1295 ) != EFI_SUCCESS) { 1296 1297 return EFI_DEVICE_ERROR; 1298 } 1299 1300 IoWrite8 (SectorCountReg, 0); 1301 IoWrite8 (SectorNumberReg, 0); 1302 IoWrite8 (CylinderLsbReg, 0); 1303 IoWrite8 (CylinderMsbReg, 0); 1304 1305 // 1306 // send command via Command Register 1307 // 1308 IoWrite8 (CommandReg, ATA_CMD_IDENTIFY_DEVICE); 1309 1310 // 1311 // According to PIO data in protocol, host can perform a series of reads to the 1312 // data register after each time device set DRQ ready; 1313 // The data size of "a series of read" is command specific. 1314 // For most ATA command, data size received from device will not exceed 1 sector, 1315 // hense the data size for "a series of read" can be the whole data size of one command request. 1316 // For ATA command such as Read Sector command, whole data size of one ATA command request is often larger 1317 // than 1 sector, according to the Read Sector command, the data size of "a series of read" is exactly 1318 // 1 sector. 1319 // Here for simplification reason, we specify the data size for "a series of read" to 1320 // 1 sector (256 words) if whole data size of one ATA commmand request is larger than 256 words. 1321 // 1322 Increment = 256; 1323 // 1324 // 256 words 1325 // 1326 WordCount = 0; 1327 // 1328 // WordCount is used to record bytes of currently transfered data 1329 // 1330 while (WordCount < ByteCount / 2) { 1331 // 1332 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready. 1333 // 1334 Status = DRQReady2 (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), ATATIMEOUT); 1335 if (Status != EFI_SUCCESS) { 1336 return Status; 1337 } 1338 1339 if (CheckErrorStatus (AtapiBlkIoDev, StatusReg) != EFI_SUCCESS) { 1340 1341 return EFI_DEVICE_ERROR; 1342 } 1343 // 1344 // Get the byte count for one series of read 1345 // 1346 if ((WordCount + Increment) > ByteCount / 2) { 1347 Increment = ByteCount / 2 - WordCount; 1348 } 1349 // 1350 // perform a series of read without check DRQ ready 1351 // 1352 for (Index = 0; Index < Increment; Index++) { 1353 *Buffer16++ = IoRead16 (DataReg); 1354 } 1355 1356 WordCount += Increment; 1357 1358 } 1359 // 1360 // while 1361 // 1362 if (DRQClear ( 1363 AtapiBlkIoDev, 1364 &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 1365 ATATIMEOUT 1366 ) != EFI_SUCCESS) { 1367 return CheckErrorStatus (AtapiBlkIoDev, StatusReg); 1368 } 1369 1370 return EFI_SUCCESS; 1371 1372 } 1373 1374 /** 1375 Sends out ATAPI Test Unit Ready Packet Command to the specified device 1376 to find out whether device is accessible. 1377 1378 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 1379 @param[in] DevicePosition An integer to signify device position. 1380 1381 @retval EFI_SUCCESS TestUnit command executed successfully. 1382 @retval EFI_DEVICE_ERROR Device cannot be executed TestUnit command successfully. 1383 1384 **/ 1385 EFI_STATUS 1386 TestUnitReady ( 1387 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 1388 IN UINTN DevicePosition 1389 ) 1390 { 1391 ATAPI_PACKET_COMMAND Packet; 1392 EFI_STATUS Status; 1393 1394 // 1395 // fill command packet 1396 // 1397 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); 1398 Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY; 1399 1400 // 1401 // send command packet 1402 // 1403 Status = AtapiPacketCommandIn (AtapiBlkIoDev, DevicePosition, &Packet, NULL, 0, ATAPITIMEOUT); 1404 return Status; 1405 } 1406 1407 /** 1408 Send out ATAPI commands conforms to the Packet Command with PIO Data In Protocol. 1409 1410 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 1411 @param[in] DevicePosition An integer to signify device position. 1412 @param[in] Packet A pointer to ATAPI command packet. 1413 @param[in] Buffer Buffer to contain requested transfer data from device. 1414 @param[in] ByteCount Requested transfer data length. 1415 @param[in] TimeoutInMilliSeconds Time out value, in unit of milliseconds. 1416 1417 @retval EFI_SUCCESS Command executed successfully. 1418 @retval EFI_DEVICE_ERROR Device cannot be executed command successfully. 1419 1420 **/ 1421 EFI_STATUS 1422 AtapiPacketCommandIn ( 1423 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 1424 IN UINTN DevicePosition, 1425 IN ATAPI_PACKET_COMMAND *Packet, 1426 IN UINT16 *Buffer, 1427 IN UINT32 ByteCount, 1428 IN UINTN TimeoutInMilliSeconds 1429 ) 1430 { 1431 UINT8 Channel; 1432 UINT8 Device; 1433 UINT16 StatusReg; 1434 UINT16 HeadReg; 1435 UINT16 CommandReg; 1436 UINT16 FeatureReg; 1437 UINT16 CylinderLsbReg; 1438 UINT16 CylinderMsbReg; 1439 UINT16 DeviceControlReg; 1440 UINT16 DataReg; 1441 EFI_STATUS Status; 1442 UINT32 Count; 1443 UINT16 *CommandIndex; 1444 UINT16 *PtrBuffer; 1445 UINT32 Index; 1446 UINT8 StatusValue; 1447 UINT32 WordCount; 1448 1449 // 1450 // required transfer data in word unit. 1451 // 1452 UINT32 RequiredWordCount; 1453 1454 // 1455 // actual transfer data in word unit. 1456 // 1457 UINT32 ActualWordCount; 1458 1459 Channel = (UINT8) (DevicePosition / 2); 1460 Device = (UINT8) (DevicePosition % 2); 1461 1462 ASSERT (Channel < MAX_IDE_CHANNELS); 1463 1464 StatusReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Status; 1465 HeadReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Head; 1466 CommandReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command; 1467 FeatureReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg1.Feature; 1468 CylinderLsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderLsb; 1469 CylinderMsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderMsb; 1470 DeviceControlReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Alt.DeviceControl; 1471 DataReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Data; 1472 1473 // 1474 // Set all the command parameters by fill related registers. 1475 // Before write to all the following registers, BSY and DRQ must be 0. 1476 // 1477 if (DRQClear2 ( 1478 AtapiBlkIoDev, 1479 &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 1480 ATATIMEOUT 1481 ) != EFI_SUCCESS) { 1482 return EFI_DEVICE_ERROR; 1483 } 1484 // 1485 // Select device via Device/Head Register. 1486 // DEFAULT_CMD: 0xa0 (1010,0000) 1487 // 1488 IoWrite8 (HeadReg, (UINT8) ((Device << 4) | ATA_DEFAULT_CMD)); 1489 1490 // 1491 // No OVL; No DMA 1492 // 1493 IoWrite8 (FeatureReg, 0x00); 1494 1495 // 1496 // set the transfersize to MAX_ATAPI_BYTE_COUNT to let the device 1497 // determine how many data should be transfered. 1498 // 1499 IoWrite8 (CylinderLsbReg, (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff)); 1500 IoWrite8 (CylinderMsbReg, (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8)); 1501 1502 // 1503 // DEFAULT_CTL:0x0a (0000,1010) 1504 // Disable interrupt 1505 // 1506 IoWrite8 (DeviceControlReg, ATA_DEFAULT_CTL); 1507 1508 // 1509 // Send Packet command to inform device 1510 // that the following data bytes are command packet. 1511 // 1512 IoWrite8 (CommandReg, ATA_CMD_PACKET); 1513 1514 Status = DRQReady (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), TimeoutInMilliSeconds); 1515 if (Status != EFI_SUCCESS) { 1516 return Status; 1517 } 1518 // 1519 // Send out command packet 1520 // 1521 CommandIndex = Packet->Data16; 1522 for (Count = 0; Count < 6; Count++, CommandIndex++) { 1523 IoWrite16 (DataReg, *CommandIndex); 1524 MicroSecondDelay (10); 1525 } 1526 1527 StatusValue = IoRead8 (StatusReg); 1528 if ((StatusValue & ATA_STSREG_ERR) == ATA_STSREG_ERR) { 1529 // 1530 // Trouble! Something's wrong here... Wait some time and return. 3 second is 1531 // supposed to be long enough for a device reset latency or error recovery 1532 // 1533 MicroSecondDelay (3000000); 1534 return EFI_DEVICE_ERROR; 1535 } 1536 1537 if (Buffer == NULL || ByteCount == 0) { 1538 return EFI_SUCCESS; 1539 } 1540 // 1541 // call PioReadWriteData() function to get 1542 // requested transfer data form device. 1543 // 1544 PtrBuffer = Buffer; 1545 RequiredWordCount = ByteCount / 2; 1546 // 1547 // ActuralWordCount means the word count of data really transfered. 1548 // 1549 ActualWordCount = 0; 1550 1551 Status = EFI_SUCCESS; 1552 while ((Status == EFI_SUCCESS) && (ActualWordCount < RequiredWordCount)) { 1553 // 1554 // before each data transfer stream, the host should poll DRQ bit ready, 1555 // which informs device is ready to transfer data. 1556 // 1557 if (DRQReady2 ( 1558 AtapiBlkIoDev, 1559 &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 1560 TimeoutInMilliSeconds 1561 ) != EFI_SUCCESS) { 1562 return CheckErrorStatus (AtapiBlkIoDev, StatusReg); 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 1582 *PtrBuffer = IoRead16 (DataReg); 1583 1584 PtrBuffer++; 1585 1586 } 1587 1588 if (((ATAPI_REQUEST_SENSE_CMD *) Packet)->opcode == ATA_CMD_REQUEST_SENSE && ActualWordCount >= 4) { 1589 RequiredWordCount = MIN ( 1590 RequiredWordCount, 1591 (UINT32) (4 + (((ATAPI_REQUEST_SENSE_DATA *) Buffer)->addnl_sense_length / 2)) 1592 ); 1593 } 1594 1595 } 1596 // 1597 // After data transfer is completed, normally, DRQ bit should clear. 1598 // 1599 Status = DRQClear2 (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), TimeoutInMilliSeconds); 1600 if (Status != EFI_SUCCESS) { 1601 return EFI_DEVICE_ERROR; 1602 } 1603 // 1604 // read status register to check whether error happens. 1605 // 1606 Status = CheckErrorStatus (AtapiBlkIoDev, StatusReg); 1607 return Status; 1608 } 1609 1610 /** 1611 Sends out ATAPI Inquiry Packet Command to the specified device. 1612 This command will return INQUIRY data of the device. 1613 1614 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 1615 @param[in] DevicePosition An integer to signify device position. 1616 @param[out] MediaInfo The media information of the specified block media. 1617 @param[out] MediaInfo2 The media information 2 of the specified block media. 1618 1619 @retval EFI_SUCCESS Command executed successfully. 1620 @retval EFI_DEVICE_ERROR Device cannot be executed command successfully. 1621 @retval EFI_UNSUPPORTED Unsupported device type. 1622 1623 **/ 1624 EFI_STATUS 1625 Inquiry ( 1626 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 1627 IN UINTN DevicePosition, 1628 OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, 1629 OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2 1630 ) 1631 { 1632 ATAPI_PACKET_COMMAND Packet; 1633 EFI_STATUS Status; 1634 ATAPI_INQUIRY_DATA Idata; 1635 1636 // 1637 // prepare command packet for the ATAPI Inquiry Packet Command. 1638 // 1639 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); 1640 ZeroMem (&Idata, sizeof (ATAPI_INQUIRY_DATA)); 1641 1642 Packet.Inquiry.opcode = ATA_CMD_INQUIRY; 1643 Packet.Inquiry.page_code = 0; 1644 Packet.Inquiry.allocation_length = (UINT8) sizeof (ATAPI_INQUIRY_DATA); 1645 1646 // 1647 // Send command packet and get requested Inquiry data. 1648 // 1649 Status = AtapiPacketCommandIn ( 1650 AtapiBlkIoDev, 1651 DevicePosition, 1652 &Packet, 1653 (UINT16 *) (&Idata), 1654 sizeof (ATAPI_INQUIRY_DATA), 1655 ATAPITIMEOUT 1656 //50 1657 ); 1658 1659 if (Status != EFI_SUCCESS) { 1660 return EFI_DEVICE_ERROR; 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 1705 /** 1706 Used before read/write blocks from/to ATAPI device media. 1707 Since ATAPI device media is removable, it is necessary to detect 1708 whether media is present and get current present media's information. 1709 1710 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 1711 @param[in] DevicePosition An integer to signify device position. 1712 @param[in, out] MediaInfo The media information of the specified block media. 1713 @param[in, out] MediaInfo2 The media information 2 of the specified block media. 1714 1715 @retval EFI_SUCCESS Command executed successfully. 1716 @retval EFI_DEVICE_ERROR Some device errors happen. 1717 @retval EFI_OUT_OF_RESOURCES Can not allocate required resources. 1718 1719 **/ 1720 EFI_STATUS 1721 DetectMedia ( 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 1729 UINTN Index; 1730 UINTN RetryNum; 1731 UINTN MaxRetryNum; 1732 ATAPI_REQUEST_SENSE_DATA *SenseBuffers; 1733 BOOLEAN NeedReadCapacity; 1734 BOOLEAN NeedRetry; 1735 EFI_STATUS Status; 1736 UINT8 SenseCounts; 1737 1738 SenseBuffers = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (*SenseBuffers))); 1739 if (SenseBuffers == NULL) { 1740 return EFI_OUT_OF_RESOURCES; 1741 } 1742 1743 // 1744 // Test Unit Ready command is used to detect whether device is accessible, 1745 // the device will produce corresponding Sense data. 1746 // 1747 for (Index = 0; Index < 2; Index++) { 1748 1749 Status = TestUnitReady (AtapiBlkIoDev, DevicePosition); 1750 if (Status != EFI_SUCCESS) { 1751 Status = ResetDevice (AtapiBlkIoDev, DevicePosition, FALSE); 1752 1753 if (Status != EFI_SUCCESS) { 1754 ResetDevice (AtapiBlkIoDev, DevicePosition, TRUE); 1755 } 1756 1757 } else { 1758 break; 1759 } 1760 } 1761 1762 SenseCounts = MAX_SENSE_KEY_COUNT; 1763 Status = EFI_SUCCESS; 1764 NeedReadCapacity = TRUE; 1765 1766 for (Index = 0; Index < 5; Index++) { 1767 SenseCounts = MAX_SENSE_KEY_COUNT; 1768 Status = RequestSense ( 1769 AtapiBlkIoDev, 1770 DevicePosition, 1771 SenseBuffers, 1772 &SenseCounts 1773 ); 1774 DEBUG ((EFI_D_INFO, "Atapi Request Sense Count is %d\n", SenseCounts)); 1775 if (IsDeviceStateUnclear (SenseBuffers, SenseCounts) || IsNoMedia (SenseBuffers, SenseCounts)) { 1776 // 1777 // We are not sure whether the media is present or not, try again 1778 // 1779 TestUnitReady (AtapiBlkIoDev, DevicePosition); 1780 } else { 1781 break; 1782 } 1783 } 1784 1785 if (Status == EFI_SUCCESS) { 1786 1787 if (IsNoMedia (SenseBuffers, SenseCounts)) { 1788 1789 NeedReadCapacity = FALSE; 1790 MediaInfo->MediaPresent = FALSE; 1791 MediaInfo->LastBlock = 0; 1792 MediaInfo2->MediaPresent = FALSE; 1793 MediaInfo2->LastBlock = 0; 1794 } 1795 1796 if (IsMediaError (SenseBuffers, SenseCounts)) { 1797 return EFI_DEVICE_ERROR; 1798 } 1799 } 1800 1801 if (NeedReadCapacity) { 1802 // 1803 // at most retry 5 times 1804 // 1805 MaxRetryNum = 5; 1806 RetryNum = 1; 1807 // 1808 // initial retry once 1809 // 1810 for (Index = 0; (Index < RetryNum) && (Index < MaxRetryNum); Index++) { 1811 1812 Status = ReadCapacity (AtapiBlkIoDev, DevicePosition, MediaInfo, MediaInfo2); 1813 MicroSecondDelay (200000); 1814 SenseCounts = MAX_SENSE_KEY_COUNT; 1815 1816 if (Status != EFI_SUCCESS) { 1817 1818 Status = RequestSense (AtapiBlkIoDev, DevicePosition, SenseBuffers, &SenseCounts); 1819 // 1820 // If Request Sense data failed, reset the device and retry. 1821 // 1822 if (Status != EFI_SUCCESS) { 1823 1824 Status = ResetDevice (AtapiBlkIoDev, DevicePosition, FALSE); 1825 // 1826 // if ATAPI soft reset fail, 1827 // use stronger reset mechanism -- ATA soft reset. 1828 // 1829 if (Status != EFI_SUCCESS) { 1830 ResetDevice (AtapiBlkIoDev, DevicePosition, TRUE); 1831 } 1832 1833 RetryNum++; 1834 // 1835 // retry once more 1836 // 1837 continue; 1838 } 1839 // 1840 // No Media 1841 // 1842 if (IsNoMedia (SenseBuffers, SenseCounts)) { 1843 1844 MediaInfo->MediaPresent = FALSE; 1845 MediaInfo->LastBlock = 0; 1846 MediaInfo2->MediaPresent = FALSE; 1847 MediaInfo2->LastBlock = 0; 1848 break; 1849 } 1850 1851 if (IsMediaError (SenseBuffers, SenseCounts)) { 1852 return EFI_DEVICE_ERROR; 1853 } 1854 1855 if (!IsDriveReady (SenseBuffers, SenseCounts, &NeedRetry)) { 1856 // 1857 // Drive not ready: if NeedRetry, then retry once more; 1858 // else return error 1859 // 1860 if (NeedRetry) { 1861 RetryNum++; 1862 continue; 1863 } else { 1864 return EFI_DEVICE_ERROR; 1865 } 1866 } 1867 // 1868 // if read capacity fail not for above reasons, retry once more 1869 // 1870 RetryNum++; 1871 1872 } 1873 1874 } 1875 1876 } 1877 1878 return EFI_SUCCESS; 1879 } 1880 1881 /** 1882 Reset specified Atapi device. 1883 1884 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 1885 @param[in] DevicePosition An integer to signify device position. 1886 @param[in] Extensive If TRUE, use ATA soft reset, otherwise use Atapi soft reset. 1887 1888 @retval EFI_SUCCESS Command executed successfully. 1889 @retval EFI_DEVICE_ERROR Some device errors happen. 1890 1891 **/ 1892 EFI_STATUS 1893 ResetDevice ( 1894 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 1895 IN UINTN DevicePosition, 1896 IN BOOLEAN Extensive 1897 ) 1898 { 1899 UINT8 DevControl; 1900 UINT8 Command; 1901 UINT8 DeviceSelect; 1902 UINT16 DeviceControlReg; 1903 UINT16 CommandReg; 1904 UINT16 HeadReg; 1905 UINT8 Channel; 1906 UINT8 Device; 1907 1908 Channel = (UINT8) (DevicePosition / 2); 1909 Device = (UINT8) (DevicePosition % 2); 1910 1911 ASSERT (Channel < MAX_IDE_CHANNELS); 1912 1913 DeviceControlReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Alt.DeviceControl; 1914 CommandReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command; 1915 HeadReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Head; 1916 1917 if (Extensive) { 1918 1919 DevControl = 0; 1920 DevControl |= ATA_CTLREG_SRST; 1921 // 1922 // set SRST bit to initiate soft reset 1923 // 1924 DevControl |= BIT1; 1925 // 1926 // disable Interrupt 1927 // 1928 IoWrite8 (DeviceControlReg, DevControl); 1929 1930 // 1931 // Wait 10us 1932 // 1933 MicroSecondDelay (10); 1934 1935 // 1936 // Clear SRST bit 1937 // 1938 DevControl &= 0xfb; 1939 // 1940 // 0xfb:1111,1011 1941 // 1942 IoWrite8 (DeviceControlReg, DevControl); 1943 1944 // 1945 // slave device needs at most 31s to clear BSY 1946 // 1947 if (WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 31000) == EFI_TIMEOUT) { 1948 return EFI_DEVICE_ERROR; 1949 } 1950 1951 } else { 1952 // 1953 // for ATAPI device, no need to wait DRDY ready after device selecting. 1954 // bit7 and bit5 are both set to 1 for backward compatibility 1955 // 1956 DeviceSelect = (UINT8) (((BIT7 | BIT5) | (Device << 4))); 1957 IoWrite8 (HeadReg, DeviceSelect); 1958 1959 Command = ATA_CMD_SOFT_RESET; 1960 IoWrite8 (CommandReg, Command); 1961 1962 // 1963 // BSY cleared is the only status return to the host by the device when reset is completed 1964 // slave device needs at most 31s to clear BSY 1965 // 1966 if (WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 31000) != EFI_SUCCESS) { 1967 return EFI_DEVICE_ERROR; 1968 } 1969 // 1970 // stall 5 seconds to make the device status stable 1971 // 1972 MicroSecondDelay (STALL_1_SECONDS * 5); 1973 } 1974 1975 return EFI_SUCCESS; 1976 1977 } 1978 1979 /** 1980 Sends out ATAPI Request Sense Packet Command to the specified device. 1981 1982 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 1983 @param[in] DevicePosition An integer to signify device position. 1984 @param[in] SenseBuffers Pointer to sense buffer. 1985 @param[in, out] SenseCounts Length of sense buffer. 1986 1987 @retval EFI_SUCCESS Command executed successfully. 1988 @retval EFI_DEVICE_ERROR Some device errors happen. 1989 1990 **/ 1991 EFI_STATUS 1992 RequestSense ( 1993 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 1994 IN UINTN DevicePosition, 1995 IN ATAPI_REQUEST_SENSE_DATA *SenseBuffers, 1996 IN OUT UINT8 *SenseCounts 1997 ) 1998 { 1999 EFI_STATUS Status; 2000 ATAPI_REQUEST_SENSE_DATA *Sense; 2001 UINT16 *Ptr; 2002 BOOLEAN SenseReq; 2003 ATAPI_PACKET_COMMAND Packet; 2004 2005 ZeroMem (SenseBuffers, sizeof (ATAPI_REQUEST_SENSE_DATA) * (*SenseCounts)); 2006 // 2007 // fill command packet for Request Sense Packet Command 2008 // 2009 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); 2010 Packet.RequestSence.opcode = ATA_CMD_REQUEST_SENSE; 2011 Packet.RequestSence.allocation_length = (UINT8) sizeof (ATAPI_REQUEST_SENSE_DATA); 2012 2013 Ptr = (UINT16 *) SenseBuffers; 2014 // 2015 // initialize pointer 2016 // 2017 *SenseCounts = 0; 2018 // 2019 // request sense data from device continiously until no sense data exists in the device. 2020 // 2021 for (SenseReq = TRUE; SenseReq;) { 2022 2023 Sense = (ATAPI_REQUEST_SENSE_DATA *) Ptr; 2024 2025 // 2026 // send out Request Sense Packet Command and get one Sense data form device 2027 // 2028 Status = AtapiPacketCommandIn ( 2029 AtapiBlkIoDev, 2030 DevicePosition, 2031 &Packet, 2032 Ptr, 2033 sizeof (ATAPI_REQUEST_SENSE_DATA), 2034 ATAPITIMEOUT 2035 ); 2036 // 2037 // failed to get Sense data 2038 // 2039 if (Status != EFI_SUCCESS) { 2040 if (*SenseCounts == 0) { 2041 return EFI_DEVICE_ERROR; 2042 } else { 2043 return EFI_SUCCESS; 2044 } 2045 } 2046 2047 (*SenseCounts)++; 2048 2049 if (*SenseCounts > MAX_SENSE_KEY_COUNT) { 2050 return EFI_SUCCESS; 2051 } 2052 // 2053 // We limit MAX sense data count to 20 in order to avoid dead loop. Some 2054 // incompatible ATAPI devices don't retrive NO_SENSE when there is no media. 2055 // In this case, dead loop occurs if we don't have a gatekeeper. 20 is 2056 // supposed to be large enough for any ATAPI device. 2057 // 2058 if ((Sense->sense_key != ATA_SK_NO_SENSE) && ((*SenseCounts) < 20)) { 2059 2060 Ptr += sizeof (ATAPI_REQUEST_SENSE_DATA) / 2; 2061 // 2062 // Ptr is word based pointer 2063 // 2064 } else { 2065 // 2066 // when no sense key, skip out the loop 2067 // 2068 SenseReq = FALSE; 2069 } 2070 } 2071 2072 return EFI_SUCCESS; 2073 } 2074 2075 /** 2076 Sends out ATAPI Read Capacity Packet Command to the specified device. 2077 This command will return the information regarding the capacity of the 2078 media in the device. 2079 2080 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 2081 @param[in] DevicePosition An integer to signify device position. 2082 @param[in, out] MediaInfo The media information of the specified block media. 2083 @param[in, out] MediaInfo2 The media information 2 of the specified block media. 2084 2085 @retval EFI_SUCCESS Command executed successfully. 2086 @retval EFI_DEVICE_ERROR Some device errors happen. 2087 2088 **/ 2089 EFI_STATUS 2090 ReadCapacity ( 2091 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 2092 IN UINTN DevicePosition, 2093 IN OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, 2094 IN OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2 2095 ) 2096 { 2097 EFI_STATUS Status; 2098 ATAPI_PACKET_COMMAND Packet; 2099 2100 // 2101 // used for capacity data returned from ATAPI device 2102 // 2103 ATAPI_READ_CAPACITY_DATA Data; 2104 ATAPI_READ_FORMAT_CAPACITY_DATA FormatData; 2105 2106 ZeroMem (&Data, sizeof (Data)); 2107 ZeroMem (&FormatData, sizeof (FormatData)); 2108 2109 if (MediaInfo->DeviceType == IdeCDROM) { 2110 2111 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); 2112 Packet.Inquiry.opcode = ATA_CMD_READ_CAPACITY; 2113 Status = AtapiPacketCommandIn ( 2114 AtapiBlkIoDev, 2115 DevicePosition, 2116 &Packet, 2117 (UINT16 *) (&Data), 2118 sizeof (ATAPI_READ_CAPACITY_DATA), 2119 ATAPITIMEOUT 2120 ); 2121 2122 } else { 2123 // 2124 // DeviceType == IdeLS120 2125 // 2126 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); 2127 Packet.ReadFormatCapacity.opcode = ATA_CMD_READ_FORMAT_CAPACITY; 2128 Packet.ReadFormatCapacity.allocation_length_lo = 12; 2129 Status = AtapiPacketCommandIn ( 2130 AtapiBlkIoDev, 2131 DevicePosition, 2132 &Packet, 2133 (UINT16 *) (&FormatData), 2134 sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA), 2135 ATAPITIMEOUT*10 2136 ); 2137 } 2138 2139 if (Status == EFI_SUCCESS) { 2140 2141 if (MediaInfo->DeviceType == IdeCDROM) { 2142 2143 MediaInfo->LastBlock = (Data.LastLba3 << 24) | (Data.LastLba2 << 16) | (Data.LastLba1 << 8) | Data.LastLba0; 2144 MediaInfo->MediaPresent = TRUE; 2145 // 2146 // Because the user data portion in the sector of the Data CD supported 2147 // is always 800h 2148 // 2149 MediaInfo->BlockSize = 0x800; 2150 2151 MediaInfo2->LastBlock = MediaInfo->LastBlock; 2152 MediaInfo2->MediaPresent = MediaInfo->MediaPresent; 2153 MediaInfo2->BlockSize = (UINT32)MediaInfo->BlockSize; 2154 } 2155 2156 if (MediaInfo->DeviceType == IdeLS120) { 2157 2158 if (FormatData.DesCode == 3) { 2159 MediaInfo->MediaPresent = FALSE; 2160 MediaInfo->LastBlock = 0; 2161 MediaInfo2->MediaPresent = FALSE; 2162 MediaInfo2->LastBlock = 0; 2163 } else { 2164 MediaInfo->LastBlock = (FormatData.LastLba3 << 24) | 2165 (FormatData.LastLba2 << 16) | 2166 (FormatData.LastLba1 << 8) | 2167 FormatData.LastLba0; 2168 MediaInfo->LastBlock--; 2169 2170 MediaInfo->MediaPresent = TRUE; 2171 2172 MediaInfo->BlockSize = 0x200; 2173 2174 MediaInfo2->LastBlock = MediaInfo->LastBlock; 2175 MediaInfo2->MediaPresent = MediaInfo->MediaPresent; 2176 MediaInfo2->BlockSize = (UINT32)MediaInfo->BlockSize; 2177 2178 } 2179 } 2180 2181 return EFI_SUCCESS; 2182 2183 } else { 2184 return EFI_DEVICE_ERROR; 2185 } 2186 } 2187 2188 /** 2189 Perform read from disk in block unit. 2190 2191 @param[in] AtapiBlkIoDev A pointer to atapi block IO device. 2192 @param[in] DevicePosition An integer to signify device position. 2193 @param[in] Buffer Buffer to contain read data. 2194 @param[in] StartLba Starting LBA address. 2195 @param[in] NumberOfBlocks Number of blocks to read. 2196 @param[in] BlockSize Size of each block. 2197 2198 @retval EFI_SUCCESS Command executed successfully. 2199 @retval EFI_DEVICE_ERROR Some device errors happen. 2200 2201 **/ 2202 EFI_STATUS 2203 ReadSectors ( 2204 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, 2205 IN UINTN DevicePosition, 2206 IN VOID *Buffer, 2207 IN EFI_PEI_LBA StartLba, 2208 IN UINTN NumberOfBlocks, 2209 IN UINTN BlockSize 2210 ) 2211 { 2212 2213 ATAPI_PACKET_COMMAND Packet; 2214 ATAPI_READ10_CMD *Read10Packet; 2215 EFI_STATUS Status; 2216 UINTN BlocksRemaining; 2217 UINT32 Lba32; 2218 UINT32 ByteCount; 2219 UINT16 SectorCount; 2220 VOID *PtrBuffer; 2221 UINT16 MaxBlock; 2222 2223 // 2224 // fill command packet for Read(10) command 2225 // 2226 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); 2227 Read10Packet = &Packet.Read10; 2228 Lba32 = (UINT32) StartLba; 2229 PtrBuffer = Buffer; 2230 2231 // 2232 // limit the data bytes that can be transfered by one Read(10) Command 2233 // 2234 MaxBlock = (UINT16) (0x10000 / BlockSize); 2235 // 2236 // (64k bytes) 2237 // 2238 BlocksRemaining = NumberOfBlocks; 2239 2240 Status = EFI_SUCCESS; 2241 while (BlocksRemaining > 0) { 2242 2243 if (BlocksRemaining <= MaxBlock) { 2244 SectorCount = (UINT16) BlocksRemaining; 2245 } else { 2246 SectorCount = MaxBlock; 2247 } 2248 // 2249 // fill the Packet data sturcture 2250 // 2251 Read10Packet->opcode = ATA_CMD_READ_10; 2252 2253 // 2254 // Lba0 ~ Lba3 specify the start logical block address of the data transfer. 2255 // Lba0 is MSB, Lba3 is LSB 2256 // 2257 Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff); 2258 Read10Packet->Lba2 = (UINT8) (Lba32 >> 8); 2259 Read10Packet->Lba1 = (UINT8) (Lba32 >> 16); 2260 Read10Packet->Lba0 = (UINT8) (Lba32 >> 24); 2261 2262 // 2263 // TranLen0 ~ TranLen1 specify the transfer length in block unit. 2264 // TranLen0 is MSB, TranLen is LSB 2265 // 2266 Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff); 2267 Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8); 2268 2269 ByteCount = (UINT32) (SectorCount * BlockSize); 2270 2271 Status = AtapiPacketCommandIn ( 2272 AtapiBlkIoDev, 2273 DevicePosition, 2274 &Packet, 2275 (UINT16 *) PtrBuffer, 2276 ByteCount, 2277 ATAPILONGTIMEOUT 2278 ); 2279 if (Status != EFI_SUCCESS) { 2280 return Status; 2281 } 2282 2283 Lba32 += SectorCount; 2284 PtrBuffer = (UINT8 *) PtrBuffer + SectorCount * BlockSize; 2285 BlocksRemaining -= SectorCount; 2286 } 2287 2288 return Status; 2289 } 2290 2291 /** 2292 Check if there is media according to sense data. 2293 2294 @param[in] SenseData Pointer to sense data. 2295 @param[in] SenseCounts Count of sense data. 2296 2297 @retval TRUE No media 2298 @retval FALSE Media exists 2299 2300 **/ 2301 BOOLEAN 2302 IsNoMedia ( 2303 IN ATAPI_REQUEST_SENSE_DATA *SenseData, 2304 IN UINTN SenseCounts 2305 ) 2306 { 2307 ATAPI_REQUEST_SENSE_DATA *SensePtr; 2308 UINTN Index; 2309 BOOLEAN IsNoMedia; 2310 2311 IsNoMedia = FALSE; 2312 2313 SensePtr = SenseData; 2314 2315 for (Index = 0; Index < SenseCounts; Index++) { 2316 2317 if ((SensePtr->sense_key == ATA_SK_NOT_READY) && (SensePtr->addnl_sense_code == ATA_ASC_NO_MEDIA)) { 2318 IsNoMedia = TRUE; 2319 } 2320 2321 SensePtr++; 2322 } 2323 2324 return IsNoMedia; 2325 } 2326 2327 /** 2328 Check if device state is unclear according to sense data. 2329 2330 @param[in] SenseData Pointer to sense data. 2331 @param[in] SenseCounts Count of sense data. 2332 2333 @retval TRUE Device state is unclear 2334 @retval FALSE Device state is clear 2335 2336 **/ 2337 BOOLEAN 2338 IsDeviceStateUnclear ( 2339 IN ATAPI_REQUEST_SENSE_DATA *SenseData, 2340 IN UINTN SenseCounts 2341 ) 2342 { 2343 ATAPI_REQUEST_SENSE_DATA *SensePtr; 2344 UINTN Index; 2345 BOOLEAN Unclear; 2346 2347 Unclear = FALSE; 2348 2349 SensePtr = SenseData; 2350 2351 for (Index = 0; Index < SenseCounts; Index++) { 2352 2353 if (SensePtr->sense_key == 0x06) { 2354 // 2355 // Sense key is 0x06 means the device is just be reset or media just 2356 // changed. The current state of the device is unclear. 2357 // 2358 Unclear = TRUE; 2359 break; 2360 } 2361 2362 SensePtr++; 2363 } 2364 2365 return Unclear; 2366 } 2367 2368 /** 2369 Check if there is media error according to sense data. 2370 2371 @param[in] SenseData Pointer to sense data. 2372 @param[in] SenseCounts Count of sense data. 2373 2374 @retval TRUE Media error 2375 @retval FALSE No media error 2376 2377 **/ 2378 BOOLEAN 2379 IsMediaError ( 2380 IN ATAPI_REQUEST_SENSE_DATA *SenseData, 2381 IN UINTN SenseCounts 2382 ) 2383 { 2384 ATAPI_REQUEST_SENSE_DATA *SensePtr; 2385 UINTN Index; 2386 BOOLEAN IsError; 2387 2388 IsError = FALSE; 2389 2390 SensePtr = SenseData; 2391 2392 for (Index = 0; Index < SenseCounts; Index++) { 2393 2394 switch (SensePtr->sense_key) { 2395 2396 case ATA_SK_MEDIUM_ERROR: 2397 switch (SensePtr->addnl_sense_code) { 2398 case ATA_ASC_MEDIA_ERR1: 2399 // 2400 // fall through 2401 // 2402 case ATA_ASC_MEDIA_ERR2: 2403 // 2404 // fall through 2405 // 2406 case ATA_ASC_MEDIA_ERR3: 2407 // 2408 // fall through 2409 // 2410 case ATA_ASC_MEDIA_ERR4: 2411 IsError = TRUE; 2412 break; 2413 2414 default: 2415 break; 2416 } 2417 2418 break; 2419 2420 case ATA_SK_NOT_READY: 2421 switch (SensePtr->addnl_sense_code) { 2422 case ATA_ASC_MEDIA_UPSIDE_DOWN: 2423 IsError = TRUE; 2424 break; 2425 2426 default: 2427 break; 2428 } 2429 break; 2430 2431 default: 2432 break; 2433 } 2434 2435 SensePtr++; 2436 } 2437 2438 return IsError; 2439 } 2440 2441 /** 2442 Check if drive is ready according to sense data. 2443 2444 @param[in] SenseData Pointer to sense data. 2445 @param[in] SenseCounts Count of sense data. 2446 @param[out] NeedRetry Indicate if retry is needed. 2447 2448 @retval TRUE Drive ready 2449 @retval FALSE Drive not ready 2450 2451 **/ 2452 BOOLEAN 2453 IsDriveReady ( 2454 IN ATAPI_REQUEST_SENSE_DATA *SenseData, 2455 IN UINTN SenseCounts, 2456 OUT BOOLEAN *NeedRetry 2457 ) 2458 { 2459 ATAPI_REQUEST_SENSE_DATA *SensePtr; 2460 UINTN Index; 2461 BOOLEAN IsReady; 2462 2463 IsReady = TRUE; 2464 *NeedRetry = FALSE; 2465 2466 SensePtr = SenseData; 2467 2468 for (Index = 0; Index < SenseCounts; Index++) { 2469 2470 switch (SensePtr->sense_key) { 2471 2472 case ATA_SK_NOT_READY: 2473 switch (SensePtr->addnl_sense_code) { 2474 case ATA_ASC_NOT_READY: 2475 switch (SensePtr->addnl_sense_code_qualifier) { 2476 case ATA_ASCQ_IN_PROGRESS: 2477 IsReady = FALSE; 2478 *NeedRetry = TRUE; 2479 break; 2480 2481 default: 2482 IsReady = FALSE; 2483 *NeedRetry = FALSE; 2484 break; 2485 } 2486 break; 2487 2488 default: 2489 break; 2490 } 2491 break; 2492 2493 default: 2494 break; 2495 } 2496 2497 SensePtr++; 2498 } 2499 2500 return IsReady; 2501 } 2502