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