ReactOS 0.4.15-dev-5895-g2687c1b
id_sata.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) 2008-2019 Alexandr A. Telyatnikov (Alter)
4
5Module Name:
6 id_probe.cpp
7
8Abstract:
9 This module handles SATA- and AHCI-related staff
10
11Author:
12 Alexander A. Telyatnikov (Alter)
13
14Environment:
15 kernel mode only
16
17Notes:
18
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30Revision History:
31
32 SATA support
33 AHCI support
34
35Licence:
36 GPLv2
37
38--*/
39
40#include "stdafx.h"
41
45 IN PVOID HwDeviceExtension,
46 IN ULONG lChannel, // logical channel
47 IN ULONG pm_port /* for port multipliers */
48 )
49{
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;
54 ULONG i;
55/*
56 UCHAR signatureLow,
57 signatureHigh;
58*/
60
61 KdPrint2((PRINT_PREFIX "UniataSataConnect:\n"));
62
63 if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
64 KdPrint2((PRINT_PREFIX " no I/O range\n"));
65 return IDE_STATUS_IDLE;
66 }
67
68 /* clear SATA error register, some controllers need this */
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);
84
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;
89 }
90 if(deviceExtension->MaxTransferMode < chan->lun[0]->TransferMode) {
91 KdPrint2((PRINT_PREFIX "SATA upd controller TransferMode\n"));
92 deviceExtension->MaxTransferMode = chan->lun[0]->TransferMode;
93 }
94
95 break;
96 }
98 }
99 if(i >= 100) {
100 KdPrint2((PRINT_PREFIX "UniataSataConnect: SStatus %8.8x\n", SStatus.Reg));
101 return IDE_STATUS_WRONG;
102 }
103 /* clear SATA error register */
105 UniataSataReadPort4(chan, IDX_SATA_SError, pm_port), pm_port);
106
108 if(Status & IDE_STATUS_BUSY) {
109 return Status;
110 }
111/*
112 signatureLow = AtapiReadPort1(chan, &deviceExtension->BaseIoAddress1[lChannel].i.CylinderLow);
113 signatureHigh = AtapiReadPort1(chan, &deviceExtension->baseIoAddress1[lChannel].i.CylinderHigh);
114
115 if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) {
116 }
117*/
118 KdPrint2((PRINT_PREFIX "UniataSataConnect: OK, ATA status %#x\n", Status));
119 return IDE_STATUS_IDLE;
120} // end UniataSataConnect()
121
122UCHAR
123NTAPI
125 IN PVOID HwDeviceExtension,
126 IN ULONG lChannel, // logical channel
127 IN ULONG pm_port, /* for port multipliers */
128 IN BOOLEAN doReset
129 )
130{
131 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
132 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
133 SATA_SCONTROL_REG SControl;
134 int loop, retry;
135
136 KdPrint2((PRINT_PREFIX "UniataSataPhyEnable:\n"));
137
138 if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
139 KdPrint2((PRINT_PREFIX " no I/O range\n"));
140 return IDE_STATUS_IDLE;
141 }
142
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) {
146 if(!doReset) {
147 return UniataSataConnect(HwDeviceExtension, lChannel, pm_port);
148 }
149 }
150
151 for (retry = 0; retry < 10; retry++) {
152 KdPrint2((PRINT_PREFIX "UniataSataPhyEnable: retry init %d\n", retry));
153 for (loop = 0; loop < 10; loop++) {
154 SControl.Reg = 0;
155 SControl.DET = SControl_DET_Init;
156 UniataSataWritePort4(chan, IDX_SATA_SControl, SControl.Reg, pm_port);
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) {
161 break;
162 }
163 }
165 KdPrint2((PRINT_PREFIX "UniataSataPhyEnable: retry idle %d\n", retry));
166 for (loop = 0; loop < 10; loop++) {
167 SControl.Reg = 0;
168 SControl.DET = SControl_DET_DoNothing;
170 UniataSataWritePort4(chan, IDX_SATA_SControl, SControl.Reg, pm_port);
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);
176 }
177 }
178 }
179
180 KdPrint2((PRINT_PREFIX "UniataSataPhyEnable: failed\n"));
181 return IDE_STATUS_WRONG;
182} // end UniataSataPhyEnable()
183
185NTAPI
187 IN PVOID HwDeviceExtension,
188 IN ULONG lChannel, // logical channel
189 IN BOOLEAN do_connect,
190 IN ULONG pm_port /* for port multipliers */
191 )
192{
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;
198
199 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
200 //if(ChipFlags & UNIATA_SATA) {
201
202 SStatus.Reg = UniataSataReadPort4(chan, IDX_SATA_SStatus, pm_port);
203 SError.Reg = UniataSataReadPort4(chan, IDX_SATA_SError, pm_port);
204
205 if(SStatus.Reg) {
206 KdPrint2((PRINT_PREFIX " SStatus %#x\n", SStatus.Reg));
207 }
208 if(SError.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);
212
213 if(do_connect) {
214 /* if we have a connection event deal with it */
215 if(SError.DIAG.N) {
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);
219 } else {
220 UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH, pm_port);
221 }
222 return TRUE;
223 }
224 }
225 //return TRUE;
226 }
227 }
228 return FALSE;
229} // end UniataSataClearErr()
230
232NTAPI
234 IN PVOID HwDeviceExtension,
235 IN ULONG lChannel, // logical channel
237 IN ULONG pm_port /* for port multipliers */
238 )
239{
240 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
242 ULONG DeviceNumber = (pm_port ? 1 : 0);
243
244 if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
245 return FALSE;
246 }
247
248 switch(Action) {
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) {
254 return FALSE;
255 }
256 CheckDevice(HwDeviceExtension, lChannel, DeviceNumber /*dev*/, FALSE);
257 return TRUE;
258 break;
260 KdPrint2((PRINT_PREFIX " DISCONNECTED\n"));
261 UniataForgetDevice(deviceExtension->chan[lChannel].lun[DeviceNumber]);
262 return TRUE;
263 break;
264 }
265 return FALSE;
266} // end UniataSataEvent()
267
268ULONG
269NTAPI
271 IN PHW_CHANNEL chan,
272 IN ULONG io_port_ndx,
273 IN ULONG pm_port /* for port multipliers */
274 )
275{
276 if(chan && (io_port_ndx < IDX_MAX_REG) &&
277 chan->RegTranslation[io_port_ndx].Proc) {
278
279 KdPrint3((PRINT_PREFIX " UniataSataReadPort4 %#x[%d]\n", io_port_ndx, pm_port));
280
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;
286 ULONG offs;
287 ULONG p;
288
289 switch(VendorID) {
290 case ATA_INTEL_ID: {
291 p = pm_port ? 1 : 0;
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:
297 offs += 0;
298 break;
299 case IDX_SATA_SError:
300 offs += 1*4;
301 break;
303 offs += 2*4;
304 break;
305 default:
306 return -1;
307 }
308 SetPciConfig4(0xa0, offs);
309 GetPciConfig4(0xa4, offs);
310 return offs;
311 } else
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;
318 break;
319 case IDX_SATA_SError:
320 offs += IDX_AHCI_P_SError;
321 break;
323 offs += IDX_AHCI_P_SControl;
324 break;
325 default:
326 return -1;
327 }
328 return AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), offs);
329 } else {
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:
334 offs += 0;
335 break;
337 offs += 1;
338 break;
339 case IDX_SATA_SError:
340 offs += 2;
341 break;
342 default:
343 return -1;
344 }
346 return AtapiReadPort4(chan, IDX_INDEXED_DATA);
347 }
348 } // ATA_INTEL_ID
349 } // end switch(VendorID)
350 return -1;
351 }
352 return AtapiReadPort4(chan, io_port_ndx);
353} // end UniataSataReadPort4()
354
355VOID
356NTAPI
358 IN PHW_CHANNEL chan,
359 IN ULONG io_port_ndx,
360 IN ULONG data,
361 IN ULONG pm_port /* for port multipliers */
362 )
363{
364 if(chan && (io_port_ndx < IDX_MAX_REG) &&
365 chan->RegTranslation[io_port_ndx].Proc) {
366
367 KdPrint3((PRINT_PREFIX " UniataSataWritePort4 %#x[%d]\n", io_port_ndx, pm_port));
368
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;
374 ULONG offs;
375 ULONG p;
376
377 switch(VendorID) {
378 case ATA_INTEL_ID: {
379 p = pm_port ? 1 : 0;
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:
385 offs += 0;
386 break;
387 case IDX_SATA_SError:
388 offs += 1*4;
389 break;
391 offs += 2*4;
392 break;
393 default:
394 return;
395 }
396 SetPciConfig4(0xa0, offs);
397 SetPciConfig4(0xa4, data);
398 return;
399 } else
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;
406 break;
407 case IDX_SATA_SError:
408 offs += IDX_AHCI_P_SError;
409 break;
411 offs += IDX_AHCI_P_SControl;
412 break;
413 default:
414 return;
415 }
416 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), offs, data);
417 return;
418 } else {
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:
423 offs += 0;
424 break;
426 offs += 1;
427 break;
428 case IDX_SATA_SError:
429 offs += 2;
430 break;
431 default:
432 return;
433 }
436 }
437 } // ATA_INTEL_ID
438 } // end switch(VendorID)
439 return;
440 }
441 AtapiWritePort4(chan, io_port_ndx, data);
442} // end UniataSataWritePort4()
443
445NTAPI
447 IN PHW_CHANNEL chan,
449 IN ULONG Reg,
451 )
452{
453 if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
454 return UniataAhciReadPM(chan, DeviceNumber, Reg, result);
455 }
456 return FALSE;
457} // end UniataSataReadPM()
458
459UCHAR
460NTAPI
462 IN PHW_CHANNEL chan,
464 IN ULONG Reg,
466 )
467{
468 if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
469 return UniataAhciWritePM(chan, DeviceNumber, Reg, value);
470 }
471 return IDE_STATUS_WRONG;
472} // end UniataSataWritePM()
473
474ULONG
475NTAPI
477 IN PVOID HwDeviceExtension,
478 IN ULONG lChannel,
480 )
481{
482 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
483
484 if(deviceExtension->HwFlags & UNIATA_AHCI) {
485 return UniataAhciSoftReset(HwDeviceExtension, lChannel, DeviceNumber);
486 }
487 return 0xffffffff;
488} // end UniataSataSoftReset()
489
490VOID
492 IN PHW_CHANNEL chan
493 )
494{
495 ULONG PM_DeviceId;
496 ULONG PM_RevId;
497 ULONG PM_Ports;
498 UCHAR i;
499 ULONG signature;
500 PHW_LU_EXTENSION LunExt;
501
502 KdPrint((PRINT_PREFIX "UniataSataIdentifyPM:\n"));
503
504 chan->PmLunMap = 0;
505
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"));
509 return;
510 }
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"));
514 return;
515 }
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"));
519 return;
520 }
521
522 PM_Ports &= 0x0000000f;
523
524 switch(PM_DeviceId) {
525 case 0x37261095:
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));
531 PM_Ports = 5;
532 break;
533 case 0x47261095:
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));
541 PM_Ports = 5;
542 break;
543 default:
544 KdPrint2((PRINT_PREFIX " Port Multiplier (id=%08x rev=%#x) with %d ports\n",
545 PM_DeviceId, PM_RevId, PM_Ports));
546 break;
547 }
548
549 // reset
550 for(i=0; i<PM_Ports; i++) {
551
552 LunExt = chan->lun[i];
553
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;
557 continue;
558 }
559 /*
560 * XXX: I have no idea how to properly wait for PMP port hardreset
561 * completion. Without this delay soft reset does not completes
562 * successfully.
563 */
564 AtapiStallExecution(1000000);
565
566 signature = UniataSataSoftReset(chan->DeviceExtension, chan->lChannel, i);
567 KdPrint2((PRINT_PREFIX " signature %#x\n", signature));
568
570 chan->PmLunMap |= (1 << i);
571 /* figure out whats there */
572 switch (signature >> 16) {
573 case 0x0000:
574 LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE;
575 continue;
576 case 0xeb14:
578 continue;
579 }
580
581 }
582
583} // end UniataSataIdentifyPM()
584
585#ifdef _DEBUG
586VOID
587NTAPI
588UniataDumpAhciRegs(
589 IN PHW_DEVICE_EXTENSION deviceExtension
590 )
591{
592 ULONG j;
593 ULONG xReg;
594
596 " AHCI Base: %#x MemIo %d Proc %d\n",
597 deviceExtension->BaseIoAHCI_0.Addr,
598 deviceExtension->BaseIoAHCI_0.MemIo,
599 deviceExtension->BaseIoAHCI_0.Proc));
600
601 for(j=0; j<=IDX_AHCI_VS; j+=sizeof(ULONG)) {
602 xReg = AtapiReadPortEx4(NULL, (ULONGIO_PTR)&deviceExtension->BaseIoAHCI_0, j);
604 " AHCI_%#x (%#x) = %#x\n",
605 j,
606 (deviceExtension->BaseIoAHCI_0.Addr+j),
607 xReg));
608 }
609 return;
610} // end UniataDumpAhciRegs()
611
612
613VOID
614NTAPI
615UniataDumpAhciPortRegs(
616 IN PHW_CHANNEL chan
617 )
618{
619 ULONG j;
620 ULONG xReg;
621
623 " AHCI port %d Base: %#x MemIo %d Proc %d\n",
624 chan->lChannel,
625 chan->BaseIoAHCI_Port.Addr,
626 chan->BaseIoAHCI_Port.MemIo,
627 chan->BaseIoAHCI_Port.Proc));
628
629 for(j=0; j<=IDX_AHCI_P_SNTF; j+=sizeof(ULONG)) {
630 xReg = AtapiReadPortEx4(NULL, (ULONGIO_PTR)&chan->BaseIoAHCI_Port, j);
632 " AHCI%d_%#x (%#x) = %#x\n",
633 chan->lChannel,
634 j,
635 (chan->BaseIoAHCI_Port.Addr+j),
636 xReg));
637 }
638 return;
639} // end UniataDumpAhciPortRegs()
640#endif //_DEBUG
641
642
644NTAPI
646 IN PVOID HwDeviceExtension
647 )
648{
649 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
650 ULONG c, i;
651 PHW_CHANNEL chan;
652 ULONG offs;
653#ifdef __REACTOS__
654 ULONG_PTR BaseMemAddress;
655#else
656 ULONG BaseMemAddress;
657#endif
658 ULONG PI;
659 ULONG CAP;
660 ULONG CAP2;
661 ULONG BOHC;
662 ULONG GHC;
663 BOOLEAN MemIo = FALSE;
664
665 KdPrint2((PRINT_PREFIX " UniataAhciInit:\n"));
666
667#ifdef _DEBUG
668 UniataDumpAhciRegs(deviceExtension);
669#endif //_DEBUG
670
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));
676 BOHC | AHCI_BOHC_OOS);
677 for(i=0; i<50; i++) {
679 BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
680 KdPrint2((PRINT_PREFIX " BOHC %#x\n", BOHC));
681 if(BOHC & AHCI_BOHC_BB) {
682 break;
683 }
684 if(!(BOHC & AHCI_BOHC_BOS)) {
685 break;
686 }
687 }
688 KdPrint2((PRINT_PREFIX " stage 2 BOHC %#x\n", BOHC));
689 if(BOHC & AHCI_BOHC_BB) {
690 for(i=0; i<2000; i++) {
692 BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
693 KdPrint2((PRINT_PREFIX " BOHC %#x\n", BOHC));
694 if(!(BOHC & AHCI_BOHC_BOS)) {
695 break;
696 }
697 }
698 }
699 KdPrint2((PRINT_PREFIX " final BOHC %#x\n", BOHC));
700 }
701
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
705 */
706
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);
714 } else {
715 KdPrint2((PRINT_PREFIX " disable intr, GHC %#x\n", GHC));
716 UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
717 GHC & ~AHCI_GHC_IE);
718 }
720
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,
725 GHC | AHCI_GHC_HR);
726
727 for(i=0; i<1000; i++) {
729 GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
730 KdPrint2((PRINT_PREFIX " AHCI GHC %#x\n", GHC));
731 if(!(GHC & AHCI_GHC_HR)) {
732 break;
733 }
734 }
735 if(GHC & AHCI_GHC_HR) {
736 KdPrint2((PRINT_PREFIX " AHCI reset failed\n"));
737 return FALSE;
738 }
739
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.
743 */
744 GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
745 for(i=0; i<5; i++) {
746 if(!(GHC & AHCI_GHC_AE)) {
747 KdPrint2((PRINT_PREFIX " re-enable AHCI mode, GHC %#x\n", GHC));
748 UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
749 GHC | AHCI_GHC_AE);
751 GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
752 } else {
753 break;
754 }
755 }
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"));
759 return FALSE;
760 }
761
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;
768 }
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"));
772 }
773 if(CAP & AHCI_CAP_SAM) {
774 KdPrint2((PRINT_PREFIX " AHCI legasy SATA\n"));
775 }
776
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));
784
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));
791 BOHC | AHCI_BOHC_OOS);
792 }
793 /* clear interrupts */
794 UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_IS,
795 UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS));
796
797 /* enable AHCI interrupts */
798 UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
800
801 BaseMemAddress = deviceExtension->BaseIoAHCI_0.Addr;
802 MemIo = deviceExtension->BaseIoAHCI_0.MemIo;
803
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) ));
806
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);
810
811 KdPrint2((PRINT_PREFIX " chan %d, offs %#x\n", c, offs));
812
813 chan->MaxTransferMode = deviceExtension->MaxTransferMode;
814
815 AtapiSetupLunPtrs(chan, deviceExtension, c);
816
817 chan->BaseIoAHCI_Port = deviceExtension->BaseIoAHCI_0;
818 chan->BaseIoAHCI_Port.Addr = BaseMemAddress + offs;
819
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;
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;
831
833
834 chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SSTS);
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);
840 chan->RegTranslation[IDX_SATA_SActive].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SACT);
842
843 AtapiDmaAlloc(HwDeviceExtension, NULL, c);
844
845 if(!UniataAhciChanImplemented(deviceExtension, c)) {
846 KdPrint2((PRINT_PREFIX " chan %d not implemented\n", c));
847 continue;
848 }
849
850 UniataAhciResume(chan);
851
853 }
854
855 return TRUE;
856} // end UniataAhciInit()
857
859NTAPI
861 IN PHW_DEVICE_EXTENSION deviceExtension,
863 IN BOOLEAN Strict
864 )
865{
866 switch(version) {
867 case 0x00000000:
868 case 0xffffffff:
869 KdPrint((" wrong AHCI revision %#x\n", version));
870 return FALSE;
871 case 0x00000905:
872 case 0x00010000:
873 case 0x00010100:
874 case 0x00010200:
875 case 0x00010300:
876 case 0x00010301:
877 break;
878 default:
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));
882 return FALSE;
883 }
884 }
885 return TRUE;
886} // end UniAtaAhciValidateVersion()
887
889NTAPI
891 IN PVOID HwDeviceExtension,
892 IN PPCI_COMMON_CONFIG pciData, // optional
894 )
895{
896 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
897 //ULONG slotNumber = deviceExtension->slotNumber;
898 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
900 ULONG i, n;
901 ULONG PI;
902 //ULONG PI_ex_mask=0;
903 ULONG CAP;
904 ULONG CAP2;
905 ULONG GHC, GHC0;
906#ifdef _DEBUG
907 ULONG BOHC;
908 ULONG v_Mn, v_Mj;
909#endif //_DEBUG
910 ULONG NumberChannels;
911 ULONG_PTR BaseMemAddress;
912 BOOLEAN MemIo = FALSE;
913 BOOLEAN found = FALSE;
914 ULONG BarId=5;
915
916 KdPrint2((PRINT_PREFIX " UniataAhciDetect:\n"));
917
918 if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreAhci", 0)) {
919 KdPrint((" AHCI excluded\n"));
920 return FALSE;
921 }
922 switch(deviceExtension->DevID) {
923 case 0xa01c0031:
924 KdPrint2((PRINT_PREFIX " Cavium uses BAR(0)\n"));
925 BarId = 0;
926 break;
927 }
928 BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
929 BarId, 0, 0x10);
930 if(!BaseMemAddress) {
931 KdPrint2((PRINT_PREFIX " AHCI init failed - no IoRange\n"));
932 return FALSE;
933 }
934 if((*ConfigInfo->AccessRanges)[BarId].RangeInMemory) {
935 KdPrint2((PRINT_PREFIX "MemIo\n"));
936 MemIo = TRUE;
937 }
938 deviceExtension->BaseIoAHCI_0.Addr = BaseMemAddress;
939 deviceExtension->BaseIoAHCI_0.MemIo = MemIo;
940
941#ifdef _DEBUG
942 UniataDumpAhciRegs(deviceExtension);
943#endif //_DEBUG
944
945 GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
946 if(GHC & AHCI_GHC_HR) {
947 KdPrint2((PRINT_PREFIX " AHCI in reset state\n"));
948 return FALSE;
949 }
950
951 /* check AHCI mode. Save state and try enable */
952 GHC0 =
953 GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
954 KdPrint2((PRINT_PREFIX " check AHCI mode, GHC %#x\n", GHC));
955
956 version = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_VS);
957
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"));
962 goto exit_detect;
963 }
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);
968
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"));
972 goto exit_detect;
973 }
974 }
975
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
982 }
983#ifdef _DEBUG
984 if(CAP2 & AHCI_CAP2_BOH) {
985 BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
986 KdPrint2((PRINT_PREFIX " BOHC %#x", BOHC));
987 }
988#endif //_DEBUG
989 if(CAP & AHCI_CAP_NCQ) {
990 KdPrint2((PRINT_PREFIX " NCQ"));
991 }
992 if(CAP & AHCI_CAP_SNTF) {
993 KdPrint2((PRINT_PREFIX " SNTF"));
994 }
995 if(CAP & AHCI_CAP_CCC) {
996 KdPrint2((PRINT_PREFIX " CCC"));
997 }
998 KdPrint2((PRINT_PREFIX "\n"));
999
1000 /* get the number of HW channels */
1001
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.
1006 */
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));
1010
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);
1017 }
1018 }
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));
1022
1023 for(i=PI, n=0; i; n++, i=i>>1);
1024 NumberChannels =
1025 max((CAP & AHCI_CAP_NOP_MASK)+1, n);
1026
1027 if(!PI && ((CAP & AHCI_CAP_NOP_MASK)+1)) {
1028 /* Enable ports.
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.
1032 */
1033 KdPrint2((PRINT_PREFIX "PI=0 -> Enable ports (mask) %#x\n", deviceExtension->AHCI_PI_mask));
1034 n = NumberChannels;
1035 deviceExtension->AHCI_PI = ((ULONG)1 << n)-1;
1036
1037 if(deviceExtension->AHCI_PI_mask) {
1038 // we have some forced port mask
1039 PI = deviceExtension->AHCI_PI_mask;
1040 } else {
1041 // construct mask
1042 PI = deviceExtension->AHCI_PI = (((ULONG)1 << n)-1);
1043 deviceExtension->AHCI_PI_mask = (((ULONG)1 << n)-1);
1044 }
1045 KdPrint2((PRINT_PREFIX "Enable ports final PI %#x\n", PI));
1046 UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_PI, PI);
1047 }
1048
1049 KdPrint2((PRINT_PREFIX " CommandSlots %d\n", (CAP & AHCI_CAP_NCS_MASK)>>8 ));
1050 KdPrint2((PRINT_PREFIX " Detected Channels %d / %d\n", NumberChannels, n));
1051
1052 switch(deviceExtension->DevID) {
1053 case 0x2361197b:
1054 KdPrint2((PRINT_PREFIX " JMicron JMB361 -> 1\n"));
1055 NumberChannels = 1;
1056 break;
1057 case ATA_M88SE6111:
1058 KdPrint2((PRINT_PREFIX " Marvell M88SE6111 -> 1\n"));
1059 NumberChannels = 1;
1060 break;
1061 case ATA_M88SE6121:
1062 KdPrint2((PRINT_PREFIX " Marvell M88SE6121 -> 2\n"));
1063 NumberChannels = min(NumberChannels, 2);
1064 break;
1065 case ATA_M88SE6141:
1066 case ATA_M88SE6145:
1067 case ATA_M88SE9123:
1068 KdPrint2((PRINT_PREFIX " Marvell M88SE614x/9123 -> 4\n"));
1069 NumberChannels = min(NumberChannels, 4);
1070 break;
1071 } // switch()
1072
1073 if(!NumberChannels) {
1074 KdPrint2((PRINT_PREFIX " Non-AHCI - NumberChannels=0\n"));
1075 found = FALSE;
1076 goto exit_detect;
1077 }
1078 KdPrint2((PRINT_PREFIX " Adjusted Channels %d\n", NumberChannels));
1079
1080#ifdef _DEBUG
1081 v_Mj = ((version >> 20) & 0xf0) + ((version >> 16) & 0x0f);
1082 v_Mn = ((version >> 4) & 0xf0) + (version & 0x0f);
1083
1084 KdPrint2((PRINT_PREFIX " AHCI version %x.%02x controller with %d ports (mask %#x) detected\n",
1085 v_Mj, v_Mn,
1086 NumberChannels, PI));
1087 KdPrint((" AHCI SATA Gen %d\n", (((CAP & AHCI_CAP_ISS_MASK) >> 20)) ));
1088#endif //_DEBUG
1089
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;
1096 } else {
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;
1100 }
1101 } else {
1102 KdPrint2((PRINT_PREFIX " PM not supported -> 1 lun/chan\n"));
1103 deviceExtension->NumberLuns = 1;
1104 }
1105
1106 if(!UniAtaAhciValidateVersion(deviceExtension, version, TRUE)) {
1107 goto exit_detect;
1108 }
1109
1110 deviceExtension->HwFlags |= UNIATA_SATA | UNIATA_AHCI;
1111 if(deviceExtension->NumberChannels < NumberChannels) {
1112 deviceExtension->NumberChannels = NumberChannels;
1113 }
1114 deviceExtension->DmaSegmentLength = 0x3fffff+1; // 4MB
1115 deviceExtension->DmaSegmentAlignmentMask = -1; // no restrictions
1116
1117 deviceExtension->BusMaster = DMA_MODE_AHCI;
1118 deviceExtension->MaxTransferMode = max(deviceExtension->MaxTransferMode, ATA_SA150+(((CAP & AHCI_CAP_ISS_MASK) >> 20)-1) );
1119
1120 found = TRUE;
1121
1122exit_detect:
1123 UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC, GHC0);
1124 KdPrint((" AHCI detect status %d\n", found));
1125
1126 return found;
1127} // end UniataAhciDetect()
1128
1129UCHAR
1130NTAPI
1132 IN PVOID HwDeviceExtension,
1133 IN ULONG lChannel,
1135 )
1136{
1137 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1138 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1139 ULONG Channel = deviceExtension->Channel + lChannel;
1140 ULONG hIS;
1141 ULONG CI, ACT;
1142 AHCI_IS_REG IS;
1143 SATA_SSTATUS_REG SStatus;
1145 //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
1146 ULONG tag=0;
1147
1148 KdPrint(("UniataAhciStatus(%d-%d):\n", lChannel, Channel));
1149
1150 hIS = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS);
1151 KdPrint((" hIS %#x\n", hIS));
1152 hIS &= (1 << Channel);
1153 if(!hIS) {
1155 }
1159 SStatus.Reg = AtapiReadPort4(chan, IDX_SATA_SStatus);
1161
1162 /* clear interrupt(s) */
1163 UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_IS, hIS);
1166
1167 KdPrint((" AHCI: is=%08x ss=%08x serror=%08x CI=%08x, ACT=%08x\n",
1168 IS.Reg, SStatus.Reg, SError.Reg, CI, ACT));
1169
1170 /* do we have cold connect surprise */
1171 if(IS.CPDS) {
1172 }
1173
1174 /* check for and handle connect events */
1175 if(IS.PCS) {
1176 UniataSataEvent(HwDeviceExtension, lChannel, UNIATA_SATA_EVENT_ATTACH);
1177 }
1178 if(IS.PRCS) {
1179 UniataSataEvent(HwDeviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH);
1180 }
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)) {
1187#ifdef _DEBUG
1188 UniataDumpAhciPortRegs(chan);
1189#endif //_DEBUG
1190 //deviceExtension->ExpectingInterrupt++; // will be updated in ISR on ReturnEnableInterrupts
1191 if(IS.Reg &
1194 KdPrint((" AHCI: unexpected, error\n"));
1195 } else {
1196 KdPrint((" AHCI: unexpected, incomplete command or error ?\n"));
1197/*
1198 ULONG TFD;
1199
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;
1205 }
1206*/
1208 }
1209 }
1210 return INTERRUPT_REASON_OUR;
1211
1212} // end UniataAhciStatus()
1213
1214VOID
1215NTAPI
1217 IN PHW_CHANNEL chan,
1220 )
1221{
1222 ULONG TFD, SIG;
1223
1224 regs->bDriveHeadReg = IDE_DRIVE_SELECT_1;
1226 regs->bCommandReg = (UCHAR)(TFD & 0xff);
1227 regs->bFeaturesReg = (UCHAR)((TFD >> 8) & 0xff);
1228
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);
1234 regs->bOpFlags = 0;
1235
1236 return;
1237} // end UniataAhciSnapAtaRegs()
1238
1239ULONG
1240NTAPI
1242 IN PHW_DEVICE_EXTENSION deviceExtension,
1244 IN ULONG lChannel,
1245 OUT PUCHAR fis,
1248 IN USHORT count,
1250 )
1251{
1252 //ULONG i;
1253 PUCHAR plba;
1254 BOOLEAN need48;
1255 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1256
1257 KdPrint2((PRINT_PREFIX " AHCI setup FIS %x, ch %d, dev %d\n", fis, lChannel, DeviceNumber));
1258 //i = 0;
1259 plba = (PUCHAR)&lba;
1260
1261 RtlZeroMemory(fis, 20);
1262
1263 fis[0] = AHCI_FIS_TYPE_ATA_H2D; /* host to device */
1264 fis[1] = 0x80 | ((UCHAR)DeviceNumber & 0x0f); /* command FIS (note PM goes here) */
1268
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) &&
1272 */
1275 if(feature & ATA_F_DMA) {
1276 fis[IDX_AHCI_o_Feature] = (UCHAR)(feature & 0xff);
1277 } else {
1278 fis[IDX_AHCI_o_CylinderLow] = (UCHAR)(count & 0xff);
1279 fis[IDX_AHCI_o_CylinderHigh] = (UCHAR)(count>>8) & 0xff;
1280 }
1281 //fis[IDX_AHCI_o_Control] |= IDE_DC_A_4BIT;
1282 } else {
1283
1286 KdPrint3((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count));
1287 return 0;
1288 }
1289
1291 chan->lun[DeviceNumber]->IdentifyData.FeaturesSupport.Address48);
1292
1293 /* translate command into 48bit version */
1294 if(need48) {
1297 } else {
1298 KdPrint2((PRINT_PREFIX " unhandled LBA48 command\n"));
1299 return 0;
1300 }
1301 }
1302
1305
1306 fis[IDX_AHCI_o_BlockNumber] = plba[0];
1307 fis[IDX_AHCI_o_CylinderLow] = plba[1];
1308 fis[IDX_AHCI_o_CylinderHigh] = plba[2];
1309
1310 fis[IDX_AHCI_o_BlockCount] = (UCHAR)count & 0xff;
1311
1312 if(need48) {
1313 //i++;
1315
1316 fis[IDX_AHCI_o_BlockNumberExp] = plba[3];
1317 fis[IDX_AHCI_o_CylinderLowExp] = plba[4];
1318 fis[IDX_AHCI_o_CylinderHighExp] = plba[5];
1319
1320 fis[IDX_AHCI_o_BlockCountExp] = (UCHAR)(count>>8) & 0xff;
1321
1322 fis[IDX_AHCI_o_FeatureExp] = (UCHAR)(feature>>8) & 0xff;
1323
1325 } else {
1326 fis[IDX_AHCI_o_DriveSelect] |= /*IDE_DRIVE_1 |*/ (plba[3] & 0x0f);
1327 chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48;
1328 }
1329
1330 //fis[14] = 0x00;
1331
1332 }
1333
1334 //KdDump(fis, 20);
1335
1336 return 20;
1337} // end UniataAhciSetupFIS_H2D()
1338
1339ULONG
1340NTAPI
1342 IN PHW_DEVICE_EXTENSION deviceExtension,
1344 IN ULONG lChannel,
1345 OUT PUCHAR fis,
1347 )
1348{
1349 //ULONG i;
1350 //PUCHAR plba;
1351 BOOLEAN need48;
1352 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1353 UCHAR command;
1354
1355 command = regs->bCommandReg;
1356
1357 KdPrint2((PRINT_PREFIX " AHCI setup FIS Direct %x, ch %d, dev %d\n", fis, lChannel, DeviceNumber));
1358 //i = 0;
1359 //plba = (PUCHAR)&lba;
1360
1361 RtlZeroMemory(fis, 20);
1362
1363 fis[0] = AHCI_FIS_TYPE_ATA_H2D; /* host to device */
1364 fis[1] = 0x80 | ((UCHAR)DeviceNumber & 0x0f); /* command FIS (note PM goes here) */
1368
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) &&
1372 */
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);
1377 } else {
1378 fis[IDX_AHCI_o_CylinderLow] = (UCHAR)(count & 0xff);
1379 fis[IDX_AHCI_o_CylinderHigh] = (UCHAR)(count>>8) & 0xff;
1380 }*/
1381 return 0;
1382 //fis[IDX_AHCI_o_Control] |= IDE_DC_A_4BIT;
1383 } else {
1384
1385 need48 = (regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND) &&
1386 chan->lun[DeviceNumber]->IdentifyData.FeaturesSupport.Address48;
1387
1388 /* translate command into 48bit version */
1389 if(need48) {
1392 } else {
1393 KdPrint2((PRINT_PREFIX " unhandled LBA48 command\n"));
1394 return 0;
1395 }
1396 }
1397
1399 fis[IDX_AHCI_o_Feature] = regs->bFeaturesReg;
1400
1401 fis[IDX_AHCI_o_BlockNumber] = regs->bSectorNumberReg;
1402 fis[IDX_AHCI_o_CylinderLow] = regs->bCylLowReg;
1403 fis[IDX_AHCI_o_CylinderHigh] = regs->bCylHighReg;
1404
1405 fis[IDX_AHCI_o_BlockCount] = regs->bSectorCountReg;
1406
1407 if(need48) {
1408 //i++;
1410
1411 fis[IDX_AHCI_o_BlockNumberExp] = regs->bSectorNumberRegH;
1412 fis[IDX_AHCI_o_CylinderLowExp] = regs->bCylLowRegH;
1413 fis[IDX_AHCI_o_CylinderHighExp] = regs->bCylHighRegH;
1414
1415 fis[IDX_AHCI_o_BlockCountExp] = regs->bSectorCountRegH;
1416
1417 fis[IDX_AHCI_o_FeatureExp] = regs->bFeaturesRegH;
1418
1420 } else {
1421 //fis[IDX_AHCI_o_DriveSelect] |= /*IDE_DRIVE_1 |*/ (plba[3] & 0x0f);
1422 chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48;
1423 }
1424 fis[IDX_AHCI_o_DriveSelect] |= regs->bDriveHeadReg & 0x0f;
1425 }
1426
1427 KdDump(fis, 20);
1428
1429 return 20;
1430} // end UniataAhciSetupFIS_H2D_Direct()
1431
1432UCHAR
1433NTAPI
1435 IN PHW_CHANNEL chan,
1437 )
1438{
1439 AHCI_IS_REG IS;
1440 //ULONG ACT;
1441 ULONG CI=0;
1442 ULONG i;
1443 ULONG SError;
1444 ULONG tag=0;
1445
1446 timeout *= 5;
1447
1448 for (i=0; i<timeout; i++) {
1450 //ACT = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_ACT);
1451 if (!(( CI >> tag) & 0x01)) {
1452 break;
1453 }
1455 //KdPrint((" IS %#x\n", IS.Reg));
1456 if(IS.Reg) {
1457 break;
1458 }
1460 if(SError) {
1461 KdPrint((" AHCI: error %#x\n", SError));
1462 i = timeout;
1463 break;
1464 }
1466 }
1467 KdPrint((" CI %#x\n", CI));
1468
1469 //SStatus.Reg = AtapiReadPort4(chan, IDX_SATA_SStatus);
1470 //SError.Reg = AtapiReadPort4(chan, IDX_SATA_SError);
1471
1472 /* clear interrupt(s) */
1474 KdPrint((" IS %#x\n", IS.Reg));
1476
1477 if (timeout && (i >= timeout)) {
1478#ifdef _DEBUG
1479 ULONG TFD;
1480
1482 KdPrint((" AHCI: timeout, SError %#x\n", SError));
1483
1485 KdPrint2((" TFD %#x\n", TFD));
1486#endif //_DEBUG
1487
1488 return IDE_STATUS_WRONG;
1489 }
1490
1491 return IDE_STATUS_IDLE;
1492} // end UniataAhciWaitCommandReady()
1493
1494UCHAR
1495NTAPI
1497 IN PVOID HwDeviceExtension,
1498 IN ULONG lChannel,
1500 IN USHORT ahci_flags,
1502 )
1503{
1504 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1505 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1506 //ULONG Channel = deviceExtension->Channel + lChannel;
1507 //ULONG hIS;
1508 //ULONG SError;
1509 //SATA_SSTATUS_REG SStatus;
1510 //SATA_SERROR_REG SError;
1511 //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
1512 //ULONGIO_PTR base;
1513 ULONG tag=0;
1514
1515 PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
1516
1517 KdPrint(("UniataAhciSendCommand: lChan %d\n", chan->lChannel));
1518
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);
1522
1523 AHCI_CL->bytecount = 0;
1526 KdPrint2((PRINT_PREFIX " AHCI CMD address is not aligned (mask %#x)\n", (ULONG)AHCI_CMD_ALIGNEMENT_MASK));
1527 }
1528
1529 //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag);
1531
1532 return UniataAhciWaitCommandReady(chan, timeout);
1533
1534} // end UniataAhciSendCommand()
1535
1536UCHAR
1537NTAPI
1539 IN PVOID HwDeviceExtension,
1540 IN ULONG lChannel,
1543 IN PUCHAR data,
1544 IN ULONG length, /* bytes */
1547 IN USHORT bcount, /* block count, just ATA register */
1549 IN USHORT ahci_flags,
1550 IN ULONG wait_flags,
1552 )
1553{
1554 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1555 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1556 UCHAR statusByte;
1557 PATA_REQ AtaReq;
1558 ULONG fis_size;
1559 //ULONG tag=0;
1560 //PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
1561 PIDE_AHCI_CMD AHCI_CMD = NULL;
1562
1563 //PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
1564
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 ));
1567
1568 if(length/DEV_BSIZE != bcount) {
1569 KdPrint((" length/DEV_BSIZE != bcount\n"));
1570 }
1571
1572#ifdef _DEBUG
1573 //UniataDumpAhciPortRegs(chan);
1574#endif // _DEBUG
1575
1576 if(!Srb) {
1577 Srb = BuildAhciInternalSrb(HwDeviceExtension, DeviceNumber, lChannel, data, length);
1578 if(!Srb) {
1579 KdPrint((" !Srb\n"));
1580 return IDE_STATUS_WRONG;
1581 }
1582 //UniataAhciSetupCmdPtr(AtaReq); // must be called before DMA setup
1583 //should be already called on init
1584 }
1585 AtaReq = (PATA_REQ)(Srb->SrbExtension);
1586 //KdPrint((" Srb %#x, AtaReq %#x\n", Srb, AtaReq));
1587
1588 AHCI_CMD = AtaReq->ahci.ahci_cmd_ptr;
1589
1590 fis_size = UniataAhciSetupFIS_H2D(deviceExtension, DeviceNumber, lChannel,
1591 &(AHCI_CMD->cfis[0]),
1592 command,
1593 lba,
1594 bcount,
1595 feature
1596 );
1597
1598 if(!fis_size) {
1599 KdPrint2(("!fis_size\n"));
1600 return IDE_STATUS_WRONG;
1601 }
1602
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));
1606
1607 if(data) {
1608 if(ahci_flags & ATA_AHCI_CMD_WRITE) {
1609 AtaReq->Flags &= ~REQ_FLAG_READ;
1611 KdPrint((" assume OUT\n"));
1612 } else {
1613 AtaReq->Flags |= REQ_FLAG_READ;
1615 KdPrint((" assume IN\n"));
1616 }
1617 if(!AtapiDmaSetup(HwDeviceExtension,
1619 lChannel, // logical channel,
1620 Srb,
1621 data,
1622 length)) {
1623 KdPrint2((" can't setup buffer\n"));
1624 return IDE_STATUS_WRONG;
1625 }
1626 }
1627
1628 AtaReq->ahci.io_cmd_flags = ahci_flags;
1629
1630#ifdef _DEBUG
1631 //UniataDumpAhciPortRegs(chan);
1632#endif // _DEBUG
1633
1634 UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
1635
1636#ifdef _DEBUG
1637 //UniataDumpAhciPortRegs(chan);
1638#endif // _DEBUG
1639
1640 if(wait_flags == ATA_IMMEDIATE) {
1641 statusByte = 0;
1642 KdPrint2((" return imemdiately\n"));
1643 } else {
1644 statusByte = UniataAhciWaitCommandReady(chan, timeout);
1645 UniataAhciStatus(HwDeviceExtension, lChannel, DeviceNumber);
1646 UniataAhciEndTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
1647 }
1648
1649 return statusByte;
1650
1651} // end UniataAhciSendPIOCommand()
1652
1653UCHAR
1654NTAPI
1656 IN PVOID HwDeviceExtension,
1657 IN ULONG lChannel,
1661 IN ULONG wait_flags,
1663 )
1664{
1665 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1666 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1667 UCHAR statusByte;
1668 PATA_REQ AtaReq;
1669 ULONG fis_size;
1670 //ULONG tag=0;
1671 //PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
1672 PIDE_AHCI_CMD AHCI_CMD = NULL;
1673 USHORT ahci_flags=0;
1674// USHORT bcount=0;
1675
1676 //PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
1677
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 ));
1680
1681// if(Srb->DataTransferLength/DEV_BSIZE != bcount) {
1682// KdPrint((" length/DEV_BSIZE != bcount\n"));
1683// }
1684
1685#ifdef _DEBUG
1686 //UniataDumpAhciPortRegs(chan);
1687#endif // _DEBUG
1688
1689 if(!Srb) {
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
1694 }
1695 AtaReq = (PATA_REQ)(Srb->SrbExtension);
1696 //KdPrint((" Srb %#x, AtaReq %#x\n", Srb, AtaReq));
1697
1698 AHCI_CMD = AtaReq->ahci.ahci_cmd_ptr;
1699 if(!AHCI_CMD) {
1700 KdPrint((" !AHCI_CMD\n"));
1701 return IDE_STATUS_WRONG;
1702 }
1703
1704 if(Srb->DataTransferLength) {
1706 ahci_flags |= ATA_AHCI_CMD_WRITE;
1707 AtaReq->Flags &= ~REQ_FLAG_READ;
1708 } else {
1709 AtaReq->Flags |= REQ_FLAG_READ;
1710 }
1711 }
1712
1713 fis_size = UniataAhciSetupFIS_H2D_Direct(deviceExtension, DeviceNumber, lChannel,
1714 &(AHCI_CMD->cfis[0]),
1715 regs);
1716
1717 if(!fis_size) {
1718 KdPrint2(("!fis_size\n"));
1719 return IDE_STATUS_WRONG;
1720 }
1721
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));
1725
1726 if(Srb->DataTransferLength) {
1727 if(!AtapiDmaSetup(HwDeviceExtension,
1729 lChannel, // logical channel,
1730 Srb,
1731 (PUCHAR)(Srb->DataBuffer),
1733 KdPrint2((" can't setup buffer\n"));
1734 return IDE_STATUS_WRONG;
1735 }
1736 }
1737
1738 AtaReq->ahci.io_cmd_flags = ahci_flags;
1739
1740#ifdef _DEBUG
1741 //UniataDumpAhciPortRegs(chan);
1742#endif // _DEBUG
1743
1744 UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
1745
1746#ifdef _DEBUG
1747 //UniataDumpAhciPortRegs(chan);
1748#endif // _DEBUG
1749
1750 if(wait_flags == ATA_IMMEDIATE) {
1751 statusByte = 0;
1752 KdPrint2((" return imemdiately\n"));
1753 } else {
1754 statusByte = UniataAhciWaitCommandReady(chan, timeout);
1755 UniataAhciStatus(HwDeviceExtension, lChannel, DeviceNumber);
1756 UniataAhciEndTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
1757 }
1758
1759 return statusByte;
1760
1761} // end UniataAhciSendPIOCommandDirect()
1762
1763BOOLEAN
1764NTAPI
1766 IN PHW_CHANNEL chan
1767 )
1768{
1769 /* kick controller into sane state */
1770 if(!UniataAhciStop(chan)) {
1771 return FALSE;
1772 }
1773 if(!UniataAhciStopFR(chan)) {
1774 return FALSE;
1775 }
1776 if(!UniataAhciCLO(chan)) {
1777 return FALSE;
1778 }
1779 UniataAhciStartFR(chan);
1780 UniataAhciStart(chan);
1781
1782 return TRUE;
1783} // end UniataAhciAbortOperation()
1784
1785ULONG
1786NTAPI
1788 IN PVOID HwDeviceExtension,
1789 IN ULONG lChannel,
1791 )
1792{
1793 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1794 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1795 //ULONG Channel = deviceExtension->Channel + lChannel;
1796 //ULONG hIS;
1797 //ULONG CI;
1798 //AHCI_IS_REG IS;
1799 //ULONG tag=0;
1800
1801 KdPrint(("UniataAhciSoftReset: lChan %d\n", chan->lChannel));
1802
1803 PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
1804 PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
1805
1806 /* kick controller into sane state */
1807 if(!UniataAhciAbortOperation(chan)) {
1808 KdPrint2((" abort failed\n"));
1809 return (ULONG)(-1);
1810 }
1811
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);
1818
1820 KdPrint2((" timeout\n"));
1821 return (ULONG)(-1);
1822 }
1824
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"));
1833 return (ULONG)(-1);
1834 }
1835
1836 UniataAhciWaitReady(chan, 1);
1837
1838 KdDump(RCV_FIS, sizeof(chan->AhciCtlBlock->rcv_fis.rfis));
1839
1840 if(deviceExtension->HwFlags & UNIATA_AHCI_ALT_SIG) {
1841 ULONG signature;
1842 signature = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_SIG);
1843 KdPrint((" alt sig: %#x\n", signature));
1844 return signature;
1845 }
1846
1847 return UniataAhciUlongFromRFIS(RCV_FIS);
1848
1849} // end UniataAhciSoftReset()
1850
1851ULONG
1852NTAPI
1854 IN PHW_CHANNEL chan,
1856 )
1857{
1858 ULONG TFD;
1859 ULONG i;
1860
1861 KdPrint2(("UniataAhciWaitReady: lChan %d\n", chan->lChannel));
1862
1863 //base = (ULONGIO_PTR)(&deviceExtension->BaseIoAHCI_0 + offs);
1864
1866 for(i=0; i<timeout && (TFD &
1868 AtapiStallExecution(1000);
1870 }
1871
1872 KdPrint2((" TFD %#x\n", TFD));
1873
1874 return TFD;
1875
1876} // end UniataAhciWaitReady()
1877
1878ULONG
1879NTAPI
1881 IN PVOID HwDeviceExtension,
1882 IN ULONG lChannel,
1883 OUT PULONG signature
1884 )
1885{
1886 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1887 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1888 //ULONG Channel = deviceExtension->Channel + lChannel;
1889 ULONG TFD;
1890
1891
1892 KdPrint(("UniataAhciHardReset: lChan %d\n", chan->lChannel));
1893
1894 (*signature) = 0xffffffff;
1895
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;
1900 }
1901
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));
1906 return TFD;
1907 }
1908 KdPrint((" TFD %#x\n", TFD));
1909
1910#ifdef _DEBUG
1911 UniataDumpAhciPortRegs(chan);
1912#endif // _DEBUG
1913
1914 (*signature) = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_SIG);
1915 KdPrint((" sig: %#x\n", *signature));
1916
1917 UniataAhciStart(chan);
1918
1919 return 0;
1920
1921} // end UniataAhciHardReset()
1922
1923VOID
1924NTAPI
1926 IN PVOID HwDeviceExtension,
1927 IN ULONG lChannel
1928 )
1929{
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);
1934 ULONG CAP;
1935 //ULONGIO_PTR base;
1936 ULONG signature;
1937 ULONG i;
1938 ULONG VendorID = deviceExtension->DevID & 0xffff;
1939
1940 KdPrint(("UniataAhciReset: lChan %d\n", chan->lChannel));
1941
1942 //base = (ULONGIO_PTR)(&deviceExtension->BaseIoAHCI_0 + offs);
1943
1944 /* Disable port interrupts */
1946
1947 if(UniataAhciHardReset(HwDeviceExtension, lChannel, &signature)) {
1948
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]);
1954 }
1955
1956 /* enable wanted port interrupts */
1959 return;
1960 }
1961
1962 /* enable wanted port interrupts */
1966 ((/*ch->pm_level == */0) ? (ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC) : 0) |
1969
1970 /*
1971 * Only probe for PortMultiplier if HW has support.
1972 * Ignore Marvell, which is not working,
1973 */
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);
1985 }
1986 } else {
1987 signature = UniataAhciSoftReset(HwDeviceExtension, lChannel, 0);
1988 }
1989
1990 KdPrint((" signature %#x\n", signature));
1991 chan->lun[0]->DeviceFlags &= ~(DFLAGS_ATAPI_DEVICE | DFLAGS_DEVICE_PRESENT | CTRFLAGS_AHCI_PM);
1992 switch (signature >> 16) {
1993 case 0x0000:
1994 KdPrint((" ATA dev\n"));
1995 chan->lun[0]->DeviceFlags |= DFLAGS_DEVICE_PRESENT;
1996 chan->PmLunMap = 0;
1997 break;
1998 case 0x9669:
1999 KdPrint((" PM\n"));
2000 if(deviceExtension->NumberLuns > 1) {
2003 } else {
2004 KdPrint((" no PM supported (1 lun/chan)\n"));
2005 }
2006 break;
2007 case 0xeb14:
2008 KdPrint((" ATAPI dev\n"));
2009 chan->lun[0]->DeviceFlags |= (DFLAGS_ATAPI_DEVICE | DFLAGS_DEVICE_PRESENT);
2010 chan->PmLunMap = 0;
2011 break;
2012 default: /* SOS XXX */
2013 KdPrint((" default to ATA ???\n"));
2014 chan->lun[0]->DeviceFlags |= DFLAGS_DEVICE_PRESENT;
2015 chan->PmLunMap = 0;
2016 }
2017
2018 return;
2019
2020} // end UniataAhciReset()
2021
2022VOID
2023NTAPI
2025 IN PHW_CHANNEL chan
2026 )
2027{
2028 ULONG CMD;
2029
2030 KdPrint2(("UniataAhciStartFR: lChan %d\n", chan->lChannel));
2031
2033 KdPrint2((" CMD %#x\n", CMD));
2035 UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2036
2037 return;
2038} // end UniataAhciStartFR()
2039
2040BOOLEAN
2041NTAPI
2043 IN PHW_CHANNEL chan
2044 )
2045{
2046 ULONG CMD;
2047 ULONG i;
2048
2049 KdPrint2(("UniataAhciStopFR: lChan %d\n", chan->lChannel));
2050
2052 KdPrint2((" CMD %#x\n", CMD));
2054
2055 for(i=0; i<1000; i++) {
2057 if(!(CMD & ATA_AHCI_P_CMD_FR)) {
2058 KdPrint2((" final CMD %#x\n", CMD));
2059 return TRUE;
2060 }
2061 AtapiStallExecution(1000);
2062 }
2063 KdPrint2((" CMD %#x\n", CMD));
2064 KdPrint((" SError %#x\n", AtapiReadPort4(chan, IDX_SATA_SError)));
2065 KdPrint2(("UniataAhciStopFR: timeout\n"));
2066 return FALSE;
2067} // end UniataAhciStopFR()
2068
2069VOID
2070NTAPI
2072 IN PHW_CHANNEL chan
2073 )
2074{
2075 ULONG IS, CMD;
2077
2078 KdPrint2(("UniataAhciStart: lChan %d\n", chan->lChannel));
2079
2080 /* clear SATA error register */
2082
2083 /* clear any interrupts pending on this channel */
2086
2087 KdPrint2((" SError %#x, IS %#x\n", SError.Reg, IS));
2088
2090 KdPrint2((" CMD %#x\n", CMD));
2092 CMD |
2094 ((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM) ? ATA_AHCI_P_CMD_PMA : 0));
2095 UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2096
2097 return;
2098} // end UniataAhciStart()
2099
2100BOOLEAN
2101NTAPI
2103 IN PHW_CHANNEL chan
2104 )
2105{
2106 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2107 //PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
2108 ULONG CAP, CMD;
2109 //SATA_SERROR_REG SError;
2110 ULONG i;
2111
2112 KdPrint2(("UniataAhciCLO: lChan %d\n", chan->lChannel));
2113
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)) {
2118 return TRUE;
2119 }
2120 KdPrint2((" send CLO\n"));
2124
2125 for(i=0; i<1000; i++) {
2127 if(!(CMD & ATA_AHCI_P_CMD_CLO)) {
2128 KdPrint2((" final CMD %#x\n", CMD));
2129 return TRUE;
2130 }
2131 AtapiStallExecution(1000);
2132 }
2133 KdPrint2((" CMD %#x\n", CMD));
2134 KdPrint2(("UniataAhciCLO: timeout\n"));
2135 return FALSE;
2136} // end UniataAhciCLO()
2137
2138BOOLEAN
2139NTAPI
2141 IN PHW_CHANNEL chan
2142 )
2143{
2144 ULONG CMD;
2145 //SATA_SERROR_REG SError;
2146 ULONG i;
2147
2148 KdPrint2(("UniataAhciStop: lChan %d\n", chan->lChannel));
2149
2150 /* issue Command List Override if supported */
2152 CMD &= ~ATA_AHCI_P_CMD_ST;
2154
2155 for(i=0; i<1000; i++) {
2157 if(!(CMD & ATA_AHCI_P_CMD_CR)) {
2158 KdPrint2((" final CMD %#x\n", CMD));
2159 return TRUE;
2160 }
2161 AtapiStallExecution(1000);
2162 }
2163 KdPrint2((" CMD %#x\n", CMD));
2164 KdPrint((" SError %#x\n", AtapiReadPort4(chan, IDX_SATA_SError)));
2165 KdPrint2(("UniataAhciStop: timeout\n"));
2166 return FALSE;
2167} // end UniataAhciStop()
2168
2169UCHAR
2170NTAPI
2172 IN PVOID HwDeviceExtension,
2173 IN ULONG lChannel,
2176 )
2177{
2178 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2179 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
2180 //ULONG Channel = deviceExtension->Channel + lChannel;
2181 //ULONG hIS;
2182 ULONG CMD, CMD0;
2183 //AHCI_IS_REG IS;
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);
2188 //ULONGIO_PTR base;
2189 ULONG tag=0;
2190 //ULONG i;
2191
2192 PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
2193
2194 KdPrint2(("UniataAhciBeginTransaction: lChan %d, AtaReq %#x\n", chan->lChannel, AtaReq));
2195
2196 if(Srb->DataTransferLength && (!AtaReq->dma_entries || AtaReq->dma_entries >= (USHORT)0xffff)) {
2197 KdPrint2(("UniataAhciBeginTransaction wrong DMA tab len %x\n", AtaReq->dma_entries));
2198 return 0;
2199 }
2200
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;
2207 } else
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),
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));
2215 } else {
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);
2218 return 0;
2219 }
2221 KdPrint2((PRINT_PREFIX " AHCI CMD address is not aligned (mask %#x)\n", (ULONG)AHCI_CMD_ALIGNEMENT_MASK));
2222 return 0;
2223 }
2224
2225#ifdef _DEBUG
2226 KdPrint2((" prd_length %#x, flags %#x, base %I64x\n", AHCI_CL->prd_length, AHCI_CL->cmd_flags,
2227 AHCI_CL->cmd_table_phys));
2228#endif // _DEBUG
2229
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"));
2237 KdDump(&(AtaReq->ahci.ahci_cmd_ptr->acmd), 16);
2238 } else {
2239 CMD &= ~ATA_AHCI_P_CMD_ATAPI;
2240 }
2241 if(CMD0 != CMD) {
2242 KdPrint2((" send CMD %#x, entries %#x\n", CMD, AHCI_CL->prd_length));
2244 CMD0 = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2245 }
2246
2247 /* issue command to controller */
2248 //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag); // Used for NCQ
2249 KdPrint2((" Set CI\n"));
2251 chan->AhciPrevCI |= 0x01 << tag;
2252
2253 //CMD0 = CMD;
2256 if(CMD != CMD0) {
2257 KdPrint2((" Send CMD START (%#x != %#x)\n", CMD, CMD0));
2259 CMD0 = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2260 } else {
2261 KdPrint2((" No CMD START, already active\n"));
2262 }
2263
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) {
2267 ULONG TFD;
2268 ULONG i;
2269
2270 for(i=0; i<1000000; i++) {
2272 if(!(TFD & IDE_STATUS_BUSY)) {
2273 break;
2274 }
2275 }
2276 if(TFD & IDE_STATUS_BUSY) {
2277 KdPrint2((" timeout\n"));
2278 }
2279 if(TFD & IDE_STATUS_ERROR) {
2280 KdPrint2((" ERROR %#x\n", (UCHAR)(TFD >> 8)));
2281 }
2282 AtaReq->ahci.in_status = TFD;
2283
2284 return IDE_STATUS_SUCCESS;
2285 }
2286 }
2287
2288 return IDE_STATUS_IDLE;
2289
2290} // end UniataAhciBeginTransaction()
2291
2292UCHAR
2293NTAPI
2295 IN PVOID HwDeviceExtension,
2296 IN ULONG lChannel,
2299 )
2300{
2301 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2302 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
2303 //ULONG Channel = deviceExtension->Channel + lChannel;
2304 //ULONG hIS;
2305 ULONG CI, ACT;
2306 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
2307 ULONG TFD;
2308 PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
2309 ULONG tag=0;
2310 //ULONG i;
2311 PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
2312 //PHW_LU_EXTENSION LunExt;
2313
2314 KdPrint2(("UniataAhciEndTransaction: lChan %d\n", chan->lChannel));
2315
2316 //LunExt = chan->lun[DeviceNumber];
2317
2319 KdPrint2((" TFD %#x\n", TFD));
2320
2321 if(TFD & IDE_STATUS_ERROR) {
2322 AtaReq->ahci.in_error = (UCHAR)(TFD >> 8);
2323 KdPrint2((" ERROR %#x\n", AtaReq->ahci.in_error));
2324 } else {
2325 AtaReq->ahci.in_error = 0;
2326 }
2327 AtaReq->ahci.in_status = TFD;
2328
2329 //if (request->flags & ATA_R_CONTROL) {
2330
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);
2338 } else {
2339 AtaReq->ahci.in_lba |= ((ULONGLONG)(RCV_FIS[8]) << 24) |
2340 ((ULONGLONG)(RCV_FIS[9]) << 32) |
2341 ((ULONGLONG)(RCV_FIS[7] & 0x0f) << 24);
2342 }
2343 AtaReq->WordsTransfered = AHCI_CL->bytecount/2;
2344
2345/*
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);
2351
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;
2355 }
2356 }
2357*/
2360 if(CI & (1 << tag)) {
2361 // clear CI
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]));
2364
2365#ifdef _DEBUG
2366 UniataDumpAhciPortRegs(chan);
2367#endif
2368 if(!UniataAhciAbortOperation(chan)) {
2369 KdPrint2((" Abort failed, need RESET\n"));
2370 }
2371#ifdef _DEBUG
2372 UniataDumpAhciPortRegs(chan);
2373#endif
2374 chan->AhciPrevCI = CI & ~((ULONG)1 << tag);
2375 if(chan->AhciPrevCI) {
2376 KdPrint2((" Need command list restart, CI %#x\n", chan->AhciPrevCI));
2377 }
2378 } else {
2379 chan->AhciPrevCI &= ~((ULONG)1 << tag);
2380 RtlZeroMemory(AHCI_CL, sizeof(IDE_AHCI_CMD_LIST));
2381 }
2382 //}
2383
2384 return 0;
2385
2386} // end UniataAhciEndTransaction()
2387
2388VOID
2389NTAPI
2391 IN PHW_CHANNEL chan
2392 )
2393{
2395
2396 KdPrint2(("UniataAhciResume: lChan %d\n", chan->lChannel));
2397
2398#ifdef _DEBUG
2399 //UniataDumpAhciPortRegs(chan);
2400#endif // _DEBUG
2401
2402 /* Disable port interrupts */
2404
2405 /* setup work areas */
2406 base = chan->AHCI_CTL_PhAddr;
2407 if(!base) {
2408 KdPrint2((PRINT_PREFIX " AHCI buffer allocation failed\n"));
2409 return;
2410 }
2411 KdPrint2((PRINT_PREFIX " AHCI CLB setup\n"));
2413 KdPrint2((PRINT_PREFIX " AHCI CLB address is not aligned (mask %#x)\n", (ULONG)AHCI_FIS_ALIGNEMENT_MASK));
2414 }
2416 (ULONG)(base & 0xffffffff));
2418 (ULONG)((base >> 32) & 0xffffffff));
2419
2420 KdPrint2((PRINT_PREFIX " AHCI RCV FIS setup\n"));
2421 base = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, rcv_fis);
2423 KdPrint2((PRINT_PREFIX " AHCI FIS address is not aligned (mask %#x)\n", (ULONG)AHCI_FIS_ALIGNEMENT_MASK));
2424 }
2426 (ULONG)(base & 0xffffffff));
2428 (ULONG)((base >> 32) & 0xffffffff));
2429
2430 /* activate the channel and power/spin up device */
2433 (((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM)) ? ATA_AHCI_P_CMD_ALPE : 0) |
2434 (((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM2)) ? ATA_AHCI_P_CMD_ASP : 0 ))
2435 );
2436 UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2437
2438#ifdef _DEBUG
2439 //UniataDumpAhciPortRegs(chan);
2440#endif // _DEBUG
2441
2442 UniataAhciStartFR(chan);
2443 UniataAhciStart(chan);
2444
2445#ifdef _DEBUG
2446 UniataDumpAhciPortRegs(chan);
2447#endif // _DEBUG
2448
2449 return;
2450} // end UniataAhciResume()
2451
2452#if 0
2453VOID
2454NTAPI
2455UniataAhciSuspend(
2456 IN PHW_CHANNEL chan
2457 )
2458{
2460 SATA_SCONTROL_REG SControl;
2461
2462 KdPrint2(("UniataAhciSuspend:\n"));
2463
2464 /* Disable port interrupts */
2466
2467 /* Reset command register. */
2468 UniataAhciStop(chan);
2469 UniataAhciStopFR(chan);
2471 UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2472
2473 /* Allow everything including partial and slumber modes. */
2475
2476 /* Request slumber mode transition and give some time to get there. */
2479
2480 /* Disable PHY. */
2481 SControl.Reg = 0;
2482 SControl.DET = SStatus_DET_Offline;
2483 UniataSataWritePort4(chan, IDX_SATA_SControl, SControl.Reg, 0);
2484
2485 return;
2486} // end UniataAhciSuspend()
2487#endif
2488
2489BOOLEAN
2490NTAPI
2492 IN PHW_CHANNEL chan,
2494 IN ULONG Reg,
2496 )
2497{
2498 //ULONG Channel = deviceExtension->Channel + lChannel;
2499 //ULONG hIS;
2500 //ULONG CI;
2501 //AHCI_IS_REG IS;
2502 //ULONG tag=0;
2503 PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
2504 PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
2505
2506 KdPrint(("UniataAhciReadPM: lChan %d [%#x]\n", chan->lChannel, DeviceNumber));
2507
2509 (*result) = UniataSataReadPort4(chan, Reg, 0);
2510 return TRUE;
2511 }
2513 switch(Reg) {
2514 case IDX_SATA_SStatus:
2515 Reg = 0; break;
2516 case IDX_SATA_SError:
2517 Reg = 1; break;
2518 case IDX_SATA_SControl:
2519 Reg = 2; break;
2520 default:
2521 return FALSE;
2522 }
2523 }
2524
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;
2532
2533 if(UniataAhciSendCommand(chan->DeviceExtension, chan->lChannel, DeviceNumber, 0, 10) == IDE_STATUS_WRONG) {
2534 KdPrint2((" PM read failed\n"));
2535 return FALSE;
2536 }
2537
2538 KdDump(RCV_FIS, sizeof(chan->AhciCtlBlock->rcv_fis.rfis));
2539
2540 (*result) = UniataAhciUlongFromRFIS(RCV_FIS);
2541 return TRUE;
2542
2543} // end UniataAhciReadPM()
2544
2545UCHAR
2546NTAPI
2548 IN PHW_CHANNEL chan,
2550 IN ULONG Reg,
2551 IN ULONG value
2552 )
2553{
2554 //ULONG Channel = deviceExtension->Channel + lChannel;
2555 //ULONG hIS;
2556 //ULONG CI;
2557 //AHCI_IS_REG IS;
2558 //ULONG tag=0;
2559 ULONG TFD;
2560 PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
2561 //PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
2562
2563 KdPrint(("UniataAhciWritePM: lChan %d [%#x] %#x\n", chan->lChannel, DeviceNumber, value));
2564
2566 UniataSataWritePort4(chan, Reg, value, 0);
2567 return 0;
2568 }
2570 switch(Reg) {
2571 case IDX_SATA_SStatus:
2572 Reg = 0; break;
2573 case IDX_SATA_SError:
2574 Reg = 1; break;
2575 case IDX_SATA_SControl:
2576 Reg = 2; break;
2577 default:
2578 return IDE_STATUS_WRONG;
2579 }
2580 }
2581
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);
2588
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);
2593
2594 AHCI_CMD->cfis[15] = IDE_DC_A_4BIT;
2595
2596 if(UniataAhciSendCommand(chan->DeviceExtension, chan->lChannel, DeviceNumber, 0, 100) == IDE_STATUS_WRONG) {
2597 KdPrint2((" PM write failed\n"));
2598 return IDE_STATUS_WRONG;
2599 }
2600
2602
2603 if(TFD & IDE_STATUS_ERROR) {
2604 KdPrint2((" ERROR %#x\n", (UCHAR)(TFD >> 8)));
2605 }
2606 return (UCHAR)(TFD >> 8);
2607
2608} // end UniataAhciWritePM()
2609
2610VOID
2612IN OUT PATA_REQ AtaReq
2613 )
2614{
2615 union {
2616 PUCHAR prd_base;
2617 ULONGLONG prd_base64;
2618 };
2619 union {
2620 PUCHAR prd_base0;
2621 ULONGLONG prd_base64_0;
2622 };
2623#ifdef _DEBUG
2624 ULONG d;
2625#endif // _DEBUG
2626
2627 prd_base64_0 = prd_base64 = 0;
2628 prd_base = (PUCHAR)(&AtaReq->ahci_cmd0);
2629 prd_base0 = prd_base;
2630
2631 prd_base64 = (prd_base64 + max(FIELD_OFFSET(ATA_REQ, ahci_cmd0), AHCI_CMD_ALIGNEMENT_MASK+1)) & ~AHCI_CMD_ALIGNEMENT_MASK;
2632
2633#ifdef _DEBUG
2634 d = (ULONG)(prd_base64 - prd_base64_0);
2635 KdPrint2((PRINT_PREFIX " AtaReq %#x: cmd aligned %I64x, d=%x\n", AtaReq, prd_base64, d));
2636#endif // _DEBUG
2637
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()
2641
2643NTAPI
2645 IN PVOID HwDeviceExtension,
2647 IN ULONG lChannel,
2650 )
2651{
2652 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2653 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
2655// PCDB cdb;
2656 PATA_REQ AtaReq = chan->AhciInternalAtaReq;
2657
2658 KdPrint(("BuildAhciInternalSrb: lChan %d [%#x]\n", lChannel, DeviceNumber));
2659
2660 if(!AtaReq) {
2661 KdPrint2((PRINT_PREFIX " !chan->AhciInternalAtaReq\n"));
2662 return NULL;
2663 }
2664
2665 //RtlZeroMemory((PCHAR) AtaReq, sizeof(ATA_REQ));
2666 //RtlZeroMemory((PCHAR) AtaReq, FIELD_OFFSET(ATA_REQ, ahci));
2667 UniAtaClearAtaReq(AtaReq);
2668
2669 srb = chan->AhciInternalSrb;
2670
2671 RtlZeroMemory((PCHAR) srb, sizeof(SCSI_REQUEST_BLOCK));
2672
2673 srb->PathId = (UCHAR)lChannel;
2674 srb->TargetId = (UCHAR)DeviceNumber;
2676 srb->Length = sizeof(SCSI_REQUEST_BLOCK);
2677
2678 // Set flags to disable synchronous negociation.
2679 //srb->SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
2680
2681 // Set timeout to 4 seconds.
2682 srb->TimeOutValue = 4;
2683
2684 srb->CdbLength = 6;
2685 srb->DataBuffer = Buffer;
2687 srb->SrbExtension = AtaReq;
2688
2689 AtaReq->Srb = srb;
2690 AtaReq->DataBuffer = (PUSHORT)Buffer;
2691 AtaReq->TransferLength = Length;
2692
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);
2697 //}
2698 //AtaReq->ahci.ahci_cmd_ptr = &(AtaReq->ahci_cmd0);
2699 //AtaReq->ahci.ahci_base64 = NULL; // indicate that we should copy command to proper place
2700
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));
2703
2704/* // Set CDB operation code.
2705 cdb = (PCDB)srb->Cdb;
2706 cdb->CDB6INQUIRY.OperationCode = SCSIOP_REQUEST_SENSE;
2707 cdb->CDB6INQUIRY.AllocationLength = sizeof(SENSE_DATA);
2708*/
2709 return srb;
2710} // end BuildAhciInternalSrb()
2711
unsigned char BOOLEAN
const char * SError(int e)
Definition: SError.c:141
#define PI
Definition: appview.h:57
UCHAR const AtaCommands48[256]
Definition: atacmd_map.h:5
UCHAR const AtaCommandFlags[256]
Definition: atacmd_map.h:25
#define DFLAGS_ATAPI_DEVICE
Definition: atapi.h:41
#define IDE_COMMAND_ATAPI_PACKET
Definition: atapi.h:109
#define IDE_COMMAND_ATAPI_RESET
Definition: atapi.h:102
#define DFLAGS_DEVICE_PRESENT
Definition: atapi.h:40
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
bool NTAPI CheckIfBadBlock(IN PHW_LU_EXTENSION LunExt, IN ULONGLONG lba, IN ULONG count)
#define ATA_M88SE6141
Definition: bm_devs_decl.h:340
#define ATA_M88SE6111
Definition: bm_devs_decl.h:338
#define ATA_INTEL_ID
Definition: bm_devs_decl.h:184
#define ICH5
Definition: bm_devs_decl.h:691
#define ATA_M88SE9123
Definition: bm_devs_decl.h:342
#define UNIATA_SATA
Definition: bm_devs_decl.h:626
#define UNIATA_AHCI
Definition: bm_devs_decl.h:629
#define ATA_M88SE6145
Definition: bm_devs_decl.h:341
#define UNIATA_AHCI_ALT_SIG
Definition: bm_devs_decl.h:632
#define ICH7
Definition: bm_devs_decl.h:695
#define ATA_M88SE6121
Definition: bm_devs_decl.h:339
#define ATA_MARVELL_ID
Definition: bm_devs_decl.h:327
#define ATA_AHCI_P_CMD_FR
Definition: bsmaster.h:705
#define IDX_INDEXED_ADDR
Definition: bsmaster.h:466
#define ATA_AHCI_P_IX_PC
Definition: bsmaster.h:505
#define ATA_AHCI_P_CMD_ST
Definition: bsmaster.h:698
#define AHCI_CAP2_BOH
Definition: bsmaster.h:245
#define CTRFLAGS_AHCI_PM
Definition: bsmaster.h:1143
#define ATA_AHCI_P_CMD_ACTIVE
Definition: bsmaster.h:719
#define IDX_AHCI_P_IE
Definition: bsmaster.h:685
#define ATA_AHCI_P_IX_HBD
Definition: bsmaster.h:513
#define IDX_AHCI_o_CylinderHighExp
Definition: bsmaster.h:796
#define ATA_AHCI_CMD_CLR_BUSY
Definition: bsmaster.h:820
#define AHCI_FIS_ALIGNEMENT_MASK
Definition: bsmaster.h:519
#define IDX_MAX_REG
Definition: bsmaster.h:469
#define AHCI_BOHC_BB
Definition: bsmaster.h:259
#define ATA_AHCI_P_IX_DS
Definition: bsmaster.h:501
#define ATA_AHCI_P_IX_TFE
Definition: bsmaster.h:515
#define AHCI_CAP_SPM
Definition: bsmaster.h:204
struct _IDE_AHCI_CMD * PIDE_AHCI_CMD
#define SetPciConfig4(offs, op)
Definition: bsmaster.h:1688
#define IDX_AHCI_o_CylinderLowExp
Definition: bsmaster.h:795
#define AHCI_CAP_NCS_MASK
Definition: bsmaster.h:202
VOID NTAPI AtapiSetupLunPtrs(IN PHW_CHANNEL chan, IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG c)
Definition: id_init.cpp:2846
#define ATA_AHCI_P_CMD_ASP
Definition: bsmaster.h:716
#define IDX_AHCI_o_BlockCount
Definition: bsmaster.h:791
#define SControl_DET_Idle
Definition: bsmaster.h:332
#define IDX_AHCI_P_SError
Definition: bsmaster.h:692
#define IDX_AHCI_o_BlockNumberExp
Definition: bsmaster.h:794
#define AHCI_CAP_SNTF
Definition: bsmaster.h:208
#define AHCI_CAP_SAM
Definition: bsmaster.h:205
BOOLEAN NTAPI AtapiDmaSetup(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN PSCSI_REQUEST_BLOCK Srb, IN PUCHAR data, IN ULONG count)
Definition: id_dma.cpp:247
#define IDX_AHCI_o_FeatureExp
Definition: bsmaster.h:793
#define AHCI_CAP_NCQ
Definition: bsmaster.h:209
#define IDX_AHCI_CAP
Definition: bsmaster.h:270
#define IDX_AHCI_o_Feature
Definition: bsmaster.h:786
#define AHCI_CLB_ALIGNEMENT_MASK
Definition: bsmaster.h:518
#define IDX_AHCI_o_CylinderHigh
Definition: bsmaster.h:789
#define IDX_AHCI_o_Command
Definition: bsmaster.h:785
#define IDX_SATA_SControl
Definition: bsmaster.h:459
#define IDX_SATA_SActive
Definition: bsmaster.h:460
#define SControl_IPM_NoPartialSlumber
Definition: bsmaster.h:348
#define IDX_AHCI_o_BlockCountExp
Definition: bsmaster.h:797
#define ATA_AHCI_CMD_WRITE
Definition: bsmaster.h:816
VOID NTAPI UniataForgetDevice(PHW_LU_EXTENSION LunExt)
Definition: id_ata.cpp:2385
#define IDX_AHCI_P_SNTF
Definition: bsmaster.h:695
#define IDX_AHCI_BOHC
Definition: bsmaster.h:276
#define IDX_AHCI_P_ACT
Definition: bsmaster.h:693
ULONG DDKFASTAPI AtapiReadPort4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port)
#define IDX_AHCI_IS
Definition: bsmaster.h:272
#define AHCI_CMD_ALIGNEMENT_MASK
Definition: bsmaster.h:520
#define ATA_AHCI_P_IX_HBF
Definition: bsmaster.h:514
#define SStatus_SPD_Gen1
Definition: bsmaster.h:292
#define IDX_AHCI_o_Control
Definition: bsmaster.h:792
#define AHCI_BOHC_OOS
Definition: bsmaster.h:262
VOID DDKFASTAPI AtapiWritePortEx4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs, IN ULONG data)
#define ATA_AHCI_P_IX_SDB
Definition: bsmaster.h:502
#define AHCI_FIS_TYPE_ATA_H2D
Definition: bsmaster.h:752
#define ATA_AHCI_P_CMD_ALPE
Definition: bsmaster.h:715
#define AHCI_CAP_SCLO
Definition: bsmaster.h:207
#define AHCI_GHC_HR
Definition: bsmaster.h:221
#define SStatus_DET_Offline
Definition: bsmaster.h:287
#define ATA_AHCI_P_CMD_CLO
Definition: bsmaster.h:701
#define ATA_AHCI_P_CMD_SLUMBER
Definition: bsmaster.h:721
#define SStatus_SPD_Gen2
Definition: bsmaster.h:293
#define ATA_AHCI_P_IX_IF
Definition: bsmaster.h:512
#define IDX_AHCI_P_FB
Definition: bsmaster.h:683
#define DMA_MODE_AHCI
Definition: bsmaster.h:1708
#define IDX_AHCI_CAP2
Definition: bsmaster.h:275
#define ATA_AHCI_P_CMD_SUD
Definition: bsmaster.h:699
#define IDX_INDEXED_DATA
Definition: bsmaster.h:467
#define ATA_AHCI_P_IX_DHR
Definition: bsmaster.h:499
#define IDX_AHCI_PI
Definition: bsmaster.h:274
#define IDX_AHCI_P_CLB
Definition: bsmaster.h:682
#define IDX_AHCI_P_SStatus
Definition: bsmaster.h:690
#define CTRFLAGS_LBA48
Definition: bsmaster.h:1137
ULONG DDKFASTAPI AtapiReadPortEx4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs)
struct _IDE_AHCI_REGISTERS IDE_AHCI_REGISTERS
VOID NTAPI AtapiDmaAlloc(IN PVOID HwDeviceExtension, IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, IN ULONG lChannel)
Definition: id_dma.cpp:138
#define SControl_DET_DoNothing
Definition: bsmaster.h:331
#define AHCI_CAP_ISS_MASK
Definition: bsmaster.h:206
#define ATA_AHCI_P_IX_DP
Definition: bsmaster.h:504
#define AHCI_CAP_PMD
Definition: bsmaster.h:203
#define GetPciConfig4(offs, op)
Definition: bsmaster.h:1678
#define ATA_AHCI_P_IX_INF
Definition: bsmaster.h:511
#define AHCI_CAP_CCC
Definition: bsmaster.h:201
#define DEV_BSIZE
Definition: bsmaster.h:103
#define AHCI_GHC_AE
Definition: bsmaster.h:223
#define AHCI_CAP_S64A
Definition: bsmaster.h:210
#define IDX_AHCI_P_SIG
Definition: bsmaster.h:688
#define ATA_AHCI_P_IX_PRC
Definition: bsmaster.h:508
#define IDX_AHCI_o_DriveSelect
Definition: bsmaster.h:790
VOID DDKFASTAPI AtapiWritePort4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG data)
#define IDX_AHCI_o_CylinderLow
Definition: bsmaster.h:788
union _ATA_REQ * PATA_REQ
#define ATA_AHCI_P_IX_UF
Definition: bsmaster.h:503
#define AHCI_GHC_IE
Definition: bsmaster.h:222
#define IDX_AHCI_VS
Definition: bsmaster.h:273
#define IDX_AHCI_P_CMD
Definition: bsmaster.h:689
#define SControl_DET_Init
Definition: bsmaster.h:333
#define ATA_AHCI_CMD_RESET
Definition: bsmaster.h:818
ULONGIO_PTR NTAPI AtapiGetIoRange(IN PVOID HwDeviceExtension, IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, IN PPCI_COMMON_CONFIG pciData, IN ULONG SystemIoBusNumber, IN ULONG rid, IN ULONG offset, IN ULONG length)
Definition: id_probe.cpp:153
#define CTRFLAGS_AHCI_PM2
Definition: bsmaster.h:1144
#define ATA_AHCI_P_IX_CPD
Definition: bsmaster.h:516
#define IDX_AHCI_P_CI
Definition: bsmaster.h:686
#define AHCI_DEV_SEL_PM
Definition: bsmaster.h:803
#define ATA_AHCI_P_CMD_FRE
Definition: bsmaster.h:702
#define ATA_AHCI_P_CMD_ATAPI
Definition: bsmaster.h:713
#define ATA_IMMEDIATE
Definition: bsmaster.h:55
#define AHCI_CAP_NOP_MASK
Definition: bsmaster.h:200
#define SATA_MAX_PM_UNITS
Definition: bsmaster.h:110
#define AHCI_FIS_COMM_PM
Definition: bsmaster.h:799
#define ATA_AHCI_P_CMD_CR
Definition: bsmaster.h:706
#define SStatus_SPD_Gen3
Definition: bsmaster.h:294
#define CTRFLAGS_NO_SLAVE
Definition: bsmaster.h:1139
#define IDX_AHCI_GHC
Definition: bsmaster.h:271
#define IDX_AHCI_P_TFD
Definition: bsmaster.h:687
#define IDX_SATA_SError
Definition: bsmaster.h:458
#define IDX_SATA_SStatus
Definition: bsmaster.h:457
#define IDX_AHCI_P_SControl
Definition: bsmaster.h:691
#define ATA_AHCI_P_CMD_POD
Definition: bsmaster.h:700
#define IDX_AHCI_o_BlockNumber
Definition: bsmaster.h:787
#define AHCI_BOHC_BOS
Definition: bsmaster.h:263
#define IDX_AHCI_P_IS
Definition: bsmaster.h:684
#define REQ_FLAG_READ
Definition: bsmaster.h:935
#define ATA_AHCI_P_CMD_PMA
Definition: bsmaster.h:708
#define ATA_AHCI_P_IX_PS
Definition: bsmaster.h:500
#define ATA_AHCI_P_IX_OF
Definition: bsmaster.h:510
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989
Definition: bufpool.h:45
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1230
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CI(cs)
Definition: fontdlg.c:68
static const WCHAR version[]
Definition: asmname.c:66
#define ULONGIO_PTR
Definition: config.h:102
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:401
#define SRB_FLAGS_DATA_IN
Definition: srb.h:400
#define KdPrint(x)
Definition: env_spec_w32.h:288
#define KdDump(a, b)
Definition: env_spec_w32.h:312
Status
Definition: gdiplustypes.h:25
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble n
Definition: glext.h:7729
const GLubyte * c
Definition: glext.h:8905
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat GLfloat p
Definition: glext.h:8902
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define IDE_STATUS_WRONG
Definition: hwide.h:121
#define IDE_DC_USE_HOB
Definition: hwide.h:141
#define IDE_USE_LBA
Definition: hwide.h:133
#define IDE_STATUS_BUSY
Definition: hwide.h:119
#define IDE_STATUS_ERROR
Definition: hwide.h:110
#define IDE_STATUS_SUCCESS
Definition: hwide.h:109
#define IDE_DRIVE_SELECT_1
Definition: hwide.h:130
#define IDE_DC_RESET_CONTROLLER
Definition: hwide.h:139
#define IDX_IO1_i_Status
Definition: hwide.h:48
#define IDE_STATUS_DRQ
Definition: hwide.h:113
#define IDX_IO1_i_CylinderLow
Definition: hwide.h:45
#define IDX_IO1_i_BlockCount
Definition: hwide.h:43
#define IDX_IO1_i_CylinderHigh
Definition: hwide.h:46
#define IDE_DC_A_4BIT
Definition: hwide.h:140
#define IDE_STATUS_IDLE
Definition: hwide.h:118
#define IDX_IO1_i_Error
Definition: hwide.h:42
VOID NTAPI UniataAhciStartFR(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:2024
VOID NTAPI UniataAhciResume(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:2390
BOOLEAN NTAPI UniataAhciStop(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:2140
PSCSI_REQUEST_BLOCK NTAPI BuildAhciInternalSrb(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN PUCHAR Buffer, IN ULONG Length)
Definition: id_sata.cpp:2644
UCHAR NTAPI UniataAhciWritePM(IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN ULONG Reg, IN ULONG value)
Definition: id_sata.cpp:2547
VOID NTAPI UniataAhciStart(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:2071
VOID NTAPI UniataSataWritePort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG data, IN ULONG pm_port)
Definition: id_sata.cpp:357
ULONG NTAPI UniataAhciSetupFIS_H2D(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, OUT PUCHAR fis, IN UCHAR command, IN ULONGLONG lba, IN USHORT count, IN USHORT feature)
Definition: id_sata.cpp:1241
BOOLEAN NTAPI UniataAhciReadPM(IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN ULONG Reg, OUT PULONG result)
Definition: id_sata.cpp:2491
ULONG NTAPI UniataAhciWaitReady(IN PHW_CHANNEL chan, IN ULONG timeout)
Definition: id_sata.cpp:1853
ULONG NTAPI UniataSataSoftReset(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_sata.cpp:476
UCHAR NTAPI UniataAhciStatus(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_sata.cpp:1131
BOOLEAN NTAPI UniataAhciDetect(IN PVOID HwDeviceExtension, IN PPCI_COMMON_CONFIG pciData, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo)
Definition: id_sata.cpp:890
ULONG NTAPI UniataAhciHardReset(IN PVOID HwDeviceExtension, IN ULONG lChannel, OUT PULONG signature)
Definition: id_sata.cpp:1880
VOID NTAPI UniataAhciSnapAtaRegs(IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN OUT PIDEREGS_EX regs)
Definition: id_sata.cpp:1216
UCHAR NTAPI UniataAhciSendCommand(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN USHORT ahci_flags, IN ULONG timeout)
Definition: id_sata.cpp:1496
VOID NTAPI UniataAhciReset(IN PVOID HwDeviceExtension, IN ULONG lChannel)
Definition: id_sata.cpp:1925
UCHAR NTAPI UniataSataConnect(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG pm_port)
Definition: id_sata.cpp:44
BOOLEAN NTAPI UniAtaAhciValidateVersion(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG version, IN BOOLEAN Strict)
Definition: id_sata.cpp:860
VOID UniataSataIdentifyPM(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:491
UCHAR NTAPI UniataAhciBeginTransaction(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_sata.cpp:2171
UCHAR NTAPI UniataSataPhyEnable(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG pm_port, IN BOOLEAN doReset)
Definition: id_sata.cpp:124
BOOLEAN NTAPI UniataAhciStopFR(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:2042
BOOLEAN NTAPI UniataAhciCLO(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:2102
UCHAR NTAPI UniataAhciSendPIOCommand(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb, IN PUCHAR data, IN ULONG length, IN UCHAR command, IN ULONGLONG lba, IN USHORT bcount, IN USHORT feature, IN USHORT ahci_flags, IN ULONG wait_flags, IN ULONG timeout)
Definition: id_sata.cpp:1538
BOOLEAN NTAPI UniataSataClearErr(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN BOOLEAN do_connect, IN ULONG pm_port)
Definition: id_sata.cpp:186
UCHAR NTAPI UniataSataWritePM(IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN ULONG Reg, IN ULONG value)
Definition: id_sata.cpp:461
UCHAR NTAPI UniataAhciWaitCommandReady(IN PHW_CHANNEL chan, IN ULONG timeout)
Definition: id_sata.cpp:1434
BOOLEAN NTAPI UniataAhciAbortOperation(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:1765
ULONG NTAPI UniataAhciSoftReset(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_sata.cpp:1787
UCHAR NTAPI UniataAhciSendPIOCommandDirect(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb, IN PIDEREGS_EX regs, IN ULONG wait_flags, IN ULONG timeout)
Definition: id_sata.cpp:1655
ULONG NTAPI UniataSataReadPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG pm_port)
Definition: id_sata.cpp:270
BOOLEAN NTAPI UniataSataReadPM(IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN ULONG Reg, OUT PULONG result)
Definition: id_sata.cpp:446
ULONG NTAPI UniataAhciSetupFIS_H2D_Direct(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, OUT PUCHAR fis, IN PIDEREGS_EX regs)
Definition: id_sata.cpp:1341
BOOLEAN NTAPI UniataSataEvent(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG Action, IN ULONG pm_port)
Definition: id_sata.cpp:233
VOID UniataAhciSetupCmdPtr(IN OUT PATA_REQ AtaReq)
Definition: id_sata.cpp:2611
BOOLEAN NTAPI UniataAhciInit(IN PVOID HwDeviceExtension)
Definition: id_sata.cpp:645
UCHAR NTAPI UniataAhciEndTransaction(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_sata.cpp:2294
__inline ULONG UniataAhciUlongFromRFIS(PUCHAR RCV_FIS)
Definition: id_sata.h:345
__inline ULONG UniataAhciReadChannelPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx)
Definition: id_sata.h:290
#define UNIATA_SATA_EVENT_ATTACH
Definition: id_sata.h:72
__inline USHORT UniAtaAhciAdjustIoFlags(IN UCHAR command, IN USHORT ahci_flags, IN ULONG fis_size, IN ULONG DeviceNumber)
Definition: id_sata.h:357
#define UNIATA_SATA_RESET_ENABLE
Definition: id_sata.h:48
__inline BOOLEAN UniataAhciChanImplemented(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG c)
Definition: id_sata.h:415
__inline BOOLEAN UniataIsSATARangeAvailable(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG lChannel)
Definition: id_sata.h:91
#define UNIATA_SATA_EVENT_DETACH
Definition: id_sata.h:73
#define UniataAhciWriteHostPort4(deviceExtension, io_port_ndx, data)
Definition: id_sata.h:316
__inline VOID UniataAhciWriteChannelPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG data)
Definition: id_sata.h:302
#define UniataAhciReadHostPort4(deviceExtension, io_port_ndx)
Definition: id_sata.h:313
#define d
Definition: ke_i.h:81
#define c
Definition: ke_i.h:80
INTERNETFEATURELIST feature
Definition: misc.c:1719
#define min(a, b)
Definition: monoChain.cc:55
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
struct @4800 regs[]
#define CMD
Definition: stat64.c:23
ULONG ChannelCtrlFlags
Definition: bsmaster.h:1059
ULONG AhciPrevCI
Definition: bsmaster.h:1106
IORES BaseIoAHCI_Port
Definition: bsmaster.h:1105
PATA_REQ AhciInternalAtaReq
Definition: bsmaster.h:1113
ULONG lChannel
Definition: bsmaster.h:1064
ULONG PmLunMap
Definition: bsmaster.h:1091
ULONG AhciLastIS
Definition: bsmaster.h:1108
IORES RegTranslation[IDX_MAX_REG]
Definition: bsmaster.h:1127
ULONG AhciLastSError
Definition: bsmaster.h:1109
struct _HW_LU_EXTENSION * lun[IDE_MAX_LUN_PER_CHAN]
Definition: bsmaster.h:1088
ULONGLONG AHCI_CTL_PhAddr
Definition: bsmaster.h:1104
ULONG AhciCompleteCI
Definition: bsmaster.h:1107
PIDE_AHCI_CHANNEL_CTL_BLOCK AhciCtlBlock
Definition: bsmaster.h:1103
PSCSI_REQUEST_BLOCK AhciInternalSrb
Definition: bsmaster.h:1114
ULONG MaxTransferMode
Definition: bsmaster.h:1057
ULONG NumberChannels
Definition: atapi.c:68
ULONG DmaSegmentAlignmentMask
Definition: bsmaster.h:1320
PHW_CHANNEL chan
Definition: bsmaster.h:1257
IDE_AHCI_CMD_LIST cmd_list[ATA_AHCI_MAX_TAGS]
Definition: bsmaster.h:846
IDE_AHCI_RCV_FIS rcv_fis
Definition: bsmaster.h:847
ULONGLONG cmd_table_phys
Definition: bsmaster.h:827
UCHAR cfis[64]
Definition: bsmaster.h:807
struct _IDE_AHCI_PORT_REGISTERS::@1102::@1122::@1124 STS
Definition: bsmaster.h:724
UCHAR rfis[20]
Definition: bsmaster.h:837
ULONG MemIo
Definition: bsmaster.h:1013
ULONG Addr
Definition: bsmaster.h:1009
ULONG TimeOutValue
Definition: srb.h:262
UCHAR TargetId
Definition: srb.h:254
PVOID DataBuffer
Definition: srb.h:263
UCHAR PathId
Definition: srb.h:253
UCHAR CdbLength
Definition: srb.h:258
UCHAR Function
Definition: srb.h:250
ULONG DataTransferLength
Definition: srb.h:261
PVOID SrbExtension
Definition: srb.h:267
ULONG SrbFlags
Definition: srb.h:260
USHORT Length
Definition: srb.h:249
Definition: ftp_var.h:139
Definition: ecma_167.h:138
Definition: dhcpd.h:245
#define max(a, b)
Definition: svc.c:63
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define ATA_FLAGS_48BIT_COMMAND
Definition: uata_ctl.h:223
#define lba
#define IDE_COMMAND_WRITE_PM
Definition: atapi.h:402
#define INTERRUPT_REASON_UNEXPECTED
Definition: atapi.h:1280
ULONG NTAPI AtapiRegCheckDevValue(IN PVOID HwDeviceExtension, IN ULONG chan, IN ULONG dev, IN PCWSTR Name, IN ULONG Default)
Definition: id_ata.cpp:11365
#define UniAta_need_lba48(command, lba, count, supp48)
Definition: atapi.h:1609
#define ATAPI_DEVICE(chan, dev)
Definition: atapi.h:1624
#define ATA_CMD_FLAG_FUA
Definition: atapi.h:1601
#define IDX_IO2_AltStatus
Definition: atapi.h:225
#define ATA_SA150
Definition: atapi.h:337
#define AtapiStallExecution(dt)
Definition: atapi.h:158
#define ATA_F_DMA
Definition: atapi.h:557
#define KdPrint3(_x_)
Definition: atapi.h:153
ULONG NTAPI CheckDevice(IN PVOID HwDeviceExtension, IN ULONG Channel, IN ULONG deviceNumber, IN BOOLEAN ResetBus)
Definition: id_probe.cpp:2897
#define KdPrint2(_x_)
Definition: atapi.h:154
#define DEVNUM_NOT_SPECIFIED
Definition: atapi.h:1483
#define INTERRUPT_REASON_IGNORE
Definition: atapi.h:1278
#define ATA_CMD_FLAG_48
Definition: atapi.h:1599
#define ATA_CMD_FLAG_48supp
Definition: atapi.h:1598
#define CHAN_NOT_SPECIFIED
Definition: atapi.h:1481
UCHAR DDKFASTAPI WaitOnBaseBusyLong(IN struct _HW_CHANNEL *chan)
VOID NTAPI UniataInitSyncBaseIO(IN struct _HW_CHANNEL *chan)
#define IDE_COMMAND_READ_PM
Definition: atapi.h:399
#define UniAtaClearAtaReq(AtaReq)
Definition: atapi.h:1615
#define PRINT_PREFIX
Definition: atapi.h:150
#define INTERRUPT_REASON_OUR
Definition: atapi.h:1279
#define ATA_CMD_FLAG_LBAIOsupp
Definition: atapi.h:1597
ULONG PRCS
Definition: bsmaster.h:484
ULONG CPDS
Definition: bsmaster.h:494
ULONG Reg
Definition: bsmaster.h:496
ULONG PCS
Definition: bsmaster.h:480
struct _ATA_REQ::@1141::@1143::@1147::@1150 ahci
ULONG WordsTransfered
Definition: bsmaster.h:886
PSCSI_REQUEST_BLOCK Srb
Definition: bsmaster.h:880
PUSHORT DataBuffer
Definition: bsmaster.h:882
ULONG TransferLength
Definition: bsmaster.h:884
ULONG dma_entries
Definition: bsmaster.h:897
UCHAR Flags
Definition: bsmaster.h:892
Definition: pdh_main.c:94
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
unsigned char UCHAR
Definition: xmlstorage.h:181