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