changes after code review
[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 <storport.h>
10
11 #define DEBUG 1
12
13 #define MAXIMUM_AHCI_PORT_COUNT 12
14 #define MAXIMUM_TRANSFER_LENGTH (128*1024) // 128 KB
15
16 // section 3.1.2
17 #define AHCI_Global_HBA_CONTROL_HR (1 << 0)
18 #define AHCI_Global_HBA_CONTROL_IE (1 << 1)
19 #define AHCI_Global_HBA_CONTROL_MRSM (1 << 2)
20 #define AHCI_Global_HBA_CONTROL_AE (1 << 31)
21 #define AHCI_Global_HBA_CAP_S64A (1 << 31)
22
23 // 3.1.1 NCS = CAP[12:08] -> Align
24 #define AHCI_Global_Port_CAP_NCS(x) (((x) & 0xF00) >> 8)
25
26 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
27 #if DEBUG
28 #define DebugPrint(format, ...) StorPortDebugPrint(0, format, __VA_ARGS__)
29 #endif
30
31 //////////////////////////////////////////////////////////////
32 // ---- Support Structures --- //
33 //////////////////////////////////////////////////////////////
34
35 typedef struct _AHCI_FIS_DMA_SETUP
36 {
37 ULONG ULONG0_1; // FIS_TYPE_DMA_SETUP
38 // Port multiplier
39 // Reserved
40 // Data transfer direction, 1 - device to host
41 // Interrupt bit
42 // Auto-activate. Specifies if DMA Activate FIS is needed
43 UCHAR Reserved[2]; // Reserved
44 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.
45 ULONG DmaBufferHigh;
46 ULONG Reserved2; // More reserved
47 ULONG DmaBufferOffset; // Byte offset into buffer. First 2 bits must be 0
48 ULONG TranferCount; // Number of bytes to transfer. Bit 0 must be 0
49 ULONG Reserved3; // Reserved
50 } AHCI_FIS_DMA_SETUP;
51
52 typedef struct _AHCI_PIO_SETUP_FIS
53 {
54 UCHAR FisType;
55 UCHAR Reserved1 :5;
56 UCHAR D :1;
57 UCHAR I :1;
58 UCHAR Reserved2 :1;
59 UCHAR Status;
60 UCHAR Error;
61
62 UCHAR SectorNumber;
63 UCHAR CylLow;
64 UCHAR CylHigh;
65 UCHAR Dev_Head;
66
67 UCHAR SectorNumb_Exp;
68 UCHAR CylLow_Exp;
69 UCHAR CylHigh_Exp;
70 UCHAR Reserved3;
71
72 UCHAR SectorCount;
73 UCHAR SectorCount_Exp;
74 UCHAR Reserved4;
75 UCHAR E_Status;
76
77 USHORT TransferCount;
78 UCHAR Reserved5[2];
79 } AHCI_PIO_SETUP_FIS;
80
81 typedef struct _AHCI_D2H_REGISTER_FIS
82 {
83 UCHAR FisType;
84 UCHAR Reserved1 :6;
85 UCHAR I:1;
86 UCHAR Reserved2 :1;
87 UCHAR Status;
88 UCHAR Error;
89
90 UCHAR SectorNumber;
91 UCHAR CylLow;
92 UCHAR CylHigh;
93 UCHAR Dev_Head;
94
95 UCHAR SectorNum_Exp;
96 UCHAR CylLow_Exp;
97 UCHAR CylHigh_Exp;
98 UCHAR Reserved;
99
100 UCHAR SectorCount;
101 UCHAR SectorCount_Exp;
102 UCHAR Reserved3[2];
103
104 UCHAR Reserved4[4];
105 } AHCI_D2H_REGISTER_FIS;
106
107 typedef struct _AHCI_SET_DEVICE_BITS_FIS
108 {
109 UCHAR FisType;
110
111 UCHAR PMPort: 4;
112 UCHAR Reserved1 :2;
113 UCHAR I :1;
114 UCHAR N :1;
115
116 UCHAR Status_Lo :3;
117 UCHAR Reserved2 :1;
118 UCHAR Status_Hi :3;
119 UCHAR Reserved3 :1;
120
121 UCHAR Error;
122
123 UCHAR Reserved5[4];
124 } AHCI_SET_DEVICE_BITS_FIS;
125
126 //////////////////////////////////////////////////////////////
127 // --------------------------- //
128 //////////////////////////////////////////////////////////////
129
130 // 4.2.2 Command Header
131 typedef struct _AHCI_COMMAND_HEADER
132 {
133 ULONG HEADER_DESCRIPTION; // DW 0
134 ULONG PRDBC; // DW 1
135 ULONG CTBA0; // DW 2
136 ULONG CTBA_U0; // DW 3
137 ULONG Reserved[4]; // DW 4-7
138 } AHCI_COMMAND_HEADER, *PAHCI_COMMAND_HEADER;
139
140 // Received FIS
141 typedef struct _AHCI_RECEIVED_FIS
142 {
143 struct _AHCI_FIS_DMA_SETUP DmaSetupFIS; // 0x00 -- DMA Setup FIS
144 ULONG pad0; // 4 BYTE padding
145 struct _AHCI_PIO_SETUP_FIS PioSetupFIS; // 0x20 -- PIO Setup FIS
146 ULONG pad1[3]; // 12 BYTE padding
147 struct _AHCI_D2H_REGISTER_FIS RegisterFIS; // 0x40 -- Register – Device to Host FIS
148 ULONG pad2; // 4 BYTE padding
149 struct _AHCI_SET_DEVICE_BITS_FIS SetDeviceFIS; // 0x58 -- Set Device Bit FIS
150 ULONG UnknowFIS[16]; // 0x60 -- Unknown FIS
151 ULONG Reserved[24]; // 0xA0 -- Reserved
152 } AHCI_RECEIVED_FIS, *PAHCI_RECEIVED_FIS;
153
154 // Holds Port Information
155 typedef struct _AHCI_PORT
156 {
157 ULONG CLB; // 0x00, command list base address, 1K-byte aligned
158 ULONG CLBU; // 0x04, command list base address upper 32 bits
159 ULONG FB; // 0x08, FIS base address, 256-byte aligned
160 ULONG FBU; // 0x0C, FIS base address upper 32 bits
161 ULONG IS; // 0x10, interrupt status
162 ULONG IE; // 0x14, interrupt enable
163 ULONG CMD; // 0x18, command and status
164 ULONG RSV0; // 0x1C, Reserved
165 ULONG TFD; // 0x20, task file data
166 ULONG SIG; // 0x24, signature
167 ULONG SSTS; // 0x28, SATA status (SCR0:SStatus)
168 ULONG SCTL; // 0x2C, SATA control (SCR2:SControl)
169 ULONG SERR; // 0x30, SATA error (SCR1:SError)
170 ULONG SACT; // 0x34, SATA active (SCR3:SActive)
171 ULONG CI; // 0x38, command issue
172 ULONG SNTF; // 0x3C, SATA notification (SCR4:SNotification)
173 ULONG FBS; // 0x40, FIS-based switch control
174 ULONG RSV1[11]; // 0x44 ~ 0x6F, Reserved
175 ULONG Vendor[4]; // 0x70 ~ 0x7F, vendor specific
176 } AHCI_PORT, *PAHCI_PORT;
177
178 typedef struct _AHCI_MEMORY_REGISTERS
179 {
180 // 0x00 - 0x2B, Generic Host Control
181 ULONG CAP; // 0x00, Host capability
182 ULONG GHC; // 0x04, Global host control
183 ULONG IS; // 0x08, Interrupt status
184 ULONG PI; // 0x0C, Port implemented
185 ULONG VS; // 0x10, Version
186 ULONG CCC_CTL; // 0x14, Command completion coalescing control
187 ULONG CCC_PTS; // 0x18, Command completion coalescing ports
188 ULONG EM_LOC; // 0x1C, Enclosure management location
189 ULONG EM_CTL; // 0x20, Enclosure management control
190 ULONG CAP2; // 0x24, Host capabilities extended
191 ULONG BOHC; // 0x28, BIOS/OS handoff control and status
192 ULONG Reserved[0xA0-0x2C]; // 0x2C - 0x9F, Reserved
193 ULONG VendorSpecific[0x100-0xA0]; // 0xA0 - 0xFF, Vendor specific registers
194 AHCI_PORT PortList[MAXIMUM_AHCI_PORT_COUNT];
195
196 } AHCI_MEMORY_REGISTERS, *PAHCI_MEMORY_REGISTERS;
197
198 // Holds information for each attached attached port to a given adapter.
199 typedef struct _AHCI_PORT_EXTENSION
200 {
201 ULONG PortNumber;
202 BOOLEAN IsActive;
203 PAHCI_PORT Port; // AHCI Port Infomation
204 PAHCI_RECEIVED_FIS ReceivedFIS;
205 PAHCI_COMMAND_HEADER CommandList;
206 STOR_DEVICE_POWER_STATE DevicePowerState; // Device Power State
207 struct _AHCI_ADAPTER_EXTENSION* AdapterExtension; // Port's Adapter Information
208 } AHCI_PORT_EXTENSION, *PAHCI_PORT_EXTENSION;
209
210 // Holds Adapter Information
211 typedef struct _AHCI_ADAPTER_EXTENSION
212 {
213 ULONG SystemIoBusNumber;
214 ULONG SlotNumber;
215 ULONG AhciBaseAddress;
216 PULONG IS;// Interrupt Status, In case of MSIM == `1`
217 ULONG PortImplemented;// bit-mapping of ports which are implemented
218
219 USHORT VendorID;
220 USHORT DeviceID;
221 USHORT RevisionID;
222
223 ULONG Version;
224 ULONG CAP;
225 ULONG CAP2;
226 ULONG LastInterruptPort;
227
228 PVOID NonCachedExtension;// holds virtual address to noncached buffer allocated for Port Extension
229
230 struct
231 {
232 // Message per port or shared port?
233 ULONG MessagePerPort : 1;
234 ULONG Removed : 1;
235 ULONG Reserved : 30; // not in use -- maintain 4 byte alignment
236 } StateFlags;
237
238 PAHCI_MEMORY_REGISTERS ABAR_Address;
239 AHCI_PORT_EXTENSION PortExtension[MAXIMUM_AHCI_PORT_COUNT];
240 } AHCI_ADAPTER_EXTENSION, *PAHCI_ADAPTER_EXTENSION;
241
242 typedef struct _AHCI_SRB_EXTENSION
243 {
244 ULONG Reserved[4];
245 } AHCI_SRB_EXTENSION;
246
247 //////////////////////////////////////////////////////////////
248 // Declarations //
249 //////////////////////////////////////////////////////////////
250
251 BOOLEAN
252 AhciAdapterReset (
253 __in PAHCI_ADAPTER_EXTENSION adapterExtension
254 );
255
256 __inline
257 VOID
258 AhciZeroMemory (
259 __out PCHAR buffer,
260 __in ULONG bufferSize
261 );
262
263 __inline
264 BOOLEAN
265 IsPortValid (
266 __in PAHCI_ADAPTER_EXTENSION adapterExtension,
267 __in UCHAR pathId
268 );
269
270 ULONG
271 DeviceInquiryRequest (
272 __in PAHCI_ADAPTER_EXTENSION adapterExtension,
273 __in PSCSI_REQUEST_BLOCK Srb,
274 __in PCDB Cdb
275 );