1 /* 2 * PROJECT: ReactOS Kernel 3 * LICENSE: GNU GPLv2 only as published by the Free Software Foundation 4 * PURPOSE: To Implement AHCI Miniport driver targeting storport NT 5.2 5 * PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) 6 */ 7 8 #include <ntddk.h> 9 #include <ata.h> 10 #include <storport.h> 11 12 #define NDEBUG 13 #include <debug.h> 14 15 #define DEBUG 1 16 #if defined(_MSC_VER) 17 #pragma warning(disable:4214) // bit field types other than int 18 #pragma warning(disable:4201) // nameless struct/union 19 #endif 20 21 #define MAXIMUM_AHCI_PORT_COUNT 32 22 #define MAXIMUM_AHCI_PRDT_ENTRIES 32 23 #define MAXIMUM_AHCI_PORT_NCS 30 24 #define MAXIMUM_QUEUE_BUFFER_SIZE 255 25 #define MAXIMUM_TRANSFER_LENGTH (128*1024) // 128 KB 26 27 #define DEVICE_ATA_BLOCK_SIZE 512 28 29 // device type (DeviceParams) 30 #define AHCI_DEVICE_TYPE_ATA 1 31 #define AHCI_DEVICE_TYPE_ATAPI 2 32 #define AHCI_DEVICE_TYPE_NODEVICE 3 33 34 // section 3.1.2 35 #define AHCI_Global_HBA_CAP_S64A (1 << 31) 36 37 // FIS Types : http://wiki.osdev.org/AHCI 38 #define FIS_TYPE_REG_H2D 0x27 // Register FIS - host to device 39 #define FIS_TYPE_REG_D2H 0x34 // Register FIS - device to host 40 #define FIS_TYPE_DMA_ACT 0x39 // DMA activate FIS - device to host 41 #define FIS_TYPE_DMA_SETUP 0x41 // DMA setup FIS - bidirectional 42 #define FIS_TYPE_BIST 0x58 // BIST activate FIS - bidirectional 43 #define FIS_TYPE_PIO_SETUP 0x5F // PIO setup FIS - device to host 44 #define FIS_TYPE_DEV_BITS 0xA1 // Set device bits FIS - device to host 45 46 #define AHCI_ATA_CFIS_FisType 0 47 #define AHCI_ATA_CFIS_PMPort_C 1 48 #define AHCI_ATA_CFIS_CommandReg 2 49 #define AHCI_ATA_CFIS_FeaturesLow 3 50 #define AHCI_ATA_CFIS_LBA0 4 51 #define AHCI_ATA_CFIS_LBA1 5 52 #define AHCI_ATA_CFIS_LBA2 6 53 #define AHCI_ATA_CFIS_Device 7 54 #define AHCI_ATA_CFIS_LBA3 8 55 #define AHCI_ATA_CFIS_LBA4 9 56 #define AHCI_ATA_CFIS_LBA5 10 57 #define AHCI_ATA_CFIS_FeaturesHigh 11 58 #define AHCI_ATA_CFIS_SectorCountLow 12 59 #define AHCI_ATA_CFIS_SectorCountHigh 13 60 61 // ATA Functions 62 #define ATA_FUNCTION_ATA_COMMAND 0x100 63 #define ATA_FUNCTION_ATA_IDENTIFY 0x101 64 #define ATA_FUNCTION_ATA_READ 0x102 65 66 // ATAPI Functions 67 #define ATA_FUNCTION_ATAPI_COMMAND 0x200 68 69 // ATA Flags 70 #define ATA_FLAGS_DATA_IN (1 << 1) 71 #define ATA_FLAGS_DATA_OUT (1 << 2) 72 #define ATA_FLAGS_48BIT_COMMAND (1 << 3) 73 #define ATA_FLAGS_USE_DMA (1 << 4) 74 75 #define IsAtaCommand(AtaFunction) (AtaFunction & ATA_FUNCTION_ATA_COMMAND) 76 #define IsAtapiCommand(AtaFunction) (AtaFunction & ATA_FUNCTION_ATAPI_COMMAND) 77 #define IsDataTransferNeeded(SrbExtension) (SrbExtension->Flags & (ATA_FLAGS_DATA_IN | ATA_FLAGS_DATA_OUT)) 78 #define IsAdapterCAPS64(CAP) (CAP & AHCI_Global_HBA_CAP_S64A) 79 80 // 3.1.1 NCS = CAP[12:08] -> Align 81 #define AHCI_Global_Port_CAP_NCS(x) (((x) & 0xF00) >> 8) 82 83 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) 84 //#define AhciDebugPrint(format, ...) StorPortDebugPrint(0, format, __VA_ARGS__) 85 #define AhciDebugPrint(format, ...) DbgPrint("(%s:%d) " format, __RELFILE__, __LINE__, ##__VA_ARGS__) 86 87 typedef 88 VOID 89 (*PAHCI_COMPLETION_ROUTINE) ( 90 __in PVOID PortExtension, 91 __in PVOID Srb 92 ); 93 94 ////////////////////////////////////////////////////////////// 95 // ---- Support Structures --- // 96 ////////////////////////////////////////////////////////////// 97 98 // section 3.3.5 99 typedef union _AHCI_INTERRUPT_STATUS 100 { 101 struct 102 { 103 ULONG DHRS:1; //Device to Host Register FIS Interrupt 104 ULONG PSS :1; //PIO Setup FIS Interrupt 105 ULONG DSS :1; //DMA Setup FIS Interrupt 106 ULONG SDBS :1; //Set Device Bits Interrupt 107 ULONG UFS :1; //Unknown FIS Interrupt 108 ULONG DPS :1; //Descriptor Processed 109 ULONG PCS :1; //Port Connect Change Status 110 ULONG DMPS :1; //Device Mechanical Presence Status (DMPS) 111 ULONG Reserved :14; 112 ULONG PRCS :1; //PhyRdy Change Status 113 ULONG IPMS :1; //Incorrect Port Multiplier Status 114 ULONG OFS :1; //Overflow Status 115 ULONG Reserved2 :1; 116 ULONG INFS :1; //Interface Non-fatal Error Status 117 ULONG IFS :1; //Interface Fatal Error Status 118 ULONG HBDS :1; //Host Bus Data Error Status 119 ULONG HBFS :1; //Host Bus Fatal Error Status 120 ULONG TFES :1; //Task File Error Status 121 ULONG CPDS :1; //Cold Port Detect Status 122 }; 123 124 ULONG Status; 125 } AHCI_INTERRUPT_STATUS; 126 127 typedef struct _AHCI_FIS_DMA_SETUP 128 { 129 ULONG ULONG0_1; // FIS_TYPE_DMA_SETUP 130 // Port multiplier 131 // Reserved 132 // Data transfer direction, 1 - device to host 133 // Interrupt bit 134 // Auto-activate. Specifies if DMA Activate FIS is needed 135 UCHAR Reserved[2]; // Reserved 136 ULONG DmaBufferLow; // DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work. 137 ULONG DmaBufferHigh; 138 ULONG Reserved2; // More reserved 139 ULONG DmaBufferOffset; // Byte offset into buffer. First 2 bits must be 0 140 ULONG TranferCount; // Number of bytes to transfer. Bit 0 must be 0 141 ULONG Reserved3; // Reserved 142 } AHCI_FIS_DMA_SETUP; 143 144 typedef struct _AHCI_PIO_SETUP_FIS 145 { 146 UCHAR FisType; 147 UCHAR Reserved1 :5; 148 UCHAR D :1; 149 UCHAR I :1; 150 UCHAR Reserved2 :1; 151 UCHAR Status; 152 UCHAR Error; 153 154 UCHAR SectorNumber; 155 UCHAR CylLow; 156 UCHAR CylHigh; 157 UCHAR Dev_Head; 158 159 UCHAR SectorNumb_Exp; 160 UCHAR CylLow_Exp; 161 UCHAR CylHigh_Exp; 162 UCHAR Reserved3; 163 164 UCHAR SectorCount; 165 UCHAR SectorCount_Exp; 166 UCHAR Reserved4; 167 UCHAR E_Status; 168 169 USHORT TransferCount; 170 UCHAR Reserved5[2]; 171 } AHCI_PIO_SETUP_FIS; 172 173 typedef struct _AHCI_D2H_REGISTER_FIS 174 { 175 UCHAR FisType; 176 UCHAR Reserved1 :6; 177 UCHAR I:1; 178 UCHAR Reserved2 :1; 179 UCHAR Status; 180 UCHAR Error; 181 182 UCHAR SectorNumber; 183 UCHAR CylLow; 184 UCHAR CylHigh; 185 UCHAR Dev_Head; 186 187 UCHAR SectorNum_Exp; 188 UCHAR CylLow_Exp; 189 UCHAR CylHigh_Exp; 190 UCHAR Reserved; 191 192 UCHAR SectorCount; 193 UCHAR SectorCount_Exp; 194 UCHAR Reserved3[2]; 195 196 UCHAR Reserved4[4]; 197 } AHCI_D2H_REGISTER_FIS; 198 199 typedef struct _AHCI_SET_DEVICE_BITS_FIS 200 { 201 UCHAR FisType; 202 203 UCHAR PMPort: 4; 204 UCHAR Reserved1 :2; 205 UCHAR I :1; 206 UCHAR N :1; 207 208 UCHAR Status_Lo :3; 209 UCHAR Reserved2 :1; 210 UCHAR Status_Hi :3; 211 UCHAR Reserved3 :1; 212 213 UCHAR Error; 214 215 UCHAR Reserved5[4]; 216 } AHCI_SET_DEVICE_BITS_FIS; 217 218 typedef struct _AHCI_QUEUE 219 { 220 PVOID Buffer[MAXIMUM_QUEUE_BUFFER_SIZE]; // because Storahci hold Srb queue of 255 size 221 ULONG Head; 222 ULONG Tail; 223 } AHCI_QUEUE, *PAHCI_QUEUE; 224 225 ////////////////////////////////////////////////////////////// 226 // --------------------------- // 227 ////////////////////////////////////////////////////////////// 228 229 typedef union _AHCI_COMMAND_HEADER_DESCRIPTION 230 { 231 struct 232 { 233 ULONG CFL : 5; // Command FIS Length 234 ULONG A : 1; // IsATAPI 235 ULONG W : 1; // Write 236 ULONG P : 1; // Prefetchable 237 238 ULONG R : 1; // Reset 239 ULONG B : 1; // BIST 240 ULONG C : 1; //Clear Busy upon R_OK 241 ULONG RSV : 1; 242 ULONG PMP : 4; //Port Multiplier Port 243 244 ULONG PRDTL : 16; //Physical Region Descriptor Table Length 245 }; 246 247 ULONG Status; 248 } AHCI_COMMAND_HEADER_DESCRIPTION; 249 250 typedef union _AHCI_GHC 251 { 252 struct 253 { 254 ULONG HR : 1; 255 ULONG IE : 1; 256 ULONG MRSM : 1; 257 ULONG RSV0 : 28; 258 ULONG AE : 1; 259 }; 260 261 ULONG Status; 262 } AHCI_GHC; 263 264 // section 3.3.7 265 typedef union _AHCI_PORT_CMD 266 { 267 struct 268 { 269 ULONG ST : 1; 270 ULONG SUD : 1; 271 ULONG POD : 1; 272 ULONG CLO : 1; 273 ULONG FRE : 1; 274 ULONG RSV0 : 3; 275 ULONG CCS : 5; 276 ULONG MPSS : 1; 277 ULONG FR : 1; 278 ULONG CR : 1; 279 ULONG CPS : 1; 280 ULONG PMA : 1; 281 ULONG HPCP : 1; 282 ULONG MPSP : 1; 283 ULONG CPD : 1; 284 ULONG ESP : 1; 285 ULONG FBSCP : 1; 286 ULONG APSTE : 1; 287 ULONG ATAPI : 1; 288 ULONG DLAE : 1; 289 ULONG ALPE : 1; 290 ULONG ASP : 1; 291 ULONG ICC : 4; 292 }; 293 294 ULONG Status; 295 } AHCI_PORT_CMD; 296 297 typedef union _AHCI_SERIAL_ATA_CONTROL 298 { 299 struct 300 { 301 ULONG DET :4; 302 ULONG SPD :4; 303 ULONG IPM :4; 304 ULONG SPM :4; 305 ULONG PMP :4; 306 ULONG DW11_Reserved :12; 307 }; 308 309 ULONG Status; 310 } AHCI_SERIAL_ATA_CONTROL; 311 312 typedef union _AHCI_SERIAL_ATA_STATUS 313 { 314 struct 315 { 316 ULONG DET :4; 317 ULONG SPD :4; 318 ULONG IPM :4; 319 ULONG RSV0 :20; 320 }; 321 322 ULONG Status; 323 } AHCI_SERIAL_ATA_STATUS; 324 325 typedef union _AHCI_TASK_FILE_DATA 326 { 327 struct 328 { 329 struct _STS 330 { 331 UCHAR ERR : 1; 332 UCHAR CS1 : 2; 333 UCHAR DRQ : 1; 334 UCHAR CS2 : 3; 335 UCHAR BSY : 1; 336 } STS; 337 UCHAR ERR; 338 USHORT RSV; 339 }; 340 341 ULONG Status; 342 } AHCI_TASK_FILE_DATA; 343 344 typedef struct _AHCI_PRDT 345 { 346 ULONG DBA; 347 ULONG DBAU; 348 ULONG RSV0; 349 350 ULONG DBC : 22; 351 ULONG RSV1 : 9; 352 ULONG I : 1; 353 } AHCI_PRDT, *PAHCI_PRDT; 354 355 // 4.2.3 Command Table 356 typedef struct _AHCI_COMMAND_TABLE 357 { 358 // (16 * 32) + 64 + 16 + 48 = 648 359 // 128 byte aligned :D 360 UCHAR CFIS[64]; 361 UCHAR ACMD[16]; 362 UCHAR RSV0[48]; 363 AHCI_PRDT PRDT[MAXIMUM_AHCI_PRDT_ENTRIES]; 364 } AHCI_COMMAND_TABLE, *PAHCI_COMMAND_TABLE; 365 366 // 4.2.2 Command Header 367 typedef struct _AHCI_COMMAND_HEADER 368 { 369 AHCI_COMMAND_HEADER_DESCRIPTION DI; // DW 0 370 ULONG PRDBC; // DW 1 371 ULONG CTBA; // DW 2 372 ULONG CTBA_U; // DW 3 373 ULONG Reserved[4]; // DW 4-7 374 } AHCI_COMMAND_HEADER, *PAHCI_COMMAND_HEADER; 375 376 // Received FIS 377 typedef struct _AHCI_RECEIVED_FIS 378 { 379 struct _AHCI_FIS_DMA_SETUP DmaSetupFIS; // 0x00 -- DMA Setup FIS 380 ULONG pad0; // 4 BYTE padding 381 struct _AHCI_PIO_SETUP_FIS PioSetupFIS; // 0x20 -- PIO Setup FIS 382 ULONG pad1[3]; // 12 BYTE padding 383 struct _AHCI_D2H_REGISTER_FIS RegisterFIS; // 0x40 -- Register – Device to Host FIS 384 ULONG pad2; // 4 BYTE padding 385 struct _AHCI_SET_DEVICE_BITS_FIS SetDeviceFIS; // 0x58 -- Set Device Bit FIS 386 ULONG UnknowFIS[16]; // 0x60 -- Unknown FIS 387 ULONG Reserved[24]; // 0xA0 -- Reserved 388 } AHCI_RECEIVED_FIS, *PAHCI_RECEIVED_FIS; 389 390 // Holds Port Information 391 typedef struct _AHCI_PORT 392 { 393 ULONG CLB; // 0x00, command list base address, 1K-byte aligned 394 ULONG CLBU; // 0x04, command list base address upper 32 bits 395 ULONG FB; // 0x08, FIS base address, 256-byte aligned 396 ULONG FBU; // 0x0C, FIS base address upper 32 bits 397 ULONG IS; // 0x10, interrupt status 398 ULONG IE; // 0x14, interrupt enable 399 ULONG CMD; // 0x18, command and status 400 ULONG RSV0; // 0x1C, Reserved 401 ULONG TFD; // 0x20, task file data 402 ULONG SIG; // 0x24, signature 403 ULONG SSTS; // 0x28, SATA status (SCR0:SStatus) 404 ULONG SCTL; // 0x2C, SATA control (SCR2:SControl) 405 ULONG SERR; // 0x30, SATA error (SCR1:SError) 406 ULONG SACT; // 0x34, SATA active (SCR3:SActive) 407 ULONG CI; // 0x38, command issue 408 ULONG SNTF; // 0x3C, SATA notification (SCR4:SNotification) 409 ULONG FBS; // 0x40, FIS-based switch control 410 ULONG RSV1[11]; // 0x44 ~ 0x6F, Reserved 411 ULONG Vendor[4]; // 0x70 ~ 0x7F, vendor specific 412 } AHCI_PORT, *PAHCI_PORT; 413 414 typedef union _AHCI_INTERRUPT_ENABLE 415 { 416 struct 417 { 418 ULONG DHRE :1; 419 ULONG PSE :1; 420 ULONG DSE :1; 421 ULONG SDBE :1; 422 ULONG UFE :1; 423 ULONG DPE :1; 424 ULONG PCE :1; 425 ULONG DMPE :1; 426 ULONG DW5_Reserved :14; 427 ULONG PRCE :1; 428 ULONG IPME :1; 429 ULONG OFE :1; 430 ULONG DW5_Reserved2 :1; 431 ULONG INFE :1; 432 ULONG IFE :1; 433 ULONG HBDE :1; 434 ULONG HBFE :1; 435 ULONG TFEE :1; 436 ULONG CPDE :1; 437 }; 438 439 ULONG Status; 440 } AHCI_INTERRUPT_ENABLE; 441 442 typedef struct _AHCI_MEMORY_REGISTERS 443 { 444 // 0x00 - 0x2B, Generic Host Control 445 ULONG CAP; // 0x00, Host capability 446 ULONG GHC; // 0x04, Global host control 447 ULONG IS; // 0x08, Interrupt status 448 ULONG PI; // 0x0C, Port implemented 449 ULONG VS; // 0x10, Version 450 ULONG CCC_CTL; // 0x14, Command completion coalescing control 451 ULONG CCC_PTS; // 0x18, Command completion coalescing ports 452 ULONG EM_LOC; // 0x1C, Enclosure management location 453 ULONG EM_CTL; // 0x20, Enclosure management control 454 ULONG CAP2; // 0x24, Host capabilities extended 455 ULONG BOHC; // 0x28, BIOS/OS handoff control and status 456 ULONG Reserved[0x1d]; // 0x2C - 0x9F, Reserved 457 ULONG VendorSpecific[0x18]; // 0xA0 - 0xFF, Vendor specific registers 458 AHCI_PORT PortList[MAXIMUM_AHCI_PORT_COUNT]; 459 } AHCI_MEMORY_REGISTERS, *PAHCI_MEMORY_REGISTERS; 460 461 // Holds information for each attached attached port to a given adapter. 462 typedef struct _AHCI_PORT_EXTENSION 463 { 464 ULONG PortNumber; 465 ULONG QueueSlots; // slots which we have already assigned task (Slot) 466 ULONG CommandIssuedSlots; // slots which has been programmed 467 ULONG MaxPortQueueDepth; 468 469 struct 470 { 471 UCHAR RemovableDevice; 472 UCHAR Lba48BitMode; 473 UCHAR AccessType; 474 UCHAR DeviceType; 475 UCHAR IsActive; 476 LARGE_INTEGER MaxLba; 477 ULONG BytesPerLogicalSector; 478 ULONG BytesPerPhysicalSector; 479 UCHAR VendorId[41]; 480 UCHAR RevisionID[9]; 481 UCHAR SerialNumber[21]; 482 } DeviceParams; 483 484 STOR_DPC CommandCompletion; 485 PAHCI_PORT Port; // AHCI Port Infomation 486 AHCI_QUEUE SrbQueue; // pending Srbs 487 AHCI_QUEUE CompletionQueue; 488 PSCSI_REQUEST_BLOCK Slot[MAXIMUM_AHCI_PORT_NCS]; // Srbs which has been alloted a port 489 PAHCI_RECEIVED_FIS ReceivedFIS; 490 PAHCI_COMMAND_HEADER CommandList; 491 STOR_DEVICE_POWER_STATE DevicePowerState; // Device Power State 492 PIDENTIFY_DEVICE_DATA IdentifyDeviceData; 493 STOR_PHYSICAL_ADDRESS IdentifyDeviceDataPhysicalAddress; 494 struct _AHCI_ADAPTER_EXTENSION* AdapterExtension; // Port's Adapter Information 495 } AHCI_PORT_EXTENSION, *PAHCI_PORT_EXTENSION; 496 497 // Holds Adapter Information 498 typedef struct _AHCI_ADAPTER_EXTENSION 499 { 500 ULONG SystemIoBusNumber; 501 ULONG SlotNumber; 502 ULONG AhciBaseAddress; 503 PULONG IS;// Interrupt Status, In case of MSIM == `1` 504 ULONG PortImplemented;// bit-mapping of ports which are implemented 505 ULONG PortCount; 506 507 USHORT VendorID; 508 USHORT DeviceID; 509 USHORT RevisionID; 510 511 ULONG Version; 512 ULONG CAP; 513 ULONG CAP2; 514 ULONG LastInterruptPort; 515 ULONG CurrentCommandSlot; 516 517 PVOID NonCachedExtension; // holds virtual address to noncached buffer allocated for Port Extension 518 519 struct 520 { 521 // Message per port or shared port? 522 ULONG MessagePerPort : 1; 523 ULONG Removed : 1; 524 ULONG Reserved : 30; // not in use -- maintain 4 byte alignment 525 } StateFlags; 526 527 PAHCI_MEMORY_REGISTERS ABAR_Address; 528 AHCI_PORT_EXTENSION PortExtension[MAXIMUM_AHCI_PORT_COUNT]; 529 } AHCI_ADAPTER_EXTENSION, *PAHCI_ADAPTER_EXTENSION; 530 531 typedef struct _LOCAL_SCATTER_GATHER_LIST 532 { 533 ULONG NumberOfElements; 534 ULONG_PTR Reserved; 535 STOR_SCATTER_GATHER_ELEMENT List[MAXIMUM_AHCI_PRDT_ENTRIES]; 536 } LOCAL_SCATTER_GATHER_LIST, *PLOCAL_SCATTER_GATHER_LIST; 537 538 typedef struct _AHCI_SRB_EXTENSION 539 { 540 AHCI_COMMAND_TABLE CommandTable; 541 ULONG AtaFunction; 542 ULONG Flags; 543 544 UCHAR CommandReg; 545 UCHAR FeaturesLow; 546 UCHAR LBA0; 547 UCHAR LBA1; 548 UCHAR LBA2; 549 UCHAR Device; 550 UCHAR LBA3; 551 UCHAR LBA4; 552 UCHAR LBA5; 553 UCHAR FeaturesHigh; 554 555 UCHAR SectorCountLow; 556 UCHAR SectorCountHigh; 557 558 ULONG SlotIndex; 559 LOCAL_SCATTER_GATHER_LIST Sgl; 560 PLOCAL_SCATTER_GATHER_LIST pSgl; 561 PAHCI_COMPLETION_ROUTINE CompletionRoutine; 562 563 // for alignment purpose -- 128 byte alignment 564 // do not try to access (R/W) this field 565 UCHAR Reserved[128]; 566 } AHCI_SRB_EXTENSION, *PAHCI_SRB_EXTENSION; 567 568 ////////////////////////////////////////////////////////////// 569 // Declarations // 570 ////////////////////////////////////////////////////////////// 571 572 VOID 573 AhciProcessIO ( 574 __in PAHCI_ADAPTER_EXTENSION AdapterExtension, 575 __in UCHAR PathId, 576 __in PSCSI_REQUEST_BLOCK Srb 577 ); 578 579 BOOLEAN 580 AhciAdapterReset ( 581 __in PAHCI_ADAPTER_EXTENSION AdapterExtension 582 ); 583 584 FORCEINLINE 585 VOID 586 AhciZeroMemory ( 587 __out PCHAR Buffer, 588 __in ULONG BufferSize 589 ); 590 591 FORCEINLINE 592 BOOLEAN 593 IsPortValid ( 594 __in PAHCI_ADAPTER_EXTENSION AdapterExtension, 595 __in ULONG pathId 596 ); 597 598 UCHAR DeviceRequestSense ( 599 __in PAHCI_ADAPTER_EXTENSION AdapterExtension, 600 __in PSCSI_REQUEST_BLOCK Srb, 601 __in PCDB Cdb 602 ); 603 604 UCHAR DeviceRequestReadWrite ( 605 __in PAHCI_ADAPTER_EXTENSION AdapterExtension, 606 __in PSCSI_REQUEST_BLOCK Srb, 607 __in PCDB Cdb 608 ); 609 610 UCHAR DeviceRequestCapacity ( 611 __in PAHCI_ADAPTER_EXTENSION AdapterExtension, 612 __in PSCSI_REQUEST_BLOCK Srb, 613 __in PCDB Cdb 614 ); 615 616 UCHAR 617 DeviceInquiryRequest ( 618 __in PAHCI_ADAPTER_EXTENSION AdapterExtension, 619 __in PSCSI_REQUEST_BLOCK Srb, 620 __in PCDB Cdb 621 ); 622 623 UCHAR DeviceRequestComplete ( 624 __in PAHCI_ADAPTER_EXTENSION AdapterExtension, 625 __in PSCSI_REQUEST_BLOCK Srb, 626 __in PCDB Cdb 627 ); 628 629 UCHAR DeviceReportLuns ( 630 __in PAHCI_ADAPTER_EXTENSION AdapterExtension, 631 __in PSCSI_REQUEST_BLOCK Srb, 632 __in PCDB Cdb 633 ); 634 635 FORCEINLINE 636 BOOLEAN 637 AddQueue ( 638 __inout PAHCI_QUEUE Queue, 639 __in PVOID Srb 640 ); 641 642 FORCEINLINE 643 PVOID 644 RemoveQueue ( 645 __inout PAHCI_QUEUE Queue 646 ); 647 648 FORCEINLINE 649 PAHCI_SRB_EXTENSION 650 GetSrbExtension( 651 __in PSCSI_REQUEST_BLOCK Srb 652 ); 653 654 FORCEINLINE 655 ULONG64 656 AhciGetLba ( 657 __in PCDB Cdb, 658 __in ULONG CdbLength 659 ); 660 661 ////////////////////////////////////////////////////////////// 662 // Assertions // 663 ////////////////////////////////////////////////////////////// 664 665 // I assert every silly mistake I can do while coding 666 // because god never help me debugging the code 667 // but these asserts do :') 668 669 C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CAP) == 0x00); 670 C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, GHC) == 0x04); 671 C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, IS) == 0x08); 672 C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, PI) == 0x0C); 673 C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, VS) == 0x10); 674 C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CCC_CTL) == 0x14); 675 C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CCC_PTS) == 0x18); 676 C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, EM_LOC) == 0x1C); 677 C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, EM_CTL) == 0x20); 678 C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CAP2) == 0x24); 679 C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, BOHC) == 0x28); 680 C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, Reserved) == 0x2C); 681 C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, VendorSpecific) == 0xA0); 682 C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, PortList) == 0x100); 683 684 C_ASSERT(FIELD_OFFSET(AHCI_PORT, CLB) == 0x00); 685 C_ASSERT(FIELD_OFFSET(AHCI_PORT, CLBU) == 0x04); 686 C_ASSERT(FIELD_OFFSET(AHCI_PORT, FB) == 0x08); 687 C_ASSERT(FIELD_OFFSET(AHCI_PORT, FBU) == 0x0C); 688 C_ASSERT(FIELD_OFFSET(AHCI_PORT, IS) == 0x10); 689 C_ASSERT(FIELD_OFFSET(AHCI_PORT, IE) == 0x14); 690 C_ASSERT(FIELD_OFFSET(AHCI_PORT, CMD) == 0x18); 691 C_ASSERT(FIELD_OFFSET(AHCI_PORT, RSV0) == 0x1C); 692 C_ASSERT(FIELD_OFFSET(AHCI_PORT, TFD) == 0x20); 693 C_ASSERT(FIELD_OFFSET(AHCI_PORT, SIG) == 0x24); 694 C_ASSERT(FIELD_OFFSET(AHCI_PORT, SSTS) == 0x28); 695 C_ASSERT(FIELD_OFFSET(AHCI_PORT, SCTL) == 0x2C); 696 C_ASSERT(FIELD_OFFSET(AHCI_PORT, SERR) == 0x30); 697 C_ASSERT(FIELD_OFFSET(AHCI_PORT, SACT) == 0x34); 698 C_ASSERT(FIELD_OFFSET(AHCI_PORT, CI) == 0x38); 699 C_ASSERT(FIELD_OFFSET(AHCI_PORT, SNTF) == 0x3C); 700 C_ASSERT(FIELD_OFFSET(AHCI_PORT, FBS) == 0x40); 701 C_ASSERT(FIELD_OFFSET(AHCI_PORT, RSV1) == 0x44); 702 C_ASSERT(FIELD_OFFSET(AHCI_PORT, Vendor) == 0x70); 703 704 C_ASSERT((sizeof(AHCI_COMMAND_TABLE) % 128) == 0); 705 706 C_ASSERT(sizeof(AHCI_GHC) == sizeof(ULONG)); 707 C_ASSERT(sizeof(AHCI_PORT_CMD) == sizeof(ULONG)); 708 C_ASSERT(sizeof(AHCI_TASK_FILE_DATA) == sizeof(ULONG)); 709 C_ASSERT(sizeof(AHCI_INTERRUPT_ENABLE) == sizeof(ULONG)); 710 C_ASSERT(sizeof(AHCI_SERIAL_ATA_STATUS) == sizeof(ULONG)); 711 C_ASSERT(sizeof(AHCI_SERIAL_ATA_CONTROL) == sizeof(ULONG)); 712 C_ASSERT(sizeof(AHCI_COMMAND_HEADER_DESCRIPTION) == sizeof(ULONG)); 713 714 C_ASSERT(FIELD_OFFSET(AHCI_COMMAND_TABLE, CFIS) == 0x00); 715 C_ASSERT(FIELD_OFFSET(AHCI_COMMAND_TABLE, ACMD) == 0x40); 716 C_ASSERT(FIELD_OFFSET(AHCI_COMMAND_TABLE, RSV0) == 0x50); 717 C_ASSERT(FIELD_OFFSET(AHCI_COMMAND_TABLE, PRDT) == 0x80); 718