xref: /reactos/drivers/storage/ide/uniata/id_sata.h (revision 98e8827a)
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     volatile 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__
428