[USBOHCI_NEW][USBUHCI_NEW] Avoid unnecessary/incorrect status defines.
[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 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 __inline
585 VOID
586 AhciZeroMemory (
587 __out PCHAR Buffer,
588 __in ULONG BufferSize
589 );
590
591 __inline
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 __inline
636 BOOLEAN
637 AddQueue (
638 __inout PAHCI_QUEUE Queue,
639 __in PVOID Srb
640 );
641
642 __inline
643 PVOID
644 RemoveQueue (
645 __inout PAHCI_QUEUE Queue
646 );
647
648 __inline
649 PAHCI_SRB_EXTENSION
650 GetSrbExtension(
651 __in PSCSI_REQUEST_BLOCK Srb
652 );
653
654 __inline
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);