ReactOS  0.4.13-dev-259-g5ca9c9c
id_probe.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 2002-2016 Alexandr A. Telyatnikov (Alter)
4 
5 Module Name:
6  id_probe.cpp
7 
8 Abstract:
9  This module scans PCI and ISA buses for IDE controllers
10  and determines their Busmaster DMA capabilities
11 
12 Author:
13  Alexander A. Telyatnikov (Alter)
14 
15 Environment:
16  kernel mode only
17 
18 Notes:
19 
20  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 Revision History:
32 
33  Some parts of hardware-specific code were taken from FreeBSD 4.3-6.1 ATA driver by
34  Søren Schmidt, Copyright (c) 1998-2007
35 
36  Some parts of device detection code were taken from from standard ATAPI.SYS from NT4 DDK by
37  Mike Glass (MGlass)
38  Chuck Park (ChuckP)
39 
40  Device search/init algorithm is completly rewritten by
41  Alter, Copyright (c) 2002-2004
42 
43  Fixes for Native/Compatible modes of onboard IDE controller by
44  Vitaliy Vorobyov, deathsoft@yandex.ru (c) 2004
45 
46 Licence:
47  GPLv2
48 
49 --*/
50 
51 #include "stdafx.h"
52 
57 
59 // This is our own resource check,
60 // ReactOS allows to allocate same I/O range for both PCI and ISA controllers
63 
64 #ifndef UNIATA_CORE
65 
68 
70 
71 // local routines
72 
73 ULONG
74 NTAPI
76 /* IN PVOID HwDeviceExtension,
77  IN PVOID Context,
78  IN PVOID BusInformation,
79  IN PCHAR ArgumentString,
80  IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
81  OUT PBOOLEAN Again*/
82  );
83 
84 VOID
85 NTAPI
87 {
88  return;
89 } // end AtapiDoNothing()
90 
91 #endif //UNIATA_CORE
92 
93 USHORT
94 NTAPI
96  IN ULONG busNumber,
97  IN ULONG slotNumber,
98  IN OUT PPCI_COMMON_CONFIG pciData
99  )
100 {
101  ULONG i;
102  ULONG busDataRead;
103  USHORT CmdOrig;
104 
105  // Enable Busmastering, IO-space and Mem-space
106  // Note: write to CONFIG *may* cause controller to interrupt (not handled yet)
107  // even if no bits are updated. Was observed on ICH7
108  KdPrint2((PRINT_PREFIX "Enabling Mem/Io spaces and busmastering...\n"));
109  KdPrint2((PRINT_PREFIX "Initial pciData.Command = %#x\n", pciData->Command));
110  for(i=0; i<3; i++) {
111  CmdOrig = pciData->Command;
112  switch(i) {
113  case 0:
114  KdPrint2((PRINT_PREFIX "PCI_ENABLE_IO_SPACE\n"));
115  pciData->Command |= PCI_ENABLE_IO_SPACE;
116  break;
117  case 1:
118  KdPrint2((PRINT_PREFIX "PCI_ENABLE_MEMORY_SPACE\n"));
119  pciData->Command |= PCI_ENABLE_MEMORY_SPACE;
120  break;
121  case 2:
122  KdPrint2((PRINT_PREFIX "PCI_ENABLE_BUS_MASTER\n"));
123  pciData->Command |= PCI_ENABLE_BUS_MASTER;
124  break;
125  }
126  if(CmdOrig == pciData->Command) {
127  continue;
128  }
129  HalSetBusDataByOffset( PCIConfiguration, busNumber, slotNumber,
130  &(pciData->Command),
132  sizeof(pciData->Command));
133 
134  // reread config space
135  busDataRead = HalGetBusData(PCIConfiguration, busNumber, slotNumber,
136  pciData, PCI_COMMON_HDR_LENGTH);
137  if(busDataRead < PCI_COMMON_HDR_LENGTH) {
138  KdPrint2((PRINT_PREFIX "HalGetBusData() failed %#x\n", busDataRead));
139  break;
140  }
141  KdPrint2((PRINT_PREFIX "New pciData.Command = %#x\n", pciData->Command));
142  }
143  KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData->u.type0.InterruptLine));
144  KdPrint2((PRINT_PREFIX "Final pciData.Command = %#x\n", pciData->Command));
145  return pciData->Command;
146 } // end UniataEnableIoPCI()
147 
148 /*
149  Get PCI address by ConfigInfo and RID
150 */
152 NTAPI
154  IN PVOID HwDeviceExtension,
156  IN PPCI_COMMON_CONFIG pciData,
157  IN ULONG SystemIoBusNumber,
158  IN ULONG rid, //range id
159  IN ULONG offset,
160  IN ULONG length
161  )
162 {
163  ULONGIO_PTR io_start = 0;
164  KdPrint2((PRINT_PREFIX " AtapiGetIoRange:\n"));
165 
166  if(ConfigInfo->NumberOfAccessRanges <= rid)
167  return 0;
168 
169  KdPrint2((PRINT_PREFIX " AtapiGetIoRange: rid %#x, start %#x, offs %#x, len %#x, mem %#x\n",
170  rid,
171  ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[rid].RangeStart),
172  offset,
173  length,
174  (*ConfigInfo->AccessRanges)[rid].RangeInMemory
175  ));
176 
177  if(!(*ConfigInfo->AccessRanges)[rid].RangeInMemory) {
178  io_start = (pciData->u.type0.BaseAddresses[rid] & ~0x07/*PCI_ADDRESS_IOMASK*/) + offset;
179  // if(pciData->u.type0.BaseAddresses[rid] != 0) ;)
180  if(io_start > offset) {
181  if(/*(WinVer_Id() <= WinVer_NT) &&*/ offset && rid == 4) {
182  // MS atapi.sys does so for BusMaster controllers
183  (*ConfigInfo->AccessRanges)[rid+1].RangeStart =
185  (*ConfigInfo->AccessRanges)[rid+1].RangeLength = length;
186  } else {
187  (*ConfigInfo->AccessRanges)[rid].RangeStart =
189  (*ConfigInfo->AccessRanges)[rid].RangeLength = length;
190  }
191  if((pciData->u.type0.BaseAddresses[rid] & PCI_ADDRESS_IO_SPACE)) {
192  (*ConfigInfo->AccessRanges)[rid].RangeInMemory = FALSE;
193  } else {
194  KdPrint2((PRINT_PREFIX " AtapiGetIoRange: adjust mem 0 -> 1\n"));
195  (*ConfigInfo->AccessRanges)[rid].RangeInMemory = TRUE;
196  }
197  } else {
198  io_start = 0;
199  }
200  }
201 
202  if((*ConfigInfo->AccessRanges)[rid].RangeInMemory) {
203  if(offset) {
204  KdPrint2((PRINT_PREFIX " AtapiGetIoRange: can't map memory range with offset\n"));
205  return 0;
206  }
207  io_start =
208  // Get the system physical address for this IO range.
209  ((ULONG_PTR)ScsiPortGetDeviceBase(HwDeviceExtension,
210  PCIBus /*ConfigInfo->AdapterInterfaceType*/,
211  SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/,
213  (ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[rid].RangeStart) &
214  ~0x07/*PCI_ADDRESS_IOMASK*/) + offset
215  ),
216  length,
217  (BOOLEAN)!(*ConfigInfo->AccessRanges)[rid].RangeInMemory)
218  );
219 
220  KdPrint2((PRINT_PREFIX " AtapiGetIoRange: %#x\n", io_start));
221  // if(io_start > offset) {
222  return io_start;
223  // }
224  }
225 
226  KdPrint2((PRINT_PREFIX " AtapiGetIoRange: (2) %#x\n", io_start));
227  return io_start;
228 
229 } // end AtapiGetIoRange()
230 
231 #ifndef UNIATA_CORE
232 
233 /*
234  Do nothing, but build list of supported IDE controllers
235  It is a hack, ScsiPort architecture assumes, that DriverEntry
236  can support only KNOWN Vendor/Device combinations.
237  Thus, we build list here. Later we pretend that always knew
238  about found devices.
239 
240  We shall initiate ISA device init, but callback will use
241  Hal routines directly in order to scan PCI bus.
242 */
243 VOID
244 NTAPI
248  )
249 {
251 
252 } // end UniataEnumBusMasterController()
253 
254 BOOLEAN
255 NTAPI
257  BOOLEAN known,
258  ULONG RaidFlags,
259  UCHAR SubClass
260  )
261 {
262  if(known) {
263  if((RaidFlags & UNIATA_RAID_CONTROLLER) &&
264  SkipRaids) {
265  KdPrint2((PRINT_PREFIX "Skip RAID\n"));
266  return FALSE;
267  }
268  return TRUE;
269  }
270  KdPrint2((PRINT_PREFIX "unknown\n"));
271 
272  switch(SubClass) {
274  if(SkipRaids) {
275  KdPrint2((PRINT_PREFIX "Skip RAID (2)\n"));
276  return FALSE;
277  }
278  break;
281  break;
283  break;
284  default:
285  KdPrint2((PRINT_PREFIX "Subclass not supported\n"));
286  return FALSE;
287  }
288  return TRUE;
289 } // end UniataCheckPCISubclass()
290 
292 
293 /*
294  Device initializaton callback
295  Builds PCI device list using Hal routines (not ScsiPort wrappers)
296 */
297 ULONG
298 NTAPI
300  )
301 {
302 // PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
303 // PVOID HwDeviceExtension;
304  PHW_DEVICE_EXTENSION deviceExtension = NULL;
305  PCHAR PciDevMap = NULL;
306  PCI_SLOT_NUMBER slotData;
307  PCI_COMMON_CONFIG pciData;
308  ULONG busNumber;
309  ULONG slotNumber;
310  ULONG funcNumber;
311  BOOLEAN no_buses = FALSE;
312  BOOLEAN no_ranges = FALSE;
313  BOOLEAN non_isa = TRUE;
314  ULONG busDataRead;
315 // BOOLEAN SimplexOnly;
316 
317  UCHAR vendorString[5];
318  UCHAR deviceString[5];
319  PUCHAR vendorStrPtr;
320  PUCHAR deviceStrPtr;
321 
322  UCHAR BaseClass; // (ro)
323  UCHAR SubClass; // (ro)
324  ULONG VendorID;
325  ULONG DeviceID;
326  ULONG dev_id;
327 
330 
331  ULONG i;
332  ULONG pass=0;
333 
334  ULONG RaidFlags;
335 
336  BOOLEAN found;
337  BOOLEAN known;
338  BOOLEAN NeedPciAltInit;
339  BOOLEAN NonZeroSubId = 0;
340 
341  UCHAR IrqForCompat = 10;
342 
343  vendorStrPtr = vendorString;
344  deviceStrPtr = deviceString;
345  slotData.u.AsULONG = 0;
346 
347  KdPrint2((PRINT_PREFIX "UniataEnumBusMasterController__: maxPciBus=%d\n", maxPciBus));
348  if(!maxPciBus) {
349  return(SP_RETURN_NOT_FOUND);
350  }
351  /*HwDeviceExtension =*/
353  if(!deviceExtension) {
354  KdPrint2((PRINT_PREFIX "!deviceExtension\n"));
355  return(SP_RETURN_NOT_FOUND);
356  }
357  RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION));
359  if(!PciDevMap) {
360  KdPrint2((PRINT_PREFIX "!PciDevMap\n"));
361  goto exit;
362  }
364 
365  for(pass=0; pass<3; pass++) {
366  KdPrint2((PRINT_PREFIX " pass %d\n", pass));
367  no_buses = FALSE;
368  for(busNumber=0 ;busNumber<maxPciBus && !no_buses; busNumber++) {
369  for(slotNumber=0; slotNumber<PCI_MAX_DEVICES && !no_buses; slotNumber++) {
370  NeedPciAltInit = FALSE;
371  for(funcNumber=0; funcNumber<PCI_MAX_FUNCTION && !no_buses; funcNumber++) {
372 
373  if(pass) {
374  // use cached device presence map from the 1st pass
375  if(PciDevMap[busNumber*PCI_MAX_DEVICES + slotNumber] & (1 << funcNumber)) {
376  // ok
377  } else {
378  continue;
379  }
380  }
381 // KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x\n",busNumber,slotNumber,funcNumber));
382  slotData.u.bits.DeviceNumber = slotNumber;
383  slotData.u.bits.FunctionNumber = funcNumber;
384 
385  busDataRead = HalGetBusData
386  //ScsiPortGetBusData
387  (
388  //HwDeviceExtension,
389  PCIConfiguration, busNumber, slotData.u.AsULONG,
390  &pciData, PCI_COMMON_HDR_LENGTH);
391  // no more buses
392  if(!busDataRead) {
393  no_buses = TRUE; // break all nested bus scan loops and continue with next pass
394  maxPciBus = busNumber;
395  break;
396  }
397  // indicate that system has PCI bus(es)
398  hasPCI = TRUE;
399 
400  // no device in this slot
401  if(busDataRead == 2) {
402  NeedPciAltInit = TRUE;
403  continue;
404  }
405 
406  if(busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
407  NeedPciAltInit = TRUE;
408  continue;
409  }
410 
411  VendorID = pciData.VendorID;
412  DeviceID = pciData.DeviceID;
413  BaseClass = pciData.BaseClass;
414  SubClass = pciData.SubClass;
415  dev_id = VendorID | (DeviceID << 16);
416 
417  SubVendorID = pciData.u.type0.SubVendorID;
418  SubSystemID = pciData.u.type0.SubSystemID;
419 
420  if(SubVendorID && SubSystemID) {
421  NonZeroSubId = 1;
422  }
423 
424  KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X, SubVen/Sys %4.4x/%4.4x\n", dev_id, BaseClass, SubClass, SubVendorID, SubSystemID));
425 
426  // check for (g_opt_VirtualMachine == VM_AUTO) is performed inside each
427  // VM check for debug purposes
428  // Do not optimize :)
429  if((VendorID == 0x80ee && DeviceID == 0xcafe) ||
430  (VendorID == 0x80ee && DeviceID == 0xbeef)) {
431  KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x - VirtualBox Guest Service\n",busNumber,slotNumber,funcNumber));
434  }
435  } else
436  if((VendorID == 0x15ad) ||
437  (SubVendorID == 0x15ad && SubSystemID == 0x1976)) {
438  KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x - VMWare\n",busNumber,slotNumber,funcNumber));
441  }
442  } else
443  if(SubVendorID == 0x1af4 && SubSystemID == 0x1100) {
444  KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x - QEmu\n",busNumber,slotNumber,funcNumber));
447  }
448  } else
449  if(VendorID == 0x1234 && DeviceID == 0x1111) {
450  KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x - Bochs\n",busNumber,slotNumber,funcNumber));
453  }
454 /* } else
455  if(pass>0 && !NonZeroSubId &&
456  VendorID == 0x8086 &&
457  (DeviceID == 0x7010 ||
458  DeviceID == 0x1230)) {
459  KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x - Bochs PIIX emulation\n",busNumber,slotNumber,funcNumber));
460  if(g_opt_VirtualMachine == VM_AUTO) {
461  g_opt_VirtualMachine = VM_BOCHS;
462  }*/
463  }
464 
465  if(BaseClass != PCI_DEV_CLASS_STORAGE) {
466  continue;
467  }
468 
469  KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x\n",busNumber,slotNumber,funcNumber));
470  KdPrint2((PRINT_PREFIX "Storage Class\n"));
471  KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X, ProgIf %2.2X\n", dev_id, BaseClass, SubClass, pciData.ProgIf ));
472  // look for known chipsets
473  found = FALSE;
474  known = FALSE;
475 
476  if(pciData.u.type0.InterruptPin == 14 ||
477  pciData.u.type0.InterruptPin == 15 ||
478  pciData.u.type0.InterruptLine == 14 ||
479  pciData.u.type0.InterruptLine == 15) {
480  KdPrint2((PRINT_PREFIX "(!) InterruptPin = %#x\n", pciData.u.type0.InterruptPin));
481  KdPrint2((PRINT_PREFIX "(!) InterruptLine = %#x\n", pciData.u.type0.InterruptLine));
482  }
483 
484  if(deviceExtension) {
485  deviceExtension->slotNumber = slotData.u.AsULONG;
486  deviceExtension->SystemIoBusNumber = busNumber;
487  deviceExtension->DevID = dev_id;
488  deviceExtension->RevID = pciData.RevisionID;
489  deviceExtension->AdapterInterfaceType = PCIBus;
490  }
491 
492  found = (BOOLEAN)AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Include", 0);
493  if(!found) {
494  KdPrint2((PRINT_PREFIX "No force include, check exclude\n"));
495  found = !AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Exclude", 0);
496  if(!found) {
497  KdPrint2((PRINT_PREFIX "Device excluded\n"));
498  continue;
499  }
500  }
501 
502  //known = UniataChipDetect(HwDeviceExtension, NULL, -1, ConfigInfo, &SimplexOnly);
504 
505  known = (i != BMLIST_TERMINATOR);
506  if(known) {
507  deviceExtension->FullDevName = BusMasterAdapters[i].FullDevName;
508  RaidFlags = BusMasterAdapters[i].RaidFlags;
509  } else {
510  deviceExtension->FullDevName = "Unknown Storage";
511  RaidFlags = 0;
512  }
513  found = UniataCheckPCISubclass(known, RaidFlags, SubClass);
514  if(!found) {
515  KdPrint2((PRINT_PREFIX "Subclass not supported\n"));
516  continue;
517  }
518 
519  switch(dev_id) {
520  /* additional checks for some supported chipsets */
521  case 0xc6931080:
522  if (SubClass != PCI_DEV_SUBCLASS_IDE)
523  found = FALSE;
524  break;
525 
526  /* unknown chipsets, try generic DMA if it seems possible */
527  default:
528  KdPrint2((PRINT_PREFIX "Default device\n"));
529  if(Ata_is_supported_dev(&pciData) ||
530  Ata_is_ahci_dev(&pciData))
531  found = TRUE;
532  break;
533  }
534 
535  if(!found) {
536  continue;
537  }
538 
539  KdPrint2((PRINT_PREFIX "found, pass %d\n", pass));
540 
541  KdPrint2((PRINT_PREFIX "InterruptPin = %#x\n", pciData.u.type0.InterruptPin));
542  KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine));
543 
544  if(!pass && known) {
545  UniataEnableIoPCI(busNumber, slotData.u.AsULONG, &pciData);
546  }
547  // validate Mem/Io ranges
548  no_ranges = TRUE;
549  non_isa = TRUE;
550  for(i=0; i<PCI_TYPE0_ADDRESSES; i++) {
551  if(pciData.u.type0.BaseAddresses[i] & ~0x7) {
552  no_ranges = FALSE;
553  //break;
554  KdPrint2((PRINT_PREFIX "Range %d = %#x\n", i, pciData.u.type0.BaseAddresses[i]));
555  if(i<4) {
556  if(StdIsaPorts[i] == (pciData.u.type0.BaseAddresses[i] & ~0x7)) {
557  non_isa = FALSE;
558  }
559  }
560  }
561  }
562  if(no_ranges) {
563  KdPrint2((PRINT_PREFIX "No PCI Mem/Io ranges found on device, skip it\n"));
564  continue;
565  }
566  if(!non_isa) {
567  KdPrint2((PRINT_PREFIX "standard ISA ranges on PCI, special case ?\n"));
568  }
569 
570  if(pass) {
571  // fill list of detected devices
572  // it'll be used for further init
573  KdPrint2((PRINT_PREFIX "found suitable device\n"));
575 
576  if(pass == 1) {
577  if(!IsMasterDev(&pciData)) {
578  continue;
579  }
580  if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"NativePCIMode", 0)) {
581  KdPrint2((PRINT_PREFIX "try switch to native mode\n"));
582 
583  IrqForCompat = (UCHAR)AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"NativePCIModeIRQ", 0xff);
584  KdPrint2((PRINT_PREFIX "IrqForCompat = %#x\n", IrqForCompat));
585  if((IrqForCompat & 0xffffff00) /*||
586  (IrqForCompat & 0xff) > 31*/ ||
587  (IrqForCompat == 0xff)) {
588  IrqForCompat = 0x0b;
589  KdPrint2((PRINT_PREFIX "default to IRQ 11\n"));
590  }
591 
592  //ChangePciConfig1(0x09, a | PCI_IDE_PROGIF_NATIVE_ALL); // ProgIf
593  pciData.ProgIf |= PCI_IDE_PROGIF_NATIVE_ALL;
594  HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG,
595  &(pciData.ProgIf),
596  offsetof(PCI_COMMON_CONFIG, ProgIf),
597  sizeof(pciData.ProgIf));
598 
599  // reread config space
600  busDataRead = HalGetBusData(PCIConfiguration, busNumber, slotData.u.AsULONG,
601  &pciData, PCI_COMMON_HDR_LENGTH);
602  // check if the device have switched to Native Mode
603  if(IsMasterDev(&pciData)) {
604  KdPrint2((PRINT_PREFIX "Can't switch to native mode\n"));
605  } else {
606  KdPrint2((PRINT_PREFIX "switched to native mode\n"));
607  KdPrint2((PRINT_PREFIX "InterruptPin = %#x\n", pciData.u.type0.InterruptPin));
608  KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine));
609  // check if IRQ is assigned to device
610  if(!(pciData.u.type0.InterruptLine) ||
611  (pciData.u.type0.InterruptLine == 0xff)) {
612  KdPrint2((PRINT_PREFIX "assign interrupt for device\n"));
613  pciData.u.type0.InterruptLine = IrqForCompat;
614  HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG,
615  &(pciData.u.type0.InterruptLine),
616  offsetof(PCI_COMMON_CONFIG, u.type0.InterruptLine),
617  sizeof(pciData.u.type0.InterruptLine));
618  } else {
619  KdPrint2((PRINT_PREFIX "Auto-assigned interrupt line %#x\n",
620  pciData.u.type0.InterruptLine));
621  IrqForCompat = pciData.u.type0.InterruptLine;
622  }
623  KdPrint2((PRINT_PREFIX "reread config space\n"));
624  // reread config space
625  busDataRead = HalGetBusData(PCIConfiguration, busNumber, slotData.u.AsULONG,
626  &pciData, PCI_COMMON_HDR_LENGTH);
627  KdPrint2((PRINT_PREFIX "busDataRead = %#x\n", busDataRead));
628  KdPrint2((PRINT_PREFIX "reread InterruptLine = %#x\n", pciData.u.type0.InterruptLine));
629  // check if we have successfully assigned IRQ to device
630  if((pciData.u.type0.InterruptLine != IrqForCompat) ||
631  (pciData.u.type0.InterruptLine == 0xff) ||
632  !pciData.u.type0.InterruptLine) {
633  KdPrint2((PRINT_PREFIX "can't assign interrupt for device, revert to compat mode\n"));
634  pciData.u.type0.InterruptLine = 0xff;
635  KdPrint2((PRINT_PREFIX "set IntrLine to 0xff\n"));
636  HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG,
637  &(pciData.u.type0.InterruptLine),
638  offsetof(PCI_COMMON_CONFIG, u.type0.InterruptLine),
639  sizeof(pciData.u.type0.InterruptLine));
640  KdPrint2((PRINT_PREFIX "clear PCI_IDE_PROGIF_NATIVE_ALL\n"));
641  pciData.ProgIf &= ~PCI_IDE_PROGIF_NATIVE_ALL;
642  HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG,
643  &(pciData.ProgIf),
644  offsetof(PCI_COMMON_CONFIG, ProgIf),
645  sizeof(pciData.ProgIf));
646  // reread config space
647  KdPrint2((PRINT_PREFIX "reread config space on revert\n"));
648  busDataRead = HalGetBusData(PCIConfiguration, busNumber, slotData.u.AsULONG,
649  &pciData, PCI_COMMON_HDR_LENGTH);
650  } else {
651  KdPrint2((PRINT_PREFIX "Assigned interrupt %#x for device\n", IrqForCompat));
652  KdPrint2((PRINT_PREFIX "continue detection on next round\n"));
653  continue;
654  }
655  }
656  }
657  } else
658  if(pass == 2) {
659  if(IsMasterDev(&pciData)) {
660  continue;
661  }
662  }
663 
664 /* if(known) {
665  RtlCopyMemory(newBMListPtr, (PVOID)&(BusMasterAdapters[i]), sizeof(BUSMASTER_CONTROLLER_INFORMATION));
666  } else {*/
667  sprintf((PCHAR)vendorStrPtr, "%4.4lx", VendorID);
668  sprintf((PCHAR)deviceStrPtr, "%4.4lx", DeviceID);
669 
670  RtlCopyMemory(&(newBMListPtr->VendorIdStr), (PCHAR)vendorStrPtr, 4);
671  RtlCopyMemory(&(newBMListPtr->DeviceIdStr), (PCHAR)deviceStrPtr, 4);
672 
673  newBMListPtr->nVendorId = VendorID;
674  newBMListPtr->VendorId = (PCHAR)&(newBMListPtr->VendorIdStr);
675  newBMListPtr->VendorIdLength = 4;
676  newBMListPtr->nDeviceId = DeviceID;
677  newBMListPtr->DeviceId = (PCHAR)&(newBMListPtr->DeviceIdStr);
678  newBMListPtr->DeviceIdLength = 4;
679 
680  newBMListPtr->RaidFlags = RaidFlags;
681 // }
682  newBMListPtr->slotNumber = slotData.u.AsULONG;
683  newBMListPtr->MasterDev = IsMasterDev(&pciData) ? 1 : 0;
684  newBMListPtr->busNumber = busNumber;
685 
686  newBMListPtr->NeedAltInit = NeedPciAltInit;
687  newBMListPtr->Known = known;
688 
689  if(!non_isa) {
690  KdPrint2((PRINT_PREFIX "* ISA ranges on PCI, special case !\n"));
691  // Do not fail init after unseccessfull call of UniataClaimLegacyPCIIDE()
692  // some SMP HALs fails to reallocate IO range
693  newBMListPtr->ChanInitOk |= 0x40;
694  }
695 
696  KdPrint2((PRINT_PREFIX "Add to BMList, AltInit %d\n", NeedPciAltInit));
697  } else {
698  KdPrint2((PRINT_PREFIX "count: BMListLen++\n"));
699  PciDevMap[busNumber*PCI_MAX_DEVICES + slotNumber] |= (1 << funcNumber);
700  }
701 
702  BMListLen++;
703 
704  } // Function
705  } // Slot
706  if(!hasPCI) {
707  break;
708  }
709  }
710  if(!pass) {
711  if(!BMListLen)
712  break;
715  if(!BMList) {
716  BMListLen=0;
717  break;
718  }
720  no_buses = FALSE;
721  BMListLen=0;
722  }
723  }
724 exit:
725  KdPrint2((PRINT_PREFIX " BMListLen=%x\n", BMListLen));
726  if(deviceExtension) {
727  ExFreePool(deviceExtension);
728  }
729  if(PciDevMap) {
730  ExFreePool(PciDevMap);
731  }
732  return(SP_RETURN_NOT_FOUND);
733 } // end UniataEnumBusMasterController__()
734 
735 
736 /*
737  Wrapper for read PCI config space
738 */
739 ULONG
740 NTAPI
742  IN PVOID HwDeviceExtension,
743  IN BUS_DATA_TYPE BusDataType,
746  IN PVOID Buffer,
747  IN ULONG Offset,
748  IN ULONG Length
749  )
750 {
751  UCHAR tmp[256];
752  ULONG busDataRead;
753 
754  if(Offset+Length > 256)
755  return 0;
756 
757  busDataRead = HalGetBusData(
758  //ScsiPortGetBusData(HwDeviceExtension,
759  BusDataType,
760  BusNumber,
761  SlotNumber,
762  &tmp,
763  Offset+Length);
764  if(busDataRead < Offset+Length) {
765  if(busDataRead < Offset)
766  return 0;
767  return (Offset+Length-busDataRead);
768  }
770  return Length;
771 } // end ScsiPortGetBusDataByOffset()
772 
773 /*
774  Looks for devices from list on specified bus(es)/slot(s)
775  returnts its index in list.
776  If no matching record found, -1 is returned
777 */
778 ULONG
779 NTAPI
782  IN ULONG lim,
783  IN PVOID HwDeviceExtension,
786  OUT PCI_SLOT_NUMBER* _slotData // optional
787  )
788 {
789  PCI_SLOT_NUMBER slotData;
790  PCI_COMMON_CONFIG pciData;
791  ULONG busDataRead;
792 
793  ULONG busNumber;
794  ULONG slotNumber;
795  ULONG funcNumber;
796 
797  ULONG busNumber2;
798  ULONG slotNumber2;
799 
800  ULONG i;
801 
802  KdPrint2((PRINT_PREFIX "AtapiFindListedDev: lim=%x, Bus=%x, Slot=%x\n", lim, BusNumber, SlotNumber));
803 
804  // set start/end bus
806  busNumber = 0;
807  busNumber2 = maxPciBus;
808  } else {
809  busNumber = BusNumber;
810  busNumber2 = BusNumber+1;
811  }
812  // set start/end slot
814  slotNumber = 0;
815  slotNumber2 = PCI_MAX_DEVICES;
816  } else {
817  slotNumber = SlotNumber;
818  slotNumber2 = SlotNumber+1;
819  }
820  slotData.u.AsULONG = 0;
821 
822  KdPrint2((PRINT_PREFIX " scanning range Bus %x-%x, Slot %x-%x\n", busNumber, busNumber2-1, slotNumber, slotNumber2-1));
823 
824  for( ; busNumber < busNumber2 ; busNumber++ ) {
825  for( ; slotNumber < slotNumber2 ; slotNumber++) {
826  for(funcNumber=0; funcNumber < PCI_MAX_FUNCTION ; funcNumber++) {
827 
828  slotData.u.bits.DeviceNumber = slotNumber;
829  slotData.u.bits.FunctionNumber = funcNumber;
830 
831  busDataRead = HalGetBusData(
832  //ScsiPortGetBusData(HwDeviceExtension,
833  PCIConfiguration, busNumber, slotData.u.AsULONG,
834  &pciData, PCI_COMMON_HDR_LENGTH);
835  // no more buses (this should not happen)
836  if(!busDataRead) {
837  continue;
838  }
839  // no device in this slot
840  if(busDataRead == 2)
841  continue;
842 
843  if(busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH)
844  continue;
845 /*
846  KdPrint2((PRINT_PREFIX "AtapiFindListedDev: b:s:f(%x:%x:%x) %4.4x/%4.4x/%2.2x\n",
847  busNumber, slotNumber, funcNumber,
848  pciData.VendorID, pciData.DeviceID, pciData.RevisionID));
849  */
850  i = Ata_is_dev_listed(BusMasterAdapters, pciData.VendorID, pciData.DeviceID, pciData.RevisionID, lim);
851  if(i != BMLIST_TERMINATOR) {
852  if(_slotData)
853  *_slotData = slotData;
854  KdPrint2((PRINT_PREFIX "AtapiFindListedDev: found\n"));
855  KdPrint2((PRINT_PREFIX "AtapiFindListedDev: b:s:f(%x:%x:%x) %4.4x/%4.4x/%2.2x\n",
856  busNumber, slotNumber, funcNumber,
857  pciData.VendorID, pciData.DeviceID, pciData.RevisionID));
858  return i;
859  }
860 
861  }}}
862  return -1;
863 } // end AtapiFindListedDev()
864 
865 /*
866  Looks for device with specified Device/Vendor and Revision
867  on specified Bus/Slot
868 */
869 ULONG
870 NTAPI
872  IN PVOID HwDeviceExtension,
873  IN BUS_DATA_TYPE BusDataType,
876  IN ULONG dev_id,
877  IN ULONG RevID
878  )
879 {
880  PCI_COMMON_CONFIG pciData;
881  ULONG funcNumber;
882  ULONG busDataRead;
883 
884  ULONG VendorID;
885  ULONG DeviceID;
886  PCI_SLOT_NUMBER slotData;
887 
888  slotData.u.AsULONG = SlotNumber;
889  // walk through all Function Numbers
890  for(funcNumber = 0; funcNumber < PCI_MAX_FUNCTION; funcNumber++) {
891 
892  slotData.u.bits.FunctionNumber = funcNumber;
893  if(slotData.u.AsULONG == SlotNumber)
894  continue;
895 
896  busDataRead = HalGetBusData(
897  //busDataRead = ScsiPortGetBusData(HwDeviceExtension,
899  BusNumber,
900  slotData.u.AsULONG,
901  &pciData,
903 
904  if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
905  continue;
906  }
907 
908  VendorID = pciData.VendorID;
909  DeviceID = pciData.DeviceID;
910 
911  if(dev_id != (VendorID | (DeviceID << 16)) )
912  continue;
913  if(RevID >= pciData.RevisionID)
914  return 1;
915  }
916  return 0;
917 } // end AtapiFindDev()
918 
919 #endif //UNIATA_CORE
920 
921 
922 ULONG
923 NTAPI
925  IN PVOID HwDeviceExtension,
926  IN PVOID Context,
927  IN PVOID BusInformation,
928  IN PCHAR ArgumentString,
930  OUT PBOOLEAN Again
931  )
932 {
934  HwDeviceExtension,
935  UlongToPtr(0x00000000),
936  BusInformation,
937  ArgumentString,
938  ConfigInfo,
939  Again
940  );
941 } // end UniataFindCompatBusMasterController1()
942 
943 ULONG
944 NTAPI
946  IN PVOID HwDeviceExtension,
947  IN PVOID Context,
948  IN PVOID BusInformation,
949  IN PCHAR ArgumentString,
951  OUT PBOOLEAN Again
952  )
953 {
955  HwDeviceExtension,
956  UlongToPtr(0x80000000),
957  BusInformation,
958  ArgumentString,
959  ConfigInfo,
960  Again
961  );
962 } // end UniataFindCompatBusMasterController2()
963 
964 /*++
965 
966 Routine Description:
967 
968  This function is called by the OS-specific port driver after
969  the necessary storage has been allocated, to gather information
970  about the adapter's configuration.
971 
972 Arguments:
973 
974  HwDeviceExtension - HBA miniport driver's adapter data storage
975  Context - Address of adapter count
976  BusInformation -
977  ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility.
978  ConfigInfo - Configuration information structure describing HBA
979  Again - Indicates search for adapters to continue
980 
981 Return Value:
982 
983  ULONG
984 
985 --*/
986 ULONG
987 NTAPI
989  IN PVOID HwDeviceExtension,
990  IN PVOID Context,
991  IN PVOID BusInformation,
992  IN PCHAR ArgumentString,
994  OUT PBOOLEAN Again
995  )
996 {
997  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
998  PHW_CHANNEL chan = NULL;
999 #ifndef UNIATA_CORE
1000  // this buffer must be global for UNIATA_CORE build
1001  PCI_COMMON_CONFIG pciData;
1002 #endif //UNIATA_CORE
1003  ULONG slotNumber;
1004  ULONG busDataRead;
1005  ULONG SystemIoBusNumber;
1006 /*
1007  UCHAR vendorString[5];
1008  UCHAR deviceString[5];
1009 
1010  PUCHAR vendorStrPtr;
1011  PUCHAR deviceStrPtr;
1012 */
1013  UCHAR BaseClass;
1014  UCHAR SubClass;
1015  ULONG VendorID;
1016  ULONG DeviceID;
1017  ULONG RevID;
1018  ULONG dev_id;
1019  PCI_SLOT_NUMBER slotData;
1020 
1021  ULONG i;
1022  ULONG channel;
1023  ULONG c = 0;
1024  PUCHAR ioSpace;
1025  UCHAR statusByte;
1026  ULONG bm_offset;
1027 
1028 // UCHAR tmp8;
1029 // ULONG irq;
1030 
1031  BOOLEAN found = FALSE;
1032  BOOLEAN MasterDev;
1033  BOOLEAN simplexOnly = FALSE;
1034 #ifndef UNIATA_CORE
1035 #ifdef UNIATA_INIT_ON_PROBE
1036  BOOLEAN skip_find_dev = FALSE;
1037 #endif
1038 #endif
1039  BOOLEAN AltInit = FALSE;
1040 
1041  SCSI_PHYSICAL_ADDRESS IoBasePort1;
1042  SCSI_PHYSICAL_ADDRESS IoBasePort2;
1043 
1044  PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0 = NULL;
1045  PIDE_REGISTERS_1 BaseIoAddress1[IDE_MAX_CHAN];
1046  PIDE_REGISTERS_2 BaseIoAddress2[IDE_MAX_CHAN];
1047 
1048  RtlZeroMemory(&BaseIoAddress1, sizeof(BaseIoAddress1));
1049  RtlZeroMemory(&BaseIoAddress2, sizeof(BaseIoAddress2));
1050 
1051  NTSTATUS status;
1054 
1055  if(!WinVer_WDM_Model) {
1056  *Again = FALSE;
1057  } else {
1058  *Again = TRUE;
1059  }
1060 
1061  KdPrint2((PRINT_PREFIX "UniataFindBusMasterController: Context=%x, BMListLen=%d\n", Context, BMListLen));
1062 
1063  KdPrint2((PRINT_PREFIX "ConfigInfo->Length %x\n", ConfigInfo->Length));
1064 
1065  if(ForceSimplex) {
1066  KdPrint2((PRINT_PREFIX "ForceSimplex (1)\n"));
1067  simplexOnly = TRUE;
1068  }
1069 
1070  if(ConfigInfo->AdapterInterfaceType == Isa) {
1071  KdPrint2((PRINT_PREFIX "AdapterInterfaceType: Isa\n"));
1072  }
1073  if(InDriverEntry) {
1074  i = PtrToUlong(Context);
1075  if(i & 0x80000000) {
1076  AltInit = TRUE;
1077  }
1078  i &= ~0x80000000;
1079  channel = BMList[i].channel;
1080  } else {
1081  channel = 0;
1082  for(i=0; i<BMListLen; i++) {
1083  if(BMList[i].slotNumber == ConfigInfo->SlotNumber &&
1084  BMList[i].busNumber == ConfigInfo->SystemIoBusNumber) {
1085  break;
1086  }
1087  }
1088  if(i >= BMListLen) {
1089  KdPrint2((PRINT_PREFIX "unexpected device arrival\n"));
1090  i = PtrToUlong(Context);
1091  if(FirstMasterOk) {
1092  channel = 1;
1093  }
1094  i &= ~0x80000000;
1095  if(i >= BMListLen) {
1096  KdPrint2((PRINT_PREFIX " => SP_RETURN_NOT_FOUND\n"));
1097  goto exit_notfound;
1098  }
1099  }
1100  BMList[i].channel = (UCHAR)channel;
1101  }
1102 
1103  bm_offset = channel ? ATA_BM_OFFSET1 : 0;
1104 
1105  KdPrint2((PRINT_PREFIX "bm_offset %x, channel %x \n", bm_offset, channel));
1106 
1107  if (!deviceExtension) {
1108  KdPrint2((PRINT_PREFIX "!deviceExtension => SP_RETURN_ERROR\n"));
1109  return SP_RETURN_ERROR;
1110  }
1111  RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION));
1112 /*
1113  vendorStrPtr = vendorString;
1114  deviceStrPtr = deviceString;
1115 */
1116  slotNumber = BMList[i].slotNumber;
1117  SystemIoBusNumber = BMList[i].busNumber;
1118 
1119 
1120  KdPrint2((PRINT_PREFIX "AdapterInterfaceType=%#x\n",ConfigInfo->AdapterInterfaceType));
1121  KdPrint2((PRINT_PREFIX "IoBusNumber=%#x\n",ConfigInfo->SystemIoBusNumber));
1122  KdPrint2((PRINT_PREFIX "slotNumber=%#x\n",slotNumber));
1123 
1124  // this buffer must be global and already filled for UNIATA_CORE build
1125  busDataRead = HalGetBusData(
1126  //busDataRead = ScsiPortGetBusData(HwDeviceExtension,
1128  SystemIoBusNumber,
1129  slotNumber,
1130  &pciData,
1132 
1133 #ifndef UNIATA_CORE
1134  if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
1135  KdPrint2((PRINT_PREFIX "busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n"));
1136  goto exit_error;
1137  }
1138 
1139  KdPrint2((PRINT_PREFIX "busDataRead\n"));
1140  if (pciData.VendorID == PCI_INVALID_VENDORID) {
1141  KdPrint2((PRINT_PREFIX "PCI_INVALID_VENDORID\n"));
1142  goto exit_error;
1143  }
1144 #endif //UNIATA_CORE
1145 
1146  VendorID = pciData.VendorID;
1147  DeviceID = pciData.DeviceID;
1148  BaseClass = pciData.BaseClass;
1149  SubClass = pciData.SubClass;
1150  RevID = pciData.RevisionID;
1151  dev_id = VendorID | (DeviceID << 16);
1152  slotData.u.AsULONG = slotNumber;
1153  KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass ));
1154 
1155  deviceExtension->slotNumber = slotNumber;
1156  deviceExtension->SystemIoBusNumber = SystemIoBusNumber;
1157  deviceExtension->DevID = dev_id;
1158  deviceExtension->RevID = RevID;
1159  deviceExtension->NumberChannels = IDE_DEFAULT_MAX_CHAN; // default
1160  deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN; // default
1161  deviceExtension->DevIndex = i;
1162 
1163  _snprintf(deviceExtension->Signature, sizeof(deviceExtension->Signature),
1164  "UATA%8.8x/%1.1x@%8.8x", dev_id, channel, slotNumber);
1165 
1166  if(BaseClass != PCI_DEV_CLASS_STORAGE) {
1167  KdPrint2((PRINT_PREFIX "BaseClass != PCI_DEV_CLASS_STORAGE => SP_RETURN_NOT_FOUND\n"));
1168  goto exit_notfound;
1169  }
1170 
1171  KdPrint2((PRINT_PREFIX "Storage Class\n"));
1172 
1173  // look for known chipsets
1174  if(VendorID != BMList[i].nVendorId ||
1175  DeviceID != BMList[i].nDeviceId) {
1176  KdPrint2((PRINT_PREFIX "device not suitable\n"));
1177  goto exit_notfound;
1178  }
1179 
1180  found = UniataCheckPCISubclass(BMList[i].Known, BMList[i].RaidFlags, SubClass);
1181  if(!found) {
1182  KdPrint2((PRINT_PREFIX "Subclass not supported\n"));
1183  goto exit_notfound;
1184  }
1185 
1186  ConfigInfo->AlignmentMask = 0x00000003;
1187 
1188  MasterDev = IsMasterDev(&pciData);
1189 
1190  if(MasterDev) {
1191  KdPrint2((PRINT_PREFIX "MasterDev (1)\n"));
1192  deviceExtension->MasterDev = TRUE;
1193  KdPrint2((PRINT_PREFIX "Check exclude\n"));
1194  if(AtapiRegCheckDevValue(deviceExtension, channel, DEVNUM_NOT_SPECIFIED, L"Exclude", 0)) {
1195  KdPrint2((PRINT_PREFIX "Device excluded\n"));
1196  goto exit_notfound;
1197  }
1198  }
1199 
1200  status = UniataChipDetect(HwDeviceExtension, &pciData, i, ConfigInfo, &simplexOnly);
1201  switch(status) {
1202  case STATUS_SUCCESS:
1203  found = TRUE;
1204  break;
1205  case STATUS_NOT_FOUND:
1206  found = FALSE;
1207  break;
1208  default:
1209  KdPrint2((PRINT_PREFIX "FAILED => SP_RETURN_ERROR\n"));
1210  goto exit_error;
1211  }
1212  KdPrint2((PRINT_PREFIX "ForceSimplex = %d\n", simplexOnly));
1213  KdPrint2((PRINT_PREFIX "HwFlags = %x\n (0)", deviceExtension->HwFlags));
1214  switch(dev_id) {
1215  /* additional checks for some supported chipsets */
1216  case 0xc6931080:
1217  if (SubClass != PCI_DEV_SUBCLASS_IDE) {
1218  KdPrint2((PRINT_PREFIX "0xc6931080, SubClass != PCI_DEV_SUBCLASS_IDE => found = FALSE\n"));
1219  found = FALSE;
1220  } else {
1221  found = FALSE;
1222  }
1223  break;
1224 
1225  /* unknown chipsets, try generic DMA if it seems possible */
1226  default:
1227  if (found)
1228  break;
1229  KdPrint2((PRINT_PREFIX "Default device\n"));
1230  if(Ata_is_supported_dev(&pciData)) {
1231  KdPrint2((PRINT_PREFIX "Ata_is_supported_dev\n"));
1232  found = TRUE;
1233  } else
1234  if(deviceExtension->HwFlags & UNIATA_AHCI) {
1235  KdPrint2((PRINT_PREFIX "AHCI candidate\n"));
1236  found = TRUE;
1237  } else {
1238  KdPrint2((PRINT_PREFIX "!Ata_is_supported_dev => found = FALSE\n"));
1239  found = FALSE;
1240  }
1241  deviceExtension->UnknownDev = TRUE;
1242  break;
1243  }
1244 
1245  KdPrint2((PRINT_PREFIX "HwFlags = %x\n (1)", deviceExtension->HwFlags));
1246  if(!found) {
1247  KdPrint2((PRINT_PREFIX "!found => SP_RETURN_NOT_FOUND\n"));
1248  goto exit_notfound;
1249  }
1250 
1251  KdPrint2((PRINT_PREFIX "HwFlags = %x\n (2)", deviceExtension->HwFlags));
1252  KdPrint2((PRINT_PREFIX "found suitable device\n"));
1253 
1254  /***********************************************************/
1255  /***********************************************************/
1256  /***********************************************************/
1257 
1258  deviceExtension->UseDpc = TRUE;
1259 #ifndef UNIATA_CORE
1260  if (g_Dump) {
1261  deviceExtension->DriverMustPoll = TRUE;
1262  deviceExtension->UseDpc = FALSE;
1263  deviceExtension->simplexOnly = TRUE;
1264  deviceExtension->HwFlags |= UNIATA_NO_DPC;
1265  }
1266 #endif //UNIATA_CORE
1267  KdPrint2((PRINT_PREFIX "HwFlags = %x\n (3)", deviceExtension->HwFlags));
1268  if(deviceExtension->HwFlags & UNIATA_NO_DPC) {
1269  /* CMD 649, ROSB SWK33, ICH4 */
1270  KdPrint2((PRINT_PREFIX "UniataFindBusMasterController: UNIATA_NO_DPC (0)\n"));
1271  deviceExtension->UseDpc = FALSE;
1272  }
1273 
1274  if(MasterDev) {
1275  if((WinVer_Id() <= WinVer_NT) && AltInit && FirstMasterOk) {
1276  // this is the 2nd attempt to init this controller by OUR driver
1277  KdPrint2((PRINT_PREFIX "Skip primary/secondary claiming checks\n"));
1278  } else {
1279  if((channel==0) && ConfigInfo->AtdiskPrimaryClaimed) {
1280  KdPrint2((PRINT_PREFIX "Error: Primary channel already claimed by another driver\n"));
1281  goto exit_notfound;
1282  }
1283  if((channel==1) && ConfigInfo->AtdiskSecondaryClaimed) {
1284  KdPrint2((PRINT_PREFIX "Error: Secondary channel already claimed by another driver\n"));
1285  goto exit_notfound;
1286  }
1287  }
1288  }
1289  if(deviceExtension->HwFlags & UNIATA_AHCI) {
1290  KdPrint2((PRINT_PREFIX " AHCI registers layout\n"));
1291  } else
1292  if(deviceExtension->AltRegMap) {
1293  KdPrint2((PRINT_PREFIX " Non-standard registers layout\n"));
1294  if(deviceExtension->HwFlags & UNIATA_SATA) {
1295  KdPrint2((PRINT_PREFIX "UNIATA_SATA -> IsBusMaster == TRUE\n"));
1296  if(!deviceExtension->BusMaster) {
1297  deviceExtension->BusMaster = DMA_MODE_BM;
1298  }
1299  }
1300  } else {
1301  deviceExtension->BusMaster = DMA_MODE_NONE;
1302 
1303  if(WinVer_WDM_Model && !deviceExtension->UnknownDev) {
1304  UniataEnableIoPCI(ConfigInfo->SystemIoBusNumber, slotData.u.AsULONG, &pciData);
1305  }
1306  // validate Mem/Io ranges
1307  //no_ranges = TRUE;
1308  {
1309  ULONG j;
1310  for(j=0; j<PCI_TYPE0_ADDRESSES; j++) {
1311  if(pciData.u.type0.BaseAddresses[j] & ~0x7) {
1312  //no_ranges = FALSE;
1313  //break;
1314  KdPrint2((PRINT_PREFIX "Range %d = %#x\n", j, pciData.u.type0.BaseAddresses[j]));
1315  }
1316  }
1317  }
1318 
1319  if(IsBusMaster(&pciData)) {
1320 
1321  KdPrint2((PRINT_PREFIX "IsBusMaster == TRUE\n"));
1322  BaseIoAddressBM_0 = (PIDE_BUSMASTER_REGISTERS)
1323  (AtapiGetIoRange(HwDeviceExtension, ConfigInfo, &pciData, SystemIoBusNumber,
1324  4, bm_offset, MasterDev ? 0x08 : 0x10/*ATA_BMIOSIZE*/)/* - bm_offset*/); //range id
1325  if(BaseIoAddressBM_0) {
1326  UniataInitMapBM(deviceExtension,
1327  BaseIoAddressBM_0,
1328  (*ConfigInfo->AccessRanges)[4].RangeInMemory ? TRUE : FALSE);
1329  deviceExtension->BusMaster = DMA_MODE_BM;
1330  deviceExtension->BaseIoAddressBM_0.Addr = (ULONGIO_PTR)BaseIoAddressBM_0;
1331  if((*ConfigInfo->AccessRanges)[4].RangeInMemory) {
1332  deviceExtension->BaseIoAddressBM_0.MemIo = TRUE;
1333  }
1334  }
1335  KdPrint2((PRINT_PREFIX " BusMasterAddress (base): %#x\n", BaseIoAddressBM_0));
1336  }
1337 
1338  if(!deviceExtension->BusMaster) {
1339  KdPrint2((PRINT_PREFIX " !BusMasterAddress -> PIO4\n"));
1340  deviceExtension->MaxTransferMode = ATA_PIO4;
1341  }
1342 
1343  if(deviceExtension->BusMaster && !MasterDev) {
1344  KdPrint2((PRINT_PREFIX "IsBusMaster == TRUE && !MasterDev\n"));
1345  statusByte = AtapiReadPort1(&(deviceExtension->chan[0]), IDX_BM_Status);
1346  KdPrint2((PRINT_PREFIX " BM statusByte = %x\n", statusByte));
1347  if(statusByte == IDE_STATUS_WRONG) {
1348  KdPrint2((PRINT_PREFIX " invalid port ?\n"));
1349  deviceExtension->BusMaster = DMA_MODE_NONE;
1350 /*
1351  if(BaseIoAddressBM_0) {
1352  ScsiPortFreeDeviceBase(HwDeviceExtension,
1353  BaseIoAddressBM_0);
1354  BaseIoAddressBM_0 = NULL;
1355  }
1356 */
1357  } else
1358  if(statusByte & BM_STATUS_SIMPLEX_ONLY) {
1359  KdPrint2((PRINT_PREFIX " BM_STATUS => simplexOnly\n"));
1360  simplexOnly = TRUE;
1361  }
1362  }
1363  }
1364 
1365  /*
1366  * the Cypress chip is a mess, it contains two ATA functions, but
1367  * both channels are visible on the first one.
1368  * simply ignore the second function for now, as the right
1369  * solution (ignoring the second channel on the first function)
1370  * doesn't work with the crappy ATA interrupt setup on the alpha.
1371  */
1372  if (dev_id == 0xc6931080 && slotData.u.bits.FunctionNumber > 1) {
1373  KdPrint2((PRINT_PREFIX "dev_id == 0xc6931080 && FunctionNumber > 1 => exit_findbm\n"));
1374  goto exit_findbm;
1375  }
1376 
1377  /* do extra chipset specific setups */
1378  AtapiReadChipConfig(HwDeviceExtension, i, CHAN_NOT_SPECIFIED);
1379  AtapiChipInit(HwDeviceExtension, i, CHAN_NOT_SPECIFIED_CHECK_CABLE);
1380 
1381  simplexOnly |= deviceExtension->simplexOnly;
1382  deviceExtension->simplexOnly |= simplexOnly;
1383 
1384  KdPrint2((PRINT_PREFIX "simplexOnly = %d (2)", simplexOnly));
1385 
1386  //TODO: fix hang with UseDpc=TRUE in Simplex mode
1387  //deviceExtension->UseDpc = TRUE;
1388  if(simplexOnly) {
1389  KdPrint2((PRINT_PREFIX "simplexOnly => UseDpc = FALSE\n"));
1390  deviceExtension->UseDpc = FALSE;
1391  }
1392 
1393  if(simplexOnly && MasterDev) {
1394  if(deviceExtension->NumberChannels < IDE_DEFAULT_MAX_CHAN) {
1395  KdPrint2((PRINT_PREFIX "set NumberChannels = %d\n", IDE_DEFAULT_MAX_CHAN));
1396  deviceExtension->NumberChannels = IDE_DEFAULT_MAX_CHAN;
1397  if(BaseIoAddressBM_0) {
1398  UniataInitMapBM(deviceExtension,
1399  BaseIoAddressBM_0,
1400  (*ConfigInfo->AccessRanges)[4].RangeInMemory ? TRUE : FALSE);
1401  }
1402  }
1403  }
1404  if((channel > 0) &&
1405  (deviceExtension->NumberChannels > 1)) {
1406  KdPrint2((PRINT_PREFIX "Error: channel > 0 && NumberChannels > 1\n"));
1407  goto exit_findbm;
1408  }
1409 
1410  // Indicate number of buses.
1411  ConfigInfo->NumberOfBuses = (UCHAR)(deviceExtension->NumberChannels);
1412  if(!ConfigInfo->InitiatorBusId[0]) {
1413  ConfigInfo->InitiatorBusId[0] = (CHAR)(IoGetConfigurationInformation()->ScsiPortCount);
1414  KdPrint2((PRINT_PREFIX "set ConfigInfo->InitiatorBusId[0] = %#x\n", ConfigInfo->InitiatorBusId[0]));
1415  }
1416  // Indicate four devices can be attached to the adapter
1417  ConfigInfo->MaximumNumberOfTargets = (UCHAR)(deviceExtension->NumberLuns);
1418 
1419  if (MasterDev) {
1420  KdPrint2((PRINT_PREFIX "MasterDev (2)\n"));
1421 /*
1422  if((WinVer_Id() > WinVer_NT) ||
1423  (deviceExtension->NumberChannels > 1)) {
1424 
1425  KdPrint2((PRINT_PREFIX "2 channels & 2 irq for 1 controller Win 2000+\n"));
1426 
1427  if (ConfigInfo->AdapterInterfaceType == MicroChannel) {
1428  ConfigInfo->InterruptMode2 =
1429  ConfigInfo->InterruptMode = LevelSensitive;
1430  } else {
1431  ConfigInfo->InterruptMode2 =
1432  ConfigInfo->InterruptMode = Latched;
1433  }
1434  ConfigInfo->BusInterruptLevel = 14;
1435  ConfigInfo->BusInterruptLevel2 = 15;
1436  } else*/
1437  if(simplexOnly) {
1438 
1439  KdPrint2((PRINT_PREFIX "2 channels & 2 irq for 1 controller\n"));
1440 
1441  if (ConfigInfo->AdapterInterfaceType == MicroChannel) {
1442  ConfigInfo->InterruptMode2 =
1443  ConfigInfo->InterruptMode = LevelSensitive;
1444  } else {
1445  ConfigInfo->InterruptMode2 =
1446  ConfigInfo->InterruptMode = Latched;
1447  }
1448  ConfigInfo->BusInterruptLevel = 14;
1449  ConfigInfo->BusInterruptLevel2 = 15;
1450  } else {
1451  KdPrint2((PRINT_PREFIX "1 channels & 1 irq for 1 controller\n"));
1452  if (ConfigInfo->AdapterInterfaceType == MicroChannel) {
1453  ConfigInfo->InterruptMode = LevelSensitive;
1454  } else {
1455  ConfigInfo->InterruptMode = Latched;
1456  }
1457  ConfigInfo->BusInterruptLevel = (channel == 0 ? 14 : 15);
1458  }
1459  } else {
1460  KdPrint2((PRINT_PREFIX "!MasterDev\n"));
1461  ConfigInfo->SlotNumber = slotNumber;
1462  ConfigInfo->SystemIoBusNumber = SystemIoBusNumber;
1463  ConfigInfo->InterruptMode = LevelSensitive;
1464 
1465  /* primary and secondary channels share the same interrupt */
1466  if(!ConfigInfo->BusInterruptVector ||
1467  (ConfigInfo->BusInterruptVector != pciData.u.type0.InterruptLine)) {
1468  KdPrint2((PRINT_PREFIX "patch irq line = %#x\n", pciData.u.type0.InterruptLine));
1469  ConfigInfo->BusInterruptVector = pciData.u.type0.InterruptLine; // set default value
1470  if(!ConfigInfo->BusInterruptVector) {
1471  KdPrint2((PRINT_PREFIX "patch irq line (2) = 10\n"));
1472  ConfigInfo->BusInterruptVector = 10;
1473  }
1474  }
1475  }
1476  ConfigInfo->MultipleRequestPerLu = TRUE;
1477  ConfigInfo->AutoRequestSense = TRUE;
1478  ConfigInfo->TaggedQueuing = TRUE;
1479 
1480  if((WinVer_Id() >= WinVer_NT) ||
1481  (ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4))) {
1482  KdPrint2((PRINT_PREFIX "update ConfigInfo->nt4\n"));
1483  _ConfigInfo->nt4.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
1484  _ConfigInfo->nt4.SpecificLuExtensionSize = sizeof(HW_LU_EXTENSION);
1485  //if(deviceExtension->HwFlags & UNIATA_AHCI) {
1486  _ConfigInfo->nt4.SrbExtensionSize = sizeof(ATA_REQ);
1487  //} else {
1488  // _ConfigInfo->nt4.SrbExtensionSize = FIELD_OFFSET(ATA_REQ, dma_tab) + sizeof(BM_DMA_ENTRY)*ATA_DMA_ENTRIES;
1489  //}
1490  KdPrint2((PRINT_PREFIX "using AtaReq sz %x\n", _ConfigInfo->nt4.SrbExtensionSize));
1491  }
1492  if((WinVer_Id() > WinVer_2k) ||
1493  (ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4) + sizeof(_ConfigInfo->w2k))) {
1494  KdPrint2((PRINT_PREFIX "update ConfigInfo->w2k: 64bit %d\n",
1495  deviceExtension->Host64));
1496 #ifdef USE_OWN_DMA
1497  // We need not set Dma64BitAddresses since we perform address translation manually.
1498 #else
1499  _ConfigInfo->w2k.Dma64BitAddresses = deviceExtension->Host64;
1500 #endif //USE_OWN_DMA
1501  _ConfigInfo->w2k.ResetTargetSupported = TRUE;
1502  _ConfigInfo->w2k.MaximumNumberOfLogicalUnits = (UCHAR)deviceExtension->NumberLuns;
1503  }
1504 
1505  // Save the Interrupe Mode for later use
1506  deviceExtension->InterruptMode = ConfigInfo->InterruptMode;
1507  deviceExtension->BusInterruptLevel = ConfigInfo->BusInterruptLevel;
1508  deviceExtension->BusInterruptVector = ConfigInfo->BusInterruptVector;
1509  deviceExtension->Channel = channel;
1510  deviceExtension->DevIndex = i;
1511  deviceExtension->OrigAdapterInterfaceType
1512  = ConfigInfo->AdapterInterfaceType;
1513  deviceExtension->AlignmentMask = ConfigInfo->AlignmentMask;
1514  deviceExtension->AdapterInterfaceType = PCIBus;
1515 
1516  KdPrint2((PRINT_PREFIX "chan[%d] InterruptMode: %d, Level %d, Level2 %d, Vector %d, Vector2 %d\n",
1517  channel,
1518  ConfigInfo->InterruptMode,
1519  ConfigInfo->BusInterruptLevel,
1520  ConfigInfo->BusInterruptLevel2,
1521  ConfigInfo->BusInterruptVector,
1522  ConfigInfo->BusInterruptVector2
1523  ));
1524 
1525  found = FALSE;
1526 
1527  if(deviceExtension->BusMaster) {
1528 
1529  KdPrint2((PRINT_PREFIX "Reconstruct ConfigInfo\n"));
1530 #ifdef USE_OWN_DMA
1531  ConfigInfo->NeedPhysicalAddresses = FALSE;
1532 #else
1533  ConfigInfo->NeedPhysicalAddresses = TRUE;
1534 #endif //USE_OWN_DMA
1535  if(!MasterDev) {
1536 //#ifdef USE_OWN_DMA
1537 // KdPrint2((PRINT_PREFIX "!MasterDev, own DMA\n"));
1538 //#else
1539  KdPrint2((PRINT_PREFIX "set Dma32BitAddresses\n"));
1540  ConfigInfo->Dma32BitAddresses = TRUE;
1541 //#endif //USE_OWN_DMA
1542  }
1543 
1544  // thanks to Vitaliy Vorobyov aka deathsoft@yandex.ru for
1545  // better solution:
1546 
1547  if(AltInit) {
1548  // I'm sorry, I have to do this
1549  // when Win doesn't
1550 
1551  if(ConfigInfo->AdapterInterfaceType == Isa /*&&
1552 // InDriverEntry*/) {
1553  KdPrint2((PRINT_PREFIX "AdapterInterfaceType Isa => PCIBus\n"));
1554  ConfigInfo->AdapterInterfaceType = PCIBus;
1555  }
1556  if(ConfigInfo->AdapterInterfaceType == PCIBus /*&&
1557 // InDriverEntry*/) {
1558  KdPrint2((PRINT_PREFIX "AdapterInterfaceType PCIBus, update address\n"));
1559  ConfigInfo->SlotNumber = slotNumber;
1560  ConfigInfo->SystemIoBusNumber = SystemIoBusNumber;
1561  }
1562  }
1563 
1564 #ifndef USE_OWN_DMA
1565  ConfigInfo->Master = TRUE;
1566  ConfigInfo->DmaWidth = Width16Bits;
1567 #endif //USE_OWN_DMA
1568  ConfigInfo->ScatterGather = TRUE;
1569  }
1570  ConfigInfo->MapBuffers = TRUE; // Need for PIO and OWN_DMA
1571  ConfigInfo->CachesData = TRUE;
1572 
1573  KdPrint2((PRINT_PREFIX "BMList[i].channel %#x, NumberChannels %#x, channel %#x\n",BMList[i].channel, deviceExtension->NumberChannels, channel));
1574 
1575  for (; channel < (BMList[i].channel + deviceExtension->NumberChannels); channel++, c++) {
1576 
1577  KdPrint2((PRINT_PREFIX "de %#x, Channel %#x\n",deviceExtension, channel));
1578  //PrintNtConsole("de %#x, Channel %#x, nchan %#x\n",deviceExtension, channel, deviceExtension->NumberChannels);
1579  chan = &deviceExtension->chan[c];
1580 
1581  KdPrint2((PRINT_PREFIX "chan = %#x\n", chan));
1582  //PrintNtConsole("chan = %#x, c=%#x\n", chan, c);
1583  AtapiSetupLunPtrs(chan, deviceExtension, c);
1584 
1585  /* do extra channel-specific setups */
1586  AtapiReadChipConfig(HwDeviceExtension, i, channel);
1587  //AtapiChipInit(HwDeviceExtension, i, channel);
1588  if(deviceExtension->HwFlags & UNIATA_AHCI) {
1589  KdPrint2((PRINT_PREFIX " No more setup for AHCI channel\n"));
1590  } else
1591  if(deviceExtension->AltRegMap) {
1592  KdPrint2((PRINT_PREFIX " Non-standard registers layout\n"));
1593  } else {
1594  // Check if the range specified is not used by another driver
1595  if(MasterDev) {
1596  KdPrint2((PRINT_PREFIX "set AccessRanges\n"));
1597  (*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeStart =
1599  (*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeLength = ATA_IOSIZE;
1600 
1601  (*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeStart =
1603  (*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeLength = ATA_ALTIOSIZE;
1604  } else
1605  if(AltInit &&
1606  !(*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeStart.QuadPart &&
1607  !(*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeStart.QuadPart) {
1608  KdPrint2((PRINT_PREFIX "cheat ScsiPort, sync real PCI and ConfigInfo IO ranges\n"));
1609  AtapiGetIoRange(HwDeviceExtension, ConfigInfo, &pciData, SystemIoBusNumber,
1610  channel * 2 + 0, 0, ATA_IOSIZE);
1611  AtapiGetIoRange(HwDeviceExtension, ConfigInfo, &pciData, SystemIoBusNumber,
1612  channel * 2 + 1, 0, ATA_ALTIOSIZE);
1613  }
1614 
1615  IoBasePort1 = (*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeStart;
1616  IoBasePort2 = (*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeStart;
1617 
1618  if(!MasterDev) {
1619  if(!IoBasePort1.QuadPart || !IoBasePort2.QuadPart) {
1620  KdPrint2((PRINT_PREFIX "ScsiPortValidateRange failed (1)\n"));
1621  continue;
1622  }
1623  }
1624 
1625  if(!ScsiPortValidateRange(HwDeviceExtension,
1626  PCIBus /*ConfigInfo->AdapterInterfaceType*/,
1627  SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/,
1628  IoBasePort1,
1629  ATA_IOSIZE,
1630  TRUE) ) {
1631  KdPrint2((PRINT_PREFIX "ScsiPortValidateRange failed (1)\n"));
1632  continue;
1633  }
1634 
1635  if(!ScsiPortValidateRange(HwDeviceExtension,
1636  PCIBus /*ConfigInfo->AdapterInterfaceType*/,
1637  SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/,
1638  IoBasePort2,
1639  ATA_ALTIOSIZE,
1640  TRUE) ) {
1641  KdPrint2((PRINT_PREFIX "ScsiPortValidateRange failed (2)\n"));
1642  continue;
1643  }
1644 
1645  KdPrint2((PRINT_PREFIX "Getting IO ranges\n"));
1646 
1647  // Ok, translate adresses to io-space
1648  if(ScsiPortConvertPhysicalAddressToUlong(IoBasePort2)) {
1649  if(!(MasterDev /* || USE_16_BIT */)) {
1650  KdPrint2((PRINT_PREFIX "!MasterDev mode\n"));
1652  ScsiPortConvertPhysicalAddressToUlong(IoBasePort2) + 2);
1653  }
1654  } else {
1655  KdPrint2((PRINT_PREFIX "use relative IoBasePort2\n"));
1658  }
1659 
1660  // Get the system physical address for this IO range.
1661  ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
1662  MasterDev ? ConfigInfo->AdapterInterfaceType : PCIBus /*ConfigInfo->AdapterInterfaceType*/,
1663  MasterDev ? ConfigInfo->SystemIoBusNumber : SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/,
1664  IoBasePort1,
1665  ATA_IOSIZE,
1666  TRUE);
1667  KdPrint2((PRINT_PREFIX "IO range 1 %#x\n",ioSpace));
1668 
1669  // Check if ioSpace accessible.
1670  if (!ioSpace) {
1671  KdPrint2((PRINT_PREFIX "!ioSpace\n"));
1672  continue;
1673  }
1674 /*
1675  if(deviceExtension->BusMaster) {
1676  KdPrint2((PRINT_PREFIX "set BusMaster io-range in DO\n"));
1677  // bm_offset already includes (channel ? ATA_BM_OFFSET1 : 0)
1678  deviceExtension->BaseIoAddressBM[c] = (PIDE_BUSMASTER_REGISTERS)
1679  ((ULONG)(deviceExtension->BaseIoAddressBM_0) + bm_offset + (c ? ATA_BM_OFFSET1 : 0));
1680  }
1681 */
1682  //deviceExtension->BaseIoAddress1[c] = (PIDE_REGISTERS_1)(ioSpace);
1683  BaseIoAddress1[c] = (PIDE_REGISTERS_1)(ioSpace);
1684 
1685  // Get the system physical address for the second IO range.
1686  ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
1687  MasterDev ? ConfigInfo->AdapterInterfaceType : PCIBus /*ConfigInfo->AdapterInterfaceType*/,
1688  MasterDev ? ConfigInfo->SystemIoBusNumber : SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/,
1689  IoBasePort2,
1690  ATA_ALTIOSIZE,
1691  TRUE);
1692  KdPrint2((PRINT_PREFIX "IO range 2 %#x\n",ioSpace));
1693 
1694  BaseIoAddress2[c] = (PIDE_REGISTERS_2)(ioSpace);
1695  if(!ioSpace) {
1696  // Release all allocated resources
1697  KdPrint2((PRINT_PREFIX "!deviceExtension->BaseIoAddress2\n"));
1698  //ioSpace = (PUCHAR)BaseIoAddress1[c];
1699  // goto free_iospace_1;
1700  found = FALSE;
1701  goto exit_findbm;
1702  }
1703  UniataInitMapBase(chan, BaseIoAddress1[c], BaseIoAddress2[c]);
1704  }
1705  //ioSpace = (PUCHAR)(deviceExtension->BaseIoAddress1[c]);
1706 
1711 
1712  if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
1713 #ifdef _DEBUG
1714  UniataDumpATARegs(chan);
1715 #endif
1716 
1717 #ifndef UNIATA_CORE
1718 #ifdef UNIATA_INIT_ON_PROBE
1719 // if(deviceExtension->HwFlags & UNIATA_SATA) {
1720 //#endif //UNIATA_INIT_ON_PROBE
1721  KdPrint2((PRINT_PREFIX "Check drive 0\n"));
1722  // Check master.
1723  SelectDrive(chan, 0);
1724  AtapiStallExecution(10);
1725  GetBaseStatus(chan, statusByte);
1726  skip_find_dev = FALSE;
1727  if(!(deviceExtension->HwFlags & UNIATA_NO_SLAVE) && (deviceExtension->NumberLuns > 1)) {
1728  if ((statusByte & 0xf8) == 0xf8 ||
1729  (statusByte == 0xa5)) {
1730  // Check slave.
1731  KdPrint2((PRINT_PREFIX "Check drive 1\n"));
1732  SelectDrive(chan, 1);
1734  GetBaseStatus(chan, statusByte);
1735  if ((statusByte & 0xf8) == 0xf8 ||
1736  (statusByte == 0xa5)) {
1737  // No controller at this base address.
1738  KdPrint2((PRINT_PREFIX "Empty channel\n"));
1739  skip_find_dev = TRUE;
1740  }
1741  }
1742  }
1743 
1744  // Search for devices on this controller.
1745  if (!skip_find_dev &&
1746  FindDevices(HwDeviceExtension,
1747  0,
1748  c)) {
1749  KdPrint2((PRINT_PREFIX "Found some devices\n"));
1750  found = TRUE;
1751  } else {
1752  KdPrint2((PRINT_PREFIX "no devices\n"));
1753  /* KeBugCheckEx(0xc000000e,
1754  ScsiPortConvertPhysicalAddressToUlong(IoBasePort1),
1755  ScsiPortConvertPhysicalAddressToUlong(IoBasePort2),
1756  (ULONG)(deviceExtension->BaseIoAddressBM[c]), skip_find_dev);*/
1757  }
1758 //#ifdef UNIATA_INIT_ON_PROBE
1759 // }
1760 #else //UNIATA_INIT_ON_PROBE
1761  KdPrint2((PRINT_PREFIX "clean IDE intr 0\n"));
1762 
1763  SelectDrive(chan, 0);
1764  AtapiStallExecution(10);
1765  GetBaseStatus(chan, statusByte);
1766 
1767  if(!(deviceExtension->HwFlags & UNIATA_NO_SLAVE) && (deviceExtension->NumberLuns > 1)) {
1768  KdPrint2((PRINT_PREFIX "clean IDE intr 1\n"));
1769 
1770  SelectDrive(chan, 1);
1772  GetBaseStatus(chan, statusByte);
1773 
1774  SelectDrive(chan, 0);
1775  }
1776 
1777  statusByte = GetDmaStatus(deviceExtension, c);
1778  KdPrint2((PRINT_PREFIX " DMA status %#x\n", statusByte));
1779  if(statusByte & BM_STATUS_INTR) {
1780  // bullshit, we have DMA interrupt, but had never initiate DMA operation
1781  KdPrint2((PRINT_PREFIX " clear unexpected DMA intr\n"));
1782  AtapiDmaDone(deviceExtension, 0, c, NULL);
1783  GetBaseStatus(chan, statusByte);
1784  }
1785 
1786 #endif //UNIATA_INIT_ON_PROBE
1787  }
1788  found = TRUE;
1789 
1790  chan->PrimaryAddress = FALSE;
1791  // Claim primary or secondary ATA IO range.
1792  if (MasterDev) {
1793  KdPrint2((PRINT_PREFIX "claim Compatible controller\n"));
1794  if (channel == 0) {
1795  KdPrint2((PRINT_PREFIX "claim Primary\n"));
1797  ConfigInfo->AtdiskPrimaryClaimed = TRUE;
1798  chan->PrimaryAddress = TRUE;
1799 
1800  FirstMasterOk = TRUE;
1801 
1802  } else
1803  if (channel == 1) {
1804  KdPrint2((PRINT_PREFIX "claim Secondary\n"));
1806  ConfigInfo->AtdiskSecondaryClaimed = TRUE;
1807 
1808  FirstMasterOk = TRUE;
1809  }
1810  } else {
1811  if(chan->RegTranslation[IDX_IO1].Addr == IO_WD1 &&
1812  !chan->RegTranslation[IDX_IO1].MemIo) {
1813  KdPrint2((PRINT_PREFIX "claim Primary (PCI over ISA range)\n"));
1815  ConfigInfo->AtdiskPrimaryClaimed = TRUE;
1816  }
1817  if(chan->RegTranslation[IDX_IO1].Addr == IO_WD2 &&
1818  !chan->RegTranslation[IDX_IO1].MemIo) {
1819  KdPrint2((PRINT_PREFIX "claim Secondary (PCI over ISA range)\n"));
1821  ConfigInfo->AtdiskSecondaryClaimed = TRUE;
1822  }
1823  }
1824 
1825  AtapiDmaAlloc(HwDeviceExtension, ConfigInfo, c);
1826 #else //UNIATA_CORE
1827  }
1828  found = TRUE;
1829 #endif //UNIATA_CORE
1830  } // end for(channel)
1831 
1832 exit_findbm:
1833 
1834 #ifndef UNIATA_CORE
1835  if(!found) {
1836  KdPrint2((PRINT_PREFIX "exit: !found\n"));
1837  if(BaseIoAddress1[0])
1838  ScsiPortFreeDeviceBase(HwDeviceExtension,
1839  BaseIoAddress1[0]);
1840  if(BaseIoAddress2[0])
1841  ScsiPortFreeDeviceBase(HwDeviceExtension,
1842  BaseIoAddress2[0]);
1843 
1844  if(BaseIoAddress1[1])
1845  ScsiPortFreeDeviceBase(HwDeviceExtension,
1846  BaseIoAddress1[1]);
1847  if(BaseIoAddress2[1])
1848  ScsiPortFreeDeviceBase(HwDeviceExtension,
1849  BaseIoAddress2[1]);
1850 
1851  if(BaseIoAddressBM_0)
1852  ScsiPortFreeDeviceBase(HwDeviceExtension,
1853  BaseIoAddressBM_0);
1854 
1855  if(deviceExtension->BaseIoAHCI_0.Addr) {
1856  ScsiPortFreeDeviceBase(HwDeviceExtension,
1857  deviceExtension->BaseIoAHCI_0.pAddr);
1858  }
1859 
1860  KdPrint2((PRINT_PREFIX "return SP_RETURN_NOT_FOUND\n"));
1861  goto exit_notfound;
1862  } else {
1863 
1864  KdPrint2((PRINT_PREFIX "exit: init spinlock\n"));
1865  //KeInitializeSpinLock(&(deviceExtension->DpcSpinLock));
1866  deviceExtension->ActiveDpcChan =
1867  deviceExtension->FirstDpcChan = CHAN_NOT_SPECIFIED;
1868 
1869  BMList[i].Isr2Enable = FALSE;
1870 
1871  KdPrint2((PRINT_PREFIX "MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n",
1872  MasterDev, deviceExtension->NumberChannels, BMList[i].Isr2DevObj));
1873 
1874  // ConnectIntr2 should be moved to HwInitialize
1875  status = UniataConnectIntr2(HwDeviceExtension);
1876 
1877  KdPrint2((PRINT_PREFIX "MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n",
1878  MasterDev, deviceExtension->NumberChannels, BMList[i].Isr2DevObj));
1879 
1880  if(/*WinVer_WDM_Model &&*/ MasterDev) {
1881  KdPrint2((PRINT_PREFIX "do not tell system, that we know about PCI IO ranges\n"));
1882 /* if(BaseIoAddressBM_0) {
1883  ScsiPortFreeDeviceBase(HwDeviceExtension,
1884  BaseIoAddressBM_0);
1885  }*/
1886  (*ConfigInfo->AccessRanges)[4].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
1887  (*ConfigInfo->AccessRanges)[4].RangeLength = 0;
1888  (*ConfigInfo->AccessRanges)[5].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
1889  (*ConfigInfo->AccessRanges)[5].RangeLength = 0;
1890  }
1891 
1892  if(!NT_SUCCESS(status)) {
1893  KdPrint2((PRINT_PREFIX "failed\n"));
1894  found = FALSE;
1895  goto exit_findbm;
1896  }
1897 
1898  KdPrint2((PRINT_PREFIX "final chan[%d] InterruptMode: %d, Level %d, Level2 %d, Vector %d, Vector2 %d\n",
1899  channel,
1900  ConfigInfo->InterruptMode,
1901  ConfigInfo->BusInterruptLevel,
1902  ConfigInfo->BusInterruptLevel2,
1903  ConfigInfo->BusInterruptVector,
1904  ConfigInfo->BusInterruptVector2
1905  ));
1906 
1907 
1908  }
1909 #endif //UNIATA_CORE
1910 
1911  KdPrint2((PRINT_PREFIX "return SP_RETURN_FOUND\n"));
1912  //PrintNtConsole("return SP_RETURN_FOUND, de %#x, c0.lun0 %#x\n", deviceExtension, deviceExtension->chan[0].lun[0]);
1913 
1914  if(MasterDev) {
1915  KdPrint2((PRINT_PREFIX "Attempt %d of MasterDev ok\n", AltInit));
1916  FirstMasterOk = TRUE;
1917  }
1918 
1919  ConfigInfo->NumberOfBuses++; // add virtual channel for communication port
1920  return SP_RETURN_FOUND;
1921 
1922 exit_error:
1923  UniataFreeLunExt(deviceExtension);
1924  return SP_RETURN_ERROR;
1925 
1926 exit_notfound:
1927  UniataFreeLunExt(deviceExtension);
1928  return SP_RETURN_NOT_FOUND;
1929 
1930 } // end UniataFindBusMasterController()
1931 
1932 #ifndef UNIATA_CORE
1933 
1934 /*
1935  This is for claiming PCI Busmaster in compatible mode under WDM OSes
1936 */
1937 NTSTATUS
1938 NTAPI
1940  ULONG i
1941  )
1942 {
1943  NTSTATUS status;
1944  PCM_RESOURCE_LIST resourceList = NULL;
1945  UNICODE_STRING devname;
1946 
1947  KdPrint2((PRINT_PREFIX "UniataClaimLegacyPCIIDE:\n"));
1948 
1949  if(BMList[i].PciIdeDevObj) {
1950  KdPrint2((PRINT_PREFIX "Already initialized\n"));
1951  return STATUS_UNSUCCESSFUL;
1952  }
1953 
1954  RtlInitUnicodeString(&devname, L"\\Device\\uniata_PCIIDE");
1956  /*NULL*/ &devname, FILE_DEVICE_UNKNOWN,
1957  0, FALSE, &(BMList[i].PciIdeDevObj));
1958 
1959  if(!NT_SUCCESS(status)) {
1960  KdPrint2((PRINT_PREFIX "IoCreateDevice failed %#x\n", status));
1961  return status;
1962  }
1963 
1964  resourceList = (PCM_RESOURCE_LIST) ExAllocatePool(PagedPool,
1965  sizeof(CM_RESOURCE_LIST));
1966 
1967  if (!resourceList) {
1968  KdPrint2((PRINT_PREFIX "!resourceList\n"));
1970 del_do:
1971  IoDeleteDevice(BMList[i].PciIdeDevObj);
1973  return status;
1974  }
1975 
1976  RtlZeroMemory(
1977  resourceList,
1978  sizeof(CM_RESOURCE_LIST));
1979 
1980  // IoReportDetectedDevice() should be used for WDM OSes
1981 
1982  // TODO: check if resourceList is actually used inside HalAssignSlotResources()
1983  // Note: with empty resourceList call to HalAssignSlotResources() fails on some HW
1984  // e.g. Intel ICH4, but works with non-empty.
1985 
1986  resourceList->Count = 1;
1987  resourceList->List[0].InterfaceType = PCIBus;
1988  resourceList->List[0].BusNumber = BMList[i].busNumber;
1989  // we do not report IO ranges since they are used/claimed by ISA part(s)
1990  resourceList->List[0].PartialResourceList.Count = 0;
1991 
1992  RtlInitUnicodeString(&devname, L"PCIIDE");
1994  &devname,
1996  BMList[i].PciIdeDevObj,
1997  PCIBus,
1998  BMList[i].busNumber,
1999  BMList[i].slotNumber,
2000  &resourceList);
2001 
2002  if (!NT_SUCCESS(status)) {
2003  KdPrint2((PRINT_PREFIX "HalAssignSlotResources failed %#x\n", status));
2004  // this is always deallocated inside HalAssignSlotResources() implementation
2005  //ExFreePool(resourceList);
2006  goto del_do;
2007  }
2008 
2009  KdPrint2((PRINT_PREFIX "ok %#x\n", status));
2010  BMList[i].ChanInitOk |= 0x80;
2011 
2012  return status;
2013 } // end UniataClaimLegacyPCIIDE()
2014 
2015 
2016 /*++
2017 
2018 Routine Description:
2019 
2020  This function is called to initialize 2nd device object for
2021  multichannel controllers.
2022 
2023 Arguments:
2024 
2025  HwDeviceExtension - HBA miniport driver's adapter data storage
2026 
2027 Return Value:
2028 
2029  ULONG
2030 
2031 --*/
2032 NTSTATUS
2033 NTAPI
2035  IN PVOID HwDeviceExtension
2036  )
2037 {
2038  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2039  ULONG i = deviceExtension->DevIndex;
2040  NTSTATUS status;
2041  PISR2_DEVICE_EXTENSION Isr2DevExt;
2042  WCHAR devname_str[33];
2043  UNICODE_STRING devname;
2044 
2045  KdPrint2((PRINT_PREFIX "Init ISR:\n"));
2046 
2047  /*
2048  We MUST register 2nd ISR for multichannel controllers even for UP systems.
2049  This is needed for cases when
2050  multichannel controller generate interrupt while we are still in its ISR for
2051  other channle's interrupt. New interrupt must be detected and queued for
2052  further processing. If we do not do this, system will not route this
2053  interrupt to main ISR (since it is busy) and we shall get to infinite loop
2054  looking for interrupt handler.
2055  */
2056 
2057  if(!deviceExtension->MasterDev && (deviceExtension->NumberChannels > 1) && // do not touch MasterDev
2058  !deviceExtension->simplexOnly && /* // this is unnecessary on simplex controllers
2059  !BMList[i].Isr2DevObj*/ // handle re-init under w2k+
2061  /*(CPU_num > 1) && // unnecessary for UP systems*/
2062  TRUE) {
2063  // Ok, continue...
2064  KdPrint2((PRINT_PREFIX "Multichannel native mode, go...\n"));
2065 #ifndef UNIATA_USE_XXableInterrupts
2066  // If we raise IRQL to TIMER value, other interrupt cannot occure on the same CPU
2067 /* if(KeNumberProcessors < 2) {
2068  KdPrint2((PRINT_PREFIX "Unnecessary (?), UP machine\n"));
2069  //return STATUS_SUCCESS;
2070  }*/
2071 #endif //UNIATA_USE_XXableInterrupts
2072  } else {
2073  KdPrint2((PRINT_PREFIX "Unnecessary\n"));
2074  return STATUS_SUCCESS;
2075  }
2076 
2077  if(BMList[i].Isr2DevObj) {
2078  KdPrint2((PRINT_PREFIX "Already initialized [%d] %#x\n", i, BMList[i].Isr2DevObj));
2079  return STATUS_SUCCESS;
2080  }
2081 
2082  KdPrint2((PRINT_PREFIX "Create DO\n"));
2083 
2084  devname.Length =
2085  _snwprintf(devname_str, sizeof(devname_str)/sizeof(WCHAR)-1,
2086  L"\\Device\\uniata%d_2ch", i);
2087  devname_str[devname.Length] = 0;
2088  devname.Length *= sizeof(WCHAR);
2089  devname.MaximumLength = devname.Length;
2090  devname.Buffer = devname_str;
2091 
2092  KdPrint2((PRINT_PREFIX "DO name: len(%d, %d), %S\n", devname.Length, devname.MaximumLength, devname.Buffer));
2093 
2095  /*NULL*/ &devname, FILE_DEVICE_UNKNOWN,
2096  0, FALSE, &(BMList[i].Isr2DevObj));
2097 
2098  if(!NT_SUCCESS(status)) {
2099  KdPrint2((PRINT_PREFIX "IoCreateDevice failed %#x\n", status));
2100  return status;
2101  }
2102 
2103  KdPrint2((PRINT_PREFIX "HalGetInterruptVector\n"));
2104  KdPrint2((PRINT_PREFIX " OrigAdapterInterfaceType=%d\n", deviceExtension->OrigAdapterInterfaceType));
2105  KdPrint2((PRINT_PREFIX " SystemIoBusNumber=%d\n", deviceExtension->SystemIoBusNumber));
2106  KdPrint2((PRINT_PREFIX " BusInterruptLevel=%d\n", deviceExtension->BusInterruptLevel));
2107  KdPrint2((PRINT_PREFIX " BusInterruptVector=%d\n", deviceExtension->BusInterruptVector));
2109  deviceExtension->OrigAdapterInterfaceType,
2110  deviceExtension->SystemIoBusNumber,
2111  deviceExtension->BusInterruptLevel,
2112  deviceExtension->BusInterruptVector,
2113  &(BMList[i].Isr2Irql),
2114  &(BMList[i].Isr2Affinity));
2115 
2116  Isr2DevExt = (PISR2_DEVICE_EXTENSION)(BMList[i].Isr2DevObj->DeviceExtension);
2117  Isr2DevExt->HwDeviceExtension = deviceExtension;
2118  Isr2DevExt->DevIndex = i;
2119 
2120  KdPrint2((PRINT_PREFIX "isr2_de %#x\n", Isr2DevExt));
2121  KdPrint2((PRINT_PREFIX "isr2_vector %#x\n", BMList[i].Isr2Vector));
2122  KdPrint2((PRINT_PREFIX "isr2_irql %#x\n", BMList[i].Isr2Irql));
2123  KdPrint2((PRINT_PREFIX "isr2_affinity %#x\n", BMList[i].Isr2Affinity));
2124 
2125 // deviceExtension->QueueNewIrql = BMList[i].Isr2Irql;
2126 
2127  KdPrint2((PRINT_PREFIX "IoConnectInterrupt\n"));
2129  &(BMList[i].Isr2InterruptObject),
2131  Isr2DevExt,
2132  NULL,
2133  BMList[i].Isr2Vector,
2134  BMList[i].Isr2Irql,
2135  BMList[i].Isr2Irql,
2136  (KINTERRUPT_MODE)(deviceExtension->InterruptMode),
2137  TRUE,
2139  FALSE);
2140 
2141  if(!NT_SUCCESS(status)) {
2142  KdPrint2((PRINT_PREFIX "IoConnectInterrupt failed\n"));
2143  IoDeleteDevice(BMList[i].Isr2DevObj);
2144  BMList[i].Isr2DevObj = NULL;
2146  return status;
2147  }
2148 
2149  //deviceExtension->Isr2DevObj = BMList[i].Isr2DevObj;
2150 
2151  return status;
2152 } // end UniataConnectIntr2()
2153 
2154 NTSTATUS
2155 NTAPI
2157  IN PVOID HwDeviceExtension
2158  )
2159 {
2160  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2161  ULONG i = deviceExtension->DevIndex;
2162 // NTSTATUS status;
2163 
2164  KdPrint2((PRINT_PREFIX "Deinit ISR:\n"));
2165 
2166  if(!BMList[i].Isr2DevObj) {
2167  KdPrint2((PRINT_PREFIX "Already uninitialized %#x\n"));
2168  return STATUS_SUCCESS;
2169  }
2170 
2171  IoDisconnectInterrupt(BMList[i].Isr2InterruptObject);
2172 
2174 
2175  IoDeleteDevice(BMList[i].Isr2DevObj);
2176 
2177  BMList[i].Isr2DevObj = NULL;
2178  //deviceExtension->Isr2DevObj = NULL;
2179 
2180  return STATUS_SUCCESS;
2181 } // end UniataDisconnectIntr2()
2182 
2183 #endif //UNIATA_CORE
2184 
2185 BOOLEAN
2186 NTAPI
2189  ULONG portBase) {
2190  // check if Primary/Secondary Master IDE claimed
2191  if((portBase == IO_WD1) &&
2192  (ConfigInfo->AtdiskPrimaryClaimed || AtdiskPrimaryClaimed)) {
2193  KdPrint2((PRINT_PREFIX "AtapiCheckIOInterference: AtdiskPrimaryClaimed\n"));
2194  return TRUE;
2195  } else
2196  if((portBase == IO_WD2) &&
2197  (ConfigInfo->AtdiskSecondaryClaimed || AtdiskSecondaryClaimed)) {
2198  KdPrint2((PRINT_PREFIX "AtapiCheckIOInterference: AtdiskSecondaryClaimed\n"));
2199  return TRUE;
2200  }
2201  return FALSE;
2202 } // end AtapiCheckIOInterference()
2203 
2204 /*++
2205 
2206 Routine Description:
2207 
2208  This function is called by the OS-specific port driver after
2209  the necessary storage has been allocated, to gather information
2210  about the adapter's configuration.
2211 
2212 Arguments:
2213 
2214  HwDeviceExtension - HBA miniport driver's adapter data storage
2215  Context - Address of adapter count
2216  ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility.
2217  ConfigInfo - Configuration information structure describing HBA
2218  Again - Indicates search for adapters to continue
2219 
2220 Return Value:
2221 
2222  ULONG
2223 
2224 --*/
2225 ULONG
2226 NTAPI
2228  IN PVOID HwDeviceExtension,
2229  IN PVOID Context,
2230  IN PVOID BusInformation,
2231  IN PCHAR ArgumentString,
2233  OUT PBOOLEAN Again
2234  )
2235 {
2236  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2237  PHW_CHANNEL chan;
2238  PULONG adapterCount = (PULONG)Context;
2239  PUCHAR ioSpace = NULL;
2240  ULONG i;
2241  ULONG irq=0;
2242  ULONG portBase=0;
2243  ULONG retryCount;
2244 // BOOLEAN atapiOnly;
2245  UCHAR statusByte, statusByte2;
2246  BOOLEAN preConfig = FALSE;
2247  //
2248  PIDE_REGISTERS_1 BaseIoAddress1;
2249  PIDE_REGISTERS_2 BaseIoAddress2 = NULL;
2250 
2251  // The following table specifies the ports to be checked when searching for
2252  // an IDE controller. A zero entry terminates the search.
2253  static CONST ULONG AdapterAddresses[5] = {IO_WD1, IO_WD2, IO_WD1-8, IO_WD2-8, 0};
2254 // CONST UCHAR Channels[5] = {0, 1, 0, 1, 0};
2255 
2256  // The following table specifies interrupt levels corresponding to the
2257  // port addresses in the previous table.
2258  static CONST ULONG InterruptLevels[5] = {14, 15, 11, 10, 0};
2259 
2260  KdPrint2((PRINT_PREFIX "AtapiFindIsaController (ISA):\n"));
2261 
2262  if (!deviceExtension) {
2263  return SP_RETURN_ERROR;
2264  }
2265  RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION));
2266 
2267  KdPrint2((PRINT_PREFIX " assume max PIO4\n"));
2268  deviceExtension->MaxTransferMode = ATA_PIO4;
2269  deviceExtension->NumberChannels = 1;
2270  deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN; // default
2271 
2272  if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) {
2273  goto exit_error;
2274  }
2275 
2276  chan = &(deviceExtension->chan[0]);
2277  AtapiSetupLunPtrs(chan, deviceExtension, 0);
2278 
2279  deviceExtension->AdapterInterfaceType =
2280  deviceExtension->OrigAdapterInterfaceType
2281  = ConfigInfo->AdapterInterfaceType;
2282 
2283 #ifndef UNIATA_CORE
2284 
2285  /* do extra chipset specific setups */
2288 
2289  // Check to see if this is a special configuration environment.
2290  portBase = irq = 0;
2291  if (ArgumentString) {
2292 
2293  irq = AtapiParseArgumentString(ArgumentString, "Interrupt");
2294  if (irq ) {
2295 
2296  // Both parameters must be present to proceed
2297  portBase = AtapiParseArgumentString(ArgumentString, "BaseAddress");
2298  if (!portBase) {
2299 
2300  // Try a default search for the part.
2301  irq = 0;
2302  }
2303  }
2304  }
2305 
2306 #endif //UNIATA_CORE
2307 /*
2308  for(i=0; i<2; i++) {
2309  if((*ConfigInfo->AccessRanges)[i].RangeStart) {
2310  KdPrint2((PRINT_PREFIX " IoRange[%d], start %#x, len %#x, mem %#x\n",
2311  i,
2312  ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[i].RangeStart),
2313  (*ConfigInfo->AccessRanges)[i].RangeLength,
2314  (*ConfigInfo->AccessRanges)[i].RangeInMemory
2315  ));
2316  }
2317  }
2318 */
2319 // if((*ConfigInfo->AccessRanges)[0].RangeStart) {
2320  portBase = ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart);
2321 // }
2322  if(portBase) {
2323  if(!AtapiCheckIOInterference(ConfigInfo, portBase)) {
2324  ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2325  ConfigInfo->AdapterInterfaceType,
2326  ConfigInfo->SystemIoBusNumber,
2327  (*ConfigInfo->AccessRanges)[0].RangeStart,
2328  (*ConfigInfo->AccessRanges)[0].RangeLength,
2329  (BOOLEAN) !((*ConfigInfo->AccessRanges)[0].RangeInMemory));
2330  } else {
2331  // do not touch resources, just fail later inside loop on next call to
2332  // AtapiCheckIOInterference()
2333  }
2334  *Again = FALSE;
2335  // Since we have pre-configured information we only need to go through this loop once
2336  preConfig = TRUE;
2337  KdPrint2((PRINT_PREFIX " preconfig, portBase=%x, len=%x\n", portBase, (*ConfigInfo->AccessRanges)[0].RangeLength));
2338  }
2339 
2340  // Scan through the adapter address looking for adapters.
2341 #ifndef UNIATA_CORE
2342  while (AdapterAddresses[*adapterCount] != 0) {
2343 #else
2344  do {
2345 #endif //UNIATA_CORE
2346 
2347  retryCount = 4;
2348  deviceExtension->DevIndex = (*adapterCount); // this is used inside AtapiRegCheckDevValue()
2349  KdPrint2((PRINT_PREFIX "AtapiFindIsaController: adapterCount=%d\n", *adapterCount));
2350 
2351  for (i = 0; i < deviceExtension->NumberLuns; i++) {
2352  // Zero device fields to ensure that if earlier devices were found,
2353  // but not claimed, the fields are cleared.
2355  }
2356  // Get the system physical address for this IO range.
2357 
2358  // Check if configInfo has the default information
2359  // if not, we go and find ourselves
2360  if (preConfig == FALSE) {
2361 
2362  ULONG portBase_reg = 0;
2363  ULONG irq_reg = 0;
2364 
2365  if (!portBase) {
2366  portBase = AdapterAddresses[*adapterCount];
2367  KdPrint2((PRINT_PREFIX "portBase[%d]=%x\n", *adapterCount, portBase));
2368  } else {
2369  KdPrint2((PRINT_PREFIX "portBase=%x\n", portBase));
2370  }
2371 
2372  portBase_reg = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PortBase", 0);
2373  irq_reg = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Irq", 0);
2374  if(portBase_reg && irq_reg) {
2375  KdPrint2((PRINT_PREFIX "use registry settings portBase=%x, irq=%d\n", portBase_reg, irq_reg));
2376  portBase = portBase_reg;
2377  irq = irq_reg;
2378  }
2379  // check if Primary/Secondary Master IDE claimed
2380  if(AtapiCheckIOInterference(ConfigInfo, portBase)) {
2381  goto next_adapter;
2382  }
2383  ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2384  ConfigInfo->AdapterInterfaceType,
2385  ConfigInfo->SystemIoBusNumber,
2387  ATA_IOSIZE,
2388  TRUE);
2389 
2390  } else {
2391  KdPrint2((PRINT_PREFIX "preconfig portBase=%x\n", portBase));
2392  // Check if Primary/Secondary Master IDE claimed
2393  // We can also get here from preConfig branc with conflicting portBase
2394  // (and thus, w/o ioSpace allocated)
2395  if(AtapiCheckIOInterference(ConfigInfo, portBase)) {
2396  goto not_found;
2397  }
2398  }
2399  BaseIoAddress1 = (PIDE_REGISTERS_1)ioSpace;
2400 next_adapter:
2401  // Update the adapter count.
2402  (*adapterCount)++;
2403 
2404  // Check if ioSpace accessible.
2405  if (!ioSpace) {
2406  KdPrint2((PRINT_PREFIX "AtapiFindIsaController: !ioSpace\n"));
2407  portBase = 0;
2408  continue;
2409  }
2410 
2411  // Get the system physical address for the second IO range.
2412  if (BaseIoAddress1) {
2413  if(preConfig &&
2414  !ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[1].RangeStart)) {
2415  KdPrint2((PRINT_PREFIX "AtapiFindIsaController: PCMCIA ?\n"));
2416  ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2417  ConfigInfo->AdapterInterfaceType,
2418  ConfigInfo->SystemIoBusNumber,
2419  ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR)BaseIoAddress1 + 0x0E),
2420  ATA_ALTIOSIZE,
2421  TRUE);
2422  } else {
2423  ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2424  ConfigInfo->AdapterInterfaceType,
2425  ConfigInfo->SystemIoBusNumber,
2427  ATA_ALTIOSIZE,
2428  TRUE);
2429  }
2430  }
2431  BaseIoAddress2 = (PIDE_REGISTERS_2)ioSpace;
2432  KdPrint2((PRINT_PREFIX " BaseIoAddress1=%x\n", BaseIoAddress1));
2433  KdPrint2((PRINT_PREFIX " BaseIoAddress2=%x\n", BaseIoAddress2));
2434  if(!irq) {
2435  KdPrint2((PRINT_PREFIX " expected InterruptLevel=%x\n", InterruptLevels[*adapterCount - 1]));
2436  }
2437 
2438  UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2);
2439  UniataInitMapBM(deviceExtension, 0, FALSE);
2440 
2441 #ifdef _DEBUG
2442  UniataDumpATARegs(chan);
2443 #endif
2444 
2445  // Select master.
2446  SelectDrive(chan, 0);
2447 
2448  statusByte = AtapiReadPort1(chan, IDX_IO1_i_Status);
2449  statusByte2 = AtapiReadPort1(chan, IDX_IO2_AltStatus);
2450  if((statusByte ^ statusByte2) & ~IDE_STATUS_INDEX) {
2451  KdPrint2((PRINT_PREFIX "AtapiFindIsaController: Status %x vs AltStatus %x missmatch, abort init ?\n", statusByte, statusByte2));
2452 
2453  if(BaseIoAddress2) {
2454  ScsiPortFreeDeviceBase(HwDeviceExtension,
2455  (PCHAR)BaseIoAddress2);
2456  BaseIoAddress2 = NULL;
2457  }
2458  BaseIoAddress2 = (PIDE_REGISTERS_2)((ULONGIO_PTR)BaseIoAddress1 + 0x0E);
2459  KdPrint2((PRINT_PREFIX " try BaseIoAddress2=%x\n", BaseIoAddress2));
2460  ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2461  ConfigInfo->AdapterInterfaceType,
2462  ConfigInfo->SystemIoBusNumber,
2464  ATA_ALTIOSIZE,
2465  TRUE);
2466  if(!ioSpace) {
2467  BaseIoAddress2 = NULL;
2468  KdPrint2((PRINT_PREFIX " abort (0)\n"));
2469  goto not_found;
2470  }
2471  UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2);
2472  statusByte = AtapiReadPort1(chan, IDX_IO1_i_Status);
2473  statusByte2 = AtapiReadPort1(chan, IDX_IO2_AltStatus);
2474  if((statusByte ^ statusByte2) & ~IDE_STATUS_INDEX) {
2475  KdPrint2((PRINT_PREFIX " abort: Status %x vs AltStatus %x missmatch\n", statusByte, statusByte2));
2476  goto not_found;
2477  }
2478  }
2479 
2480 retryIdentifier:
2481 
2482  // Select master.
2483  SelectDrive(chan, 0);
2484 
2485  // Check if card at this address.
2487  statusByte = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
2488 
2489  // Check if indentifier can be read back.
2490  if (AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) != 0xAA ||
2491  statusByte == IDE_STATUS_WRONG) {
2492 
2493  KdPrint2((PRINT_PREFIX "AtapiFindIsaController: Identifier read back from Master (%#x)\n",
2494  statusByte));
2495 
2496  statusByte = AtapiReadPort1(chan, IDX_IO2_AltStatus);
2497 
2498  if (statusByte != IDE_STATUS_WRONG && (statusByte & IDE_STATUS_BUSY)) {
2499 
2500  i = 0;
2501 
2502  // Could be the TEAC in a thinkpad. Their dos driver puts it in a sleep-mode that
2503  // warm boots don't clear.
2504  do {
2505  AtapiStallExecution(1000);
2506  statusByte = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_Status);
2508  "AtapiFindIsaController: First access to status %#x\n",
2509  statusByte));
2510  } while ((statusByte & IDE_STATUS_BUSY) && ++i < 10);
2511 
2512  if (retryCount-- && (!(statusByte & IDE_STATUS_BUSY))) {
2513  goto retryIdentifier;
2514  }
2515  }
2516 
2517  // Select slave.
2518  SelectDrive(chan, 1);
2519  statusByte = AtapiReadPort1(chan, IDX_IO2_AltStatus);
2520 
2521  // See if slave is present.
2523 
2524  if (AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) != 0xAA ||
2525  statusByte == IDE_STATUS_WRONG) {
2526 
2528  "AtapiFindIsaController: Identifier read back from Slave (%#x)\n",
2529  statusByte));
2530  goto not_found;
2531  }
2532  }
2533 
2534  // Fill in the access array information only if default params are not in there.
2535  if (preConfig == FALSE) {
2536 
2537  // An adapter has been found request another call, only if we didn't get preconfigured info.
2538  *Again = TRUE;
2539 
2540  if (portBase) {
2541  (*ConfigInfo->AccessRanges)[0].RangeStart = ScsiPortConvertUlongToPhysicalAddress(portBase);
2542  } else {
2543  (*ConfigInfo->AccessRanges)[0].RangeStart =
2544  ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount - 1]);
2545  }
2546 
2547  (*ConfigInfo->AccessRanges)[0].RangeLength = ATA_IOSIZE;
2548  (*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE;
2549 
2550  if(BaseIoAddress2) {
2551  if(hasPCI) {
2552  (*ConfigInfo->AccessRanges)[1].RangeStart = ScsiPortConvertUlongToPhysicalAddress((ULONG_PTR)BaseIoAddress2);
2553  (*ConfigInfo->AccessRanges)[1].RangeLength = ATA_ALTIOSIZE;
2554  (*ConfigInfo->AccessRanges)[1].RangeInMemory = FALSE;
2555  } else {
2556  // NT4 and NT3.51 on ISA-only hardware definitly fail floppy.sys load
2557  // when this range is claimed by other driver.
2558  // However, floppy should use only 0x3f0-3f5,3f7
2559  if((ULONGIO_PTR)BaseIoAddress2 >= 0x3f0 && (ULONGIO_PTR)BaseIoAddress2 <= 0x3f7) {
2560  KdPrint2((PRINT_PREFIX "!!! Possible AltStatus vs Floppy IO range interference !!!\n"));
2561  }
2562  KdPrint2((PRINT_PREFIX "Do not expose to OS on old ISA\n"));
2563  (*ConfigInfo->AccessRanges)[1].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
2564  (*ConfigInfo->AccessRanges)[1].RangeLength = 0;
2565  }
2566  }
2567 
2568  // Indicate the interrupt level corresponding to this IO range.
2569  if (irq) {
2570  ConfigInfo->BusInterruptLevel = irq;
2571  } else {
2572  ConfigInfo->BusInterruptLevel = InterruptLevels[*adapterCount - 1];
2573  }
2574 
2575  if (ConfigInfo->AdapterInterfaceType == MicroChannel) {
2576  ConfigInfo->InterruptMode = LevelSensitive;
2577  } else {
2578  ConfigInfo->InterruptMode = Latched;
2579  }
2580  }
2581 
2582  ConfigInfo->NumberOfBuses = 1;
2583  ConfigInfo->MaximumNumberOfTargets = IDE_MAX_LUN_PER_CHAN;
2584 
2585  // Indicate maximum transfer length is 64k.
2586  ConfigInfo->MaximumTransferLength = 0x10000;
2587  deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
2588 
2589  KdPrint2((PRINT_PREFIX "de %#x, Channel ???\n", deviceExtension));
2590  //PrintNtConsole("de %#x, Channel %#x, nchan %#x\n",deviceExtension, channel, deviceExtension->NumberChannels);
2591 
2592  KdPrint2((PRINT_PREFIX "chan = %#x\n", chan));
2593  //PrintNtConsole("chan = %#x, c=%#x\n", chan, c);
2594 /*
2595  // should be already set up in AtapiSetupLunPtrs(chan, deviceExtension, 0);
2596 
2597  chan->DeviceExtension = deviceExtension;
2598  chan->lChannel = 0;
2599  chan->lun[0] = &(deviceExtension->lun[0]);
2600  chan->lun[1] = &(deviceExtension->lun[1]);*/
2601 
2602  /* do extra channel-specific setups */
2603  AtapiReadChipConfig(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, 0);
2604  AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, 0);
2605 
2607  "AtapiFindIsaController: Found IDE at %#x\n",
2608  BaseIoAddress1));
2609 
2610  // For Daytona, the atdisk driver gets the first shot at the
2611  // primary and secondary controllers.
2612  if (preConfig == FALSE) {
2613 
2614  if (*adapterCount - 1 < 2) {
2615 
2616  // Determine whether this driver is being initialized by the
2617  // system or as a crash dump driver.
2618  if (g_Dump) {
2619 #ifndef UNIATA_CORE
2620  deviceExtension->DriverMustPoll = TRUE;
2621 #endif //UNIATA_CORE
2622  } else {
2623  deviceExtension->DriverMustPoll = FALSE;
2624  }
2625 
2626  } else {
2627  //atapiOnly = FALSE;
2628  }
2629 
2630  } else {
2631 
2632  //atapiOnly = FALSE;
2633  deviceExtension->DriverMustPoll = FALSE;
2634 
2635  }// preConfig check
2636 
2637  // Save the Interrupe Mode for later use
2638  deviceExtension->InterruptMode = ConfigInfo->InterruptMode;
2639  deviceExtension->BusInterruptLevel = ConfigInfo->BusInterruptLevel;
2640  deviceExtension->BusInterruptVector = ConfigInfo->BusInterruptVector;
2641 
2643  "AtapiFindIsaController: look for devices\n"));
2644  // Search for devices on this controller.
2645  if (FindDevices(HwDeviceExtension,
2646  0,
2647  0 /* Channel */)) {
2648 
2650  "AtapiFindIsaController: detected\n"));
2651  // Claim primary or secondary ATA IO range.
2652  if (portBase) {
2653  switch (portBase) {
2654  case IO_WD2:
2655  ConfigInfo->AtdiskSecondaryClaimed = TRUE;
2656  chan->PrimaryAddress = FALSE;
2657  break;
2658  case IO_WD1:
2659  ConfigInfo->AtdiskPrimaryClaimed = TRUE;
2660  chan->PrimaryAddress = TRUE;
2661  break;
2662  default:
2663  break;
2664  }
2665  } else {
2666  if (*adapterCount == 1) {
2667  ConfigInfo->AtdiskPrimaryClaimed = TRUE;
2668  chan->PrimaryAddress = TRUE;
2669  } else if (*adapterCount == 2) {
2670  ConfigInfo->AtdiskSecondaryClaimed = TRUE;
2671  chan->PrimaryAddress = FALSE;
2672  }
2673  }
2674 
2675  if(deviceExtension->AdapterInterfaceType == Isa) {
2676  IsaCount++;
2677  } else
2678  if(deviceExtension->AdapterInterfaceType == MicroChannel) {
2679  MCACount++;
2680  }
2681 
2682  ConfigInfo->NumberOfBuses++; // add virtual channel for communication port
2684  "AtapiFindIsaController: return SP_RETURN_FOUND\n"));
2685  return(SP_RETURN_FOUND);
2686  } else {
2687 not_found:
2688  // No controller at this base address.
2689  if(BaseIoAddress1) {
2690  ScsiPortFreeDeviceBase(HwDeviceExtension,
2691  (PCHAR)BaseIoAddress1);
2692  BaseIoAddress1 = NULL;
2693  }
2694  if(BaseIoAddress2) {
2695  ScsiPortFreeDeviceBase(HwDeviceExtension,
2696  (PCHAR)BaseIoAddress2);
2697  BaseIoAddress2 = NULL;
2698  }
2699  for(i=0; i<2; i++) {
2701  "AtapiFindIsaController: cleanup AccessRanges %d\n", i));
2702  (*ConfigInfo->AccessRanges)[i].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
2703  (*ConfigInfo->AccessRanges)[i].RangeLength = 0;
2704  (*ConfigInfo->AccessRanges)[i].RangeInMemory = FALSE;
2705  }
2706  irq = 0;
2707  portBase = 0;
2708  }
2709 #ifndef UNIATA_CORE
2710  }
2711 #else
2712  } while(FALSE);
2713 #endif //UNIATA_CORE
2714 
2715  // The entire table has been searched and no adapters have been found.
2716  // There is no need to call again and the device base can now be freed.
2717  // Clear the adapter count for the next bus.
2718  *Again = FALSE;
2719  *(adapterCount) = 0;
2720 
2722  "AtapiFindIsaController: return SP_RETURN_NOT_FOUND\n"));
2723  UniataFreeLunExt(deviceExtension);
2724  return(SP_RETURN_NOT_FOUND);
2725 
2726 exit_error:
2727  UniataFreeLunExt(deviceExtension);
2728  return SP_RETURN_ERROR;
2729 
2730 } // end AtapiFindIsaController()
2731 
2732 /*
2733  Do nothing, but parse ScsiPort ArgumentString and setup global variables.
2734 */
2735 
2736 ULONG
2737 NTAPI
2739  IN PVOID HwDeviceExtension,
2740  IN PVOID Context,
2741  IN PVOID BusInformation,
2742  IN PCHAR ArgumentString,
2744  OUT PBOOLEAN Again
2745  )
2746 {
2747 #ifndef __REACTOS__
2748  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2749 #endif
2750 
2751  if (AtapiParseArgumentString(ArgumentString, "dump") == 1) {
2753  "AtapiReadArgumentString: Crash dump\n"));
2754  //atapiOnly = FALSE;
2755  g_Dump = TRUE;
2756  }
2757  return(SP_RETURN_NOT_FOUND);
2758 } // end AtapiReadArgumentString()
2759 
2760 ULONG
2761 NTAPI
2763  IN PVOID HwDeviceExtension,
2764  IN ULONG lChannel,
2765  IN ULONG deviceNumber
2766  )
2767 {
2768  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2769  PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
2770  //ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0);
2771  PHW_LU_EXTENSION LunExt = chan->lun[deviceNumber];
2772 
2773  SATA_SSTATUS_REG SStatus;
2774  UCHAR signatureLow;
2775  UCHAR signatureHigh;
2776 
2777  if(LunExt->DeviceFlags & DFLAGS_HIDDEN) {
2778  KdPrint2((PRINT_PREFIX " hidden\n"));
2779  UniataForgetDevice(LunExt);
2780  return ATA_AT_HOME_NOBODY;
2781  }
2782  if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
2783 
2784  SStatus.Reg = UniataSataReadPort4(chan, IDX_SATA_SStatus, deviceNumber);
2785  KdPrint2((PRINT_PREFIX "SStatus %x\n", SStatus.Reg));
2786  if(SStatus.DET <= SStatus_DET_Dev_NoPhy) {
2787  KdPrint2((PRINT_PREFIX " SATA DET <= SStatus_DET_Dev_NoPhy\n"));
2788  return ATA_AT_HOME_NOBODY;
2789  }
2790  if(SStatus.SPD < SStatus_SPD_Gen1) {
2791  KdPrint2((PRINT_PREFIX " SATA SPD < SStatus_SPD_Gen1\n"));
2792  return ATA_AT_HOME_NOBODY;
2793  }
2794  if(SStatus.IPM == SStatus_IPM_NoDev) {
2795  KdPrint2((PRINT_PREFIX " SATA IPN == SStatus_IPM_NoDev\n"));
2796  return ATA_AT_HOME_NOBODY;
2797  }
2798  if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
2799  // Select the device for legacy.
2800  goto legacy_select;
2801  }
2802 
2803  } else {
2804 legacy_select:
2805  // Select the device.
2806  SelectDrive(chan, deviceNumber);
2808  }
2809 
2810  if((deviceExtension->HwFlags & UNIATA_AHCI) &&
2811  UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
2812  KdPrint2((PRINT_PREFIX " AHCI check\n"));
2814  signatureLow = (UCHAR)(SIG >> 16);
2815  signatureHigh = (UCHAR)(SIG >> 24);
2816  } else {
2817  signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
2818  signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
2819  }
2820 
2821  if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) {
2822  KdPrint2((PRINT_PREFIX " ATAPI at home\n"));
2823  return ATA_AT_HOME_ATAPI;
2824  }
2825  if(deviceExtension->HwFlags & UNIATA_AHCI) {
2826  KdPrint2((PRINT_PREFIX " AHCI HDD at home\n"));
2827  return ATA_AT_HOME_HDD;
2828  }
2829  if(g_opt_VirtualMachine > VM_NONE /*== VM_BOCHS ||
2830  g_opt_VirtualMachine == VM_VBOX*/) {
2831  GetStatus(chan, signatureLow);
2832  if(!signatureLow) {
2833  KdPrint2((PRINT_PREFIX " 0-status VM - not present\n"));
2834  UniataForgetDevice(LunExt);
2835  return ATA_AT_HOME_NOBODY;
2836  }
2837  }
2838 
2839  AtapiStallExecution(10);
2840 
2844  signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber);
2845  if(signatureLow != 0x55) {
2846  if(signatureLow == 0xff || signatureLow == 0) {
2847  KdPrint2((PRINT_PREFIX " nobody home! %#x != 0x55\n", signatureLow));
2848  UniataForgetDevice(LunExt);
2849  return ATA_AT_HOME_NOBODY;
2850  }
2851  // another chance
2852  signatureLow = AtapiReadPort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh);
2853  signatureLow += 2;
2854  AtapiWritePort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh, signatureLow);
2856  signatureHigh = AtapiReadPort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh);
2857  if(signatureLow != signatureHigh) {
2858  KdPrint2((PRINT_PREFIX " nobody home! last chance failed %#x != %#x\n", signatureLow, signatureHigh));
2859  UniataForgetDevice(LunExt);
2860  return ATA_AT_HOME_NOBODY;
2861  }
2862  return ATA_AT_HOME_XXX;
2863  }
2864 
2868  signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber);
2869  if(signatureLow != 0xAA) {
2870  KdPrint2((PRINT_PREFIX " nobody home! %#x != 0xAA\n", signatureLow));
2871  UniataForgetDevice(LunExt);
2872  return ATA_AT_HOME_NOBODY;
2873  }
2874 
2875  KdPrint2((PRINT_PREFIX " HDD at home\n"));
2876  return ATA_AT_HOME_HDD;
2877 } // end UniataAnybodyHome()
2878 
2879 ULONG
2880 NTAPI
2882  IN PVOID HwDeviceExtension,
2883  IN ULONG lChannel,
2884  IN ULONG deviceNumber,
2885  IN BOOLEAN ResetDev
2886  )
2887 {
2888  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2889  PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
2890  //ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0);
2891  PHW_LU_EXTENSION LunExt;
2892 
2893  UCHAR signatureLow,
2894  signatureHigh;
2895  UCHAR statusByte;
2896  ULONG RetVal=0;
2897  ULONG waitCount = g_opt_WaitBusyResetCount;
2898  ULONG at_home = 0;
2899 
2900  KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x\n",
2901  deviceNumber));
2902 
2903  if(deviceNumber >= chan->NumberLuns) {
2904  return 0;
2905  }
2906  if(deviceExtension->HwFlags & UNIATA_AHCI) {
2907  if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
2908  return 0;
2909  }
2910  }
2911  LunExt = chan->lun[deviceNumber];
2912 
2913  if(ResetDev) {
2914  LunExt->PowerState = 0;
2915  }
2916 
2917  if((deviceExtension->HwFlags & UNIATA_SATA) &&
2918  !UniataIsSATARangeAvailable(deviceExtension, lChannel) &&
2919  deviceNumber) {
2920  KdPrint2((PRINT_PREFIX " SATA w/o i/o registers, check slave presence\n"));
2921  SelectDrive(chan, deviceNumber & 0x01);
2922  statusByte = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_DriveSelect);
2923  KdPrint2((PRINT_PREFIX " DriveSelect: %#x\n", statusByte));
2924  if((statusByte & IDE_DRIVE_MASK) != IDE_DRIVE_SELECT_2) {
2925  KdPrint2((PRINT_PREFIX "CheckDevice: (no dev)\n"));
2926  UniataForgetDevice(LunExt);
2927  return 0;
2928  }
2929  }
2930 
2931  if(ResetDev && (deviceExtension->HwFlags & UNIATA_AHCI)) {
2932  KdPrint2((PRINT_PREFIX "CheckDevice: reset AHCI dev\n"));
2933  if(UniataAhciSoftReset(HwDeviceExtension, chan->lChannel, deviceNumber) == (ULONG)(-1)) {
2934  KdPrint2((PRINT_PREFIX "CheckDevice: (no dev)\n"));
2935  UniataForgetDevice(LunExt);
2936  return 0;
2937  }
2938  } else
2939  if(ResetDev) {
2940  KdPrint2((PRINT_PREFIX "CheckDevice: reset dev\n"));
2941 
2942  // Reset device
2943  AtapiSoftReset(chan, deviceNumber);
2944 
2945  if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
2946  //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 1\n"));
2947  return 0;
2948  }
2949  statusByte = WaitOnBusy(chan);
2950 
2951  if((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) {
2953  "CheckDevice: bad status %x\n", statusByte));
2954  } else
2955  if(statusByte != IDE_STATUS_WRONG && (statusByte & IDE_STATUS_BUSY)) {
2956  // Perform hard-reset.
2958  "CheckDevice: BUSY\n"));
2959 
2960  AtapiHardReset(chan, FALSE, 500 * 1000);
2961 /*
2962  AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER );
2963  chan->last_devsel = -1;
2964  AtapiStallExecution(500 * 1000);
2965  AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER);
2966 */
2967  SelectDrive(chan, deviceNumber & 0x01);
2968 
2969  do {
2970  // Wait for Busy to drop.
2971  AtapiStallExecution(100);
2972  GetStatus(chan, statusByte);
2973 
2974  } while ((statusByte & IDE_STATUS_BUSY) && waitCount--);
2975 
2976  GetBaseStatus(chan, statusByte);
2978  "CheckDevice: status after hard reset %x\n", statusByte));
2979  }
2980 
2981  if((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) {
2983  "CheckDevice: no dev ?\n"));
2984  UniataForgetDevice(LunExt);
2985  return 0;
2986  } else
2987  if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
2988  //if(deviceExtension->HwFlags & UNIATA_SATA) {
2990  "CheckDevice: try enable SATA Phy\n"));
2991  statusByte = UniataSataPhyEnable(HwDeviceExtension, lChannel, deviceNumber);
2992  if(statusByte == IDE_STATUS_WRONG) {
2993  KdPrint2((PRINT_PREFIX "CheckDevice: status %#x (no dev)\n", statusByte));
2994  UniataForgetDevice(LunExt);
2995  return 0;
2996  }
2997  }
2998  }
2999 
3000  if(deviceExtension->HwFlags & UNIATA_AHCI) {
3001  RetVal = LunExt->DeviceFlags;
3002  signatureLow = signatureHigh = 0; // make GCC happy
3003  } else {
3004  // Select the device.
3005  SelectDrive(chan, deviceNumber);
3006 
3007  if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
3008  //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 2\n"));
3009  return 0;
3010  }
3011 
3012  statusByte = WaitOnBaseBusyLong(chan);
3013 
3014  GetBaseStatus(chan, statusByte);
3015  if(deviceExtension->HwFlags & UNIATA_SATA) {
3016  UniataSataClearErr(HwDeviceExtension, lChannel, UNIATA_SATA_IGNORE_CONNECT, deviceNumber);
3017  }
3018 
3019  KdPrint2((PRINT_PREFIX "CheckDevice: status %#x\n", statusByte));
3020  if(((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) ||
3021  (statusByte & IDE_STATUS_BUSY)) {
3022  KdPrint2((PRINT_PREFIX "CheckDevice: busy => return\n"));
3023  UniataForgetDevice(LunExt);
3024  return 0;
3025  }
3026 
3027  signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
3028  signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
3029  }
3030 
3031  // set default costs
3035  LunExt->AtapiReadyWaitDelay = 0;
3036 
3037  if(deviceExtension->HwFlags & UNIATA_AHCI) {
3038  if(RetVal & DFLAGS_DEVICE_PRESENT) {
3039  if(IssueIdentify(HwDeviceExtension,
3040  deviceNumber,
3041  lChannel,
3043  FALSE)) {
3044  // OK
3045  KdPrint2((PRINT_PREFIX "CheckDevice: detected AHCI Device %#x\n",
3046  deviceNumber));
3047  } else {
3048  //RetVal &= ~DFLAGS_ATAPI_DEVICE;
3049  //LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE;
3050 
3051  UniataForgetDevice(LunExt);
3052  RetVal = 0;
3053  }
3054  }
3055  } else
3056  if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) {
3057 
3058  KdPrint2((PRINT_PREFIX "CheckDevice: ATAPI signature found\n"));
3059  // ATAPI signature found.
3060  // Issue the ATAPI identify command if this
3061  // is not for the crash dump utility.
3062 try_atapi:
3063  if (!g_Dump) {
3064 
3065  // Issue ATAPI packet identify command.
3066  if (IssueIdentify(HwDeviceExtension,
3067  deviceNumber,
3068  lChannel,
3070 
3071  // Indicate ATAPI device.
3072  KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x is ATAPI\n",
3073  deviceNumber));
3074 
3077 
3078  // some ATAPI devices doesn't work with DPC on CMD-649
3079  // and probably some other controllers
3080  if(deviceExtension->HwFlags & UNIATA_NO_DPC_ATAPI) {
3081  /* CMD 649, ROSB SWK33, ICH4 */
3082  KdPrint2((PRINT_PREFIX "CheckDevice: UNIATA_NO_DPC_ATAPI\n"));
3083  deviceExtension->UseDpc = FALSE;
3084  }
3085 
3086  GetStatus(chan, statusByte);
3087  if (statusByte & IDE_STATUS_ERROR) {
3088  AtapiSoftReset(chan, deviceNumber);
3089  }
3090 
3091  } else {
3092 forget_device:
3093  // Indicate no working device.
3094  KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x not responding\n",
3095  deviceNumber));
3096 
3097  UniataForgetDevice(LunExt);
3098  RetVal = 0;
3099  }
3100  GetBaseStatus(chan, statusByte);
3101 
3102  }
3103 
3104  } else {
3105 
3106  KdPrint2((PRINT_PREFIX "CheckDevice: IDE device check\n"));
3107  // Issue IDE Identify. If an Atapi device is actually present, the signature
3108  // will be asserted, and the drive will be recognized as such.
3109  if(deviceExtension->DWordIO) {
3110  KdPrint2((PRINT_PREFIX " try 32bit IO\n"));
3112  }
3113  if (IssueIdentify(HwDeviceExtension,
3114  deviceNumber,
3115  lChannel,
3117 
3118  // IDE drive found.
3119  KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x is IDE\n",
3120  deviceNumber));
3121 
3122  // Indicate IDE - not ATAPI device.
3123  RetVal = DFLAGS_DEVICE_PRESENT;
3125  LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE;
3126  } else
3127  if(g_opt_VirtualMachine <= VM_NONE) {
3128  // This can be ATAPI on broken hardware
3129  GetBaseStatus(chan, statusByte);
3130  if(!at_home && UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) {
3131  KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home post IDE\n"));
3132  goto forget_device;
3133  }
3134  KdPrint2((PRINT_PREFIX "CheckDevice: try ATAPI %#x, status %#x\n",
3135  deviceNumber, statusByte));
3136  goto try_atapi;
3137  } else {
3138  KdPrint2((PRINT_PREFIX "CheckDevice: VM Device %#x not present\n",
3139  deviceNumber));
3140  }
3141  GetBaseStatus(chan, statusByte);
3142  }
3143  KdPrint2((PRINT_PREFIX "CheckDevice: check status: %sfound\n", RetVal ? "" : "not "));
3144  return RetVal;
3145 } // end CheckDevice()
3146 
3147 
3148 /*++
3149 
3150 Routine Description:
3151 
3152  This routine is called from AtapiFindXxxController to identify
3153  devices attached to an IDE controller.
3154 
3155 Arguments:
3156 
3157  HwDeviceExtension - HBA miniport driver's adapter data storage
3158  AtapiOnly - Indicates that routine should return TRUE only if
3159  an ATAPI device is attached to the controller.
3160 
3161 Return Value:
3162 
3163  TRUE - True if devices found.
3164 
3165 --*/
3166 BOOLEAN
3167 NTAPI
3169  IN PVOID HwDeviceExtension,
3170  IN ULONG Flags,
3171  IN ULONG Channel
3172  )
3173 {
3174  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
3175  PHW_CHANNEL chan = &(deviceExtension->chan[Channel]);
3176  PHW_LU_EXTENSION LunExt;
3177  BOOLEAN deviceResponded = FALSE,
3178  skipSetParameters = FALSE;
3179  ULONG waitCount = 10000;
3180  //ULONG deviceNumber;
3181  ULONG i;
3182  UCHAR statusByte;
3183  ULONG max_ldev;
3184  BOOLEAN AtapiOnly = FALSE;
3185 
3186  KdPrint2((PRINT_PREFIX "FindDevices:\n"));
3187 
3188  // Disable interrupts
3189  AtapiDisableInterrupts(deviceExtension, Channel);
3190 // AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_DISABLE_INTERRUPTS | IDE_DC_A_4BIT );
3191 
3192  // Clear expecting interrupt flag and current SRB field.
3194 // chan->CurrentSrb = NULL;
3195 // max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : IDE_MAX_LUN_PER_CHAN;
3196  max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : deviceExtension->NumberLuns;
3197  KdPrint2((PRINT_PREFIX " max_ldev %d\n", max_ldev));
3198 
3199  // Search for devices.
3200  for (i = 0; i < max_ldev; i++) {
3201  //AtapiDisableInterrupts(deviceExtension, Channel);
3203  chan->lun[i]->DeviceFlags &= ~DFLAGS_HIDDEN;
3204  }
3205  deviceResponded |=
3206  (CheckDevice(HwDeviceExtension, Channel, i, TRUE) != 0);
3207  //AtapiEnableInterrupts(deviceExtension, Channel);
3208  }
3209 
3210  if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
3211  AtapiEnableInterrupts(deviceExtension, Channel);
3213  "FindDevices: returning %d (AHCI)\n",
3214  deviceResponded));
3215  return deviceResponded;
3216  }
3217 
3218  for (i = 0; i < max_ldev; i++) {
3219  LunExt = chan->lun[i];
3220 
3221  if (( LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT) &&
3222  !(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) &&
3223  !(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) && deviceResponded) {
3224 
3225  // This hideous hack is to deal with ESDI devices that return
3226  // garbage geometry in the IDENTIFY data.
3227  // This is ONLY for the crashdump environment as
3228  // these are ESDI devices.
3229  if (LunExt->IdentifyData.SectorsPerTrack == 0x35 &&
3230  LunExt->IdentifyData.NumberOfHeads == 0x07) {
3231 
3232  KdPrint2((PRINT_PREFIX "FindDevices: Found nasty Compaq ESDI!\n"));
3233 
3234  // Change these values to something reasonable.
3235  LunExt->IdentifyData.SectorsPerTrack = 0x34;
3236  LunExt->IdentifyData.NumberOfHeads = 0x0E;
3237  }
3238 
3239  if (LunExt->IdentifyData.SectorsPerTrack == 0x35 &&
3240  LunExt->IdentifyData.NumberOfHeads == 0x0F) {
3241 
3242  KdPrint2((PRINT_PREFIX "FindDevices: Found nasty Compaq ESDI!\n"));
3243 
3244  // Change these values to something reasonable.
3245  LunExt->IdentifyData.SectorsPerTrack = 0x34;
3246  LunExt->IdentifyData.NumberOfHeads = 0x0F;
3247  }
3248 
3249 
3250  if (LunExt->IdentifyData.SectorsPerTrack == 0x36 &&
3251  LunExt->IdentifyData.NumberOfHeads == 0x07) {
3252 
3253  KdPrint2((PRINT_PREFIX "FindDevices: Found nasty UltraStor ESDI!\n"));
3254 
3255  // Change these values to something reasonable.
3256  LunExt->IdentifyData.SectorsPerTrack = 0x3F;
3257  LunExt->IdentifyData.NumberOfHeads = 0x10;
3258  skipSetParameters = TRUE;
3259  }
3260 
3261 
3262  if (skipSetParameters)
3263  continue;
3264 
3265  statusByte = WaitOnBusy(chan);
3266 
3267  // Select the device.
3268  SelectDrive(chan, i & 0x01);
3269  GetStatus(chan, statusByte);
3270 
3271  if (statusByte & IDE_STATUS_ERROR) {
3272 
3273  // Reset the device.
3275  "FindDevices: Resetting controller before SetDriveParameters.\n"));
3276 
3277  AtapiHardReset(chan, FALSE, 500 * 1000);
3278 /*
3279  AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER );
3280  chan->last_devsel = -1;
3281  AtapiStallExecution(500 * 1000);
3282  AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER);
3283 */
3284  SelectDrive(chan, i & 0x01);
3285 
3286  do {
3287  // Wait for Busy to drop.
3288  AtapiStallExecution(100);
3289  GetStatus(chan, statusByte);
3290 
3291  } while ((statusByte & IDE_STATUS_BUSY) && waitCount--);
3292  }
3293 
3294  statusByte = WaitOnBusy(chan);
3295 
3297  "FindDevices: Status before SetDriveParameters: (%#x) (%#x)\n",
3298  statusByte,
3300 
3301  GetBaseStatus(chan, statusByte);
3302 
3303  // Use the IDENTIFY data to set drive parameters.
3304  if (!SetDriveParameters(HwDeviceExtension,i,Channel)) {
3305 
3307  "FindDevices: Set drive parameters for device %d failed\n",
3308  i));
3309  // Don't use this device as writes could cause corruption.
3310  LunExt->DeviceFlags &= ~DFLAGS_DEVICE_PRESENT;
3311  UniataForgetDevice(LunExt);
3312  continue;
3313 
3314  }
3315  if (LunExt->DeviceFlags & DFLAGS_REMOVABLE_DRIVE) {
3316 
3317  // Pick up ALL IDE removable drives that conform to Yosemite V0.2...
3318  AtapiOnly = FALSE;
3319  }
3320 
3321  // Indicate that a device was found.
3322  if (!AtapiOnly) {
3323  deviceResponded = TRUE;
3324  }
3325  }
3326  }
3327 
3328 /* // Reset the controller. This is a feeble attempt to leave the ESDI
3329  // controllers in a state that ATDISK driver will recognize them.
3330  // The problem in ATDISK has to do with timings as it is not reproducible
3331  // in debug. The reset should restore the controller to its poweron state
3332  // and give the system enough time to settle.
3333  if (!deviceResponded) {
3334 
3335  AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_RESET_CONTROLLER );
3336  AtapiStallExecution(50 * 1000);
3337  AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_REENABLE_CONTROLLER);
3338  }
3339 */
3340  if(deviceResponded) {
3341  for (i = 0; i < max_ldev; i++) {
3342  LunExt = chan->lun[i];
3343 
3345  "FindDevices: select %d dev to clear INTR\n", i));
3346  SelectDrive(chan, i);
3347  GetBaseStatus(chan, statusByte);
3349  "FindDevices: statusByte=%#x\n", statusByte));
3350  }
3351  for (i = 0; i < max_ldev; i++) {
3352  LunExt = chan->lun[i];
3353 
3354  if(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT) {
3355  // Make sure some device (master is preferred) is selected on exit.
3357  "FindDevices: select %d dev on exit\n", i));
3358  SelectDrive(chan, i);
3359  break;
3360  }
3361  }
3362  }
3363 
3364  GetBaseStatus(chan, statusByte);
3365  // Enable interrupts
3366  AtapiEnableInterrupts(deviceExtension, Channel);
3367 // AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_A_4BIT );
3368  GetBaseStatus(chan, statusByte);
3369 
3371  "FindDevices: returning %d\n",
3372  deviceResponded));
3373 
3374  return deviceResponded;
3375 
3376 } // end FindDevices()
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 * u
Definition: glfuncs.h:240
signed char * PCHAR
Definition: retypes.h:7
struct _CM_RESOURCE_LIST * PCM_RESOURCE_LIST
BOOLEAN PrimaryAddress
Definition: bsmaster.h:1031
IDENTIFY_DATA2 IdentifyData
Definition: bsmaster.h:1157
ULONG NTAPI UniataSataReadPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG pm_port)
Definition: id_sata.cpp:270
#define PCI_TYPE0_ADDRESSES
Definition: iotypes.h:3143
#define AtapiSoftReset(BaseIoAddress, DeviceNumber)
Definition: atapi.h:418
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VOID UniataExpectChannelInterrupt(IN struct _HW_CHANNEL *chan, IN BOOLEAN Expecting)
Definition: id_ata.cpp:4446
#define ATAPI_MAGIC_MSB
Definition: bsmaster.h:106
#define ATA_AT_HOME_ATAPI
Definition: atapi.h:1595
#define CHAN_NOT_SPECIFIED_CHECK_CABLE
Definition: atapi.h:1484
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define PCI_DEV_SUBCLASS_IDE
Definition: bsmaster.h:119
#define KdPrint2(_x_)
Definition: atapi.h:154
#define BM_STATUS_SIMPLEX_ONLY
Definition: bsmaster.h:148
#define GetStatus(BaseIoAddress, Status)
Definition: atapi.h:328
#define GetDmaStatus(de, c)
Definition: bsmaster.h:1706
#define CHAN_NOT_SPECIFIED
Definition: atapi.h:1483
NTSTATUS NTAPI UniataClaimLegacyPCIIDE(ULONG i)
Definition: id_probe.cpp:1939
#define ATA_AT_HOME_HDD
Definition: atapi.h:1594
#define VM_VBOX
Definition: bsmaster.h:1898
NTHALAPI ULONG NTAPI HalGetInterruptVector(INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY)
USHORT MaximumLength
Definition: env_spec_w32.h:370
__inline ULONG UniataAhciReadChannelPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx)
Definition: id_sata.h:290
#define PCI_ENABLE_IO_SPACE
Definition: iotypes.h:3259
PBUSMASTER_CONTROLLER_INFORMATION BMList
Definition: id_probe.cpp:53
CM_FULL_RESOURCE_DESCRIPTOR List[1]
Definition: hwresource.cpp:165
NTSTATUS NTAPI UniataConnectIntr2(IN PVOID HwDeviceExtension)
Definition: id_probe.cpp:2034
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Definition: iorsrce.c:830
#define VM_AUTO
Definition: bsmaster.h:1896
ULONG MCACount
Definition: id_probe.cpp:56
UCHAR NTAPI UniataSataPhyEnable(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG pm_port, IN BOOLEAN doReset)
Definition: id_sata.cpp:124
#define CTRFLAGS_NO_SLAVE
Definition: bsmaster.h:1134
#define UNIATA_RAID_CONTROLLER
Definition: bm_devs_decl.h:623
INTERFACE_TYPE OrigAdapterInterfaceType
Definition: bsmaster.h:1310
enum _BUS_DATA_TYPE BUS_DATA_TYPE
NTSTATUS NTAPI UniataChipDetect(IN PVOID HwDeviceExtension, IN PPCI_COMMON_CONFIG pciData, IN ULONG DeviceNumber, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, IN BOOLEAN *simplexOnly)
Definition: id_init.cpp:339
#define IDX_IO2_AltStatus
Definition: atapi.h:225
ULONG NTAPI AtapiFindDev(IN PVOID HwDeviceExtension, IN BUS_DATA_TYPE BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN ULONG dev_id, IN ULONG RevID)
Definition: id_probe.cpp:871
unsigned char * PUCHAR
Definition: retypes.h:3
#define ATA_AT_HOME_NOBODY
Definition: atapi.h:1597
ULONG ChannelCtrlFlags
Definition: bsmaster.h:1054
BOOLEAN NTAPI UniataCheckPCISubclass(BOOLEAN known, ULONG RaidFlags, UCHAR SubClass)
Definition: id_probe.cpp:256
struct _BUSMASTER_CONTROLLER_INFORMATION * PBUSMASTER_CONTROLLER_INFORMATION
USHORT SectorsPerTrack
Definition: atapi.h:255
#define IO_WD2
Definition: bsmaster.h:79
#define ScsiPortConvertPhysicalAddressToUlong(Address)
Definition: srb.h:949
_In_ USHORT DeviceID
Definition: iotypes.h:859
LONG NTSTATUS
Definition: precomp.h:26
GLintptr offset
Definition: glext.h:5920
#define IDX_BM_IO
Definition: bsmaster.h:163
BOOLEAN hasPCI
Definition: id_ata.cpp:103
#define ATA_PCCARD_ALTOFFSET
Definition: bsmaster.h:88
BOOLEAN DWordIO
Definition: atapi.c:117
BOOLEAN WinVer_WDM_Model
Definition: id_ata.cpp:112
UCHAR pciBuffer[256]
Definition: id_probe.cpp:66
UCHAR DDKFASTAPI SelectDrive(IN struct _HW_CHANNEL *chan, IN ULONG DeviceNumber)
struct _IDE_REGISTERS_2 * PIDE_REGISTERS_2
#define IDE_COMMAND_IDENTIFY
Definition: atapi.h:118
#define REORDER_COST_SWITCH_RW_HDD
Definition: bsmaster.h:988
PHW_CHANNEL chan
Definition: bsmaster.h:1252
#define DFLAGS_ATAPI_DEVICE
Definition: atapi.h:41
Definition: shell.h:41
#define VM_QEMU
Definition: bsmaster.h:1900
struct _IDE_BUSMASTER_REGISTERS * PIDE_BUSMASTER_REGISTERS
ULONG NTAPI UniataAhciSoftReset(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_sata.cpp:1783
#define IDE_STATUS_WRONG
Definition: atapi.h:431
#define ATA_PIO4
Definition: atapi.h:313
ULONG NTAPI AtapiParseArgumentString(IN PCHAR String, IN PCHAR KeyWord)
Definition: atapi.c:1852
PORT_CONFIGURATION_INFORMATION_NT nt4
Definition: srb.h:130
#define IDE_MAX_CHAN
Definition: bm_devs_decl.h:42
ULONG maxPciBus
Definition: id_probe.cpp:67
unsigned char irq
Definition: dsp.h:13
#define IDE_STATUS_INDEX
Definition: atapi.h:126
#define PCI_DEV_SUBCLASS_ATA
Definition: bsmaster.h:121
VOID NTAPI UniataForgetDevice(PHW_LU_EXTENSION LunExt)
Definition: id_ata.cpp:2339
ULONG MemIo
Definition: bsmaster.h:1008
ULONG NTAPI UniataFindCompatBusMasterController2(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
Definition: id_probe.cpp:945
BOOLEAN NTAPI UniataAllocateLunExt(PHW_DEVICE_EXTENSION deviceExtension, ULONG NewNumberChannels)
Definition: id_init.cpp:2891
uint32_t ULONG_PTR
Definition: typedefs.h:63
PVOID NTAPI ScsiPortGetDeviceBase(IN PVOID HwDeviceExtension, IN INTERFACE_TYPE BusType, IN ULONG SystemIoBusNumber, IN SCSI_PHYSICAL_ADDRESS IoAddress, IN ULONG NumberOfBytes, IN BOOLEAN InIoSpace)
Definition: scsiport.c:537
#define GetBaseStatus(BaseIoAddress, Status)
Definition: atapi.h:331
ULONG BMListLen
Definition: id_probe.cpp:54
#define SStatus_DET_Dev_NoPhy
Definition: bsmaster.h:285
#define sprintf(buf, format,...)
Definition: sprintf.c:55
VOID NTAPI ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension, IN PVOID MappedAddress)
Definition: scsiport.c:515
#define BM_STATUS_INTR
Definition: bsmaster.h:144
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
pass
Definition: typegen.h:24
ULONG IsaCount
Definition: id_probe.cpp:55
PDRIVER_OBJECT SavedDriverObject
Definition: id_probe.cpp:69
#define _snprintf
Definition: xmlstorage.h:200
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
#define IDE_DEFAULT_MAX_CHAN
Definition: bm_devs_decl.h:43
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
VOID NTAPI UniataDumpATARegs(IN struct _HW_CHANNEL *chan)
NTSTATUS NTAPI IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave)
Definition: irq.c:22
#define IDX_IO1_i_DriveSelect
Definition: atapi.h:202
#define ATA_BM_OFFSET1
Definition: bsmaster.h:85
struct _HW_LU_EXTENSION HW_LU_EXTENSION
BOOLEAN NTAPI SetDriveParameters(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG Channel)
Definition: atapi.c:636
#define IDE_DRIVE_MASK
Definition: atapi.h:444
ULONG ForceSimplex
Definition: id_ata.cpp:78
ULONG NTAPI CheckDevice(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG deviceNumber, IN BOOLEAN ResetDev)
Definition: id_probe.cpp:2881
#define UNIATA_NO_SLAVE
Definition: bm_devs_decl.h:626
#define SStatus_SPD_Gen1
Definition: bsmaster.h:292
#define PCIBUSNUM_NOT_SPECIFIED
Definition: bsmaster.h:1446
ULONG NTAPI AtapiFindIsaController(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
Definition: id_probe.cpp:2227
unsigned char BOOLEAN
struct _HW_DEVICE_EXTENSION HW_DEVICE_EXTENSION
PHW_LU_EXTENSION lun
Definition: bsmaster.h:1251
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
smooth NULL
Definition: ftsmooth.c:416
enum _KINTERRUPT_MODE KINTERRUPT_MODE
#define offsetof(TYPE, MEMBER)
#define DMA_MODE_BM
Definition: bsmaster.h:1702
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:140
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define UNIATA_SATA
Definition: bm_devs_decl.h:627
struct _ISR2_DEVICE_EXTENSION * PISR2_DEVICE_EXTENSION
Definition: bufpool.h:45
#define IDE_COMMAND_ATAPI_IDENTIFY
Definition: atapi.h:110
NTSTATUS NTAPI UniataDisconnectIntr2(IN PVOID HwDeviceExtension)
Definition: id_probe.cpp:2156
#define WinVer_NT
Definition: CrossNt.h:112
#define UlongToPtr(u)
Definition: config.h:106
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:156
_In_ PVOID Argument2
Definition: classpnp.h:680
#define PtrToUlong(u)
Definition: config.h:107
BOOLEAN NTAPI AtapiCheckIOInterference(IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, ULONG portBase)
Definition: id_probe.cpp:2187
union _PCI_SLOT_NUMBER::@3627 u
PORT_CONFIGURATION_INFORMATION_2K w2k
Definition: srb.h:131
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define PCHAR
Definition: match.c:90
__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 REORDER_MCOST_SWITCH_RW_HDD
Definition: bsmaster.h:989
#define IDX_ATAPI_IO1_i_Status
Definition: atapi.h:513
ULONG InterruptMode
Definition: atapi.c:47
#define BMLIST_TERMINATOR
Definition: bm_devs_decl.h:740
PORT_CONFIGURATION_INFORMATION comm
Definition: srb.h:129
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
#define IDX_IO1_o_BlockNumber
Definition: atapi.h:211
#define DFLAGS_TAPE_DEVICE
Definition: atapi.h:42
#define UNIATA_ALLOCATE_NEW_LUNS
Definition: bsmaster.h:1393
#define IDX_ATAPI_IO1_o_ByteCountHigh
Definition: atapi.h:520
#define STATUS_NOT_FOUND
Definition: shellext.h:67
UCHAR DDKFASTAPI AtapiReadPort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port)
ULONG NTAPI AtapiRegCheckDevValue(IN PVOID HwDeviceExtension, IN ULONG chan, IN ULONG dev, IN PCWSTR Name, IN ULONG Default)
Definition: id_ata.cpp:11226
VOID NTAPI AtapiDisableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4411
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3244
#define ATA_ALTOFFSET
Definition: bsmaster.h:87
ULONG NTAPI AtapiReadArgumentString(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
Definition: id_probe.cpp:2738
__wchar_t WCHAR
Definition: xmlstorage.h:180
static CONST ULONG StdIsaPorts[]
Definition: id_probe.cpp:291
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
SCSI_PHYSICAL_ADDRESS NTAPI ScsiPortConvertUlongToPhysicalAddress(IN ULONG_PTR UlongAddress)
Definition: scsiport.c:495
BOOLEAN InDriverEntry
Definition: id_ata.cpp:107
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define IDX_BM_Status
Definition: bsmaster.h:169
struct _PCI_SLOT_NUMBER::@3627::@3628 bits
LONGLONG RwSwitchCost
Definition: bsmaster.h:1176
BOOLEAN NTAPI IssueIdentify(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG Channel, IN UCHAR Command)
Definition: atapi.c:251
_In_ USHORT _In_ UCHAR _In_ USHORT SubVendorID
Definition: iotypes.h:859
#define WinVer_2k
Definition: CrossNt.h:114
#define PCI_ENABLE_BUS_MASTER
Definition: iotypes.h:3261
#define PCI_IDE_PROGIF_NATIVE_ALL
Definition: bsmaster.h:858
#define IDX_SATA_IO
Definition: bsmaster.h:453
const GLubyte * c
Definition: glext.h:8905
#define PCI_MAX_DEVICES
Definition: iotypes.h:3241
#define IDX_IO2
Definition: atapi.h:222
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
NTHALAPI ULONG NTAPI HalGetBusData(BUS_DATA_TYPE, ULONG, ULONG, PVOID, ULONG)
#define DEVNUM_NOT_SPECIFIED
Definition: atapi.h:1485
#define SP_RETURN_NOT_FOUND
Definition: srb.h:513
VOID NTAPI UniataInitMapBase(IN struct _HW_CHANNEL *chan, IN PIDE_REGISTERS_1 BaseIoAddress1, IN PIDE_REGISTERS_2 BaseIoAddress2)
#define Ata_is_supported_dev(pciData)
Definition: bm_devs_decl.h:779
struct _HW_DEVICE_EXTENSION * DeviceExtension
Definition: bsmaster.h:1082
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define SP_RETURN_FOUND
Definition: srb.h:514
union _ATA_REQ ATA_REQ
BOOLEAN g_Dump
Definition: id_ata.cpp:108
#define DFLAGS_REMOVABLE_DRIVE
Definition: atapi.h:45
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG _In_ ULONG SlotNumber
Definition: halfuncs.h:156
BOOLEAN NTAPI AtapiReadChipConfig(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG channel)
Definition: id_init.cpp:1782
unsigned char UCHAR
Definition: xmlstorage.h:181
char * PBOOLEAN
Definition: retypes.h:11
VOID NTAPI AtapiDmaAlloc(IN PVOID HwDeviceExtension, IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, IN ULONG lChannel)
Definition: id_dma.cpp:138
VOID DDKFASTAPI AtapiHardReset(IN struct _HW_CHANNEL *chan, IN BOOLEAN DisableInterrupts, IN ULONG Delay)
Definition: id_ata.cpp:902
#define DbgDumpRegTranslation(chan, idx)
Definition: tools.h:135
VOID NTAPI UniataEnumBusMasterController(IN PVOID DriverObject, PVOID Argument2)
Definition: id_probe.cpp:245
static const WCHAR L[]
Definition: oid.c:1250
#define PCI_DEV_CLASS_STORAGE
Definition: bsmaster.h:117
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define DFLAGS_LBA_ENABLED
Definition: atapi.h:247
struct _BUSMASTER_CONTROLLER_INFORMATION BUSMASTER_CONTROLLER_INFORMATION
ULONG NTAPI UniataFindCompatBusMasterController1(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
Definition: id_probe.cpp:924
_In_ USHORT _In_ UCHAR _In_ USHORT _In_ USHORT SubSystemID
Definition: iotypes.h:859
#define VM_VMWARE
Definition: bsmaster.h:1899
#define UNIATA_AHCI
Definition: bm_devs_decl.h:630
BOOLEAN AtdiskPrimaryClaimed
Definition: id_probe.cpp:61
IORES RegTranslation[IDX_MAX_REG]
Definition: bsmaster.h:1122
VOID NTAPI UniataFreeLunExt(PHW_DEVICE_EXTENSION deviceExtension)
Definition: id_init.cpp:2956
VOID NTAPI AtapiEnableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4351
#define ATA_IOSIZE
Definition: bsmaster.h:86
#define IDX_IO1_i_CylinderHigh
Definition: atapi.h:201
#define PCI_DEV_SUBCLASS_RAID
Definition: bsmaster.h:120
PHW_DEVICE_EXTENSION HwDeviceExtension
Definition: bsmaster.h:1346
#define DMA_MODE_NONE
Definition: bsmaster.h:1701
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
#define PCI_MAX_FUNCTION
Definition: iotypes.h:3242
LONGLONG SeekBackMCost
Definition: bsmaster.h:1178
VOID DDKFASTAPI AtapiWritePort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN UCHAR data)
BOOLEAN AtdiskSecondaryClaimed
Definition: id_probe.cpp:62
#define IDX_IO1_i_Status
Definition: atapi.h:203
#define DFLAGS_DEVICE_PRESENT
Definition: atapi.h:40
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1250
BOOLEAN DriverMustPoll
Definition: atapi.c:111
#define IDX_IO1_o_CylinderLow
Definition: atapi.h:212
UNICODE_STRING SavedRegPath
Definition: id_ata.cpp:69
#define PCI_DEV_SUBCLASS_SATA
Definition: bsmaster.h:122
#define PCISLOTNUM_NOT_SPECIFIED
Definition: bsmaster.h:1447
unsigned short USHORT
Definition: pedump.c:61
#define UNIATA_SATA_IGNORE_CONNECT
Definition: id_sata.h:61
#define IDE_STATUS_BUSY
Definition: atapi.h:132
ULONG SkipRaids
Definition: id_ata.cpp:77
ULONG lChannel
Definition: bsmaster.h:1059
#define Ata_is_ahci_dev(pciData)
Definition: bm_devs_decl.h:783
ULONG NTAPI UniataFindBusMasterController(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
Definition: id_probe.cpp:988
BOOLEAN NTAPI AtapiInterrupt2(IN PKINTERRUPT Interrupt, IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:4146
LONGLONG RwSwitchMCost
Definition: bsmaster.h:1177
ULONG NTAPI ScsiPortGetBusDataByOffset(IN PVOID HwDeviceExtension, IN BUS_DATA_TYPE BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: id_probe.cpp:741
#define ATA_AT_HOME_XXX
Definition: atapi.h:1596
USHORT NTAPI UniataEnableIoPCI(IN ULONG busNumber, IN ULONG slotNumber, IN OUT PPCI_COMMON_CONFIG pciData)
Definition: id_probe.cpp:95
unsigned int * PULONG
Definition: retypes.h:1
#define FILE_DEVICE_UNKNOWN
Definition: winioctl.h:139
#define IDX_SATA_SStatus
Definition: bsmaster.h:457
#define PRINT_PREFIX
Definition: atapi.h:150
#define IO_WD1
Definition: bsmaster.h:78
#define VM_NONE
Definition: bsmaster.h:1897
#define PCI_ENABLE_MEMORY_SPACE
Definition: iotypes.h:3260
#define UNIATA_NO_DPC
Definition: bm_devs_decl.h:628
#define AtapiStallExecution(dt)
Definition: atapi.h:158
#define REORDER_MCOST_SEEK_BACK_HDD
Definition: bsmaster.h:990
#define VM_BOCHS
Definition: bsmaster.h:1901
#define SStatus_IPM_NoDev
Definition: bsmaster.h:298
BOOLEAN NTAPI ScsiPortValidateRange(IN PVOID HwDeviceExtension, IN INTERFACE_TYPE BusType, IN ULONG SystemIoBusNumber, IN SCSI_PHYSICAL_ADDRESS IoAddress, IN ULONG NumberOfBytes, IN BOOLEAN InIoSpace)
Definition: scsiport.c:1453
#define UNIATA_NO_DPC_ATAPI
Definition: bm_devs_decl.h:629
#define ATA_ALTIOSIZE
Definition: bsmaster.h:89
#define BOOLEAN
Definition: pedump.c:73
#define OUT
Definition: typedefs.h:39
#define DFLAGS_DWORDIO_ENABLED
Definition: atapi.h:248
#define IDE_STATUS_ERROR
Definition: atapi.h:125
VOID NTAPI UniataInitMapBM(IN struct _HW_DEVICE_EXTENSION *deviceExtension, IN struct _IDE_BUSMASTER_REGISTERS *BaseIoAddressBM_0, IN BOOLEAN MemIo)
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
#define WaitOnBusy(BaseIoAddress, Status)
Definition: atapi.h:359
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
USHORT NumberOfHeads
Definition: atapi.h:252
#define ULONG_PTR
Definition: config.h:101
#define WinVer_Id()
Definition: CrossNt.h:109
BOOLEAN NTAPI AtapiChipInit(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG c)
Definition: id_init.cpp:1879
BUSMASTER_CONTROLLER_INFORMATION_BASE const BusMasterAdapters[]
Definition: bm_devs.h:40
__inline ULONG Ata_is_dev_listed(IN PBUSMASTER_CONTROLLER_INFORMATION_BASE BusMasterAdapters, ULONG VendorId, ULONG DeviceId, ULONG RevId, ULONG lim)
Definition: bm_devs_decl.h:755
NTHALAPI NTSTATUS NTAPI HalAssignSlotResources(PUNICODE_STRING, PUNICODE_STRING, PDRIVER_OBJECT, PDEVICE_OBJECT, INTERFACE_TYPE, ULONG, ULONG, PCM_RESOURCE_LIST *)
#define IDE_MAX_LUN_PER_CHAN
Definition: bm_devs_decl.h:46
#define DFLAGS_HIDDEN
Definition: atapi.h:253
#define IDE_DRIVE_SELECT_2
Definition: atapi.h:139
ULONG MaximumDmaTransferLength
Definition: bsmaster.h:1312
void exit(int exitcode)
Definition: _exit.c:33
#define SP_RETURN_ERROR
Definition: srb.h:515
UCHAR NTAPI AtapiDmaDone(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:685
ULONG NumberLuns
Definition: bsmaster.h:1085
ULONG NTAPI HalSetBusDataByOffset(IN BUS_DATA_TYPE BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: bus.c:123
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define PCI_ADDRESS_IO_SPACE
Definition: iotypes.h:3873
#define IsBusMaster(pciData)
Definition: bsmaster.h:852
#define IsMasterDev(pciData)
Definition: bsmaster.h:860
#define IDX_IO1_i_CylinderLow
Definition: atapi.h:200
#define UNIATA_FIND_DEV_UNHIDE
Definition: atapi.h:1362
ULONG NTAPI UniataEnumBusMasterController__()
Definition: id_probe.cpp:299
#define CHAR(Char)
BOOLEAN FirstMasterOk
Definition: id_probe.cpp:58
static SERVICE_STATUS status
Definition: service.c:31
ULONG g_opt_VirtualMachine
Definition: id_ata.cpp:105
#define ULONGIO_PTR
Definition: config.h:102
#define IDX_IO1
Definition: atapi.h:194
ULONG NTAPI UniataAnybodyHome(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG deviceNumber)
Definition: id_probe.cpp:2762
ULONG AtapiReadyWaitDelay
Definition: bsmaster.h:1186
#define IDX_IO1_i_BlockNumber
Definition: atapi.h:199
#define IDX_ATAPI_IO1_i_DriveSelect
Definition: atapi.h:512
#define CONST
Definition: pedump.c:81
struct _HW_LU_EXTENSION * lun[IDE_MAX_LUN_PER_CHAN]
Definition: bsmaster.h:1083
ULONG NumberChannels
Definition: atapi.c:68
#define ATAPI_MAGIC_LSB
Definition: bsmaster.h:105
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
ULONG const NUM_BUSMASTER_ADAPTERS
VOID NTAPI AtapiDoNothing(VOID)
Definition: id_probe.cpp:86
BOOLEAN NTAPI FindDevices(IN PVOID HwDeviceExtension, IN ULONG Flags, IN ULONG Channel)
Definition: id_probe.cpp:3168
ULONG g_opt_WaitBusyResetCount
Definition: id_ata.cpp:89
struct _PORT_CONFIGURATION_INFORMATION_COMMON * PPORT_CONFIGURATION_INFORMATION_COMMON
INTERFACE_TYPE AdapterInterfaceType
Definition: bsmaster.h:1311
LONGLONG QuadPart
Definition: typedefs.h:112
struct _IDE_REGISTERS_1 * PIDE_REGISTERS_1
ULONG NTAPI AtapiFindListedDev(IN PBUSMASTER_CONTROLLER_INFORMATION_BASE BusMasterAdapters, IN ULONG lim, IN PVOID HwDeviceExtension, IN ULONG BusNumber, IN ULONG SlotNumber, OUT PCI_SLOT_NUMBER *_slotData)
Definition: id_probe.cpp:780
ULONG Addr
Definition: bsmaster.h:1005
#define PCI_COMMON_HDR_LENGTH
Definition: iotypes.h:3237
Definition: ps.c:97