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