ReactOS  0.4.14-dev-115-g4576127
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 #ifdef __REACTOS__
654  ULONG_PTR BaseMemAddress;
655 #else
656  ULONG BaseMemAddress;
657 #endif
658  ULONG PI;
659  ULONG CAP;
660  ULONG CAP2;
661  ULONG BOHC;
662  ULONG GHC;
663  BOOLEAN MemIo = FALSE;
664 
665  KdPrint2((PRINT_PREFIX " UniataAhciInit:\n"));
666 
667 #ifdef _DEBUG
668  UniataDumpAhciRegs(deviceExtension);
669 #endif //_DEBUG
670 
671  CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2);
672  if(CAP2 & AHCI_CAP2_BOH) {
673  BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
674  KdPrint2((PRINT_PREFIX " stage 1 BOHC %#x\n", BOHC));
675  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_BOHC,
676  BOHC | AHCI_BOHC_OOS);
677  for(i=0; i<50; i++) {
678  AtapiStallExecution(500);
679  BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
680  KdPrint2((PRINT_PREFIX " BOHC %#x\n", BOHC));
681  if(BOHC & AHCI_BOHC_BB) {
682  break;
683  }
684  if(!(BOHC & AHCI_BOHC_BOS)) {
685  break;
686  }
687  }
688  KdPrint2((PRINT_PREFIX " stage 2 BOHC %#x\n", BOHC));
689  if(BOHC & AHCI_BOHC_BB) {
690  for(i=0; i<2000; i++) {
691  AtapiStallExecution(1000);
692  BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
693  KdPrint2((PRINT_PREFIX " BOHC %#x\n", BOHC));
694  if(!(BOHC & AHCI_BOHC_BOS)) {
695  break;
696  }
697  }
698  }
699  KdPrint2((PRINT_PREFIX " final BOHC %#x\n", BOHC));
700  }
701 
702  /* disable AHCI interrupts, for MSI compatibility issue
703  see http://www.intel.com/Assets/PDF/specupdate/307014.pdf
704  26. AHCI Reset and MSI Request
705  */
706 
707  KdPrint2((PRINT_PREFIX " get GHC\n"));
708  /* enable AHCI mode */
709  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
710  if(!(GHC & AHCI_GHC_AE)) {
711  KdPrint2((PRINT_PREFIX " enable AHCI mode, disable intr, GHC %#x\n", GHC));
712  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
713  (GHC | AHCI_GHC_AE) & ~AHCI_GHC_IE);
714  } else {
715  KdPrint2((PRINT_PREFIX " disable intr, GHC %#x\n", GHC));
716  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
717  GHC & ~AHCI_GHC_IE);
718  }
719  AtapiStallExecution(100);
720 
721  /* read GHC again and reset AHCI controller */
722  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
723  KdPrint2((PRINT_PREFIX " reset AHCI controller, GHC %#x\n", GHC));
724  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
725  GHC | AHCI_GHC_HR);
726 
727  for(i=0; i<1000; i++) {
728  AtapiStallExecution(1000);
729  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
730  KdPrint2((PRINT_PREFIX " AHCI GHC %#x\n", GHC));
731  if(!(GHC & AHCI_GHC_HR)) {
732  break;
733  }
734  }
735  if(GHC & AHCI_GHC_HR) {
736  KdPrint2((PRINT_PREFIX " AHCI reset failed\n"));
737  return FALSE;
738  }
739 
740  /* re-enable AHCI mode */
741  /* Linux: Some controllers need AHCI_EN to be written multiple times.
742  * Try a few times before giving up.
743  */
744  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
745  for(i=0; i<5; i++) {
746  if(!(GHC & AHCI_GHC_AE)) {
747  KdPrint2((PRINT_PREFIX " re-enable AHCI mode, GHC %#x\n", GHC));
748  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
749  GHC | AHCI_GHC_AE);
750  AtapiStallExecution(1000);
751  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
752  } else {
753  break;
754  }
755  }
756  KdPrint2((PRINT_PREFIX " AHCI GHC %#x\n", GHC));
757  if(!(GHC & AHCI_GHC_AE)) {
758  KdPrint2((PRINT_PREFIX " Can't enable AHCI mode\n"));
759  return FALSE;
760  }
761 
762  deviceExtension->AHCI_CAP =
763  CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
764  KdPrint2((PRINT_PREFIX " AHCI CAP %#x\n", CAP));
765  if(CAP & AHCI_CAP_S64A) {
766  KdPrint2((PRINT_PREFIX " AHCI 64bit\n"));
767  deviceExtension->Host64 = TRUE;
768  }
769  KdPrint2((PRINT_PREFIX " AHCI %d CMD slots\n", (CAP & AHCI_CAP_NCS_MASK) >> 8 ));
770  if(CAP & AHCI_CAP_PMD) {
771  KdPrint2((PRINT_PREFIX " AHCI multi-block PIO\n"));
772  }
773  if(CAP & AHCI_CAP_SAM) {
774  KdPrint2((PRINT_PREFIX " AHCI legasy SATA\n"));
775  }
776 
777  /* get the number of HW channels */
778  PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI);
779  deviceExtension->AHCI_PI = PI;
780  KdPrint2((PRINT_PREFIX " AHCI PI %#x\n", PI));
781  KdPrint2((PRINT_PREFIX " AHCI PI mask %#x\n", deviceExtension->AHCI_PI_mask));
782  deviceExtension->AHCI_PI = PI = PI & deviceExtension->AHCI_PI_mask;
783  KdPrint2((PRINT_PREFIX " masked AHCI PI %#x\n", PI));
784 
785  CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2);
786  if(CAP2 & AHCI_CAP2_BOH) {
787  KdPrint2((PRINT_PREFIX " retry BOHC\n"));
788  BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
789  KdPrint2((PRINT_PREFIX " BOHC %#x\n", BOHC));
790  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_BOHC,
791  BOHC | AHCI_BOHC_OOS);
792  }
793  /* clear interrupts */
794  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_IS,
795  UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS));
796 
797  /* enable AHCI interrupts */
798  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
799  UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC) | AHCI_GHC_IE);
800 
801  BaseMemAddress = deviceExtension->BaseIoAHCI_0.Addr;
802  MemIo = deviceExtension->BaseIoAHCI_0.MemIo;
803 
804  deviceExtension->MaxTransferMode = ATA_SA150+(((CAP & AHCI_CAP_ISS_MASK) >> 20)-1);
805  KdPrint2((PRINT_PREFIX " SATA Gen %d\n", ((CAP & AHCI_CAP_ISS_MASK) >> 20) ));
806 
807  for(c=0; c<deviceExtension->NumberChannels; c++) {
808  chan = &deviceExtension->chan[c];
809  offs = sizeof(IDE_AHCI_REGISTERS) + c*sizeof(IDE_AHCI_PORT_REGISTERS);
810 
811  KdPrint2((PRINT_PREFIX " chan %d, offs %#x\n", c, offs));
812 
813  chan->MaxTransferMode = deviceExtension->MaxTransferMode;
814 
815  AtapiSetupLunPtrs(chan, deviceExtension, c);
816 
817  chan->BaseIoAHCI_Port = deviceExtension->BaseIoAHCI_0;
818  chan->BaseIoAHCI_Port.Addr = BaseMemAddress + offs;
819 
820  chan->RegTranslation[IDX_IO1_i_Status ].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, TFD.STS);
821  chan->RegTranslation[IDX_IO1_i_Status ].MemIo = MemIo;
823  chan->RegTranslation[IDX_IO1_i_Error ].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, TFD.ERR);
824  chan->RegTranslation[IDX_IO1_i_Error ].MemIo = MemIo;
830  chan->RegTranslation[IDX_IO1_i_BlockCount ].MemIo = MemIo;
831 
832  UniataInitSyncBaseIO(chan);
833 
834  chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SSTS);
835  chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo;
836  chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SERR);
837  chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo;
838  chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SCTL);
839  chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo;
840  chan->RegTranslation[IDX_SATA_SActive].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SACT);
841  chan->RegTranslation[IDX_SATA_SActive].MemIo = MemIo;
842 
843  AtapiDmaAlloc(HwDeviceExtension, NULL, c);
844 
845  if(!UniataAhciChanImplemented(deviceExtension, c)) {
846  KdPrint2((PRINT_PREFIX " chan %d not implemented\n", c));
847  continue;
848  }
849 
850  UniataAhciResume(chan);
851 
853  }
854 
855  return TRUE;
856 } // end UniataAhciInit()
857 
858 BOOLEAN
859 NTAPI
861  IN PHW_DEVICE_EXTENSION deviceExtension,
862  IN ULONG version,
863  IN BOOLEAN Strict
864  )
865 {
866  switch(version) {
867  case 0x00000000:
868  case 0xffffffff:
869  KdPrint((" wrong AHCI revision %#x\n", version));
870  return FALSE;
871  case 0x00000905:
872  case 0x00010000:
873  case 0x00010100:
874  case 0x00010200:
875  case 0x00010300:
876  case 0x00010301:
877  break;
878  default:
879  KdPrint2((PRINT_PREFIX " Unknown AHCI revision\n"));
880  if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"CheckAhciRevision", Strict)) {
881  KdPrint((" AHCI revision excluded %#x\n", version));
882  return FALSE;
883  }
884  }
885  return TRUE;
886 } // end UniAtaAhciValidateVersion()
887 
888 BOOLEAN
889 NTAPI
891  IN PVOID HwDeviceExtension,
892  IN PPCI_COMMON_CONFIG pciData, // optional
894  )
895 {
896  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
897  //ULONG slotNumber = deviceExtension->slotNumber;
898  ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
899  ULONG version;
900  ULONG i, n;
901  ULONG PI;
902  //ULONG PI_ex_mask=0;
903  ULONG CAP;
904  ULONG CAP2;
905  ULONG GHC, GHC0;
906 #ifdef _DEBUG
907  ULONG BOHC;
908  ULONG v_Mn, v_Mj;
909 #endif //_DEBUG
910  ULONG NumberChannels;
911  ULONG_PTR BaseMemAddress;
912  BOOLEAN MemIo = FALSE;
913  BOOLEAN found = FALSE;
914  ULONG BarId=5;
915 
916  KdPrint2((PRINT_PREFIX " UniataAhciDetect:\n"));
917 
918  if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreAhci", 0)) {
919  KdPrint((" AHCI excluded\n"));
920  return FALSE;
921  }
922  switch(deviceExtension->DevID) {
923  case 0xa01c0031:
924  KdPrint2((PRINT_PREFIX " Cavium uses BAR(0)\n"));
925  BarId = 0;
926  break;
927  }
928  BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
929  BarId, 0, 0x10);
930  if(!BaseMemAddress) {
931  KdPrint2((PRINT_PREFIX " AHCI init failed - no IoRange\n"));
932  return FALSE;
933  }
934  if((*ConfigInfo->AccessRanges)[BarId].RangeInMemory) {
935  KdPrint2((PRINT_PREFIX "MemIo\n"));
936  MemIo = TRUE;
937  }
938  deviceExtension->BaseIoAHCI_0.Addr = BaseMemAddress;
939  deviceExtension->BaseIoAHCI_0.MemIo = MemIo;
940 
941 #ifdef _DEBUG
942  UniataDumpAhciRegs(deviceExtension);
943 #endif //_DEBUG
944 
945  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
946  if(GHC & AHCI_GHC_HR) {
947  KdPrint2((PRINT_PREFIX " AHCI in reset state\n"));
948  return FALSE;
949  }
950 
951  /* check AHCI mode. Save state and try enable */
952  GHC0 =
953  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
954  KdPrint2((PRINT_PREFIX " check AHCI mode, GHC %#x\n", GHC));
955 
956  version = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_VS);
957 
958  if(!(GHC & AHCI_GHC_AE)) {
959  KdPrint2((PRINT_PREFIX " Non-AHCI GHC (!AE), check revision %#x\n", version));
960  if(!UniAtaAhciValidateVersion(deviceExtension, version, FALSE)) {
961  KdPrint2((PRINT_PREFIX " Non-AHCI\n"));
962  goto exit_detect;
963  }
964  KdPrint2((PRINT_PREFIX " try enable\n"));
965  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
966  (GHC | AHCI_GHC_AE) & ~AHCI_GHC_IE);
967  GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
968 
969  KdPrint2((PRINT_PREFIX " re-check AHCI mode, GHC %#x\n", GHC));
970  if(!(GHC & AHCI_GHC_AE)) {
971  KdPrint2((PRINT_PREFIX " Non-AHCI GHC (!AE)\n"));
972  goto exit_detect;
973  }
974  }
975 
976  CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
977  CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2);
978  KdPrint2((PRINT_PREFIX " AHCI CAP %#x, CAP2 %#x, ver %#x\n", CAP, CAP2, version));
979  if(CAP & AHCI_CAP_S64A) {
980  KdPrint2((PRINT_PREFIX " 64bit"));
981  //deviceExtension->Host64 = TRUE; // this is just DETECT, do not update anything
982  }
983 #ifdef _DEBUG
984  if(CAP2 & AHCI_CAP2_BOH) {
985  BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
986  KdPrint2((PRINT_PREFIX " BOHC %#x", BOHC));
987  }
988 #endif //_DEBUG
989  if(CAP & AHCI_CAP_NCQ) {
990  KdPrint2((PRINT_PREFIX " NCQ"));
991  }
992  if(CAP & AHCI_CAP_SNTF) {
993  KdPrint2((PRINT_PREFIX " SNTF"));
994  }
995  if(CAP & AHCI_CAP_CCC) {
996  KdPrint2((PRINT_PREFIX " CCC"));
997  }
998  KdPrint2((PRINT_PREFIX "\n"));
999 
1000  /* get the number of HW channels */
1001 
1002  /* CAP.NOP sometimes indicate the index of the last enabled
1003  * port, at other times, that of the last possible port, so
1004  * determining the maximum port number requires looking at
1005  * both CAP.NOP and PI.
1006  */
1007  PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI);
1008  deviceExtension->AHCI_PI = deviceExtension->AHCI_PI_mask = PI;
1009  KdPrint2((PRINT_PREFIX " AHCI PI %#x\n", PI));
1010 
1011  for(i=PI, n=0; i; n++, i=i>>1) {
1012  if(AtapiRegCheckDevValue(deviceExtension, n, DEVNUM_NOT_SPECIFIED, L"Exclude", 0)) {
1013  KdPrint2((PRINT_PREFIX "Channel %d excluded\n", n));
1014  deviceExtension->AHCI_PI &= ~((ULONG)1 << n);
1015  deviceExtension->AHCI_PI_mask &= ~((ULONG)1 << n);
1016  //PI_ex_mask |= ((ULONG)1 << n);
1017  }
1018  }
1019  deviceExtension->AHCI_PI_mask =
1020  AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PortMask", deviceExtension->AHCI_PI_mask);
1021  KdPrint2((PRINT_PREFIX "Force PortMask %#x\n", deviceExtension->AHCI_PI_mask));
1022 
1023  for(i=PI, n=0; i; n++, i=i>>1);
1024  NumberChannels =
1025  max((CAP & AHCI_CAP_NOP_MASK)+1, n);
1026 
1027  if(!PI && ((CAP & AHCI_CAP_NOP_MASK)+1)) {
1028  /* Enable ports.
1029  * The spec says that BIOS sets up bits corresponding to
1030  * available ports. On platforms where this information
1031  * is missing, the driver can define available ports on its own.
1032  */
1033  KdPrint2((PRINT_PREFIX "PI=0 -> Enable ports (mask) %#x\n", deviceExtension->AHCI_PI_mask));
1034  n = NumberChannels;
1035  deviceExtension->AHCI_PI = ((ULONG)1 << n)-1;
1036 
1037  if(deviceExtension->AHCI_PI_mask) {
1038  // we have some forced port mask
1039  PI = deviceExtension->AHCI_PI_mask;
1040  } else {
1041  // construct mask
1042  PI = deviceExtension->AHCI_PI = (((ULONG)1 << n)-1);
1043  deviceExtension->AHCI_PI_mask = (((ULONG)1 << n)-1);
1044  }
1045  KdPrint2((PRINT_PREFIX "Enable ports final PI %#x\n", PI));
1046  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_PI, PI);
1047  }
1048 
1049  KdPrint2((PRINT_PREFIX " CommandSlots %d\n", (CAP & AHCI_CAP_NCS_MASK)>>8 ));
1050  KdPrint2((PRINT_PREFIX " Detected Channels %d / %d\n", NumberChannels, n));
1051 
1052  switch(deviceExtension->DevID) {
1053  case 0x2361197b:
1054  KdPrint2((PRINT_PREFIX " JMicron JMB361 -> 1\n"));
1055  NumberChannels = 1;
1056  break;
1057  case ATA_M88SE6111:
1058  KdPrint2((PRINT_PREFIX " Marvell M88SE6111 -> 1\n"));
1059  NumberChannels = 1;
1060  break;
1061  case ATA_M88SE6121:
1062  KdPrint2((PRINT_PREFIX " Marvell M88SE6121 -> 2\n"));
1063  NumberChannels = min(NumberChannels, 2);
1064  break;
1065  case ATA_M88SE6141:
1066  case ATA_M88SE6145:
1067  case ATA_M88SE9123:
1068  KdPrint2((PRINT_PREFIX " Marvell M88SE614x/9123 -> 4\n"));
1069  NumberChannels = min(NumberChannels, 4);
1070  break;
1071  } // switch()
1072 
1073  if(!NumberChannels) {
1074  KdPrint2((PRINT_PREFIX " Non-AHCI - NumberChannels=0\n"));
1075  found = FALSE;
1076  goto exit_detect;
1077  }
1078  KdPrint2((PRINT_PREFIX " Adjusted Channels %d\n", NumberChannels));
1079 
1080 #ifdef _DEBUG
1081  v_Mj = ((version >> 20) & 0xf0) + ((version >> 16) & 0x0f);
1082  v_Mn = ((version >> 4) & 0xf0) + (version & 0x0f);
1083 
1084  KdPrint2((PRINT_PREFIX " AHCI version %x.%02x controller with %d ports (mask %#x) detected\n",
1085  v_Mj, v_Mn,
1086  NumberChannels, PI));
1087  KdPrint((" AHCI SATA Gen %d\n", (((CAP & AHCI_CAP_ISS_MASK) >> 20)) ));
1088 #endif //_DEBUG
1089 
1090  if(CAP & AHCI_CAP_SPM) {
1091  KdPrint2((PRINT_PREFIX " PM supported\n"));
1092  if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreAhciPM", 1 /* DEBUG */)) {
1093  KdPrint2((PRINT_PREFIX "SATA/AHCI w/o PM, max luns 1\n"));
1094  deviceExtension->NumberLuns = 1;
1095  //chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
1096  } else {
1097  KdPrint2((PRINT_PREFIX "SATA/AHCI -> possible PM, max luns %d\n", SATA_MAX_PM_UNITS));
1098  deviceExtension->NumberLuns = SATA_MAX_PM_UNITS;
1099  //deviceExtension->NumberLuns = 1;
1100  }
1101  } else {
1102  KdPrint2((PRINT_PREFIX " PM not supported -> 1 lun/chan\n"));
1103  deviceExtension->NumberLuns = 1;
1104  }
1105 
1106  if(!UniAtaAhciValidateVersion(deviceExtension, version, TRUE)) {
1107  goto exit_detect;
1108  }
1109 
1110  deviceExtension->HwFlags |= UNIATA_SATA | UNIATA_AHCI;
1111  if(deviceExtension->NumberChannels < NumberChannels) {
1112  deviceExtension->NumberChannels = NumberChannels;
1113  }
1114  deviceExtension->DmaSegmentLength = 0x3fffff+1; // 4MB
1115  deviceExtension->DmaSegmentAlignmentMask = -1; // no restrictions
1116 
1117  deviceExtension->BusMaster = DMA_MODE_AHCI;
1118  deviceExtension->MaxTransferMode = max(deviceExtension->MaxTransferMode, ATA_SA150+(((CAP & AHCI_CAP_ISS_MASK) >> 20)-1) );
1119 
1120  found = TRUE;
1121 
1122 exit_detect:
1123  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC, GHC0);
1124  KdPrint((" AHCI detect status %d\n", found));
1125 
1126  return found;
1127 } // end UniataAhciDetect()
1128 
1129 UCHAR
1130 NTAPI
1132  IN PVOID HwDeviceExtension,
1133  IN ULONG lChannel,
1135  )
1136 {
1137  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1138  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1139  ULONG Channel = deviceExtension->Channel + lChannel;
1140  ULONG hIS;
1141  ULONG CI, ACT;
1142  AHCI_IS_REG IS;
1143  SATA_SSTATUS_REG SStatus;
1145  //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
1146  ULONG tag=0;
1147 
1148  KdPrint(("UniataAhciStatus(%d-%d):\n", lChannel, Channel));
1149 
1150  hIS = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS);
1151  KdPrint((" hIS %#x\n", hIS));
1152  hIS &= (1 << Channel);
1153  if(!hIS) {
1154  return INTERRUPT_REASON_IGNORE;
1155  }
1159  SStatus.Reg = AtapiReadPort4(chan, IDX_SATA_SStatus);
1160  SError.Reg = AtapiReadPort4(chan, IDX_SATA_SError);
1161 
1162  /* clear interrupt(s) */
1163  UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_IS, hIS);
1166 
1167  KdPrint((" AHCI: is=%08x ss=%08x serror=%08x CI=%08x, ACT=%08x\n",
1168  IS.Reg, SStatus.Reg, SError.Reg, CI, ACT));
1169 
1170  /* do we have cold connect surprise */
1171  if(IS.CPDS) {
1172  }
1173 
1174  /* check for and handle connect events */
1175  if(IS.PCS) {
1176  UniataSataEvent(HwDeviceExtension, lChannel, UNIATA_SATA_EVENT_ATTACH);
1177  }
1178  if(IS.PRCS) {
1179  UniataSataEvent(HwDeviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH);
1180  }
1181  chan->AhciCompleteCI = (chan->AhciPrevCI ^ CI) & chan->AhciPrevCI; // only 1->0 states
1182  chan->AhciPrevCI = CI;
1183  chan->AhciLastSError = SError.Reg;
1184  KdPrint((" AHCI: complete mask %#x\n", chan->AhciCompleteCI));
1185  chan->AhciLastIS = IS.Reg;
1186  if(CI & (1 << tag)) {
1187 #ifdef _DEBUG
1188  UniataDumpAhciPortRegs(chan);
1189 #endif //_DEBUG
1190  //deviceExtension->ExpectingInterrupt++; // will be updated in ISR on ReturnEnableInterrupts
1191  if(IS.Reg &
1194  KdPrint((" AHCI: unexpected, error\n"));
1195  } else {
1196  KdPrint((" AHCI: unexpected, incomplete command or error ?\n"));
1197 /*
1198  ULONG TFD;
1199 
1200  TFD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_TFD);
1201  KdPrint2((" TFD %#x\n", TFD));
1202  if(TFD & IDE_STATUS_BUSY) {
1203  KdPrint2((" Seems to be interrupt on error\n"));
1204  return INTERRUPT_REASON_OUR;
1205  }
1206 */
1208  }
1209  }
1210  return INTERRUPT_REASON_OUR;
1211 
1212 } // end UniataAhciStatus()
1213 
1214 VOID
1215 NTAPI
1217  IN PHW_CHANNEL chan,
1220  )
1221 {
1222  ULONG TFD, SIG;
1223 
1224  regs->bDriveHeadReg = IDE_DRIVE_SELECT_1;
1226  regs->bCommandReg = (UCHAR)(TFD & 0xff);
1227  regs->bFeaturesReg = (UCHAR)((TFD >> 8) & 0xff);
1228 
1230  regs->bSectorCountReg = (UCHAR)(SIG & 0xff);
1231  regs->bSectorNumberReg = (UCHAR)((SIG >> 8) & 0xff);
1232  regs->bCylLowReg = (UCHAR)((SIG >> 16) & 0xff);
1233  regs->bCylHighReg = (UCHAR)((SIG >> 24) & 0xff);
1234  regs->bOpFlags = 0;
1235 
1236  return;
1237 } // end UniataAhciSnapAtaRegs()
1238 
1239 ULONG
1240 NTAPI
1242  IN PHW_DEVICE_EXTENSION deviceExtension,
1244  IN ULONG lChannel,
1245  OUT PUCHAR fis,
1246  IN UCHAR command,
1247  IN ULONGLONG lba,
1248  IN USHORT count,
1249  IN USHORT feature
1250  )
1251 {
1252  //ULONG i;
1253  PUCHAR plba;
1254  BOOLEAN need48;
1255  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1256 
1257  KdPrint2((PRINT_PREFIX " AHCI setup FIS %x, ch %d, dev %d\n", fis, lChannel, DeviceNumber));
1258  //i = 0;
1259  plba = (PUCHAR)&lba;
1260 
1261  RtlZeroMemory(fis, 20);
1262 
1263  fis[0] = AHCI_FIS_TYPE_ATA_H2D; /* host to device */
1264  fis[1] = 0x80 | ((UCHAR)DeviceNumber & 0x0f); /* command FIS (note PM goes here) */
1268 
1269  // IDE_COMMAND_ATAPI_IDENTIFY should be processed as regular ATA command,
1270  // the rest of ATAPI requests are processed via IDE_COMMAND_ATAPI_PACKET
1271  if(/*(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
1272  */
1275  if(feature & ATA_F_DMA) {
1276  fis[IDX_AHCI_o_Feature] = (UCHAR)(feature & 0xff);
1277  } else {
1278  fis[IDX_AHCI_o_CylinderLow] = (UCHAR)(count & 0xff);
1279  fis[IDX_AHCI_o_CylinderHigh] = (UCHAR)(count>>8) & 0xff;
1280  }
1281  //fis[IDX_AHCI_o_Control] |= IDE_DC_A_4BIT;
1282  } else {
1283 
1286  KdPrint3((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count));
1287  return 0;
1288  }
1289 
1290  need48 = UniAta_need_lba48(command, lba, count,
1291  chan->lun[DeviceNumber]->IdentifyData.FeaturesSupport.Address48);
1292 
1293  /* translate command into 48bit version */
1294  if(need48) {
1297  } else {
1298  KdPrint2((PRINT_PREFIX " unhandled LBA48 command\n"));
1299  return 0;
1300  }
1301  }
1302 
1303  fis[IDX_AHCI_o_Command] = command;
1305 
1306  fis[IDX_AHCI_o_BlockNumber] = plba[0];
1307  fis[IDX_AHCI_o_CylinderLow] = plba[1];
1308  fis[IDX_AHCI_o_CylinderHigh] = plba[2];
1309 
1310  fis[IDX_AHCI_o_BlockCount] = (UCHAR)count & 0xff;
1311 
1312  if(need48) {
1313  //i++;
1315 
1316  fis[IDX_AHCI_o_BlockNumberExp] = plba[3];
1317  fis[IDX_AHCI_o_CylinderLowExp] = plba[4];
1318  fis[IDX_AHCI_o_CylinderHighExp] = plba[5];
1319 
1320  fis[IDX_AHCI_o_BlockCountExp] = (UCHAR)(count>>8) & 0xff;
1321 
1322  fis[IDX_AHCI_o_FeatureExp] = (UCHAR)(feature>>8) & 0xff;
1323 
1325  } else {
1326  fis[IDX_AHCI_o_DriveSelect] |= /*IDE_DRIVE_1 |*/ (plba[3] & 0x0f);
1327  chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48;
1328  }
1329 
1330  //fis[14] = 0x00;
1331 
1332  }
1333 
1334  //KdDump(fis, 20);
1335 
1336  return 20;
1337 } // end UniataAhciSetupFIS_H2D()
1338 
1339 ULONG
1340 NTAPI
1342  IN PHW_DEVICE_EXTENSION deviceExtension,
1344  IN ULONG lChannel,
1345  OUT PUCHAR fis,
1347  )
1348 {
1349  //ULONG i;
1350  //PUCHAR plba;
1351  BOOLEAN need48;
1352  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1353  UCHAR command;
1354 
1355  command = regs->bCommandReg;
1356 
1357  KdPrint2((PRINT_PREFIX " AHCI setup FIS Direct %x, ch %d, dev %d\n", fis, lChannel, DeviceNumber));
1358  //i = 0;
1359  //plba = (PUCHAR)&lba;
1360 
1361  RtlZeroMemory(fis, 20);
1362 
1363  fis[0] = AHCI_FIS_TYPE_ATA_H2D; /* host to device */
1364  fis[1] = 0x80 | ((UCHAR)DeviceNumber & 0x0f); /* command FIS (note PM goes here) */
1368 
1369  // IDE_COMMAND_ATAPI_IDENTIFY should be processed as regular ATA command,
1370  // the rest of ATAPI requests are processed via IDE_COMMAND_ATAPI_PACKET
1371  if(/*(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
1372  */
1374 /* fis[IDX_AHCI_o_Command] = IDE_COMMAND_ATAPI_PACKET;
1375  if(feature & ATA_F_DMA) {
1376  fis[IDX_AHCI_o_Feature] = (UCHAR)(feature & 0xff);
1377  } else {
1378  fis[IDX_AHCI_o_CylinderLow] = (UCHAR)(count & 0xff);
1379  fis[IDX_AHCI_o_CylinderHigh] = (UCHAR)(count>>8) & 0xff;
1380  }*/
1381  return 0;
1382  //fis[IDX_AHCI_o_Control] |= IDE_DC_A_4BIT;
1383  } else {
1384 
1385  need48 = (regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND) &&
1386  chan->lun[DeviceNumber]->IdentifyData.FeaturesSupport.Address48;
1387 
1388  /* translate command into 48bit version */
1389  if(need48) {
1392  } else {
1393  KdPrint2((PRINT_PREFIX " unhandled LBA48 command\n"));
1394  return 0;
1395  }
1396  }
1397 
1398  fis[IDX_AHCI_o_Command] = command;
1399  fis[IDX_AHCI_o_Feature] = regs->bFeaturesReg;
1400 
1401  fis[IDX_AHCI_o_BlockNumber] = regs->bSectorNumberReg;
1402  fis[IDX_AHCI_o_CylinderLow] = regs->bCylLowReg;
1403  fis[IDX_AHCI_o_CylinderHigh] = regs->bCylHighReg;
1404 
1405  fis[IDX_AHCI_o_BlockCount] = regs->bSectorCountReg;
1406 
1407  if(need48) {
1408  //i++;
1410 
1411  fis[IDX_AHCI_o_BlockNumberExp] = regs->bSectorNumberRegH;
1412  fis[IDX_AHCI_o_CylinderLowExp] = regs->bCylLowRegH;
1413  fis[IDX_AHCI_o_CylinderHighExp] = regs->bCylHighRegH;
1414 
1415  fis[IDX_AHCI_o_BlockCountExp] = regs->bSectorCountRegH;
1416 
1417  fis[IDX_AHCI_o_FeatureExp] = regs->bFeaturesRegH;
1418 
1420  } else {
1421  //fis[IDX_AHCI_o_DriveSelect] |= /*IDE_DRIVE_1 |*/ (plba[3] & 0x0f);
1422  chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48;
1423  }
1424  fis[IDX_AHCI_o_DriveSelect] |= regs->bDriveHeadReg & 0x0f;
1425  }
1426 
1427  KdDump(fis, 20);
1428 
1429  return 20;
1430 } // end UniataAhciSetupFIS_H2D_Direct()
1431 
1432 UCHAR
1433 NTAPI
1435  IN PHW_CHANNEL chan,
1436  IN ULONG timeout
1437  )
1438 {
1439  AHCI_IS_REG IS;
1440  //ULONG ACT;
1441  ULONG CI=0;
1442  ULONG i;
1443  ULONG SError;
1444  ULONG tag=0;
1445 
1446  timeout *= 5;
1447 
1448  for (i=0; i<timeout; i++) {
1450  //ACT = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_ACT);
1451  if (!(( CI >> tag) & 0x01)) {
1452  break;
1453  }
1455  //KdPrint((" IS %#x\n", IS.Reg));
1456  if(IS.Reg) {
1457  break;
1458  }
1460  if(SError) {
1461  KdPrint((" AHCI: error %#x\n", SError));
1462  i = timeout;
1463  break;
1464  }
1465  AtapiStallExecution(200);
1466  }
1467  KdPrint((" CI %#x\n", CI));
1468 
1469  //SStatus.Reg = AtapiReadPort4(chan, IDX_SATA_SStatus);
1470  //SError.Reg = AtapiReadPort4(chan, IDX_SATA_SError);
1471 
1472  /* clear interrupt(s) */
1474  KdPrint((" IS %#x\n", IS.Reg));
1476 
1477  if (timeout && (i >= timeout)) {
1478 #ifdef _DEBUG
1479  ULONG TFD;
1480 
1482  KdPrint((" AHCI: timeout, SError %#x\n", SError));
1483 
1485  KdPrint2((" TFD %#x\n", TFD));
1486 #endif //_DEBUG
1487 
1488  return IDE_STATUS_WRONG;
1489  }
1490 
1491  return IDE_STATUS_IDLE;
1492 } // end UniataAhciWaitCommandReady()
1493 
1494 UCHAR
1495 NTAPI
1497  IN PVOID HwDeviceExtension,
1498  IN ULONG lChannel,
1500  IN USHORT ahci_flags,
1501  IN ULONG timeout
1502  )
1503 {
1504  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1505  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1506  //ULONG Channel = deviceExtension->Channel + lChannel;
1507  //ULONG hIS;
1508  //ULONG SError;
1509  //SATA_SSTATUS_REG SStatus;
1510  //SATA_SERROR_REG SError;
1511  //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
1512  //ULONGIO_PTR base;
1513  ULONG tag=0;
1514 
1515  PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
1516 
1517  KdPrint(("UniataAhciSendCommand: lChan %d\n", chan->lChannel));
1518 
1519  AHCI_CL->prd_length = 0;
1520  //AHCI_CL->cmd_flags = (20 / sizeof(ULONG)) | ahci_flags | (DeviceNumber << 12);
1521  AHCI_CL->cmd_flags = UniAtaAhciAdjustIoFlags(0, ahci_flags, 20, DeviceNumber);
1522 
1523  AHCI_CL->bytecount = 0;
1525  if(AHCI_CL->cmd_table_phys & AHCI_CMD_ALIGNEMENT_MASK) {
1526  KdPrint2((PRINT_PREFIX " AHCI CMD address is not aligned (mask %#x)\n", (ULONG)AHCI_CMD_ALIGNEMENT_MASK));
1527  }
1528 
1529  //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag);
1531 
1532  return UniataAhciWaitCommandReady(chan, timeout);
1533 
1534 } // end UniataAhciSendCommand()
1535 
1536 UCHAR
1537 NTAPI
1539  IN PVOID HwDeviceExtension,
1540  IN ULONG lChannel,
1543  IN PUCHAR data,
1544  IN ULONG length, /* bytes */
1545  IN UCHAR command,
1546  IN ULONGLONG lba,
1547  IN USHORT bcount, /* block count, just ATA register */
1548  IN USHORT feature,
1549  IN USHORT ahci_flags,
1550  IN ULONG wait_flags,
1551  IN ULONG timeout
1552  )
1553 {
1554  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1555  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1556  UCHAR statusByte;
1557  PATA_REQ AtaReq;
1558  ULONG fis_size;
1559  //ULONG tag=0;
1560  //PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
1561  PIDE_AHCI_CMD AHCI_CMD = NULL;
1562 
1563  //PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
1564 
1565  KdPrint2((PRINT_PREFIX "UniataAhciSendPIOCommand: cntrlr %#x:%#x dev %#x, cmd %#x, lba %#I64x bcount %#x feature %#x, buff %#x, len %#x, WF %#x \n",
1566  deviceExtension->DevIndex, lChannel, DeviceNumber, command, lba, bcount, feature, data, length, wait_flags ));
1567 
1568  if(length/DEV_BSIZE != bcount) {
1569  KdPrint((" length/DEV_BSIZE != bcount\n"));
1570  }
1571 
1572 #ifdef _DEBUG
1573  //UniataDumpAhciPortRegs(chan);
1574 #endif // _DEBUG
1575 
1576  if(!Srb) {
1577  Srb = BuildAhciInternalSrb(HwDeviceExtension, DeviceNumber, lChannel, data, length);
1578  if(!Srb) {
1579  KdPrint((" !Srb\n"));
1580  return IDE_STATUS_WRONG;
1581  }
1582  //UniataAhciSetupCmdPtr(AtaReq); // must be called before DMA setup
1583  //should be already called on init
1584  }
1585  AtaReq = (PATA_REQ)(Srb->SrbExtension);
1586  //KdPrint((" Srb %#x, AtaReq %#x\n", Srb, AtaReq));
1587 
1588  AHCI_CMD = AtaReq->ahci.ahci_cmd_ptr;
1589 
1590  fis_size = UniataAhciSetupFIS_H2D(deviceExtension, DeviceNumber, lChannel,
1591  &(AHCI_CMD->cfis[0]),
1592  command,
1593  lba,
1594  bcount,
1595  feature
1596  );
1597 
1598  if(!fis_size) {
1599  KdPrint2(("!fis_size\n"));
1600  return IDE_STATUS_WRONG;
1601  }
1602 
1603  //KdPrint2(("UniAtaAhciAdjustIoFlags(command, ahci_flags, fis_size, DeviceNumber)\n"));
1604  ahci_flags = UniAtaAhciAdjustIoFlags(command, ahci_flags, fis_size, DeviceNumber);
1605  KdPrint2(("ahci_flags %#x\n", ahci_flags));
1606 
1607  if(data) {
1608  if(ahci_flags & ATA_AHCI_CMD_WRITE) {
1609  AtaReq->Flags &= ~REQ_FLAG_READ;
1610  Srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
1611  KdPrint((" assume OUT\n"));
1612  } else {
1613  AtaReq->Flags |= REQ_FLAG_READ;
1614  Srb->SrbFlags |= SRB_FLAGS_DATA_IN;
1615  KdPrint((" assume IN\n"));
1616  }
1617  if(!AtapiDmaSetup(HwDeviceExtension,
1618  DeviceNumber,
1619  lChannel, // logical channel,
1620  Srb,
1621  data,
1622  length)) {
1623  KdPrint2((" can't setup buffer\n"));
1624  return IDE_STATUS_WRONG;
1625  }
1626  }
1627 
1628  AtaReq->ahci.io_cmd_flags = ahci_flags;
1629 
1630 #ifdef _DEBUG
1631  //UniataDumpAhciPortRegs(chan);
1632 #endif // _DEBUG
1633 
1634  UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
1635 
1636 #ifdef _DEBUG
1637  //UniataDumpAhciPortRegs(chan);
1638 #endif // _DEBUG
1639 
1640  if(wait_flags == ATA_IMMEDIATE) {
1641  statusByte = 0;
1642  KdPrint2((" return imemdiately\n"));
1643  } else {
1644  statusByte = UniataAhciWaitCommandReady(chan, timeout);
1645  UniataAhciStatus(HwDeviceExtension, lChannel, DeviceNumber);
1646  UniataAhciEndTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
1647  }
1648 
1649  return statusByte;
1650 
1651 } // end UniataAhciSendPIOCommand()
1652 
1653 UCHAR
1654 NTAPI
1656  IN PVOID HwDeviceExtension,
1657  IN ULONG lChannel,
1661  IN ULONG wait_flags,
1662  IN ULONG timeout
1663  )
1664 {
1665  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1666  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1667  UCHAR statusByte;
1668  PATA_REQ AtaReq;
1669  ULONG fis_size;
1670  //ULONG tag=0;
1671  //PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
1672  PIDE_AHCI_CMD AHCI_CMD = NULL;
1673  USHORT ahci_flags=0;
1674 // USHORT bcount=0;
1675 
1676  //PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
1677 
1678  KdPrint2((PRINT_PREFIX "UniataAhciSendPIOCommand: cntrlr %#x:%#x dev %#x, buff %#x, len %#x, WF %#x \n",
1679  deviceExtension->DevIndex, lChannel, DeviceNumber, Srb->DataBuffer, Srb->DataTransferLength, wait_flags ));
1680 
1681 // if(Srb->DataTransferLength/DEV_BSIZE != bcount) {
1682 // KdPrint((" length/DEV_BSIZE != bcount\n"));
1683 // }
1684 
1685 #ifdef _DEBUG
1686  //UniataDumpAhciPortRegs(chan);
1687 #endif // _DEBUG
1688 
1689  if(!Srb) {
1690  KdPrint((" !Srb\n"));
1691  return IDE_STATUS_WRONG;
1692  //UniataAhciSetupCmdPtr(AtaReq); // must be called before DMA setup
1693  //should be already called on init
1694  }
1695  AtaReq = (PATA_REQ)(Srb->SrbExtension);
1696  //KdPrint((" Srb %#x, AtaReq %#x\n", Srb, AtaReq));
1697 
1698  AHCI_CMD = AtaReq->ahci.ahci_cmd_ptr;
1699  if(!AHCI_CMD) {
1700  KdPrint((" !AHCI_CMD\n"));
1701  return IDE_STATUS_WRONG;
1702  }
1703 
1704  if(Srb->DataTransferLength) {
1705  if(Srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
1706  ahci_flags |= ATA_AHCI_CMD_WRITE;
1707  AtaReq->Flags &= ~REQ_FLAG_READ;
1708  } else {
1709  AtaReq->Flags |= REQ_FLAG_READ;
1710  }
1711  }
1712 
1713  fis_size = UniataAhciSetupFIS_H2D_Direct(deviceExtension, DeviceNumber, lChannel,
1714  &(AHCI_CMD->cfis[0]),
1715  regs);
1716 
1717  if(!fis_size) {
1718  KdPrint2(("!fis_size\n"));
1719  return IDE_STATUS_WRONG;
1720  }
1721 
1722  //KdPrint2(("UniAtaAhciAdjustIoFlags(command, ahci_flags, fis_size, DeviceNumber)\n"));
1723  ahci_flags = UniAtaAhciAdjustIoFlags(regs->bCommandReg, ahci_flags, fis_size, DeviceNumber);
1724  KdPrint2(("ahci_flags %#x\n", ahci_flags));
1725 
1726  if(Srb->DataTransferLength) {
1727  if(!AtapiDmaSetup(HwDeviceExtension,
1728  DeviceNumber,
1729  lChannel, // logical channel,
1730  Srb,
1731  (PUCHAR)(Srb->DataBuffer),
1732  Srb->DataTransferLength)) {
1733  KdPrint2((" can't setup buffer\n"));
1734  return IDE_STATUS_WRONG;
1735  }
1736  }
1737 
1738  AtaReq->ahci.io_cmd_flags = ahci_flags;
1739 
1740 #ifdef _DEBUG
1741  //UniataDumpAhciPortRegs(chan);
1742 #endif // _DEBUG
1743 
1744  UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
1745 
1746 #ifdef _DEBUG
1747  //UniataDumpAhciPortRegs(chan);
1748 #endif // _DEBUG
1749 
1750  if(wait_flags == ATA_IMMEDIATE) {
1751  statusByte = 0;
1752  KdPrint2((" return imemdiately\n"));
1753  } else {
1754  statusByte = UniataAhciWaitCommandReady(chan, timeout);
1755  UniataAhciStatus(HwDeviceExtension, lChannel, DeviceNumber);
1756  UniataAhciEndTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
1757  }
1758 
1759  return statusByte;
1760 
1761 } // end UniataAhciSendPIOCommandDirect()
1762 
1763 BOOLEAN
1764 NTAPI
1766  IN PHW_CHANNEL chan
1767  )
1768 {
1769  /* kick controller into sane state */
1770  if(!UniataAhciStop(chan)) {
1771  return FALSE;
1772  }
1773  if(!UniataAhciStopFR(chan)) {
1774  return FALSE;
1775  }
1776  if(!UniataAhciCLO(chan)) {
1777  return FALSE;
1778  }
1779  UniataAhciStartFR(chan);
1780  UniataAhciStart(chan);
1781 
1782  return TRUE;
1783 } // end UniataAhciAbortOperation()
1784 
1785 ULONG
1786 NTAPI
1788  IN PVOID HwDeviceExtension,
1789  IN ULONG lChannel,
1791  )
1792 {
1793  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1794  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1795  //ULONG Channel = deviceExtension->Channel + lChannel;
1796  //ULONG hIS;
1797  //ULONG CI;
1798  //AHCI_IS_REG IS;
1799  //ULONG tag=0;
1800 
1801  KdPrint(("UniataAhciSoftReset: lChan %d\n", chan->lChannel));
1802 
1803  PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
1804  PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
1805 
1806  /* kick controller into sane state */
1807  if(!UniataAhciAbortOperation(chan)) {
1808  KdPrint2((" abort failed\n"));
1809  return (ULONG)(-1);
1810  }
1811 
1812  /* pull reset active */
1813  RtlZeroMemory(AHCI_CMD->cfis, sizeof(AHCI_CMD->cfis));
1814  AHCI_CMD->cfis[0] = AHCI_FIS_TYPE_ATA_H2D;
1815  AHCI_CMD->cfis[1] = (UCHAR)DeviceNumber & 0x0f;
1816  //AHCI_CMD->cfis[7] = IDE_USE_LBA | IDE_DRIVE_SELECT;
1817  AHCI_CMD->cfis[15] = (IDE_DC_A_4BIT | IDE_DC_RESET_CONTROLLER);
1818 
1819  if(UniataAhciSendCommand(HwDeviceExtension, lChannel, DeviceNumber, ATA_AHCI_CMD_RESET | ATA_AHCI_CMD_CLR_BUSY, 100) == IDE_STATUS_WRONG) {
1820  KdPrint2((" timeout\n"));
1821  return (ULONG)(-1);
1822  }
1823  AtapiStallExecution(50);
1824 
1825  /* pull reset inactive */
1826  RtlZeroMemory(AHCI_CMD->cfis, sizeof(AHCI_CMD->cfis));
1827  AHCI_CMD->cfis[0] = AHCI_FIS_TYPE_ATA_H2D;
1828  AHCI_CMD->cfis[1] = (UCHAR)DeviceNumber & 0x0f;
1829  //AHCI_CMD->cfis[7] = IDE_USE_LBA | IDE_DRIVE_SELECT;
1830  AHCI_CMD->cfis[15] = (IDE_DC_A_4BIT);
1831  if(UniataAhciSendCommand(HwDeviceExtension, lChannel, DeviceNumber, 0, 3000) == IDE_STATUS_WRONG) {
1832  KdPrint2((" timeout (2)\n"));
1833  return (ULONG)(-1);
1834  }
1835 
1836  UniataAhciWaitReady(chan, 1);
1837 
1838  KdDump(RCV_FIS, sizeof(chan->AhciCtlBlock->rcv_fis.rfis));
1839 
1840  if(deviceExtension->HwFlags & UNIATA_AHCI_ALT_SIG) {
1841  ULONG signature;
1842  signature = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_SIG);
1843  KdPrint((" alt sig: %#x\n", signature));
1844  return signature;
1845  }
1846 
1847  return UniataAhciUlongFromRFIS(RCV_FIS);
1848 
1849 } // end UniataAhciSoftReset()
1850 
1851 ULONG
1852 NTAPI
1854  IN PHW_CHANNEL chan,
1855  IN ULONG timeout
1856  )
1857 {
1858  ULONG TFD;
1859  ULONG i;
1860 
1861  KdPrint2(("UniataAhciWaitReady: lChan %d\n", chan->lChannel));
1862 
1863  //base = (ULONGIO_PTR)(&deviceExtension->BaseIoAHCI_0 + offs);
1864 
1866  for(i=0; i<timeout && (TFD &
1867  (IDE_STATUS_DRQ | IDE_STATUS_BUSY)); i++) {
1868  AtapiStallExecution(1000);
1870  }
1871 
1872  KdPrint2((" TFD %#x\n", TFD));
1873 
1874  return TFD;
1875 
1876 } // end UniataAhciWaitReady()
1877 
1878 ULONG
1879 NTAPI
1881  IN PVOID HwDeviceExtension,
1882  IN ULONG lChannel,
1883  OUT PULONG signature
1884  )
1885 {
1886  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1887  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1888  //ULONG Channel = deviceExtension->Channel + lChannel;
1889  ULONG TFD;
1890 
1891 
1892  KdPrint(("UniataAhciHardReset: lChan %d\n", chan->lChannel));
1893 
1894  (*signature) = 0xffffffff;
1895 
1896  UniataAhciStop(chan);
1897  if(UniataSataPhyEnable(HwDeviceExtension, lChannel, 0/* dev0*/, UNIATA_SATA_RESET_ENABLE) == IDE_STATUS_WRONG) {
1898  KdPrint((" no PHY\n"));
1899  return IDE_STATUS_WRONG;
1900  }
1901 
1902  /* Wait for clearing busy status. */
1903  TFD = UniataAhciWaitReady(chan, 15000);
1904  if(TFD & (IDE_STATUS_DRQ | IDE_STATUS_BUSY)) {
1905  KdPrint((" busy: TFD %#x\n", TFD));
1906  return TFD;
1907  }
1908  KdPrint((" TFD %#x\n", TFD));
1909 
1910 #ifdef _DEBUG
1911  UniataDumpAhciPortRegs(chan);
1912 #endif // _DEBUG
1913 
1914  (*signature) = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_SIG);
1915  KdPrint((" sig: %#x\n", *signature));
1916 
1917  UniataAhciStart(chan);
1918 
1919  return 0;
1920 
1921 } // end UniataAhciHardReset()
1922 
1923 VOID
1924 NTAPI
1926  IN PVOID HwDeviceExtension,
1927  IN ULONG lChannel
1928  )
1929 {
1930  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1931  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1932  //ULONG Channel = deviceExtension->Channel + lChannel;
1933  //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
1934  ULONG CAP;
1935  //ULONGIO_PTR base;
1936  ULONG signature;
1937  ULONG i;
1938  ULONG VendorID = deviceExtension->DevID & 0xffff;
1939 
1940  KdPrint(("UniataAhciReset: lChan %d\n", chan->lChannel));
1941 
1942  //base = (ULONGIO_PTR)(&deviceExtension->BaseIoAHCI_0 + offs);
1943 
1944  /* Disable port interrupts */
1946 
1947  if(UniataAhciHardReset(HwDeviceExtension, lChannel, &signature)) {
1948 
1949  KdPrint((" No devices in all LUNs\n"));
1950  for (i=0; i<deviceExtension->NumberLuns; i++) {
1951  // Zero device fields to ensure that if earlier devices were found,
1952  // but not claimed, the fields are cleared.
1953  UniataForgetDevice(chan->lun[i]);
1954  }
1955 
1956  /* enable wanted port interrupts */
1959  return;
1960  }
1961 
1962  /* enable wanted port interrupts */
1966  ((/*ch->pm_level == */0) ? (ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC) : 0) |
1969 
1970  /*
1971  * Only probe for PortMultiplier if HW has support.
1972  * Ignore Marvell, which is not working,
1973  */
1974  CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
1975  if ((CAP & AHCI_CAP_SPM) &&
1976  (VendorID != ATA_MARVELL_ID)) {
1977  KdPrint((" check PM\n"));
1978  signature = UniataAhciSoftReset(HwDeviceExtension, lChannel, AHCI_DEV_SEL_PM);
1979  /* Workaround for some ATI chips, failing to soft-reset
1980  * when port multiplicator supported, but absent.
1981  * XXX: We can also check PxIS.IPMS==1 here to be sure. */
1982  if (signature == 0xffffffff) {
1983  KdPrint((" re-check PM\n"));
1984  signature = UniataAhciSoftReset(HwDeviceExtension, lChannel, 0);
1985  }
1986  } else {
1987  signature = UniataAhciSoftReset(HwDeviceExtension, lChannel, 0);
1988  }
1989 
1990  KdPrint((" signature %#x\n", signature));
1991  chan->lun[0]->DeviceFlags &= ~(DFLAGS_ATAPI_DEVICE | DFLAGS_DEVICE_PRESENT | CTRFLAGS_AHCI_PM);
1992  switch (signature >> 16) {
1993  case 0x0000:
1994  KdPrint((" ATA dev\n"));
1995  chan->lun[0]->DeviceFlags |= DFLAGS_DEVICE_PRESENT;
1996  chan->PmLunMap = 0;
1997  break;
1998  case 0x9669:
1999  KdPrint((" PM\n"));
2000  if(deviceExtension->NumberLuns > 1) {
2002  UniataSataIdentifyPM(chan);
2003  } else {
2004  KdPrint((" no PM supported (1 lun/chan)\n"));
2005  }
2006  break;
2007  case 0xeb14:
2008  KdPrint((" ATAPI dev\n"));
2009  chan->lun[0]->DeviceFlags |= (DFLAGS_ATAPI_DEVICE | DFLAGS_DEVICE_PRESENT);
2010  chan->PmLunMap = 0;
2011  break;
2012  default: /* SOS XXX */
2013  KdPrint((" default to ATA ???\n"));
2014  chan->lun[0]->DeviceFlags |= DFLAGS_DEVICE_PRESENT;
2015  chan->PmLunMap = 0;
2016  }
2017 
2018  return;
2019 
2020 } // end UniataAhciReset()
2021 
2022 VOID
2023 NTAPI
2025  IN PHW_CHANNEL chan
2026  )
2027 {
2028  ULONG CMD;
2029 
2030  KdPrint2(("UniataAhciStartFR: lChan %d\n", chan->lChannel));
2031 
2033  KdPrint2((" CMD %#x\n", CMD));
2035  UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2036 
2037  return;
2038 } // end UniataAhciStartFR()
2039 
2040 BOOLEAN
2041 NTAPI
2043  IN PHW_CHANNEL chan
2044  )
2045 {
2046  ULONG CMD;
2047  ULONG i;
2048 
2049  KdPrint2(("UniataAhciStopFR: lChan %d\n", chan->lChannel));
2050 
2052  KdPrint2((" CMD %#x\n", CMD));
2054 
2055  for(i=0; i<1000; i++) {
2057  if(!(CMD & ATA_AHCI_P_CMD_FR)) {
2058  KdPrint2((" final CMD %#x\n", CMD));
2059  return TRUE;
2060  }
2061  AtapiStallExecution(1000);
2062  }
2063  KdPrint2((" CMD %#x\n", CMD));
2064  KdPrint((" SError %#x\n", AtapiReadPort4(chan, IDX_SATA_SError)));
2065  KdPrint2(("UniataAhciStopFR: timeout\n"));
2066  return FALSE;
2067 } // end UniataAhciStopFR()
2068 
2069 VOID
2070 NTAPI
2072  IN PHW_CHANNEL chan
2073  )
2074 {
2075  ULONG IS, CMD;
2077 
2078  KdPrint2(("UniataAhciStart: lChan %d\n", chan->lChannel));
2079 
2080  /* clear SATA error register */
2081  SError.Reg = AtapiReadPort4(chan, IDX_SATA_SError);
2082 
2083  /* clear any interrupts pending on this channel */
2086 
2087  KdPrint2((" SError %#x, IS %#x\n", SError.Reg, IS));
2088 
2090  KdPrint2((" CMD %#x\n", CMD));
2092  CMD |
2094  ((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM) ? ATA_AHCI_P_CMD_PMA : 0));
2095  UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2096 
2097  return;
2098 } // end UniataAhciStart()
2099 
2100 BOOLEAN
2101 NTAPI
2103  IN PHW_CHANNEL chan
2104  )
2105 {
2106  //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2107  //PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
2108  ULONG CAP, CMD;
2109  //SATA_SERROR_REG SError;
2110  ULONG i;
2111 
2112  KdPrint2(("UniataAhciCLO: lChan %d\n", chan->lChannel));
2113 
2114  /* issue Command List Override if supported */
2115  //CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
2116  CAP = chan->DeviceExtension->AHCI_CAP;
2117  if(!(CAP & AHCI_CAP_SCLO)) {
2118  return TRUE;
2119  }
2120  KdPrint2((" send CLO\n"));
2124 
2125  for(i=0; i<1000; i++) {
2127  if(!(CMD & ATA_AHCI_P_CMD_CLO)) {
2128  KdPrint2((" final CMD %#x\n", CMD));
2129  return TRUE;
2130  }
2131  AtapiStallExecution(1000);
2132  }
2133  KdPrint2((" CMD %#x\n", CMD));
2134  KdPrint2(("UniataAhciCLO: timeout\n"));
2135  return FALSE;
2136 } // end UniataAhciCLO()
2137 
2138 BOOLEAN
2139 NTAPI
2141  IN PHW_CHANNEL chan
2142  )
2143 {
2144  ULONG CMD;
2145  //SATA_SERROR_REG SError;
2146  ULONG i;
2147 
2148  KdPrint2(("UniataAhciStop: lChan %d\n", chan->lChannel));
2149 
2150  /* issue Command List Override if supported */
2152  CMD &= ~ATA_AHCI_P_CMD_ST;
2154 
2155  for(i=0; i<1000; i++) {
2157  if(!(CMD & ATA_AHCI_P_CMD_CR)) {
2158  KdPrint2((" final CMD %#x\n", CMD));
2159  return TRUE;
2160  }
2161  AtapiStallExecution(1000);
2162  }
2163  KdPrint2((" CMD %#x\n", CMD));
2164  KdPrint((" SError %#x\n", AtapiReadPort4(chan, IDX_SATA_SError)));
2165  KdPrint2(("UniataAhciStop: timeout\n"));
2166  return FALSE;
2167 } // end UniataAhciStop()
2168 
2169 UCHAR
2170 NTAPI
2172  IN PVOID HwDeviceExtension,
2173  IN ULONG lChannel,
2176  )
2177 {
2178  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2179  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
2180  //ULONG Channel = deviceExtension->Channel + lChannel;
2181  //ULONG hIS;
2182  ULONG CMD, CMD0;
2183  //AHCI_IS_REG IS;
2184  PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
2185  //SATA_SSTATUS_REG SStatus;
2186  //SATA_SERROR_REG SError;
2187  //ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
2188  //ULONGIO_PTR base;
2189  ULONG tag=0;
2190  //ULONG i;
2191 
2192  PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
2193 
2194  KdPrint2(("UniataAhciBeginTransaction: lChan %d, AtaReq %#x\n", chan->lChannel, AtaReq));
2195 
2196  if(Srb->DataTransferLength && (!AtaReq->dma_entries || AtaReq->dma_entries >= (USHORT)0xffff)) {
2197  KdPrint2(("UniataAhciBeginTransaction wrong DMA tab len %x\n", AtaReq->dma_entries));
2198  return 0;
2199  }
2200 
2201  AHCI_CL->prd_length = (USHORT)(AtaReq->dma_entries);
2202  AHCI_CL->cmd_flags = AtaReq->ahci.io_cmd_flags;
2203  AHCI_CL->bytecount = 0;
2204  if(AtaReq->ahci.ahci_base64) {
2205  KdPrint2((PRINT_PREFIX " AHCI AtaReq CMD %#x (ph %#x)\n", AtaReq->ahci.ahci_cmd_ptr, (ULONG)(AtaReq->ahci.ahci_base64)));
2206  AHCI_CL->cmd_table_phys = AtaReq->ahci.ahci_base64;
2207  } else
2208  if(AtaReq->ahci.ahci_cmd_ptr) {
2209  KdPrint2((PRINT_PREFIX " AHCI AtaReq->Chan CMD %#x (ph %#x) -> %#x (ph %#x)\n",
2210  AtaReq->ahci.ahci_cmd_ptr, (ULONG)(AtaReq->ahci.ahci_base64),
2212  RtlCopyMemory(&(chan->AhciCtlBlock->cmd), AtaReq->ahci.ahci_cmd_ptr,
2213  FIELD_OFFSET(IDE_AHCI_CMD, prd_tab)+AHCI_CL->prd_length*sizeof(IDE_AHCI_PRD_ENTRY));
2215  } else {
2216  KdPrint2((PRINT_PREFIX " no AHCI CMD\n"));
2217  //AHCI_CL->cmd_table_phys = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, cmd);
2218  return 0;
2219  }
2220  if(AHCI_CL->cmd_table_phys & AHCI_CMD_ALIGNEMENT_MASK) {
2221  KdPrint2((PRINT_PREFIX " AHCI CMD address is not aligned (mask %#x)\n", (ULONG)AHCI_CMD_ALIGNEMENT_MASK));
2222  return 0;
2223  }
2224 
2225 #ifdef _DEBUG
2226  KdPrint2((" prd_length %#x, flags %#x, base %I64x\n", AHCI_CL->prd_length, AHCI_CL->cmd_flags,
2227  AHCI_CL->cmd_table_phys));
2228 #endif // _DEBUG
2229 
2231  KdPrint2((" CMD %#x\n", CMD));
2232  // switch controller to ATAPI mode for ATA_PACKET commands only
2233  if(ATAPI_DEVICE(chan, DeviceNumber) &&
2234  AtaReq->ahci.ahci_cmd_ptr->cfis[2] == IDE_COMMAND_ATAPI_PACKET) {
2235  KdPrint2((" ATAPI\n"));
2237  KdDump(&(AtaReq->ahci.ahci_cmd_ptr->acmd), 16);
2238  } else {
2240  }
2241  if(CMD0 != CMD) {
2242  KdPrint2((" send CMD %#x, entries %#x\n", CMD, AHCI_CL->prd_length));
2244  CMD0 = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2245  }
2246 
2247  /* issue command to controller */
2248  //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag); // Used for NCQ
2249  KdPrint2((" Set CI\n"));
2251  chan->AhciPrevCI |= 0x01 << tag;
2252 
2253  //CMD0 = CMD;
2254  CMD |= ATA_AHCI_P_CMD_ST |
2256  if(CMD != CMD0) {
2257  KdPrint2((" Send CMD START (%#x != %#x)\n", CMD, CMD0));
2259  CMD0 = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2260  } else {
2261  KdPrint2((" No CMD START, already active\n"));
2262  }
2263 
2264  if(!ATAPI_DEVICE(chan, DeviceNumber)) {
2265  // TODO: check if we send ATAPI_RESET and wait for ready of so.
2266  if(AtaReq->ahci.ahci_cmd_ptr->cfis[2] == IDE_COMMAND_ATAPI_RESET) {
2267  ULONG TFD;
2268  ULONG i;
2269 
2270  for(i=0; i<1000000; i++) {
2272  if(!(TFD & IDE_STATUS_BUSY)) {
2273  break;
2274  }
2275  }
2276  if(TFD & IDE_STATUS_BUSY) {
2277  KdPrint2((" timeout\n"));
2278  }
2279  if(TFD & IDE_STATUS_ERROR) {
2280  KdPrint2((" ERROR %#x\n", (UCHAR)(TFD >> 8)));
2281  }
2282  AtaReq->ahci.in_status = TFD;
2283 
2284  return IDE_STATUS_SUCCESS;
2285  }
2286  }
2287 
2288  return IDE_STATUS_IDLE;
2289 
2290 } // end UniataAhciBeginTransaction()
2291 
2292 UCHAR
2293 NTAPI
2295  IN PVOID HwDeviceExtension,
2296  IN ULONG lChannel,
2299  )
2300 {
2301  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2302  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
2303  //ULONG Channel = deviceExtension->Channel + lChannel;
2304  //ULONG hIS;
2305  ULONG CI, ACT;
2306  PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
2307  ULONG TFD;
2308  PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
2309  ULONG tag=0;
2310  //ULONG i;
2311  PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
2312  //PHW_LU_EXTENSION LunExt;
2313 
2314  KdPrint2(("UniataAhciEndTransaction: lChan %d\n", chan->lChannel));
2315 
2316  //LunExt = chan->lun[DeviceNumber];
2317 
2319  KdPrint2((" TFD %#x\n", TFD));
2320 
2321  if(TFD & IDE_STATUS_ERROR) {
2322  AtaReq->ahci.in_error = (UCHAR)(TFD >> 8);
2323  KdPrint2((" ERROR %#x\n", AtaReq->ahci.in_error));
2324  } else {
2325  AtaReq->ahci.in_error = 0;
2326  }
2327  AtaReq->ahci.in_status = TFD;
2328 
2329  //if (request->flags & ATA_R_CONTROL) {
2330 
2331  AtaReq->ahci.in_bcount = (ULONG)(RCV_FIS[12]) | ((ULONG)(RCV_FIS[13]) << 8);
2332  AtaReq->ahci.in_lba = (ULONG)(RCV_FIS[4]) | ((ULONGLONG)(RCV_FIS[5]) << 8) |
2333  ((ULONGLONG)(RCV_FIS[6]) << 16);
2334  if(chan->ChannelCtrlFlags & CTRFLAGS_LBA48) {
2335  AtaReq->ahci.in_lba |= ((ULONGLONG)(RCV_FIS[8]) << 24) |
2336  ((ULONGLONG)(RCV_FIS[9]) << 32) |
2337  ((ULONGLONG)(RCV_FIS[10]) << 40);
2338  } else {
2339  AtaReq->ahci.in_lba |= ((ULONGLONG)(RCV_FIS[8]) << 24) |
2340  ((ULONGLONG)(RCV_FIS[9]) << 32) |
2341  ((ULONGLONG)(RCV_FIS[7] & 0x0f) << 24);
2342  }
2343  AtaReq->WordsTransfered = AHCI_CL->bytecount/2;
2344 
2345 /*
2346  if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
2347  KdPrint2(("RCV:\n"));
2348  KdDump(RCV_FIS, 24);
2349  KdPrint2(("PIO:\n"));
2350  KdDump(&(chan->AhciCtlBlock->rcv_fis.psfis[0]), 24);
2351 
2352  KdPrint2(("len: %d vs %d\n", AHCI_CL->bytecount, (ULONG)RCV_FIS[5] | ((ULONG)RCV_FIS[6] << 8) ));
2353  if(!AHCI_CL->bytecount) {
2354  AtaReq->WordsTransfered = ((ULONG)RCV_FIS[5] | ((ULONG)RCV_FIS[6] << 8)) / 2;
2355  }
2356  }
2357 */
2360  if(CI & (1 << tag)) {
2361  // clear CI
2362  KdPrint2((" Incomplete command, CI %#x, ACT %#x\n", CI, ACT));
2363  KdPrint2((" FIS status %#x, error %#x\n", RCV_FIS[2], RCV_FIS[3]));
2364 
2365 #ifdef _DEBUG
2366  UniataDumpAhciPortRegs(chan);
2367 #endif
2368  if(!UniataAhciAbortOperation(chan)) {
2369  KdPrint2((" Abort failed, need RESET\n"));
2370  }
2371 #ifdef _DEBUG
2372  UniataDumpAhciPortRegs(chan);
2373 #endif
2374  chan->AhciPrevCI = CI & ~((ULONG)1 << tag);
2375  if(chan->AhciPrevCI) {
2376  KdPrint2((" Need command list restart, CI %#x\n", chan->AhciPrevCI));
2377  }
2378  } else {
2379  chan->AhciPrevCI &= ~((ULONG)1 << tag);
2380  RtlZeroMemory(AHCI_CL, sizeof(IDE_AHCI_CMD_LIST));
2381  }
2382  //}
2383 
2384  return 0;
2385 
2386 } // end UniataAhciEndTransaction()
2387 
2388 VOID
2389 NTAPI
2391  IN PHW_CHANNEL chan
2392  )
2393 {
2394  ULONGLONG base;
2395 
2396  KdPrint2(("UniataAhciResume: lChan %d\n", chan->lChannel));
2397 
2398 #ifdef _DEBUG
2399  //UniataDumpAhciPortRegs(chan);
2400 #endif // _DEBUG
2401 
2402  /* Disable port interrupts */
2404 
2405  /* setup work areas */
2406  base = chan->AHCI_CTL_PhAddr;
2407  if(!base) {
2408  KdPrint2((PRINT_PREFIX " AHCI buffer allocation failed\n"));
2409  return;
2410  }
2411  KdPrint2((PRINT_PREFIX " AHCI CLB setup\n"));
2413  KdPrint2((PRINT_PREFIX " AHCI CLB address is not aligned (mask %#x)\n", (ULONG)AHCI_FIS_ALIGNEMENT_MASK));
2414  }
2416  (ULONG)(base & 0xffffffff));
2418  (ULONG)((base >> 32) & 0xffffffff));
2419 
2420  KdPrint2((PRINT_PREFIX " AHCI RCV FIS setup\n"));
2421  base = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, rcv_fis);
2423  KdPrint2((PRINT_PREFIX " AHCI FIS address is not aligned (mask %#x)\n", (ULONG)AHCI_FIS_ALIGNEMENT_MASK));
2424  }
2426  (ULONG)(base & 0xffffffff));
2428  (ULONG)((base >> 32) & 0xffffffff));
2429 
2430  /* activate the channel and power/spin up device */
2433  (((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM)) ? ATA_AHCI_P_CMD_ALPE : 0) |
2434  (((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM2)) ? ATA_AHCI_P_CMD_ASP : 0 ))
2435  );
2436  UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2437 
2438 #ifdef _DEBUG
2439  //UniataDumpAhciPortRegs(chan);
2440 #endif // _DEBUG
2441 
2442  UniataAhciStartFR(chan);
2443  UniataAhciStart(chan);
2444 
2445 #ifdef _DEBUG
2446  UniataDumpAhciPortRegs(chan);
2447 #endif // _DEBUG
2448 
2449  return;
2450 } // end UniataAhciResume()
2451 
2452 #if 0
2453 VOID
2454 NTAPI
2455 UniataAhciSuspend(
2456  IN PHW_CHANNEL chan
2457  )
2458 {
2459  ULONGLONG base;
2460  SATA_SCONTROL_REG SControl;
2461 
2462  KdPrint2(("UniataAhciSuspend:\n"));
2463 
2464  /* Disable port interrupts */
2466 
2467  /* Reset command register. */
2468  UniataAhciStop(chan);
2469  UniataAhciStopFR(chan);
2471  UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
2472 
2473  /* Allow everything including partial and slumber modes. */
2475 
2476  /* Request slumber mode transition and give some time to get there. */
2478  AtapiStallExecution(100);
2479 
2480  /* Disable PHY. */
2481  SControl.Reg = 0;
2482  SControl.DET = SStatus_DET_Offline;
2483  UniataSataWritePort4(chan, IDX_SATA_SControl, SControl.Reg, 0);
2484 
2485  return;
2486 } // end UniataAhciSuspend()
2487 #endif
2488 
2489 BOOLEAN
2490 NTAPI
2492  IN PHW_CHANNEL chan,
2494  IN ULONG Reg,
2495  OUT PULONG result
2496  )
2497 {
2498  //ULONG Channel = deviceExtension->Channel + lChannel;
2499  //ULONG hIS;
2500  //ULONG CI;
2501  //AHCI_IS_REG IS;
2502  //ULONG tag=0;
2503  PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
2504  PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
2505 
2506  KdPrint(("UniataAhciReadPM: lChan %d [%#x]\n", chan->lChannel, DeviceNumber));
2507 
2509  (*result) = UniataSataReadPort4(chan, Reg, 0);
2510  return TRUE;
2511  }
2513  switch(Reg) {
2514  case IDX_SATA_SStatus:
2515  Reg = 0; break;
2516  case IDX_SATA_SError:
2517  Reg = 1; break;
2518  case IDX_SATA_SControl:
2519  Reg = 2; break;
2520  default:
2521  return FALSE;
2522  }
2523  }
2524 
2525  RtlZeroMemory(AHCI_CMD->cfis, sizeof(AHCI_CMD->cfis));
2526  AHCI_CMD->cfis[0] = AHCI_FIS_TYPE_ATA_H2D;
2527  AHCI_CMD->cfis[1] = AHCI_FIS_COMM_PM;
2528  AHCI_CMD->cfis[2] = IDE_COMMAND_READ_PM;
2529  AHCI_CMD->cfis[3] = (UCHAR)Reg;
2530  AHCI_CMD->cfis[7] = (UCHAR)(IDE_USE_LBA | DeviceNumber);
2531  AHCI_CMD->cfis[15] = IDE_DC_A_4BIT;
2532 
2533  if(UniataAhciSendCommand(chan->DeviceExtension, chan->lChannel, DeviceNumber, 0, 10) == IDE_STATUS_WRONG) {
2534  KdPrint2((" PM read failed\n"));
2535  return FALSE;
2536  }
2537 
2538  KdDump(RCV_FIS, sizeof(chan->AhciCtlBlock->rcv_fis.rfis));
2539 
2540  (*result) = UniataAhciUlongFromRFIS(RCV_FIS);
2541  return TRUE;
2542 
2543 } // end UniataAhciReadPM()
2544 
2545 UCHAR
2546 NTAPI
2548  IN PHW_CHANNEL chan,
2550  IN ULONG Reg,
2551  IN ULONG value
2552  )
2553 {
2554  //ULONG Channel = deviceExtension->Channel + lChannel;
2555  //ULONG hIS;
2556  //ULONG CI;
2557  //AHCI_IS_REG IS;
2558  //ULONG tag=0;
2559  ULONG TFD;
2560  PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
2561  //PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
2562 
2563  KdPrint(("UniataAhciWritePM: lChan %d [%#x] %#x\n", chan->lChannel, DeviceNumber, value));
2564 
2566  UniataSataWritePort4(chan, Reg, value, 0);
2567  return 0;
2568  }
2570  switch(Reg) {
2571  case IDX_SATA_SStatus:
2572  Reg = 0; break;
2573  case IDX_SATA_SError:
2574  Reg = 1; break;
2575  case IDX_SATA_SControl:
2576  Reg = 2; break;
2577  default:
2578  return IDE_STATUS_WRONG;
2579  }
2580  }
2581 
2582  RtlZeroMemory(AHCI_CMD->cfis, sizeof(AHCI_CMD->cfis));
2583  AHCI_CMD->cfis[0] = AHCI_FIS_TYPE_ATA_H2D;
2584  AHCI_CMD->cfis[1] = AHCI_FIS_COMM_PM;
2585  AHCI_CMD->cfis[2] = IDE_COMMAND_WRITE_PM;
2586  AHCI_CMD->cfis[3] = (UCHAR)Reg;
2587  AHCI_CMD->cfis[7] = (UCHAR)(IDE_USE_LBA | DeviceNumber);
2588 
2589  AHCI_CMD->cfis[12] = (UCHAR)(value & 0xff);
2590  AHCI_CMD->cfis[4] = (UCHAR)((value >> 8) & 0xff);
2591  AHCI_CMD->cfis[5] = (UCHAR)((value >> 16) & 0xff);
2592  AHCI_CMD->cfis[6] = (UCHAR)((value >> 24) & 0xff);
2593 
2594  AHCI_CMD->cfis[15] = IDE_DC_A_4BIT;
2595 
2596  if(UniataAhciSendCommand(chan->DeviceExtension, chan->lChannel, DeviceNumber, 0, 100) == IDE_STATUS_WRONG) {
2597  KdPrint2((" PM write failed\n"));
2598  return IDE_STATUS_WRONG;
2599  }
2600 
2602 
2603  if(TFD & IDE_STATUS_ERROR) {
2604  KdPrint2((" ERROR %#x\n", (UCHAR)(TFD >> 8)));
2605  }
2606  return (UCHAR)(TFD >> 8);
2607 
2608 } // end UniataAhciWritePM()
2609 
2610 VOID
2612 IN OUT PATA_REQ AtaReq
2613  )
2614 {
2615  union {
2616  PUCHAR prd_base;
2617  ULONGLONG prd_base64;
2618  };
2619  union {
2620  PUCHAR prd_base0;
2621  ULONGLONG prd_base64_0;
2622  };
2623 #ifdef _DEBUG
2624  ULONG d;
2625 #endif // _DEBUG
2626 
2627  prd_base64_0 = prd_base64 = 0;
2628  prd_base = (PUCHAR)(&AtaReq->ahci_cmd0);
2629  prd_base0 = prd_base;
2630 
2631  prd_base64 = (prd_base64 + max(FIELD_OFFSET(ATA_REQ, ahci_cmd0), AHCI_CMD_ALIGNEMENT_MASK+1)) & ~AHCI_CMD_ALIGNEMENT_MASK;
2632 
2633 #ifdef _DEBUG
2634  d = (ULONG)(prd_base64 - prd_base64_0);
2635  KdPrint2((PRINT_PREFIX " AtaReq %#x: cmd aligned %I64x, d=%x\n", AtaReq, prd_base64, d));
2636 #endif // _DEBUG
2637 
2638  AtaReq->ahci.ahci_cmd_ptr = (PIDE_AHCI_CMD)prd_base64;
2639  KdPrint2((PRINT_PREFIX " ahci_cmd_ptr %#x\n", AtaReq->ahci.ahci_cmd_ptr));
2640 } // end UniataAhciSetupCmdPtr()
2641 
2643 NTAPI
2645  IN PVOID HwDeviceExtension,
2647  IN ULONG lChannel,
2648  IN PUCHAR Buffer,
2649  IN ULONG Length
2650  )
2651 {
2652  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2653  PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
2654  PSCSI_REQUEST_BLOCK srb;
2655 // PCDB cdb;
2656  PATA_REQ AtaReq = chan->AhciInternalAtaReq;
2657 
2658  KdPrint(("BuildAhciInternalSrb: lChan %d [%#x]\n", lChannel, DeviceNumber));
2659 
2660  if(!AtaReq) {
2661  KdPrint2((PRINT_PREFIX " !chan->AhciInternalAtaReq\n"));
2662  return NULL;
2663  }
2664 
2665  //RtlZeroMemory((PCHAR) AtaReq, sizeof(ATA_REQ));
2666  //RtlZeroMemory((PCHAR) AtaReq, FIELD_OFFSET(ATA_REQ, ahci));
2667  UniAtaClearAtaReq(AtaReq);
2668 
2669  srb = chan->AhciInternalSrb;
2670 
2671  RtlZeroMemory((PCHAR) srb, sizeof(SCSI_REQUEST_BLOCK));
2672 
2673  srb->PathId = (UCHAR)lChannel;
2674  srb->TargetId = (UCHAR)DeviceNumber;
2675  srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
2676  srb->Length = sizeof(SCSI_REQUEST_BLOCK);
2677 
2678  // Set flags to disable synchronous negociation.
2679  //srb->SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
2680 
2681  // Set timeout to 4 seconds.
2682  srb->TimeOutValue = 4;
2683 
2684  srb->CdbLength = 6;
2685  srb->DataBuffer = Buffer;
2686  srb->DataTransferLength = Length;
2687  srb->SrbExtension = AtaReq;
2688 
2689  AtaReq->Srb = srb;
2690  AtaReq->DataBuffer = (PUSHORT)Buffer;
2691  AtaReq->TransferLength = Length;
2692 
2693  //if(!AtaReq->ahci.ahci_cmd_ptr) {
2694  //UniataAhciSetupCmdPtr(AtaReq);
2695  //AtaReq->ahci.ahci_cmd_ptr = &(chan->AhciCtlBlock->cmd);
2696  //AtaReq->ahci.ahci_base64 = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, cmd);
2697  //}
2698  //AtaReq->ahci.ahci_cmd_ptr = &(AtaReq->ahci_cmd0);
2699  //AtaReq->ahci.ahci_base64 = NULL; // indicate that we should copy command to proper place
2700 
2701  KdPrint2((PRINT_PREFIX " Srb %#x, AtaReq %#x, CMD %#x ph %I64x\n", srb, AtaReq,
2702  AtaReq->ahci.ahci_cmd_ptr, AtaReq->ahci.ahci_base64));
2703 
2704 /* // Set CDB operation code.
2705  cdb = (PCDB)srb->Cdb;
2706  cdb->CDB6INQUIRY.OperationCode = SCSIOP_REQUEST_SENSE;
2707  cdb->CDB6INQUIRY.AllocationLength = sizeof(SENSE_DATA);
2708 */
2709  return srb;
2710 } // end BuildAhciInternalSrb()
2711 
IORES BaseIoAHCI_Port
Definition: bsmaster.h:1105
BOOLEAN NTAPI UniataAhciStopFR(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:2042
#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:1144
#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:2547
#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:2102
#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:1143
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:1139
ULONG NTAPI UniataAhciSetupFIS_H2D(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, OUT PUCHAR fis, IN UCHAR command, IN ULONGLONG lba, IN USHORT count, IN USHORT feature)
Definition: id_sata.cpp:1241
BOOLEAN NTAPI UniataAhciDetect(IN PVOID HwDeviceExtension, IN PPCI_COMMON_CONFIG pciData, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo)
Definition: id_sata.cpp:890
#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:1131
ULONG ChannelCtrlFlags
Definition: bsmaster.h:1059
#define AHCI_CAP_SNTF
Definition: bsmaster.h:208
ULONG MaxTransferMode
Definition: bsmaster.h:1057
#define ATA_AHCI_P_CMD_SLUMBER
Definition: bsmaster.h:721
#define DMA_MODE_AHCI
Definition: bsmaster.h:1708
#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:2390
#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:1257
VOID NTAPI UniataAhciStart(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:2071
#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:1108
#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:2024
#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:1787
#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:1880
#define ATA_AHCI_P_IX_DP
Definition: bsmaster.h:504
#define IDE_DC_USE_HOB
Definition: atapi.h:455
ULONG AhciCompleteCI
Definition: bsmaster.h:1107
__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:1013
#define IDX_AHCI_P_SError
Definition: bsmaster.h:692
#define CTRFLAGS_LBA48
Definition: bsmaster.h:1137
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
#define IDX_AHCI_P_FB
Definition: bsmaster.h:683
PIDE_AHCI_CHANNEL_CTL_BLOCK AhciCtlBlock
Definition: bsmaster.h:1103
#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
struct _ATA_REQ::@1109::@1111::@1115::@1118 ahci
__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:1434
GLuint base
Definition: 3dtext.c:35
PSCSI_REQUEST_BLOCK AhciInternalSrb
Definition: bsmaster.h:1114
#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:1765
#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:2294
#define SStatus_SPD_Gen1
Definition: bsmaster.h:292
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:1925
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:1109
#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:2644
#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:1104
#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:1688
UCHAR NTAPI UniataAhciSendCommand(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN USHORT ahci_flags, IN ULONG timeout)
Definition: id_sata.cpp:1496
#define AHCI_CAP_ISS_MASK
Definition: bsmaster.h:206
#define GetPciConfig4(offs, op)
Definition: bsmaster.h:1678
#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:2171
#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:1853
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
#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:1320
#define UNIATA_AHCI
Definition: bm_devs_decl.h:630
IORES RegTranslation[IDX_MAX_REG]
Definition: bsmaster.h:1127
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:1216
#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:2491
#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:2611
#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:1655
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:1064
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:1341
int command(const char *fmt,...)
Definition: ftp.c:266
PATA_REQ AhciInternalAtaReq
Definition: bsmaster.h:1113
#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:2140
#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:1106
#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:860
#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
struct @4020 regs[]
#define SControl_DET_DoNothing
Definition: bsmaster.h:331
struct _IDE_AHCI_PORT_REGISTERS::@1070::@1090::@1092 STS
#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:1088
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:1091
UCHAR NTAPI UniataAhciSendPIOCommand(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb, IN PUCHAR data, IN ULONG length, IN UCHAR command, IN ULONGLONG lba, IN USHORT bcount, IN USHORT feature, IN USHORT ahci_flags, IN ULONG wait_flags, IN ULONG timeout)
Definition: id_sata.cpp:1538
#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:1009
ULONGLONG cmd_table_phys
Definition: bsmaster.h:827
char * tag
Definition: main.c:59