692d6bdf6a4b8ab4f405cf27af5ab23ead6804b4
[reactos.git] / drivers / storage / ide / uniata / id_sata.h
1 /*++
2
3 Copyright (c) 2008-2012 Alexandr A. Telyatnikov (Alter)
4
5 Module Name:
6 id_probe.cpp
7
8 Abstract:
9 This module handles SATA-related staff
10
11 Author:
12 Alexander A. Telyatnikov (Alter)
13
14 Environment:
15 kernel mode only
16
17 Notes:
18
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 Revision History:
31
32 Licence:
33 GPLv2
34
35 --*/
36
37 #ifndef __UNIATA_SATA__H__
38 #define __UNIATA_SATA__H__
39
40 UCHAR
41 NTAPI
42 UniataSataConnect(
43 IN PVOID HwDeviceExtension,
44 IN ULONG lChannel, // logical channel
45 IN ULONG pm_port = 0 /* for port multipliers */
46 );
47
48 #define UNIATA_SATA_RESET_ENABLE TRUE
49 #define UNIATA_SATA_FAST_ENABLE FALSE
50
51 UCHAR
52 NTAPI
53 UniataSataPhyEnable(
54 IN PVOID HwDeviceExtension,
55 IN ULONG lChannel, // logical channel
56 IN ULONG pm_port = 0, /* for port multipliers */
57 IN BOOLEAN doReset = UNIATA_SATA_FAST_ENABLE
58 );
59
60 #define UNIATA_SATA_DO_CONNECT TRUE
61 #define UNIATA_SATA_IGNORE_CONNECT FALSE
62
63 BOOLEAN
64 NTAPI
65 UniataSataClearErr(
66 IN PVOID HwDeviceExtension,
67 IN ULONG lChannel, // logical channel
68 IN BOOLEAN do_connect,
69 IN ULONG pm_port = 0 /* for port multipliers */
70 );
71
72 #define UNIATA_SATA_EVENT_ATTACH 0x01
73 #define UNIATA_SATA_EVENT_DETACH 0x02
74
75 BOOLEAN
76 NTAPI
77 UniataSataEvent(
78 IN PVOID HwDeviceExtension,
79 IN ULONG lChannel, // logical channel
80 IN ULONG Action,
81 IN ULONG pm_port = 0 /* for port multipliers */
82 );
83 /*
84 #define UniataIsSATARangeAvailable(deviceExtension, lChannel) \
85 ((deviceExtension->BaseIoAddressSATA_0.Addr || \
86 deviceExtension->BaseIoAHCI_0.Addr) && \
87 (deviceExtension->chan[lChannel].RegTranslation[IDX_SATA_SStatus].Addr))
88 */
89 __inline
90 BOOLEAN
91 UniataIsSATARangeAvailable(
92 IN PHW_DEVICE_EXTENSION deviceExtension,
93 IN ULONG lChannel
94 )
95 {
96 // seems, check for deviceExtension->BaseIoAddressSATA_0.Addr and
97 // deviceExtension->BaseIoAHCI_0.Addr is not necessary now
98 if(deviceExtension->chan[lChannel].RegTranslation[IDX_SATA_SStatus].Addr ||
99 deviceExtension->chan[lChannel].RegTranslation[IDX_SATA_SStatus].Proc) {
100 return TRUE;
101 }
102 return FALSE;
103 } // end UniataIsSATARangeAvailable()
104
105
106 ULONG
107 NTAPI
108 UniataSataReadPort4(
109 IN PHW_CHANNEL chan,
110 IN ULONG io_port_ndx,
111 IN ULONG pm_port=0 /* for port multipliers */
112 );
113
114 VOID
115 NTAPI
116 UniataSataWritePort4(
117 IN PHW_CHANNEL chan,
118 IN ULONG io_port_ndx,
119 IN ULONG data,
120 IN ULONG pm_port=0 /* for port multipliers */
121 );
122
123 BOOLEAN
124 NTAPI
125 UniataAhciInit(
126 IN PVOID HwDeviceExtension
127 );
128
129 #ifdef _DEBUG
130 VOID
131 NTAPI
132 UniataDumpAhciPortRegs(
133 IN PHW_CHANNEL chan
134 );
135 #endif
136
137 BOOLEAN
138 NTAPI
139 UniataAhciDetect(
140 IN PVOID HwDeviceExtension,
141 IN PPCI_COMMON_CONFIG pciData, // optional
142 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
143 );
144
145 UCHAR
146 NTAPI
147 UniataAhciStatus(
148 IN PVOID HwDeviceExtension,
149 IN ULONG lChannel,
150 IN ULONG DeviceNumber
151 );
152
153 VOID
154 NTAPI
155 UniataAhciSnapAtaRegs(
156 IN PHW_CHANNEL chan,
157 IN ULONG DeviceNumber,
158 IN OUT PIDEREGS_EX regs
159 );
160
161 ULONG
162 NTAPI
163 UniataAhciSetupFIS_H2D(
164 IN PHW_DEVICE_EXTENSION deviceExtension,
165 IN ULONG DeviceNumber,
166 IN ULONG lChannel,
167 OUT PUCHAR fis,
168 IN UCHAR command,
169 IN ULONGLONG lba,
170 IN USHORT count,
171 IN USHORT feature
172 );
173
174 UCHAR
175 NTAPI
176 UniataAhciWaitCommandReady(
177 IN PHW_CHANNEL chan,
178 IN ULONG timeout
179 );
180
181 UCHAR
182 NTAPI
183 UniataAhciSendCommand(
184 IN PVOID HwDeviceExtension,
185 IN ULONG lChannel,
186 IN ULONG DeviceNumber,
187 IN USHORT ahci_flags,
188 IN ULONG timeout
189 );
190
191 UCHAR
192 NTAPI
193 UniataAhciSendPIOCommand(
194 IN PVOID HwDeviceExtension,
195 IN ULONG lChannel,
196 IN ULONG DeviceNumber,
197 IN PSCSI_REQUEST_BLOCK Srb,
198 IN PUCHAR data,
199 IN ULONG length,
200 IN UCHAR command,
201 IN ULONGLONG lba,
202 IN USHORT count,
203 IN USHORT feature,
204 IN USHORT ahci_flags,
205 IN ULONG flags,
206 IN ULONG timeout
207 );
208
209 UCHAR
210 NTAPI
211 UniataAhciSendPIOCommandDirect(
212 IN PVOID HwDeviceExtension,
213 IN ULONG lChannel,
214 IN ULONG DeviceNumber,
215 IN PSCSI_REQUEST_BLOCK Srb,
216 IN PIDEREGS_EX regs,
217 IN ULONG wait_flags,
218 IN ULONG timeout
219 );
220
221 BOOLEAN
222 NTAPI
223 UniataAhciAbortOperation(
224 IN PHW_CHANNEL chan
225 );
226
227 ULONG
228 NTAPI
229 UniataAhciSoftReset(
230 IN PVOID HwDeviceExtension,
231 IN ULONG lChannel,
232 IN ULONG DeviceNumber
233 );
234
235 ULONG
236 NTAPI
237 UniataAhciWaitReady(
238 IN PHW_CHANNEL chan,
239 IN ULONG timeout
240 );
241
242 ULONG
243 NTAPI
244 UniataAhciHardReset(
245 IN PVOID HwDeviceExtension,
246 IN ULONG lChannel,
247 OUT PULONG signature
248 );
249
250 VOID
251 NTAPI
252 UniataAhciReset(
253 IN PVOID HwDeviceExtension,
254 IN ULONG lChannel
255 );
256
257 VOID
258 NTAPI
259 UniataAhciStartFR(
260 IN PHW_CHANNEL chan
261 );
262
263 BOOLEAN
264 NTAPI
265 UniataAhciStopFR(
266 IN PHW_CHANNEL chan
267 );
268
269 VOID
270 NTAPI
271 UniataAhciStart(
272 IN PHW_CHANNEL chan
273 );
274
275 BOOLEAN
276 NTAPI
277 UniataAhciCLO(
278 IN PHW_CHANNEL chan
279 );
280
281 BOOLEAN
282 NTAPI
283 UniataAhciStop(
284 IN PHW_CHANNEL chan
285 );
286
287
288 __inline
289 ULONG
290 UniataAhciReadChannelPort4(
291 IN PHW_CHANNEL chan,
292 IN ULONG io_port_ndx
293 )
294 {
295 ULONG v = AtapiReadPortEx4(NULL, (ULONGIO_PTR)&((chan)->BaseIoAHCI_Port), io_port_ndx);
296 KdPrint3((PRINT_PREFIX "ReadChannelPort4 ch%d[%x] = %x\n", chan->lChannel, io_port_ndx, v));
297 return v;
298 } // end UniataAhciReadChannelPort4()
299
300 __inline
301 VOID
302 UniataAhciWriteChannelPort4(
303 IN PHW_CHANNEL chan,
304 IN ULONG io_port_ndx,
305 IN ULONG data
306 )
307 {
308 KdPrint3((PRINT_PREFIX "WriteChannelPort4 %x => ch%d[%x]\n", data, chan->lChannel, io_port_ndx));
309 AtapiWritePortEx4(NULL, (ULONGIO_PTR)&((chan)->BaseIoAHCI_Port), io_port_ndx, data);
310 } // end UniataAhciWriteChannelPort4()
311
312
313 #define UniataAhciReadHostPort4(deviceExtension, io_port_ndx) \
314 AtapiReadPortEx4(NULL, (ULONGIO_PTR)&((deviceExtension)->BaseIoAHCI_0), io_port_ndx)
315
316 #define UniataAhciWriteHostPort4(deviceExtension, io_port_ndx, data) \
317 AtapiWritePortEx4(NULL, (ULONGIO_PTR)&((deviceExtension)->BaseIoAHCI_0), io_port_ndx, data)
318
319 UCHAR
320 NTAPI
321 UniataAhciBeginTransaction(
322 IN PVOID HwDeviceExtension,
323 IN ULONG lChannel,
324 IN ULONG DeviceNumber,
325 IN PSCSI_REQUEST_BLOCK Srb
326 );
327
328 UCHAR
329 NTAPI
330 UniataAhciEndTransaction(
331 IN PVOID HwDeviceExtension,
332 IN ULONG lChannel,
333 IN ULONG DeviceNumber,
334 IN PSCSI_REQUEST_BLOCK Srb
335 );
336
337 VOID
338 NTAPI
339 UniataAhciResume(
340 IN PHW_CHANNEL chan
341 );
342
343 __inline
344 ULONG
345 UniataAhciUlongFromRFIS(
346 PUCHAR RCV_FIS
347 )
348 {
349 return ( (((ULONG)(RCV_FIS[6])) << 24) |
350 (((ULONG)(RCV_FIS[5])) << 16) |
351 (((ULONG)(RCV_FIS[4])) << 8) |
352 ((ULONG)(RCV_FIS[12])) );
353 } // end UniataAhciUlongFromRFIS()
354
355 __inline
356 USHORT
357 UniAtaAhciAdjustIoFlags(
358 IN UCHAR command,
359 IN USHORT ahci_flags,
360 IN ULONG fis_size,
361 IN ULONG DeviceNumber
362 )
363 {
364 ahci_flags |= (fis_size / sizeof(ULONG)) | (DeviceNumber << 12);
365 if(!command) {
366 return ahci_flags;
367 }
368
369 if(AtaCommandFlags[command] & ATA_CMD_FLAG_Out) {
370 ahci_flags |= ATA_AHCI_CMD_WRITE;
371 }
372 /*
373 if(AtaCommandFlags[command] & ATA_CMD_FLAG_In) {
374 ahci_flags |= ATA_AHCI_CMD_READ;
375 }
376 */
377 return ahci_flags;
378 } // end UniAtaAhciAdjustIoFlags()
379
380 BOOLEAN
381 NTAPI
382 UniataAhciReadPM(
383 IN PHW_CHANNEL chan,
384 IN ULONG DeviceNumber,
385 IN ULONG Reg,
386 OUT PULONG result
387 );
388
389 UCHAR
390 NTAPI
391 UniataAhciWritePM(
392 IN PHW_CHANNEL chan,
393 IN ULONG DeviceNumber,
394 IN ULONG Reg,
395 IN ULONG value
396 );
397
398 VOID
399 UniataAhciSetupCmdPtr(
400 IN OUT PATA_REQ AtaReq
401 );
402
403 PSCSI_REQUEST_BLOCK
404 NTAPI
405 BuildAhciInternalSrb (
406 IN PVOID HwDeviceExtension,
407 IN ULONG DeviceNumber,
408 IN ULONG lChannel,
409 IN PUCHAR Buffer = NULL,
410 IN ULONG Length = 0
411 );
412
413 __inline
414 BOOLEAN
415 UniataAhciChanImplemented(
416 IN PHW_DEVICE_EXTENSION deviceExtension,
417 IN ULONG c
418 )
419 {
420 #ifdef _DEBUG
421 KdPrint2((PRINT_PREFIX "imp: %#x & %#x\n", (deviceExtension)->AHCI_PI, (1<<c) ));
422 #endif
423 return (((deviceExtension)->AHCI_PI) & ((ULONG)1 << c)) ? TRUE : FALSE;
424 } // end UniataAhciChanImplemented()
425
426
427 #endif //__UNIATA_SATA__H__