3 Copyright (c) 2008-2019 Alexandr A. Telyatnikov (Alter)
9 This module handles SATA- and AHCI-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.
45 IN PVOID HwDeviceExtension
,
46 IN ULONG lChannel
, // logical channel
47 IN ULONG pm_port
/* for port multipliers */
50 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
51 //ULONG Channel = deviceExtension->Channel + lChannel;
52 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
53 SATA_SSTATUS_REG SStatus
;
61 KdPrint2((PRINT_PREFIX
"UniataSataConnect:\n"));
63 if(!UniataIsSATARangeAvailable(deviceExtension
, lChannel
)) {
64 KdPrint2((PRINT_PREFIX
" no I/O range\n"));
65 return IDE_STATUS_IDLE
;
68 /* clear SATA error register, some controllers need this */
69 UniataSataWritePort4(chan
, IDX_SATA_SError
,
70 UniataSataReadPort4(chan
, IDX_SATA_SError
, pm_port
), pm_port
);
71 /* wait up to 1 second for "connect well" */
72 for(i
=0; i
<100; i
++) {
73 SStatus
.Reg
= UniataSataReadPort4(chan
, IDX_SATA_SStatus
, pm_port
);
74 if(SStatus
.SPD
== SStatus_SPD_Gen1
||
75 SStatus
.SPD
== SStatus_SPD_Gen2
||
76 SStatus
.SPD
== SStatus_SPD_Gen3
) {
77 // SATA sets actual transfer rate in LunExt on init.
78 // There is no run-time SATA rate adjustment yet.
79 // On the other hand, we may turn SATA device in PIO mode
80 // TODO: make separate states for interface speed and transfer mode (DMA vs PIO)
81 chan
->lun
[0]->LimitedTransferMode
=
82 chan
->lun
[0]->PhyTransferMode
=
83 chan
->lun
[0]->TransferMode
= ATA_SA150
+ (UCHAR
)(SStatus
.SPD
- 1);
85 KdPrint2((PRINT_PREFIX
"SATA TransferMode %#x\n", chan
->lun
[0]->TransferMode
));
86 if(chan
->MaxTransferMode
< chan
->lun
[0]->TransferMode
) {
87 KdPrint2((PRINT_PREFIX
"SATA upd chan TransferMode\n"));
88 chan
->MaxTransferMode
= chan
->lun
[0]->TransferMode
;
90 if(deviceExtension
->MaxTransferMode
< chan
->lun
[0]->TransferMode
) {
91 KdPrint2((PRINT_PREFIX
"SATA upd controller TransferMode\n"));
92 deviceExtension
->MaxTransferMode
= chan
->lun
[0]->TransferMode
;
97 AtapiStallExecution(10000);
100 KdPrint2((PRINT_PREFIX
"UniataSataConnect: SStatus %8.8x\n", SStatus
.Reg
));
101 return IDE_STATUS_WRONG
;
103 /* clear SATA error register */
104 UniataSataWritePort4(chan
, IDX_SATA_SError
,
105 UniataSataReadPort4(chan
, IDX_SATA_SError
, pm_port
), pm_port
);
107 Status
= WaitOnBaseBusyLong(chan
);
108 if(Status
& IDE_STATUS_BUSY
) {
112 signatureLow = AtapiReadPort1(chan, &deviceExtension->BaseIoAddress1[lChannel].i.CylinderLow);
113 signatureHigh = AtapiReadPort1(chan, &deviceExtension->baseIoAddress1[lChannel].i.CylinderHigh);
115 if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) {
118 KdPrint2((PRINT_PREFIX
"UniataSataConnect: OK, ATA status %#x\n", Status
));
119 return IDE_STATUS_IDLE
;
120 } // end UniataSataConnect()
125 IN PVOID HwDeviceExtension
,
126 IN ULONG lChannel
, // logical channel
127 IN ULONG pm_port
, /* for port multipliers */
131 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
132 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
133 SATA_SCONTROL_REG SControl
;
136 KdPrint2((PRINT_PREFIX
"UniataSataPhyEnable:\n"));
138 if(!UniataIsSATARangeAvailable(deviceExtension
, lChannel
)) {
139 KdPrint2((PRINT_PREFIX
" no I/O range\n"));
140 return IDE_STATUS_IDLE
;
143 SControl
.Reg
= UniataSataReadPort4(chan
, IDX_SATA_SControl
, pm_port
);
144 KdPrint2((PRINT_PREFIX
"SControl %#x\n", SControl
.Reg
));
145 if(SControl
.DET
== SControl_DET_Idle
) {
147 return UniataSataConnect(HwDeviceExtension
, lChannel
, pm_port
);
151 for (retry
= 0; retry
< 10; retry
++) {
152 KdPrint2((PRINT_PREFIX
"UniataSataPhyEnable: retry init %d\n", retry
));
153 for (loop
= 0; loop
< 10; loop
++) {
155 SControl
.DET
= SControl_DET_Init
;
156 UniataSataWritePort4(chan
, IDX_SATA_SControl
, SControl
.Reg
, pm_port
);
157 AtapiStallExecution(100);
158 SControl
.Reg
= UniataSataReadPort4(chan
, IDX_SATA_SControl
, pm_port
);
159 KdPrint2((PRINT_PREFIX
" SControl %8.8x\n", SControl
.Reg
));
160 if(SControl
.DET
== SControl_DET_Init
) {
164 AtapiStallExecution(5000);
165 KdPrint2((PRINT_PREFIX
"UniataSataPhyEnable: retry idle %d\n", retry
));
166 for (loop
= 0; loop
< 10; loop
++) {
168 SControl
.DET
= SControl_DET_DoNothing
;
169 SControl
.IPM
= SControl_IPM_NoPartialSlumber
;
170 UniataSataWritePort4(chan
, IDX_SATA_SControl
, SControl
.Reg
, pm_port
);
171 AtapiStallExecution(100);
172 SControl
.Reg
= UniataSataReadPort4(chan
, IDX_SATA_SControl
, pm_port
);
173 KdPrint2((PRINT_PREFIX
" SControl %8.8x\n", SControl
.Reg
));
174 if(SControl
.DET
== SControl_DET_Idle
) {
175 return UniataSataConnect(HwDeviceExtension
, lChannel
, pm_port
);
180 KdPrint2((PRINT_PREFIX
"UniataSataPhyEnable: failed\n"));
181 return IDE_STATUS_WRONG
;
182 } // end UniataSataPhyEnable()
187 IN PVOID HwDeviceExtension
,
188 IN ULONG lChannel
, // logical channel
189 IN BOOLEAN do_connect
,
190 IN ULONG pm_port
/* for port multipliers */
193 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
194 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
195 //ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
196 SATA_SSTATUS_REG SStatus
;
197 SATA_SERROR_REG SError
;
199 if(UniataIsSATARangeAvailable(deviceExtension
, lChannel
)) {
200 //if(ChipFlags & UNIATA_SATA) {
202 SStatus
.Reg
= UniataSataReadPort4(chan
, IDX_SATA_SStatus
, pm_port
);
203 SError
.Reg
= UniataSataReadPort4(chan
, IDX_SATA_SError
, pm_port
);
206 KdPrint2((PRINT_PREFIX
" SStatus %#x\n", SStatus
.Reg
));
209 KdPrint2((PRINT_PREFIX
" SError %#x\n", SError
.Reg
));
210 /* clear error bits/interrupt */
211 UniataSataWritePort4(chan
, IDX_SATA_SError
, SError
.Reg
, pm_port
);
214 /* if we have a connection event deal with it */
216 KdPrint2((PRINT_PREFIX
" catch SATA connect/disconnect\n"));
217 if(SStatus
.SPD
>= SStatus_SPD_Gen1
) {
218 UniataSataEvent(deviceExtension
, lChannel
, UNIATA_SATA_EVENT_ATTACH
, pm_port
);
220 UniataSataEvent(deviceExtension
, lChannel
, UNIATA_SATA_EVENT_DETACH
, pm_port
);
229 } // end UniataSataClearErr()
234 IN PVOID HwDeviceExtension
,
235 IN ULONG lChannel
, // logical channel
237 IN ULONG pm_port
/* for port multipliers */
240 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
242 ULONG DeviceNumber
= (pm_port
? 1 : 0);
244 if(!UniataIsSATARangeAvailable(deviceExtension
, lChannel
)) {
249 case UNIATA_SATA_EVENT_ATTACH
:
250 KdPrint2((PRINT_PREFIX
" CONNECTED\n"));
251 Status
= UniataSataConnect(HwDeviceExtension
, lChannel
, pm_port
);
252 KdPrint2((PRINT_PREFIX
" Status %#x\n", Status
));
253 if(Status
!= IDE_STATUS_IDLE
) {
256 CheckDevice(HwDeviceExtension
, lChannel
, DeviceNumber
/*dev*/, FALSE
);
259 case UNIATA_SATA_EVENT_DETACH
:
260 KdPrint2((PRINT_PREFIX
" DISCONNECTED\n"));
261 UniataForgetDevice(deviceExtension
->chan
[lChannel
].lun
[DeviceNumber
]);
266 } // end UniataSataEvent()
272 IN ULONG io_port_ndx
,
273 IN ULONG pm_port
/* for port multipliers */
276 if(chan
&& (io_port_ndx
< IDX_MAX_REG
) &&
277 chan
->RegTranslation
[io_port_ndx
].Proc
) {
279 KdPrint3((PRINT_PREFIX
" UniataSataReadPort4 %#x[%d]\n", io_port_ndx
, pm_port
));
281 PHW_DEVICE_EXTENSION deviceExtension
= chan
->DeviceExtension
;
282 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
283 ULONG slotNumber
= deviceExtension
->slotNumber
;
284 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
285 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
292 if(deviceExtension
->HwFlags
& ICH5
) {
293 offs
= 0x50+chan
->lun
[p
]->SATA_lun_map
*0x10;
294 KdPrint3((PRINT_PREFIX
" ICH5 way, offs %#x\n", offs
));
295 switch(io_port_ndx
) {
296 case IDX_SATA_SStatus
:
299 case IDX_SATA_SError
:
302 case IDX_SATA_SControl
:
308 SetPciConfig4(0xa0, offs
);
309 GetPciConfig4(0xa4, offs
);
312 if(deviceExtension
->HwFlags
& ICH7
) {
313 offs
= 0x100+chan
->lun
[p
]->SATA_lun_map
*0x80;
314 KdPrint3((PRINT_PREFIX
" ICH7 way, offs %#x\n", offs
));
315 switch(io_port_ndx
) {
316 case IDX_SATA_SStatus
:
317 offs
+= IDX_AHCI_P_SStatus
;
319 case IDX_SATA_SError
:
320 offs
+= IDX_AHCI_P_SError
;
322 case IDX_SATA_SControl
:
323 offs
+= IDX_AHCI_P_SControl
;
328 return AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), offs
);
330 offs
= ((deviceExtension
->Channel
+chan
->lChannel
)*2+p
) * 0x100;
331 KdPrint3((PRINT_PREFIX
" def way, offs %#x\n", offs
));
332 switch(io_port_ndx
) {
333 case IDX_SATA_SStatus
:
336 case IDX_SATA_SControl
:
339 case IDX_SATA_SError
:
345 AtapiWritePort4(chan
, IDX_INDEXED_ADDR
, offs
);
346 return AtapiReadPort4(chan
, IDX_INDEXED_DATA
);
349 } // end switch(VendorID)
352 return AtapiReadPort4(chan
, io_port_ndx
);
353 } // end UniataSataReadPort4()
357 UniataSataWritePort4(
359 IN ULONG io_port_ndx
,
361 IN ULONG pm_port
/* for port multipliers */
364 if(chan
&& (io_port_ndx
< IDX_MAX_REG
) &&
365 chan
->RegTranslation
[io_port_ndx
].Proc
) {
367 KdPrint3((PRINT_PREFIX
" UniataSataWritePort4 %#x[%d]\n", io_port_ndx
, pm_port
));
369 PHW_DEVICE_EXTENSION deviceExtension
= chan
->DeviceExtension
;
370 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
371 ULONG slotNumber
= deviceExtension
->slotNumber
;
372 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
373 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
380 if(deviceExtension
->HwFlags
& ICH5
) {
381 offs
= 0x50+chan
->lun
[p
]->SATA_lun_map
*0x10;
382 KdPrint3((PRINT_PREFIX
" ICH5 way, offs %#x\n", offs
));
383 switch(io_port_ndx
) {
384 case IDX_SATA_SStatus
:
387 case IDX_SATA_SError
:
390 case IDX_SATA_SControl
:
396 SetPciConfig4(0xa0, offs
);
397 SetPciConfig4(0xa4, data
);
400 if(deviceExtension
->HwFlags
& ICH7
) {
401 offs
= 0x100+chan
->lun
[p
]->SATA_lun_map
*0x80;
402 KdPrint3((PRINT_PREFIX
" ICH7 way, offs %#x\n", offs
));
403 switch(io_port_ndx
) {
404 case IDX_SATA_SStatus
:
405 offs
+= IDX_AHCI_P_SStatus
;
407 case IDX_SATA_SError
:
408 offs
+= IDX_AHCI_P_SError
;
410 case IDX_SATA_SControl
:
411 offs
+= IDX_AHCI_P_SControl
;
416 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), offs
, data
);
419 offs
= ((deviceExtension
->Channel
+chan
->lChannel
)*2+p
) * 0x100;
420 KdPrint3((PRINT_PREFIX
" def way, offs %#x\n", offs
));
421 switch(io_port_ndx
) {
422 case IDX_SATA_SStatus
:
425 case IDX_SATA_SControl
:
428 case IDX_SATA_SError
:
434 AtapiWritePort4(chan
, IDX_INDEXED_ADDR
, offs
);
435 AtapiWritePort4(chan
, IDX_INDEXED_DATA
, data
);
438 } // end switch(VendorID)
441 AtapiWritePort4(chan
, io_port_ndx
, data
);
442 } // end UniataSataWritePort4()
448 IN ULONG DeviceNumber
,
453 if(chan
->DeviceExtension
->HwFlags
& UNIATA_AHCI
) {
454 return UniataAhciReadPM(chan
, DeviceNumber
, Reg
, result
);
457 } // end UniataSataReadPM()
463 IN ULONG DeviceNumber
,
468 if(chan
->DeviceExtension
->HwFlags
& UNIATA_AHCI
) {
469 return UniataAhciWritePM(chan
, DeviceNumber
, Reg
, value
);
471 return IDE_STATUS_WRONG
;
472 } // end UniataSataWritePM()
477 IN PVOID HwDeviceExtension
,
479 IN ULONG DeviceNumber
482 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
484 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
485 return UniataAhciSoftReset(HwDeviceExtension
, lChannel
, DeviceNumber
);
488 } // end UniataSataSoftReset()
491 UniataSataIdentifyPM(
500 PHW_LU_EXTENSION LunExt
;
502 KdPrint((PRINT_PREFIX
"UniataSataIdentifyPM:\n"));
506 /* get PM vendor & product data */
507 if(!UniataSataReadPM(chan
, AHCI_DEV_SEL_PM
, 0, &PM_DeviceId
)) {
508 KdPrint2((PRINT_PREFIX
" error getting PM vendor data\n"));
511 /* get PM revision data */
512 if(!UniataSataReadPM(chan
, AHCI_DEV_SEL_PM
, 1, &PM_RevId
)) {
513 KdPrint2((PRINT_PREFIX
" error getting PM revison data\n"));
516 /* get number of HW ports on the PM */
517 if(!UniataSataReadPM(chan
, AHCI_DEV_SEL_PM
, 2, &PM_Ports
)) {
518 KdPrint2((PRINT_PREFIX
" error getting PM port info\n"));
522 PM_Ports
&= 0x0000000f;
524 switch(PM_DeviceId
) {
526 /* This PM declares 6 ports, while only 5 of them are real.
527 * Port 5 is enclosure management bridge port, which has implementation
528 * problems, causing probe faults. Hide it for now. */
529 KdPrint2((PRINT_PREFIX
" SiI 3726 (rev=%#x) Port Multiplier with %d (5) ports\n",
530 PM_RevId
, PM_Ports
));
534 /* This PM declares 7 ports, while only 5 of them are real.
535 * Port 5 is some fake "Config Disk" with 640 sectors size,
536 * port 6 is enclosure management bridge port.
537 * Both fake ports has implementation problems, causing
538 * probe faults. Hide them for now. */
539 KdPrint2((PRINT_PREFIX
" SiI 4726 (rev=%#x) Port Multiplier with %d (5) ports\n",
540 PM_RevId
, PM_Ports
));
544 KdPrint2((PRINT_PREFIX
" Port Multiplier (id=%08x rev=%#x) with %d ports\n",
545 PM_DeviceId
, PM_RevId
, PM_Ports
));
550 for(i
=0; i
<PM_Ports
; i
++) {
552 LunExt
= chan
->lun
[i
];
554 KdPrint2((PRINT_PREFIX
" Port %d\n", i
));
555 if(UniataSataPhyEnable(chan
->DeviceExtension
, chan
->lChannel
, i
, UNIATA_SATA_RESET_ENABLE
) != IDE_STATUS_IDLE
) {
556 LunExt
->DeviceFlags
&= ~DFLAGS_DEVICE_PRESENT
;
560 * XXX: I have no idea how to properly wait for PMP port hardreset
561 * completion. Without this delay soft reset does not completes
564 AtapiStallExecution(1000000);
566 signature
= UniataSataSoftReset(chan
->DeviceExtension
, chan
->lChannel
, i
);
567 KdPrint2((PRINT_PREFIX
" signature %#x\n", signature
));
569 LunExt
->DeviceFlags
|= DFLAGS_DEVICE_PRESENT
;
570 chan
->PmLunMap
|= (1 << i
);
571 /* figure out whats there */
572 switch (signature
>> 16) {
574 LunExt
->DeviceFlags
&= ~DFLAGS_ATAPI_DEVICE
;
577 LunExt
->DeviceFlags
|= DFLAGS_ATAPI_DEVICE
;
583 } // end UniataSataIdentifyPM()
589 IN PHW_DEVICE_EXTENSION deviceExtension
595 KdPrint2((PRINT_PREFIX
596 " AHCI Base: %#x MemIo %d Proc %d\n",
597 deviceExtension
->BaseIoAHCI_0
.Addr
,
598 deviceExtension
->BaseIoAHCI_0
.MemIo
,
599 deviceExtension
->BaseIoAHCI_0
.Proc
));
601 for(j
=0; j
<=IDX_AHCI_VS
; j
+=sizeof(ULONG
)) {
602 xReg
= AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)&deviceExtension
->BaseIoAHCI_0
, j
);
603 KdPrint2((PRINT_PREFIX
604 " AHCI_%#x (%#x) = %#x\n",
606 (deviceExtension
->BaseIoAHCI_0
.Addr
+j
),
610 } // end UniataDumpAhciRegs()
615 UniataDumpAhciPortRegs(
622 KdPrint2((PRINT_PREFIX
623 " AHCI port %d Base: %#x MemIo %d Proc %d\n",
625 chan
->BaseIoAHCI_Port
.Addr
,
626 chan
->BaseIoAHCI_Port
.MemIo
,
627 chan
->BaseIoAHCI_Port
.Proc
));
629 for(j
=0; j
<=IDX_AHCI_P_SNTF
; j
+=sizeof(ULONG
)) {
630 xReg
= AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)&chan
->BaseIoAHCI_Port
, j
);
631 KdPrint2((PRINT_PREFIX
632 " AHCI%d_%#x (%#x) = %#x\n",
635 (chan
->BaseIoAHCI_Port
.Addr
+j
),
639 } // end UniataDumpAhciPortRegs()
646 IN PVOID HwDeviceExtension
649 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
654 ULONG_PTR BaseMemAddress
;
656 ULONG BaseMemAddress
;
663 BOOLEAN MemIo
= FALSE
;
665 KdPrint2((PRINT_PREFIX
" UniataAhciInit:\n"));
668 UniataDumpAhciRegs(deviceExtension
);
671 CAP2
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_CAP2
);
672 if(CAP2
& AHCI_CAP2_BOH
) {
673 BOHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_BOHC
);
674 KdPrint2((PRINT_PREFIX
" stage 1 BOHC %#x\n", BOHC
));
675 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_BOHC
,
676 BOHC
| AHCI_BOHC_OOS
);
677 for(i
=0; i
<50; i
++) {
678 AtapiStallExecution(500);
679 BOHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_BOHC
);
680 KdPrint2((PRINT_PREFIX
" BOHC %#x\n", BOHC
));
681 if(BOHC
& AHCI_BOHC_BB
) {
684 if(!(BOHC
& AHCI_BOHC_BOS
)) {
688 KdPrint2((PRINT_PREFIX
" stage 2 BOHC %#x\n", BOHC
));
689 if(BOHC
& AHCI_BOHC_BB
) {
690 for(i
=0; i
<2000; i
++) {
691 AtapiStallExecution(1000);
692 BOHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_BOHC
);
693 KdPrint2((PRINT_PREFIX
" BOHC %#x\n", BOHC
));
694 if(!(BOHC
& AHCI_BOHC_BOS
)) {
699 KdPrint2((PRINT_PREFIX
" final BOHC %#x\n", BOHC
));
702 /* disable AHCI interrupts, for MSI compatibility issue
703 see http://www.intel.com/Assets/PDF/specupdate/307014.pdf
704 26. AHCI Reset and MSI Request
707 KdPrint2((PRINT_PREFIX
" get GHC\n"));
708 /* enable AHCI mode */
709 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
710 if(!(GHC
& AHCI_GHC_AE
)) {
711 KdPrint2((PRINT_PREFIX
" enable AHCI mode, disable intr, GHC %#x\n", GHC
));
712 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_GHC
,
713 (GHC
| AHCI_GHC_AE
) & ~AHCI_GHC_IE
);
715 KdPrint2((PRINT_PREFIX
" disable intr, GHC %#x\n", GHC
));
716 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_GHC
,
719 AtapiStallExecution(100);
721 /* read GHC again and reset AHCI controller */
722 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
723 KdPrint2((PRINT_PREFIX
" reset AHCI controller, GHC %#x\n", GHC
));
724 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_GHC
,
727 for(i
=0; i
<1000; i
++) {
728 AtapiStallExecution(1000);
729 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
730 KdPrint2((PRINT_PREFIX
" AHCI GHC %#x\n", GHC
));
731 if(!(GHC
& AHCI_GHC_HR
)) {
735 if(GHC
& AHCI_GHC_HR
) {
736 KdPrint2((PRINT_PREFIX
" AHCI reset failed\n"));
740 /* re-enable AHCI mode */
741 /* Linux: Some controllers need AHCI_EN to be written multiple times.
742 * Try a few times before giving up.
744 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
746 if(!(GHC
& AHCI_GHC_AE
)) {
747 KdPrint2((PRINT_PREFIX
" re-enable AHCI mode, GHC %#x\n", GHC
));
748 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_GHC
,
750 AtapiStallExecution(1000);
751 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
756 KdPrint2((PRINT_PREFIX
" AHCI GHC %#x\n", GHC
));
757 if(!(GHC
& AHCI_GHC_AE
)) {
758 KdPrint2((PRINT_PREFIX
" Can't enable AHCI mode\n"));
762 deviceExtension
->AHCI_CAP
=
763 CAP
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_CAP
);
764 KdPrint2((PRINT_PREFIX
" AHCI CAP %#x\n", CAP
));
765 if(CAP
& AHCI_CAP_S64A
) {
766 KdPrint2((PRINT_PREFIX
" AHCI 64bit\n"));
767 deviceExtension
->Host64
= TRUE
;
769 KdPrint2((PRINT_PREFIX
" AHCI %d CMD slots\n", (CAP
& AHCI_CAP_NCS_MASK
) >> 8 ));
770 if(CAP
& AHCI_CAP_PMD
) {
771 KdPrint2((PRINT_PREFIX
" AHCI multi-block PIO\n"));
773 if(CAP
& AHCI_CAP_SAM
) {
774 KdPrint2((PRINT_PREFIX
" AHCI legasy SATA\n"));
777 /* get the number of HW channels */
778 PI
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_PI
);
779 deviceExtension
->AHCI_PI
= PI
;
780 KdPrint2((PRINT_PREFIX
" AHCI PI %#x\n", PI
));
781 KdPrint2((PRINT_PREFIX
" AHCI PI mask %#x\n", deviceExtension
->AHCI_PI_mask
));
782 deviceExtension
->AHCI_PI
= PI
= PI
& deviceExtension
->AHCI_PI_mask
;
783 KdPrint2((PRINT_PREFIX
" masked AHCI PI %#x\n", PI
));
785 CAP2
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_CAP2
);
786 if(CAP2
& AHCI_CAP2_BOH
) {
787 KdPrint2((PRINT_PREFIX
" retry BOHC\n"));
788 BOHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_BOHC
);
789 KdPrint2((PRINT_PREFIX
" BOHC %#x\n", BOHC
));
790 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_BOHC
,
791 BOHC
| AHCI_BOHC_OOS
);
793 /* clear interrupts */
794 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_IS
,
795 UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_IS
));
797 /* enable AHCI interrupts */
798 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_GHC
,
799 UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
) | AHCI_GHC_IE
);
801 BaseMemAddress
= deviceExtension
->BaseIoAHCI_0
.Addr
;
802 MemIo
= deviceExtension
->BaseIoAHCI_0
.MemIo
;
804 deviceExtension
->MaxTransferMode
= ATA_SA150
+(((CAP
& AHCI_CAP_ISS_MASK
) >> 20)-1);
805 KdPrint2((PRINT_PREFIX
" SATA Gen %d\n", ((CAP
& AHCI_CAP_ISS_MASK
) >> 20) ));
807 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
808 chan
= &deviceExtension
->chan
[c
];
809 offs
= sizeof(IDE_AHCI_REGISTERS
) + c
*sizeof(IDE_AHCI_PORT_REGISTERS
);
811 KdPrint2((PRINT_PREFIX
" chan %d, offs %#x\n", c
, offs
));
813 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
815 AtapiSetupLunPtrs(chan
, deviceExtension
, c
);
817 chan
->BaseIoAHCI_Port
= deviceExtension
->BaseIoAHCI_0
;
818 chan
->BaseIoAHCI_Port
.Addr
= BaseMemAddress
+ offs
;
820 chan
->RegTranslation
[IDX_IO1_i_Status
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, TFD
.STS
);
821 chan
->RegTranslation
[IDX_IO1_i_Status
].MemIo
= MemIo
;
822 chan
->RegTranslation
[IDX_IO2_AltStatus
] = chan
->RegTranslation
[IDX_IO1_i_Status
];
823 chan
->RegTranslation
[IDX_IO1_i_Error
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, TFD
.ERR
);
824 chan
->RegTranslation
[IDX_IO1_i_Error
].MemIo
= MemIo
;
825 chan
->RegTranslation
[IDX_IO1_i_CylinderLow
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, SIG
.LbaLow
);
826 chan
->RegTranslation
[IDX_IO1_i_CylinderLow
].MemIo
= MemIo
;
827 chan
->RegTranslation
[IDX_IO1_i_CylinderHigh
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, SIG
.LbaHigh
);
828 chan
->RegTranslation
[IDX_IO1_i_CylinderHigh
].MemIo
= MemIo
;
829 chan
->RegTranslation
[IDX_IO1_i_BlockCount
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, SIG
.SectorCount
);
830 chan
->RegTranslation
[IDX_IO1_i_BlockCount
].MemIo
= MemIo
;
832 UniataInitSyncBaseIO(chan
);
834 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, SSTS
);
835 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
836 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, SERR
);
837 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
838 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, SCTL
);
839 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
840 chan
->RegTranslation
[IDX_SATA_SActive
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, SACT
);
841 chan
->RegTranslation
[IDX_SATA_SActive
].MemIo
= MemIo
;
843 AtapiDmaAlloc(HwDeviceExtension
, NULL
, c
);
845 if(!UniataAhciChanImplemented(deviceExtension
, c
)) {
846 KdPrint2((PRINT_PREFIX
" chan %d not implemented\n", c
));
850 UniataAhciResume(chan
);
852 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
856 } // end UniataAhciInit()
860 UniAtaAhciValidateVersion(
861 IN PHW_DEVICE_EXTENSION deviceExtension
,
869 KdPrint((" wrong AHCI revision %#x\n", version
));
879 KdPrint2((PRINT_PREFIX
" Unknown AHCI revision\n"));
880 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"CheckAhciRevision", Strict
)) {
881 KdPrint((" AHCI revision excluded %#x\n", version
));
886 } // end UniAtaAhciValidateVersion()
891 IN PVOID HwDeviceExtension
,
892 IN PPCI_COMMON_CONFIG pciData
, // optional
893 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
896 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
897 //ULONG slotNumber = deviceExtension->slotNumber;
898 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
902 //ULONG PI_ex_mask=0;
910 ULONG NumberChannels
;
911 ULONG_PTR BaseMemAddress
;
912 BOOLEAN MemIo
= FALSE
;
913 BOOLEAN found
= FALSE
;
916 KdPrint2((PRINT_PREFIX
" UniataAhciDetect:\n"));
918 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"IgnoreAhci", 0)) {
919 KdPrint((" AHCI excluded\n"));
922 switch(deviceExtension
->DevID
) {
924 KdPrint2((PRINT_PREFIX
" Cavium uses BAR(0)\n"));
928 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
930 if(!BaseMemAddress
) {
931 KdPrint2((PRINT_PREFIX
" AHCI init failed - no IoRange\n"));
934 if((*ConfigInfo
->AccessRanges
)[BarId
].RangeInMemory
) {
935 KdPrint2((PRINT_PREFIX
"MemIo\n"));
938 deviceExtension
->BaseIoAHCI_0
.Addr
= BaseMemAddress
;
939 deviceExtension
->BaseIoAHCI_0
.MemIo
= MemIo
;
942 UniataDumpAhciRegs(deviceExtension
);
945 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
946 if(GHC
& AHCI_GHC_HR
) {
947 KdPrint2((PRINT_PREFIX
" AHCI in reset state\n"));
951 /* check AHCI mode. Save state and try enable */
953 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
954 KdPrint2((PRINT_PREFIX
" check AHCI mode, GHC %#x\n", GHC
));
956 version
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_VS
);
958 if(!(GHC
& AHCI_GHC_AE
)) {
959 KdPrint2((PRINT_PREFIX
" Non-AHCI GHC (!AE), check revision %#x\n", version
));
960 if(!UniAtaAhciValidateVersion(deviceExtension
, version
, FALSE
)) {
961 KdPrint2((PRINT_PREFIX
" Non-AHCI\n"));
964 KdPrint2((PRINT_PREFIX
" try enable\n"));
965 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_GHC
,
966 (GHC
| AHCI_GHC_AE
) & ~AHCI_GHC_IE
);
967 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
969 KdPrint2((PRINT_PREFIX
" re-check AHCI mode, GHC %#x\n", GHC
));
970 if(!(GHC
& AHCI_GHC_AE
)) {
971 KdPrint2((PRINT_PREFIX
" Non-AHCI GHC (!AE)\n"));
976 CAP
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_CAP
);
977 CAP2
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_CAP2
);
978 KdPrint2((PRINT_PREFIX
" AHCI CAP %#x, CAP2 %#x, ver %#x\n", CAP
, CAP2
, version
));
979 if(CAP
& AHCI_CAP_S64A
) {
980 KdPrint2((PRINT_PREFIX
" 64bit"));
981 //deviceExtension->Host64 = TRUE; // this is just DETECT, do not update anything
984 if(CAP2
& AHCI_CAP2_BOH
) {
985 BOHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_BOHC
);
986 KdPrint2((PRINT_PREFIX
" BOHC %#x", BOHC
));
989 if(CAP
& AHCI_CAP_NCQ
) {
990 KdPrint2((PRINT_PREFIX
" NCQ"));
992 if(CAP
& AHCI_CAP_SNTF
) {
993 KdPrint2((PRINT_PREFIX
" SNTF"));
995 if(CAP
& AHCI_CAP_CCC
) {
996 KdPrint2((PRINT_PREFIX
" CCC"));
998 KdPrint2((PRINT_PREFIX
"\n"));
1000 /* get the number of HW channels */
1002 /* CAP.NOP sometimes indicate the index of the last enabled
1003 * port, at other times, that of the last possible port, so
1004 * determining the maximum port number requires looking at
1005 * both CAP.NOP and PI.
1007 PI
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_PI
);
1008 deviceExtension
->AHCI_PI
= deviceExtension
->AHCI_PI_mask
= PI
;
1009 KdPrint2((PRINT_PREFIX
" AHCI PI %#x\n", PI
));
1011 for(i
=PI
, n
=0; i
; n
++, i
=i
>>1) {
1012 if(AtapiRegCheckDevValue(deviceExtension
, n
, DEVNUM_NOT_SPECIFIED
, L
"Exclude", 0)) {
1013 KdPrint2((PRINT_PREFIX
"Channel %d excluded\n", n
));
1014 deviceExtension
->AHCI_PI
&= ~((ULONG
)1 << n
);
1015 deviceExtension
->AHCI_PI_mask
&= ~((ULONG
)1 << n
);
1016 //PI_ex_mask |= ((ULONG)1 << n);
1019 deviceExtension
->AHCI_PI_mask
=
1020 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"PortMask", deviceExtension
->AHCI_PI_mask
);
1021 KdPrint2((PRINT_PREFIX
"Force PortMask %#x\n", deviceExtension
->AHCI_PI_mask
));
1023 for(i
=PI
, n
=0; i
; n
++, i
=i
>>1);
1025 max((CAP
& AHCI_CAP_NOP_MASK
)+1, n
);
1027 if(!PI
&& ((CAP
& AHCI_CAP_NOP_MASK
)+1)) {
1029 * The spec says that BIOS sets up bits corresponding to
1030 * available ports. On platforms where this information
1031 * is missing, the driver can define available ports on its own.
1033 KdPrint2((PRINT_PREFIX
"PI=0 -> Enable ports (mask) %#x\n", deviceExtension
->AHCI_PI_mask
));
1035 deviceExtension
->AHCI_PI
= ((ULONG
)1 << n
)-1;
1037 if(deviceExtension
->AHCI_PI_mask
) {
1038 // we have some forced port mask
1039 PI
= deviceExtension
->AHCI_PI_mask
;
1042 PI
= deviceExtension
->AHCI_PI
= (((ULONG
)1 << n
)-1);
1043 deviceExtension
->AHCI_PI_mask
= (((ULONG
)1 << n
)-1);
1045 KdPrint2((PRINT_PREFIX
"Enable ports final PI %#x\n", PI
));
1046 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_PI
, PI
);
1049 KdPrint2((PRINT_PREFIX
" CommandSlots %d\n", (CAP
& AHCI_CAP_NCS_MASK
)>>8 ));
1050 KdPrint2((PRINT_PREFIX
" Detected Channels %d / %d\n", NumberChannels
, n
));
1052 switch(deviceExtension
->DevID
) {
1054 KdPrint2((PRINT_PREFIX
" JMicron JMB361 -> 1\n"));
1058 KdPrint2((PRINT_PREFIX
" Marvell M88SE6111 -> 1\n"));
1062 KdPrint2((PRINT_PREFIX
" Marvell M88SE6121 -> 2\n"));
1063 NumberChannels
= min(NumberChannels
, 2);
1068 KdPrint2((PRINT_PREFIX
" Marvell M88SE614x/9123 -> 4\n"));
1069 NumberChannels
= min(NumberChannels
, 4);
1073 if(!NumberChannels
) {
1074 KdPrint2((PRINT_PREFIX
" Non-AHCI - NumberChannels=0\n"));
1078 KdPrint2((PRINT_PREFIX
" Adjusted Channels %d\n", NumberChannels
));
1081 v_Mj
= ((version
>> 20) & 0xf0) + ((version
>> 16) & 0x0f);
1082 v_Mn
= ((version
>> 4) & 0xf0) + (version
& 0x0f);
1084 KdPrint2((PRINT_PREFIX
" AHCI version %x.%02x controller with %d ports (mask %#x) detected\n",
1086 NumberChannels
, PI
));
1087 KdPrint((" AHCI SATA Gen %d\n", (((CAP
& AHCI_CAP_ISS_MASK
) >> 20)) ));
1090 if(CAP
& AHCI_CAP_SPM
) {
1091 KdPrint2((PRINT_PREFIX
" PM supported\n"));
1092 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"IgnoreAhciPM", 1 /* DEBUG */)) {
1093 KdPrint2((PRINT_PREFIX
"SATA/AHCI w/o PM, max luns 1\n"));
1094 deviceExtension
->NumberLuns
= 1;
1095 //chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
1097 KdPrint2((PRINT_PREFIX
"SATA/AHCI -> possible PM, max luns %d\n", SATA_MAX_PM_UNITS
));
1098 deviceExtension
->NumberLuns
= SATA_MAX_PM_UNITS
;
1099 //deviceExtension->NumberLuns = 1;
1102 KdPrint2((PRINT_PREFIX
" PM not supported -> 1 lun/chan\n"));
1103 deviceExtension
->NumberLuns
= 1;
1106 if(!UniAtaAhciValidateVersion(deviceExtension
, version
, TRUE
)) {
1110 deviceExtension
->HwFlags
|= UNIATA_SATA
| UNIATA_AHCI
;
1111 if(deviceExtension
->NumberChannels
< NumberChannels
) {
1112 deviceExtension
->NumberChannels
= NumberChannels
;
1114 deviceExtension
->DmaSegmentLength
= 0x3fffff+1; // 4MB
1115 deviceExtension
->DmaSegmentAlignmentMask
= -1; // no restrictions
1117 deviceExtension
->BusMaster
= DMA_MODE_AHCI
;
1118 deviceExtension
->MaxTransferMode
= max(deviceExtension
->MaxTransferMode
, ATA_SA150
+(((CAP
& AHCI_CAP_ISS_MASK
) >> 20)-1) );
1123 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_GHC
, GHC0
);
1124 KdPrint((" AHCI detect status %d\n", found
));
1127 } // end UniataAhciDetect()
1132 IN PVOID HwDeviceExtension
,
1134 IN ULONG DeviceNumber
1137 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1138 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1139 ULONG Channel
= deviceExtension
->Channel
+ lChannel
;
1143 SATA_SSTATUS_REG SStatus
;
1144 SATA_SERROR_REG SError
;
1145 //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
1148 KdPrint(("UniataAhciStatus(%d-%d):\n", lChannel
, Channel
));
1150 hIS
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_IS
);
1151 KdPrint((" hIS %#x\n", hIS
));
1152 hIS
&= (1 << Channel
);
1154 return INTERRUPT_REASON_IGNORE
;
1156 IS
.Reg
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_IS
);
1157 CI
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CI
);
1158 ACT
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_ACT
);
1159 SStatus
.Reg
= AtapiReadPort4(chan
, IDX_SATA_SStatus
);
1160 SError
.Reg
= AtapiReadPort4(chan
, IDX_SATA_SError
);
1162 /* clear interrupt(s) */
1163 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_IS
, hIS
);
1164 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IS
, IS
.Reg
);
1165 AtapiWritePort4(chan
, IDX_SATA_SError
, SError
.Reg
);
1167 KdPrint((" AHCI: is=%08x ss=%08x serror=%08x CI=%08x, ACT=%08x\n",
1168 IS
.Reg
, SStatus
.Reg
, SError
.Reg
, CI
, ACT
));
1170 /* do we have cold connect surprise */
1174 /* check for and handle connect events */
1176 UniataSataEvent(HwDeviceExtension
, lChannel
, UNIATA_SATA_EVENT_ATTACH
);
1179 UniataSataEvent(HwDeviceExtension
, lChannel
, UNIATA_SATA_EVENT_DETACH
);
1181 chan
->AhciCompleteCI
= (chan
->AhciPrevCI
^ CI
) & chan
->AhciPrevCI
; // only 1->0 states
1182 chan
->AhciPrevCI
= CI
;
1183 chan
->AhciLastSError
= SError
.Reg
;
1184 KdPrint((" AHCI: complete mask %#x\n", chan
->AhciCompleteCI
));
1185 chan
->AhciLastIS
= IS
.Reg
;
1186 if(CI
& (1 << tag
)) {
1188 UniataDumpAhciPortRegs(chan
);
1190 //deviceExtension->ExpectingInterrupt++; // will be updated in ISR on ReturnEnableInterrupts
1192 (ATA_AHCI_P_IX_OF
| ATA_AHCI_P_IX_INF
| ATA_AHCI_P_IX_IF
|
1193 ATA_AHCI_P_IX_HBD
| ATA_AHCI_P_IX_HBF
| ATA_AHCI_P_IX_TFE
)) {
1194 KdPrint((" AHCI: unexpected, error\n"));
1196 KdPrint((" AHCI: unexpected, incomplete command or error ?\n"));
1200 TFD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_TFD);
1201 KdPrint2((" TFD %#x\n", TFD));
1202 if(TFD & IDE_STATUS_BUSY) {
1203 KdPrint2((" Seems to be interrupt on error\n"));
1204 return INTERRUPT_REASON_OUR;
1207 return INTERRUPT_REASON_UNEXPECTED
;
1210 return INTERRUPT_REASON_OUR
;
1212 } // end UniataAhciStatus()
1216 UniataAhciSnapAtaRegs(
1217 IN PHW_CHANNEL chan
,
1218 IN ULONG DeviceNumber
,
1219 IN OUT PIDEREGS_EX regs
1224 regs
->bDriveHeadReg
= IDE_DRIVE_SELECT_1
;
1225 TFD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_TFD
);
1226 regs
->bCommandReg
= (UCHAR
)(TFD
& 0xff);
1227 regs
->bFeaturesReg
= (UCHAR
)((TFD
>> 8) & 0xff);
1229 SIG
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_SIG
);
1230 regs
->bSectorCountReg
= (UCHAR
)(SIG
& 0xff);
1231 regs
->bSectorNumberReg
= (UCHAR
)((SIG
>> 8) & 0xff);
1232 regs
->bCylLowReg
= (UCHAR
)((SIG
>> 16) & 0xff);
1233 regs
->bCylHighReg
= (UCHAR
)((SIG
>> 24) & 0xff);
1237 } // end UniataAhciSnapAtaRegs()
1241 UniataAhciSetupFIS_H2D(
1242 IN PHW_DEVICE_EXTENSION deviceExtension
,
1243 IN ULONG DeviceNumber
,
1255 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1257 KdPrint2((PRINT_PREFIX
" AHCI setup FIS %x, ch %d, dev %d\n", fis
, lChannel
, DeviceNumber
));
1259 plba
= (PUCHAR
)&lba
;
1261 RtlZeroMemory(fis
, 20);
1263 fis
[0] = AHCI_FIS_TYPE_ATA_H2D
; /* host to device */
1264 fis
[1] = 0x80 | ((UCHAR
)DeviceNumber
& 0x0f); /* command FIS (note PM goes here) */
1265 fis
[IDX_AHCI_o_DriveSelect
] = IDE_DRIVE_SELECT_1
|
1266 ((AtaCommandFlags
[command
] & (ATA_CMD_FLAG_LBAIOsupp
| ATA_CMD_FLAG_48
)) ? IDE_USE_LBA
: 0);
1267 fis
[IDX_AHCI_o_Control
] = IDE_DC_A_4BIT
;
1269 // IDE_COMMAND_ATAPI_IDENTIFY should be processed as regular ATA command,
1270 // the rest of ATAPI requests are processed via IDE_COMMAND_ATAPI_PACKET
1271 if(/*(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
1273 command
== IDE_COMMAND_ATAPI_PACKET
) {
1274 fis
[IDX_AHCI_o_Command
] = IDE_COMMAND_ATAPI_PACKET
;
1275 if(feature
& ATA_F_DMA
) {
1276 fis
[IDX_AHCI_o_Feature
] = (UCHAR
)(feature
& 0xff);
1278 fis
[IDX_AHCI_o_CylinderLow
] = (UCHAR
)(count
& 0xff);
1279 fis
[IDX_AHCI_o_CylinderHigh
] = (UCHAR
)(count
>>8) & 0xff;
1281 //fis[IDX_AHCI_o_Control] |= IDE_DC_A_4BIT;
1284 if(((AtaCommandFlags
[command
] & (ATA_CMD_FLAG_LBAIOsupp
|ATA_CMD_FLAG_FUA
)) == ATA_CMD_FLAG_LBAIOsupp
) &&
1285 CheckIfBadBlock(chan
->lun
[DeviceNumber
], lba
, count
)) {
1286 KdPrint3((PRINT_PREFIX
": artificial bad block, lba %#I64x count %#x\n", lba
, count
));
1290 need48
= UniAta_need_lba48(command
, lba
, count
,
1291 chan
->lun
[DeviceNumber
]->IdentifyData
.FeaturesSupport
.Address48
);
1293 /* translate command into 48bit version */
1295 if(AtaCommandFlags
[command
] & ATA_CMD_FLAG_48supp
) {
1296 command
= AtaCommands48
[command
];
1298 KdPrint2((PRINT_PREFIX
" unhandled LBA48 command\n"));
1303 fis
[IDX_AHCI_o_Command
] = command
;
1304 fis
[IDX_AHCI_o_Feature
] = (UCHAR
)feature
;
1306 fis
[IDX_AHCI_o_BlockNumber
] = plba
[0];
1307 fis
[IDX_AHCI_o_CylinderLow
] = plba
[1];
1308 fis
[IDX_AHCI_o_CylinderHigh
] = plba
[2];
1310 fis
[IDX_AHCI_o_BlockCount
] = (UCHAR
)count
& 0xff;
1314 fis
[IDX_AHCI_o_Control
] |= IDE_DC_USE_HOB
;
1316 fis
[IDX_AHCI_o_BlockNumberExp
] = plba
[3];
1317 fis
[IDX_AHCI_o_CylinderLowExp
] = plba
[4];
1318 fis
[IDX_AHCI_o_CylinderHighExp
] = plba
[5];
1320 fis
[IDX_AHCI_o_BlockCountExp
] = (UCHAR
)(count
>>8) & 0xff;
1322 fis
[IDX_AHCI_o_FeatureExp
] = (UCHAR
)(feature
>>8) & 0xff;
1324 chan
->ChannelCtrlFlags
|= CTRFLAGS_LBA48
;
1326 fis
[IDX_AHCI_o_DriveSelect
] |= /*IDE_DRIVE_1 |*/ (plba
[3] & 0x0f);
1327 chan
->ChannelCtrlFlags
&= ~CTRFLAGS_LBA48
;
1337 } // end UniataAhciSetupFIS_H2D()
1341 UniataAhciSetupFIS_H2D_Direct(
1342 IN PHW_DEVICE_EXTENSION deviceExtension
,
1343 IN ULONG DeviceNumber
,
1352 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1355 command
= regs
->bCommandReg
;
1357 KdPrint2((PRINT_PREFIX
" AHCI setup FIS Direct %x, ch %d, dev %d\n", fis
, lChannel
, DeviceNumber
));
1359 //plba = (PUCHAR)&lba;
1361 RtlZeroMemory(fis
, 20);
1363 fis
[0] = AHCI_FIS_TYPE_ATA_H2D
; /* host to device */
1364 fis
[1] = 0x80 | ((UCHAR
)DeviceNumber
& 0x0f); /* command FIS (note PM goes here) */
1365 fis
[IDX_AHCI_o_DriveSelect
] = IDE_DRIVE_SELECT_1
|
1366 ((AtaCommandFlags
[command
] & (ATA_CMD_FLAG_LBAIOsupp
| ATA_CMD_FLAG_48
)) ? IDE_USE_LBA
: 0);
1367 fis
[IDX_AHCI_o_Control
] = IDE_DC_A_4BIT
;
1369 // IDE_COMMAND_ATAPI_IDENTIFY should be processed as regular ATA command,
1370 // the rest of ATAPI requests are processed via IDE_COMMAND_ATAPI_PACKET
1371 if(/*(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
1373 command
== IDE_COMMAND_ATAPI_PACKET
) {
1374 /* fis[IDX_AHCI_o_Command] = IDE_COMMAND_ATAPI_PACKET;
1375 if(feature & ATA_F_DMA) {
1376 fis[IDX_AHCI_o_Feature] = (UCHAR)(feature & 0xff);
1378 fis[IDX_AHCI_o_CylinderLow] = (UCHAR)(count & 0xff);
1379 fis[IDX_AHCI_o_CylinderHigh] = (UCHAR)(count>>8) & 0xff;
1382 //fis[IDX_AHCI_o_Control] |= IDE_DC_A_4BIT;
1385 need48
= (regs
->bOpFlags
& ATA_FLAGS_48BIT_COMMAND
) &&
1386 chan
->lun
[DeviceNumber
]->IdentifyData
.FeaturesSupport
.Address48
;
1388 /* translate command into 48bit version */
1390 if(AtaCommandFlags
[command
] & ATA_CMD_FLAG_48supp
) {
1391 command
= AtaCommands48
[command
];
1393 KdPrint2((PRINT_PREFIX
" unhandled LBA48 command\n"));
1398 fis
[IDX_AHCI_o_Command
] = command
;
1399 fis
[IDX_AHCI_o_Feature
] = regs
->bFeaturesReg
;
1401 fis
[IDX_AHCI_o_BlockNumber
] = regs
->bSectorNumberReg
;
1402 fis
[IDX_AHCI_o_CylinderLow
] = regs
->bCylLowReg
;
1403 fis
[IDX_AHCI_o_CylinderHigh
] = regs
->bCylHighReg
;
1405 fis
[IDX_AHCI_o_BlockCount
] = regs
->bSectorCountReg
;
1409 fis
[IDX_AHCI_o_Control
] |= IDE_DC_USE_HOB
;
1411 fis
[IDX_AHCI_o_BlockNumberExp
] = regs
->bSectorNumberRegH
;
1412 fis
[IDX_AHCI_o_CylinderLowExp
] = regs
->bCylLowRegH
;
1413 fis
[IDX_AHCI_o_CylinderHighExp
] = regs
->bCylHighRegH
;
1415 fis
[IDX_AHCI_o_BlockCountExp
] = regs
->bSectorCountRegH
;
1417 fis
[IDX_AHCI_o_FeatureExp
] = regs
->bFeaturesRegH
;
1419 chan
->ChannelCtrlFlags
|= CTRFLAGS_LBA48
;
1421 //fis[IDX_AHCI_o_DriveSelect] |= /*IDE_DRIVE_1 |*/ (plba[3] & 0x0f);
1422 chan
->ChannelCtrlFlags
&= ~CTRFLAGS_LBA48
;
1424 fis
[IDX_AHCI_o_DriveSelect
] |= regs
->bDriveHeadReg
& 0x0f;
1430 } // end UniataAhciSetupFIS_H2D_Direct()
1434 UniataAhciWaitCommandReady(
1435 IN PHW_CHANNEL chan
,
1448 for (i
=0; i
<timeout
; i
++) {
1449 CI
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CI
);
1450 //ACT = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_ACT);
1451 if (!(( CI
>> tag
) & 0x01)) {
1454 IS
.Reg
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_IS
);
1455 //KdPrint((" IS %#x\n", IS.Reg));
1459 SError
= AtapiReadPort4(chan
, IDX_SATA_SError
);
1461 KdPrint((" AHCI: error %#x\n", SError
));
1465 AtapiStallExecution(200);
1467 KdPrint((" CI %#x\n", CI
));
1469 //SStatus.Reg = AtapiReadPort4(chan, IDX_SATA_SStatus);
1470 //SError.Reg = AtapiReadPort4(chan, IDX_SATA_SError);
1472 /* clear interrupt(s) */
1473 IS
.Reg
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_IS
);
1474 KdPrint((" IS %#x\n", IS
.Reg
));
1475 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IS
, IS
.Reg
);
1477 if (timeout
&& (i
>= timeout
)) {
1481 SError
= AtapiReadPort4(chan
, IDX_SATA_SError
);
1482 KdPrint((" AHCI: timeout, SError %#x\n", SError
));
1484 TFD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_TFD
);
1485 KdPrint2((" TFD %#x\n", TFD
));
1488 return IDE_STATUS_WRONG
;
1491 return IDE_STATUS_IDLE
;
1492 } // end UniataAhciWaitCommandReady()
1496 UniataAhciSendCommand(
1497 IN PVOID HwDeviceExtension
,
1499 IN ULONG DeviceNumber
,
1500 IN USHORT ahci_flags
,
1504 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1505 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1506 //ULONG Channel = deviceExtension->Channel + lChannel;
1509 //SATA_SSTATUS_REG SStatus;
1510 //SATA_SERROR_REG SError;
1511 //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
1515 PIDE_AHCI_CMD_LIST AHCI_CL
= &(chan
->AhciCtlBlock
->cmd_list
[tag
]);
1517 KdPrint(("UniataAhciSendCommand: lChan %d\n", chan
->lChannel
));
1519 AHCI_CL
->prd_length
= 0;
1520 //AHCI_CL->cmd_flags = (20 / sizeof(ULONG)) | ahci_flags | (DeviceNumber << 12);
1521 AHCI_CL
->cmd_flags
= UniAtaAhciAdjustIoFlags(0, ahci_flags
, 20, DeviceNumber
);
1523 AHCI_CL
->bytecount
= 0;
1524 AHCI_CL
->cmd_table_phys
= chan
->AHCI_CTL_PhAddr
+ FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK
, cmd
);
1525 if(AHCI_CL
->cmd_table_phys
& AHCI_CMD_ALIGNEMENT_MASK
) {
1526 KdPrint2((PRINT_PREFIX
" AHCI CMD address is not aligned (mask %#x)\n", (ULONG
)AHCI_CMD_ALIGNEMENT_MASK
));
1529 //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag);
1530 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CI
, 1 << tag
);
1532 return UniataAhciWaitCommandReady(chan
, timeout
);
1534 } // end UniataAhciSendCommand()
1538 UniataAhciSendPIOCommand(
1539 IN PVOID HwDeviceExtension
,
1541 IN ULONG DeviceNumber
,
1542 IN PSCSI_REQUEST_BLOCK Srb
,
1544 IN ULONG length
, /* bytes */
1547 IN USHORT bcount
, /* block count, just ATA register */
1549 IN USHORT ahci_flags
,
1550 IN ULONG wait_flags
,
1554 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1555 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1560 //PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
1561 PIDE_AHCI_CMD AHCI_CMD
= NULL
;
1563 //PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
1565 KdPrint2((PRINT_PREFIX
"UniataAhciSendPIOCommand: cntrlr %#x:%#x dev %#x, cmd %#x, lba %#I64x bcount %#x feature %#x, buff %#x, len %#x, WF %#x \n",
1566 deviceExtension
->DevIndex
, lChannel
, DeviceNumber
, command
, lba
, bcount
, feature
, data
, length
, wait_flags
));
1568 if(length
/DEV_BSIZE
!= bcount
) {
1569 KdPrint((" length/DEV_BSIZE != bcount\n"));
1573 //UniataDumpAhciPortRegs(chan);
1577 Srb
= BuildAhciInternalSrb(HwDeviceExtension
, DeviceNumber
, lChannel
, data
, length
);
1579 KdPrint((" !Srb\n"));
1580 return IDE_STATUS_WRONG
;
1582 //UniataAhciSetupCmdPtr(AtaReq); // must be called before DMA setup
1583 //should be already called on init
1585 AtaReq
= (PATA_REQ
)(Srb
->SrbExtension
);
1586 //KdPrint((" Srb %#x, AtaReq %#x\n", Srb, AtaReq));
1588 AHCI_CMD
= AtaReq
->ahci
.ahci_cmd_ptr
;
1590 fis_size
= UniataAhciSetupFIS_H2D(deviceExtension
, DeviceNumber
, lChannel
,
1591 &(AHCI_CMD
->cfis
[0]),
1599 KdPrint2(("!fis_size\n"));
1600 return IDE_STATUS_WRONG
;
1603 //KdPrint2(("UniAtaAhciAdjustIoFlags(command, ahci_flags, fis_size, DeviceNumber)\n"));
1604 ahci_flags
= UniAtaAhciAdjustIoFlags(command
, ahci_flags
, fis_size
, DeviceNumber
);
1605 KdPrint2(("ahci_flags %#x\n", ahci_flags
));
1608 if(ahci_flags
& ATA_AHCI_CMD_WRITE
) {
1609 AtaReq
->Flags
&= ~REQ_FLAG_READ
;
1610 Srb
->SrbFlags
|= SRB_FLAGS_DATA_OUT
;
1611 KdPrint((" assume OUT\n"));
1613 AtaReq
->Flags
|= REQ_FLAG_READ
;
1614 Srb
->SrbFlags
|= SRB_FLAGS_DATA_IN
;
1615 KdPrint((" assume IN\n"));
1617 if(!AtapiDmaSetup(HwDeviceExtension
,
1619 lChannel
, // logical channel,
1623 KdPrint2((" can't setup buffer\n"));
1624 return IDE_STATUS_WRONG
;
1628 AtaReq
->ahci
.io_cmd_flags
= ahci_flags
;
1631 //UniataDumpAhciPortRegs(chan);
1634 UniataAhciBeginTransaction(HwDeviceExtension
, lChannel
, DeviceNumber
, Srb
);
1637 //UniataDumpAhciPortRegs(chan);
1640 if(wait_flags
== ATA_IMMEDIATE
) {
1642 KdPrint2((" return imemdiately\n"));
1644 statusByte
= UniataAhciWaitCommandReady(chan
, timeout
);
1645 UniataAhciStatus(HwDeviceExtension
, lChannel
, DeviceNumber
);
1646 UniataAhciEndTransaction(HwDeviceExtension
, lChannel
, DeviceNumber
, Srb
);
1651 } // end UniataAhciSendPIOCommand()
1655 UniataAhciSendPIOCommandDirect(
1656 IN PVOID HwDeviceExtension
,
1658 IN ULONG DeviceNumber
,
1659 IN PSCSI_REQUEST_BLOCK Srb
,
1660 IN PIDEREGS_EX regs
,
1661 IN ULONG wait_flags
,
1665 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1666 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1671 //PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
1672 PIDE_AHCI_CMD AHCI_CMD
= NULL
;
1673 USHORT ahci_flags
=0;
1676 //PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
1678 KdPrint2((PRINT_PREFIX
"UniataAhciSendPIOCommand: cntrlr %#x:%#x dev %#x, buff %#x, len %#x, WF %#x \n",
1679 deviceExtension
->DevIndex
, lChannel
, DeviceNumber
, Srb
->DataBuffer
, Srb
->DataTransferLength
, wait_flags
));
1681 // if(Srb->DataTransferLength/DEV_BSIZE != bcount) {
1682 // KdPrint((" length/DEV_BSIZE != bcount\n"));
1686 //UniataDumpAhciPortRegs(chan);
1690 KdPrint((" !Srb\n"));
1691 return IDE_STATUS_WRONG
;
1692 //UniataAhciSetupCmdPtr(AtaReq); // must be called before DMA setup
1693 //should be already called on init
1695 AtaReq
= (PATA_REQ
)(Srb
->SrbExtension
);
1696 //KdPrint((" Srb %#x, AtaReq %#x\n", Srb, AtaReq));
1698 AHCI_CMD
= AtaReq
->ahci
.ahci_cmd_ptr
;
1700 KdPrint((" !AHCI_CMD\n"));
1701 return IDE_STATUS_WRONG
;
1704 if(Srb
->DataTransferLength
) {
1705 if(Srb
->SrbFlags
& SRB_FLAGS_DATA_OUT
) {
1706 ahci_flags
|= ATA_AHCI_CMD_WRITE
;
1707 AtaReq
->Flags
&= ~REQ_FLAG_READ
;
1709 AtaReq
->Flags
|= REQ_FLAG_READ
;
1713 fis_size
= UniataAhciSetupFIS_H2D_Direct(deviceExtension
, DeviceNumber
, lChannel
,
1714 &(AHCI_CMD
->cfis
[0]),
1718 KdPrint2(("!fis_size\n"));
1719 return IDE_STATUS_WRONG
;
1722 //KdPrint2(("UniAtaAhciAdjustIoFlags(command, ahci_flags, fis_size, DeviceNumber)\n"));
1723 ahci_flags
= UniAtaAhciAdjustIoFlags(regs
->bCommandReg
, ahci_flags
, fis_size
, DeviceNumber
);
1724 KdPrint2(("ahci_flags %#x\n", ahci_flags
));
1726 if(Srb
->DataTransferLength
) {
1727 if(!AtapiDmaSetup(HwDeviceExtension
,
1729 lChannel
, // logical channel,
1731 (PUCHAR
)(Srb
->DataBuffer
),
1732 Srb
->DataTransferLength
)) {
1733 KdPrint2((" can't setup buffer\n"));
1734 return IDE_STATUS_WRONG
;
1738 AtaReq
->ahci
.io_cmd_flags
= ahci_flags
;
1741 //UniataDumpAhciPortRegs(chan);
1744 UniataAhciBeginTransaction(HwDeviceExtension
, lChannel
, DeviceNumber
, Srb
);
1747 //UniataDumpAhciPortRegs(chan);
1750 if(wait_flags
== ATA_IMMEDIATE
) {
1752 KdPrint2((" return imemdiately\n"));
1754 statusByte
= UniataAhciWaitCommandReady(chan
, timeout
);
1755 UniataAhciStatus(HwDeviceExtension
, lChannel
, DeviceNumber
);
1756 UniataAhciEndTransaction(HwDeviceExtension
, lChannel
, DeviceNumber
, Srb
);
1761 } // end UniataAhciSendPIOCommandDirect()
1765 UniataAhciAbortOperation(
1769 /* kick controller into sane state */
1770 if(!UniataAhciStop(chan
)) {
1773 if(!UniataAhciStopFR(chan
)) {
1776 if(!UniataAhciCLO(chan
)) {
1779 UniataAhciStartFR(chan
);
1780 UniataAhciStart(chan
);
1783 } // end UniataAhciAbortOperation()
1787 UniataAhciSoftReset(
1788 IN PVOID HwDeviceExtension
,
1790 IN ULONG DeviceNumber
1793 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1794 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1795 //ULONG Channel = deviceExtension->Channel + lChannel;
1801 KdPrint(("UniataAhciSoftReset: lChan %d\n", chan
->lChannel
));
1803 PIDE_AHCI_CMD AHCI_CMD
= &(chan
->AhciCtlBlock
->cmd
);
1804 PUCHAR RCV_FIS
= &(chan
->AhciCtlBlock
->rcv_fis
.rfis
[0]);
1806 /* kick controller into sane state */
1807 if(!UniataAhciAbortOperation(chan
)) {
1808 KdPrint2((" abort failed\n"));
1812 /* pull reset active */
1813 RtlZeroMemory(AHCI_CMD
->cfis
, sizeof(AHCI_CMD
->cfis
));
1814 AHCI_CMD
->cfis
[0] = AHCI_FIS_TYPE_ATA_H2D
;
1815 AHCI_CMD
->cfis
[1] = (UCHAR
)DeviceNumber
& 0x0f;
1816 //AHCI_CMD->cfis[7] = IDE_USE_LBA | IDE_DRIVE_SELECT;
1817 AHCI_CMD
->cfis
[15] = (IDE_DC_A_4BIT
| IDE_DC_RESET_CONTROLLER
);
1819 if(UniataAhciSendCommand(HwDeviceExtension
, lChannel
, DeviceNumber
, ATA_AHCI_CMD_RESET
| ATA_AHCI_CMD_CLR_BUSY
, 100) == IDE_STATUS_WRONG
) {
1820 KdPrint2((" timeout\n"));
1823 AtapiStallExecution(50);
1825 /* pull reset inactive */
1826 RtlZeroMemory(AHCI_CMD
->cfis
, sizeof(AHCI_CMD
->cfis
));
1827 AHCI_CMD
->cfis
[0] = AHCI_FIS_TYPE_ATA_H2D
;
1828 AHCI_CMD
->cfis
[1] = (UCHAR
)DeviceNumber
& 0x0f;
1829 //AHCI_CMD->cfis[7] = IDE_USE_LBA | IDE_DRIVE_SELECT;
1830 AHCI_CMD
->cfis
[15] = (IDE_DC_A_4BIT
);
1831 if(UniataAhciSendCommand(HwDeviceExtension
, lChannel
, DeviceNumber
, 0, 3000) == IDE_STATUS_WRONG
) {
1832 KdPrint2((" timeout (2)\n"));
1836 UniataAhciWaitReady(chan
, 1);
1838 KdDump(RCV_FIS
, sizeof(chan
->AhciCtlBlock
->rcv_fis
.rfis
));
1840 if(deviceExtension
->HwFlags
& UNIATA_AHCI_ALT_SIG
) {
1842 signature
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_SIG
);
1843 KdPrint((" alt sig: %#x\n", signature
));
1847 return UniataAhciUlongFromRFIS(RCV_FIS
);
1849 } // end UniataAhciSoftReset()
1853 UniataAhciWaitReady(
1854 IN PHW_CHANNEL chan
,
1861 KdPrint2(("UniataAhciWaitReady: lChan %d\n", chan
->lChannel
));
1863 //base = (ULONGIO_PTR)(&deviceExtension->BaseIoAHCI_0 + offs);
1865 TFD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_TFD
);
1866 for(i
=0; i
<timeout
&& (TFD
&
1867 (IDE_STATUS_DRQ
| IDE_STATUS_BUSY
)); i
++) {
1868 AtapiStallExecution(1000);
1869 TFD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_TFD
);
1872 KdPrint2((" TFD %#x\n", TFD
));
1876 } // end UniataAhciWaitReady()
1880 UniataAhciHardReset(
1881 IN PVOID HwDeviceExtension
,
1883 OUT PULONG signature
1886 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1887 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1888 //ULONG Channel = deviceExtension->Channel + lChannel;
1892 KdPrint(("UniataAhciHardReset: lChan %d\n", chan
->lChannel
));
1894 (*signature
) = 0xffffffff;
1896 UniataAhciStop(chan
);
1897 if(UniataSataPhyEnable(HwDeviceExtension
, lChannel
, 0/* dev0*/, UNIATA_SATA_RESET_ENABLE
) == IDE_STATUS_WRONG
) {
1898 KdPrint((" no PHY\n"));
1899 return IDE_STATUS_WRONG
;
1902 /* Wait for clearing busy status. */
1903 TFD
= UniataAhciWaitReady(chan
, 15000);
1904 if(TFD
& (IDE_STATUS_DRQ
| IDE_STATUS_BUSY
)) {
1905 KdPrint((" busy: TFD %#x\n", TFD
));
1908 KdPrint((" TFD %#x\n", TFD
));
1911 UniataDumpAhciPortRegs(chan
);
1914 (*signature
) = UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_SIG
);
1915 KdPrint((" sig: %#x\n", *signature
));
1917 UniataAhciStart(chan
);
1921 } // end UniataAhciHardReset()
1926 IN PVOID HwDeviceExtension
,
1930 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1931 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1932 //ULONG Channel = deviceExtension->Channel + lChannel;
1933 //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
1938 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
1940 KdPrint(("UniataAhciReset: lChan %d\n", chan
->lChannel
));
1942 //base = (ULONGIO_PTR)(&deviceExtension->BaseIoAHCI_0 + offs);
1944 /* Disable port interrupts */
1945 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IE
, 0);
1947 if(UniataAhciHardReset(HwDeviceExtension
, lChannel
, &signature
)) {
1949 KdPrint((" No devices in all LUNs\n"));
1950 for (i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
1951 // Zero device fields to ensure that if earlier devices were found,
1952 // but not claimed, the fields are cleared.
1953 UniataForgetDevice(chan
->lun
[i
]);
1956 /* enable wanted port interrupts */
1957 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IE
,
1958 ATA_AHCI_P_IX_CPD
| ATA_AHCI_P_IX_PRC
| ATA_AHCI_P_IX_PC
);
1962 /* enable wanted port interrupts */
1963 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IE
,
1964 (ATA_AHCI_P_IX_CPD
| ATA_AHCI_P_IX_TFE
| ATA_AHCI_P_IX_HBF
|
1965 ATA_AHCI_P_IX_HBD
| ATA_AHCI_P_IX_IF
| ATA_AHCI_P_IX_OF
|
1966 ((/*ch->pm_level == */0) ? (ATA_AHCI_P_IX_PRC
| ATA_AHCI_P_IX_PC
) : 0) |
1967 ATA_AHCI_P_IX_DP
| ATA_AHCI_P_IX_UF
| ATA_AHCI_P_IX_SDB
|
1968 ATA_AHCI_P_IX_DS
| ATA_AHCI_P_IX_PS
| ATA_AHCI_P_IX_DHR
) );
1971 * Only probe for PortMultiplier if HW has support.
1972 * Ignore Marvell, which is not working,
1974 CAP
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_CAP
);
1975 if ((CAP
& AHCI_CAP_SPM
) &&
1976 (VendorID
!= ATA_MARVELL_ID
)) {
1977 KdPrint((" check PM\n"));
1978 signature
= UniataAhciSoftReset(HwDeviceExtension
, lChannel
, AHCI_DEV_SEL_PM
);
1979 /* Workaround for some ATI chips, failing to soft-reset
1980 * when port multiplicator supported, but absent.
1981 * XXX: We can also check PxIS.IPMS==1 here to be sure. */
1982 if (signature
== 0xffffffff) {
1983 KdPrint((" re-check PM\n"));
1984 signature
= UniataAhciSoftReset(HwDeviceExtension
, lChannel
, 0);
1987 signature
= UniataAhciSoftReset(HwDeviceExtension
, lChannel
, 0);
1990 KdPrint((" signature %#x\n", signature
));
1991 chan
->lun
[0]->DeviceFlags
&= ~(DFLAGS_ATAPI_DEVICE
| DFLAGS_DEVICE_PRESENT
| CTRFLAGS_AHCI_PM
);
1992 switch (signature
>> 16) {
1994 KdPrint((" ATA dev\n"));
1995 chan
->lun
[0]->DeviceFlags
|= DFLAGS_DEVICE_PRESENT
;
2000 if(deviceExtension
->NumberLuns
> 1) {
2001 chan
->ChannelCtrlFlags
|= CTRFLAGS_AHCI_PM
;
2002 UniataSataIdentifyPM(chan
);
2004 KdPrint((" no PM supported (1 lun/chan)\n"));
2008 KdPrint((" ATAPI dev\n"));
2009 chan
->lun
[0]->DeviceFlags
|= (DFLAGS_ATAPI_DEVICE
| DFLAGS_DEVICE_PRESENT
);
2012 default: /* SOS XXX */
2013 KdPrint((" default to ATA ???\n"));
2014 chan
->lun
[0]->DeviceFlags
|= DFLAGS_DEVICE_PRESENT
;
2020 } // end UniataAhciReset()
2030 KdPrint2(("UniataAhciStartFR: lChan %d\n", chan
->lChannel
));
2032 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2033 KdPrint2((" CMD %#x\n", CMD
));
2034 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, CMD
| ATA_AHCI_P_CMD_FRE
);
2035 UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
); /* flush */
2038 } // end UniataAhciStartFR()
2049 KdPrint2(("UniataAhciStopFR: lChan %d\n", chan
->lChannel
));
2051 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2052 KdPrint2((" CMD %#x\n", CMD
));
2053 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, CMD
& ~ATA_AHCI_P_CMD_FRE
);
2055 for(i
=0; i
<1000; i
++) {
2056 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2057 if(!(CMD
& ATA_AHCI_P_CMD_FR
)) {
2058 KdPrint2((" final CMD %#x\n", CMD
));
2061 AtapiStallExecution(1000);
2063 KdPrint2((" CMD %#x\n", CMD
));
2064 KdPrint((" SError %#x\n", AtapiReadPort4(chan
, IDX_SATA_SError
)));
2065 KdPrint2(("UniataAhciStopFR: timeout\n"));
2067 } // end UniataAhciStopFR()
2076 SATA_SERROR_REG SError
;
2078 KdPrint2(("UniataAhciStart: lChan %d\n", chan
->lChannel
));
2080 /* clear SATA error register */
2081 SError
.Reg
= AtapiReadPort4(chan
, IDX_SATA_SError
);
2083 /* clear any interrupts pending on this channel */
2084 IS
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_IS
);
2085 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IS
, IS
);
2087 KdPrint2((" SError %#x, IS %#x\n", SError
.Reg
, IS
));
2089 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2090 KdPrint2((" CMD %#x\n", CMD
));
2091 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
,
2094 ((chan
->ChannelCtrlFlags
& CTRFLAGS_AHCI_PM
) ? ATA_AHCI_P_CMD_PMA
: 0));
2095 UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
); /* flush */
2098 } // end UniataAhciStart()
2106 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2107 //PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
2109 //SATA_SERROR_REG SError;
2112 KdPrint2(("UniataAhciCLO: lChan %d\n", chan
->lChannel
));
2114 /* issue Command List Override if supported */
2115 //CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
2116 CAP
= chan
->DeviceExtension
->AHCI_CAP
;
2117 if(!(CAP
& AHCI_CAP_SCLO
)) {
2120 KdPrint2((" send CLO\n"));
2121 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2122 CMD
|= ATA_AHCI_P_CMD_CLO
;
2123 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, CMD
);
2125 for(i
=0; i
<1000; i
++) {
2126 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2127 if(!(CMD
& ATA_AHCI_P_CMD_CLO
)) {
2128 KdPrint2((" final CMD %#x\n", CMD
));
2131 AtapiStallExecution(1000);
2133 KdPrint2((" CMD %#x\n", CMD
));
2134 KdPrint2(("UniataAhciCLO: timeout\n"));
2136 } // end UniataAhciCLO()
2145 //SATA_SERROR_REG SError;
2148 KdPrint2(("UniataAhciStop: lChan %d\n", chan
->lChannel
));
2150 /* issue Command List Override if supported */
2151 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2152 CMD
&= ~ATA_AHCI_P_CMD_ST
;
2153 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, CMD
);
2155 for(i
=0; i
<1000; i
++) {
2156 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2157 if(!(CMD
& ATA_AHCI_P_CMD_CR
)) {
2158 KdPrint2((" final CMD %#x\n", CMD
));
2161 AtapiStallExecution(1000);
2163 KdPrint2((" CMD %#x\n", CMD
));
2164 KdPrint((" SError %#x\n", AtapiReadPort4(chan
, IDX_SATA_SError
)));
2165 KdPrint2(("UniataAhciStop: timeout\n"));
2167 } // end UniataAhciStop()
2171 UniataAhciBeginTransaction(
2172 IN PVOID HwDeviceExtension
,
2174 IN ULONG DeviceNumber
,
2175 IN PSCSI_REQUEST_BLOCK Srb
2178 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2179 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
2180 //ULONG Channel = deviceExtension->Channel + lChannel;
2184 PATA_REQ AtaReq
= (PATA_REQ
)(Srb
->SrbExtension
);
2185 //SATA_SSTATUS_REG SStatus;
2186 //SATA_SERROR_REG SError;
2187 //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
2192 PIDE_AHCI_CMD_LIST AHCI_CL
= &(chan
->AhciCtlBlock
->cmd_list
[tag
]);
2194 KdPrint2(("UniataAhciBeginTransaction: lChan %d, AtaReq %#x\n", chan
->lChannel
, AtaReq
));
2196 if(Srb
->DataTransferLength
&& (!AtaReq
->dma_entries
|| AtaReq
->dma_entries
>= (USHORT
)0xffff)) {
2197 KdPrint2(("UniataAhciBeginTransaction wrong DMA tab len %x\n", AtaReq
->dma_entries
));
2201 AHCI_CL
->prd_length
= (USHORT
)(AtaReq
->dma_entries
);
2202 AHCI_CL
->cmd_flags
= AtaReq
->ahci
.io_cmd_flags
;
2203 AHCI_CL
->bytecount
= 0;
2204 if(AtaReq
->ahci
.ahci_base64
) {
2205 KdPrint2((PRINT_PREFIX
" AHCI AtaReq CMD %#x (ph %#x)\n", AtaReq
->ahci
.ahci_cmd_ptr
, (ULONG
)(AtaReq
->ahci
.ahci_base64
)));
2206 AHCI_CL
->cmd_table_phys
= AtaReq
->ahci
.ahci_base64
;
2208 if(AtaReq
->ahci
.ahci_cmd_ptr
) {
2209 KdPrint2((PRINT_PREFIX
" AHCI AtaReq->Chan CMD %#x (ph %#x) -> %#x (ph %#x)\n",
2210 AtaReq
->ahci
.ahci_cmd_ptr
, (ULONG
)(AtaReq
->ahci
.ahci_base64
),
2211 &(chan
->AhciCtlBlock
->cmd
), chan
->AHCI_CTL_PhAddr
+ FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK
, cmd
) ));
2212 RtlCopyMemory(&(chan
->AhciCtlBlock
->cmd
), AtaReq
->ahci
.ahci_cmd_ptr
,
2213 FIELD_OFFSET(IDE_AHCI_CMD
, prd_tab
)+AHCI_CL
->prd_length
*sizeof(IDE_AHCI_PRD_ENTRY
));
2214 AHCI_CL
->cmd_table_phys
= chan
->AHCI_CTL_PhAddr
+ FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK
, cmd
);
2216 KdPrint2((PRINT_PREFIX
" no AHCI CMD\n"));
2217 //AHCI_CL->cmd_table_phys = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, cmd);
2220 if(AHCI_CL
->cmd_table_phys
& AHCI_CMD_ALIGNEMENT_MASK
) {
2221 KdPrint2((PRINT_PREFIX
" AHCI CMD address is not aligned (mask %#x)\n", (ULONG
)AHCI_CMD_ALIGNEMENT_MASK
));
2226 KdPrint2((" prd_length %#x, flags %#x, base %I64x\n", AHCI_CL
->prd_length
, AHCI_CL
->cmd_flags
,
2227 AHCI_CL
->cmd_table_phys
));
2230 CMD0
= CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2231 KdPrint2((" CMD %#x\n", CMD
));
2232 // switch controller to ATAPI mode for ATA_PACKET commands only
2233 if(ATAPI_DEVICE(chan
, DeviceNumber
) &&
2234 AtaReq
->ahci
.ahci_cmd_ptr
->cfis
[2] == IDE_COMMAND_ATAPI_PACKET
) {
2235 KdPrint2((" ATAPI\n"));
2236 CMD
|= ATA_AHCI_P_CMD_ATAPI
;
2237 KdDump(&(AtaReq
->ahci
.ahci_cmd_ptr
->acmd
), 16);
2239 CMD
&= ~ATA_AHCI_P_CMD_ATAPI
;
2242 KdPrint2((" send CMD %#x, entries %#x\n", CMD
, AHCI_CL
->prd_length
));
2243 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, CMD
);
2244 CMD0
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
); /* flush */
2247 /* issue command to controller */
2248 //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag); // Used for NCQ
2249 KdPrint2((" Set CI\n"));
2250 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CI
, 0x01 << tag
);
2251 chan
->AhciPrevCI
|= 0x01 << tag
;
2254 CMD
|= ATA_AHCI_P_CMD_ST
|
2255 ((chan
->ChannelCtrlFlags
& CTRFLAGS_AHCI_PM
) ? ATA_AHCI_P_CMD_PMA
: 0);
2257 KdPrint2((" Send CMD START (%#x != %#x)\n", CMD
, CMD0
));
2258 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, CMD
);
2259 CMD0
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
); /* flush */
2261 KdPrint2((" No CMD START, already active\n"));
2264 if(!ATAPI_DEVICE(chan
, DeviceNumber
)) {
2265 // TODO: check if we send ATAPI_RESET and wait for ready of so.
2266 if(AtaReq
->ahci
.ahci_cmd_ptr
->cfis
[2] == IDE_COMMAND_ATAPI_RESET
) {
2270 for(i
=0; i
<1000000; i
++) {
2271 TFD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_TFD
);
2272 if(!(TFD
& IDE_STATUS_BUSY
)) {
2276 if(TFD
& IDE_STATUS_BUSY
) {
2277 KdPrint2((" timeout\n"));
2279 if(TFD
& IDE_STATUS_ERROR
) {
2280 KdPrint2((" ERROR %#x\n", (UCHAR
)(TFD
>> 8)));
2282 AtaReq
->ahci
.in_status
= TFD
;
2284 return IDE_STATUS_SUCCESS
;
2288 return IDE_STATUS_IDLE
;
2290 } // end UniataAhciBeginTransaction()
2294 UniataAhciEndTransaction(
2295 IN PVOID HwDeviceExtension
,
2297 IN ULONG DeviceNumber
,
2298 IN PSCSI_REQUEST_BLOCK Srb
2301 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2302 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
2303 //ULONG Channel = deviceExtension->Channel + lChannel;
2306 PATA_REQ AtaReq
= (PATA_REQ
)(Srb
->SrbExtension
);
2308 PUCHAR RCV_FIS
= &(chan
->AhciCtlBlock
->rcv_fis
.rfis
[0]);
2311 PIDE_AHCI_CMD_LIST AHCI_CL
= &(chan
->AhciCtlBlock
->cmd_list
[tag
]);
2312 //PHW_LU_EXTENSION LunExt;
2314 KdPrint2(("UniataAhciEndTransaction: lChan %d\n", chan
->lChannel
));
2316 //LunExt = chan->lun[DeviceNumber];
2318 TFD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_TFD
);
2319 KdPrint2((" TFD %#x\n", TFD
));
2321 if(TFD
& IDE_STATUS_ERROR
) {
2322 AtaReq
->ahci
.in_error
= (UCHAR
)(TFD
>> 8);
2323 KdPrint2((" ERROR %#x\n", AtaReq
->ahci
.in_error
));
2325 AtaReq
->ahci
.in_error
= 0;
2327 AtaReq
->ahci
.in_status
= TFD
;
2329 //if (request->flags & ATA_R_CONTROL) {
2331 AtaReq
->ahci
.in_bcount
= (ULONG
)(RCV_FIS
[12]) | ((ULONG
)(RCV_FIS
[13]) << 8);
2332 AtaReq
->ahci
.in_lba
= (ULONG
)(RCV_FIS
[4]) | ((ULONGLONG
)(RCV_FIS
[5]) << 8) |
2333 ((ULONGLONG
)(RCV_FIS
[6]) << 16);
2334 if(chan
->ChannelCtrlFlags
& CTRFLAGS_LBA48
) {
2335 AtaReq
->ahci
.in_lba
|= ((ULONGLONG
)(RCV_FIS
[8]) << 24) |
2336 ((ULONGLONG
)(RCV_FIS
[9]) << 32) |
2337 ((ULONGLONG
)(RCV_FIS
[10]) << 40);
2339 AtaReq
->ahci
.in_lba
|= ((ULONGLONG
)(RCV_FIS
[8]) << 24) |
2340 ((ULONGLONG
)(RCV_FIS
[9]) << 32) |
2341 ((ULONGLONG
)(RCV_FIS
[7] & 0x0f) << 24);
2343 AtaReq
->WordsTransfered
= AHCI_CL
->bytecount
/2;
2346 if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
2347 KdPrint2(("RCV:\n"));
2348 KdDump(RCV_FIS, 24);
2349 KdPrint2(("PIO:\n"));
2350 KdDump(&(chan->AhciCtlBlock->rcv_fis.psfis[0]), 24);
2352 KdPrint2(("len: %d vs %d\n", AHCI_CL->bytecount, (ULONG)RCV_FIS[5] | ((ULONG)RCV_FIS[6] << 8) ));
2353 if(!AHCI_CL->bytecount) {
2354 AtaReq->WordsTransfered = ((ULONG)RCV_FIS[5] | ((ULONG)RCV_FIS[6] << 8)) / 2;
2358 ACT
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_ACT
);
2359 CI
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CI
);
2360 if(CI
& (1 << tag
)) {
2362 KdPrint2((" Incomplete command, CI %#x, ACT %#x\n", CI
, ACT
));
2363 KdPrint2((" FIS status %#x, error %#x\n", RCV_FIS
[2], RCV_FIS
[3]));
2366 UniataDumpAhciPortRegs(chan
);
2368 if(!UniataAhciAbortOperation(chan
)) {
2369 KdPrint2((" Abort failed, need RESET\n"));
2372 UniataDumpAhciPortRegs(chan
);
2374 chan
->AhciPrevCI
= CI
& ~((ULONG
)1 << tag
);
2375 if(chan
->AhciPrevCI
) {
2376 KdPrint2((" Need command list restart, CI %#x\n", chan
->AhciPrevCI
));
2379 chan
->AhciPrevCI
&= ~((ULONG
)1 << tag
);
2380 RtlZeroMemory(AHCI_CL
, sizeof(IDE_AHCI_CMD_LIST
));
2386 } // end UniataAhciEndTransaction()
2396 KdPrint2(("UniataAhciResume: lChan %d\n", chan
->lChannel
));
2399 //UniataDumpAhciPortRegs(chan);
2402 /* Disable port interrupts */
2403 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IE
, 0);
2405 /* setup work areas */
2406 base
= chan
->AHCI_CTL_PhAddr
;
2408 KdPrint2((PRINT_PREFIX
" AHCI buffer allocation failed\n"));
2411 KdPrint2((PRINT_PREFIX
" AHCI CLB setup\n"));
2412 if(base
& AHCI_CLB_ALIGNEMENT_MASK
) {
2413 KdPrint2((PRINT_PREFIX
" AHCI CLB address is not aligned (mask %#x)\n", (ULONG
)AHCI_FIS_ALIGNEMENT_MASK
));
2415 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CLB
,
2416 (ULONG
)(base
& 0xffffffff));
2417 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CLB
+ 4,
2418 (ULONG
)((base
>> 32) & 0xffffffff));
2420 KdPrint2((PRINT_PREFIX
" AHCI RCV FIS setup\n"));
2421 base
= chan
->AHCI_CTL_PhAddr
+ FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK
, rcv_fis
);
2422 if(base
& AHCI_FIS_ALIGNEMENT_MASK
) {
2423 KdPrint2((PRINT_PREFIX
" AHCI FIS address is not aligned (mask %#x)\n", (ULONG
)AHCI_FIS_ALIGNEMENT_MASK
));
2425 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_FB
,
2426 (ULONG
)(base
& 0xffffffff));
2427 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_FB
+ 4,
2428 (ULONG
)((base
>> 32) & 0xffffffff));
2430 /* activate the channel and power/spin up device */
2431 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
,
2432 (ATA_AHCI_P_CMD_ACTIVE
| ATA_AHCI_P_CMD_POD
| ATA_AHCI_P_CMD_SUD
|
2433 (((chan
->ChannelCtrlFlags
& CTRFLAGS_AHCI_PM
)) ? ATA_AHCI_P_CMD_ALPE
: 0) |
2434 (((chan
->ChannelCtrlFlags
& CTRFLAGS_AHCI_PM2
)) ? ATA_AHCI_P_CMD_ASP
: 0 ))
2436 UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
); /* flush */
2439 //UniataDumpAhciPortRegs(chan);
2442 UniataAhciStartFR(chan
);
2443 UniataAhciStart(chan
);
2446 UniataDumpAhciPortRegs(chan
);
2450 } // end UniataAhciResume()
2460 SATA_SCONTROL_REG SControl
;
2462 KdPrint2(("UniataAhciSuspend:\n"));
2464 /* Disable port interrupts */
2465 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IE
, 0);
2467 /* Reset command register. */
2468 UniataAhciStop(chan
);
2469 UniataAhciStopFR(chan
);
2470 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, 0);
2471 UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
); /* flush */
2473 /* Allow everything including partial and slumber modes. */
2474 UniataSataWritePort4(chan
, IDX_SATA_SControl
, 0, 0);
2476 /* Request slumber mode transition and give some time to get there. */
2477 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, ATA_AHCI_P_CMD_SLUMBER
);
2478 AtapiStallExecution(100);
2482 SControl
.DET
= SStatus_DET_Offline
;
2483 UniataSataWritePort4(chan
, IDX_SATA_SControl
, SControl
.Reg
, 0);
2486 } // end UniataAhciSuspend()
2492 IN PHW_CHANNEL chan
,
2493 IN ULONG DeviceNumber
,
2498 //ULONG Channel = deviceExtension->Channel + lChannel;
2503 PIDE_AHCI_CMD AHCI_CMD
= &(chan
->AhciCtlBlock
->cmd
);
2504 PUCHAR RCV_FIS
= &(chan
->AhciCtlBlock
->rcv_fis
.rfis
[0]);
2506 KdPrint(("UniataAhciReadPM: lChan %d [%#x]\n", chan
->lChannel
, DeviceNumber
));
2508 if(DeviceNumber
== DEVNUM_NOT_SPECIFIED
) {
2509 (*result
) = UniataSataReadPort4(chan
, Reg
, 0);
2512 if(DeviceNumber
< AHCI_DEV_SEL_PM
) {
2514 case IDX_SATA_SStatus
:
2516 case IDX_SATA_SError
:
2518 case IDX_SATA_SControl
:
2525 RtlZeroMemory(AHCI_CMD
->cfis
, sizeof(AHCI_CMD
->cfis
));
2526 AHCI_CMD
->cfis
[0] = AHCI_FIS_TYPE_ATA_H2D
;
2527 AHCI_CMD
->cfis
[1] = AHCI_FIS_COMM_PM
;
2528 AHCI_CMD
->cfis
[2] = IDE_COMMAND_READ_PM
;
2529 AHCI_CMD
->cfis
[3] = (UCHAR
)Reg
;
2530 AHCI_CMD
->cfis
[7] = (UCHAR
)(IDE_USE_LBA
| DeviceNumber
);
2531 AHCI_CMD
->cfis
[15] = IDE_DC_A_4BIT
;
2533 if(UniataAhciSendCommand(chan
->DeviceExtension
, chan
->lChannel
, DeviceNumber
, 0, 10) == IDE_STATUS_WRONG
) {
2534 KdPrint2((" PM read failed\n"));
2538 KdDump(RCV_FIS
, sizeof(chan
->AhciCtlBlock
->rcv_fis
.rfis
));
2540 (*result
) = UniataAhciUlongFromRFIS(RCV_FIS
);
2543 } // end UniataAhciReadPM()
2548 IN PHW_CHANNEL chan
,
2549 IN ULONG DeviceNumber
,
2554 //ULONG Channel = deviceExtension->Channel + lChannel;
2560 PIDE_AHCI_CMD AHCI_CMD
= &(chan
->AhciCtlBlock
->cmd
);
2561 //PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
2563 KdPrint(("UniataAhciWritePM: lChan %d [%#x] %#x\n", chan
->lChannel
, DeviceNumber
, value
));
2565 if(DeviceNumber
== DEVNUM_NOT_SPECIFIED
) {
2566 UniataSataWritePort4(chan
, Reg
, value
, 0);
2569 if(DeviceNumber
< AHCI_DEV_SEL_PM
) {
2571 case IDX_SATA_SStatus
:
2573 case IDX_SATA_SError
:
2575 case IDX_SATA_SControl
:
2578 return IDE_STATUS_WRONG
;
2582 RtlZeroMemory(AHCI_CMD
->cfis
, sizeof(AHCI_CMD
->cfis
));
2583 AHCI_CMD
->cfis
[0] = AHCI_FIS_TYPE_ATA_H2D
;
2584 AHCI_CMD
->cfis
[1] = AHCI_FIS_COMM_PM
;
2585 AHCI_CMD
->cfis
[2] = IDE_COMMAND_WRITE_PM
;
2586 AHCI_CMD
->cfis
[3] = (UCHAR
)Reg
;
2587 AHCI_CMD
->cfis
[7] = (UCHAR
)(IDE_USE_LBA
| DeviceNumber
);
2589 AHCI_CMD
->cfis
[12] = (UCHAR
)(value
& 0xff);
2590 AHCI_CMD
->cfis
[4] = (UCHAR
)((value
>> 8) & 0xff);
2591 AHCI_CMD
->cfis
[5] = (UCHAR
)((value
>> 16) & 0xff);
2592 AHCI_CMD
->cfis
[6] = (UCHAR
)((value
>> 24) & 0xff);
2594 AHCI_CMD
->cfis
[15] = IDE_DC_A_4BIT
;
2596 if(UniataAhciSendCommand(chan
->DeviceExtension
, chan
->lChannel
, DeviceNumber
, 0, 100) == IDE_STATUS_WRONG
) {
2597 KdPrint2((" PM write failed\n"));
2598 return IDE_STATUS_WRONG
;
2601 TFD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_TFD
);
2603 if(TFD
& IDE_STATUS_ERROR
) {
2604 KdPrint2((" ERROR %#x\n", (UCHAR
)(TFD
>> 8)));
2606 return (UCHAR
)(TFD
>> 8);
2608 } // end UniataAhciWritePM()
2611 UniataAhciSetupCmdPtr(
2612 IN OUT PATA_REQ AtaReq
2617 ULONGLONG prd_base64
;
2621 ULONGLONG prd_base64_0
;
2627 prd_base64_0
= prd_base64
= 0;
2628 prd_base
= (PUCHAR
)(&AtaReq
->ahci_cmd0
);
2629 prd_base0
= prd_base
;
2631 prd_base64
= (prd_base64
+ max(FIELD_OFFSET(ATA_REQ
, ahci_cmd0
), AHCI_CMD_ALIGNEMENT_MASK
+1)) & ~AHCI_CMD_ALIGNEMENT_MASK
;
2634 d
= (ULONG
)(prd_base64
- prd_base64_0
);
2635 KdPrint2((PRINT_PREFIX
" AtaReq %#x: cmd aligned %I64x, d=%x\n", AtaReq
, prd_base64
, d
));
2638 AtaReq
->ahci
.ahci_cmd_ptr
= (PIDE_AHCI_CMD
)prd_base64
;
2639 KdPrint2((PRINT_PREFIX
" ahci_cmd_ptr %#x\n", AtaReq
->ahci
.ahci_cmd_ptr
));
2640 } // end UniataAhciSetupCmdPtr()
2644 BuildAhciInternalSrb (
2645 IN PVOID HwDeviceExtension
,
2646 IN ULONG DeviceNumber
,
2652 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2653 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
2654 PSCSI_REQUEST_BLOCK srb
;
2656 PATA_REQ AtaReq
= chan
->AhciInternalAtaReq
;
2658 KdPrint(("BuildAhciInternalSrb: lChan %d [%#x]\n", lChannel
, DeviceNumber
));
2661 KdPrint2((PRINT_PREFIX
" !chan->AhciInternalAtaReq\n"));
2665 //RtlZeroMemory((PCHAR) AtaReq, sizeof(ATA_REQ));
2666 //RtlZeroMemory((PCHAR) AtaReq, FIELD_OFFSET(ATA_REQ, ahci));
2667 UniAtaClearAtaReq(AtaReq
);
2669 srb
= chan
->AhciInternalSrb
;
2671 RtlZeroMemory((PCHAR
) srb
, sizeof(SCSI_REQUEST_BLOCK
));
2673 srb
->PathId
= (UCHAR
)lChannel
;
2674 srb
->TargetId
= (UCHAR
)DeviceNumber
;
2675 srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
2676 srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
2678 // Set flags to disable synchronous negociation.
2679 //srb->SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
2681 // Set timeout to 4 seconds.
2682 srb
->TimeOutValue
= 4;
2685 srb
->DataBuffer
= Buffer
;
2686 srb
->DataTransferLength
= Length
;
2687 srb
->SrbExtension
= AtaReq
;
2690 AtaReq
->DataBuffer
= (PUSHORT
)Buffer
;
2691 AtaReq
->TransferLength
= Length
;
2693 //if(!AtaReq->ahci.ahci_cmd_ptr) {
2694 //UniataAhciSetupCmdPtr(AtaReq);
2695 //AtaReq->ahci.ahci_cmd_ptr = &(chan->AhciCtlBlock->cmd);
2696 //AtaReq->ahci.ahci_base64 = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, cmd);
2698 //AtaReq->ahci.ahci_cmd_ptr = &(AtaReq->ahci_cmd0);
2699 //AtaReq->ahci.ahci_base64 = NULL; // indicate that we should copy command to proper place
2701 KdPrint2((PRINT_PREFIX
" Srb %#x, AtaReq %#x, CMD %#x ph %I64x\n", srb
, AtaReq
,
2702 AtaReq
->ahci
.ahci_cmd_ptr
, AtaReq
->ahci
.ahci_base64
));
2704 /* // Set CDB operation code.
2705 cdb = (PCDB)srb->Cdb;
2706 cdb->CDB6INQUIRY.OperationCode = SCSIOP_REQUEST_SENSE;
2707 cdb->CDB6INQUIRY.AllocationLength = sizeof(SENSE_DATA);
2710 } // end BuildAhciInternalSrb()