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