ReactOS  0.4.13-dev-563-g0561610
id_sata.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 2008-2019 Alexandr A. Telyatnikov (Alter)
4 
5 Module Name:
6  id_probe.cpp
7 
8 Abstract:
9  This module handles SATA- and AHCI-related staff
10 
11 Author:
12  Alexander A. Telyatnikov (Alter)
13 
14 Environment:
15  kernel mode only
16 
17 Notes:
18 
19  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 Revision History:
31 
32  SATA support
33  AHCI support
34 
35 Licence:
36  GPLv2
37 
38 --*/
39 
40 #include "stdafx.h"
41 
42 UCHAR
43 NTAPI
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 */
59  UCHAR Status;
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  }
97  AtapiStallExecution(10000);
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 
107  Status = WaitOnBaseBusyLong(chan);
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 
122 UCHAR
123 NTAPI
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);
157  AtapiStallExecution(100);
158  SControl.Reg = UniataSataReadPort4(chan, IDX_SATA_SControl, pm_port);
159  KdPrint2((PRINT_PREFIX " SControl %8.8x\n", SControl.Reg));
160  if(SControl.DET == SControl_DET_Init) {
161  break;
162  }
163  }
164  AtapiStallExecution(5000);
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);
171  AtapiStallExecution(100);
172  SControl.Reg = UniataSataReadPort4(chan, IDX_SATA_SControl, pm_port);
173  KdPrint2((PRINT_PREFIX " SControl %8.8x\n", SControl.Reg));
174  if(SControl.DET == SControl_DET_Idle) {
175  return UniataSataConnect(HwDeviceExtension, lChannel, pm_port);
176  }
177  }
178  }
179 
180  KdPrint2((PRINT_PREFIX "UniataSataPhyEnable: failed\n"));
181  return IDE_STATUS_WRONG;
182 } // end UniataSataPhyEnable()
183 
184 BOOLEAN
185 NTAPI
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 
231 BOOLEAN
232 NTAPI
234  IN PVOID HwDeviceExtension,
235  IN ULONG lChannel, // logical channel
236  IN ULONG Action,
237  IN ULONG pm_port /* for port multipliers */
238  )
239 {
240  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
241  UCHAR Status;
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 
268 ULONG
269 NTAPI
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;
302  case IDX_SATA_SControl:
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;
322  case IDX_SATA_SControl:
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;
336  case IDX_SATA_SControl:
337  offs += 1;
338  break;
339  case IDX_SATA_SError:
340  offs += 2;
341  break;
342  default:
343  return -1;
344  }
345  AtapiWritePort4(chan, IDX_INDEXED_ADDR, offs);
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 
355 VOID
356 NTAPI
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;
390  case IDX_SATA_SControl:
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;
410  case IDX_SATA_SControl:
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;
425  case IDX_SATA_SControl:
426  offs += 1;
427  break;
428  case IDX_SATA_SError:
429  offs += 2;
430  break;
431  default:
432  return;
433  }
434  AtapiWritePort4(chan, IDX_INDEXED_ADDR, offs);
436  }
437  } // ATA_INTEL_ID
438  } // end switch(VendorID)
439  return;
440  }
441  AtapiWritePort4(chan, io_port_ndx, data);
442 } // end UniataSataWritePort4()
443 
444 BOOLEAN
445 NTAPI
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 
459 UCHAR
460 NTAPI
462  IN PHW_CHANNEL chan,
464  IN ULONG Reg,
465  IN ULONG value
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 
474 ULONG
475 NTAPI
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 
490 VOID
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) {
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:
577  LunExt->DeviceFlags |= DFLAGS_ATAPI_DEVICE;
578  continue;
579  }
580 
581  }
582 
583 } // end UniataSataIdentifyPM()
584 
585 #ifdef _DEBUG
586 VOID
587 NTAPI
588 UniataDumpAhciRegs(
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 
613 VOID
614 NTAPI
615 UniataDumpAhciPortRegs(
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 
643 BOOLEAN
644 NTAPI
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  ULONG BaseMemAddress;
654  ULONG PI;
655  ULONG CAP;
656  ULONG CAP2;
657  ULONG BOHC;
658  ULONG GHC;
659  BOOLEAN MemIo = FALSE;
660 
661  KdPrint2((PRINT_PREFIX " UniataAhciInit:\n"));
662 
663 #ifdef _DEBUG
664  UniataDumpAhciRegs(deviceExtension);
665 #endif //_DEBUG
666 
667  CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2);
668  if(CAP2 & AHCI_CAP2_BOH) {
669  BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
670  KdPrint2((PRINT_PREFIX " stage 1 BOHC %#x\n", BOHC));
671  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_BOHC,
672  BOHC | AHCI_BOHC_OOS);
673  for(i=0; i<50; i++) {
674  AtapiStallExecution(500);
675  BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
676  KdPrint2((PRINT_PREFIX " BOHC %#x\n", BOHC));
677  if(BOHC & AHCI_BOHC_BB) {
678  break;
679  }
680  if(!(BOHC & AHCI_BOHC_BOS)) {
681  break;
682  }
683  }
684  KdPrint2((PRINT_PREFIX " stage 2 BOHC %#x\n", BOHC));
685  if(BOHC & AHCI_BOHC_BB) {
686  for(i=0; i<2000; i++) {
687  AtapiStallExecution(1000);
688  BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
689  KdPrint2((PRINT_PREFIX " BOHC %#x\n", BOHC));
690  if(!(BOHC & AHCI_BOHC_BOS)) {
691  break;
692  }
693  }
694  }
695  KdPrint2((PRINT_PREFIX " final BOHC %#x\n", BOHC));
696  }
697 
698  /* disable AHCI interrupts, for MSI compatibility issue
699  see http://www.intel.com/Assets/PDF/specupdate/307014.pdf
700  26. AHCI Reset and MSI Request
701  */
702 
703  KdPrint2((PRINT_PREFIX " get GHC\n"));
704  /* enable AHCI mode */
705  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
706  if(!(GHC & AHCI_GHC_AE)) {
707  KdPrint2((PRINT_PREFIX " enable AHCI mode, disable intr, GHC %#x\n", GHC));
708  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
709  (GHC | AHCI_GHC_AE) & ~AHCI_GHC_IE);
710  } else {
711  KdPrint2((PRINT_PREFIX " disable intr, GHC %#x\n", GHC));
712  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
713  GHC & ~AHCI_GHC_IE);
714  }
715  AtapiStallExecution(100);
716 
717  /* read GHC again and reset AHCI controller */
718  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
719  KdPrint2((PRINT_PREFIX " reset AHCI controller, GHC %#x\n", GHC));
720  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
721  GHC | AHCI_GHC_HR);
722 
723  for(i=0; i<1000; i++) {
724  AtapiStallExecution(1000);
725  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
726  KdPrint2((PRINT_PREFIX " AHCI GHC %#x\n", GHC));
727  if(!(GHC & AHCI_GHC_HR)) {
728  break;
729  }
730  }
731  if(GHC & AHCI_GHC_HR) {
732  KdPrint2((PRINT_PREFIX " AHCI reset failed\n"));
733  return FALSE;
734  }
735 
736  /* re-enable AHCI mode */
737  /* Linux: Some controllers need AHCI_EN to be written multiple times.
738  * Try a few times before giving up.
739  */
740  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
741  for(i=0; i<5; i++) {
742  if(!(GHC & AHCI_GHC_AE)) {
743  KdPrint2((PRINT_PREFIX " re-enable AHCI mode, GHC %#x\n", GHC));
744  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
745  GHC | AHCI_GHC_AE);
746  AtapiStallExecution(1000);
747  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
748  } else {
749  break;
750  }
751  }
752  KdPrint2((PRINT_PREFIX " AHCI GHC %#x\n", GHC));
753  if(!(GHC & AHCI_GHC_AE)) {
754  KdPrint2((PRINT_PREFIX " Can't enable AHCI mode\n"));
755  return FALSE;
756  }
757 
758  deviceExtension->AHCI_CAP =
759  CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
760  KdPrint2((PRINT_PREFIX " AHCI CAP %#x\n", CAP));
761  if(CAP & AHCI_CAP_S64A) {
762  KdPrint2((PRINT_PREFIX " AHCI 64bit\n"));
763  deviceExtension->Host64 = TRUE;
764  }
765  KdPrint2((PRINT_PREFIX " AHCI %d CMD slots\n", (CAP & AHCI_CAP_NCS_MASK) >> 8 ));
766  if(CAP & AHCI_CAP_PMD) {
767  KdPrint2((PRINT_PREFIX " AHCI multi-block PIO\n"));
768  }
769  if(CAP & AHCI_CAP_SAM) {
770  KdPrint2((PRINT_PREFIX " AHCI legasy SATA\n"));
771  }
772 
773  /* get the number of HW channels */
774  PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI);
775  deviceExtension->AHCI_PI = PI;
776  KdPrint2((PRINT_PREFIX " AHCI PI %#x\n", PI));
777  KdPrint2((PRINT_PREFIX " AHCI PI mask %#x\n", deviceExtension->AHCI_PI_mask));
778  deviceExtension->AHCI_PI = PI = PI & deviceExtension->AHCI_PI_mask;
779  KdPrint2((PRINT_PREFIX " masked AHCI PI %#x\n", PI));
780 
781  CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2);
782  if(CAP2 & AHCI_CAP2_BOH) {
783  KdPrint2((PRINT_PREFIX " retry BOHC\n"));
784  BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
785  KdPrint2((PRINT_PREFIX " BOHC %#x\n", BOHC));
786  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_BOHC,
787  BOHC | AHCI_BOHC_OOS);
788  }
789  /* clear interrupts */
790  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_IS,
791  UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS));
792 
793  /* enable AHCI interrupts */
794  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
795  UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC) | AHCI_GHC_IE);
796 
797  BaseMemAddress = deviceExtension->BaseIoAHCI_0.Addr;
798  MemIo = deviceExtension->BaseIoAHCI_0.MemIo;
799 
800  deviceExtension->MaxTransferMode = ATA_SA150+(((CAP & AHCI_CAP_ISS_MASK) >> 20)-1);
801  KdPrint2((PRINT_PREFIX " SATA Gen %d\n", ((CAP & AHCI_CAP_ISS_MASK) >> 20) ));
802 
803  for(c=0; c<deviceExtension->NumberChannels; c++) {
804  chan = &deviceExtension->chan[c];
805  offs = sizeof(IDE_AHCI_REGISTERS) + c*sizeof(IDE_AHCI_PORT_REGISTERS);
806 
807  KdPrint2((PRINT_PREFIX " chan %d, offs %#x\n", c, offs));
808 
809  chan->MaxTransferMode = deviceExtension->MaxTransferMode;
810 
811  AtapiSetupLunPtrs(chan, deviceExtension, c);
812 
813  chan->BaseIoAHCI_Port = deviceExtension->BaseIoAHCI_0;
814  chan->BaseIoAHCI_Port.Addr = BaseMemAddress + offs;
815 
816  chan->RegTranslation[IDX_IO1_i_Status ].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, TFD.STS);
817  chan->RegTranslation[IDX_IO1_i_Status ].MemIo = MemIo;
819  chan->RegTranslation[IDX_IO1_i_Error ].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, TFD.ERR);
820  chan->RegTranslation[IDX_IO1_i_Error ].MemIo = MemIo;
826  chan->RegTranslation[IDX_IO1_i_BlockCount ].MemIo = MemIo;
827 
828  UniataInitSyncBaseIO(chan);
829 
830  chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SSTS);
831  chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo;
832  chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SERR);
833  chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo;
834  chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SCTL);
835  chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo;
836  chan->RegTranslation[IDX_SATA_SActive].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SACT);
837  chan->RegTranslation[IDX_SATA_SActive].MemIo = MemIo;
838 
839  AtapiDmaAlloc(HwDeviceExtension, NULL, c);
840 
841  if(!UniataAhciChanImplemented(deviceExtension, c)) {
842  KdPrint2((PRINT_PREFIX " chan %d not implemented\n", c));
843  continue;
844  }
845 
846  UniataAhciResume(chan);
847 
849  }
850 
851  return TRUE;
852 } // end UniataAhciInit()
853 
854 BOOLEAN
855 NTAPI
857  IN PHW_DEVICE_EXTENSION deviceExtension,
858  IN ULONG version,
859  IN BOOLEAN Strict
860  )
861 {
862  switch(version) {
863  case 0x00000000:
864  case 0xffffffff:
865  KdPrint((" wrong AHCI revision %#x\n", version));
866  return FALSE;
867  case 0x00000905:
868  case 0x00010000:
869  case 0x00010100:
870  case 0x00010200:
871  case 0x00010300:
872  case 0x00010301:
873  break;
874  default:
875  KdPrint2((PRINT_PREFIX " Unknown AHCI revision\n"));
876  if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"CheckAhciRevision", Strict)) {
877  KdPrint((" AHCI revision excluded %#x\n", version));
878  return FALSE;
879  }
880  }
881  return TRUE;
882 } // end UniAtaAhciValidateVersion()
883 
884 BOOLEAN
885 NTAPI
887  IN PVOID HwDeviceExtension,
888  IN PPCI_COMMON_CONFIG pciData, // optional
890  )
891 {
892  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
893  //ULONG slotNumber = deviceExtension->slotNumber;
894  ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
895  ULONG version;
896  ULONG i, n;
897  ULONG PI;
898  //ULONG PI_ex_mask=0;
899  ULONG CAP;
900  ULONG CAP2;
901  ULONG GHC, GHC0;
902 #ifdef _DEBUG
903  ULONG BOHC;
904  ULONG v_Mn, v_Mj;
905 #endif //_DEBUG
906  ULONG NumberChannels;
907  ULONG_PTR BaseMemAddress;
908  BOOLEAN MemIo = FALSE;
909  BOOLEAN found = FALSE;
910  ULONG BarId=5;
911 
912  KdPrint2((PRINT_PREFIX " UniataAhciDetect:\n"));
913 
914  if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreAhci", 0)) {
915  KdPrint((" AHCI excluded\n"));
916  return FALSE;
917  }
918  switch(deviceExtension->DevID) {
919  case 0xa01c0031:
920  KdPrint2((PRINT_PREFIX " Cavium uses BAR(0)\n"));
921  BarId = 0;
922  break;
923  }
924  BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
925  BarId, 0, 0x10);
926  if(!BaseMemAddress) {
927  KdPrint2((PRINT_PREFIX " AHCI init failed - no IoRange\n"));
928  return FALSE;
929  }
930  if((*ConfigInfo->AccessRanges)[BarId].RangeInMemory) {
931  KdPrint2((PRINT_PREFIX "MemIo\n"));
932  MemIo = TRUE;
933  }
934  deviceExtension->BaseIoAHCI_0.Addr = BaseMemAddress;
935  deviceExtension->BaseIoAHCI_0.MemIo = MemIo;
936 
937 #ifdef _DEBUG
938  UniataDumpAhciRegs(deviceExtension);
939 #endif //_DEBUG
940 
941  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
942  if(GHC & AHCI_GHC_HR) {
943  KdPrint2((PRINT_PREFIX " AHCI in reset state\n"));
944  return FALSE;
945  }
946 
947  /* check AHCI mode. Save state and try enable */
948  GHC0 =
949  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
950  KdPrint2((PRINT_PREFIX " check AHCI mode, GHC %#x\n", GHC));
951 
952  version = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_VS);
953 
954  if(!(GHC & AHCI_GHC_AE)) {
955  KdPrint2((PRINT_PREFIX " Non-AHCI GHC (!AE), check revision %#x\n", version));
956  if(!UniAtaAhciValidateVersion(deviceExtension, version, FALSE)) {
957  KdPrint2((PRINT_PREFIX " Non-AHCI\n"));
958  goto exit_detect;
959  }
960  KdPrint2((PRINT_PREFIX " try enable\n"));
961  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
962  (GHC | AHCI_GHC_AE) & ~AHCI_GHC_IE);
963  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
964 
965  KdPrint2((PRINT_PREFIX " re-check AHCI mode, GHC %#x\n", GHC));
966  if(!(GHC & AHCI_GHC_AE)) {
967  KdPrint2((PRINT_PREFIX " Non-AHCI GHC (!AE)\n"));
968  goto exit_detect;
969  }
970  }
971 
972  CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
973  CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2);
974  KdPrint2((PRINT_PREFIX " AHCI CAP %#x, CAP2 %#x, ver %#x\n", CAP, CAP2, version));
975  if(CAP & AHCI_CAP_S64A) {
976  KdPrint2((PRINT_PREFIX " 64bit"));
977  //deviceExtension->Host64 = TRUE; // this is just DETECT, do not update anything
978  }
979 #ifdef _DEBUG
980  if(CAP2 & AHCI_CAP2_BOH) {
981  BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
982  KdPrint2((PRINT_PREFIX " BOHC %#x", BOHC));
983  }
984 #endif //_DEBUG
985  if(CAP & AHCI_CAP_NCQ) {
986  KdPrint2((PRINT_PREFIX " NCQ"));
987  }
988  if(CAP & AHCI_CAP_SNTF) {
989  KdPrint2((PRINT_PREFIX " SNTF"));
990  }
991  if(CAP & AHCI_CAP_CCC) {
992  KdPrint2((PRINT_PREFIX " CCC"));
993  }
994  KdPrint2((PRINT_PREFIX "\n"));
995 
996  /* get the number of HW channels */
997 
998  /* CAP.NOP sometimes indicate the index of the last enabled
999  * port, at other times, that of the last possible port, so
1000  * determining the maximum port number requires looking at
1001  * both CAP.NOP and PI.
1002  */
1003  PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI);
1004  deviceExtension->AHCI_PI = deviceExtension->AHCI_PI_mask = PI;
1005  KdPrint2((PRINT_PREFIX " AHCI PI %#x\n", PI));
1006 
1007  for(i=PI, n=0; i; n++, i=i>>1) {
1008  if(AtapiRegCheckDevValue(deviceExtension, n, DEVNUM_NOT_SPECIFIED, L"Exclude", 0)) {
1009  KdPrint2((PRINT_PREFIX "Channel %d excluded\n", n));
1010  deviceExtension->AHCI_PI &= ~((ULONG)1 << n);
1011  deviceExtension->AHCI_PI_mask &= ~((ULONG)1 << n);
1012  //PI_ex_mask |= ((ULONG)1 << n);
1013  }
1014  }
1015  deviceExtension->AHCI_PI_mask =
1016  AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PortMask", deviceExtension->AHCI_PI_mask);
1017  KdPrint2((PRINT_PREFIX "Force PortMask %#x\n", deviceExtension->AHCI_PI_mask));
1018 
1019  for(i=PI, n=0; i; n++, i=i>>1);
1020  NumberChannels =
1021  max((CAP & AHCI_CAP_NOP_MASK)+1, n);
1022 
1023  if(!PI && ((CAP & AHCI_CAP_NOP_MASK)+1)) {
1024  /* Enable ports.
1025  * The spec says that BIOS sets up bits corresponding to
1026  * available ports. On platforms where this information
1027  * is missing, the driver can define available ports on its own.
1028  */
1029  KdPrint2((PRINT_PREFIX "PI=0 -> Enable ports (mask) %#x\n", deviceExtension->AHCI_PI_mask));
1030  n = NumberChannels;
1031  deviceExtension->AHCI_PI = ((ULONG)1 << n)-1;
1032 
1033  if(deviceExtension->AHCI_PI_mask) {
1034  // we have some forced port mask
1035  PI = deviceExtension->AHCI_PI_mask;
1036  } else {
1037  // construct mask
1038  PI = deviceExtension->AHCI_PI = (((ULONG)1 << n)-1);
1039  deviceExtension->AHCI_PI_mask = (((ULONG)1 << n)-1);
1040  }
1041  KdPrint2((PRINT_PREFIX "Enable ports final PI %#x\n", PI));
1042  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_PI, PI);
1043  }
1044 
1045  KdPrint2((PRINT_PREFIX " CommandSlots %d\n", (CAP & AHCI_CAP_NCS_MASK)>>8 ));
1046  KdPrint2((PRINT_PREFIX " Detected Channels %d / %d\n", NumberChannels, n));
1047 
1048  switch(deviceExtension->DevID) {
1049  case 0x2361197b:
1050  KdPrint2((PRINT_PREFIX " JMicron JMB361 -> 1\n"));
1051  NumberChannels = 1;
1052  break;
1053  case ATA_M88SE6111:
1054  KdPrint2((PRINT_PREFIX " Marvell M88SE6111 -> 1\n"));
1055  NumberChannels = 1;
1056  break;
1057  case ATA_M88SE6121:
1058  KdPrint2((PRINT_PREFIX " Marvell M88SE6121 -> 2\n"));
1059  NumberChannels = min(NumberChannels, 2);
1060  break;
1061  case ATA_M88SE6141:
1062  case ATA_M88SE6145:
1063  case ATA_M88SE9123:
1064  KdPrint2((PRINT_PREFIX " Marvell M88SE614x/9123 -> 4\n"));
1065  NumberChannels = min(NumberChannels, 4);
1066  break;
1067  } // switch()
1068 
1069  if(!NumberChannels) {
1070  KdPrint2((PRINT_PREFIX " Non-AHCI - NumberChannels=0\n"));
1071  found = FALSE;
1072  goto exit_detect;
1073  }
1074  KdPrint2((PRINT_PREFIX " Adjusted Channels %d\n", NumberChannels));
1075 
1076 #ifdef _DEBUG
1077  v_Mj = ((version >> 20) & 0xf0) + ((version >> 16) & 0x0f);
1078  v_Mn = ((version >> 4) & 0xf0) + (version & 0x0f);
1079 
1080  KdPrint2((PRINT_PREFIX " AHCI version %x.%02x controller with %d ports (mask %#x) detected\n",
1081  v_Mj, v_Mn,
1082  NumberChannels, PI));
1083  KdPrint((" AHCI SATA Gen %d\n", (((CAP & AHCI_CAP_ISS_MASK) >> 20)) ));
1084 #endif //_DEBUG
1085 
1086  if(CAP & AHCI_CAP_SPM) {
1087  KdPrint2((PRINT_PREFIX " PM supported\n"));
1088  if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreAhciPM", 1 /* DEBUG */)) {
1089  KdPrint2((PRINT_PREFIX "SATA/AHCI w/o PM, max luns 1\n"));
1090  deviceExtension->NumberLuns = 1;
1091  //chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
1092  } else {
1093  KdPrint2((PRINT_PREFIX "SATA/AHCI -> possible PM, max luns %d\n", SATA_MAX_PM_UNITS));
1094  deviceExtension->NumberLuns = SATA_MAX_PM_UNITS;
1095  //deviceExtension->NumberLuns = 1;
1096  }
1097  } else {
1098  KdPrint2((PRINT_PREFIX " PM not supported -> 1 lun/chan\n"));
1099  deviceExtension->NumberLuns = 1;
1100  }
1101 
1102  if(!UniAtaAhciValidateVersion(deviceExtension, version, TRUE)) {
1103  goto exit_detect;
1104  }
1105 
1106  deviceExtension->HwFlags |= UNIATA_SATA | UNIATA_AHCI;
1107  if(deviceExtension->NumberChannels < NumberChannels) {
1108  deviceExtension->NumberChannels = NumberChannels;
1109  }
1110  deviceExtension->DmaSegmentLength = 0x3fffff+1; // 4MB
1111  deviceExtension->DmaSegmentAlignmentMask = -1; // no restrictions
1112 
1113  deviceExtension->BusMaster = DMA_MODE_AHCI;
1114  deviceExtension->MaxTransferMode = max(deviceExtension->MaxTransferMode, ATA_SA150+(((CAP & AHCI_CAP_ISS_MASK) >> 20)-1) );
1115 
1116  found = TRUE;
1117 
1118 exit_detect:
1119  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC, GHC0);
1120  KdPrint((" AHCI detect status %d\n", found));
1121 
1122  return found;
1123 } // end UniataAhciDetect()
1124 
1125 UCHAR
1126 NTAPI
1128  IN PVOID HwDeviceExtension,
1129  IN ULONG lChannel,
1131  )
1132 {
1133  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1134  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1135  ULONG Channel = deviceExtension->Channel + lChannel;
1136  ULONG hIS;
1137  ULONG CI, ACT;
1138  AHCI_IS_REG IS;
1139  SATA_SSTATUS_REG SStatus;
1141  //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
1142  ULONG tag=0;
1143 
1144  KdPrint(("UniataAhciStatus(%d-%d):\n", lChannel, Channel));
1145 
1146  hIS = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS);
1147  KdPrint((" hIS %#x\n", hIS));
1148  hIS &= (1 << Channel);
1149  if(!hIS) {
1150  return INTERRUPT_REASON_IGNORE;
1151  }
1155  SStatus.Reg = AtapiReadPort4(chan, IDX_SATA_SStatus);
1156  SError.Reg = AtapiReadPort4(chan, IDX_SATA_SError);
1157 
1158  /* clear interrupt(s) */
1159  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_IS, hIS);
1162 
1163  KdPrint((" AHCI: is=%08x ss=%08x serror=%08x CI=%08x, ACT=%08x\n",
1164  IS.Reg, SStatus.Reg, SError.Reg, CI, ACT));
1165 
1166  /* do we have cold connect surprise */
1167  if(IS.CPDS) {
1168  }
1169 
1170  /* check for and handle connect events */
1171  if(IS.PCS) {
1172  UniataSataEvent(HwDeviceExtension, lChannel, UNIATA_SATA_EVENT_ATTACH);
1173  }
1174  if(IS.PRCS) {
1175  UniataSataEvent(HwDeviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH);
1176  }
1177  chan->AhciCompleteCI = (chan->AhciPrevCI ^ CI) & chan->AhciPrevCI; // only 1->0 states
1178  chan->AhciPrevCI = CI;
1179  chan->AhciLastSError = SError.Reg;
1180  KdPrint((" AHCI: complete mask %#x\n", chan->AhciCompleteCI));
1181  chan->AhciLastIS = IS.Reg;
1182  if(CI & (1 << tag)) {
1183 #ifdef _DEBUG
1184  UniataDumpAhciPortRegs(chan);
1185 #endif //_DEBUG
1186  //deviceExtension->ExpectingInterrupt++; // will be updated in ISR on ReturnEnableInterrupts
1187  if(IS.Reg &
1190  KdPrint((" AHCI: unexpected, error\n"));
1191  } else {
1192  KdPrint((" AHCI: unexpected, incomplete command or error ?\n"));
1193 /*
1194  ULONG TFD;
1195 
1196  TFD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_TFD);
1197  KdPrint2((" TFD %#x\n", TFD));
1198  if(TFD & IDE_STATUS_BUSY) {
1199  KdPrint2((" Seems to be interrupt on error\n"));
1200  return INTERRUPT_REASON_OUR;
1201  }
1202 */
1204  }
1205  }
1206  return INTERRUPT_REASON_OUR;
1207 
1208 } // end UniataAhciStatus()
1209 
1210 VOID
1211 NTAPI
1213  IN PHW_CHANNEL chan,
1216  )
1217 {
1218  ULONG TFD, SIG;
1219 
1220  regs->bDriveHeadReg = IDE_DRIVE_SELECT_1;
1222  regs->bCommandReg = (UCHAR)(TFD & 0xff);
1223  regs->bFeaturesReg = (UCHAR)((TFD >> 8) & 0xff);
1224 
1226  regs->bSectorCountReg = (UCHAR)(SIG & 0xff);
1227  regs->bSectorNumberReg = (UCHAR)((SIG >> 8) & 0xff);
1228  regs->bCylLowReg = (UCHAR)((SIG >> 16) & 0xff);
1229  regs->bCylHighReg = (UCHAR)((SIG >> 24) & 0xff);
1230  regs->bOpFlags = 0;
1231 
1232  return;
1233 } // end UniataAhciSnapAtaRegs()
1234 
1235 ULONG
1236 NTAPI
1238  IN PHW_DEVICE_EXTENSION deviceExtension,
1240  IN ULONG lChannel,
1241  OUT PUCHAR fis,
1242  IN UCHAR command,
1243  IN ULONGLONG lba,
1244  IN USHORT count,
1245  IN USHORT feature
1246  )
1247 {
1248  //ULONG i;
1249  PUCHAR plba;
1250  BOOLEAN need48;
1251  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1252 
1253  KdPrint2((PRINT_PREFIX " AHCI setup FIS %x, ch %d, dev %d\n", fis, lChannel, DeviceNumber));
1254  //i = 0;
1255  plba = (PUCHAR)&lba;
1256 
1257  RtlZeroMemory(fis, 20);
1258 
1259  fis[0] = AHCI_FIS_TYPE_ATA_H2D; /* host to device */
1260  fis[1] = 0x80 | ((UCHAR)DeviceNumber & 0x0f); /* command FIS (note PM goes here) */
1264 
1265  // IDE_COMMAND_ATAPI_IDENTIFY should be processed as regular ATA command,
1266  // the rest of ATAPI requests are processed via IDE_COMMAND_ATAPI_PACKET
1267  if(/*(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
1268  */
1271  if(feature & ATA_F_DMA) {
1272  fis[IDX_AHCI_o_Feature] = (UCHAR)(feature & 0xff);
1273  } else {
1274  fis[IDX_AHCI_o_CylinderLow] = (UCHAR)(count & 0xff);
1275  fis[IDX_AHCI_o_CylinderHigh] = (UCHAR)(count>>8) & 0xff;
1276  }
1277  //fis[IDX_AHCI_o_Control] |= IDE_DC_A_4BIT;
1278  } else {
1279 
1282  KdPrint3((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count));
1283  return 0;
1284  }
1285 
1286  need48 = UniAta_need_lba48(command, lba, count,
1287  chan->lun[DeviceNumber]->IdentifyData.FeaturesSupport.Address48);
1288 
1289  /* translate command into 48bit version */
1290  if(need48) {
1293  } else {
1294  KdPrint2((PRINT_PREFIX " unhandled LBA48 command\n"));
1295  return 0;
1296  }
1297  }
1298 
1299  fis[IDX_AHCI_o_Command] = command;
1301 
1302  fis[IDX_AHCI_o_BlockNumber] = plba[0];
1303  fis[IDX_AHCI_o_CylinderLow] = plba[1];
1304  fis[IDX_AHCI_o_CylinderHigh] = plba[2];
1305 
1306  fis[IDX_AHCI_o_BlockCount] = (UCHAR)count & 0xff;
1307 
1308  if(need48) {
1309  //i++;
1311 
1312  fis[IDX_AHCI_o_BlockNumberExp] = plba[3];
1313  fis[IDX_AHCI_o_CylinderLowExp] = plba[4];
1314  fis[IDX_AHCI_o_CylinderHighExp] = plba[5];
1315 
1316  fis[IDX_AHCI_o_BlockCountExp] = (UCHAR)(count>>8) & 0xff;
1317 
1318  fis[IDX_AHCI_o_FeatureExp] = (UCHAR)(feature>>8) & 0xff;
1319 
1321  } else {
1322  fis[IDX_AHCI_o_DriveSelect] |= /*IDE_DRIVE_1 |*/ (plba[3] & 0x0f);
1323  chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48;
1324  }
1325 
1326  //fis[14] = 0x00;
1327 
1328  }
1329 
1330  //KdDump(fis, 20);
1331 
1332  return 20;
1333 } // end UniataAhciSetupFIS_H2D()
1334 
1335 ULONG
1336 NTAPI
1338  IN PHW_DEVICE_EXTENSION deviceExtension,
1340  IN ULONG lChannel,
1341  OUT PUCHAR fis,
1343  )
1344 {
1345  //ULONG i;
1346  //PUCHAR plba;
1347  BOOLEAN need48;
1348  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1349  UCHAR command;
1350 
1351  command = regs->bCommandReg;
1352 
1353  KdPrint2((PRINT_PREFIX " AHCI setup FIS Direct %x, ch %d, dev %d\n", fis, lChannel, DeviceNumber));
1354  //i = 0;
1355  //plba = (PUCHAR)&lba;
1356 
1357  RtlZeroMemory(fis, 20);
1358 
1359  fis[0] = AHCI_FIS_TYPE_ATA_H2D; /* host to device */
1360  fis[1] = 0x80 | ((UCHAR)DeviceNumber & 0x0f); /* command FIS (note PM goes here) */
1364 
1365  // IDE_COMMAND_ATAPI_IDENTIFY should be processed as regular ATA command,
1366  // the rest of ATAPI requests are processed via IDE_COMMAND_ATAPI_PACKET
1367  if(/*(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
1368  */
1370 /* fis[IDX_AHCI_o_Command] = IDE_COMMAND_ATAPI_PACKET;
1371  if(feature & ATA_F_DMA) {
1372  fis[IDX_AHCI_o_Feature] = (UCHAR)(feature & 0xff);
1373  } else {
1374  fis[IDX_AHCI_o_CylinderLow] = (UCHAR)(count & 0xff);
1375  fis[IDX_AHCI_o_CylinderHigh] = (UCHAR)(count>>8) & 0xff;
1376  }*/
1377  return 0;
1378  //fis[IDX_AHCI_o_Control] |= IDE_DC_A_4BIT;
1379  } else {
1380 
1381  need48 = (regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND) &&
1382  chan->lun[DeviceNumber]->IdentifyData.FeaturesSupport.Address48;
1383 
1384  /* translate command into 48bit version */
1385  if(need48) {
1388  } else {
1389  KdPrint2((PRINT_PREFIX " unhandled LBA48 command\n"));
1390  return 0;
1391  }
1392  }
1393 
1394  fis[IDX_AHCI_o_Command] = command;
1395  fis[IDX_AHCI_o_Feature] = regs->bFeaturesReg;
1396 
1397  fis[IDX_AHCI_o_BlockNumber] = regs->bSectorNumberReg;
1398  fis[IDX_AHCI_o_CylinderLow] = regs->bCylLowReg;
1399  fis[IDX_AHCI_o_CylinderHigh] = regs->bCylHighReg;
1400 
1401  fis[IDX_AHCI_o_BlockCount] = regs->bSectorCountReg;
1402 
1403  if(need48) {
1404  //i++;
1406 
1407  fis[IDX_AHCI_o_BlockNumberExp] = regs->bSectorNumberRegH;
1408  fis[IDX_AHCI_o_CylinderLowExp] = regs->bCylLowRegH;
1409  fis[IDX_AHCI_o_CylinderHighExp] = regs->bCylHighRegH;
1410 
1411  fis[IDX_AHCI_o_BlockCountExp] = regs->bSectorCountRegH;
1412 
1413  fis[IDX_AHCI_o_FeatureExp] = regs->bFeaturesRegH;
1414 
1416  } else {
1417  //fis[IDX_AHCI_o_DriveSelect] |= /*IDE_DRIVE_1 |*/ (plba[3] & 0x0f);
1418  chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48;
1419  }
1420  fis[IDX_AHCI_o_DriveSelect] |= regs->bDriveHeadReg & 0x0f;
1421  }
1422 
1423  KdDump(fis, 20);
1424 
1425  return 20;
1426 } // end UniataAhciSetupFIS_H2D_Direct()
1427 
1428 UCHAR
1429 NTAPI
1431  IN PHW_CHANNEL chan,
1432  IN ULONG timeout
1433  )
1434 {
1435  AHCI_IS_REG IS;
1436  //ULONG ACT;
1437  ULONG CI=0;
1438  ULONG i;
1439  ULONG SError;
1440  ULONG tag=0;
1441 
1442  timeout *= 5;
1443 
1444  for (i=0; i<timeout; i++) {
1446  //ACT = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_ACT);
1447  if (!(( CI >> tag) & 0x01)) {
1448  break;
1449  }
1451  //KdPrint((" IS %#x\n", IS.Reg));
1452  if(IS.Reg) {
1453  break;
1454  }
1456  if(SError) {
1457  KdPrint((" AHCI: error %#x\n", SError));
1458  i = timeout;
1459  break;
1460  }
1461  AtapiStallExecution(200);
1462  }
1463  KdPrint((" CI %#x\n", CI));
1464 
1465  //SStatus.Reg = AtapiReadPort4(chan, IDX_SATA_SStatus);
1466  //SError.Reg = AtapiReadPort4(chan, IDX_SATA_SError);
1467 
1468  /* clear interrupt(s) */
1470  KdPrint((" IS %#x\n", IS.Reg));
1472 
1473  if (timeout && (i >= timeout)) {
1474 #ifdef _DEBUG
1475  ULONG TFD;
1476 
1478  KdPrint((" AHCI: timeout, SError %#x\n", SError));
1479 
1481  KdPrint2((" TFD %#x\n", TFD));
1482 #endif //_DEBUG
1483 
1484  return IDE_STATUS_WRONG;
1485  }
1486 
1487  return IDE_STATUS_IDLE;
1488 } // end UniataAhciWaitCommandReady()
1489 
1490 UCHAR
1491 NTAPI
1493  IN PVOID HwDeviceExtension,
1494  IN ULONG lChannel,
1496  IN USHORT ahci_flags,
1497  IN ULONG timeout
1498  )
1499 {
1500  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1501  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1502  //ULONG Channel = deviceExtension->Channel + lChannel;
1503  //ULONG hIS;
1504  //ULONG SError;
1505  //SATA_SSTATUS_REG SStatus;
1506  //SATA_SERROR_REG SError;
1507  //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
1508  //ULONGIO_PTR base;
1509  ULONG tag=0;
1510 
1511  PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
1512 
1513  KdPrint(("UniataAhciSendCommand: lChan %d\n", chan->lChannel));
1514 
1515  AHCI_CL->prd_length = 0;
1516  //AHCI_CL->cmd_flags = (20 / sizeof(ULONG)) | ahci_flags | (DeviceNumber << 12);
1517  AHCI_CL->cmd_flags = UniAtaAhciAdjustIoFlags(0, ahci_flags, 20, DeviceNumber);
1518 
1519  AHCI_CL->bytecount = 0;
1521  if(AHCI_CL->cmd_table_phys & AHCI_CMD_ALIGNEMENT_MASK) {
1522  KdPrint2((PRINT_PREFIX " AHCI CMD address is not aligned (mask %#x)\n", (ULONG)AHCI_CMD_ALIGNEMENT_MASK));
1523  }
1524 
1525  //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag);
1527 
1528  return UniataAhciWaitCommandReady(chan, timeout);
1529 
1530 } // end UniataAhciSendCommand()
1531 
1532 UCHAR
1533 NTAPI
1535  IN PVOID HwDeviceExtension,
1536  IN ULONG lChannel,
1539  IN PUCHAR data,
1540  IN ULONG length, /* bytes */
1541  IN UCHAR command,
1542  IN ULONGLONG lba,
1543  IN USHORT bcount, /* block count, just ATA register */
1544  IN USHORT feature,
1545  IN USHORT ahci_flags,
1546  IN ULONG wait_flags,
1547  IN ULONG timeout
1548  )
1549 {
1550  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1551  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1552  UCHAR statusByte;
1553  PATA_REQ AtaReq;
1554  ULONG fis_size;
1555  //ULONG tag=0;
1556  //PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
1557  PIDE_AHCI_CMD AHCI_CMD = NULL;
1558 
1559  //PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
1560 
1561  KdPrint2((PRINT_PREFIX "UniataAhciSendPIOCommand: cntrlr %#x:%#x dev %#x, cmd %#x, lba %#I64x bcount %#x feature %#x, buff %#x, len %#x, WF %#x \n",
1562  deviceExtension->DevIndex, lChannel, DeviceNumber, command, lba, bcount, feature, data, length, wait_flags ));
1563 
1564  if(length/DEV_BSIZE != bcount) {
1565  KdPrint((" length/DEV_BSIZE != bcount\n"));
1566  }
1567 
1568 #ifdef _DEBUG
1569  //UniataDumpAhciPortRegs(chan);
1570 #endif // _DEBUG
1571 
1572  if(!Srb) {
1573  Srb = BuildAhciInternalSrb(HwDeviceExtension, DeviceNumber, lChannel, data, length);
1574  if(!Srb) {
1575  KdPrint((" !Srb\n"));
1576  return IDE_STATUS_WRONG;
1577  }
1578  //UniataAhciSetupCmdPtr(AtaReq); // must be called before DMA setup
1579  //should be already called on init
1580  }
1581  AtaReq = (PATA_REQ)(Srb->SrbExtension);
1582  //KdPrint((" Srb %#x, AtaReq %#x\n", Srb, AtaReq));
1583 
1584  AHCI_CMD = AtaReq->ahci.ahci_cmd_ptr;
1585 
1586  fis_size = UniataAhciSetupFIS_H2D(deviceExtension, DeviceNumber, lChannel,
1587  &(AHCI_CMD->cfis[0]),
1588  command,
1589  lba,
1590  bcount,
1591  feature
1592  );
1593 
1594  if(!fis_size) {
1595  KdPrint2(("!fis_size\n"));
1596  return IDE_STATUS_WRONG;
1597  }
1598 
1599  //KdPrint2(("UniAtaAhciAdjustIoFlags(command, ahci_flags, fis_size, DeviceNumber)\n"));
1600  ahci_flags = UniAtaAhciAdjustIoFlags(command, ahci_flags, fis_size, DeviceNumber);
1601  KdPrint2(("ahci_flags %#x\n", ahci_flags));
1602 
1603  if(data) {
1604  if(ahci_flags & ATA_AHCI_CMD_WRITE) {
1605  AtaReq->Flags &= ~REQ_FLAG_READ;
1606  Srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
1607  KdPrint((" assume OUT\n"));
1608  } else {
1609  AtaReq->Flags |= REQ_FLAG_READ;
1610  Srb->SrbFlags |= SRB_FLAGS_DATA_IN;
1611  KdPrint((" assume IN\n"));
1612  }
1613  if(!AtapiDmaSetup(HwDeviceExtension,
1614  DeviceNumber,
1615  lChannel, // logical channel,
1616  Srb,
1617  data,
1618  length)) {
1619  KdPrint2((" can't setup buffer\n"));
1620  return IDE_STATUS_WRONG;
1621  }
1622  }
1623 
1624  AtaReq->ahci.io_cmd_flags = ahci_flags;
1625 
1626 #ifdef _DEBUG
1627  //UniataDumpAhciPortRegs(chan);
1628 #endif // _DEBUG
1629 
1630  UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
1631 
1632 #ifdef _DEBUG
1633  //UniataDumpAhciPortRegs(chan);
1634 #endif // _DEBUG
1635 
1636  if(wait_flags == ATA_IMMEDIATE) {
1637  statusByte = 0;
1638  KdPrint2((" return imemdiately\n"));
1639  } else {
1640  statusByte = UniataAhciWaitCommandReady(chan, timeout);
1641  UniataAhciStatus(HwDeviceExtension, lChannel, DeviceNumber);
1642  UniataAhciEndTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
1643  }
1644 
1645  return statusByte;
1646 
1647 } // end UniataAhciSendPIOCommand()
1648 
1649 UCHAR
1650 NTAPI
1652  IN PVOID HwDeviceExtension,
1653  IN ULONG lChannel,
1657  IN ULONG wait_flags,
1658  IN ULONG timeout
1659  )
1660 {
1661  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1662  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1663  UCHAR statusByte;
1664  PATA_REQ AtaReq;
1665  ULONG fis_size;
1666  //ULONG tag=0;
1667  //PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
1668  PIDE_AHCI_CMD AHCI_CMD = NULL;
1669  USHORT ahci_flags=0;
1670 // USHORT bcount=0;
1671 
1672  //PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
1673 
1674  KdPrint2((PRINT_PREFIX "UniataAhciSendPIOCommand: cntrlr %#x:%#x dev %#x, buff %#x, len %#x, WF %#x \n",
1675  deviceExtension->DevIndex, lChannel, DeviceNumber, Srb->DataBuffer, Srb->DataTransferLength, wait_flags ));
1676 
1677 // if(Srb->DataTransferLength/DEV_BSIZE != bcount) {
1678 // KdPrint((" length/DEV_BSIZE != bcount\n"));
1679 // }
1680 
1681 #ifdef _DEBUG
1682  //UniataDumpAhciPortRegs(chan);
1683 #endif // _DEBUG
1684 
1685  if(!Srb) {
1686  KdPrint((" !Srb\n"));
1687  return IDE_STATUS_WRONG;
1688  //UniataAhciSetupCmdPtr(AtaReq); // must be called before DMA setup
1689  //should be already called on init
1690  }
1691  AtaReq = (PATA_REQ)(Srb->SrbExtension);
1692  //KdPrint((" Srb %#x, AtaReq %#x\n", Srb, AtaReq));
1693 
1694  AHCI_CMD = AtaReq->ahci.ahci_cmd_ptr;
1695  if(!AHCI_CMD) {
1696  KdPrint((" !AHCI_CMD\n"));
1697  return IDE_STATUS_WRONG;
1698  }
1699 
1700  if(Srb->DataTransferLength) {
1701  if(Srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
1702  ahci_flags |= ATA_AHCI_CMD_WRITE;
1703  AtaReq->Flags &= ~REQ_FLAG_READ;
1704  } else {
1705  AtaReq->Flags |= REQ_FLAG_READ;
1706  }
1707  }
1708 
1709  fis_size = UniataAhciSetupFIS_H2D_Direct(deviceExtension, DeviceNumber, lChannel,
1710  &(AHCI_CMD->cfis[0]),
1711  regs);
1712 
1713  if(!fis_size) {
1714  KdPrint2(("!fis_size\n"));
1715  return IDE_STATUS_WRONG;
1716  }
1717 
1718  //KdPrint2(("UniAtaAhciAdjustIoFlags(command, ahci_flags, fis_size, DeviceNumber)\n"));
1719  ahci_flags = UniAtaAhciAdjustIoFlags(regs->bCommandReg, ahci_flags, fis_size, DeviceNumber);
1720  KdPrint2(("ahci_flags %#x\n", ahci_flags));
1721 
1722  if(Srb->DataTransferLength) {
1723  if(!AtapiDmaSetup(HwDeviceExtension,
1724  DeviceNumber,
1725  lChannel, // logical channel,
1726  Srb,
1727  (PUCHAR)(Srb->DataBuffer),
1728  Srb->DataTransferLength)) {
1729  KdPrint2((" can't setup buffer\n"));
1730  return IDE_STATUS_WRONG;
1731  }
1732  }
1733 
1734  AtaReq->ahci.io_cmd_flags = ahci_flags;
1735 
1736 #ifdef _DEBUG
1737  //UniataDumpAhciPortRegs(chan);
1738 #endif // _DEBUG
1739 
1740  UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
1741 
1742 #ifdef _DEBUG
1743  //UniataDumpAhciPortRegs(chan);
1744 #endif // _DEBUG
1745 
1746  if(wait_flags == ATA_IMMEDIATE) {
1747  statusByte = 0;
1748  KdPrint2((" return imemdiately\n"));
1749  } else {
1750  statusByte = UniataAhciWaitCommandReady(chan, timeout);
1751  UniataAhciStatus(HwDeviceExtension, lChannel, DeviceNumber);
1752  UniataAhciEndTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
1753  }
1754 
1755  return statusByte;
1756 
1757 } // end UniataAhciSendPIOCommandDirect()
1758 
1759 BOOLEAN
1760 NTAPI
1762  IN PHW_CHANNEL chan
1763  )
1764 {
1765  /* kick controller into sane state */
1766  if(!UniataAhciStop(chan)) {
1767  return FALSE;
1768  }
1769  if(!UniataAhciStopFR(chan)) {
1770  return FALSE;
1771  }
1772  if(!UniataAhciCLO(chan)) {
1773  return FALSE;
1774  }
1775  UniataAhciStartFR(chan);
1776  UniataAhciStart(chan);
1777 
1778  return TRUE;
1779 } // end UniataAhciAbortOperation()
1780 
1781 ULONG
1782 NTAPI
1784  IN PVOID HwDeviceExtension,
1785  IN ULONG lChannel,
1787  )
1788 {
1789  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1790  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1791  //ULONG Channel = deviceExtension->Channel + lChannel;
1792  //ULONG hIS;
1793  //ULONG CI;
1794  //AHCI_IS_REG IS;
1795  //ULONG tag=0;
1796 
1797  KdPrint(("UniataAhciSoftReset: lChan %d\n", chan->lChannel));
1798 
1799  PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
1800  PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
1801 
1802  /* kick controller into sane state */
1803  if(!UniataAhciAbortOperation(chan)) {
1804  KdPrint2((" abort failed\n"));
1805  return (ULONG)(-1);
1806  }
1807 
1808  /* pull reset active */
1809  RtlZeroMemory(AHCI_CMD->cfis, sizeof(AHCI_CMD->cfis));
1810  AHCI_CMD->cfis[0] = AHCI_FIS_TYPE_ATA_H2D;
1811  AHCI_CMD->cfis[1] = (UCHAR)DeviceNumber & 0x0f;
1812  //AHCI_CMD->cfis[7] = IDE_USE_LBA | IDE_DRIVE_SELECT;
1813  AHCI_CMD->cfis[15] = (IDE_DC_A_4BIT | IDE_DC_RESET_CONTROLLER);
1814 
1815  if(UniataAhciSendCommand(HwDeviceExtension, lChannel, DeviceNumber, ATA_AHCI_CMD_RESET | ATA_AHCI_CMD_CLR_BUSY, 100) == IDE_STATUS_WRONG) {
1816  KdPrint2((" timeout\n"));
1817  return (ULONG)(-1);
1818  }
1819  AtapiStallExecution(50);
1820 
1821  /* pull reset inactive */
1822  RtlZeroMemory(AHCI_CMD->cfis, sizeof(AHCI_CMD->cfis));
1823  AHCI_CMD->cfis[0] = AHCI_FIS_TYPE_ATA_H2D;
1824  AHCI_CMD->cfis[1] = (UCHAR)DeviceNumber & 0x0f;
1825  //AHCI_CMD->cfis[7] = IDE_USE_LBA | IDE_DRIVE_SELECT;
1826  AHCI_CMD->cfis[15] = (IDE_DC_A_4BIT);
1827  if(UniataAhciSendCommand(HwDeviceExtension, lChannel, DeviceNumber, 0, 3000) == IDE_STATUS_WRONG) {
1828  KdPrint2((" timeout (2)\n"));
1829  return (ULONG)(-1);
1830  }
1831 
1832  UniataAhciWaitReady(chan, 1);
1833 
1834  KdDump(RCV_FIS, sizeof(chan->AhciCtlBlock->rcv_fis.rfis));
1835 
1836  if(deviceExtension->HwFlags & UNIATA_AHCI_ALT_SIG) {
1837  ULONG signature;
1838  signature = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_SIG);
1839  KdPrint((" alt sig: %#x\n", signature));
1840  return signature;
1841  }
1842 
1843  return UniataAhciUlongFromRFIS(RCV_FIS);
1844 
1845 } // end UniataAhciSoftReset()
1846 
1847 ULONG
1848 NTAPI
1850  IN PHW_CHANNEL chan,
1851  IN ULONG timeout
1852  )
1853 {
1854  ULONG TFD;
1855  ULONG i;
1856 
1857  KdPrint2(("UniataAhciWaitReady: lChan %d\n", chan->lChannel));
1858 
1859  //base = (ULONGIO_PTR)(&deviceExtension->BaseIoAHCI_0 + offs);
1860 
1862  for(i=0; i<timeout && (TFD &
1863  (IDE_STATUS_DRQ | IDE_STATUS_BUSY)); i++) {
1864  AtapiStallExecution(1000);
1866  }
1867 
1868  KdPrint2((" TFD %#x\n", TFD));
1869 
1870  return TFD;
1871 
1872 } // end UniataAhciWaitReady()
1873 
1874 ULONG
1875 NTAPI
1877  IN PVOID HwDeviceExtension,
1878  IN ULONG lChannel,
1879  OUT PULONG signature
1880  )
1881 {
1882  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1883  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1884  //ULONG Channel = deviceExtension->Channel + lChannel;
1885  ULONG TFD;
1886 
1887 
1888  KdPrint(("UniataAhciHardReset: lChan %d\n", chan->lChannel));
1889 
1890  (*signature) = 0xffffffff;
1891 
1892  UniataAhciStop(chan);
1893  if(UniataSataPhyEnable(HwDeviceExtension, lChannel, 0/* dev0*/, UNIATA_SATA_RESET_ENABLE) == IDE_STATUS_WRONG) {
1894  KdPrint((" no PHY\n"));
1895  return IDE_STATUS_WRONG;
1896  }
1897 
1898  /* Wait for clearing busy status. */
1899  TFD = UniataAhciWaitReady(chan, 15000);
1900  if(TFD & (IDE_STATUS_DRQ | IDE_STATUS_BUSY)) {
1901  KdPrint((" busy: TFD %#x\n", TFD));
1902  return TFD;
1903  }
1904  KdPrint((" TFD %#x\n", TFD));
1905 
1906 #ifdef _DEBUG
1907  UniataDumpAhciPortRegs(chan);
1908 #endif // _DEBUG
1909 
1910  (*signature) = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_SIG);
1911  KdPrint((" sig: %#x\n", *signature));
1912 
1913  UniataAhciStart(chan);
1914 
1915  return 0;
1916 
1917 } // end UniataAhciHardReset()
1918 
1919 VOID
1920 NTAPI
1922  IN PVOID HwDeviceExtension,
1923  IN ULONG lChannel
1924  )
1925 {
1926  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1927  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1928  //ULONG Channel = deviceExtension->Channel + lChannel;
1929  //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
1930  ULONG CAP;
1931  //ULONGIO_PTR base;
1932  ULONG signature;
1933  ULONG i;
1934  ULONG VendorID = deviceExtension->DevID & 0xffff;
1935 
1936  KdPrint(("UniataAhciReset: lChan %d\n", chan->lChannel));
1937 
1938  //base = (ULONGIO_PTR)(&deviceExtension->BaseIoAHCI_0 + offs);
1939 
1940  /* Disable port interrupts */
1942 
1943  if(UniataAhciHardReset(HwDeviceExtension, lChannel, &signature)) {
1944 
1945  KdPrint((" No devices in all LUNs\n"));
1946  for (i=0; i<deviceExtension->NumberLuns; i++) {
1947  // Zero device fields to ensure that if earlier devices were found,
1948  // but not claimed, the fields are cleared.
1949  UniataForgetDevice(chan->lun[i]);
1950  }
1951 
1952  /* enable wanted port interrupts */
1955  return;
1956  }
1957 
1958  /* enable wanted port interrupts */
1962  ((/*ch->pm_level == */0) ? (ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC) : 0) |
1965 
1966  /*
1967  * Only probe for PortMultiplier if HW has support.
1968  * Ignore Marvell, which is not working,
1969  */
1970  CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
1971  if ((CAP & AHCI_CAP_SPM) &&
1972  (VendorID != ATA_MARVELL_ID)) {
1973  KdPrint((" check PM\n"));
1974  signature = UniataAhciSoftReset(HwDeviceExtension, lChannel, AHCI_DEV_SEL_PM);
1975  /* Workaround for some ATI chips, failing to soft-reset
1976  * when port multiplicator supported, but absent.
1977  * XXX: We can also check PxIS.IPMS==1 here to be sure. */
1978  if (signature == 0xffffffff) {
1979  KdPrint((" re-check PM\n"));
1980  signature = UniataAhciSoftReset(HwDeviceExtension, lChannel, 0);
1981  }
1982  } else {
1983  signature = UniataAhciSoftReset(HwDeviceExtension, lChannel, 0);
1984  }
1985 
1986  KdPrint((" signature %#x\n", signature));
1987  chan->lun[0]->DeviceFlags &= ~(DFLAGS_ATAPI_DEVICE | DFLAGS_DEVICE_PRESENT | CTRFLAGS_AHCI_PM);
1988  switch (signature >> 16) {
1989  case 0x0000:
1990  KdPrint((" ATA dev\n"));
1991  chan->lun[0]->DeviceFlags |= DFLAGS_DEVICE_PRESENT;
1992  chan->PmLunMap = 0;
1993  break;
1994  case 0x9669:
1995  KdPrint((" PM\n"));
1996  if(deviceExtension->NumberLuns > 1) {
1998  UniataSataIdentifyPM(chan);
1999  } else {
2000  KdPrint((" no PM supported (1 lun/chan)\n"));
2001  }
2002  break;
2003  case 0xeb14:
2004  KdPrint((" ATAPI dev\n"));
2005  chan->lun[0]->DeviceFlags |= (DFLAGS_ATAPI_DEVICE | DFLAGS_DEVICE_PRESENT);
2006  chan->PmLunMap = 0;
2007  break;
2008  default: /* SOS XXX */
2009  KdPrint((" default to ATA ???\n"));
2010  chan->lun[0]->DeviceFlags |= DFLAGS_DEVICE_PRESENT;
2011  chan->PmLunMap = 0;
2012  }
2013 
2014  return;
2015 
2016 } // end UniataAhciReset()
2017 
2018 VOID
2019 NTAPI
2021  IN PHW_CHANNEL chan
2022  )
2023 {
2024  ULONG CMD;
2025 
2026  KdPrint2(("UniataAhciStartFR: lChan %d\n", chan->lChannel));
2027 
2029  KdPrint2((" CMD %#x\n", CMD));
2031  UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2032 
2033  return;
2034 } // end UniataAhciStartFR()
2035 
2036 BOOLEAN
2037 NTAPI
2039  IN PHW_CHANNEL chan
2040  )
2041 {
2042  ULONG CMD;
2043  ULONG i;
2044 
2045  KdPrint2(("UniataAhciStopFR: lChan %d\n", chan->lChannel));
2046 
2048  KdPrint2((" CMD %#x\n", CMD));
2050 
2051  for(i=0; i<1000; i++) {
2053  if(!(CMD & ATA_AHCI_P_CMD_FR)) {
2054  KdPrint2((" final CMD %#x\n", CMD));
2055  return TRUE;
2056  }
2057  AtapiStallExecution(1000);
2058  }
2059  KdPrint2((" CMD %#x\n", CMD));
2060  KdPrint((" SError %#x\n", AtapiReadPort4(chan, IDX_SATA_SError)));
2061  KdPrint2(("UniataAhciStopFR: timeout\n"));
2062  return FALSE;
2063 } // end UniataAhciStopFR()
2064 
2065 VOID
2066 NTAPI
2068  IN PHW_CHANNEL chan
2069  )
2070 {
2071  ULONG IS, CMD;
2073 
2074  KdPrint2(("UniataAhciStart: lChan %d\n", chan->lChannel));
2075 
2076  /* clear SATA error register */
2077  SError.Reg = AtapiReadPort4(chan, IDX_SATA_SError);
2078 
2079  /* clear any interrupts pending on this channel */
2082 
2083  KdPrint2((" SError %#x, IS %#x\n", SError.Reg, IS));
2084 
2086  KdPrint2((" CMD %#x\n", CMD));
2088  CMD |
2090  ((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM) ? ATA_AHCI_P_CMD_PMA : 0));
2091  UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2092 
2093  return;
2094 } // end UniataAhciStart()
2095 
2096 BOOLEAN
2097 NTAPI
2099  IN PHW_CHANNEL chan
2100  )
2101 {
2102  //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2103  //PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
2104  ULONG CAP, CMD;
2105  //SATA_SERROR_REG SError;
2106  ULONG i;
2107 
2108  KdPrint2(("UniataAhciCLO: lChan %d\n", chan->lChannel));
2109 
2110  /* issue Command List Override if supported */
2111  //CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
2112  CAP = chan->DeviceExtension->AHCI_CAP;
2113  if(!(CAP & AHCI_CAP_SCLO)) {
2114  return TRUE;
2115  }
2116  KdPrint2((" send CLO\n"));
2120 
2121  for(i=0; i<1000; i++) {
2123  if(!(CMD & ATA_AHCI_P_CMD_CLO)) {
2124  KdPrint2((" final CMD %#x\n", CMD));
2125  return TRUE;
2126  }
2127  AtapiStallExecution(1000);
2128  }
2129  KdPrint2((" CMD %#x\n", CMD));
2130  KdPrint2(("UniataAhciCLO: timeout\n"));
2131  return FALSE;
2132 } // end UniataAhciCLO()
2133 
2134 BOOLEAN
2135 NTAPI
2137  IN PHW_CHANNEL chan
2138  )
2139 {
2140  ULONG CMD;
2141  //SATA_SERROR_REG SError;
2142  ULONG i;
2143 
2144  KdPrint2(("UniataAhciStop: lChan %d\n", chan->lChannel));
2145 
2146  /* issue Command List Override if supported */
2148  CMD &= ~ATA_AHCI_P_CMD_ST;
2150 
2151  for(i=0; i<1000; i++) {
2153  if(!(CMD & ATA_AHCI_P_CMD_CR)) {
2154  KdPrint2((" final CMD %#x\n", CMD));
2155  return TRUE;
2156  }
2157  AtapiStallExecution(1000);
2158  }
2159  KdPrint2((" CMD %#x\n", CMD));
2160  KdPrint((" SError %#x\n", AtapiReadPort4(chan, IDX_SATA_SError)));
2161  KdPrint2(("UniataAhciStop: timeout\n"));
2162  return FALSE;
2163 } // end UniataAhciStop()
2164 
2165 UCHAR
2166 NTAPI
2168  IN PVOID HwDeviceExtension,
2169  IN ULONG lChannel,
2172  )
2173 {
2174  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2175  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
2176  //ULONG Channel = deviceExtension->Channel + lChannel;
2177  //ULONG hIS;
2178  ULONG CMD, CMD0;
2179  //AHCI_IS_REG IS;
2180  PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
2181  //SATA_SSTATUS_REG SStatus;
2182  //SATA_SERROR_REG SError;
2183  //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
2184  //ULONGIO_PTR base;
2185  ULONG tag=0;
2186  //ULONG i;
2187 
2188  PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
2189 
2190  KdPrint2(("UniataAhciBeginTransaction: lChan %d, AtaReq %#x\n", chan->lChannel, AtaReq));
2191 
2192  if(Srb->DataTransferLength && (!AtaReq->dma_entries || AtaReq->dma_entries >= (USHORT)0xffff)) {
2193  KdPrint2(("UniataAhciBeginTransaction wrong DMA tab len %x\n", AtaReq->dma_entries));
2194  return 0;
2195  }
2196 
2197  AHCI_CL->prd_length = (USHORT)(AtaReq->dma_entries);
2198  AHCI_CL->cmd_flags = AtaReq->ahci.io_cmd_flags;
2199  AHCI_CL->bytecount = 0;
2200  if(AtaReq->ahci.ahci_base64) {
2201  KdPrint2((PRINT_PREFIX " AHCI AtaReq CMD %#x (ph %#x)\n", AtaReq->ahci.ahci_cmd_ptr, (ULONG)(AtaReq->ahci.ahci_base64)));
2202  AHCI_CL->cmd_table_phys = AtaReq->ahci.ahci_base64;
2203  } else
2204  if(AtaReq->ahci.ahci_cmd_ptr) {
2205  KdPrint2((PRINT_PREFIX " AHCI AtaReq->Chan CMD %#x (ph %#x) -> %#x (ph %#x)\n",
2206  AtaReq->ahci.ahci_cmd_ptr, (ULONG)(AtaReq->ahci.ahci_base64),
2208  RtlCopyMemory(&(chan->AhciCtlBlock->cmd), AtaReq->ahci.ahci_cmd_ptr,
2209  FIELD_OFFSET(IDE_AHCI_CMD, prd_tab)+AHCI_CL->prd_length*sizeof(IDE_AHCI_PRD_ENTRY));
2211  } else {
2212  KdPrint2((PRINT_PREFIX " no AHCI CMD\n"));
2213  //AHCI_CL->cmd_table_phys = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, cmd);
2214  return 0;
2215  }
2216  if(AHCI_CL->cmd_table_phys & AHCI_CMD_ALIGNEMENT_MASK) {
2217  KdPrint2((PRINT_PREFIX " AHCI CMD address is not aligned (mask %#x)\n", (ULONG)AHCI_CMD_ALIGNEMENT_MASK));
2218  return 0;
2219  }
2220 
2221 #ifdef _DEBUG
2222  KdPrint2((" prd_length %#x, flags %#x, base %I64x\n", AHCI_CL->prd_length, AHCI_CL->cmd_flags,
2223  AHCI_CL->cmd_table_phys));
2224 #endif // _DEBUG
2225 
2227  KdPrint2((" CMD %#x\n", CMD));
2228  // switch controller to ATAPI mode for ATA_PACKET commands only
2229  if(ATAPI_DEVICE(chan, DeviceNumber) &&
2230  AtaReq->ahci.ahci_cmd_ptr->cfis[2] == IDE_COMMAND_ATAPI_PACKET) {
2231  KdPrint2((" ATAPI\n"));
2233  KdDump(&(AtaReq->ahci.ahci_cmd_ptr->acmd), 16);
2234  } else {
2236  }
2237  if(CMD0 != CMD) {
2238  KdPrint2((" send CMD %#x, entries %#x\n", CMD, AHCI_CL->prd_length));
2240  CMD0 = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2241  }
2242 
2243  /* issue command to controller */
2244  //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag); // Used for NCQ
2245  KdPrint2((" Set CI\n"));
2247  chan->AhciPrevCI |= 0x01 << tag;
2248 
2249  //CMD0 = CMD;
2250  CMD |= ATA_AHCI_P_CMD_ST |
2252  if(CMD != CMD0) {
2253  KdPrint2((" Send CMD START (%#x != %#x)\n", CMD, CMD0));
2255  CMD0 = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2256  } else {
2257  KdPrint2((" No CMD START, already active\n"));
2258  }
2259 
2260  if(!ATAPI_DEVICE(chan, DeviceNumber)) {
2261  // TODO: check if we send ATAPI_RESET and wait for ready of so.
2262  if(AtaReq->ahci.ahci_cmd_ptr->cfis[2] == IDE_COMMAND_ATAPI_RESET) {
2263  ULONG TFD;
2264  ULONG i;
2265 
2266  for(i=0; i<1000000; i++) {
2268  if(!(TFD & IDE_STATUS_BUSY)) {
2269  break;
2270  }
2271  }
2272  if(TFD & IDE_STATUS_BUSY) {
2273  KdPrint2((" timeout\n"));
2274  }
2275  if(TFD & IDE_STATUS_ERROR) {
2276  KdPrint2((" ERROR %#x\n", (UCHAR)(TFD >> 8)));
2277  }
2278  AtaReq->ahci.in_status = TFD;
2279 
2280  return IDE_STATUS_SUCCESS;
2281  }
2282  }
2283 
2284  return IDE_STATUS_IDLE;
2285 
2286 } // end UniataAhciBeginTransaction()
2287 
2288 UCHAR
2289 NTAPI
2291  IN PVOID HwDeviceExtension,
2292  IN ULONG lChannel,
2295  )
2296 {
2297  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2298  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
2299  //ULONG Channel = deviceExtension->Channel + lChannel;
2300  //ULONG hIS;
2301  ULONG CI, ACT;
2302  PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
2303  ULONG TFD;
2304  PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
2305  ULONG tag=0;
2306  //ULONG i;
2307  PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
2308  //PHW_LU_EXTENSION LunExt;
2309 
2310  KdPrint2(("UniataAhciEndTransaction: lChan %d\n", chan->lChannel));
2311 
2312  //LunExt = chan->lun[DeviceNumber];
2313 
2315  KdPrint2((" TFD %#x\n", TFD));
2316 
2317  if(TFD & IDE_STATUS_ERROR) {
2318  AtaReq->ahci.in_error = (UCHAR)(TFD >> 8);
2319  KdPrint2((" ERROR %#x\n", AtaReq->ahci.in_error));
2320  } else {
2321  AtaReq->ahci.in_error = 0;
2322  }
2323  AtaReq->ahci.in_status = TFD;
2324 
2325  //if (request->flags & ATA_R_CONTROL) {
2326 
2327  AtaReq->ahci.in_bcount = (ULONG)(RCV_FIS[12]) | ((ULONG)(RCV_FIS[13]) << 8);
2328  AtaReq->ahci.in_lba = (ULONG)(RCV_FIS[4]) | ((ULONGLONG)(RCV_FIS[5]) << 8) |
2329  ((ULONGLONG)(RCV_FIS[6]) << 16);
2330  if(chan->ChannelCtrlFlags & CTRFLAGS_LBA48) {
2331  AtaReq->ahci.in_lba |= ((ULONGLONG)(RCV_FIS[8]) << 24) |
2332  ((ULONGLONG)(RCV_FIS[9]) << 32) |
2333  ((ULONGLONG)(RCV_FIS[10]) << 40);
2334  } else {
2335  AtaReq->ahci.in_lba |= ((ULONGLONG)(RCV_FIS[8]) << 24) |
2336  ((ULONGLONG)(RCV_FIS[9]) << 32) |
2337  ((ULONGLONG)(RCV_FIS[7] & 0x0f) << 24);
2338  }
2339  AtaReq->WordsTransfered = AHCI_CL->bytecount/2;
2340 
2341 /*
2342  if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
2343  KdPrint2(("RCV:\n"));
2344  KdDump(RCV_FIS, 24);
2345  KdPrint2(("PIO:\n"));
2346  KdDump(&(chan->AhciCtlBlock->rcv_fis.psfis[0]), 24);
2347 
2348  KdPrint2(("len: %d vs %d\n", AHCI_CL->bytecount, (ULONG)RCV_FIS[5] | ((ULONG)RCV_FIS[6] << 8) ));
2349  if(!AHCI_CL->bytecount) {
2350  AtaReq->WordsTransfered = ((ULONG)RCV_FIS[5] | ((ULONG)RCV_FIS[6] << 8)) / 2;
2351  }
2352  }
2353 */
2356  if(CI & (1 << tag)) {
2357  // clear CI
2358  KdPrint2((" Incomplete command, CI %#x, ACT %#x\n", CI, ACT));
2359  KdPrint2((" FIS status %#x, error %#x\n", RCV_FIS[2], RCV_FIS[3]));
2360 
2361 #ifdef _DEBUG
2362  UniataDumpAhciPortRegs(chan);
2363 #endif
2364  if(!UniataAhciAbortOperation(chan)) {
2365  KdPrint2((" Abort failed, need RESET\n"));
2366  }
2367 #ifdef _DEBUG
2368  UniataDumpAhciPortRegs(chan);
2369 #endif
2370  chan->AhciPrevCI = CI & ~((ULONG)1 << tag);
2371  if(chan->AhciPrevCI) {
2372  KdPrint2((" Need command list restart, CI %#x\n", chan->AhciPrevCI));
2373  }
2374  } else {
2375  chan->AhciPrevCI &= ~((ULONG)1 << tag);
2376  RtlZeroMemory(AHCI_CL, sizeof(IDE_AHCI_CMD_LIST));
2377  }
2378  //}
2379 
2380  return 0;
2381 
2382 } // end UniataAhciEndTransaction()
2383 
2384 VOID
2385 NTAPI
2387  IN PHW_CHANNEL chan
2388  )
2389 {
2390  ULONGLONG base;
2391 
2392  KdPrint2(("UniataAhciResume: lChan %d\n", chan->lChannel));
2393 
2394 #ifdef _DEBUG
2395  //UniataDumpAhciPortRegs(chan);
2396 #endif // _DEBUG
2397 
2398  /* Disable port interrupts */
2400 
2401  /* setup work areas */
2402  base = chan->AHCI_CTL_PhAddr;
2403  if(!base) {
2404  KdPrint2((PRINT_PREFIX " AHCI buffer allocation failed\n"));
2405  return;
2406  }
2407  KdPrint2((PRINT_PREFIX " AHCI CLB setup\n"));
2409  KdPrint2((PRINT_PREFIX " AHCI CLB address is not aligned (mask %#x)\n", (ULONG)AHCI_FIS_ALIGNEMENT_MASK));
2410  }
2412  (ULONG)(base & 0xffffffff));
2414  (ULONG)((base >> 32) & 0xffffffff));
2415 
2416  KdPrint2((PRINT_PREFIX " AHCI RCV FIS setup\n"));
2417  base = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, rcv_fis);
2419  KdPrint2((PRINT_PREFIX " AHCI FIS address is not aligned (mask %#x)\n", (ULONG)AHCI_FIS_ALIGNEMENT_MASK));
2420  }
2422  (ULONG)(base & 0xffffffff));
2424  (ULONG)((base >> 32) & 0xffffffff));
2425 
2426  /* activate the channel and power/spin up device */
2429  (((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM)) ? ATA_AHCI_P_CMD_ALPE : 0) |
2430  (((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM2)) ? ATA_AHCI_P_CMD_ASP : 0 ))
2431  );
2432  UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2433 
2434 #ifdef _DEBUG
2435  //UniataDumpAhciPortRegs(chan);
2436 #endif // _DEBUG
2437 
2438  UniataAhciStartFR(chan);
2439  UniataAhciStart(chan);
2440 
2441 #ifdef _DEBUG
2442  UniataDumpAhciPortRegs(chan);
2443 #endif // _DEBUG
2444 
2445  return;
2446 } // end UniataAhciResume()
2447 
2448 #if 0
2449 VOID
2450 NTAPI
2451 UniataAhciSuspend(
2452  IN PHW_CHANNEL chan
2453  )
2454 {
2455  ULONGLONG base;
2456  SATA_SCONTROL_REG SControl;
2457 
2458  KdPrint2(("UniataAhciSuspend:\n"));
2459 
2460  /* Disable port interrupts */
2462 
2463  /* Reset command register. */
2464  UniataAhciStop(chan);
2465  UniataAhciStopFR(chan);
2467  UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2468 
2469  /* Allow everything including partial and slumber modes. */
2471 
2472  /* Request slumber mode transition and give some time to get there. */
2474  AtapiStallExecution(100);
2475 
2476  /* Disable PHY. */
2477  SControl.Reg = 0;
2478  SControl.DET = SStatus_DET_Offline;
2479  UniataSataWritePort4(chan, IDX_SATA_SControl, SControl.Reg, 0);
2480 
2481  return;
2482 } // end UniataAhciSuspend()
2483 #endif
2484 
2485 BOOLEAN
2486 NTAPI
2488  IN PHW_CHANNEL chan,
2490  IN ULONG Reg,
2491  OUT PULONG result
2492  )
2493 {
2494  //ULONG Channel = deviceExtension->Channel + lChannel;
2495  //ULONG hIS;
2496  //ULONG CI;
2497  //AHCI_IS_REG IS;
2498  //ULONG tag=0;
2499  PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
2500  PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
2501 
2502  KdPrint(("UniataAhciReadPM: lChan %d [%#x]\n", chan->lChannel, DeviceNumber));
2503 
2505  (*result) = UniataSataReadPort4(chan, Reg, 0);
2506  return TRUE;
2507  }
2509  switch(Reg) {
2510  case IDX_SATA_SStatus:
2511  Reg = 0; break;
2512  case IDX_SATA_SError:
2513  Reg = 1; break;
2514  case IDX_SATA_SControl:
2515  Reg = 2; break;
2516  default:
2517  return FALSE;
2518  }
2519  }
2520 
2521  RtlZeroMemory(AHCI_CMD->cfis, sizeof(AHCI_CMD->cfis));
2522  AHCI_CMD->cfis[0] = AHCI_FIS_TYPE_ATA_H2D;
2523  AHCI_CMD->cfis[1] = AHCI_FIS_COMM_PM;
2524  AHCI_CMD->cfis[2] = IDE_COMMAND_READ_PM;
2525  AHCI_CMD->cfis[3] = (UCHAR)Reg;
2526  AHCI_CMD->cfis[7] = (UCHAR)(IDE_USE_LBA | DeviceNumber);
2527  AHCI_CMD->cfis[15] = IDE_DC_A_4BIT;
2528 
2529  if(UniataAhciSendCommand(chan->DeviceExtension, chan->lChannel, DeviceNumber, 0, 10) == IDE_STATUS_WRONG) {
2530  KdPrint2((" PM read failed\n"));
2531  return FALSE;
2532  }
2533 
2534  KdDump(RCV_FIS, sizeof(chan->AhciCtlBlock->rcv_fis.rfis));
2535 
2536  (*result) = UniataAhciUlongFromRFIS(RCV_FIS);
2537  return TRUE;
2538 
2539 } // end UniataAhciReadPM()
2540 
2541 UCHAR
2542 NTAPI
2544  IN PHW_CHANNEL chan,
2546  IN ULONG Reg,
2547  IN ULONG value
2548  )
2549 {
2550  //ULONG Channel = deviceExtension->Channel + lChannel;
2551  //ULONG hIS;
2552  //ULONG CI;
2553  //AHCI_IS_REG IS;
2554  //ULONG tag=0;
2555  ULONG TFD;
2556  PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
2557  //PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
2558 
2559  KdPrint(("UniataAhciWritePM: lChan %d [%#x] %#x\n", chan->lChannel, DeviceNumber, value));
2560 
2562  UniataSataWritePort4(chan, Reg, value, 0);
2563  return 0;
2564  }
2566  switch(Reg) {
2567  case IDX_SATA_SStatus:
2568  Reg = 0; break;
2569  case IDX_SATA_SError:
2570  Reg = 1; break;
2571  case IDX_SATA_SControl:
2572  Reg = 2; break;
2573  default:
2574  return IDE_STATUS_WRONG;
2575  }
2576  }
2577 
2578  RtlZeroMemory(AHCI_CMD->cfis, sizeof(AHCI_CMD->cfis));
2579  AHCI_CMD->cfis[0] = AHCI_FIS_TYPE_ATA_H2D;
2580  AHCI_CMD->cfis[1] = AHCI_FIS_COMM_PM;
2581  AHCI_CMD->cfis[2] = IDE_COMMAND_WRITE_PM;
2582  AHCI_CMD->cfis[3] = (UCHAR)Reg;
2583  AHCI_CMD->cfis[7] = (UCHAR)(IDE_USE_LBA | DeviceNumber);
2584 
2585  AHCI_CMD->cfis[12] = (UCHAR)(value & 0xff);
2586  AHCI_CMD->cfis[4] = (UCHAR)((value >> 8) & 0xff);
2587  AHCI_CMD->cfis[5] = (UCHAR)((value >> 16) & 0xff);
2588  AHCI_CMD->cfis[6] = (UCHAR)((value >> 24) & 0xff);
2589 
2590  AHCI_CMD->cfis[15] = IDE_DC_A_4BIT;
2591 
2592  if(UniataAhciSendCommand(chan->DeviceExtension, chan->lChannel, DeviceNumber, 0, 100) == IDE_STATUS_WRONG) {
2593  KdPrint2((" PM write failed\n"));
2594  return IDE_STATUS_WRONG;
2595  }
2596 
2598 
2599  if(TFD & IDE_STATUS_ERROR) {
2600  KdPrint2((" ERROR %#x\n", (UCHAR)(TFD >> 8)));
2601  }
2602  return (UCHAR)(TFD >> 8);
2603 
2604 } // end UniataAhciWritePM()
2605 
2606 VOID
2608 IN OUT PATA_REQ AtaReq
2609  )
2610 {
2611  union {
2612  PUCHAR prd_base;
2613  ULONGLONG prd_base64;
2614  };
2615  union {
2616  PUCHAR prd_base0;
2617  ULONGLONG prd_base64_0;
2618  };
2619 #ifdef _DEBUG
2620  ULONG d;
2621 #endif // _DEBUG
2622 
2623  prd_base64_0 = prd_base64 = 0;
2624  prd_base = (PUCHAR)(&AtaReq->ahci_cmd0);
2625  prd_base0 = prd_base;
2626 
2627  prd_base64 = (prd_base64 + max(FIELD_OFFSET(ATA_REQ, ahci_cmd0), AHCI_CMD_ALIGNEMENT_MASK+1)) & ~AHCI_CMD_ALIGNEMENT_MASK;
2628 
2629 #ifdef _DEBUG
2630  d = (ULONG)(prd_base64 - prd_base64_0);
2631  KdPrint2((PRINT_PREFIX " AtaReq %#x: cmd aligned %I64x, d=%x\n", AtaReq, prd_base64, d));
2632 #endif // _DEBUG
2633 
2634  AtaReq->ahci.ahci_cmd_ptr = (PIDE_AHCI_CMD)prd_base64;
2635  KdPrint2((PRINT_PREFIX " ahci_cmd_ptr %#x\n", AtaReq->ahci.ahci_cmd_ptr));
2636 } // end UniataAhciSetupCmdPtr()
2637 
2639 NTAPI
2641  IN PVOID HwDeviceExtension,
2643  IN ULONG lChannel,
2644  IN PUCHAR Buffer,
2645  IN ULONG Length
2646  )
2647 {
2648  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2649  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
2650  PSCSI_REQUEST_BLOCK srb;
2651 // PCDB cdb;
2652  PATA_REQ AtaReq = chan->AhciInternalAtaReq;
2653 
2654  KdPrint(("BuildAhciInternalSrb: lChan %d [%#x]\n", lChannel, DeviceNumber));
2655 
2656  if(!AtaReq) {
2657  KdPrint2((PRINT_PREFIX " !chan->AhciInternalAtaReq\n"));
2658  return NULL;
2659  }
2660 
2661  //RtlZeroMemory((PCHAR) AtaReq, sizeof(ATA_REQ));
2662  //RtlZeroMemory((PCHAR) AtaReq, FIELD_OFFSET(ATA_REQ, ahci));
2663  UniAtaClearAtaReq(AtaReq);
2664 
2665  srb = chan->AhciInternalSrb;
2666 
2667  RtlZeroMemory((PCHAR) srb, sizeof(SCSI_REQUEST_BLOCK));
2668 
2669  srb->PathId = (UCHAR)lChannel;
2670  srb->TargetId = (UCHAR)DeviceNumber;
2671  srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
2672  srb->Length = sizeof(SCSI_REQUEST_BLOCK);
2673 
2674  // Set flags to disable synchronous negociation.
2675  //srb->SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
2676 
2677  // Set timeout to 4 seconds.
2678  srb->TimeOutValue = 4;
2679 
2680  srb->CdbLength = 6;
2681  srb->DataBuffer = Buffer;
2682  srb->DataTransferLength = Length;
2683  srb->SrbExtension = AtaReq;
2684 
2685  AtaReq->Srb = srb;
2686  AtaReq->DataBuffer = (PUSHORT)Buffer;
2687  AtaReq->TransferLength = Length;
2688 
2689  //if(!AtaReq->ahci.ahci_cmd_ptr) {
2690  //UniataAhciSetupCmdPtr(AtaReq);
2691  //AtaReq->ahci.ahci_cmd_ptr = &(chan->AhciCtlBlock->cmd);
2692  //AtaReq->ahci.ahci_base64 = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, cmd);
2693  //}
2694  //AtaReq->ahci.ahci_cmd_ptr = &(AtaReq->ahci_cmd0);
2695  //AtaReq->ahci.ahci_base64 = NULL; // indicate that we should copy command to proper place
2696 
2697  KdPrint2((PRINT_PREFIX " Srb %#x, AtaReq %#x, CMD %#x ph %I64x\n", srb, AtaReq,
2698  AtaReq->ahci.ahci_cmd_ptr, AtaReq->ahci.ahci_base64));
2699 
2700 /* // Set CDB operation code.
2701  cdb = (PCDB)srb->Cdb;
2702  cdb->CDB6INQUIRY.OperationCode = SCSIOP_REQUEST_SENSE;
2703  cdb->CDB6INQUIRY.AllocationLength = sizeof(SENSE_DATA);
2704 */
2705  return srb;
2706 } // end BuildAhciInternalSrb()
2707 
IORES BaseIoAHCI_Port
Definition: bsmaster.h:1101
BOOLEAN NTAPI UniataAhciStopFR(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:2038
#define IDX_AHCI_P_CI
Definition: bsmaster.h:686
signed char * PCHAR
Definition: retypes.h:7
#define ATA_AHCI_P_CMD_ATAPI
Definition: bsmaster.h:713
INTERNETFEATURELIST feature
Definition: misc.c:1689
#define CTRFLAGS_AHCI_PM2
Definition: bsmaster.h:1140
#define ATA_CMD_FLAG_48supp
Definition: atapi.h:1600
#define ATA_AHCI_CMD_WRITE
Definition: bsmaster.h:816
ULONG NTAPI UniataSataReadPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG pm_port)
Definition: id_sata.cpp:270
UCHAR NTAPI UniataAhciWritePM(IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN ULONG Reg, IN ULONG value)
Definition: id_sata.cpp:2543
#define IDX_AHCI_o_Control
Definition: bsmaster.h:792
#define IN
Definition: typedefs.h:38
UCHAR const AtaCommandFlags[256]
Definition: atacmd_map.h:25
#define max(a, b)
Definition: svc.c:63
UCHAR NTAPI UniataSataConnect(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG pm_port)
Definition: id_sata.cpp:44
#define IDE_DC_RESET_CONTROLLER
Definition: atapi.h:146
#define AHCI_CAP_NCQ
Definition: bsmaster.h:209
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define ATA_AHCI_P_IX_PC
Definition: bsmaster.h:505
#define KdPrint2(_x_)
Definition: atapi.h:154
BOOLEAN NTAPI UniataAhciCLO(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:2098
#define AHCI_DEV_SEL_PM
Definition: bsmaster.h:803
#define CHAN_NOT_SPECIFIED
Definition: atapi.h:1483
#define IDX_AHCI_o_BlockCount
Definition: bsmaster.h:791
#define PI
Definition: quad.c:43
#define CTRFLAGS_AHCI_PM
Definition: bsmaster.h:1139
BOOLEAN NTAPI UniataSataReadPM(IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN ULONG Reg, OUT PULONG result)
Definition: id_sata.cpp:446
#define KdDump(a, b)
Definition: env_spec_w32.h:312
#define IDX_AHCI_o_Feature
Definition: bsmaster.h:786
__inline ULONG UniataAhciReadChannelPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx)
Definition: id_sata.h:290
Definition: ftp_var.h:139
UCHAR NTAPI UniataSataPhyEnable(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG pm_port, IN BOOLEAN doReset)
Definition: id_sata.cpp:124
#define IDE_STATUS_DRQ
Definition: atapi.h:128
ULONG NTAPI UniataSataSoftReset(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_sata.cpp:476
#define CTRFLAGS_NO_SLAVE
Definition: bsmaster.h:1135
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:1237
BOOLEAN NTAPI UniataAhciDetect(IN PVOID HwDeviceExtension, IN PPCI_COMMON_CONFIG pciData, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo)
Definition: id_sata.cpp:886
#define ATA_M88SE9123
Definition: bm_devs_decl.h:342
#define SStatus_SPD_Gen2
Definition: bsmaster.h:293
#define IDX_AHCI_IS
Definition: bsmaster.h:272
#define IDX_IO2_AltStatus
Definition: atapi.h:225
GLuint GLuint GLsizei count
Definition: gl.h:1545
unsigned char * PUCHAR
Definition: retypes.h:3
BOOLEAN NTAPI UniataSataEvent(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG Action, IN ULONG pm_port)
Definition: id_sata.cpp:233
bool NTAPI CheckIfBadBlock(IN PHW_LU_EXTENSION LunExt, IN ULONGLONG lba, IN ULONG count)
UCHAR NTAPI UniataAhciStatus(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_sata.cpp:1127
ULONG ChannelCtrlFlags
Definition: bsmaster.h:1055
#define AHCI_CAP_SNTF
Definition: bsmaster.h:208
ULONG MaxTransferMode
Definition: bsmaster.h:1053
#define ATA_AHCI_P_CMD_SLUMBER
Definition: bsmaster.h:721
#define DMA_MODE_AHCI
Definition: bsmaster.h:1704
#define CI(cs)
Definition: fontdlg.c:69
#define ATA_M88SE6111
Definition: bm_devs_decl.h:338
#define IDX_AHCI_o_CylinderHighExp
Definition: bsmaster.h:796
#define ICH7
Definition: bm_devs_decl.h:697
GLdouble n
Definition: glext.h:7729
#define ATA_AHCI_P_CMD_ALPE
Definition: bsmaster.h:715
VOID NTAPI UniataAhciResume(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:2386
#define ATA_AHCI_P_CMD_POD
Definition: bsmaster.h:700
#define REQ_FLAG_READ
Definition: bsmaster.h:935
#define ATA_AHCI_P_IX_INF
Definition: bsmaster.h:511
Definition: ecma_167.h:138
#define ICH5
Definition: bm_devs_decl.h:693
__inline USHORT UniAtaAhciAdjustIoFlags(IN UCHAR command, IN USHORT ahci_flags, IN ULONG fis_size, IN ULONG DeviceNumber)
Definition: id_sata.h:357
#define ATA_AHCI_P_CMD_PMA
Definition: bsmaster.h:708
VOID NTAPI UniataInitSyncBaseIO(IN struct _HW_CHANNEL *chan)
#define IDE_COMMAND_WRITE_PM
Definition: atapi.h:402
#define IDE_COMMAND_ATAPI_RESET
Definition: atapi.h:102
#define ATA_AHCI_P_IX_UF
Definition: bsmaster.h:503
PHW_CHANNEL chan
Definition: bsmaster.h:1253
VOID NTAPI UniataAhciStart(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:2067
#define IDX_SATA_SControl
Definition: bsmaster.h:459
#define IDX_INDEXED_ADDR
Definition: bsmaster.h:466
#define AHCI_GHC_AE
Definition: bsmaster.h:223
Definition: dhcpd.h:245
ULONG AhciLastIS
Definition: bsmaster.h:1104
#define DFLAGS_ATAPI_DEVICE
Definition: atapi.h:41
UCHAR NTAPI UniataSataWritePM(IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN ULONG Reg, IN ULONG value)
Definition: id_sata.cpp:461
VOID NTAPI UniataAhciStartFR(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:2020
#define AHCI_CAP2_BOH
Definition: bsmaster.h:245
#define IDX_AHCI_P_ACT
Definition: bsmaster.h:693
ULONG NTAPI UniataAhciSoftReset(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_sata.cpp:1783
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
#define IDE_STATUS_WRONG
Definition: atapi.h:431
#define IDE_DRIVE_SELECT_1
Definition: atapi.h:138
VOID UniataSataIdentifyPM(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:491
ULONG NTAPI UniataAhciHardReset(IN PVOID HwDeviceExtension, IN ULONG lChannel, OUT PULONG signature)
Definition: id_sata.cpp:1876
#define ATA_AHCI_P_IX_DP
Definition: bsmaster.h:504
#define IDE_DC_USE_HOB
Definition: atapi.h:455
ULONG AhciCompleteCI
Definition: bsmaster.h:1103
__inline VOID UniataAhciWriteChannelPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG data)
Definition: id_sata.h:302
#define lba
GLbitfield GLuint64 timeout
Definition: glext.h:7164
ULONG DDKFASTAPI AtapiReadPort4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port)
ULONG TransferLength
Definition: bsmaster.h:884
#define IDX_AHCI_P_SNTF
Definition: bsmaster.h:695
#define AHCI_GHC_IE
Definition: bsmaster.h:222
IDE_AHCI_RCV_FIS rcv_fis
Definition: bsmaster.h:847
VOID NTAPI UniataForgetDevice(PHW_LU_EXTENSION LunExt)
Definition: id_ata.cpp:2339
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 MemIo
Definition: bsmaster.h:1009
#define IDX_AHCI_P_SError
Definition: bsmaster.h:692
#define CTRFLAGS_LBA48
Definition: bsmaster.h:1133
UCHAR rfis[20]
Definition: bsmaster.h:837
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define ATA_AHCI_P_IX_CPD
Definition: bsmaster.h:516
struct @4014 regs[]
#define IDX_AHCI_P_FB
Definition: bsmaster.h:683
PIDE_AHCI_CHANNEL_CTL_BLOCK AhciCtlBlock
Definition: bsmaster.h:1099
#define IDX_AHCI_PI
Definition: bsmaster.h:274
#define SStatus_DET_Offline
Definition: bsmaster.h:287
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
__inline ULONG UniataAhciUlongFromRFIS(PUCHAR RCV_FIS)
Definition: id_sata.h:345
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define SControl_IPM_NoPartialSlumber
Definition: bsmaster.h:348
UCHAR NTAPI UniataAhciWaitCommandReady(IN PHW_CHANNEL chan, IN ULONG timeout)
Definition: id_sata.cpp:1430
GLuint base
Definition: 3dtext.c:35
PSCSI_REQUEST_BLOCK AhciInternalSrb
Definition: bsmaster.h:1110
#define UniataAhciReadHostPort4(deviceExtension, io_port_ndx)
Definition: id_sata.h:313
#define IDX_AHCI_CAP2
Definition: bsmaster.h:275
#define UniataAhciWriteHostPort4(deviceExtension, io_port_ndx, data)
Definition: id_sata.h:316
BOOLEAN NTAPI UniataAhciAbortOperation(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:1761
#define AHCI_FIS_TYPE_ATA_H2D
Definition: bsmaster.h:752
UCHAR NTAPI UniataAhciEndTransaction(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_sata.cpp:2290
#define SStatus_SPD_Gen1
Definition: bsmaster.h:292
struct _ATA_REQ::@1103::@1105::@1109::@1112 ahci
unsigned char BOOLEAN
#define INTERRUPT_REASON_OUR
Definition: atapi.h:1281
#define AHCI_CAP_S64A
Definition: bsmaster.h:210
VOID NTAPI UniataAhciReset(IN PVOID HwDeviceExtension, IN ULONG lChannel)
Definition: id_sata.cpp:1921
smooth NULL
Definition: ftsmooth.c:416
#define ATA_CMD_FLAG_FUA
Definition: atapi.h:1603
static const WCHAR version[]
Definition: asmname.c:64
#define IDX_AHCI_P_IE
Definition: bsmaster.h:685
UCHAR const AtaCommands48[256]
Definition: atacmd_map.h:5
#define UNIATA_SATA
Definition: bm_devs_decl.h:627
#define IDX_SATA_SError
Definition: bsmaster.h:458
#define IDX_INDEXED_DATA
Definition: bsmaster.h:467
Definition: bufpool.h:45
#define SControl_DET_Init
Definition: bsmaster.h:333
ULONG AhciLastSError
Definition: bsmaster.h:1105
#define ATA_AHCI_P_CMD_ACTIVE
Definition: bsmaster.h:719
#define ATA_SA150
Definition: atapi.h:337
void * PVOID
Definition: retypes.h:9
PSCSI_REQUEST_BLOCK NTAPI BuildAhciInternalSrb(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN PUCHAR Buffer, IN ULONG Length)
Definition: id_sata.cpp:2640
#define IDX_AHCI_P_TFD
Definition: bsmaster.h:687
#define ATA_M88SE6145
Definition: bm_devs_decl.h:341
#define ATA_AHCI_P_CMD_ST
Definition: bsmaster.h:698
#define ATA_F_DMA
Definition: atapi.h:558
#define AHCI_CAP_SPM
Definition: bsmaster.h:204
#define IDX_AHCI_o_BlockNumberExp
Definition: bsmaster.h:794
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
__inline BOOLEAN UniataIsSATARangeAvailable(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG lChannel)
Definition: id_sata.h:91
UCHAR DDKFASTAPI WaitOnBaseBusyLong(IN struct _HW_CHANNEL *chan)
#define ATA_AHCI_P_IX_DHR
Definition: bsmaster.h:499
struct _IDE_AHCI_CMD * PIDE_AHCI_CMD
#define IDE_STATUS_IDLE
Definition: atapi.h:131
#define IDE_STATUS_SUCCESS
Definition: atapi.h:418
BOOLEAN NTAPI UniataSataClearErr(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN BOOLEAN do_connect, IN ULONG pm_port)
Definition: id_sata.cpp:186
VOID NTAPI AtapiSetupLunPtrs(IN PHW_CHANNEL chan, IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG c)
Definition: id_init.cpp:2846
#define IDX_AHCI_P_SIG
Definition: bsmaster.h:688
ULONGLONG AHCI_CTL_PhAddr
Definition: bsmaster.h:1100
#define IDX_AHCI_o_DriveSelect
Definition: bsmaster.h:790
#define AHCI_CAP_NOP_MASK
Definition: bsmaster.h:200
#define DEV_BSIZE
Definition: bsmaster.h:103
#define IDX_AHCI_o_BlockCountExp
Definition: bsmaster.h:797
Definition: bsmaster.h:724
ULONG NTAPI AtapiRegCheckDevValue(IN PVOID HwDeviceExtension, IN ULONG chan, IN ULONG dev, IN PCWSTR Name, IN ULONG Default)
Definition: id_ata.cpp:11226
BOOLEAN NTAPI UniataAhciInit(IN PVOID HwDeviceExtension)
Definition: id_sata.cpp:645
#define SetPciConfig4(offs, op)
Definition: bsmaster.h:1684
UCHAR NTAPI UniataAhciSendCommand(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN USHORT ahci_flags, IN ULONG timeout)
Definition: id_sata.cpp:1492
#define AHCI_CAP_ISS_MASK
Definition: bsmaster.h:206
#define GetPciConfig4(offs, op)
Definition: bsmaster.h:1674
#define d
Definition: ke_i.h:81
UCHAR NTAPI UniataAhciBeginTransaction(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_sata.cpp:2167
#define ATA_AHCI_P_CMD_CLO
Definition: bsmaster.h:701
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
uint64_t ULONGLONG
Definition: typedefs.h:65
#define AHCI_CAP_CCC
Definition: bsmaster.h:201
#define ATA_INTEL_ID
Definition: bm_devs_decl.h:184
#define AHCI_BOHC_BB
Definition: bsmaster.h:259
#define UNIATA_SATA_EVENT_ATTACH
Definition: id_sata.h:72
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING _In_opt_ PSTRING _In_ ULONG _In_ ULONG Action
Definition: fsrtlfuncs.h:738
#define ATA_AHCI_P_IX_DS
Definition: bsmaster.h:501
ULONG NTAPI UniataAhciWaitReady(IN PHW_CHANNEL chan, IN ULONG timeout)
Definition: id_sata.cpp:1849
const GLubyte * c
Definition: glext.h:8905
#define DEVNUM_NOT_SPECIFIED
Definition: atapi.h:1485
#define ATA_AHCI_P_IX_HBF
Definition: bsmaster.h:514
#define IDX_AHCI_CAP
Definition: bsmaster.h:270
#define AHCI_BOHC_BOS
Definition: bsmaster.h:263
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define ATA_IMMEDIATE
Definition: bsmaster.h:55
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define ATA_AHCI_P_IX_IF
Definition: bsmaster.h:512
#define ATA_AHCI_P_IX_SDB
Definition: bsmaster.h:502
#define IDX_AHCI_o_CylinderHigh
Definition: bsmaster.h:789
#define UniAta_need_lba48(command, lba, count, supp48)
Definition: atapi.h:1611
#define AHCI_FIS_COMM_PM
Definition: bsmaster.h:799
#define IDX_MAX_REG
Definition: bsmaster.h:469
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IDX_AHCI_o_Command
Definition: bsmaster.h:785
#define SStatus_SPD_Gen3
Definition: bsmaster.h:294
VOID NTAPI AtapiDmaAlloc(IN PVOID HwDeviceExtension, IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, IN ULONG lChannel)
Definition: id_dma.cpp:138
ULONG dma_entries
Definition: bsmaster.h:897
#define ATA_FLAGS_48BIT_COMMAND
Definition: uata_ctl.h:223
static const WCHAR L[]
Definition: oid.c:1250
const char * SError(int e)
Definition: SError.c:141
#define ATA_M88SE6121
Definition: bm_devs_decl.h:339
#define AHCI_CMD_ALIGNEMENT_MASK
Definition: bsmaster.h:520
#define KdPrint3(_x_)
Definition: atapi.h:153
struct _IDE_AHCI_PORT_REGISTERS::@1064::@1084::@1086 STS
#define ATA_AHCI_P_CMD_ASP
Definition: bsmaster.h:716
#define SATA_MAX_PM_UNITS
Definition: bsmaster.h:110
#define UNIATA_SATA_EVENT_DETACH
Definition: id_sata.h:73
ULONG DmaSegmentAlignmentMask
Definition: bsmaster.h:1316
#define UNIATA_AHCI
Definition: bm_devs_decl.h:630
IORES RegTranslation[IDX_MAX_REG]
Definition: bsmaster.h:1123
IDE_AHCI_CMD_LIST cmd_list[ATA_AHCI_MAX_TAGS]
Definition: bsmaster.h:846
#define IDX_AHCI_P_IS
Definition: bsmaster.h:684
#define INTERRUPT_REASON_IGNORE
Definition: atapi.h:1280
#define IDX_IO1_i_CylinderHigh
Definition: atapi.h:201
Status
Definition: gdiplustypes.h:24
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
ULONG WordsTransfered
Definition: bsmaster.h:886
VOID NTAPI UniataAhciSnapAtaRegs(IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN OUT PIDEREGS_EX regs)
Definition: id_sata.cpp:1212
#define IDX_IO1_i_Status
Definition: atapi.h:203
#define ATA_AHCI_P_IX_PS
Definition: bsmaster.h:500
#define DFLAGS_DEVICE_PRESENT
Definition: atapi.h:40
BOOLEAN NTAPI UniataAhciReadPM(IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN ULONG Reg, OUT PULONG result)
Definition: id_sata.cpp:2487
#define ATA_AHCI_P_CMD_FR
Definition: bsmaster.h:705
#define INTERRUPT_REASON_UNEXPECTED
Definition: atapi.h:1282
#define CMD
Definition: stat64.c:23
VOID UniataAhciSetupCmdPtr(IN OUT PATA_REQ AtaReq)
Definition: id_sata.cpp:2607
#define ATA_AHCI_P_IX_HBD
Definition: bsmaster.h:513
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:1651
unsigned short USHORT
Definition: pedump.c:61
#define AHCI_CAP_PMD
Definition: bsmaster.h:203
#define IDE_DC_A_4BIT
Definition: atapi.h:454
VOID DDKFASTAPI AtapiWritePort4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG data)
#define IDE_STATUS_BUSY
Definition: atapi.h:132
VOID DDKFASTAPI AtapiWritePortEx4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs, IN ULONG data)
UCHAR Flags
Definition: bsmaster.h:892
ULONG lChannel
Definition: bsmaster.h:1060
ULONG CPDS
Definition: bsmaster.h:494
#define IDX_SATA_SActive
Definition: bsmaster.h:460
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define ATA_AHCI_CMD_CLR_BUSY
Definition: bsmaster.h:820
#define ATA_AHCI_P_IX_OF
Definition: bsmaster.h:510
#define ATA_AHCI_CMD_RESET
Definition: bsmaster.h:818
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
#define SControl_DET_Idle
Definition: bsmaster.h:332
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
#define ATA_AHCI_P_CMD_SUD
Definition: bsmaster.h:699
#define AHCI_CLB_ALIGNEMENT_MASK
Definition: bsmaster.h:518
#define IDX_SATA_SStatus
Definition: bsmaster.h:457
PSCSI_REQUEST_BLOCK Srb
Definition: bsmaster.h:880
ULONG DDKFASTAPI AtapiReadPortEx4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs)
#define PRINT_PREFIX
Definition: atapi.h:150
ULONG NTAPI CheckDevice(IN PVOID HwDeviceExtension, IN ULONG Channel, IN ULONG deviceNumber, IN BOOLEAN ResetBus)
Definition: id_probe.cpp:2881
#define IDX_AHCI_GHC
Definition: bsmaster.h:271
#define ATA_AHCI_P_IX_PRC
Definition: bsmaster.h:508
#define ATA_CMD_FLAG_LBAIOsupp
Definition: atapi.h:1599
ULONG PRCS
Definition: bsmaster.h:484
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:1337
int command(const char *fmt,...)
Definition: ftp.c:266
PATA_REQ AhciInternalAtaReq
Definition: bsmaster.h:1109
#define AtapiStallExecution(dt)
Definition: atapi.h:158
#define ATA_AHCI_P_CMD_FRE
Definition: bsmaster.h:702
#define ATA_MARVELL_ID
Definition: bm_devs_decl.h:327
UCHAR cfis[64]
Definition: bsmaster.h:807
BOOLEAN NTAPI UniataAhciStop(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:2136
#define OUT
Definition: typedefs.h:39
#define IDE_STATUS_ERROR
Definition: atapi.h:125
#define IDX_AHCI_o_CylinderLowExp
Definition: bsmaster.h:795
#define ATA_CMD_FLAG_48
Definition: atapi.h:1601
#define UniAtaClearAtaReq(AtaReq)
Definition: atapi.h:1617
#define IDX_AHCI_o_BlockNumber
Definition: bsmaster.h:787
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
#define c
Definition: ke_i.h:80
#define ATA_AHCI_P_CMD_CR
Definition: bsmaster.h:706
#define UNIATA_SATA_RESET_ENABLE
Definition: id_sata.h:48
#define ATA_M88SE6141
Definition: bm_devs_decl.h:340
unsigned int ULONG
Definition: retypes.h:1
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 RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define AHCI_GHC_HR
Definition: bsmaster.h:221
#define IDX_AHCI_P_SControl
Definition: bsmaster.h:691
struct _IDE_AHCI_REGISTERS IDE_AHCI_REGISTERS
#define IDE_COMMAND_ATAPI_PACKET
Definition: atapi.h:109
#define IDX_IO1_i_Error
Definition: atapi.h:197
ULONG PCS
Definition: bsmaster.h:480
#define ATA_AHCI_P_IX_TFE
Definition: bsmaster.h:515
ULONG AhciPrevCI
Definition: bsmaster.h:1102
#define IDX_AHCI_P_CLB
Definition: bsmaster.h:682
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1036
#define UNIATA_AHCI_ALT_SIG
Definition: bm_devs_decl.h:633
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
#define AHCI_CAP_SAM
Definition: bsmaster.h:205
GLfloat GLfloat p
Definition: glext.h:8902
#define IDX_AHCI_VS
Definition: bsmaster.h:273
#define IDX_AHCI_BOHC
Definition: bsmaster.h:276
#define IDX_AHCI_o_FeatureExp
Definition: bsmaster.h:793
union _ATA_REQ * PATA_REQ
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
BOOLEAN NTAPI UniAtaAhciValidateVersion(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG version, IN BOOLEAN Strict)
Definition: id_sata.cpp:856
#define IDX_IO1_i_BlockCount
Definition: atapi.h:198
#define IDX_AHCI_P_CMD
Definition: bsmaster.h:689
#define AHCI_BOHC_OOS
Definition: bsmaster.h:262
GLuint64EXT * result
Definition: glext.h:11304
#define IDX_IO1_i_CylinderLow
Definition: atapi.h:200
#define KdPrint(x)
Definition: env_spec_w32.h:288
#define ULONGIO_PTR
Definition: config.h:102
#define SControl_DET_DoNothing
Definition: bsmaster.h:331
#define IDX_AHCI_P_SStatus
Definition: bsmaster.h:690
#define IDX_AHCI_o_CylinderLow
Definition: bsmaster.h:788
#define ATAPI_DEVICE(chan, dev)
Definition: atapi.h:1626
unsigned short * PUSHORT
Definition: retypes.h:2
struct _HW_LU_EXTENSION * lun[IDE_MAX_LUN_PER_CHAN]
Definition: bsmaster.h:1084
ULONG NumberChannels
Definition: atapi.c:68
#define AHCI_CAP_SCLO
Definition: bsmaster.h:207
PUSHORT DataBuffer
Definition: bsmaster.h:882
ULONG PmLunMap
Definition: bsmaster.h:1087
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:1534
#define AHCI_FIS_ALIGNEMENT_MASK
Definition: bsmaster.h:519
ULONG Reg
Definition: bsmaster.h:496
#define AHCI_CAP_NCS_MASK
Definition: bsmaster.h:202
__inline BOOLEAN UniataAhciChanImplemented(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG c)
Definition: id_sata.h:415
#define IDE_COMMAND_READ_PM
Definition: atapi.h:399
#define IDE_USE_LBA
Definition: atapi.h:446
ULONG Addr
Definition: bsmaster.h:1006
ULONGLONG cmd_table_phys
Definition: bsmaster.h:827
char * tag
Definition: main.c:59