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
;
653 ULONG BaseMemAddress
;
659 BOOLEAN MemIo
= FALSE
;
661 KdPrint2((PRINT_PREFIX
" UniataAhciInit:\n"));
664 UniataDumpAhciRegs(deviceExtension
);
667 CAP2
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_CAP2
);
668 if(CAP2
& AHCI_CAP2_BOH
) {
669 BOHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_BOHC
);
670 KdPrint2((PRINT_PREFIX
" stage 1 BOHC %#x\n", BOHC
));
671 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_BOHC
,
672 BOHC
| AHCI_BOHC_OOS
);
673 for(i
=0; i
<50; i
++) {
674 AtapiStallExecution(500);
675 BOHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_BOHC
);
676 KdPrint2((PRINT_PREFIX
" BOHC %#x\n", BOHC
));
677 if(BOHC
& AHCI_BOHC_BB
) {
680 if(!(BOHC
& AHCI_BOHC_BOS
)) {
684 KdPrint2((PRINT_PREFIX
" stage 2 BOHC %#x\n", BOHC
));
685 if(BOHC
& AHCI_BOHC_BB
) {
686 for(i
=0; i
<2000; i
++) {
687 AtapiStallExecution(1000);
688 BOHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_BOHC
);
689 KdPrint2((PRINT_PREFIX
" BOHC %#x\n", BOHC
));
690 if(!(BOHC
& AHCI_BOHC_BOS
)) {
695 KdPrint2((PRINT_PREFIX
" final BOHC %#x\n", BOHC
));
698 /* disable AHCI interrupts, for MSI compatibility issue
699 see http://www.intel.com/Assets/PDF/specupdate/307014.pdf
700 26. AHCI Reset and MSI Request
703 KdPrint2((PRINT_PREFIX
" get GHC\n"));
704 /* enable AHCI mode */
705 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
706 if(!(GHC
& AHCI_GHC_AE
)) {
707 KdPrint2((PRINT_PREFIX
" enable AHCI mode, disable intr, GHC %#x\n", GHC
));
708 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_GHC
,
709 (GHC
| AHCI_GHC_AE
) & ~AHCI_GHC_IE
);
711 KdPrint2((PRINT_PREFIX
" disable intr, GHC %#x\n", GHC
));
712 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_GHC
,
715 AtapiStallExecution(100);
717 /* read GHC again and reset AHCI controller */
718 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
719 KdPrint2((PRINT_PREFIX
" reset AHCI controller, GHC %#x\n", GHC
));
720 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_GHC
,
723 for(i
=0; i
<1000; i
++) {
724 AtapiStallExecution(1000);
725 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
726 KdPrint2((PRINT_PREFIX
" AHCI GHC %#x\n", GHC
));
727 if(!(GHC
& AHCI_GHC_HR
)) {
731 if(GHC
& AHCI_GHC_HR
) {
732 KdPrint2((PRINT_PREFIX
" AHCI reset failed\n"));
736 /* re-enable AHCI mode */
737 /* Linux: Some controllers need AHCI_EN to be written multiple times.
738 * Try a few times before giving up.
740 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
742 if(!(GHC
& AHCI_GHC_AE
)) {
743 KdPrint2((PRINT_PREFIX
" re-enable AHCI mode, GHC %#x\n", GHC
));
744 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_GHC
,
746 AtapiStallExecution(1000);
747 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
752 KdPrint2((PRINT_PREFIX
" AHCI GHC %#x\n", GHC
));
753 if(!(GHC
& AHCI_GHC_AE
)) {
754 KdPrint2((PRINT_PREFIX
" Can't enable AHCI mode\n"));
758 deviceExtension
->AHCI_CAP
=
759 CAP
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_CAP
);
760 KdPrint2((PRINT_PREFIX
" AHCI CAP %#x\n", CAP
));
761 if(CAP
& AHCI_CAP_S64A
) {
762 KdPrint2((PRINT_PREFIX
" AHCI 64bit\n"));
763 deviceExtension
->Host64
= TRUE
;
765 KdPrint2((PRINT_PREFIX
" AHCI %d CMD slots\n", (CAP
& AHCI_CAP_NCS_MASK
) >> 8 ));
766 if(CAP
& AHCI_CAP_PMD
) {
767 KdPrint2((PRINT_PREFIX
" AHCI multi-block PIO\n"));
769 if(CAP
& AHCI_CAP_SAM
) {
770 KdPrint2((PRINT_PREFIX
" AHCI legasy SATA\n"));
773 /* get the number of HW channels */
774 PI
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_PI
);
775 deviceExtension
->AHCI_PI
= PI
;
776 KdPrint2((PRINT_PREFIX
" AHCI PI %#x\n", PI
));
777 KdPrint2((PRINT_PREFIX
" AHCI PI mask %#x\n", deviceExtension
->AHCI_PI_mask
));
778 deviceExtension
->AHCI_PI
= PI
= PI
& deviceExtension
->AHCI_PI_mask
;
779 KdPrint2((PRINT_PREFIX
" masked AHCI PI %#x\n", PI
));
781 CAP2
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_CAP2
);
782 if(CAP2
& AHCI_CAP2_BOH
) {
783 KdPrint2((PRINT_PREFIX
" retry BOHC\n"));
784 BOHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_BOHC
);
785 KdPrint2((PRINT_PREFIX
" BOHC %#x\n", BOHC
));
786 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_BOHC
,
787 BOHC
| AHCI_BOHC_OOS
);
789 /* clear interrupts */
790 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_IS
,
791 UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_IS
));
793 /* enable AHCI interrupts */
794 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_GHC
,
795 UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
) | AHCI_GHC_IE
);
797 BaseMemAddress
= deviceExtension
->BaseIoAHCI_0
.Addr
;
798 MemIo
= deviceExtension
->BaseIoAHCI_0
.MemIo
;
800 deviceExtension
->MaxTransferMode
= ATA_SA150
+(((CAP
& AHCI_CAP_ISS_MASK
) >> 20)-1);
801 KdPrint2((PRINT_PREFIX
" SATA Gen %d\n", ((CAP
& AHCI_CAP_ISS_MASK
) >> 20) ));
803 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
804 chan
= &deviceExtension
->chan
[c
];
805 offs
= sizeof(IDE_AHCI_REGISTERS
) + c
*sizeof(IDE_AHCI_PORT_REGISTERS
);
807 KdPrint2((PRINT_PREFIX
" chan %d, offs %#x\n", c
, offs
));
809 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
811 AtapiSetupLunPtrs(chan
, deviceExtension
, c
);
813 chan
->BaseIoAHCI_Port
= deviceExtension
->BaseIoAHCI_0
;
814 chan
->BaseIoAHCI_Port
.Addr
= BaseMemAddress
+ offs
;
816 chan
->RegTranslation
[IDX_IO1_i_Status
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, TFD
.STS
);
817 chan
->RegTranslation
[IDX_IO1_i_Status
].MemIo
= MemIo
;
818 chan
->RegTranslation
[IDX_IO2_AltStatus
] = chan
->RegTranslation
[IDX_IO1_i_Status
];
819 chan
->RegTranslation
[IDX_IO1_i_Error
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, TFD
.ERR
);
820 chan
->RegTranslation
[IDX_IO1_i_Error
].MemIo
= MemIo
;
821 chan
->RegTranslation
[IDX_IO1_i_CylinderLow
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, SIG
.LbaLow
);
822 chan
->RegTranslation
[IDX_IO1_i_CylinderLow
].MemIo
= MemIo
;
823 chan
->RegTranslation
[IDX_IO1_i_CylinderHigh
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, SIG
.LbaHigh
);
824 chan
->RegTranslation
[IDX_IO1_i_CylinderHigh
].MemIo
= MemIo
;
825 chan
->RegTranslation
[IDX_IO1_i_BlockCount
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, SIG
.SectorCount
);
826 chan
->RegTranslation
[IDX_IO1_i_BlockCount
].MemIo
= MemIo
;
828 UniataInitSyncBaseIO(chan
);
830 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, SSTS
);
831 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
832 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, SERR
);
833 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
834 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, SCTL
);
835 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
836 chan
->RegTranslation
[IDX_SATA_SActive
].Addr
= BaseMemAddress
+ offs
+ FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS
, SACT
);
837 chan
->RegTranslation
[IDX_SATA_SActive
].MemIo
= MemIo
;
839 AtapiDmaAlloc(HwDeviceExtension
, NULL
, c
);
841 if(!UniataAhciChanImplemented(deviceExtension
, c
)) {
842 KdPrint2((PRINT_PREFIX
" chan %d not implemented\n", c
));
846 UniataAhciResume(chan
);
848 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
852 } // end UniataAhciInit()
856 UniAtaAhciValidateVersion(
857 IN PHW_DEVICE_EXTENSION deviceExtension
,
865 KdPrint((" wrong AHCI revision %#x\n", version
));
875 KdPrint2((PRINT_PREFIX
" Unknown AHCI revision\n"));
876 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"CheckAhciRevision", Strict
)) {
877 KdPrint((" AHCI revision excluded %#x\n", version
));
882 } // end UniAtaAhciValidateVersion()
887 IN PVOID HwDeviceExtension
,
888 IN PPCI_COMMON_CONFIG pciData
, // optional
889 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
892 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
893 //ULONG slotNumber = deviceExtension->slotNumber;
894 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
898 //ULONG PI_ex_mask=0;
906 ULONG NumberChannels
;
907 ULONG_PTR BaseMemAddress
;
908 BOOLEAN MemIo
= FALSE
;
909 BOOLEAN found
= FALSE
;
912 KdPrint2((PRINT_PREFIX
" UniataAhciDetect:\n"));
914 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"IgnoreAhci", 0)) {
915 KdPrint((" AHCI excluded\n"));
918 switch(deviceExtension
->DevID
) {
920 KdPrint2((PRINT_PREFIX
" Cavium uses BAR(0)\n"));
924 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
926 if(!BaseMemAddress
) {
927 KdPrint2((PRINT_PREFIX
" AHCI init failed - no IoRange\n"));
930 if((*ConfigInfo
->AccessRanges
)[BarId
].RangeInMemory
) {
931 KdPrint2((PRINT_PREFIX
"MemIo\n"));
934 deviceExtension
->BaseIoAHCI_0
.Addr
= BaseMemAddress
;
935 deviceExtension
->BaseIoAHCI_0
.MemIo
= MemIo
;
938 UniataDumpAhciRegs(deviceExtension
);
941 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
942 if(GHC
& AHCI_GHC_HR
) {
943 KdPrint2((PRINT_PREFIX
" AHCI in reset state\n"));
947 /* check AHCI mode. Save state and try enable */
949 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
950 KdPrint2((PRINT_PREFIX
" check AHCI mode, GHC %#x\n", GHC
));
952 version
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_VS
);
954 if(!(GHC
& AHCI_GHC_AE
)) {
955 KdPrint2((PRINT_PREFIX
" Non-AHCI GHC (!AE), check revision %#x\n", version
));
956 if(!UniAtaAhciValidateVersion(deviceExtension
, version
, FALSE
)) {
957 KdPrint2((PRINT_PREFIX
" Non-AHCI\n"));
960 KdPrint2((PRINT_PREFIX
" try enable\n"));
961 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_GHC
,
962 (GHC
| AHCI_GHC_AE
) & ~AHCI_GHC_IE
);
963 GHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_GHC
);
965 KdPrint2((PRINT_PREFIX
" re-check AHCI mode, GHC %#x\n", GHC
));
966 if(!(GHC
& AHCI_GHC_AE
)) {
967 KdPrint2((PRINT_PREFIX
" Non-AHCI GHC (!AE)\n"));
972 CAP
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_CAP
);
973 CAP2
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_CAP2
);
974 KdPrint2((PRINT_PREFIX
" AHCI CAP %#x, CAP2 %#x, ver %#x\n", CAP
, CAP2
, version
));
975 if(CAP
& AHCI_CAP_S64A
) {
976 KdPrint2((PRINT_PREFIX
" 64bit"));
977 //deviceExtension->Host64 = TRUE; // this is just DETECT, do not update anything
980 if(CAP2
& AHCI_CAP2_BOH
) {
981 BOHC
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_BOHC
);
982 KdPrint2((PRINT_PREFIX
" BOHC %#x", BOHC
));
985 if(CAP
& AHCI_CAP_NCQ
) {
986 KdPrint2((PRINT_PREFIX
" NCQ"));
988 if(CAP
& AHCI_CAP_SNTF
) {
989 KdPrint2((PRINT_PREFIX
" SNTF"));
991 if(CAP
& AHCI_CAP_CCC
) {
992 KdPrint2((PRINT_PREFIX
" CCC"));
994 KdPrint2((PRINT_PREFIX
"\n"));
996 /* get the number of HW channels */
998 /* CAP.NOP sometimes indicate the index of the last enabled
999 * port, at other times, that of the last possible port, so
1000 * determining the maximum port number requires looking at
1001 * both CAP.NOP and PI.
1003 PI
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_PI
);
1004 deviceExtension
->AHCI_PI
= deviceExtension
->AHCI_PI_mask
= PI
;
1005 KdPrint2((PRINT_PREFIX
" AHCI PI %#x\n", PI
));
1007 for(i
=PI
, n
=0; i
; n
++, i
=i
>>1) {
1008 if(AtapiRegCheckDevValue(deviceExtension
, n
, DEVNUM_NOT_SPECIFIED
, L
"Exclude", 0)) {
1009 KdPrint2((PRINT_PREFIX
"Channel %d excluded\n", n
));
1010 deviceExtension
->AHCI_PI
&= ~((ULONG
)1 << n
);
1011 deviceExtension
->AHCI_PI_mask
&= ~((ULONG
)1 << n
);
1012 //PI_ex_mask |= ((ULONG)1 << n);
1015 deviceExtension
->AHCI_PI_mask
=
1016 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"PortMask", deviceExtension
->AHCI_PI_mask
);
1017 KdPrint2((PRINT_PREFIX
"Force PortMask %#x\n", deviceExtension
->AHCI_PI_mask
));
1019 for(i
=PI
, n
=0; i
; n
++, i
=i
>>1);
1021 max((CAP
& AHCI_CAP_NOP_MASK
)+1, n
);
1023 if(!PI
&& ((CAP
& AHCI_CAP_NOP_MASK
)+1)) {
1025 * The spec says that BIOS sets up bits corresponding to
1026 * available ports. On platforms where this information
1027 * is missing, the driver can define available ports on its own.
1029 KdPrint2((PRINT_PREFIX
"PI=0 -> Enable ports (mask) %#x\n", deviceExtension
->AHCI_PI_mask
));
1031 deviceExtension
->AHCI_PI
= ((ULONG
)1 << n
)-1;
1033 if(deviceExtension
->AHCI_PI_mask
) {
1034 // we have some forced port mask
1035 PI
= deviceExtension
->AHCI_PI_mask
;
1038 PI
= deviceExtension
->AHCI_PI
= (((ULONG
)1 << n
)-1);
1039 deviceExtension
->AHCI_PI_mask
= (((ULONG
)1 << n
)-1);
1041 KdPrint2((PRINT_PREFIX
"Enable ports final PI %#x\n", PI
));
1042 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_PI
, PI
);
1045 KdPrint2((PRINT_PREFIX
" CommandSlots %d\n", (CAP
& AHCI_CAP_NCS_MASK
)>>8 ));
1046 KdPrint2((PRINT_PREFIX
" Detected Channels %d / %d\n", NumberChannels
, n
));
1048 switch(deviceExtension
->DevID
) {
1050 KdPrint2((PRINT_PREFIX
" JMicron JMB361 -> 1\n"));
1054 KdPrint2((PRINT_PREFIX
" Marvell M88SE6111 -> 1\n"));
1058 KdPrint2((PRINT_PREFIX
" Marvell M88SE6121 -> 2\n"));
1059 NumberChannels
= min(NumberChannels
, 2);
1064 KdPrint2((PRINT_PREFIX
" Marvell M88SE614x/9123 -> 4\n"));
1065 NumberChannels
= min(NumberChannels
, 4);
1069 if(!NumberChannels
) {
1070 KdPrint2((PRINT_PREFIX
" Non-AHCI - NumberChannels=0\n"));
1074 KdPrint2((PRINT_PREFIX
" Adjusted Channels %d\n", NumberChannels
));
1077 v_Mj
= ((version
>> 20) & 0xf0) + ((version
>> 16) & 0x0f);
1078 v_Mn
= ((version
>> 4) & 0xf0) + (version
& 0x0f);
1080 KdPrint2((PRINT_PREFIX
" AHCI version %#x.%02x controller with %d ports (mask %#x) detected\n",
1082 NumberChannels
, PI
));
1083 KdPrint((" AHCI SATA Gen %d\n", (((CAP
& AHCI_CAP_ISS_MASK
) >> 20)) ));
1086 if(CAP
& AHCI_CAP_SPM
) {
1087 KdPrint2((PRINT_PREFIX
" PM supported\n"));
1088 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"IgnoreAhciPM", 1 /* DEBUG */)) {
1089 KdPrint2((PRINT_PREFIX
"SATA/AHCI w/o PM, max luns 1\n"));
1090 deviceExtension
->NumberLuns
= 1;
1091 //chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
1093 KdPrint2((PRINT_PREFIX
"SATA/AHCI -> possible PM, max luns %d\n", SATA_MAX_PM_UNITS
));
1094 deviceExtension
->NumberLuns
= SATA_MAX_PM_UNITS
;
1095 //deviceExtension->NumberLuns = 1;
1098 KdPrint2((PRINT_PREFIX
" PM not supported -> 1 lun/chan\n"));
1099 deviceExtension
->NumberLuns
= 1;
1102 if(!UniAtaAhciValidateVersion(deviceExtension
, version
, TRUE
)) {
1106 deviceExtension
->HwFlags
|= UNIATA_SATA
| UNIATA_AHCI
;
1107 if(deviceExtension
->NumberChannels
< NumberChannels
) {
1108 deviceExtension
->NumberChannels
= NumberChannels
;
1110 deviceExtension
->DmaSegmentLength
= 0x3fffff+1; // 4MB
1111 deviceExtension
->DmaSegmentAlignmentMask
= -1; // no restrictions
1113 deviceExtension
->BusMaster
= DMA_MODE_AHCI
;
1114 deviceExtension
->MaxTransferMode
= max(deviceExtension
->MaxTransferMode
, ATA_SA150
+(((CAP
& AHCI_CAP_ISS_MASK
) >> 20)-1) );
1119 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_GHC
, GHC0
);
1120 KdPrint((" AHCI detect status %d\n", found
));
1123 } // end UniataAhciDetect()
1128 IN PVOID HwDeviceExtension
,
1130 IN ULONG DeviceNumber
1133 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1134 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1135 ULONG Channel
= deviceExtension
->Channel
+ lChannel
;
1139 SATA_SSTATUS_REG SStatus
;
1140 SATA_SERROR_REG SError
;
1141 //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
1144 KdPrint(("UniataAhciStatus(%d-%d):\n", lChannel
, Channel
));
1146 hIS
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_IS
);
1147 KdPrint((" hIS %#x\n", hIS
));
1148 hIS
&= (1 << Channel
);
1150 return INTERRUPT_REASON_IGNORE
;
1152 IS
.Reg
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_IS
);
1153 CI
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CI
);
1154 ACT
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_ACT
);
1155 SStatus
.Reg
= AtapiReadPort4(chan
, IDX_SATA_SStatus
);
1156 SError
.Reg
= AtapiReadPort4(chan
, IDX_SATA_SError
);
1158 /* clear interrupt(s) */
1159 UniataAhciWriteHostPort4(deviceExtension
, IDX_AHCI_IS
, hIS
);
1160 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IS
, IS
.Reg
);
1161 AtapiWritePort4(chan
, IDX_SATA_SError
, SError
.Reg
);
1163 KdPrint((" AHCI: is=%08x ss=%08x serror=%08x CI=%08x, ACT=%08x\n",
1164 IS
.Reg
, SStatus
.Reg
, SError
.Reg
, CI
, ACT
));
1166 /* do we have cold connect surprise */
1170 /* check for and handle connect events */
1172 UniataSataEvent(HwDeviceExtension
, lChannel
, UNIATA_SATA_EVENT_ATTACH
);
1175 UniataSataEvent(HwDeviceExtension
, lChannel
, UNIATA_SATA_EVENT_DETACH
);
1177 chan
->AhciCompleteCI
= (chan
->AhciPrevCI
^ CI
) & chan
->AhciPrevCI
; // only 1->0 states
1178 chan
->AhciPrevCI
= CI
;
1179 chan
->AhciLastSError
= SError
.Reg
;
1180 KdPrint((" AHCI: complete mask %#x\n", chan
->AhciCompleteCI
));
1181 chan
->AhciLastIS
= IS
.Reg
;
1182 if(CI
& (1 << tag
)) {
1184 UniataDumpAhciPortRegs(chan
);
1186 //deviceExtension->ExpectingInterrupt++; // will be updated in ISR on ReturnEnableInterrupts
1188 (ATA_AHCI_P_IX_OF
| ATA_AHCI_P_IX_INF
| ATA_AHCI_P_IX_IF
|
1189 ATA_AHCI_P_IX_HBD
| ATA_AHCI_P_IX_HBF
| ATA_AHCI_P_IX_TFE
)) {
1190 KdPrint((" AHCI: unexpected, error\n"));
1192 KdPrint((" AHCI: unexpected, incomplete command or error ?\n"));
1196 TFD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_TFD);
1197 KdPrint2((" TFD %#x\n", TFD));
1198 if(TFD & IDE_STATUS_BUSY) {
1199 KdPrint2((" Seems to be interrupt on error\n"));
1200 return INTERRUPT_REASON_OUR;
1203 return INTERRUPT_REASON_UNEXPECTED
;
1206 return INTERRUPT_REASON_OUR
;
1208 } // end UniataAhciStatus()
1212 UniataAhciSnapAtaRegs(
1213 IN PHW_CHANNEL chan
,
1214 IN ULONG DeviceNumber
,
1215 IN OUT PIDEREGS_EX regs
1220 regs
->bDriveHeadReg
= IDE_DRIVE_SELECT_1
;
1221 TFD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_TFD
);
1222 regs
->bCommandReg
= (UCHAR
)(TFD
& 0xff);
1223 regs
->bFeaturesReg
= (UCHAR
)((TFD
>> 8) & 0xff);
1225 SIG
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_SIG
);
1226 regs
->bSectorCountReg
= (UCHAR
)(SIG
& 0xff);
1227 regs
->bSectorNumberReg
= (UCHAR
)((SIG
>> 8) & 0xff);
1228 regs
->bCylLowReg
= (UCHAR
)((SIG
>> 16) & 0xff);
1229 regs
->bCylHighReg
= (UCHAR
)((SIG
>> 24) & 0xff);
1233 } // end UniataAhciSnapAtaRegs()
1237 UniataAhciSetupFIS_H2D(
1238 IN PHW_DEVICE_EXTENSION deviceExtension
,
1239 IN ULONG DeviceNumber
,
1251 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1253 KdPrint2((PRINT_PREFIX
" AHCI setup FIS %x, ch %d, dev %d\n", fis
, lChannel
, DeviceNumber
));
1255 plba
= (PUCHAR
)&lba
;
1257 RtlZeroMemory(fis
, 20);
1259 fis
[0] = AHCI_FIS_TYPE_ATA_H2D
; /* host to device */
1260 fis
[1] = 0x80 | ((UCHAR
)DeviceNumber
& 0x0f); /* command FIS (note PM goes here) */
1261 fis
[IDX_AHCI_o_DriveSelect
] = IDE_DRIVE_SELECT_1
|
1262 ((AtaCommandFlags
[command
] & (ATA_CMD_FLAG_LBAIOsupp
| ATA_CMD_FLAG_48
)) ? IDE_USE_LBA
: 0);
1263 fis
[IDX_AHCI_o_Control
] = IDE_DC_A_4BIT
;
1265 // IDE_COMMAND_ATAPI_IDENTIFY should be processed as regular ATA command,
1266 // the rest of ATAPI requests are processed via IDE_COMMAND_ATAPI_PACKET
1267 if(/*(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
1269 command
== IDE_COMMAND_ATAPI_PACKET
) {
1270 fis
[IDX_AHCI_o_Command
] = IDE_COMMAND_ATAPI_PACKET
;
1271 if(feature
& ATA_F_DMA
) {
1272 fis
[IDX_AHCI_o_Feature
] = (UCHAR
)(feature
& 0xff);
1274 fis
[IDX_AHCI_o_CylinderLow
] = (UCHAR
)(count
& 0xff);
1275 fis
[IDX_AHCI_o_CylinderHigh
] = (UCHAR
)(count
>>8) & 0xff;
1277 //fis[IDX_AHCI_o_Control] |= IDE_DC_A_4BIT;
1280 if(((AtaCommandFlags
[command
] & (ATA_CMD_FLAG_LBAIOsupp
|ATA_CMD_FLAG_FUA
)) == ATA_CMD_FLAG_LBAIOsupp
) &&
1281 CheckIfBadBlock(chan
->lun
[DeviceNumber
], lba
, count
)) {
1282 KdPrint3((PRINT_PREFIX
": artificial bad block, lba %#I64x count %#x\n", lba
, count
));
1286 need48
= UniAta_need_lba48(command
, lba
, count
,
1287 chan
->lun
[DeviceNumber
]->IdentifyData
.FeaturesSupport
.Address48
);
1289 /* translate command into 48bit version */
1291 if(AtaCommandFlags
[command
] & ATA_CMD_FLAG_48supp
) {
1292 command
= AtaCommands48
[command
];
1294 KdPrint2((PRINT_PREFIX
" unhandled LBA48 command\n"));
1299 fis
[IDX_AHCI_o_Command
] = command
;
1300 fis
[IDX_AHCI_o_Feature
] = (UCHAR
)feature
;
1302 fis
[IDX_AHCI_o_BlockNumber
] = plba
[0];
1303 fis
[IDX_AHCI_o_CylinderLow
] = plba
[1];
1304 fis
[IDX_AHCI_o_CylinderHigh
] = plba
[2];
1306 fis
[IDX_AHCI_o_BlockCount
] = (UCHAR
)count
& 0xff;
1310 fis
[IDX_AHCI_o_Control
] |= IDE_DC_USE_HOB
;
1312 fis
[IDX_AHCI_o_BlockNumberExp
] = plba
[3];
1313 fis
[IDX_AHCI_o_CylinderLowExp
] = plba
[4];
1314 fis
[IDX_AHCI_o_CylinderHighExp
] = plba
[5];
1316 fis
[IDX_AHCI_o_BlockCountExp
] = (UCHAR
)(count
>>8) & 0xff;
1318 fis
[IDX_AHCI_o_FeatureExp
] = (UCHAR
)(feature
>>8) & 0xff;
1320 chan
->ChannelCtrlFlags
|= CTRFLAGS_LBA48
;
1322 fis
[IDX_AHCI_o_DriveSelect
] |= /*IDE_DRIVE_1 |*/ (plba
[3] & 0x0f);
1323 chan
->ChannelCtrlFlags
&= ~CTRFLAGS_LBA48
;
1333 } // end UniataAhciSetupFIS_H2D()
1337 UniataAhciSetupFIS_H2D_Direct(
1338 IN PHW_DEVICE_EXTENSION deviceExtension
,
1339 IN ULONG DeviceNumber
,
1348 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1351 command
= regs
->bCommandReg
;
1353 KdPrint2((PRINT_PREFIX
" AHCI setup FIS Direct %x, ch %d, dev %d\n", fis
, lChannel
, DeviceNumber
));
1355 //plba = (PUCHAR)&lba;
1357 RtlZeroMemory(fis
, 20);
1359 fis
[0] = AHCI_FIS_TYPE_ATA_H2D
; /* host to device */
1360 fis
[1] = 0x80 | ((UCHAR
)DeviceNumber
& 0x0f); /* command FIS (note PM goes here) */
1361 fis
[IDX_AHCI_o_DriveSelect
] = IDE_DRIVE_SELECT_1
|
1362 ((AtaCommandFlags
[command
] & (ATA_CMD_FLAG_LBAIOsupp
| ATA_CMD_FLAG_48
)) ? IDE_USE_LBA
: 0);
1363 fis
[IDX_AHCI_o_Control
] = IDE_DC_A_4BIT
;
1365 // IDE_COMMAND_ATAPI_IDENTIFY should be processed as regular ATA command,
1366 // the rest of ATAPI requests are processed via IDE_COMMAND_ATAPI_PACKET
1367 if(/*(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
1369 command
== IDE_COMMAND_ATAPI_PACKET
) {
1370 /* fis[IDX_AHCI_o_Command] = IDE_COMMAND_ATAPI_PACKET;
1371 if(feature & ATA_F_DMA) {
1372 fis[IDX_AHCI_o_Feature] = (UCHAR)(feature & 0xff);
1374 fis[IDX_AHCI_o_CylinderLow] = (UCHAR)(count & 0xff);
1375 fis[IDX_AHCI_o_CylinderHigh] = (UCHAR)(count>>8) & 0xff;
1378 //fis[IDX_AHCI_o_Control] |= IDE_DC_A_4BIT;
1381 need48
= (regs
->bOpFlags
& ATA_FLAGS_48BIT_COMMAND
) &&
1382 chan
->lun
[DeviceNumber
]->IdentifyData
.FeaturesSupport
.Address48
;
1384 /* translate command into 48bit version */
1386 if(AtaCommandFlags
[command
] & ATA_CMD_FLAG_48supp
) {
1387 command
= AtaCommands48
[command
];
1389 KdPrint2((PRINT_PREFIX
" unhandled LBA48 command\n"));
1394 fis
[IDX_AHCI_o_Command
] = command
;
1395 fis
[IDX_AHCI_o_Feature
] = regs
->bFeaturesReg
;
1397 fis
[IDX_AHCI_o_BlockNumber
] = regs
->bSectorNumberReg
;
1398 fis
[IDX_AHCI_o_CylinderLow
] = regs
->bCylLowReg
;
1399 fis
[IDX_AHCI_o_CylinderHigh
] = regs
->bCylHighReg
;
1401 fis
[IDX_AHCI_o_BlockCount
] = regs
->bSectorCountReg
;
1405 fis
[IDX_AHCI_o_Control
] |= IDE_DC_USE_HOB
;
1407 fis
[IDX_AHCI_o_BlockNumberExp
] = regs
->bSectorNumberRegH
;
1408 fis
[IDX_AHCI_o_CylinderLowExp
] = regs
->bCylLowRegH
;
1409 fis
[IDX_AHCI_o_CylinderHighExp
] = regs
->bCylHighRegH
;
1411 fis
[IDX_AHCI_o_BlockCountExp
] = regs
->bSectorCountRegH
;
1413 fis
[IDX_AHCI_o_FeatureExp
] = regs
->bFeaturesRegH
;
1415 chan
->ChannelCtrlFlags
|= CTRFLAGS_LBA48
;
1417 //fis[IDX_AHCI_o_DriveSelect] |= /*IDE_DRIVE_1 |*/ (plba[3] & 0x0f);
1418 chan
->ChannelCtrlFlags
&= ~CTRFLAGS_LBA48
;
1420 fis
[IDX_AHCI_o_DriveSelect
] |= regs
->bDriveHeadReg
& 0x0f;
1426 } // end UniataAhciSetupFIS_H2D_Direct()
1430 UniataAhciWaitCommandReady(
1431 IN PHW_CHANNEL chan
,
1444 for (i
=0; i
<timeout
; i
++) {
1445 CI
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CI
);
1446 //ACT = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_ACT);
1447 if (!(( CI
>> tag
) & 0x01)) {
1450 IS
.Reg
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_IS
);
1451 //KdPrint((" IS %#x\n", IS.Reg));
1455 SError
= AtapiReadPort4(chan
, IDX_SATA_SError
);
1457 KdPrint((" AHCI: error %#x\n", SError
));
1461 AtapiStallExecution(200);
1463 KdPrint((" CI %#x\n", CI
));
1465 //SStatus.Reg = AtapiReadPort4(chan, IDX_SATA_SStatus);
1466 //SError.Reg = AtapiReadPort4(chan, IDX_SATA_SError);
1468 /* clear interrupt(s) */
1469 IS
.Reg
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_IS
);
1470 KdPrint((" IS %#x\n", IS
.Reg
));
1471 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IS
, IS
.Reg
);
1473 if (timeout
&& (i
>= timeout
)) {
1477 SError
= AtapiReadPort4(chan
, IDX_SATA_SError
);
1478 KdPrint((" AHCI: timeout, SError %#x\n", SError
));
1480 TFD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_TFD
);
1481 KdPrint2((" TFD %#x\n", TFD
));
1484 return IDE_STATUS_WRONG
;
1487 return IDE_STATUS_IDLE
;
1488 } // end UniataAhciWaitCommandReady()
1492 UniataAhciSendCommand(
1493 IN PVOID HwDeviceExtension
,
1495 IN ULONG DeviceNumber
,
1496 IN USHORT ahci_flags
,
1500 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1501 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1502 //ULONG Channel = deviceExtension->Channel + lChannel;
1505 //SATA_SSTATUS_REG SStatus;
1506 //SATA_SERROR_REG SError;
1507 //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
1511 PIDE_AHCI_CMD_LIST AHCI_CL
= &(chan
->AhciCtlBlock
->cmd_list
[tag
]);
1513 KdPrint(("UniataAhciSendCommand: lChan %d\n", chan
->lChannel
));
1515 AHCI_CL
->prd_length
= 0;
1516 //AHCI_CL->cmd_flags = (20 / sizeof(ULONG)) | ahci_flags | (DeviceNumber << 12);
1517 AHCI_CL
->cmd_flags
= UniAtaAhciAdjustIoFlags(0, ahci_flags
, 20, DeviceNumber
);
1519 AHCI_CL
->bytecount
= 0;
1520 AHCI_CL
->cmd_table_phys
= chan
->AHCI_CTL_PhAddr
+ FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK
, cmd
);
1521 if(AHCI_CL
->cmd_table_phys
& AHCI_CMD_ALIGNEMENT_MASK
) {
1522 KdPrint2((PRINT_PREFIX
" AHCI CMD address is not aligned (mask %#x)\n", (ULONG
)AHCI_CMD_ALIGNEMENT_MASK
));
1525 //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag);
1526 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CI
, 1 << tag
);
1528 return UniataAhciWaitCommandReady(chan
, timeout
);
1530 } // end UniataAhciSendCommand()
1534 UniataAhciSendPIOCommand(
1535 IN PVOID HwDeviceExtension
,
1537 IN ULONG DeviceNumber
,
1538 IN PSCSI_REQUEST_BLOCK Srb
,
1540 IN ULONG length
, /* bytes */
1543 IN USHORT bcount
, /* block count, just ATA register */
1545 IN USHORT ahci_flags
,
1546 IN ULONG wait_flags
,
1550 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1551 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1556 //PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
1557 PIDE_AHCI_CMD AHCI_CMD
= NULL
;
1559 //PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
1561 KdPrint2((PRINT_PREFIX
"UniataAhciSendPIOCommand: cntrlr %#x:%#x dev %#x, cmd %#x, lba %#I64x bcount %#x feature %#x, buff %#x, len %#x, WF %#x \n",
1562 deviceExtension
->DevIndex
, lChannel
, DeviceNumber
, command
, lba
, bcount
, feature
, data
, length
, wait_flags
));
1564 if(length
/DEV_BSIZE
!= bcount
) {
1565 KdPrint((" length/DEV_BSIZE != bcount\n"));
1569 //UniataDumpAhciPortRegs(chan);
1573 Srb
= BuildAhciInternalSrb(HwDeviceExtension
, DeviceNumber
, lChannel
, data
, length
);
1575 KdPrint((" !Srb\n"));
1576 return IDE_STATUS_WRONG
;
1578 //UniataAhciSetupCmdPtr(AtaReq); // must be called before DMA setup
1579 //should be already called on init
1581 AtaReq
= (PATA_REQ
)(Srb
->SrbExtension
);
1582 //KdPrint((" Srb %#x, AtaReq %#x\n", Srb, AtaReq));
1584 AHCI_CMD
= AtaReq
->ahci
.ahci_cmd_ptr
;
1586 fis_size
= UniataAhciSetupFIS_H2D(deviceExtension
, DeviceNumber
, lChannel
,
1587 &(AHCI_CMD
->cfis
[0]),
1595 KdPrint2(("!fis_size\n"));
1596 return IDE_STATUS_WRONG
;
1599 //KdPrint2(("UniAtaAhciAdjustIoFlags(command, ahci_flags, fis_size, DeviceNumber)\n"));
1600 ahci_flags
= UniAtaAhciAdjustIoFlags(command
, ahci_flags
, fis_size
, DeviceNumber
);
1601 KdPrint2(("ahci_flags %#x\n", ahci_flags
));
1604 if(ahci_flags
& ATA_AHCI_CMD_WRITE
) {
1605 AtaReq
->Flags
&= ~REQ_FLAG_READ
;
1606 Srb
->SrbFlags
|= SRB_FLAGS_DATA_OUT
;
1607 KdPrint((" assume OUT\n"));
1609 AtaReq
->Flags
|= REQ_FLAG_READ
;
1610 Srb
->SrbFlags
|= SRB_FLAGS_DATA_IN
;
1611 KdPrint((" assume IN\n"));
1613 if(!AtapiDmaSetup(HwDeviceExtension
,
1615 lChannel
, // logical channel,
1619 KdPrint2((" can't setup buffer\n"));
1620 return IDE_STATUS_WRONG
;
1624 AtaReq
->ahci
.io_cmd_flags
= ahci_flags
;
1627 //UniataDumpAhciPortRegs(chan);
1630 UniataAhciBeginTransaction(HwDeviceExtension
, lChannel
, DeviceNumber
, Srb
);
1633 //UniataDumpAhciPortRegs(chan);
1636 if(wait_flags
== ATA_IMMEDIATE
) {
1638 KdPrint2((" return imemdiately\n"));
1640 statusByte
= UniataAhciWaitCommandReady(chan
, timeout
);
1641 UniataAhciStatus(HwDeviceExtension
, lChannel
, DeviceNumber
);
1642 UniataAhciEndTransaction(HwDeviceExtension
, lChannel
, DeviceNumber
, Srb
);
1647 } // end UniataAhciSendPIOCommand()
1651 UniataAhciSendPIOCommandDirect(
1652 IN PVOID HwDeviceExtension
,
1654 IN ULONG DeviceNumber
,
1655 IN PSCSI_REQUEST_BLOCK Srb
,
1656 IN PIDEREGS_EX regs
,
1657 IN ULONG wait_flags
,
1661 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1662 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1667 //PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
1668 PIDE_AHCI_CMD AHCI_CMD
= NULL
;
1669 USHORT ahci_flags
=0;
1672 //PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
1674 KdPrint2((PRINT_PREFIX
"UniataAhciSendPIOCommand: cntrlr %#x:%#x dev %#x, buff %#x, len %#x, WF %#x \n",
1675 deviceExtension
->DevIndex
, lChannel
, DeviceNumber
, Srb
->DataBuffer
, Srb
->DataTransferLength
, wait_flags
));
1677 // if(Srb->DataTransferLength/DEV_BSIZE != bcount) {
1678 // KdPrint((" length/DEV_BSIZE != bcount\n"));
1682 //UniataDumpAhciPortRegs(chan);
1686 KdPrint((" !Srb\n"));
1687 return IDE_STATUS_WRONG
;
1688 //UniataAhciSetupCmdPtr(AtaReq); // must be called before DMA setup
1689 //should be already called on init
1691 AtaReq
= (PATA_REQ
)(Srb
->SrbExtension
);
1692 //KdPrint((" Srb %#x, AtaReq %#x\n", Srb, AtaReq));
1694 AHCI_CMD
= AtaReq
->ahci
.ahci_cmd_ptr
;
1696 KdPrint((" !AHCI_CMD\n"));
1697 return IDE_STATUS_WRONG
;
1700 if(Srb
->DataTransferLength
) {
1701 if(Srb
->SrbFlags
& SRB_FLAGS_DATA_OUT
) {
1702 ahci_flags
|= ATA_AHCI_CMD_WRITE
;
1703 AtaReq
->Flags
&= ~REQ_FLAG_READ
;
1705 AtaReq
->Flags
|= REQ_FLAG_READ
;
1709 fis_size
= UniataAhciSetupFIS_H2D_Direct(deviceExtension
, DeviceNumber
, lChannel
,
1710 &(AHCI_CMD
->cfis
[0]),
1714 KdPrint2(("!fis_size\n"));
1715 return IDE_STATUS_WRONG
;
1718 //KdPrint2(("UniAtaAhciAdjustIoFlags(command, ahci_flags, fis_size, DeviceNumber)\n"));
1719 ahci_flags
= UniAtaAhciAdjustIoFlags(regs
->bCommandReg
, ahci_flags
, fis_size
, DeviceNumber
);
1720 KdPrint2(("ahci_flags %#x\n", ahci_flags
));
1722 if(Srb
->DataTransferLength
) {
1723 if(!AtapiDmaSetup(HwDeviceExtension
,
1725 lChannel
, // logical channel,
1727 (PUCHAR
)(Srb
->DataBuffer
),
1728 Srb
->DataTransferLength
)) {
1729 KdPrint2((" can't setup buffer\n"));
1730 return IDE_STATUS_WRONG
;
1734 AtaReq
->ahci
.io_cmd_flags
= ahci_flags
;
1737 //UniataDumpAhciPortRegs(chan);
1740 UniataAhciBeginTransaction(HwDeviceExtension
, lChannel
, DeviceNumber
, Srb
);
1743 //UniataDumpAhciPortRegs(chan);
1746 if(wait_flags
== ATA_IMMEDIATE
) {
1748 KdPrint2((" return imemdiately\n"));
1750 statusByte
= UniataAhciWaitCommandReady(chan
, timeout
);
1751 UniataAhciStatus(HwDeviceExtension
, lChannel
, DeviceNumber
);
1752 UniataAhciEndTransaction(HwDeviceExtension
, lChannel
, DeviceNumber
, Srb
);
1757 } // end UniataAhciSendPIOCommandDirect()
1761 UniataAhciAbortOperation(
1765 /* kick controller into sane state */
1766 if(!UniataAhciStop(chan
)) {
1769 if(!UniataAhciStopFR(chan
)) {
1772 if(!UniataAhciCLO(chan
)) {
1775 UniataAhciStartFR(chan
);
1776 UniataAhciStart(chan
);
1779 } // end UniataAhciAbortOperation()
1783 UniataAhciSoftReset(
1784 IN PVOID HwDeviceExtension
,
1786 IN ULONG DeviceNumber
1789 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1790 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1791 //ULONG Channel = deviceExtension->Channel + lChannel;
1797 KdPrint(("UniataAhciSoftReset: lChan %d\n", chan
->lChannel
));
1799 PIDE_AHCI_CMD AHCI_CMD
= &(chan
->AhciCtlBlock
->cmd
);
1800 PUCHAR RCV_FIS
= &(chan
->AhciCtlBlock
->rcv_fis
.rfis
[0]);
1802 /* kick controller into sane state */
1803 if(!UniataAhciAbortOperation(chan
)) {
1804 KdPrint2((" abort failed\n"));
1808 /* pull reset active */
1809 RtlZeroMemory(AHCI_CMD
->cfis
, sizeof(AHCI_CMD
->cfis
));
1810 AHCI_CMD
->cfis
[0] = AHCI_FIS_TYPE_ATA_H2D
;
1811 AHCI_CMD
->cfis
[1] = (UCHAR
)DeviceNumber
& 0x0f;
1812 //AHCI_CMD->cfis[7] = IDE_USE_LBA | IDE_DRIVE_SELECT;
1813 AHCI_CMD
->cfis
[15] = (IDE_DC_A_4BIT
| IDE_DC_RESET_CONTROLLER
);
1815 if(UniataAhciSendCommand(HwDeviceExtension
, lChannel
, DeviceNumber
, ATA_AHCI_CMD_RESET
| ATA_AHCI_CMD_CLR_BUSY
, 100) == IDE_STATUS_WRONG
) {
1816 KdPrint2((" timeout\n"));
1819 AtapiStallExecution(50);
1821 /* pull reset inactive */
1822 RtlZeroMemory(AHCI_CMD
->cfis
, sizeof(AHCI_CMD
->cfis
));
1823 AHCI_CMD
->cfis
[0] = AHCI_FIS_TYPE_ATA_H2D
;
1824 AHCI_CMD
->cfis
[1] = (UCHAR
)DeviceNumber
& 0x0f;
1825 //AHCI_CMD->cfis[7] = IDE_USE_LBA | IDE_DRIVE_SELECT;
1826 AHCI_CMD
->cfis
[15] = (IDE_DC_A_4BIT
);
1827 if(UniataAhciSendCommand(HwDeviceExtension
, lChannel
, DeviceNumber
, 0, 3000) == IDE_STATUS_WRONG
) {
1828 KdPrint2((" timeout (2)\n"));
1832 UniataAhciWaitReady(chan
, 1);
1834 KdDump(RCV_FIS
, sizeof(chan
->AhciCtlBlock
->rcv_fis
.rfis
));
1836 if(deviceExtension
->HwFlags
& UNIATA_AHCI_ALT_SIG
) {
1838 signature
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_SIG
);
1839 KdPrint((" alt sig: %#x\n", signature
));
1843 return UniataAhciUlongFromRFIS(RCV_FIS
);
1845 } // end UniataAhciSoftReset()
1849 UniataAhciWaitReady(
1850 IN PHW_CHANNEL chan
,
1857 KdPrint2(("UniataAhciWaitReady: lChan %d\n", chan
->lChannel
));
1859 //base = (ULONGIO_PTR)(&deviceExtension->BaseIoAHCI_0 + offs);
1861 TFD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_TFD
);
1862 for(i
=0; i
<timeout
&& (TFD
&
1863 (IDE_STATUS_DRQ
| IDE_STATUS_BUSY
)); i
++) {
1864 AtapiStallExecution(1000);
1865 TFD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_TFD
);
1868 KdPrint2((" TFD %#x\n", TFD
));
1872 } // end UniataAhciWaitReady()
1876 UniataAhciHardReset(
1877 IN PVOID HwDeviceExtension
,
1879 OUT PULONG signature
1882 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1883 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1884 //ULONG Channel = deviceExtension->Channel + lChannel;
1888 KdPrint(("UniataAhciHardReset: lChan %d\n", chan
->lChannel
));
1890 (*signature
) = 0xffffffff;
1892 UniataAhciStop(chan
);
1893 if(UniataSataPhyEnable(HwDeviceExtension
, lChannel
, 0/* dev0*/, UNIATA_SATA_RESET_ENABLE
) == IDE_STATUS_WRONG
) {
1894 KdPrint((" no PHY\n"));
1895 return IDE_STATUS_WRONG
;
1898 /* Wait for clearing busy status. */
1899 TFD
= UniataAhciWaitReady(chan
, 15000);
1900 if(TFD
& (IDE_STATUS_DRQ
| IDE_STATUS_BUSY
)) {
1901 KdPrint((" busy: TFD %#x\n", TFD
));
1904 KdPrint((" TFD %#x\n", TFD
));
1907 UniataDumpAhciPortRegs(chan
);
1910 (*signature
) = UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_SIG
);
1911 KdPrint((" sig: %#x\n", *signature
));
1913 UniataAhciStart(chan
);
1917 } // end UniataAhciHardReset()
1922 IN PVOID HwDeviceExtension
,
1926 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1927 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
1928 //ULONG Channel = deviceExtension->Channel + lChannel;
1929 //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
1934 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
1936 KdPrint(("UniataAhciReset: lChan %d\n", chan
->lChannel
));
1938 //base = (ULONGIO_PTR)(&deviceExtension->BaseIoAHCI_0 + offs);
1940 /* Disable port interrupts */
1941 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IE
, 0);
1943 if(UniataAhciHardReset(HwDeviceExtension
, lChannel
, &signature
)) {
1945 KdPrint((" No devices in all LUNs\n"));
1946 for (i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
1947 // Zero device fields to ensure that if earlier devices were found,
1948 // but not claimed, the fields are cleared.
1949 UniataForgetDevice(chan
->lun
[i
]);
1952 /* enable wanted port interrupts */
1953 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IE
,
1954 ATA_AHCI_P_IX_CPD
| ATA_AHCI_P_IX_PRC
| ATA_AHCI_P_IX_PC
);
1958 /* enable wanted port interrupts */
1959 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IE
,
1960 (ATA_AHCI_P_IX_CPD
| ATA_AHCI_P_IX_TFE
| ATA_AHCI_P_IX_HBF
|
1961 ATA_AHCI_P_IX_HBD
| ATA_AHCI_P_IX_IF
| ATA_AHCI_P_IX_OF
|
1962 ((/*ch->pm_level == */0) ? (ATA_AHCI_P_IX_PRC
| ATA_AHCI_P_IX_PC
) : 0) |
1963 ATA_AHCI_P_IX_DP
| ATA_AHCI_P_IX_UF
| ATA_AHCI_P_IX_SDB
|
1964 ATA_AHCI_P_IX_DS
| ATA_AHCI_P_IX_PS
| ATA_AHCI_P_IX_DHR
) );
1967 * Only probe for PortMultiplier if HW has support.
1968 * Ignore Marvell, which is not working,
1970 CAP
= UniataAhciReadHostPort4(deviceExtension
, IDX_AHCI_CAP
);
1971 if ((CAP
& AHCI_CAP_SPM
) &&
1972 (VendorID
!= ATA_MARVELL_ID
)) {
1973 KdPrint((" check PM\n"));
1974 signature
= UniataAhciSoftReset(HwDeviceExtension
, lChannel
, AHCI_DEV_SEL_PM
);
1975 /* Workaround for some ATI chips, failing to soft-reset
1976 * when port multiplicator supported, but absent.
1977 * XXX: We can also check PxIS.IPMS==1 here to be sure. */
1978 if (signature
== 0xffffffff) {
1979 KdPrint((" re-check PM\n"));
1980 signature
= UniataAhciSoftReset(HwDeviceExtension
, lChannel
, 0);
1983 signature
= UniataAhciSoftReset(HwDeviceExtension
, lChannel
, 0);
1986 KdPrint((" signature %#x\n", signature
));
1987 chan
->lun
[0]->DeviceFlags
&= ~(DFLAGS_ATAPI_DEVICE
| DFLAGS_DEVICE_PRESENT
| CTRFLAGS_AHCI_PM
);
1988 switch (signature
>> 16) {
1990 KdPrint((" ATA dev\n"));
1991 chan
->lun
[0]->DeviceFlags
|= DFLAGS_DEVICE_PRESENT
;
1996 if(deviceExtension
->NumberLuns
> 1) {
1997 chan
->ChannelCtrlFlags
|= CTRFLAGS_AHCI_PM
;
1998 UniataSataIdentifyPM(chan
);
2000 KdPrint((" no PM supported (1 lun/chan)\n"));
2004 KdPrint((" ATAPI dev\n"));
2005 chan
->lun
[0]->DeviceFlags
|= (DFLAGS_ATAPI_DEVICE
| DFLAGS_DEVICE_PRESENT
);
2008 default: /* SOS XXX */
2009 KdPrint((" default to ATA ???\n"));
2010 chan
->lun
[0]->DeviceFlags
|= DFLAGS_DEVICE_PRESENT
;
2016 } // end UniataAhciReset()
2026 KdPrint2(("UniataAhciStartFR: lChan %d\n", chan
->lChannel
));
2028 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2029 KdPrint2((" CMD %#x\n", CMD
));
2030 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, CMD
| ATA_AHCI_P_CMD_FRE
);
2031 UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
); /* flush */
2034 } // end UniataAhciStartFR()
2045 KdPrint2(("UniataAhciStopFR: lChan %d\n", chan
->lChannel
));
2047 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2048 KdPrint2((" CMD %#x\n", CMD
));
2049 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, CMD
& ~ATA_AHCI_P_CMD_FRE
);
2051 for(i
=0; i
<1000; i
++) {
2052 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2053 if(!(CMD
& ATA_AHCI_P_CMD_FR
)) {
2054 KdPrint2((" final CMD %#x\n", CMD
));
2057 AtapiStallExecution(1000);
2059 KdPrint2((" CMD %#x\n", CMD
));
2060 KdPrint((" SError %#x\n", AtapiReadPort4(chan
, IDX_SATA_SError
)));
2061 KdPrint2(("UniataAhciStopFR: timeout\n"));
2063 } // end UniataAhciStopFR()
2072 SATA_SERROR_REG SError
;
2074 KdPrint2(("UniataAhciStart: lChan %d\n", chan
->lChannel
));
2076 /* clear SATA error register */
2077 SError
.Reg
= AtapiReadPort4(chan
, IDX_SATA_SError
);
2079 /* clear any interrupts pending on this channel */
2080 IS
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_IS
);
2081 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IS
, IS
);
2083 KdPrint2((" SError %#x, IS %#x\n", SError
.Reg
, IS
));
2085 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2086 KdPrint2((" CMD %#x\n", CMD
));
2087 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
,
2090 ((chan
->ChannelCtrlFlags
& CTRFLAGS_AHCI_PM
) ? ATA_AHCI_P_CMD_PMA
: 0));
2091 UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
); /* flush */
2094 } // end UniataAhciStart()
2102 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2103 //PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
2105 //SATA_SERROR_REG SError;
2108 KdPrint2(("UniataAhciCLO: lChan %d\n", chan
->lChannel
));
2110 /* issue Command List Override if supported */
2111 //CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
2112 CAP
= chan
->DeviceExtension
->AHCI_CAP
;
2113 if(!(CAP
& AHCI_CAP_SCLO
)) {
2116 KdPrint2((" send CLO\n"));
2117 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2118 CMD
|= ATA_AHCI_P_CMD_CLO
;
2119 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, CMD
);
2121 for(i
=0; i
<1000; i
++) {
2122 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2123 if(!(CMD
& ATA_AHCI_P_CMD_CLO
)) {
2124 KdPrint2((" final CMD %#x\n", CMD
));
2127 AtapiStallExecution(1000);
2129 KdPrint2((" CMD %#x\n", CMD
));
2130 KdPrint2(("UniataAhciCLO: timeout\n"));
2132 } // end UniataAhciCLO()
2141 //SATA_SERROR_REG SError;
2144 KdPrint2(("UniataAhciStop: lChan %d\n", chan
->lChannel
));
2146 /* issue Command List Override if supported */
2147 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2148 CMD
&= ~ATA_AHCI_P_CMD_ST
;
2149 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, CMD
);
2151 for(i
=0; i
<1000; i
++) {
2152 CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2153 if(!(CMD
& ATA_AHCI_P_CMD_CR
)) {
2154 KdPrint2((" final CMD %#x\n", CMD
));
2157 AtapiStallExecution(1000);
2159 KdPrint2((" CMD %#x\n", CMD
));
2160 KdPrint((" SError %#x\n", AtapiReadPort4(chan
, IDX_SATA_SError
)));
2161 KdPrint2(("UniataAhciStop: timeout\n"));
2163 } // end UniataAhciStop()
2167 UniataAhciBeginTransaction(
2168 IN PVOID HwDeviceExtension
,
2170 IN ULONG DeviceNumber
,
2171 IN PSCSI_REQUEST_BLOCK Srb
2174 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2175 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
2176 //ULONG Channel = deviceExtension->Channel + lChannel;
2180 PATA_REQ AtaReq
= (PATA_REQ
)(Srb
->SrbExtension
);
2181 //SATA_SSTATUS_REG SStatus;
2182 //SATA_SERROR_REG SError;
2183 //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
2188 PIDE_AHCI_CMD_LIST AHCI_CL
= &(chan
->AhciCtlBlock
->cmd_list
[tag
]);
2190 KdPrint2(("UniataAhciBeginTransaction: lChan %d, AtaReq %#x\n", chan
->lChannel
, AtaReq
));
2192 if(Srb
->DataTransferLength
&& (!AtaReq
->dma_entries
|| AtaReq
->dma_entries
>= (USHORT
)0xffff)) {
2193 KdPrint2(("UniataAhciBeginTransaction wrong DMA tab len %x\n", AtaReq
->dma_entries
));
2197 AHCI_CL
->prd_length
= (USHORT
)(AtaReq
->dma_entries
);
2198 AHCI_CL
->cmd_flags
= AtaReq
->ahci
.io_cmd_flags
;
2199 AHCI_CL
->bytecount
= 0;
2200 if(AtaReq
->ahci
.ahci_base64
) {
2201 KdPrint2((PRINT_PREFIX
" AHCI AtaReq CMD %#x (ph %#x)\n", AtaReq
->ahci
.ahci_cmd_ptr
, (ULONG
)(AtaReq
->ahci
.ahci_base64
)));
2202 AHCI_CL
->cmd_table_phys
= AtaReq
->ahci
.ahci_base64
;
2204 if(AtaReq
->ahci
.ahci_cmd_ptr
) {
2205 KdPrint2((PRINT_PREFIX
" AHCI AtaReq->Chan CMD %#x (ph %#x) -> %#x (ph %#x)\n",
2206 AtaReq
->ahci
.ahci_cmd_ptr
, (ULONG
)(AtaReq
->ahci
.ahci_base64
),
2207 &(chan
->AhciCtlBlock
->cmd
), chan
->AHCI_CTL_PhAddr
+ FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK
, cmd
) ));
2208 RtlCopyMemory(&(chan
->AhciCtlBlock
->cmd
), AtaReq
->ahci
.ahci_cmd_ptr
,
2209 FIELD_OFFSET(IDE_AHCI_CMD
, prd_tab
)+AHCI_CL
->prd_length
*sizeof(IDE_AHCI_PRD_ENTRY
));
2210 AHCI_CL
->cmd_table_phys
= chan
->AHCI_CTL_PhAddr
+ FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK
, cmd
);
2212 KdPrint2((PRINT_PREFIX
" no AHCI CMD\n"));
2213 //AHCI_CL->cmd_table_phys = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, cmd);
2216 if(AHCI_CL
->cmd_table_phys
& AHCI_CMD_ALIGNEMENT_MASK
) {
2217 KdPrint2((PRINT_PREFIX
" AHCI CMD address is not aligned (mask %#x)\n", (ULONG
)AHCI_CMD_ALIGNEMENT_MASK
));
2222 KdPrint2((" prd_length %#x, flags %#x, base %I64x\n", AHCI_CL
->prd_length
, AHCI_CL
->cmd_flags
,
2223 AHCI_CL
->cmd_table_phys
));
2226 CMD0
= CMD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
);
2227 KdPrint2((" CMD %#x\n", CMD
));
2228 // switch controller to ATAPI mode for ATA_PACKET commands only
2229 if(ATAPI_DEVICE(chan
, DeviceNumber
) &&
2230 AtaReq
->ahci
.ahci_cmd_ptr
->cfis
[2] == IDE_COMMAND_ATAPI_PACKET
) {
2231 KdPrint2((" ATAPI\n"));
2232 CMD
|= ATA_AHCI_P_CMD_ATAPI
;
2233 KdDump(&(AtaReq
->ahci
.ahci_cmd_ptr
->acmd
), 16);
2235 CMD
&= ~ATA_AHCI_P_CMD_ATAPI
;
2238 KdPrint2((" send CMD %#x, entries %#x\n", CMD
, AHCI_CL
->prd_length
));
2239 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, CMD
);
2240 UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
); /* flush */
2243 /* issue command to controller */
2244 //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag);
2245 KdPrint2((" Set CI\n"));
2246 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CI
, 0x01 << tag
);
2247 chan
->AhciPrevCI
|= 0x01 << tag
;
2250 CMD
|= ATA_AHCI_P_CMD_ST
|
2251 ((chan
->ChannelCtrlFlags
& CTRFLAGS_AHCI_PM
) ? ATA_AHCI_P_CMD_PMA
: 0);
2253 KdPrint2((" Send CMD START\n"));
2254 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, CMD
);
2255 UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
); /* flush */
2257 KdPrint2((" No CMD START, already active\n"));
2260 if(!ATAPI_DEVICE(chan
, DeviceNumber
)) {
2261 // TODO: check if we send ATAPI_RESET and wait for ready of so.
2262 if(AtaReq
->ahci
.ahci_cmd_ptr
->cfis
[2] == IDE_COMMAND_ATAPI_RESET
) {
2266 for(i
=0; i
<1000000; i
++) {
2267 TFD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_TFD
);
2268 if(!(TFD
& IDE_STATUS_BUSY
)) {
2272 if(TFD
& IDE_STATUS_BUSY
) {
2273 KdPrint2((" timeout\n"));
2275 if(TFD
& IDE_STATUS_ERROR
) {
2276 KdPrint2((" ERROR %#x\n", (UCHAR
)(TFD
>> 8)));
2278 AtaReq
->ahci
.in_status
= TFD
;
2280 return IDE_STATUS_SUCCESS
;
2284 return IDE_STATUS_IDLE
;
2286 } // end UniataAhciBeginTransaction()
2290 UniataAhciEndTransaction(
2291 IN PVOID HwDeviceExtension
,
2293 IN ULONG DeviceNumber
,
2294 IN PSCSI_REQUEST_BLOCK Srb
2297 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2298 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
2299 //ULONG Channel = deviceExtension->Channel + lChannel;
2302 PATA_REQ AtaReq
= (PATA_REQ
)(Srb
->SrbExtension
);
2304 PUCHAR RCV_FIS
= &(chan
->AhciCtlBlock
->rcv_fis
.rfis
[0]);
2307 PIDE_AHCI_CMD_LIST AHCI_CL
= &(chan
->AhciCtlBlock
->cmd_list
[tag
]);
2308 //PHW_LU_EXTENSION LunExt;
2310 KdPrint2(("UniataAhciEndTransaction: lChan %d\n", chan
->lChannel
));
2312 //LunExt = chan->lun[DeviceNumber];
2314 TFD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_TFD
);
2315 KdPrint2((" TFD %#x\n", TFD
));
2317 if(TFD
& IDE_STATUS_ERROR
) {
2318 AtaReq
->ahci
.in_error
= (UCHAR
)(TFD
>> 8);
2319 KdPrint2((" ERROR %#x\n", AtaReq
->ahci
.in_error
));
2321 AtaReq
->ahci
.in_error
= 0;
2323 AtaReq
->ahci
.in_status
= TFD
;
2325 //if (request->flags & ATA_R_CONTROL) {
2327 AtaReq
->ahci
.in_bcount
= (ULONG
)(RCV_FIS
[12]) | ((ULONG
)(RCV_FIS
[13]) << 8);
2328 AtaReq
->ahci
.in_lba
= (ULONG
)(RCV_FIS
[4]) | ((ULONGLONG
)(RCV_FIS
[5]) << 8) |
2329 ((ULONGLONG
)(RCV_FIS
[6]) << 16);
2330 if(chan
->ChannelCtrlFlags
& CTRFLAGS_LBA48
) {
2331 AtaReq
->ahci
.in_lba
|= ((ULONGLONG
)(RCV_FIS
[8]) << 24) |
2332 ((ULONGLONG
)(RCV_FIS
[9]) << 32) |
2333 ((ULONGLONG
)(RCV_FIS
[10]) << 40);
2335 AtaReq
->ahci
.in_lba
|= ((ULONGLONG
)(RCV_FIS
[8]) << 24) |
2336 ((ULONGLONG
)(RCV_FIS
[9]) << 32) |
2337 ((ULONGLONG
)(RCV_FIS
[7] & 0x0f) << 24);
2339 AtaReq
->WordsTransfered
= AHCI_CL
->bytecount
/2;
2342 if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
2343 KdPrint2(("RCV:\n"));
2344 KdDump(RCV_FIS, 24);
2345 KdPrint2(("PIO:\n"));
2346 KdDump(&(chan->AhciCtlBlock->rcv_fis.psfis[0]), 24);
2348 KdPrint2(("len: %d vs %d\n", AHCI_CL->bytecount, (ULONG)RCV_FIS[5] | ((ULONG)RCV_FIS[6] << 8) ));
2349 if(!AHCI_CL->bytecount) {
2350 AtaReq->WordsTransfered = ((ULONG)RCV_FIS[5] | ((ULONG)RCV_FIS[6] << 8)) / 2;
2354 ACT
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_ACT
);
2355 CI
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CI
);
2356 if(CI
& (1 << tag
)) {
2358 KdPrint2((" Incomplete command, CI %#x, ACT %#x\n", CI
, ACT
));
2359 KdPrint2((" FIS status %#x, error %#x\n", RCV_FIS
[2], RCV_FIS
[3]));
2362 UniataDumpAhciPortRegs(chan
);
2364 if(!UniataAhciAbortOperation(chan
)) {
2365 KdPrint2((" Abort failed, need RESET\n"));
2368 UniataDumpAhciPortRegs(chan
);
2370 chan
->AhciPrevCI
= CI
& ~((ULONG
)1 << tag
);
2371 if(chan
->AhciPrevCI
) {
2372 KdPrint2((" Need command list restart, CI %#x\n", chan
->AhciPrevCI
));
2375 chan
->AhciPrevCI
&= ~((ULONG
)1 << tag
);
2376 RtlZeroMemory(AHCI_CL
, sizeof(IDE_AHCI_CMD_LIST
));
2382 } // end UniataAhciEndTransaction()
2392 KdPrint2(("UniataAhciResume: lChan %d\n", chan
->lChannel
));
2395 //UniataDumpAhciPortRegs(chan);
2398 /* Disable port interrupts */
2399 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IE
, 0);
2401 /* setup work areas */
2402 base
= chan
->AHCI_CTL_PhAddr
;
2404 KdPrint2((PRINT_PREFIX
" AHCI buffer allocation failed\n"));
2407 KdPrint2((PRINT_PREFIX
" AHCI CLB setup\n"));
2408 if(base
& AHCI_CLB_ALIGNEMENT_MASK
) {
2409 KdPrint2((PRINT_PREFIX
" AHCI CLB address is not aligned (mask %#x)\n", (ULONG
)AHCI_FIS_ALIGNEMENT_MASK
));
2411 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CLB
,
2412 (ULONG
)(base
& 0xffffffff));
2413 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CLB
+ 4,
2414 (ULONG
)((base
>> 32) & 0xffffffff));
2416 KdPrint2((PRINT_PREFIX
" AHCI RCV FIS setup\n"));
2417 base
= chan
->AHCI_CTL_PhAddr
+ FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK
, rcv_fis
);
2418 if(base
& AHCI_FIS_ALIGNEMENT_MASK
) {
2419 KdPrint2((PRINT_PREFIX
" AHCI FIS address is not aligned (mask %#x)\n", (ULONG
)AHCI_FIS_ALIGNEMENT_MASK
));
2421 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_FB
,
2422 (ULONG
)(base
& 0xffffffff));
2423 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_FB
+ 4,
2424 (ULONG
)((base
>> 32) & 0xffffffff));
2426 /* activate the channel and power/spin up device */
2427 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
,
2428 (ATA_AHCI_P_CMD_ACTIVE
| ATA_AHCI_P_CMD_POD
| ATA_AHCI_P_CMD_SUD
|
2429 (((chan
->ChannelCtrlFlags
& CTRFLAGS_AHCI_PM
)) ? ATA_AHCI_P_CMD_ALPE
: 0) |
2430 (((chan
->ChannelCtrlFlags
& CTRFLAGS_AHCI_PM2
)) ? ATA_AHCI_P_CMD_ASP
: 0 ))
2432 UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
); /* flush */
2435 //UniataDumpAhciPortRegs(chan);
2438 UniataAhciStartFR(chan
);
2439 UniataAhciStart(chan
);
2442 UniataDumpAhciPortRegs(chan
);
2446 } // end UniataAhciResume()
2456 SATA_SCONTROL_REG SControl
;
2458 KdPrint2(("UniataAhciSuspend:\n"));
2460 /* Disable port interrupts */
2461 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_IE
, 0);
2463 /* Reset command register. */
2464 UniataAhciStop(chan
);
2465 UniataAhciStopFR(chan
);
2466 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, 0);
2467 UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_CMD
); /* flush */
2469 /* Allow everything including partial and slumber modes. */
2470 UniataSataWritePort4(chan
, IDX_SATA_SControl
, 0, 0);
2472 /* Request slumber mode transition and give some time to get there. */
2473 UniataAhciWriteChannelPort4(chan
, IDX_AHCI_P_CMD
, ATA_AHCI_P_CMD_SLUMBER
);
2474 AtapiStallExecution(100);
2478 SControl
.DET
= SStatus_DET_Offline
;
2479 UniataSataWritePort4(chan
, IDX_SATA_SControl
, SControl
.Reg
, 0);
2482 } // end UniataAhciSuspend()
2488 IN PHW_CHANNEL chan
,
2489 IN ULONG DeviceNumber
,
2494 //ULONG Channel = deviceExtension->Channel + lChannel;
2499 PIDE_AHCI_CMD AHCI_CMD
= &(chan
->AhciCtlBlock
->cmd
);
2500 PUCHAR RCV_FIS
= &(chan
->AhciCtlBlock
->rcv_fis
.rfis
[0]);
2502 KdPrint(("UniataAhciReadPM: lChan %d [%#x]\n", chan
->lChannel
, DeviceNumber
));
2504 if(DeviceNumber
== DEVNUM_NOT_SPECIFIED
) {
2505 (*result
) = UniataSataReadPort4(chan
, Reg
, 0);
2508 if(DeviceNumber
< AHCI_DEV_SEL_PM
) {
2510 case IDX_SATA_SStatus
:
2512 case IDX_SATA_SError
:
2514 case IDX_SATA_SControl
:
2521 RtlZeroMemory(AHCI_CMD
->cfis
, sizeof(AHCI_CMD
->cfis
));
2522 AHCI_CMD
->cfis
[0] = AHCI_FIS_TYPE_ATA_H2D
;
2523 AHCI_CMD
->cfis
[1] = AHCI_FIS_COMM_PM
;
2524 AHCI_CMD
->cfis
[2] = IDE_COMMAND_READ_PM
;
2525 AHCI_CMD
->cfis
[3] = (UCHAR
)Reg
;
2526 AHCI_CMD
->cfis
[7] = (UCHAR
)(IDE_USE_LBA
| DeviceNumber
);
2527 AHCI_CMD
->cfis
[15] = IDE_DC_A_4BIT
;
2529 if(UniataAhciSendCommand(chan
->DeviceExtension
, chan
->lChannel
, DeviceNumber
, 0, 10) == IDE_STATUS_WRONG
) {
2530 KdPrint2((" PM read failed\n"));
2534 KdDump(RCV_FIS
, sizeof(chan
->AhciCtlBlock
->rcv_fis
.rfis
));
2536 (*result
) = UniataAhciUlongFromRFIS(RCV_FIS
);
2539 } // end UniataAhciReadPM()
2544 IN PHW_CHANNEL chan
,
2545 IN ULONG DeviceNumber
,
2550 //ULONG Channel = deviceExtension->Channel + lChannel;
2556 PIDE_AHCI_CMD AHCI_CMD
= &(chan
->AhciCtlBlock
->cmd
);
2557 //PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
2559 KdPrint(("UniataAhciWritePM: lChan %d [%#x] %#x\n", chan
->lChannel
, DeviceNumber
, value
));
2561 if(DeviceNumber
== DEVNUM_NOT_SPECIFIED
) {
2562 UniataSataWritePort4(chan
, Reg
, value
, 0);
2565 if(DeviceNumber
< AHCI_DEV_SEL_PM
) {
2567 case IDX_SATA_SStatus
:
2569 case IDX_SATA_SError
:
2571 case IDX_SATA_SControl
:
2574 return IDE_STATUS_WRONG
;
2578 RtlZeroMemory(AHCI_CMD
->cfis
, sizeof(AHCI_CMD
->cfis
));
2579 AHCI_CMD
->cfis
[0] = AHCI_FIS_TYPE_ATA_H2D
;
2580 AHCI_CMD
->cfis
[1] = AHCI_FIS_COMM_PM
;
2581 AHCI_CMD
->cfis
[2] = IDE_COMMAND_WRITE_PM
;
2582 AHCI_CMD
->cfis
[3] = (UCHAR
)Reg
;
2583 AHCI_CMD
->cfis
[7] = (UCHAR
)(IDE_USE_LBA
| DeviceNumber
);
2585 AHCI_CMD
->cfis
[12] = (UCHAR
)(value
& 0xff);
2586 AHCI_CMD
->cfis
[4] = (UCHAR
)((value
>> 8) & 0xff);
2587 AHCI_CMD
->cfis
[5] = (UCHAR
)((value
>> 16) & 0xff);
2588 AHCI_CMD
->cfis
[6] = (UCHAR
)((value
>> 24) & 0xff);
2590 AHCI_CMD
->cfis
[15] = IDE_DC_A_4BIT
;
2592 if(UniataAhciSendCommand(chan
->DeviceExtension
, chan
->lChannel
, DeviceNumber
, 0, 100) == IDE_STATUS_WRONG
) {
2593 KdPrint2((" PM write failed\n"));
2594 return IDE_STATUS_WRONG
;
2597 TFD
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_TFD
);
2599 if(TFD
& IDE_STATUS_ERROR
) {
2600 KdPrint2((" ERROR %#x\n", (UCHAR
)(TFD
>> 8)));
2602 return (UCHAR
)(TFD
>> 8);
2604 } // end UniataAhciWritePM()
2607 UniataAhciSetupCmdPtr(
2608 IN OUT PATA_REQ AtaReq
2613 ULONGLONG prd_base64
;
2617 ULONGLONG prd_base64_0
;
2623 prd_base64_0
= prd_base64
= 0;
2624 prd_base
= (PUCHAR
)(&AtaReq
->ahci_cmd0
);
2625 prd_base0
= prd_base
;
2627 prd_base64
= (prd_base64
+ max(FIELD_OFFSET(ATA_REQ
, ahci_cmd0
), AHCI_CMD_ALIGNEMENT_MASK
+1)) & ~AHCI_CMD_ALIGNEMENT_MASK
;
2630 d
= (ULONG
)(prd_base64
- prd_base64_0
);
2631 KdPrint2((PRINT_PREFIX
" AtaReq %#x: cmd aligned %I64x, d=%x\n", AtaReq
, prd_base64
, d
));
2634 AtaReq
->ahci
.ahci_cmd_ptr
= (PIDE_AHCI_CMD
)prd_base64
;
2635 KdPrint2((PRINT_PREFIX
" ahci_cmd_ptr %#x\n", AtaReq
->ahci
.ahci_cmd_ptr
));
2636 } // end UniataAhciSetupCmdPtr()
2640 BuildAhciInternalSrb (
2641 IN PVOID HwDeviceExtension
,
2642 IN ULONG DeviceNumber
,
2648 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2649 PHW_CHANNEL chan
= &deviceExtension
->chan
[lChannel
];
2650 PSCSI_REQUEST_BLOCK srb
;
2652 PATA_REQ AtaReq
= chan
->AhciInternalAtaReq
;
2654 KdPrint(("BuildAhciInternalSrb: lChan %d [%#x]\n", lChannel
, DeviceNumber
));
2657 KdPrint2((PRINT_PREFIX
" !chan->AhciInternalAtaReq\n"));
2661 //RtlZeroMemory((PCHAR) AtaReq, sizeof(ATA_REQ));
2662 //RtlZeroMemory((PCHAR) AtaReq, FIELD_OFFSET(ATA_REQ, ahci));
2663 UniAtaClearAtaReq(AtaReq
);
2665 srb
= chan
->AhciInternalSrb
;
2667 RtlZeroMemory((PCHAR
) srb
, sizeof(SCSI_REQUEST_BLOCK
));
2669 srb
->PathId
= (UCHAR
)lChannel
;
2670 srb
->TargetId
= (UCHAR
)DeviceNumber
;
2671 srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
2672 srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
2674 // Set flags to disable synchronous negociation.
2675 //srb->SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
2677 // Set timeout to 4 seconds.
2678 srb
->TimeOutValue
= 4;
2681 srb
->DataBuffer
= Buffer
;
2682 srb
->DataTransferLength
= Length
;
2683 srb
->SrbExtension
= AtaReq
;
2686 AtaReq
->DataBuffer
= (PUSHORT
)Buffer
;
2687 AtaReq
->TransferLength
= Length
;
2689 //if(!AtaReq->ahci.ahci_cmd_ptr) {
2690 //UniataAhciSetupCmdPtr(AtaReq);
2691 //AtaReq->ahci.ahci_cmd_ptr = &(chan->AhciCtlBlock->cmd);
2692 //AtaReq->ahci.ahci_base64 = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, cmd);
2694 //AtaReq->ahci.ahci_cmd_ptr = &(AtaReq->ahci_cmd0);
2695 //AtaReq->ahci.ahci_base64 = NULL; // indicate that we should copy command to proper place
2697 KdPrint2((PRINT_PREFIX
" Srb %#x, AtaReq %#x, CMD %#x ph %I64x\n", srb
, AtaReq
,
2698 AtaReq
->ahci
.ahci_cmd_ptr
, AtaReq
->ahci
.ahci_base64
));
2700 /* // Set CDB operation code.
2701 cdb = (PCDB)srb->Cdb;
2702 cdb->CDB6INQUIRY.OperationCode = SCSIOP_REQUEST_SENSE;
2703 cdb->CDB6INQUIRY.AllocationLength = sizeof(SENSE_DATA);
2706 } // end BuildAhciInternalSrb()