ReactOS 0.4.15-dev-7842-g558ab78
id_probe.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) 2002-2016 Alexandr A. Telyatnikov (Alter)
4
5Module Name:
6 id_probe.cpp
7
8Abstract:
9 This module scans PCI and ISA buses for IDE controllers
10 and determines their Busmaster DMA capabilities
11
12Author:
13 Alexander A. Telyatnikov (Alter)
14
15Environment:
16 kernel mode only
17
18Notes:
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
31Revision 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
46Licence:
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
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
84VOID
87{
88 return;
89} // end AtapiDoNothing()
90
91#endif //UNIATA_CORE
92
96 IN ULONG busNumber,
97 IN ULONG slotNumber,
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*/
152NTAPI
154 IN PVOID HwDeviceExtension,
156 IN PPCI_COMMON_CONFIG pciData,
157 IN ULONG SystemIoBusNumber,
158 IN ULONG rid, //range id
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*/
243VOID
244NTAPI
248 )
249{
251
252} // end UniataEnumBusMasterController()
253
255NTAPI
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*/
297ULONG
298NTAPI
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;
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),
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),
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 }
724exit:
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*/
739ULONG
740NTAPI
742 IN PVOID HwDeviceExtension,
743 IN BUS_DATA_TYPE BusDataType,
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,
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*/
778ULONG
779NTAPI
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*/
869ULONG
870NTAPI
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;
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
922ULONG
923NTAPI
925 IN PVOID HwDeviceExtension,
928 IN PCHAR ArgumentString,
930 OUT PBOOLEAN Again
931 )
932{
934 HwDeviceExtension,
935 UlongToPtr(0x00000000),
937 ArgumentString,
938 ConfigInfo,
939 Again
940 );
941} // end UniataFindCompatBusMasterController1()
942
943ULONG
944NTAPI
946 IN PVOID HwDeviceExtension,
949 IN PCHAR ArgumentString,
951 OUT PBOOLEAN Again
952 )
953{
955 HwDeviceExtension,
956 UlongToPtr(0x80000000),
958 ArgumentString,
959 ConfigInfo,
960 Again
961 );
962} // end UniataFindCompatBusMasterController2()
963
964/*++
965
966Routine 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
972Arguments:
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
981Return Value:
982
983 ULONG
984
985--*/
986ULONG
987NTAPI
989 IN PVOID HwDeviceExtension,
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;
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
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,
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,
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);
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);
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
1801
1802 } else
1803 if (channel == 1) {
1804 KdPrint2((PRINT_PREFIX "claim Secondary\n"));
1806 ConfigInfo->AtdiskSecondaryClaimed = TRUE;
1807
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
1832exit_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
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));
1917 }
1918
1919 ConfigInfo->NumberOfBuses++; // add virtual channel for communication port
1920 return SP_RETURN_FOUND;
1921
1922exit_error:
1923 UniataFreeLunExt(deviceExtension);
1924 return SP_RETURN_ERROR;
1925
1926exit_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*/
1938NTAPI
1940 ULONG i
1941 )
1942{
1944 PCM_RESOURCE_LIST resourceList = NULL;
1945 UNICODE_STRING devname;
1946#ifdef __REACTOS__
1947 PCM_RESOURCE_LIST oldResList = NULL;
1948#endif
1949
1950 KdPrint2((PRINT_PREFIX "UniataClaimLegacyPCIIDE:\n"));
1951
1952 if(BMList[i].PciIdeDevObj) {
1953 KdPrint2((PRINT_PREFIX "Already initialized\n"));
1954 return STATUS_UNSUCCESSFUL;
1955 }
1956
1957 RtlInitUnicodeString(&devname, L"\\Device\\uniata_PCIIDE");
1959 /*NULL*/ &devname, FILE_DEVICE_UNKNOWN,
1960 0, FALSE, &(BMList[i].PciIdeDevObj));
1961
1962 if(!NT_SUCCESS(status)) {
1963 KdPrint2((PRINT_PREFIX "IoCreateDevice failed %#x\n", status));
1964 return status;
1965 }
1966
1968 sizeof(CM_RESOURCE_LIST));
1969
1970 if (!resourceList) {
1971 KdPrint2((PRINT_PREFIX "!resourceList\n"));
1973del_do:
1974 IoDeleteDevice(BMList[i].PciIdeDevObj);
1976#ifdef __REACTOS__
1977 if (oldResList)
1978 ExFreePool(oldResList);
1979#endif
1980 return status;
1981 }
1982
1984 resourceList,
1985 sizeof(CM_RESOURCE_LIST));
1986
1987#ifdef __REACTOS__
1988 oldResList = resourceList;
1989#endif
1990
1991 // IoReportDetectedDevice() should be used for WDM OSes
1992
1993 // TODO: check if resourceList is actually used inside HalAssignSlotResources()
1994 // Note: with empty resourceList call to HalAssignSlotResources() fails on some HW
1995 // e.g. Intel ICH4, but works with non-empty.
1996
1997 resourceList->Count = 1;
1998 resourceList->List[0].InterfaceType = PCIBus;
1999 resourceList->List[0].BusNumber = BMList[i].busNumber;
2000 // we do not report IO ranges since they are used/claimed by ISA part(s)
2001 resourceList->List[0].PartialResourceList.Count = 0;
2002
2003 RtlInitUnicodeString(&devname, L"PCIIDE");
2005 &devname,
2007 BMList[i].PciIdeDevObj,
2008 PCIBus,
2009 BMList[i].busNumber,
2010 BMList[i].slotNumber,
2011 &resourceList);
2012
2013 if (!NT_SUCCESS(status)) {
2014 KdPrint2((PRINT_PREFIX "HalAssignSlotResources failed %#x\n", status));
2015 // this is always deallocated inside HalAssignSlotResources() implementation
2016 //ExFreePool(resourceList);
2017 goto del_do;
2018 }
2019
2020#ifdef __REACTOS__
2021 ExFreePool(resourceList);
2022 ExFreePool(oldResList);
2023#endif
2024
2025 KdPrint2((PRINT_PREFIX "ok %#x\n", status));
2026 BMList[i].ChanInitOk |= 0x80;
2027
2028 return status;
2029} // end UniataClaimLegacyPCIIDE()
2030
2031
2032/*++
2033
2034Routine Description:
2035
2036 This function is called to initialize 2nd device object for
2037 multichannel controllers.
2038
2039Arguments:
2040
2041 HwDeviceExtension - HBA miniport driver's adapter data storage
2042
2043Return Value:
2044
2045 ULONG
2046
2047--*/
2049NTAPI
2051 IN PVOID HwDeviceExtension
2052 )
2053{
2054 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2055 ULONG i = deviceExtension->DevIndex;
2057 PISR2_DEVICE_EXTENSION Isr2DevExt;
2058 WCHAR devname_str[33];
2059 UNICODE_STRING devname;
2060
2061 KdPrint2((PRINT_PREFIX "Init ISR:\n"));
2062
2063 /*
2064 We MUST register 2nd ISR for multichannel controllers even for UP systems.
2065 This is needed for cases when
2066 multichannel controller generate interrupt while we are still in its ISR for
2067 other channle's interrupt. New interrupt must be detected and queued for
2068 further processing. If we do not do this, system will not route this
2069 interrupt to main ISR (since it is busy) and we shall get to infinite loop
2070 looking for interrupt handler.
2071 */
2072
2073 if(!deviceExtension->MasterDev && (deviceExtension->NumberChannels > 1) && // do not touch MasterDev
2074 !deviceExtension->simplexOnly && /* // this is unnecessary on simplex controllers
2075 !BMList[i].Isr2DevObj*/ // handle re-init under w2k+
2077 /*(CPU_num > 1) && // unnecessary for UP systems*/
2078 TRUE) {
2079 // Ok, continue...
2080 KdPrint2((PRINT_PREFIX "Multichannel native mode, go...\n"));
2081#ifndef UNIATA_USE_XXableInterrupts
2082 // If we raise IRQL to TIMER value, other interrupt cannot occure on the same CPU
2083/* if(KeNumberProcessors < 2) {
2084 KdPrint2((PRINT_PREFIX "Unnecessary (?), UP machine\n"));
2085 //return STATUS_SUCCESS;
2086 }*/
2087#endif //UNIATA_USE_XXableInterrupts
2088 } else {
2089 KdPrint2((PRINT_PREFIX "Unnecessary\n"));
2090 return STATUS_SUCCESS;
2091 }
2092
2093 if(BMList[i].Isr2DevObj) {
2094 KdPrint2((PRINT_PREFIX "Already initialized [%d] %#x\n", i, BMList[i].Isr2DevObj));
2095 return STATUS_SUCCESS;
2096 }
2097
2098 KdPrint2((PRINT_PREFIX "Create DO\n"));
2099
2100 devname.Length =
2101 _snwprintf(devname_str, sizeof(devname_str)/sizeof(WCHAR)-1,
2102 L"\\Device\\uniata%d_2ch", i);
2103 devname_str[devname.Length] = 0;
2104 devname.Length *= sizeof(WCHAR);
2105 devname.MaximumLength = devname.Length;
2106 devname.Buffer = devname_str;
2107
2108 KdPrint2((PRINT_PREFIX "DO name: len(%d, %d), %S\n", devname.Length, devname.MaximumLength, devname.Buffer));
2109
2111 /*NULL*/ &devname, FILE_DEVICE_UNKNOWN,
2112 0, FALSE, &(BMList[i].Isr2DevObj));
2113
2114 if(!NT_SUCCESS(status)) {
2115 KdPrint2((PRINT_PREFIX "IoCreateDevice failed %#x\n", status));
2116 return status;
2117 }
2118
2119 KdPrint2((PRINT_PREFIX "HalGetInterruptVector\n"));
2120 KdPrint2((PRINT_PREFIX " OrigAdapterInterfaceType=%d\n", deviceExtension->OrigAdapterInterfaceType));
2121 KdPrint2((PRINT_PREFIX " SystemIoBusNumber=%d\n", deviceExtension->SystemIoBusNumber));
2122 KdPrint2((PRINT_PREFIX " BusInterruptLevel=%d\n", deviceExtension->BusInterruptLevel));
2123 KdPrint2((PRINT_PREFIX " BusInterruptVector=%d\n", deviceExtension->BusInterruptVector));
2125 deviceExtension->OrigAdapterInterfaceType,
2126 deviceExtension->SystemIoBusNumber,
2127 deviceExtension->BusInterruptLevel,
2128 deviceExtension->BusInterruptVector,
2129 &(BMList[i].Isr2Irql),
2130 &(BMList[i].Isr2Affinity));
2131
2132 Isr2DevExt = (PISR2_DEVICE_EXTENSION)(BMList[i].Isr2DevObj->DeviceExtension);
2133 Isr2DevExt->HwDeviceExtension = deviceExtension;
2134 Isr2DevExt->DevIndex = i;
2135
2136 KdPrint2((PRINT_PREFIX "isr2_de %#x\n", Isr2DevExt));
2137 KdPrint2((PRINT_PREFIX "isr2_vector %#x\n", BMList[i].Isr2Vector));
2138 KdPrint2((PRINT_PREFIX "isr2_irql %#x\n", BMList[i].Isr2Irql));
2139 KdPrint2((PRINT_PREFIX "isr2_affinity %#x\n", BMList[i].Isr2Affinity));
2140
2141// deviceExtension->QueueNewIrql = BMList[i].Isr2Irql;
2142
2143 KdPrint2((PRINT_PREFIX "IoConnectInterrupt\n"));
2145 &(BMList[i].Isr2InterruptObject),
2147 Isr2DevExt,
2148 NULL,
2149 BMList[i].Isr2Vector,
2150 BMList[i].Isr2Irql,
2151 BMList[i].Isr2Irql,
2152 (KINTERRUPT_MODE)(deviceExtension->InterruptMode),
2153 TRUE,
2155 FALSE);
2156
2157 if(!NT_SUCCESS(status)) {
2158 KdPrint2((PRINT_PREFIX "IoConnectInterrupt failed\n"));
2159 IoDeleteDevice(BMList[i].Isr2DevObj);
2162 return status;
2163 }
2164
2165 //deviceExtension->Isr2DevObj = BMList[i].Isr2DevObj;
2166
2167 return status;
2168} // end UniataConnectIntr2()
2169
2171NTAPI
2173 IN PVOID HwDeviceExtension
2174 )
2175{
2176 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2177 ULONG i = deviceExtension->DevIndex;
2178// NTSTATUS status;
2179
2180 KdPrint2((PRINT_PREFIX "Deinit ISR:\n"));
2181
2182 if(!BMList[i].Isr2DevObj) {
2183 KdPrint2((PRINT_PREFIX "Already uninitialized %#x\n"));
2184 return STATUS_SUCCESS;
2185 }
2186
2187 IoDisconnectInterrupt(BMList[i].Isr2InterruptObject);
2188
2190
2191 IoDeleteDevice(BMList[i].Isr2DevObj);
2192
2194 //deviceExtension->Isr2DevObj = NULL;
2195
2196 return STATUS_SUCCESS;
2197} // end UniataDisconnectIntr2()
2198
2199#endif //UNIATA_CORE
2200
2201BOOLEAN
2202NTAPI
2205 ULONG portBase) {
2206 // check if Primary/Secondary Master IDE claimed
2207 if((portBase == IO_WD1) &&
2208 (ConfigInfo->AtdiskPrimaryClaimed || AtdiskPrimaryClaimed)) {
2209 KdPrint2((PRINT_PREFIX "AtapiCheckIOInterference: AtdiskPrimaryClaimed\n"));
2210 return TRUE;
2211 } else
2212 if((portBase == IO_WD2) &&
2213 (ConfigInfo->AtdiskSecondaryClaimed || AtdiskSecondaryClaimed)) {
2214 KdPrint2((PRINT_PREFIX "AtapiCheckIOInterference: AtdiskSecondaryClaimed\n"));
2215 return TRUE;
2216 }
2217 return FALSE;
2218} // end AtapiCheckIOInterference()
2219
2220/*++
2221
2222Routine Description:
2223
2224 This function is called by the OS-specific port driver after
2225 the necessary storage has been allocated, to gather information
2226 about the adapter's configuration.
2227
2228Arguments:
2229
2230 HwDeviceExtension - HBA miniport driver's adapter data storage
2231 Context - Address of adapter count
2232 ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility.
2233 ConfigInfo - Configuration information structure describing HBA
2234 Again - Indicates search for adapters to continue
2235
2236Return Value:
2237
2238 ULONG
2239
2240--*/
2241ULONG
2242NTAPI
2244 IN PVOID HwDeviceExtension,
2247 IN PCHAR ArgumentString,
2249 OUT PBOOLEAN Again
2250 )
2251{
2252 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2253 PHW_CHANNEL chan;
2254 PULONG adapterCount = (PULONG)Context;
2255 PUCHAR ioSpace = NULL;
2256 ULONG i;
2257 ULONG irq=0;
2258 ULONG portBase=0;
2259 ULONG retryCount;
2260// BOOLEAN atapiOnly;
2261 UCHAR statusByte, statusByte2;
2262 BOOLEAN preConfig = FALSE;
2263 //
2264 PIDE_REGISTERS_1 BaseIoAddress1;
2265 PIDE_REGISTERS_2 BaseIoAddress2 = NULL;
2266
2267 // The following table specifies the ports to be checked when searching for
2268 // an IDE controller. A zero entry terminates the search.
2269 static CONST ULONG AdapterAddresses[5] = {IO_WD1, IO_WD2, IO_WD1-8, IO_WD2-8, 0};
2270// CONST UCHAR Channels[5] = {0, 1, 0, 1, 0};
2271
2272 // The following table specifies interrupt levels corresponding to the
2273 // port addresses in the previous table.
2274 static CONST ULONG InterruptLevels[5] = {14, 15, 11, 10, 0};
2275
2276 KdPrint2((PRINT_PREFIX "AtapiFindIsaController (ISA):\n"));
2277
2278 if (!deviceExtension) {
2279 return SP_RETURN_ERROR;
2280 }
2281 RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION));
2282
2283 KdPrint2((PRINT_PREFIX " assume max PIO4\n"));
2284 deviceExtension->MaxTransferMode = ATA_PIO4;
2285 deviceExtension->NumberChannels = 1;
2286 deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN; // default
2287
2288 if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) {
2289 goto exit_error;
2290 }
2291
2292 chan = &(deviceExtension->chan[0]);
2293 AtapiSetupLunPtrs(chan, deviceExtension, 0);
2294
2295 deviceExtension->AdapterInterfaceType =
2296 deviceExtension->OrigAdapterInterfaceType
2297 = ConfigInfo->AdapterInterfaceType;
2298
2299#ifndef UNIATA_CORE
2300
2301 /* do extra chipset specific setups */
2304
2305 // Check to see if this is a special configuration environment.
2306 portBase = irq = 0;
2307 if (ArgumentString) {
2308
2309 irq = AtapiParseArgumentString(ArgumentString, "Interrupt");
2310 if (irq ) {
2311
2312 // Both parameters must be present to proceed
2313 portBase = AtapiParseArgumentString(ArgumentString, "BaseAddress");
2314 if (!portBase) {
2315
2316 // Try a default search for the part.
2317 irq = 0;
2318 }
2319 }
2320 }
2321
2322#endif //UNIATA_CORE
2323/*
2324 for(i=0; i<2; i++) {
2325 if((*ConfigInfo->AccessRanges)[i].RangeStart) {
2326 KdPrint2((PRINT_PREFIX " IoRange[%d], start %#x, len %#x, mem %#x\n",
2327 i,
2328 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[i].RangeStart),
2329 (*ConfigInfo->AccessRanges)[i].RangeLength,
2330 (*ConfigInfo->AccessRanges)[i].RangeInMemory
2331 ));
2332 }
2333 }
2334*/
2335// if((*ConfigInfo->AccessRanges)[0].RangeStart) {
2336 portBase = ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart);
2337// }
2338 if(portBase) {
2339 if(!AtapiCheckIOInterference(ConfigInfo, portBase)) {
2340 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2341 ConfigInfo->AdapterInterfaceType,
2342 ConfigInfo->SystemIoBusNumber,
2343 (*ConfigInfo->AccessRanges)[0].RangeStart,
2344 (*ConfigInfo->AccessRanges)[0].RangeLength,
2345 (BOOLEAN) !((*ConfigInfo->AccessRanges)[0].RangeInMemory));
2346 } else {
2347 // do not touch resources, just fail later inside loop on next call to
2348 // AtapiCheckIOInterference()
2349 }
2350 *Again = FALSE;
2351 // Since we have pre-configured information we only need to go through this loop once
2352 preConfig = TRUE;
2353 KdPrint2((PRINT_PREFIX " preconfig, portBase=%x, len=%x\n", portBase, (*ConfigInfo->AccessRanges)[0].RangeLength));
2354 }
2355
2356 // Scan through the adapter address looking for adapters.
2357#ifndef UNIATA_CORE
2358 while (AdapterAddresses[*adapterCount] != 0) {
2359#else
2360 do {
2361#endif //UNIATA_CORE
2362
2363 retryCount = 4;
2364 deviceExtension->DevIndex = (*adapterCount); // this is used inside AtapiRegCheckDevValue()
2365 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: adapterCount=%d\n", *adapterCount));
2366
2367 for (i = 0; i < deviceExtension->NumberLuns; i++) {
2368 // Zero device fields to ensure that if earlier devices were found,
2369 // but not claimed, the fields are cleared.
2371 }
2372 // Get the system physical address for this IO range.
2373
2374 // Check if configInfo has the default information
2375 // if not, we go and find ourselves
2376 if (preConfig == FALSE) {
2377
2378 ULONG portBase_reg = 0;
2379 ULONG irq_reg = 0;
2380
2381 if (!portBase) {
2382 portBase = AdapterAddresses[*adapterCount];
2383 KdPrint2((PRINT_PREFIX "portBase[%d]=%x\n", *adapterCount, portBase));
2384 } else {
2385 KdPrint2((PRINT_PREFIX "portBase=%x\n", portBase));
2386 }
2387
2388 portBase_reg = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PortBase", 0);
2389 irq_reg = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Irq", 0);
2390 if(portBase_reg && irq_reg) {
2391 KdPrint2((PRINT_PREFIX "use registry settings portBase=%x, irq=%d\n", portBase_reg, irq_reg));
2392 portBase = portBase_reg;
2393 irq = irq_reg;
2394 }
2395 // check if Primary/Secondary Master IDE claimed
2396 if(AtapiCheckIOInterference(ConfigInfo, portBase)) {
2397 goto next_adapter;
2398 }
2399 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2400 ConfigInfo->AdapterInterfaceType,
2401 ConfigInfo->SystemIoBusNumber,
2403 ATA_IOSIZE,
2404 TRUE);
2405
2406 } else {
2407 KdPrint2((PRINT_PREFIX "preconfig portBase=%x\n", portBase));
2408 // Check if Primary/Secondary Master IDE claimed
2409 // We can also get here from preConfig branc with conflicting portBase
2410 // (and thus, w/o ioSpace allocated)
2411 if(AtapiCheckIOInterference(ConfigInfo, portBase)) {
2412 goto not_found;
2413 }
2414 }
2415 BaseIoAddress1 = (PIDE_REGISTERS_1)ioSpace;
2416next_adapter:
2417 // Update the adapter count.
2418 (*adapterCount)++;
2419
2420 // Check if ioSpace accessible.
2421 if (!ioSpace) {
2422 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: !ioSpace\n"));
2423 portBase = 0;
2424 continue;
2425 }
2426
2427 // Get the system physical address for the second IO range.
2428 if (BaseIoAddress1) {
2429 if(preConfig &&
2430 !ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[1].RangeStart)) {
2431 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: PCMCIA ?\n"));
2432 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2433 ConfigInfo->AdapterInterfaceType,
2434 ConfigInfo->SystemIoBusNumber,
2435 ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR)BaseIoAddress1 + 0x0E),
2437 TRUE);
2438 } else {
2439 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2440 ConfigInfo->AdapterInterfaceType,
2441 ConfigInfo->SystemIoBusNumber,
2444 TRUE);
2445 }
2446 }
2447 BaseIoAddress2 = (PIDE_REGISTERS_2)ioSpace;
2448 KdPrint2((PRINT_PREFIX " BaseIoAddress1=%x\n", BaseIoAddress1));
2449 KdPrint2((PRINT_PREFIX " BaseIoAddress2=%x\n", BaseIoAddress2));
2450 if(!irq) {
2451 KdPrint2((PRINT_PREFIX " expected InterruptLevel=%x\n", InterruptLevels[*adapterCount - 1]));
2452 }
2453
2454 UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2);
2455 UniataInitMapBM(deviceExtension, 0, FALSE);
2456
2457#ifdef _DEBUG
2458 UniataDumpATARegs(chan);
2459#endif
2460
2461 // Select master.
2462 SelectDrive(chan, 0);
2463
2464 statusByte = AtapiReadPort1(chan, IDX_IO1_i_Status);
2465 statusByte2 = AtapiReadPort1(chan, IDX_IO2_AltStatus);
2466 if((statusByte ^ statusByte2) & ~IDE_STATUS_INDEX) {
2467 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: Status %x vs AltStatus %x missmatch, abort init ?\n", statusByte, statusByte2));
2468
2469 if(BaseIoAddress2) {
2470 ScsiPortFreeDeviceBase(HwDeviceExtension,
2471 (PCHAR)BaseIoAddress2);
2472 BaseIoAddress2 = NULL;
2473 }
2474 BaseIoAddress2 = (PIDE_REGISTERS_2)((ULONGIO_PTR)BaseIoAddress1 + 0x0E);
2475 KdPrint2((PRINT_PREFIX " try BaseIoAddress2=%x\n", BaseIoAddress2));
2476 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2477 ConfigInfo->AdapterInterfaceType,
2478 ConfigInfo->SystemIoBusNumber,
2481 TRUE);
2482 if(!ioSpace) {
2483 BaseIoAddress2 = NULL;
2484 KdPrint2((PRINT_PREFIX " abort (0)\n"));
2485 goto not_found;
2486 }
2487 UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2);
2488 statusByte = AtapiReadPort1(chan, IDX_IO1_i_Status);
2489 statusByte2 = AtapiReadPort1(chan, IDX_IO2_AltStatus);
2490 if((statusByte ^ statusByte2) & ~IDE_STATUS_INDEX) {
2491 KdPrint2((PRINT_PREFIX " abort: Status %x vs AltStatus %x missmatch\n", statusByte, statusByte2));
2492 goto not_found;
2493 }
2494 }
2495
2496retryIdentifier:
2497
2498 // Select master.
2499 SelectDrive(chan, 0);
2500
2501 // Check if card at this address.
2503 statusByte = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
2504
2505 // Check if indentifier can be read back.
2506 if (AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) != 0xAA ||
2507 statusByte == IDE_STATUS_WRONG) {
2508
2509 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: Identifier read back from Master (%#x)\n",
2510 statusByte));
2511
2512 statusByte = AtapiReadPort1(chan, IDX_IO2_AltStatus);
2513
2514 if (statusByte != IDE_STATUS_WRONG && (statusByte & IDE_STATUS_BUSY)) {
2515
2516 i = 0;
2517
2518 // Could be the TEAC in a thinkpad. Their dos driver puts it in a sleep-mode that
2519 // warm boots don't clear.
2520 do {
2521 AtapiStallExecution(1000);
2522 statusByte = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_Status);
2524 "AtapiFindIsaController: First access to status %#x\n",
2525 statusByte));
2526 } while ((statusByte & IDE_STATUS_BUSY) && ++i < 10);
2527
2528 if (retryCount-- && (!(statusByte & IDE_STATUS_BUSY))) {
2529 goto retryIdentifier;
2530 }
2531 }
2532
2533 // Select slave.
2534 SelectDrive(chan, 1);
2535 statusByte = AtapiReadPort1(chan, IDX_IO2_AltStatus);
2536
2537 // See if slave is present.
2539
2540 if (AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) != 0xAA ||
2541 statusByte == IDE_STATUS_WRONG) {
2542
2544 "AtapiFindIsaController: Identifier read back from Slave (%#x)\n",
2545 statusByte));
2546 goto not_found;
2547 }
2548 }
2549
2550 // Fill in the access array information only if default params are not in there.
2551 if (preConfig == FALSE) {
2552
2553 // An adapter has been found request another call, only if we didn't get preconfigured info.
2554 *Again = TRUE;
2555
2556 if (portBase) {
2557 (*ConfigInfo->AccessRanges)[0].RangeStart = ScsiPortConvertUlongToPhysicalAddress(portBase);
2558 } else {
2559 (*ConfigInfo->AccessRanges)[0].RangeStart =
2560 ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount - 1]);
2561 }
2562
2563 (*ConfigInfo->AccessRanges)[0].RangeLength = ATA_IOSIZE;
2564 (*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE;
2565
2566 if(BaseIoAddress2) {
2567 if(hasPCI) {
2568 (*ConfigInfo->AccessRanges)[1].RangeStart = ScsiPortConvertUlongToPhysicalAddress((ULONG_PTR)BaseIoAddress2);
2569 (*ConfigInfo->AccessRanges)[1].RangeLength = ATA_ALTIOSIZE;
2570 (*ConfigInfo->AccessRanges)[1].RangeInMemory = FALSE;
2571 } else {
2572 // NT4 and NT3.51 on ISA-only hardware definitly fail floppy.sys load
2573 // when this range is claimed by other driver.
2574 // However, floppy should use only 0x3f0-3f5,3f7
2575 if((ULONGIO_PTR)BaseIoAddress2 >= 0x3f0 && (ULONGIO_PTR)BaseIoAddress2 <= 0x3f7) {
2576 KdPrint2((PRINT_PREFIX "!!! Possible AltStatus vs Floppy IO range interference !!!\n"));
2577 }
2578 KdPrint2((PRINT_PREFIX "Do not expose to OS on old ISA\n"));
2579 (*ConfigInfo->AccessRanges)[1].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
2580 (*ConfigInfo->AccessRanges)[1].RangeLength = 0;
2581 }
2582 }
2583
2584 // Indicate the interrupt level corresponding to this IO range.
2585 if (irq) {
2586 ConfigInfo->BusInterruptLevel = irq;
2587 } else {
2588 ConfigInfo->BusInterruptLevel = InterruptLevels[*adapterCount - 1];
2589 }
2590
2591 if (ConfigInfo->AdapterInterfaceType == MicroChannel) {
2592 ConfigInfo->InterruptMode = LevelSensitive;
2593 } else {
2594 ConfigInfo->InterruptMode = Latched;
2595 }
2596 }
2597
2598 ConfigInfo->NumberOfBuses = 1;
2599 ConfigInfo->MaximumNumberOfTargets = IDE_MAX_LUN_PER_CHAN;
2600
2601 // Indicate maximum transfer length is 64k.
2602 ConfigInfo->MaximumTransferLength = 0x10000;
2603 deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
2604
2605 KdPrint2((PRINT_PREFIX "de %#x, Channel ???\n", deviceExtension));
2606 //PrintNtConsole("de %#x, Channel %#x, nchan %#x\n",deviceExtension, channel, deviceExtension->NumberChannels);
2607
2608 KdPrint2((PRINT_PREFIX "chan = %#x\n", chan));
2609 //PrintNtConsole("chan = %#x, c=%#x\n", chan, c);
2610/*
2611 // should be already set up in AtapiSetupLunPtrs(chan, deviceExtension, 0);
2612
2613 chan->DeviceExtension = deviceExtension;
2614 chan->lChannel = 0;
2615 chan->lun[0] = &(deviceExtension->lun[0]);
2616 chan->lun[1] = &(deviceExtension->lun[1]);*/
2617
2618 /* do extra channel-specific setups */
2619 AtapiReadChipConfig(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, 0);
2620 AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, 0);
2621
2623 "AtapiFindIsaController: Found IDE at %#x\n",
2624 BaseIoAddress1));
2625
2626 // For Daytona, the atdisk driver gets the first shot at the
2627 // primary and secondary controllers.
2628 if (preConfig == FALSE) {
2629
2630 if (*adapterCount - 1 < 2) {
2631
2632 // Determine whether this driver is being initialized by the
2633 // system or as a crash dump driver.
2634 if (g_Dump) {
2635#ifndef UNIATA_CORE
2636 deviceExtension->DriverMustPoll = TRUE;
2637#endif //UNIATA_CORE
2638 } else {
2639 deviceExtension->DriverMustPoll = FALSE;
2640 }
2641
2642 } else {
2643 //atapiOnly = FALSE;
2644 }
2645
2646 } else {
2647
2648 //atapiOnly = FALSE;
2649 deviceExtension->DriverMustPoll = FALSE;
2650
2651 }// preConfig check
2652
2653 // Save the Interrupe Mode for later use
2654 deviceExtension->InterruptMode = ConfigInfo->InterruptMode;
2655 deviceExtension->BusInterruptLevel = ConfigInfo->BusInterruptLevel;
2656 deviceExtension->BusInterruptVector = ConfigInfo->BusInterruptVector;
2657
2659 "AtapiFindIsaController: look for devices\n"));
2660 // Search for devices on this controller.
2661 if (FindDevices(HwDeviceExtension,
2662 0,
2663 0 /* Channel */)) {
2664
2666 "AtapiFindIsaController: detected\n"));
2667 // Claim primary or secondary ATA IO range.
2668 if (portBase) {
2669 switch (portBase) {
2670 case IO_WD2:
2671 ConfigInfo->AtdiskSecondaryClaimed = TRUE;
2672 chan->PrimaryAddress = FALSE;
2673 break;
2674 case IO_WD1:
2675 ConfigInfo->AtdiskPrimaryClaimed = TRUE;
2676 chan->PrimaryAddress = TRUE;
2677 break;
2678 default:
2679 break;
2680 }
2681 } else {
2682 if (*adapterCount == 1) {
2683 ConfigInfo->AtdiskPrimaryClaimed = TRUE;
2684 chan->PrimaryAddress = TRUE;
2685 } else if (*adapterCount == 2) {
2686 ConfigInfo->AtdiskSecondaryClaimed = TRUE;
2687 chan->PrimaryAddress = FALSE;
2688 }
2689 }
2690
2691 if(deviceExtension->AdapterInterfaceType == Isa) {
2692 IsaCount++;
2693 } else
2694 if(deviceExtension->AdapterInterfaceType == MicroChannel) {
2695 MCACount++;
2696 }
2697
2698 ConfigInfo->NumberOfBuses++; // add virtual channel for communication port
2700 "AtapiFindIsaController: return SP_RETURN_FOUND\n"));
2701 return(SP_RETURN_FOUND);
2702 } else {
2703not_found:
2704 // No controller at this base address.
2705 if(BaseIoAddress1) {
2706 ScsiPortFreeDeviceBase(HwDeviceExtension,
2707 (PCHAR)BaseIoAddress1);
2708 BaseIoAddress1 = NULL;
2709 }
2710 if(BaseIoAddress2) {
2711 ScsiPortFreeDeviceBase(HwDeviceExtension,
2712 (PCHAR)BaseIoAddress2);
2713 BaseIoAddress2 = NULL;
2714 }
2715 for(i=0; i<2; i++) {
2717 "AtapiFindIsaController: cleanup AccessRanges %d\n", i));
2718 (*ConfigInfo->AccessRanges)[i].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
2719 (*ConfigInfo->AccessRanges)[i].RangeLength = 0;
2720 (*ConfigInfo->AccessRanges)[i].RangeInMemory = FALSE;
2721 }
2722 irq = 0;
2723 portBase = 0;
2724 }
2725#ifndef UNIATA_CORE
2726 }
2727#else
2728 } while(FALSE);
2729#endif //UNIATA_CORE
2730
2731 // The entire table has been searched and no adapters have been found.
2732 // There is no need to call again and the device base can now be freed.
2733 // Clear the adapter count for the next bus.
2734 *Again = FALSE;
2735 *(adapterCount) = 0;
2736
2738 "AtapiFindIsaController: return SP_RETURN_NOT_FOUND\n"));
2739 UniataFreeLunExt(deviceExtension);
2740 return(SP_RETURN_NOT_FOUND);
2741
2742exit_error:
2743 UniataFreeLunExt(deviceExtension);
2744 return SP_RETURN_ERROR;
2745
2746} // end AtapiFindIsaController()
2747
2748/*
2749 Do nothing, but parse ScsiPort ArgumentString and setup global variables.
2750*/
2751
2752ULONG
2753NTAPI
2755 IN PVOID HwDeviceExtension,
2758 IN PCHAR ArgumentString,
2760 OUT PBOOLEAN Again
2761 )
2762{
2763#ifndef __REACTOS__
2764 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2765#endif
2766
2767 if (AtapiParseArgumentString(ArgumentString, "dump") == 1) {
2769 "AtapiReadArgumentString: Crash dump\n"));
2770 //atapiOnly = FALSE;
2771 g_Dump = TRUE;
2772 }
2773 return(SP_RETURN_NOT_FOUND);
2774} // end AtapiReadArgumentString()
2775
2776ULONG
2777NTAPI
2779 IN PVOID HwDeviceExtension,
2780 IN ULONG lChannel,
2781 IN ULONG deviceNumber
2782 )
2783{
2784 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2785 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
2786 //ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0);
2787 PHW_LU_EXTENSION LunExt = chan->lun[deviceNumber];
2788
2789 SATA_SSTATUS_REG SStatus;
2790 UCHAR signatureLow;
2791 UCHAR signatureHigh;
2792
2793 if(LunExt->DeviceFlags & DFLAGS_HIDDEN) {
2794 KdPrint2((PRINT_PREFIX " hidden\n"));
2795 UniataForgetDevice(LunExt);
2796 return ATA_AT_HOME_NOBODY;
2797 }
2798 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
2799
2800 SStatus.Reg = UniataSataReadPort4(chan, IDX_SATA_SStatus, deviceNumber);
2801 KdPrint2((PRINT_PREFIX "SStatus %x\n", SStatus.Reg));
2802 if(SStatus.DET <= SStatus_DET_Dev_NoPhy) {
2803 KdPrint2((PRINT_PREFIX " SATA DET <= SStatus_DET_Dev_NoPhy\n"));
2804 return ATA_AT_HOME_NOBODY;
2805 }
2806 if(SStatus.SPD < SStatus_SPD_Gen1) {
2807 KdPrint2((PRINT_PREFIX " SATA SPD < SStatus_SPD_Gen1\n"));
2808 return ATA_AT_HOME_NOBODY;
2809 }
2810 if(SStatus.IPM == SStatus_IPM_NoDev) {
2811 KdPrint2((PRINT_PREFIX " SATA IPN == SStatus_IPM_NoDev\n"));
2812 return ATA_AT_HOME_NOBODY;
2813 }
2814 if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
2815 // Select the device for legacy.
2816 goto legacy_select;
2817 }
2818
2819 } else {
2820legacy_select:
2821 // Select the device.
2822 SelectDrive(chan, deviceNumber);
2824 }
2825
2826 if((deviceExtension->HwFlags & UNIATA_AHCI) &&
2827 UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
2828 KdPrint2((PRINT_PREFIX " AHCI check\n"));
2830 signatureLow = (UCHAR)(SIG >> 16);
2831 signatureHigh = (UCHAR)(SIG >> 24);
2832 } else {
2833 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
2834 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
2835 }
2836
2837 if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) {
2838 KdPrint2((PRINT_PREFIX " ATAPI at home\n"));
2839 return ATA_AT_HOME_ATAPI;
2840 }
2841 if(deviceExtension->HwFlags & UNIATA_AHCI) {
2842 KdPrint2((PRINT_PREFIX " AHCI HDD at home\n"));
2843 return ATA_AT_HOME_HDD;
2844 }
2845 if(g_opt_VirtualMachine > VM_NONE /*== VM_BOCHS ||
2846 g_opt_VirtualMachine == VM_VBOX*/) {
2847 GetStatus(chan, signatureLow);
2848 if(!signatureLow) {
2849 KdPrint2((PRINT_PREFIX " 0-status VM - not present\n"));
2850 UniataForgetDevice(LunExt);
2851 return ATA_AT_HOME_NOBODY;
2852 }
2853 }
2854
2856
2860 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber);
2861 if(signatureLow != 0x55) {
2862 if(signatureLow == 0xff || signatureLow == 0) {
2863 KdPrint2((PRINT_PREFIX " nobody home! %#x != 0x55\n", signatureLow));
2864 UniataForgetDevice(LunExt);
2865 return ATA_AT_HOME_NOBODY;
2866 }
2867 // another chance
2868 signatureLow = AtapiReadPort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh);
2869 signatureLow += 2;
2872 signatureHigh = AtapiReadPort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh);
2873 if(signatureLow != signatureHigh) {
2874 KdPrint2((PRINT_PREFIX " nobody home! last chance failed %#x != %#x\n", signatureLow, signatureHigh));
2875 UniataForgetDevice(LunExt);
2876 return ATA_AT_HOME_NOBODY;
2877 }
2878 return ATA_AT_HOME_XXX;
2879 }
2880
2884 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber);
2885 if(signatureLow != 0xAA) {
2886 KdPrint2((PRINT_PREFIX " nobody home! %#x != 0xAA\n", signatureLow));
2887 UniataForgetDevice(LunExt);
2888 return ATA_AT_HOME_NOBODY;
2889 }
2890
2891 KdPrint2((PRINT_PREFIX " HDD at home\n"));
2892 return ATA_AT_HOME_HDD;
2893} // end UniataAnybodyHome()
2894
2895ULONG
2896NTAPI
2898 IN PVOID HwDeviceExtension,
2899 IN ULONG lChannel,
2900 IN ULONG deviceNumber,
2901 IN BOOLEAN ResetDev
2902 )
2903{
2904 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2905 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
2906 //ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0);
2907 PHW_LU_EXTENSION LunExt;
2908
2909 UCHAR signatureLow,
2910 signatureHigh;
2911 UCHAR statusByte;
2912 ULONG RetVal=0;
2913 ULONG waitCount = g_opt_WaitBusyResetCount;
2914 ULONG at_home = 0;
2915
2916 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x\n",
2917 deviceNumber));
2918
2919 if(deviceNumber >= chan->NumberLuns) {
2920 return 0;
2921 }
2922 if(deviceExtension->HwFlags & UNIATA_AHCI) {
2923 if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
2924 return 0;
2925 }
2926 }
2927 LunExt = chan->lun[deviceNumber];
2928
2929 if(ResetDev) {
2930 LunExt->PowerState = 0;
2931 }
2932
2933 if((deviceExtension->HwFlags & UNIATA_SATA) &&
2934 !UniataIsSATARangeAvailable(deviceExtension, lChannel) &&
2935 deviceNumber) {
2936 KdPrint2((PRINT_PREFIX " SATA w/o i/o registers, check slave presence\n"));
2937 SelectDrive(chan, deviceNumber & 0x01);
2938 statusByte = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_DriveSelect);
2939 KdPrint2((PRINT_PREFIX " DriveSelect: %#x\n", statusByte));
2940 if((statusByte & IDE_DRIVE_MASK) != IDE_DRIVE_SELECT_2) {
2941 KdPrint2((PRINT_PREFIX "CheckDevice: (no dev)\n"));
2942 UniataForgetDevice(LunExt);
2943 return 0;
2944 }
2945 }
2946
2947 if(ResetDev && (deviceExtension->HwFlags & UNIATA_AHCI)) {
2948 KdPrint2((PRINT_PREFIX "CheckDevice: reset AHCI dev\n"));
2949 if(UniataAhciSoftReset(HwDeviceExtension, chan->lChannel, deviceNumber) == (ULONG)(-1)) {
2950 KdPrint2((PRINT_PREFIX "CheckDevice: (no dev)\n"));
2951 UniataForgetDevice(LunExt);
2952 return 0;
2953 }
2954 } else
2955 if(ResetDev) {
2956 KdPrint2((PRINT_PREFIX "CheckDevice: reset dev\n"));
2957
2958 // Reset device
2959 AtapiSoftReset(chan, deviceNumber);
2960
2961 if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
2962 //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 1\n"));
2963 return 0;
2964 }
2965 statusByte = WaitOnBusy(chan);
2966
2967 if((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) {
2969 "CheckDevice: bad status %x\n", statusByte));
2970 } else
2971 if(statusByte != IDE_STATUS_WRONG && (statusByte & IDE_STATUS_BUSY)) {
2972 // Perform hard-reset.
2974 "CheckDevice: BUSY\n"));
2975
2976 AtapiHardReset(chan, FALSE, 500 * 1000);
2977/*
2978 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER );
2979 chan->last_devsel = -1;
2980 AtapiStallExecution(500 * 1000);
2981 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER);
2982*/
2983 SelectDrive(chan, deviceNumber & 0x01);
2984
2985 do {
2986 // Wait for Busy to drop.
2988 GetStatus(chan, statusByte);
2989
2990 } while ((statusByte & IDE_STATUS_BUSY) && waitCount--);
2991
2992 GetBaseStatus(chan, statusByte);
2994 "CheckDevice: status after hard reset %x\n", statusByte));
2995 }
2996
2997 if((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) {
2999 "CheckDevice: no dev ?\n"));
3000 UniataForgetDevice(LunExt);
3001 return 0;
3002 } else
3003 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
3004 //if(deviceExtension->HwFlags & UNIATA_SATA) {
3006 "CheckDevice: try enable SATA Phy\n"));
3007 statusByte = UniataSataPhyEnable(HwDeviceExtension, lChannel, deviceNumber);
3008 if(statusByte == IDE_STATUS_WRONG) {
3009 KdPrint2((PRINT_PREFIX "CheckDevice: status %#x (no dev)\n", statusByte));
3010 UniataForgetDevice(LunExt);
3011 return 0;
3012 }
3013 }
3014 }
3015
3016 if(deviceExtension->HwFlags & UNIATA_AHCI) {
3017 RetVal = LunExt->DeviceFlags;
3018 signatureLow = signatureHigh = 0; // make GCC happy
3019 } else {
3020 // Select the device.
3021 SelectDrive(chan, deviceNumber);
3022
3023 if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
3024 //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 2\n"));
3025 return 0;
3026 }
3027
3028 statusByte = WaitOnBaseBusyLong(chan);
3029
3030 GetBaseStatus(chan, statusByte);
3031 if(deviceExtension->HwFlags & UNIATA_SATA) {
3032 UniataSataClearErr(HwDeviceExtension, lChannel, UNIATA_SATA_IGNORE_CONNECT, deviceNumber);
3033 }
3034
3035 KdPrint2((PRINT_PREFIX "CheckDevice: status %#x\n", statusByte));
3036 if(((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) ||
3037 (statusByte & IDE_STATUS_BUSY)) {
3038 KdPrint2((PRINT_PREFIX "CheckDevice: busy => return\n"));
3039 UniataForgetDevice(LunExt);
3040 return 0;
3041 }
3042
3043 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
3044 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
3045 }
3046
3047 // set default costs
3051 LunExt->AtapiReadyWaitDelay = 0;
3052
3053 if(deviceExtension->HwFlags & UNIATA_AHCI) {
3054 if(RetVal & DFLAGS_DEVICE_PRESENT) {
3055 if(IssueIdentify(HwDeviceExtension,
3056 deviceNumber,
3057 lChannel,
3059 FALSE)) {
3060 // OK
3061 KdPrint2((PRINT_PREFIX "CheckDevice: detected AHCI Device %#x\n",
3062 deviceNumber));
3063 } else {
3064 //RetVal &= ~DFLAGS_ATAPI_DEVICE;
3065 //LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE;
3066
3067 UniataForgetDevice(LunExt);
3068 RetVal = 0;
3069 }
3070 }
3071 } else
3072 if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) {
3073
3074 KdPrint2((PRINT_PREFIX "CheckDevice: ATAPI signature found\n"));
3075 // ATAPI signature found.
3076 // Issue the ATAPI identify command if this
3077 // is not for the crash dump utility.
3078try_atapi:
3079 if (!g_Dump) {
3080
3081 // Issue ATAPI packet identify command.
3082 if (IssueIdentify(HwDeviceExtension,
3083 deviceNumber,
3084 lChannel,
3086
3087 // Indicate ATAPI device.
3088 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x is ATAPI\n",
3089 deviceNumber));
3090
3093
3094 // some ATAPI devices doesn't work with DPC on CMD-649
3095 // and probably some other controllers
3096 if(deviceExtension->HwFlags & UNIATA_NO_DPC_ATAPI) {
3097 /* CMD 649, ROSB SWK33, ICH4 */
3098 KdPrint2((PRINT_PREFIX "CheckDevice: UNIATA_NO_DPC_ATAPI\n"));
3099 deviceExtension->UseDpc = FALSE;
3100 }
3101
3102 GetStatus(chan, statusByte);
3103 if (statusByte & IDE_STATUS_ERROR) {
3104 AtapiSoftReset(chan, deviceNumber);
3105 }
3106
3107 } else {
3108forget_device:
3109 // Indicate no working device.
3110 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x not responding\n",
3111 deviceNumber));
3112
3113 UniataForgetDevice(LunExt);
3114 RetVal = 0;
3115 }
3116 GetBaseStatus(chan, statusByte);
3117
3118 }
3119
3120 } else {
3121
3122 KdPrint2((PRINT_PREFIX "CheckDevice: IDE device check\n"));
3123 // Issue IDE Identify. If an Atapi device is actually present, the signature
3124 // will be asserted, and the drive will be recognized as such.
3125 if(deviceExtension->DWordIO) {
3126 KdPrint2((PRINT_PREFIX " try 32bit IO\n"));
3128 }
3129 if (IssueIdentify(HwDeviceExtension,
3130 deviceNumber,
3131 lChannel,
3133
3134 // IDE drive found.
3135 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x is IDE\n",
3136 deviceNumber));
3137
3138 // Indicate IDE - not ATAPI device.
3139 RetVal = DFLAGS_DEVICE_PRESENT;
3141 LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE;
3142 } else
3144 // This can be ATAPI on broken hardware
3145 GetBaseStatus(chan, statusByte);
3146 if(!at_home && UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) {
3147 KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home post IDE\n"));
3148 goto forget_device;
3149 }
3150 KdPrint2((PRINT_PREFIX "CheckDevice: try ATAPI %#x, status %#x\n",
3151 deviceNumber, statusByte));
3152 goto try_atapi;
3153 } else {
3154 KdPrint2((PRINT_PREFIX "CheckDevice: VM Device %#x not present\n",
3155 deviceNumber));
3156 }
3157 GetBaseStatus(chan, statusByte);
3158 }
3159 KdPrint2((PRINT_PREFIX "CheckDevice: check status: %sfound\n", RetVal ? "" : "not "));
3160 return RetVal;
3161} // end CheckDevice()
3162
3163
3164/*++
3165
3166Routine Description:
3167
3168 This routine is called from AtapiFindXxxController to identify
3169 devices attached to an IDE controller.
3170
3171Arguments:
3172
3173 HwDeviceExtension - HBA miniport driver's adapter data storage
3174 AtapiOnly - Indicates that routine should return TRUE only if
3175 an ATAPI device is attached to the controller.
3176
3177Return Value:
3178
3179 TRUE - True if devices found.
3180
3181--*/
3182BOOLEAN
3183NTAPI
3185 IN PVOID HwDeviceExtension,
3186 IN ULONG Flags,
3187 IN ULONG Channel
3188 )
3189{
3190 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
3191 PHW_CHANNEL chan = &(deviceExtension->chan[Channel]);
3192 PHW_LU_EXTENSION LunExt;
3193 BOOLEAN deviceResponded = FALSE,
3194 skipSetParameters = FALSE;
3195 ULONG waitCount = 10000;
3196 //ULONG deviceNumber;
3197 ULONG i;
3198 UCHAR statusByte;
3199 ULONG max_ldev;
3200 BOOLEAN AtapiOnly = FALSE;
3201
3202 KdPrint2((PRINT_PREFIX "FindDevices:\n"));
3203
3204 // Disable interrupts
3205 AtapiDisableInterrupts(deviceExtension, Channel);
3206// AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_DISABLE_INTERRUPTS | IDE_DC_A_4BIT );
3207
3208 // Clear expecting interrupt flag and current SRB field.
3210// chan->CurrentSrb = NULL;
3211// max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : IDE_MAX_LUN_PER_CHAN;
3212 max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : deviceExtension->NumberLuns;
3213 KdPrint2((PRINT_PREFIX " max_ldev %d\n", max_ldev));
3214
3215 // Search for devices.
3216 for (i = 0; i < max_ldev; i++) {
3217 //AtapiDisableInterrupts(deviceExtension, Channel);
3219 chan->lun[i]->DeviceFlags &= ~DFLAGS_HIDDEN;
3220 }
3221 deviceResponded |=
3222 (CheckDevice(HwDeviceExtension, Channel, i, TRUE) != 0);
3223 //AtapiEnableInterrupts(deviceExtension, Channel);
3224 }
3225
3226 if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
3227 AtapiEnableInterrupts(deviceExtension, Channel);
3229 "FindDevices: returning %d (AHCI)\n",
3230 deviceResponded));
3231 return deviceResponded;
3232 }
3233
3234 for (i = 0; i < max_ldev; i++) {
3235 LunExt = chan->lun[i];
3236
3237 if (( LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT) &&
3238 !(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) &&
3239 !(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) && deviceResponded) {
3240
3241 // This hideous hack is to deal with ESDI devices that return
3242 // garbage geometry in the IDENTIFY data.
3243 // This is ONLY for the crashdump environment as
3244 // these are ESDI devices.
3245 if (LunExt->IdentifyData.SectorsPerTrack == 0x35 &&
3246 LunExt->IdentifyData.NumberOfHeads == 0x07) {
3247
3248 KdPrint2((PRINT_PREFIX "FindDevices: Found nasty Compaq ESDI!\n"));
3249
3250 // Change these values to something reasonable.
3251 LunExt->IdentifyData.SectorsPerTrack = 0x34;
3252 LunExt->IdentifyData.NumberOfHeads = 0x0E;
3253 }
3254
3255 if (LunExt->IdentifyData.SectorsPerTrack == 0x35 &&
3256 LunExt->IdentifyData.NumberOfHeads == 0x0F) {
3257
3258 KdPrint2((PRINT_PREFIX "FindDevices: Found nasty Compaq ESDI!\n"));
3259
3260 // Change these values to something reasonable.
3261 LunExt->IdentifyData.SectorsPerTrack = 0x34;
3262 LunExt->IdentifyData.NumberOfHeads = 0x0F;
3263 }
3264
3265
3266 if (LunExt->IdentifyData.SectorsPerTrack == 0x36 &&
3267 LunExt->IdentifyData.NumberOfHeads == 0x07) {
3268
3269 KdPrint2((PRINT_PREFIX "FindDevices: Found nasty UltraStor ESDI!\n"));
3270
3271 // Change these values to something reasonable.
3272 LunExt->IdentifyData.SectorsPerTrack = 0x3F;
3273 LunExt->IdentifyData.NumberOfHeads = 0x10;
3274 skipSetParameters = TRUE;
3275 }
3276
3277
3278 if (skipSetParameters)
3279 continue;
3280
3281 statusByte = WaitOnBusy(chan);
3282
3283 // Select the device.
3284 SelectDrive(chan, i & 0x01);
3285 GetStatus(chan, statusByte);
3286
3287 if (statusByte & IDE_STATUS_ERROR) {
3288
3289 // Reset the device.
3291 "FindDevices: Resetting controller before SetDriveParameters.\n"));
3292
3293 AtapiHardReset(chan, FALSE, 500 * 1000);
3294/*
3295 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER );
3296 chan->last_devsel = -1;
3297 AtapiStallExecution(500 * 1000);
3298 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER);
3299*/
3300 SelectDrive(chan, i & 0x01);
3301
3302 do {
3303 // Wait for Busy to drop.
3305 GetStatus(chan, statusByte);
3306
3307 } while ((statusByte & IDE_STATUS_BUSY) && waitCount--);
3308 }
3309
3310 statusByte = WaitOnBusy(chan);
3311
3313 "FindDevices: Status before SetDriveParameters: (%#x) (%#x)\n",
3314 statusByte,
3316
3317 GetBaseStatus(chan, statusByte);
3318
3319 // Use the IDENTIFY data to set drive parameters.
3320 if (!SetDriveParameters(HwDeviceExtension,i,Channel)) {
3321
3323 "FindDevices: Set drive parameters for device %d failed\n",
3324 i));
3325 // Don't use this device as writes could cause corruption.
3326 LunExt->DeviceFlags &= ~DFLAGS_DEVICE_PRESENT;
3327 UniataForgetDevice(LunExt);
3328 continue;
3329
3330 }
3331 if (LunExt->DeviceFlags & DFLAGS_REMOVABLE_DRIVE) {
3332
3333 // Pick up ALL IDE removable drives that conform to Yosemite V0.2...
3334 AtapiOnly = FALSE;
3335 }
3336
3337 // Indicate that a device was found.
3338 if (!AtapiOnly) {
3339 deviceResponded = TRUE;
3340 }
3341 }
3342 }
3343
3344/* // Reset the controller. This is a feeble attempt to leave the ESDI
3345 // controllers in a state that ATDISK driver will recognize them.
3346 // The problem in ATDISK has to do with timings as it is not reproducible
3347 // in debug. The reset should restore the controller to its poweron state
3348 // and give the system enough time to settle.
3349 if (!deviceResponded) {
3350
3351 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_RESET_CONTROLLER );
3352 AtapiStallExecution(50 * 1000);
3353 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_REENABLE_CONTROLLER);
3354 }
3355*/
3356 if(deviceResponded) {
3357 for (i = 0; i < max_ldev; i++) {
3358 LunExt = chan->lun[i];
3359
3361 "FindDevices: select %d dev to clear INTR\n", i));
3362 SelectDrive(chan, i);
3363 GetBaseStatus(chan, statusByte);
3365 "FindDevices: statusByte=%#x\n", statusByte));
3366 }
3367 for (i = 0; i < max_ldev; i++) {
3368 LunExt = chan->lun[i];
3369
3370 if(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT) {
3371 // Make sure some device (master is preferred) is selected on exit.
3373 "FindDevices: select %d dev on exit\n", i));
3374 SelectDrive(chan, i);
3375 break;
3376 }
3377 }
3378 }
3379
3380 GetBaseStatus(chan, statusByte);
3381 // Enable interrupts
3382 AtapiEnableInterrupts(deviceExtension, Channel);
3383// AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_A_4BIT );
3384 GetBaseStatus(chan, statusByte);
3385
3387 "FindDevices: returning %d\n",
3388 deviceResponded));
3389
3390 return deviceResponded;
3391
3392} // end FindDevices()
unsigned char BOOLEAN
#define DFLAGS_ATAPI_DEVICE
Definition: atapi.h:41
#define GetBaseStatus(BaseIoAddress, Status)
Definition: atapi.h:331
struct _IDE_REGISTERS_2 * PIDE_REGISTERS_2
#define IDE_COMMAND_ATAPI_IDENTIFY
Definition: atapi.h:110
#define IDE_COMMAND_IDENTIFY
Definition: atapi.h:118
#define GetStatus(BaseIoAddress, Status)
Definition: atapi.h:328
#define DFLAGS_TAPE_DEVICE
Definition: atapi.h:42
#define DFLAGS_REMOVABLE_DRIVE
Definition: atapi.h:45
#define WaitOnBusy(BaseIoAddress, Status)
Definition: atapi.h:359
#define DFLAGS_DEVICE_PRESENT
Definition: atapi.h:40
struct _IDE_REGISTERS_1 * PIDE_REGISTERS_1
#define AtapiSoftReset(BaseIoAddress, DeviceNumber)
Definition: atapi.h:418
ULONG NTAPI AtapiParseArgumentString(IN PCHAR String, IN PCHAR KeyWord)
Definition: atapi.c:1852
struct _HW_LU_EXTENSION HW_LU_EXTENSION
BOOLEAN NTAPI SetDriveParameters(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG Channel)
Definition: atapi.c:636
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
struct _HW_DEVICE_EXTENSION HW_DEVICE_EXTENSION
BOOLEAN NTAPI IssueIdentify(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG Channel, IN UCHAR Command)
Definition: atapi.c:251
LONG NTSTATUS
Definition: precomp.h:26
#define CHAR(Char)
BUSMASTER_CONTROLLER_INFORMATION_BASE const BusMasterAdapters[]
Definition: bm_devs.h:40
#define IDE_MAX_CHAN
Definition: bm_devs_decl.h:42
#define UNIATA_RAID_CONTROLLER
Definition: bm_devs_decl.h:623
#define NUM_BUSMASTER_ADAPTERS
Definition: bm_devs_decl.h:742
__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:753
#define UNIATA_NO_DPC_ATAPI
Definition: bm_devs_decl.h:628
#define UNIATA_SATA
Definition: bm_devs_decl.h:626
#define UNIATA_AHCI
Definition: bm_devs_decl.h:629
struct _BUSMASTER_CONTROLLER_INFORMATION BUSMASTER_CONTROLLER_INFORMATION
#define UNIATA_NO_SLAVE
Definition: bm_devs_decl.h:625
#define IDE_MAX_LUN_PER_CHAN
Definition: bm_devs_decl.h:46
#define UNIATA_NO_DPC
Definition: bm_devs_decl.h:627
#define IDE_DEFAULT_MAX_CHAN
Definition: bm_devs_decl.h:43
#define Ata_is_supported_dev(pciData)
Definition: bm_devs_decl.h:777
#define Ata_is_ahci_dev(pciData)
Definition: bm_devs_decl.h:781
#define BMLIST_TERMINATOR
Definition: bm_devs_decl.h:738
struct _BUSMASTER_CONTROLLER_INFORMATION * PBUSMASTER_CONTROLLER_INFORMATION
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:1497
SCSI_PHYSICAL_ADDRESS NTAPI ScsiPortConvertUlongToPhysicalAddress(IN ULONG_PTR UlongAddress)
Definition: scsiport.c:529
VOID NTAPI ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension, IN PVOID MappedAddress)
Definition: scsiport.c:549
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:571
BOOLEAN NTAPI UniataAllocateLunExt(PHW_DEVICE_EXTENSION deviceExtension, ULONG NewNumberChannels)
Definition: id_init.cpp:2891
#define SStatus_DET_Dev_NoPhy
Definition: bsmaster.h:285
UCHAR NTAPI AtapiDmaDone(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:685
BOOLEAN WinVer_WDM_Model
Definition: id_ata.cpp:112
#define IDX_BM_IO
Definition: bsmaster.h:163
#define REORDER_MCOST_SWITCH_RW_HDD
Definition: bsmaster.h:990
#define PCI_DEV_SUBCLASS_SATA
Definition: bsmaster.h:122
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 IsMasterDev(pciData)
Definition: bsmaster.h:861
#define ATA_ALTOFFSET
Definition: bsmaster.h:87
#define ATA_BM_OFFSET1
Definition: bsmaster.h:85
VOID NTAPI AtapiSetupLunPtrs(IN PHW_CHANNEL chan, IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG c)
Definition: id_init.cpp:2846
#define VM_VMWARE
Definition: bsmaster.h:1904
#define REORDER_COST_SWITCH_RW_HDD
Definition: bsmaster.h:989
#define VM_BOCHS
Definition: bsmaster.h:1906
#define VM_AUTO
Definition: bsmaster.h:1901
ULONG g_opt_WaitBusyResetCount
Definition: id_ata.cpp:89
#define ATA_PCCARD_ALTOFFSET
Definition: bsmaster.h:88
VOID NTAPI UniataForgetDevice(PHW_LU_EXTENSION LunExt)
Definition: id_ata.cpp:2385
UCHAR DDKFASTAPI AtapiReadPort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port)
#define SStatus_SPD_Gen1
Definition: bsmaster.h:292
struct _ISR2_DEVICE_EXTENSION * PISR2_DEVICE_EXTENSION
#define DMA_MODE_NONE
Definition: bsmaster.h:1706
#define PCIBUSNUM_NOT_SPECIFIED
Definition: bsmaster.h:1451
#define IDX_BM_Status
Definition: bsmaster.h:169
#define SStatus_IPM_NoDev
Definition: bsmaster.h:298
union _ATA_REQ ATA_REQ
struct _IDE_BUSMASTER_REGISTERS * PIDE_BUSMASTER_REGISTERS
#define IDX_SATA_IO
Definition: bsmaster.h:453
#define PCI_DEV_SUBCLASS_ATA
Definition: bsmaster.h:121
#define VM_NONE
Definition: bsmaster.h:1902
#define PCI_IDE_PROGIF_NATIVE_ALL
Definition: bsmaster.h:859
#define BM_STATUS_SIMPLEX_ONLY
Definition: bsmaster.h:148
#define IsBusMaster(pciData)
Definition: bsmaster.h:853
#define VM_QEMU
Definition: bsmaster.h:1905
#define REORDER_MCOST_SEEK_BACK_HDD
Definition: bsmaster.h:991
VOID NTAPI AtapiDmaAlloc(IN PVOID HwDeviceExtension, IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, IN ULONG lChannel)
Definition: id_dma.cpp:138
ULONG g_opt_VirtualMachine
Definition: id_ata.cpp:105
ULONG SkipRaids
Definition: id_ata.cpp:77
UNICODE_STRING SavedRegPath
Definition: id_ata.cpp:69
#define IDX_AHCI_P_SIG
Definition: bsmaster.h:688
#define UNIATA_ALLOCATE_NEW_LUNS
Definition: bsmaster.h:1398
BOOLEAN g_Dump
Definition: id_ata.cpp:108
#define ATA_IOSIZE
Definition: bsmaster.h:86
#define PCI_DEV_SUBCLASS_IDE
Definition: bsmaster.h:119
#define PCI_DEV_CLASS_STORAGE
Definition: bsmaster.h:117
#define PCISLOTNUM_NOT_SPECIFIED
Definition: bsmaster.h:1452
BOOLEAN NTAPI AtapiReadChipConfig(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG channel)
Definition: id_init.cpp:1782
BOOLEAN InDriverEntry
Definition: id_ata.cpp:107
BOOLEAN NTAPI AtapiInterrupt2(IN PKINTERRUPT Interrupt, IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:4192
#define IO_WD2
Definition: bsmaster.h:79
#define BM_STATUS_INTR
Definition: bsmaster.h:144
#define VM_VBOX
Definition: bsmaster.h:1903
VOID DDKFASTAPI AtapiWritePort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN UCHAR data)
#define PCI_DEV_SUBCLASS_RAID
Definition: bsmaster.h:120
#define ATA_ALTIOSIZE
Definition: bsmaster.h:89
#define CTRFLAGS_NO_SLAVE
Definition: bsmaster.h:1139
#define IDX_SATA_SStatus
Definition: bsmaster.h:457
VOID NTAPI UniataFreeLunExt(PHW_DEVICE_EXTENSION deviceExtension)
Definition: id_init.cpp:2956
BOOLEAN NTAPI AtapiChipInit(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG c)
Definition: id_init.cpp:1879
#define GetDmaStatus(de, c)
Definition: bsmaster.h:1711
#define DMA_MODE_BM
Definition: bsmaster.h:1707
#define IO_WD1
Definition: bsmaster.h:78
ULONG ForceSimplex
Definition: id_ata.cpp:78
BOOLEAN hasPCI
Definition: id_ata.cpp:103
Definition: bufpool.h:45
_In_ PVOID Argument2
Definition: classpnp.h:721
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
MMRESULT FindDevices()
Definition: utils.c:159
#define UlongToPtr(u)
Definition: config.h:106
#define ULONG_PTR
Definition: config.h:101
#define ULONGIO_PTR
Definition: config.h:102
#define PtrToUlong(u)
Definition: config.h:107
#define SP_RETURN_ERROR
Definition: srb.h:523
#define SP_RETURN_FOUND
Definition: srb.h:522
#define ScsiPortConvertPhysicalAddressToUlong(Address)
Definition: srb.h:957
#define SP_RETURN_NOT_FOUND
Definition: srb.h:521
struct _PORT_CONFIGURATION_INFORMATION_COMMON * PPORT_CONFIGURATION_INFORMATION_COMMON
NTHALAPI NTSTATUS NTAPI HalAssignSlotResources(PUNICODE_STRING, PUNICODE_STRING, PDRIVER_OBJECT, PDEVICE_OBJECT, INTERFACE_TYPE, ULONG, ULONG, PCM_RESOURCE_LIST *)
NTHALAPI ULONG NTAPI HalGetBusData(BUS_DATA_TYPE, ULONG, ULONG, PVOID, ULONG)
NTHALAPI ULONG NTAPI HalGetInterruptVector(INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY)
unsigned char irq
Definition: dsp.h:13
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define WinVer_2k
Definition: CrossNt.h:114
#define WinVer_Id()
Definition: CrossNt.h:109
#define WinVer_NT
Definition: CrossNt.h:112
const GLubyte * c
Definition: glext.h:8905
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
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
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
#define IDE_STATUS_WRONG
Definition: hwide.h:121
#define IDX_IO1_o_BlockNumber
Definition: hwide.h:56
#define IDE_STATUS_INDEX
Definition: hwide.h:111
#define ATAPI_MAGIC_MSB
Definition: hwide.h:287
#define IDX_ATAPI_IO1_o_ByteCountHigh
Definition: hwide.h:101
#define IDX_IO1_i_BlockNumber
Definition: hwide.h:44
#define IDE_STATUS_BUSY
Definition: hwide.h:119
#define IDE_STATUS_ERROR
Definition: hwide.h:110
#define IDE_DRIVE_MASK
Definition: hwide.h:132
#define IDX_IO1_i_Status
Definition: hwide.h:48
#define IDX_IO1_i_DriveSelect
Definition: hwide.h:47
#define IDX_IO1_i_CylinderLow
Definition: hwide.h:45
#define IDX_ATAPI_IO1_i_Status
Definition: hwide.h:94
#define IDX_IO1_i_CylinderHigh
Definition: hwide.h:46
#define IDE_DRIVE_SELECT_2
Definition: hwide.h:131
#define IDX_ATAPI_IO1_i_DriveSelect
Definition: hwide.h:93
#define IDX_IO1_o_CylinderLow
Definition: hwide.h:57
#define ATAPI_MAGIC_LSB
Definition: hwide.h:286
struct _CM_RESOURCE_LIST * PCM_RESOURCE_LIST
@ PCIBus
Definition: hwresource.cpp:142
@ MicroChannel
Definition: hwresource.cpp:140
@ Isa
Definition: hwresource.cpp:138
ULONG BMListLen
Definition: id_probe.cpp:54
BOOLEAN AtdiskSecondaryClaimed
Definition: id_probe.cpp:62
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
ULONG maxPciBus
Definition: id_probe.cpp:67
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
VOID NTAPI AtapiDoNothing(VOID)
Definition: id_probe.cpp:86
BOOLEAN NTAPI UniataCheckPCISubclass(BOOLEAN known, ULONG RaidFlags, UCHAR SubClass)
Definition: id_probe.cpp:256
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
ULONG NTAPI UniataEnumBusMasterController__()
Definition: id_probe.cpp:299
ULONG IsaCount
Definition: id_probe.cpp:55
ULONG NTAPI CheckDevice(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG deviceNumber, IN BOOLEAN ResetDev)
Definition: id_probe.cpp:2897
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
NTSTATUS NTAPI UniataClaimLegacyPCIIDE(ULONG i)
Definition: id_probe.cpp:1939
ULONG MCACount
Definition: id_probe.cpp:56
NTSTATUS NTAPI UniataConnectIntr2(IN PVOID HwDeviceExtension)
Definition: id_probe.cpp:2050
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
static CONST ULONG StdIsaPorts[]
Definition: id_probe.cpp:291
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
UCHAR pciBuffer[256]
Definition: id_probe.cpp:66
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
PDRIVER_OBJECT SavedDriverObject
Definition: id_probe.cpp:69
BOOLEAN AtdiskPrimaryClaimed
Definition: id_probe.cpp:61
NTSTATUS NTAPI UniataDisconnectIntr2(IN PVOID HwDeviceExtension)
Definition: id_probe.cpp:2172
USHORT NTAPI UniataEnableIoPCI(IN ULONG busNumber, IN ULONG slotNumber, IN OUT PPCI_COMMON_CONFIG pciData)
Definition: id_probe.cpp:95
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:2754
BOOLEAN NTAPI AtapiCheckIOInterference(IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, ULONG portBase)
Definition: id_probe.cpp:2203
VOID NTAPI UniataEnumBusMasterController(IN PVOID DriverObject, PVOID Argument2)
Definition: id_probe.cpp:245
PBUSMASTER_CONTROLLER_INFORMATION BMList
Definition: id_probe.cpp:53
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:2243
ULONG NTAPI UniataAnybodyHome(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG deviceNumber)
Definition: id_probe.cpp:2778
BOOLEAN FirstMasterOk
Definition: id_probe.cpp:58
UCHAR NTAPI UniataSataPhyEnable(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG pm_port, IN BOOLEAN doReset)
Definition: id_sata.cpp:124
BOOLEAN NTAPI UniataSataClearErr(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN BOOLEAN do_connect, IN ULONG pm_port)
Definition: id_sata.cpp:186
ULONG NTAPI UniataAhciSoftReset(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_sata.cpp:1787
ULONG NTAPI UniataSataReadPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG pm_port)
Definition: id_sata.cpp:270
#define UNIATA_SATA_IGNORE_CONNECT
Definition: id_sata.h:61
__inline ULONG UniataAhciReadChannelPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx)
Definition: id_sata.h:290
__inline BOOLEAN UniataIsSATARangeAvailable(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG lChannel)
Definition: id_sata.h:91
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Returns a pointer to the I/O manager's global configuration information structure.
Definition: iorsrce.c:998
#define c
Definition: ke_i.h:80
#define PCHAR
Definition: match.c:90
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
#define sprintf(buf, format,...)
Definition: sprintf.c:55
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
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
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:141
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 L(x)
Definition: ntvdm.h:50
#define CONST
Definition: pedump.c:81
#define BOOLEAN
Definition: pedump.c:73
unsigned short USHORT
Definition: pedump.c:61
#define FILE_DEVICE_UNKNOWN
Definition: winioctl.h:140
#define offsetof(TYPE, MEMBER)
@ Latched
Definition: miniport.h:81
@ LevelSensitive
Definition: miniport.h:80
@ Width16Bits
Definition: miniport.h:106
enum _KINTERRUPT_MODE KINTERRUPT_MODE
@ PCIConfiguration
Definition: miniport.h:93
enum _BUS_DATA_TYPE BUS_DATA_TYPE
#define exit(n)
Definition: config.h:202
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define DbgDumpRegTranslation(chan, idx)
Definition: tools.h:135
Definition: shell.h:41
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
CM_FULL_RESOURCE_DESCRIPTOR List[1]
Definition: hwresource.cpp:165
BOOLEAN PrimaryAddress
Definition: bsmaster.h:1036
ULONG ChannelCtrlFlags
Definition: bsmaster.h:1059
ULONG NumberLuns
Definition: bsmaster.h:1090
ULONG lChannel
Definition: bsmaster.h:1064
IORES RegTranslation[IDX_MAX_REG]
Definition: bsmaster.h:1127
struct _HW_LU_EXTENSION * lun[IDE_MAX_LUN_PER_CHAN]
Definition: bsmaster.h:1088
struct _HW_DEVICE_EXTENSION * DeviceExtension
Definition: bsmaster.h:1087
ULONG NumberChannels
Definition: atapi.c:68
BOOLEAN DriverMustPoll
Definition: atapi.c:111
PHW_LU_EXTENSION lun
Definition: bsmaster.h:1256
INTERFACE_TYPE AdapterInterfaceType
Definition: bsmaster.h:1316
BOOLEAN DWordIO
Definition: atapi.c:117
ULONG MaximumDmaTransferLength
Definition: bsmaster.h:1317
INTERFACE_TYPE OrigAdapterInterfaceType
Definition: bsmaster.h:1315
ULONG InterruptMode
Definition: atapi.c:47
PHW_CHANNEL chan
Definition: bsmaster.h:1257
LONGLONG RwSwitchMCost
Definition: bsmaster.h:1182
LONGLONG RwSwitchCost
Definition: bsmaster.h:1181
IDENTIFY_DATA2 IdentifyData
Definition: bsmaster.h:1162
ULONG AtapiReadyWaitDelay
Definition: bsmaster.h:1191
LONGLONG SeekBackMCost
Definition: bsmaster.h:1183
USHORT NumberOfHeads
Definition: atapi.h:252
USHORT SectorsPerTrack
Definition: atapi.h:255
ULONG MemIo
Definition: bsmaster.h:1013
ULONG Addr
Definition: bsmaster.h:1009
PHW_DEVICE_EXTENSION HwDeviceExtension
Definition: bsmaster.h:1351
struct _PCI_SLOT_NUMBER::@4017::@4018 bits
union _PCI_SLOT_NUMBER::@4017 u
PORT_CONFIGURATION_INFORMATION comm
Definition: srb.h:137
PORT_CONFIGURATION_INFORMATION_2K w2k
Definition: srb.h:139
PORT_CONFIGURATION_INFORMATION_NT nt4
Definition: srb.h:138
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: ps.c:97
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
pass
Definition: typegen.h:25
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define DFLAGS_LBA_ENABLED
Definition: atapi.h:247
ULONG NTAPI AtapiRegCheckDevValue(IN PVOID HwDeviceExtension, IN ULONG chan, IN ULONG dev, IN PCWSTR Name, IN ULONG Default)
Definition: id_ata.cpp:11365
VOID NTAPI UniataDumpATARegs(IN struct _HW_CHANNEL *chan)
#define ATA_PIO4
Definition: atapi.h:313
#define UNIATA_FIND_DEV_UNHIDE
Definition: atapi.h:1360
#define IDX_IO2_AltStatus
Definition: atapi.h:225
#define IDX_IO2
Definition: atapi.h:222
VOID NTAPI UniataInitMapBase(IN struct _HW_CHANNEL *chan, IN PIDE_REGISTERS_1 BaseIoAddress1, IN PIDE_REGISTERS_2 BaseIoAddress2)
#define ATA_AT_HOME_HDD
Definition: atapi.h:1592
#define AtapiStallExecution(dt)
Definition: atapi.h:158
UCHAR DDKFASTAPI SelectDrive(IN struct _HW_CHANNEL *chan, IN ULONG DeviceNumber)
#define DFLAGS_HIDDEN
Definition: atapi.h:253
#define CHAN_NOT_SPECIFIED_CHECK_CABLE
Definition: atapi.h:1482
#define ATA_AT_HOME_NOBODY
Definition: atapi.h:1595
#define KdPrint2(_x_)
Definition: atapi.h:154
#define DEVNUM_NOT_SPECIFIED
Definition: atapi.h:1483
#define DFLAGS_DWORDIO_ENABLED
Definition: atapi.h:248
#define IDX_IO1
Definition: atapi.h:194
VOID NTAPI UniataInitMapBM(IN struct _HW_DEVICE_EXTENSION *deviceExtension, IN struct _IDE_BUSMASTER_REGISTERS *BaseIoAddressBM_0, IN BOOLEAN MemIo)
#define ATA_AT_HOME_ATAPI
Definition: atapi.h:1593
VOID NTAPI AtapiEnableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4397
VOID UniataExpectChannelInterrupt(IN struct _HW_CHANNEL *chan, IN BOOLEAN Expecting)
Definition: id_ata.cpp:4492
#define CHAN_NOT_SPECIFIED
Definition: atapi.h:1481
UCHAR DDKFASTAPI WaitOnBaseBusyLong(IN struct _HW_CHANNEL *chan)
VOID NTAPI AtapiDisableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4457
#define PRINT_PREFIX
Definition: atapi.h:150
#define ATA_AT_HOME_XXX
Definition: atapi.h:1594
VOID DDKFASTAPI AtapiHardReset(IN struct _HW_CHANNEL *chan, IN BOOLEAN DisableInterrupts, IN ULONG Delay)
Definition: id_ata.cpp:948
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ WDFDEVICE _In_ PPNP_BUS_INFORMATION BusInformation
Definition: wdfdevice.h:3915
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING DeviceID
Definition: wdfpdo.h:278
_In_ WDFIORESREQLIST _In_ ULONG SlotNumber
Definition: wdfresource.h:68
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:160
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3601
#define PCI_ENABLE_BUS_MASTER
Definition: iotypes.h:3618
#define PCI_TYPE0_ADDRESSES
Definition: iotypes.h:3500
#define PCI_ENABLE_IO_SPACE
Definition: iotypes.h:3616
#define PCI_ADDRESS_IO_SPACE
Definition: iotypes.h:4230
#define PCI_ENABLE_MEMORY_SPACE
Definition: iotypes.h:3617
#define PCI_MAX_FUNCTION
Definition: iotypes.h:3599
#define PCI_COMMON_HDR_LENGTH
Definition: iotypes.h:3594
_In_ USHORT _In_ UCHAR _In_ USHORT _In_ USHORT SubSystemID
Definition: iotypes.h:895
#define PCI_MAX_DEVICES
Definition: iotypes.h:3598
_In_ USHORT _In_ UCHAR _In_ USHORT SubVendorID
Definition: iotypes.h:894
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define _snprintf
Definition: xmlstorage.h:200