1 /* 2 * PROJECT: FreeLoader 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: ATA/ATAPI programmed I/O driver. 5 * COPYRIGHT: Copyright 2019-2020 Dmitry Borisov (di.sean@protonmail.com) 6 */ 7 8 /* INCLUDES *******************************************************************/ 9 10 #include <freeldr.h> 11 #include <hwide.h> 12 13 /* DDK */ 14 #include <ata.h> 15 #include <scsi.h> 16 17 #include <debug.h> 18 DBG_DEFAULT_CHANNEL(DISK); 19 20 /* GLOBALS ********************************************************************/ 21 22 #define TAG_ATA_DEVICE 'DatA' 23 #define ATAPI_PACKET_SIZE(IdentifyData) (IdentifyData.AtapiCmdSize ? 16 : 12) 24 #define ATA_STATUS_TIMEOUT 31e5 25 26 #define AtaWritePort(Channel, Port, Data) \ 27 WRITE_PORT_UCHAR(UlongToPtr(BaseArray[(Channel)] + (Port)), (Data)) 28 29 #define AtaReadPort(Channel, Port) \ 30 READ_PORT_UCHAR(UlongToPtr(BaseArray[(Channel)] + (Port))) 31 32 #define AtaWriteBuffer(Channel, Buffer, Count) \ 33 WRITE_PORT_BUFFER_USHORT(UlongToPtr(BaseArray[(Channel)] + IDX_IO1_o_Data), \ 34 (PUSHORT)(Buffer), (Count)/sizeof(USHORT)) 35 36 #define AtaReadBuffer(Channel, Buffer, Count) \ 37 READ_PORT_BUFFER_USHORT(UlongToPtr(BaseArray[(Channel)] + IDX_IO1_i_Data), \ 38 (PUSHORT)(Buffer), (Count)/sizeof(USHORT)) 39 40 /* IDE/ATA Channels base - Primary, Secondary, Tertiary, Quaternary */ 41 static const ULONG BaseArray[] = 42 { 43 #if defined(SARCH_XBOX) 44 0x1F0 45 #elif defined(SARCH_PC98) 46 0x640, 0x640 47 #else 48 0x1F0, 0x170, 0x1E8, 0x168 49 #endif 50 }; 51 52 #define MAX_CHANNELS RTL_NUMBER_OF(BaseArray) 53 #define MAX_DEVICES 2 /* Master/Slave */ 54 55 static PDEVICE_UNIT Units[MAX_CHANNELS * MAX_DEVICES]; 56 57 /* PRIVATE PROTOTYPES *********************************************************/ 58 59 static 60 BOOLEAN 61 WaitForFlags( 62 IN UCHAR Channel, 63 IN UCHAR Flags, 64 IN UCHAR ExpectedValue, 65 IN ULONG Timeout 66 ); 67 68 static 69 BOOLEAN 70 WaitForFlagsOr( 71 IN UCHAR Channel, 72 IN UCHAR FirstValue, 73 IN UCHAR SecondValue, 74 IN ULONG Timeout 75 ); 76 77 static 78 BOOLEAN 79 WaitForBusy( 80 IN UCHAR Channel, 81 IN ULONG Timeout 82 ); 83 84 static 85 VOID 86 SelectDevice( 87 IN UCHAR Channel, 88 IN UCHAR DeviceNumber 89 ); 90 91 static 92 BOOLEAN 93 IdentifyDevice( 94 IN UCHAR Channel, 95 IN UCHAR DeviceNumber, 96 OUT PDEVICE_UNIT *DeviceUnit 97 ); 98 99 static 100 BOOLEAN 101 AtapiRequestSense( 102 IN PDEVICE_UNIT DeviceUnit, 103 OUT PSENSE_DATA SenseData 104 ); 105 106 static 107 VOID 108 AtapiPrintSenseData( 109 IN PDEVICE_UNIT DeviceUnit 110 ); 111 112 static 113 BOOLEAN 114 AtapiReadyCheck( 115 IN OUT PDEVICE_UNIT DeviceUnit 116 ); 117 118 static 119 BOOLEAN 120 AtapiReadLogicalSectorLBA( 121 IN PDEVICE_UNIT DeviceUnit, 122 IN ULONGLONG SectorNumber, 123 OUT PVOID Buffer 124 ); 125 126 static 127 BOOLEAN 128 AtaReadLogicalSectorsLBA( 129 IN PDEVICE_UNIT DeviceUnit, 130 IN ULONGLONG SectorNumber, 131 IN ULONG SectorCount, 132 OUT PVOID Buffer 133 ); 134 135 /* FUNCTIONS ******************************************************************/ 136 137 /* Don't call this before running the system timer calibration and MM initialization */ 138 BOOLEAN 139 AtaInit(OUT PUCHAR DetectedCount) 140 { 141 UCHAR Channel, DeviceNumber; 142 PDEVICE_UNIT DeviceUnit = NULL; 143 144 TRACE("AtaInit()\n"); 145 146 *DetectedCount = 0; 147 148 RtlZeroMemory(&Units, sizeof(Units)); 149 150 /* Detect and enumerate ATA/ATAPI devices */ 151 for (Channel = 0; Channel < MAX_CHANNELS; ++Channel) 152 { 153 for (DeviceNumber = 0; DeviceNumber < MAX_DEVICES; ++DeviceNumber) 154 { 155 if (IdentifyDevice(Channel, DeviceNumber, &DeviceUnit)) 156 { 157 Units[(*DetectedCount)++] = DeviceUnit; 158 } 159 } 160 } 161 162 return (*DetectedCount > 0); 163 } 164 165 VOID 166 AtaFree(VOID) 167 { 168 UCHAR i; 169 170 for (i = 0; i < RTL_NUMBER_OF(Units); ++i) 171 { 172 if (Units[i]) 173 FrLdrTempFree(Units[i], TAG_ATA_DEVICE); 174 } 175 } 176 177 PDEVICE_UNIT 178 AtaGetDevice(IN UCHAR UnitNumber) 179 { 180 if (UnitNumber < RTL_NUMBER_OF(Units)) 181 return Units[UnitNumber]; 182 else 183 return NULL; 184 } 185 186 BOOLEAN 187 AtaAtapiReadLogicalSectorsLBA( 188 IN OUT PDEVICE_UNIT DeviceUnit, 189 IN ULONGLONG SectorNumber, 190 IN ULONG SectorCount, 191 OUT PVOID Buffer) 192 { 193 UCHAR RetryCount; 194 BOOLEAN Success; 195 196 if (DeviceUnit == NULL || SectorCount == 0) 197 return FALSE; 198 199 if (DeviceUnit->Flags & ATA_DEVICE_ATAPI) 200 { 201 if ((DeviceUnit->Flags & ATA_DEVICE_NO_MEDIA) || (DeviceUnit->Flags & ATA_DEVICE_NOT_READY)) 202 { 203 /* Retry 4 times */ 204 for (RetryCount = 0; RetryCount < 4; ++RetryCount) 205 { 206 /* Make the device ready */ 207 if (AtapiReadyCheck(DeviceUnit)) 208 break; 209 } 210 if (RetryCount >= 4) 211 { 212 ERR("AtaAtapiReadLogicalSectorsLBA(): Device not ready.\n"); 213 return FALSE; 214 } 215 } 216 if (SectorNumber + SectorCount > DeviceUnit->TotalSectors + 1) 217 { 218 ERR("AtaAtapiReadLogicalSectorsLBA(): Attempt to read more than there is to read.\n"); 219 return FALSE; 220 } 221 222 while (SectorCount > 0) 223 { 224 /* Read a single sector */ 225 Success = AtapiReadLogicalSectorLBA(DeviceUnit, SectorNumber, Buffer); 226 if (!Success) 227 return FALSE; 228 229 --SectorCount; 230 ++SectorNumber; 231 Buffer = (PVOID)((ULONG_PTR)Buffer + DeviceUnit->SectorSize); 232 } 233 } 234 else 235 { 236 /* Retry 3 times */ 237 for (RetryCount = 0; RetryCount < 3; ++RetryCount) 238 { 239 /* Read a multiple sectors */ 240 Success = AtaReadLogicalSectorsLBA(DeviceUnit, SectorNumber, SectorCount, Buffer); 241 if (Success) 242 return TRUE; 243 } 244 return FALSE; 245 } 246 247 return TRUE; 248 } 249 250 static 251 BOOLEAN 252 AtaReadLogicalSectorsLBA( 253 IN PDEVICE_UNIT DeviceUnit, 254 IN ULONGLONG SectorNumber, 255 IN ULONG SectorCount, 256 OUT PVOID Buffer) 257 { 258 UCHAR Command; 259 ULONG ChsTemp; 260 USHORT Cylinder; 261 UCHAR Head; 262 UCHAR Sector; 263 ULONG BlockCount; 264 ULONG RemainingBlockCount; 265 ULONGLONG Lba; 266 BOOLEAN UseLBA48; 267 268 UseLBA48 = (DeviceUnit->Flags & ATA_DEVICE_LBA48) && 269 (((SectorNumber + SectorCount) >= UINT64_C(0x0FFFFF80)) || SectorCount > 256); 270 271 while (SectorCount > 0) 272 { 273 /* Prevent sector count overflow, divide it into maximum possible chunks and loop each one */ 274 if (UseLBA48) 275 BlockCount = min(SectorCount, USHRT_MAX); 276 else 277 BlockCount = min(SectorCount, UCHAR_MAX); 278 279 /* Convert LBA into a format CHS if needed */ 280 if (DeviceUnit->Flags & ATA_DEVICE_CHS) 281 { 282 ChsTemp = DeviceUnit->IdentifyData.SectorsPerTrack * DeviceUnit->IdentifyData.NumberOfHeads; 283 if (ChsTemp) 284 { 285 Cylinder = SectorNumber / ChsTemp; 286 Head = (SectorNumber % ChsTemp) / DeviceUnit->IdentifyData.SectorsPerTrack; 287 Sector = (SectorNumber % DeviceUnit->IdentifyData.SectorsPerTrack) + 1; 288 } 289 else 290 { 291 Cylinder = 0; 292 Head = 0; 293 Sector = 1; 294 } 295 Lba = (Sector & 0xFF) | ((Cylinder & 0xFFFFF) << 8) | ((Head & 0x0F) << 24); 296 } 297 else 298 { 299 Lba = SectorNumber; 300 } 301 302 /* Select the drive */ 303 SelectDevice(DeviceUnit->Channel, DeviceUnit->DeviceNumber); 304 if (!WaitForBusy(DeviceUnit->Channel, ATA_STATUS_TIMEOUT)) 305 { 306 ERR("AtaReadLogicalSectorsLBA() failed. Device is busy.\n"); 307 return FALSE; 308 } 309 310 /* Disable interrupts */ 311 AtaWritePort(DeviceUnit->Channel, IDX_IO2_o_Control, IDE_DC_DISABLE_INTERRUPTS); 312 StallExecutionProcessor(1); 313 314 if (UseLBA48) 315 { 316 /* FIFO */ 317 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_Feature, 0); 318 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_Feature, ATA_PIO); 319 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockCount, (BlockCount >> 8) & 0xFF); 320 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockCount, BlockCount & 0xFF); 321 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockNumber, (Lba >> 24) & 0xFF); 322 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockNumber, Lba & 0xFF); 323 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderLow, (Lba >> 32) & 0xFF); 324 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderLow, (Lba >> 8) & 0xFF); 325 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderHigh, (Lba >> 40) & 0xFF); 326 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderHigh, (Lba >> 16) & 0xFF); 327 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_DriveSelect, 328 IDE_USE_LBA | (DeviceUnit->DeviceNumber ? IDE_DRIVE_2 : IDE_DRIVE_1)); 329 Command = IDE_COMMAND_READ_EXT; 330 } 331 else 332 { 333 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_Feature, ATA_PIO); 334 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockCount, BlockCount & 0xFF); 335 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockNumber, Lba & 0xFF); 336 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderLow, (Lba >> 8) & 0xFF); 337 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderHigh, (Lba >> 16) & 0xFF); 338 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_DriveSelect, 339 ((Lba >> 24) & 0x0F) | 340 (DeviceUnit->Flags & ATA_DEVICE_CHS ? 0x00 : IDE_USE_LBA) | 341 (DeviceUnit->DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1)); 342 Command = IDE_COMMAND_READ; 343 } 344 345 /* Send read command */ 346 AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_Command, Command); 347 StallExecutionProcessor(5); 348 349 for (RemainingBlockCount = BlockCount; RemainingBlockCount > 0; --RemainingBlockCount) 350 { 351 /* Wait for ready to transfer data block */ 352 if (!WaitForFlags(DeviceUnit->Channel, IDE_STATUS_DRQ, 353 IDE_STATUS_DRQ, ATA_STATUS_TIMEOUT)) 354 { 355 ERR("AtaReadLogicalSectorsLBA() failed. Status: 0x%02x, Error: 0x%02x\n", 356 AtaReadPort(DeviceUnit->Channel, IDX_IO1_i_Status), 357 AtaReadPort(DeviceUnit->Channel, IDX_IO1_i_Error)); 358 return FALSE; 359 } 360 361 /* Transfer the data block */ 362 AtaReadBuffer(DeviceUnit->Channel, Buffer, DeviceUnit->SectorSize); 363 364 Buffer = (PVOID)((ULONG_PTR)Buffer + DeviceUnit->SectorSize); 365 } 366 367 SectorNumber += BlockCount; 368 SectorCount -= BlockCount; 369 } 370 371 return TRUE; 372 } 373 374 static 375 BOOLEAN 376 AtaSendAtapiPacket( 377 IN UCHAR Channel, 378 IN PUCHAR AtapiPacket, 379 IN UCHAR PacketSize, 380 IN USHORT ByteCount) 381 { 382 /* 383 * REQUEST SENSE is used by driver to clear the ATAPI 'Bus reset' indication. 384 * TEST UNIT READY doesn't require space for returned data. 385 */ 386 UCHAR ExpectedFlagsMask = (AtapiPacket[0] == SCSIOP_REQUEST_SENSE) ? 387 IDE_STATUS_DRDY : (IDE_STATUS_DRQ | IDE_STATUS_DRDY); 388 UCHAR ExpectedFlags = ((AtapiPacket[0] == SCSIOP_TEST_UNIT_READY) || 389 (AtapiPacket[0] == SCSIOP_REQUEST_SENSE)) ? 390 IDE_STATUS_DRDY : (IDE_STATUS_DRQ | IDE_STATUS_DRDY); 391 392 /* PIO mode */ 393 AtaWritePort(Channel, IDX_ATAPI_IO1_o_Feature, ATA_PIO); 394 395 /* Maximum byte count that is to be transferred */ 396 AtaWritePort(Channel, IDX_ATAPI_IO1_o_ByteCountLow, ByteCount & 0xFF); 397 AtaWritePort(Channel, IDX_ATAPI_IO1_o_ByteCountHigh, (ByteCount >> 8) & 0xFF); 398 399 /* Prepare to transfer a device command via a command packet */ 400 AtaWritePort(Channel, IDX_ATAPI_IO1_o_Command, IDE_COMMAND_ATAPI_PACKET); 401 StallExecutionProcessor(50); 402 if (!WaitForFlagsOr(Channel, IDE_STATUS_DRQ, IDE_STATUS_DRDY, ATA_STATUS_TIMEOUT)) 403 { 404 ERR("AtaSendAtapiPacket(0x%x) failed. A device error occurred Status: 0x%02x, Error: 0x%02x\n", 405 AtapiPacket[0], AtaReadPort(Channel, IDX_ATAPI_IO1_i_Status), AtaReadPort(Channel, IDX_ATAPI_IO1_i_Error)); 406 return FALSE; 407 } 408 409 /* Command packet transfer */ 410 AtaWriteBuffer(Channel, AtapiPacket, PacketSize); 411 if (!WaitForFlags(Channel, ExpectedFlagsMask, ExpectedFlags, ATA_STATUS_TIMEOUT)) 412 { 413 TRACE("AtaSendAtapiPacket(0x%x) failed. An execution error occurred Status: 0x%02x, Error: 0x%02x\n", 414 AtapiPacket[0], AtaReadPort(Channel, IDX_ATAPI_IO1_i_Status), AtaReadPort(Channel, IDX_ATAPI_IO1_i_Error)); 415 return FALSE; 416 } 417 418 return TRUE; 419 } 420 421 static 422 BOOLEAN 423 AtapiReadLogicalSectorLBA( 424 IN PDEVICE_UNIT DeviceUnit, 425 IN ULONGLONG SectorNumber, 426 OUT PVOID Buffer) 427 { 428 UCHAR AtapiPacket[16]; 429 USHORT DataSize; 430 BOOLEAN Success; 431 432 /* Select the drive */ 433 SelectDevice(DeviceUnit->Channel, DeviceUnit->DeviceNumber); 434 if (!WaitForBusy(DeviceUnit->Channel, ATA_STATUS_TIMEOUT)) 435 { 436 ERR("AtapiReadLogicalSectorLBA() failed. Device is busy!\n"); 437 return FALSE; 438 } 439 440 /* Disable interrupts */ 441 AtaWritePort(DeviceUnit->Channel, IDX_IO2_o_Control, IDE_DC_DISABLE_INTERRUPTS); 442 StallExecutionProcessor(1); 443 444 /* Send the SCSI READ command */ 445 RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket)); 446 AtapiPacket[0] = SCSIOP_READ; 447 AtapiPacket[2] = (SectorNumber >> 24) & 0xFF; 448 AtapiPacket[3] = (SectorNumber >> 16) & 0xFF; 449 AtapiPacket[4] = (SectorNumber >> 8) & 0xFF; 450 AtapiPacket[5] = SectorNumber & 0xFF; 451 AtapiPacket[8] = 1; 452 Success = AtaSendAtapiPacket(DeviceUnit->Channel, 453 AtapiPacket, 454 ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData), 455 DeviceUnit->SectorSize); 456 if (!Success) 457 { 458 ERR("AtapiReadLogicalSectorLBA() failed. A read error occurred.\n"); 459 AtapiPrintSenseData(DeviceUnit); 460 return FALSE; 461 } 462 463 DataSize = (AtaReadPort(DeviceUnit->Channel, IDX_ATAPI_IO1_i_ByteCountHigh) << 8) | 464 AtaReadPort(DeviceUnit->Channel, IDX_ATAPI_IO1_i_ByteCountLow); 465 466 /* Transfer the data block */ 467 AtaReadBuffer(DeviceUnit->Channel, Buffer, DataSize); 468 469 return TRUE; 470 } 471 472 static 473 VOID 474 AtapiCapacityDetect( 475 IN PDEVICE_UNIT DeviceUnit, 476 OUT PULONGLONG TotalSectors, 477 OUT PULONG SectorSize) 478 { 479 UCHAR AtapiPacket[16]; 480 UCHAR AtapiCapacity[8]; 481 482 /* Send the SCSI READ CAPACITY(10) command */ 483 RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket)); 484 AtapiPacket[0] = SCSIOP_READ_CAPACITY; 485 if (AtaSendAtapiPacket(DeviceUnit->Channel, AtapiPacket, ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData), 8)) 486 { 487 AtaReadBuffer(DeviceUnit->Channel, &AtapiCapacity, 8); 488 489 *TotalSectors = (AtapiCapacity[0] << 24) | (AtapiCapacity[1] << 16) | 490 (AtapiCapacity[2] << 8) | AtapiCapacity[3]; 491 492 *SectorSize = (AtapiCapacity[4] << 24) | (AtapiCapacity[5] << 16) | 493 (AtapiCapacity[6] << 8) | AtapiCapacity[7]; 494 495 /* If device reports a non-zero block length, reset to defaults (we use READ command instead of READ CD) */ 496 if (*SectorSize != 0) 497 *SectorSize = 2048; 498 } 499 else 500 { 501 *TotalSectors = 0; 502 *SectorSize = 0; 503 504 AtapiPrintSenseData(DeviceUnit); 505 } 506 } 507 508 static 509 BOOLEAN 510 AtapiRequestSense( 511 IN PDEVICE_UNIT DeviceUnit, 512 OUT PSENSE_DATA SenseData) 513 { 514 UCHAR AtapiPacket[16]; 515 BOOLEAN Success; 516 517 RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket)); 518 RtlZeroMemory(SenseData, sizeof(SENSE_DATA)); 519 AtapiPacket[0] = SCSIOP_REQUEST_SENSE; 520 AtapiPacket[4] = SENSE_BUFFER_SIZE; 521 Success = AtaSendAtapiPacket(DeviceUnit->Channel, 522 AtapiPacket, 523 ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData), 524 SENSE_BUFFER_SIZE); 525 if (Success) 526 { 527 AtaReadBuffer(DeviceUnit->Channel, SenseData, SENSE_BUFFER_SIZE); 528 return TRUE; 529 } 530 else 531 { 532 ERR("Cannot read the sense data.\n"); 533 return FALSE; 534 } 535 } 536 537 static 538 VOID 539 AtapiPrintSenseData(IN PDEVICE_UNIT DeviceUnit) 540 { 541 SENSE_DATA SenseData; 542 543 if (AtapiRequestSense(DeviceUnit, &SenseData)) 544 { 545 ERR("SK 0x%x, ASC 0x%x, ASCQ 0x%x\n", 546 SenseData.SenseKey, 547 SenseData.AdditionalSenseCode, 548 SenseData.AdditionalSenseCodeQualifier); 549 } 550 } 551 552 static 553 BOOLEAN 554 AtapiReadyCheck(IN OUT PDEVICE_UNIT DeviceUnit) 555 { 556 UCHAR AtapiPacket[16]; 557 UCHAR DummyData[MAXIMUM_CDROM_SIZE]; 558 SENSE_DATA SenseData; 559 BOOLEAN Success; 560 561 /* Select the drive */ 562 SelectDevice(DeviceUnit->Channel, DeviceUnit->DeviceNumber); 563 if (!WaitForBusy(DeviceUnit->Channel, ATA_STATUS_TIMEOUT)) 564 return FALSE; 565 566 /* Send the SCSI TEST UNIT READY command */ 567 RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket)); 568 AtapiPacket[0] = SCSIOP_TEST_UNIT_READY; 569 AtaSendAtapiPacket(DeviceUnit->Channel, 570 AtapiPacket, 571 ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData), 572 0); 573 574 if (!AtapiRequestSense(DeviceUnit, &SenseData)) 575 return FALSE; 576 577 AtaReadBuffer(DeviceUnit->Channel, &SenseData, SENSE_BUFFER_SIZE); 578 TRACE("SK 0x%x, ASC 0x%x, ASCQ 0x%x\n", 579 SenseData.SenseKey, 580 SenseData.AdditionalSenseCode, 581 SenseData.AdditionalSenseCodeQualifier); 582 583 if (SenseData.SenseKey == SCSI_SENSE_NOT_READY) 584 { 585 if (SenseData.AdditionalSenseCode == SCSI_ADSENSE_LUN_NOT_READY) 586 { 587 switch (SenseData.AdditionalSenseCodeQualifier) 588 { 589 case SCSI_SENSEQ_BECOMING_READY: 590 /* Wait until the CD is spun up */ 591 StallExecutionProcessor(4e6); 592 return FALSE; 593 594 case SCSI_SENSEQ_INIT_COMMAND_REQUIRED: 595 /* The drive needs to be spun up, send the SCSI READ TOC command */ 596 RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket)); 597 AtapiPacket[0] = SCSIOP_READ_TOC; 598 AtapiPacket[7] = (MAXIMUM_CDROM_SIZE << 8) & 0xFF; 599 AtapiPacket[8] = MAXIMUM_CDROM_SIZE & 0xFF; 600 AtapiPacket[9] = READ_TOC_FORMAT_SESSION << 6; 601 Success = AtaSendAtapiPacket(DeviceUnit->Channel, 602 AtapiPacket, 603 ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData), 604 MAXIMUM_CDROM_SIZE); 605 if (!Success) 606 { 607 AtapiPrintSenseData(DeviceUnit); 608 return FALSE; 609 } 610 611 AtaReadBuffer(DeviceUnit->Channel, &DummyData, MAXIMUM_CDROM_SIZE); 612 /* fall through */ 613 614 default: 615 DeviceUnit->Flags &= ~ATA_DEVICE_NOT_READY; 616 return FALSE; 617 618 } 619 } 620 else if (SenseData.AdditionalSenseCode == SCSI_ADSENSE_NO_MEDIA_IN_DEVICE) 621 { 622 DeviceUnit->Flags |= ATA_DEVICE_NO_MEDIA; 623 return FALSE; 624 } 625 } 626 else 627 { 628 DeviceUnit->Flags &= ~ATA_DEVICE_NOT_READY; 629 } 630 631 if (DeviceUnit->Flags & ATA_DEVICE_NO_MEDIA) 632 { 633 /* Detect a medium's capacity */ 634 AtapiCapacityDetect(DeviceUnit, &DeviceUnit->TotalSectors, &DeviceUnit->SectorSize); 635 636 /* If nothing was returned, reset to defaults */ 637 if (DeviceUnit->SectorSize == 0) 638 DeviceUnit->SectorSize = 2048; 639 if (DeviceUnit->TotalSectors == 0) 640 DeviceUnit->TotalSectors = 0xFFFFFFFF; 641 642 DeviceUnit->Flags &= ~ATA_DEVICE_NO_MEDIA; 643 } 644 645 return TRUE; 646 } 647 648 static 649 BOOLEAN 650 WaitForFlags( 651 IN UCHAR Channel, 652 IN UCHAR Flags, 653 IN UCHAR ExpectedValue, 654 IN ULONG Timeout) 655 { 656 UCHAR Status; 657 658 ASSERT(Timeout != 0); 659 660 WaitForBusy(Channel, ATA_STATUS_TIMEOUT); 661 662 while (Timeout--) 663 { 664 StallExecutionProcessor(10); 665 666 Status = AtaReadPort(Channel, IDX_IO1_i_Status); 667 if (Status & IDE_STATUS_ERROR) 668 return FALSE; 669 else if ((Status & Flags) == ExpectedValue) 670 return TRUE; 671 } 672 return FALSE; 673 } 674 675 static 676 BOOLEAN 677 WaitForFlagsOr( 678 IN UCHAR Channel, 679 IN UCHAR FirstValue, 680 IN UCHAR SecondValue, 681 IN ULONG Timeout) 682 { 683 UCHAR Status; 684 685 ASSERT(Timeout != 0); 686 687 WaitForBusy(Channel, ATA_STATUS_TIMEOUT); 688 689 while (Timeout--) 690 { 691 StallExecutionProcessor(10); 692 693 Status = AtaReadPort(Channel, IDX_IO1_i_Status); 694 if (Status & IDE_STATUS_ERROR) 695 return FALSE; 696 else if ((Status & FirstValue) || (Status & SecondValue)) 697 return TRUE; 698 } 699 return FALSE; 700 } 701 702 static 703 BOOLEAN 704 WaitForBusy( 705 IN UCHAR Channel, 706 IN ULONG Timeout) 707 { 708 ASSERT(Timeout != 0); 709 710 while (Timeout--) 711 { 712 StallExecutionProcessor(10); 713 714 if ((AtaReadPort(Channel, IDX_IO1_i_Status) & IDE_STATUS_BUSY) == 0) 715 return TRUE; 716 } 717 return FALSE; 718 } 719 720 static 721 VOID 722 AtaHardReset(IN UCHAR Channel) 723 { 724 TRACE("AtaHardReset(Controller %d)\n", Channel); 725 726 AtaWritePort(Channel, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER); 727 StallExecutionProcessor(100000); 728 AtaWritePort(Channel, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER); 729 StallExecutionProcessor(5); 730 WaitForBusy(Channel, ATA_STATUS_TIMEOUT); 731 } 732 733 static 734 VOID 735 SelectDevice(IN UCHAR Channel, IN UCHAR DeviceNumber) 736 { 737 #if defined(SARCH_PC98) 738 /* Select IDE Channel */ 739 WRITE_PORT_UCHAR((PUCHAR)IDE_IO_o_BankSelect, Channel); 740 StallExecutionProcessor(5); 741 #endif 742 743 AtaWritePort(Channel, IDX_IO1_o_DriveSelect, 744 DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1); 745 StallExecutionProcessor(5); 746 } 747 748 static 749 BOOLEAN 750 IdentifyDevice( 751 IN UCHAR Channel, 752 IN UCHAR DeviceNumber, 753 OUT PDEVICE_UNIT *DeviceUnit) 754 { 755 UCHAR SignatureLow, SignatureHigh, SignatureCount, SignatureNumber; 756 UCHAR Command; 757 IDENTIFY_DATA Id; 758 SENSE_DATA SenseData; 759 ULONG i; 760 ULONG SectorSize; 761 ULONGLONG TotalSectors; 762 USHORT Flags = 0; 763 764 TRACE("IdentifyDevice() Channel = %x, Device = %x, BaseIoAddress = 0x%x\n", 765 Channel, DeviceNumber, BaseArray[Channel]); 766 767 /* Look at controller */ 768 SelectDevice(Channel, DeviceNumber); 769 StallExecutionProcessor(5); 770 AtaWritePort(Channel, IDX_IO1_o_BlockNumber, 0x55); 771 AtaWritePort(Channel, IDX_IO1_o_BlockNumber, 0x55); 772 StallExecutionProcessor(5); 773 if (AtaReadPort(Channel, IDX_IO1_i_BlockNumber) != 0x55) 774 goto Failure; 775 776 /* Reset the controller */ 777 AtaHardReset(Channel); 778 779 /* Select the drive */ 780 SelectDevice(Channel, DeviceNumber); 781 if (!WaitForBusy(Channel, ATA_STATUS_TIMEOUT)) 782 goto Failure; 783 784 /* Signature check */ 785 SignatureLow = AtaReadPort(Channel, IDX_IO1_i_CylinderLow); 786 SignatureHigh = AtaReadPort(Channel, IDX_IO1_i_CylinderHigh); 787 SignatureCount = AtaReadPort(Channel, IDX_IO1_i_BlockCount); 788 SignatureNumber = AtaReadPort(Channel, IDX_IO1_i_BlockNumber); 789 TRACE("IdentifyDevice(): SL = 0x%x, SH = 0x%x, SC = 0x%x, SN = 0x%x\n", 790 SignatureLow, SignatureHigh, SignatureCount, SignatureNumber); 791 if (SignatureLow == 0x00 && SignatureHigh == 0x00 && 792 SignatureCount == 0x01 && SignatureNumber == 0x01) 793 { 794 TRACE("IdentifyDevice(): Found PATA device at %d:%d\n", Channel, DeviceNumber); 795 Command = IDE_COMMAND_IDENTIFY; 796 } 797 else if (SignatureLow == ATAPI_MAGIC_LSB && 798 SignatureHigh == ATAPI_MAGIC_MSB) 799 { 800 TRACE("IdentifyDevice(): Found ATAPI device at %d:%d\n", Channel, DeviceNumber); 801 Flags |= ATA_DEVICE_ATAPI | ATA_DEVICE_LBA | ATA_DEVICE_NOT_READY; 802 Command = IDE_COMMAND_ATAPI_IDENTIFY; 803 } 804 else 805 { 806 goto Failure; 807 } 808 809 /* Disable interrupts */ 810 AtaWritePort(Channel, IDX_IO2_o_Control, IDE_DC_DISABLE_INTERRUPTS); 811 StallExecutionProcessor(5); 812 813 /* Send the identify command */ 814 AtaWritePort(Channel, IDX_IO1_o_Command, Command); 815 StallExecutionProcessor(50); 816 if (!WaitForFlags(Channel, IDE_STATUS_DRQ, IDE_STATUS_DRQ, ATA_STATUS_TIMEOUT)) 817 { 818 ERR("IdentifyDevice(): Identify command failed.\n"); 819 goto Failure; 820 } 821 822 /* Receive parameter information from the device */ 823 AtaReadBuffer(Channel, &Id, IDENTIFY_DATA_SIZE); 824 825 /* Swap byte order of the ASCII data */ 826 for (i = 0; i < RTL_NUMBER_OF(Id.SerialNumber); ++i) 827 Id.SerialNumber[i] = RtlUshortByteSwap(Id.SerialNumber[i]); 828 829 for (i = 0; i < RTL_NUMBER_OF(Id.FirmwareRevision); ++i) 830 Id.FirmwareRevision[i] = RtlUshortByteSwap(Id.FirmwareRevision[i]); 831 832 for (i = 0; i < RTL_NUMBER_OF(Id.ModelNumber); ++i) 833 Id.ModelNumber[i] = RtlUshortByteSwap(Id.ModelNumber[i]); 834 835 TRACE("S/N %.*s\n", sizeof(Id.SerialNumber), Id.SerialNumber); 836 TRACE("FR %.*s\n", sizeof(Id.FirmwareRevision), Id.FirmwareRevision); 837 TRACE("MN %.*s\n", sizeof(Id.ModelNumber), Id.ModelNumber); 838 839 /* Allocate a new device unit structure */ 840 *DeviceUnit = FrLdrTempAlloc(sizeof(DEVICE_UNIT), TAG_ATA_DEVICE); 841 if (*DeviceUnit == NULL) 842 { 843 ERR("Failed to allocate device unit!\n"); 844 return FALSE; 845 } 846 847 RtlZeroMemory(*DeviceUnit, sizeof(DEVICE_UNIT)); 848 (*DeviceUnit)->Channel = Channel; 849 (*DeviceUnit)->DeviceNumber = DeviceNumber; 850 (*DeviceUnit)->IdentifyData = Id; 851 852 if (Flags & ATA_DEVICE_ATAPI) 853 { 854 /* Clear the ATAPI 'Bus reset' indication */ 855 for (i = 0; i < 10; ++i) 856 { 857 AtapiRequestSense(*DeviceUnit, &SenseData); 858 StallExecutionProcessor(10); 859 } 860 861 /* Detect a medium's capacity */ 862 AtapiCapacityDetect(*DeviceUnit, &TotalSectors, &SectorSize); 863 if (SectorSize == 0 || TotalSectors == 0) 864 { 865 /* It's ok and can be used to show alert like "Please insert the CD" */ 866 TRACE("No media found.\n"); 867 Flags |= ATA_DEVICE_NO_MEDIA; 868 } 869 } 870 else 871 { 872 if (Id.SupportLba || (Id.MajorRevision && Id.UserAddressableSectors)) 873 { 874 if (Id.FeaturesSupport.Address48) 875 { 876 TRACE("Using LBA48 addressing mode.\n"); 877 Flags |= ATA_DEVICE_LBA48 | ATA_DEVICE_LBA; 878 TotalSectors = Id.UserAddressableSectors48; 879 } 880 else 881 { 882 TRACE("Using LBA28 addressing mode.\n"); 883 Flags |= ATA_DEVICE_LBA; 884 TotalSectors = Id.UserAddressableSectors; 885 } 886 887 /* LBA ATA drives always have a sector size of 512 */ 888 SectorSize = 512; 889 } 890 else 891 { 892 TRACE("Using CHS addressing mode.\n"); 893 Flags |= ATA_DEVICE_CHS; 894 895 if (Id.UnformattedBytesPerSector == 0) 896 { 897 SectorSize = 512; 898 } 899 else 900 { 901 for (i = 1 << 15; i > 0; i >>= 1) 902 { 903 if ((Id.UnformattedBytesPerSector & i) != 0) 904 { 905 SectorSize = i; 906 break; 907 } 908 } 909 } 910 TotalSectors = Id.NumberOfCylinders * Id.NumberOfHeads * Id.SectorsPerTrack; 911 } 912 } 913 TRACE("Sector size %d ; Total sectors %I64d\n", SectorSize, TotalSectors); 914 915 (*DeviceUnit)->Flags = Flags; 916 (*DeviceUnit)->SectorSize = SectorSize; 917 (*DeviceUnit)->TotalSectors = TotalSectors; 918 if (Flags & ATA_DEVICE_ATAPI) 919 { 920 (*DeviceUnit)->Cylinders = 0xFFFFFFFF; 921 (*DeviceUnit)->Heads = 0xFFFFFFFF; 922 (*DeviceUnit)->Sectors = 0xFFFFFFFF; 923 } 924 else 925 { 926 (*DeviceUnit)->Cylinders = Id.NumberOfCylinders; 927 (*DeviceUnit)->Heads = Id.NumberOfHeads; 928 (*DeviceUnit)->Sectors = Id.SectorsPerTrack; 929 } 930 931 #if DBG 932 DbgDumpBuffer(DPRINT_DISK, &Id, IDENTIFY_DATA_SIZE); 933 #endif 934 935 TRACE("IdentifyDevice() done.\n"); 936 return TRUE; 937 938 Failure: 939 TRACE("IdentifyDevice() done. No device present at %d:%d\n", Channel, DeviceNumber); 940 return FALSE; 941 } 942