3 Copyright (c) 2008-2012 Alexandr A. Telyatnikov (Alter)
9 This module handles SATA-related staff
12 Alexander A. Telyatnikov (Alter)
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.
37 #ifndef __UNIATA_SATA__H__
38 #define __UNIATA_SATA__H__
43 IN PVOID HwDeviceExtension
,
44 IN ULONG lChannel
, // logical channel
45 IN ULONG pm_port
= 0 /* for port multipliers */
48 #define UNIATA_SATA_RESET_ENABLE TRUE
49 #define UNIATA_SATA_FAST_ENABLE FALSE
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
60 #define UNIATA_SATA_DO_CONNECT TRUE
61 #define UNIATA_SATA_IGNORE_CONNECT FALSE
66 IN PVOID HwDeviceExtension
,
67 IN ULONG lChannel
, // logical channel
68 IN BOOLEAN do_connect
,
69 IN ULONG pm_port
= 0 /* for port multipliers */
72 #define UNIATA_SATA_EVENT_ATTACH 0x01
73 #define UNIATA_SATA_EVENT_DETACH 0x02
78 IN PVOID HwDeviceExtension
,
79 IN ULONG lChannel
, // logical channel
81 IN ULONG pm_port
= 0 /* for port multipliers */
84 #define UniataIsSATARangeAvailable(deviceExtension, lChannel) \
85 ((deviceExtension->BaseIoAddressSATA_0.Addr || \
86 deviceExtension->BaseIoAHCI_0.Addr) && \
87 (deviceExtension->chan[lChannel].RegTranslation[IDX_SATA_SStatus].Addr))
91 UniataIsSATARangeAvailable(
92 IN PHW_DEVICE_EXTENSION deviceExtension
,
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
) {
103 } // end UniataIsSATARangeAvailable()
110 IN ULONG io_port_ndx
,
111 IN ULONG pm_port
=0 /* for port multipliers */
116 UniataSataWritePort4(
118 IN ULONG io_port_ndx
,
120 IN ULONG pm_port
=0 /* for port multipliers */
126 IN PVOID HwDeviceExtension
132 UniataDumpAhciPortRegs(
140 IN PVOID HwDeviceExtension
,
141 IN PPCI_COMMON_CONFIG pciData
, // optional
142 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
148 IN PVOID HwDeviceExtension
,
150 IN ULONG DeviceNumber
155 UniataAhciSnapAtaRegs(
157 IN ULONG DeviceNumber
,
158 IN OUT PIDEREGS_EX regs
163 UniataAhciSetupFIS_H2D(
164 IN PHW_DEVICE_EXTENSION deviceExtension
,
165 IN ULONG DeviceNumber
,
176 UniataAhciWaitCommandReady(
183 UniataAhciSendCommand(
184 IN PVOID HwDeviceExtension
,
186 IN ULONG DeviceNumber
,
187 IN USHORT ahci_flags
,
193 UniataAhciSendPIOCommand(
194 IN PVOID HwDeviceExtension
,
196 IN ULONG DeviceNumber
,
197 IN PSCSI_REQUEST_BLOCK Srb
,
204 IN USHORT ahci_flags
,
211 UniataAhciSendPIOCommandDirect(
212 IN PVOID HwDeviceExtension
,
214 IN ULONG DeviceNumber
,
215 IN PSCSI_REQUEST_BLOCK Srb
,
223 UniataAhciAbortOperation(
230 IN PVOID HwDeviceExtension
,
232 IN ULONG DeviceNumber
245 IN PVOID HwDeviceExtension
,
253 IN PVOID HwDeviceExtension
,
290 UniataAhciReadChannelPort4(
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
));
298 } // end UniataAhciReadChannelPort4()
302 UniataAhciWriteChannelPort4(
304 IN ULONG io_port_ndx
,
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()
313 #define UniataAhciReadHostPort4(deviceExtension, io_port_ndx) \
314 AtapiReadPortEx4(NULL, (ULONGIO_PTR)&((deviceExtension)->BaseIoAHCI_0), io_port_ndx)
316 #define UniataAhciWriteHostPort4(deviceExtension, io_port_ndx, data) \
317 AtapiWritePortEx4(NULL, (ULONGIO_PTR)&((deviceExtension)->BaseIoAHCI_0), io_port_ndx, data)
321 UniataAhciBeginTransaction(
322 IN PVOID HwDeviceExtension
,
324 IN ULONG DeviceNumber
,
325 IN PSCSI_REQUEST_BLOCK Srb
330 UniataAhciEndTransaction(
331 IN PVOID HwDeviceExtension
,
333 IN ULONG DeviceNumber
,
334 IN PSCSI_REQUEST_BLOCK Srb
345 UniataAhciUlongFromRFIS(
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()
357 UniAtaAhciAdjustIoFlags(
359 IN USHORT ahci_flags
,
361 IN ULONG DeviceNumber
364 ahci_flags
|= (fis_size
/ sizeof(ULONG
)) | (DeviceNumber
<< 12);
369 if(AtaCommandFlags
[command
] & ATA_CMD_FLAG_Out
) {
370 ahci_flags
|= ATA_AHCI_CMD_WRITE
;
373 if(AtaCommandFlags[command] & ATA_CMD_FLAG_In) {
374 ahci_flags |= ATA_AHCI_CMD_READ;
378 } // end UniAtaAhciAdjustIoFlags()
384 IN ULONG DeviceNumber
,
393 IN ULONG DeviceNumber
,
399 UniataAhciSetupCmdPtr(
400 IN OUT PATA_REQ AtaReq
405 BuildAhciInternalSrb (
406 IN PVOID HwDeviceExtension
,
407 IN ULONG DeviceNumber
,
409 IN PUCHAR Buffer
= NULL
,
415 UniataAhciChanImplemented(
416 IN PHW_DEVICE_EXTENSION deviceExtension
,
421 KdPrint2((PRINT_PREFIX
"imp: %#x & %#x\n", (deviceExtension
)->AHCI_PI
, (1<<c
) ));
423 return (((deviceExtension
)->AHCI_PI
) & ((ULONG
)1 << c
)) ? TRUE
: FALSE
;
424 } // end UniataAhciChanImplemented()
427 #endif //__UNIATA_SATA__H__