3 Copyright (c) 2002-2016 Alexandr A. Telyatnikov (Alter)
9 This module scans PCI and ISA buses for IDE controllers
10 and determines their Busmaster DMA capabilities
13 Alexander A. Telyatnikov (Alter)
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.
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
36 Some parts of device detection code were taken from from standard ATAPI.SYS from NT4 DDK by
40 Device search/init algorithm is completly rewritten by
41 Alter, Copyright (c) 2002-2004
43 Fixes for Native/Compatible modes of onboard IDE controller by
44 Vitaliy Vorobyov, deathsoft@yandex.ru (c) 2004
53 PBUSMASTER_CONTROLLER_INFORMATION BMList
= NULL
;
58 BOOLEAN FirstMasterOk
= FALSE
;
59 // This is our own resource check,
60 // ReactOS allows to allocate same I/O range for both PCI and ISA controllers
61 BOOLEAN AtdiskPrimaryClaimed
= FALSE
;
62 BOOLEAN AtdiskSecondaryClaimed
= FALSE
;
69 PDRIVER_OBJECT SavedDriverObject
= NULL
;
75 UniataEnumBusMasterController__(
76 /* IN PVOID HwDeviceExtension,
78 IN PVOID BusInformation,
79 IN PCHAR ArgumentString,
80 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
89 } // end AtapiDoNothing()
98 IN OUT PPCI_COMMON_CONFIG pciData
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
));
111 CmdOrig
= pciData
->Command
;
114 KdPrint2((PRINT_PREFIX
"PCI_ENABLE_IO_SPACE\n"));
115 pciData
->Command
|= PCI_ENABLE_IO_SPACE
;
118 KdPrint2((PRINT_PREFIX
"PCI_ENABLE_MEMORY_SPACE\n"));
119 pciData
->Command
|= PCI_ENABLE_MEMORY_SPACE
;
122 KdPrint2((PRINT_PREFIX
"PCI_ENABLE_BUS_MASTER\n"));
123 pciData
->Command
|= PCI_ENABLE_BUS_MASTER
;
126 if(CmdOrig
== pciData
->Command
) {
129 HalSetBusDataByOffset( PCIConfiguration
, busNumber
, slotNumber
,
131 offsetof(PCI_COMMON_CONFIG
, Command
),
132 sizeof(pciData
->Command
));
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
));
141 KdPrint2((PRINT_PREFIX
"New pciData.Command = %#x\n", pciData
->Command
));
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()
149 Get PCI address by ConfigInfo and RID
154 IN PVOID HwDeviceExtension
,
155 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
156 IN PPCI_COMMON_CONFIG pciData
,
157 IN ULONG SystemIoBusNumber
,
158 IN ULONG rid
, //range id
163 ULONGIO_PTR io_start
= 0;
164 KdPrint2((PRINT_PREFIX
" AtapiGetIoRange:\n"));
166 if(ConfigInfo
->NumberOfAccessRanges
<= rid
)
169 KdPrint2((PRINT_PREFIX
" AtapiGetIoRange: rid %#x, start %#x, offs %#x, len %#x, mem %#x\n",
171 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[rid
].RangeStart
),
174 (*ConfigInfo
->AccessRanges
)[rid
].RangeInMemory
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
=
184 ScsiPortConvertUlongToPhysicalAddress(io_start
);
185 (*ConfigInfo
->AccessRanges
)[rid
+1].RangeLength
= length
;
187 (*ConfigInfo
->AccessRanges
)[rid
].RangeStart
=
188 ScsiPortConvertUlongToPhysicalAddress(io_start
);
189 (*ConfigInfo
->AccessRanges
)[rid
].RangeLength
= length
;
191 if((pciData
->u
.type0
.BaseAddresses
[rid
] & PCI_ADDRESS_IO_SPACE
)) {
192 (*ConfigInfo
->AccessRanges
)[rid
].RangeInMemory
= FALSE
;
194 KdPrint2((PRINT_PREFIX
" AtapiGetIoRange: adjust mem 0 -> 1\n"));
195 (*ConfigInfo
->AccessRanges
)[rid
].RangeInMemory
= TRUE
;
202 if((*ConfigInfo
->AccessRanges
)[rid
].RangeInMemory
) {
204 KdPrint2((PRINT_PREFIX
" AtapiGetIoRange: can't map memory range with offset\n"));
208 // Get the system physical address for this IO range.
209 ((ULONG_PTR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
210 PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
211 SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
212 ScsiPortConvertUlongToPhysicalAddress(
213 (ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[rid
].RangeStart
) &
214 ~0x07/*PCI_ADDRESS_IOMASK*/) + offset
217 (BOOLEAN
)!(*ConfigInfo
->AccessRanges
)[rid
].RangeInMemory
)
220 KdPrint2((PRINT_PREFIX
" AtapiGetIoRange: %#x\n", io_start
));
221 // if(io_start > offset) {
226 KdPrint2((PRINT_PREFIX
" AtapiGetIoRange: (2) %#x\n", io_start
));
229 } // end AtapiGetIoRange()
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
240 We shall initiate ISA device init, but callback will use
241 Hal routines directly in order to scan PCI bus.
245 UniataEnumBusMasterController(
246 IN PVOID DriverObject
,
250 UniataEnumBusMasterController__();
252 } // end UniataEnumBusMasterController()
256 UniataCheckPCISubclass(
263 if((RaidFlags
& UNIATA_RAID_CONTROLLER
) &&
265 KdPrint2((PRINT_PREFIX
"Skip RAID\n"));
270 KdPrint2((PRINT_PREFIX
"unknown\n"));
273 case PCI_DEV_SUBCLASS_RAID
:
275 KdPrint2((PRINT_PREFIX
"Skip RAID (2)\n"));
279 case PCI_DEV_SUBCLASS_IDE
:
280 case PCI_DEV_SUBCLASS_ATA
:
282 case PCI_DEV_SUBCLASS_SATA
:
285 KdPrint2((PRINT_PREFIX
"Subclass not supported\n"));
289 } // end UniataCheckPCISubclass()
291 static CONST ULONG StdIsaPorts
[] = {IO_WD1
, IO_WD1
+ ATA_ALTOFFSET
, IO_WD2
, IO_WD2
+ ATA_ALTOFFSET
, 0, 0};
294 Device initializaton callback
295 Builds PCI device list using Hal routines (not ScsiPort wrappers)
299 UniataEnumBusMasterController__(
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
;
311 BOOLEAN no_buses
= FALSE
;
312 BOOLEAN no_ranges
= FALSE
;
313 BOOLEAN non_isa
= TRUE
;
315 // BOOLEAN SimplexOnly;
317 UCHAR vendorString
[5];
318 UCHAR deviceString
[5];
322 UCHAR BaseClass
; // (ro)
323 UCHAR SubClass
; // (ro)
338 BOOLEAN NeedPciAltInit
;
339 BOOLEAN NonZeroSubId
= 0;
341 UCHAR IrqForCompat
= 10;
343 vendorStrPtr
= vendorString
;
344 deviceStrPtr
= deviceString
;
345 slotData
.u
.AsULONG
= 0;
347 KdPrint2((PRINT_PREFIX
"UniataEnumBusMasterController__: maxPciBus=%d\n", maxPciBus
));
349 return(SP_RETURN_NOT_FOUND
);
351 /*HwDeviceExtension =*/
352 deviceExtension
= (PHW_DEVICE_EXTENSION
)ExAllocatePool(NonPagedPool
, sizeof(HW_DEVICE_EXTENSION
));
353 if(!deviceExtension
) {
354 KdPrint2((PRINT_PREFIX
"!deviceExtension\n"));
355 return(SP_RETURN_NOT_FOUND
);
357 RtlZeroMemory(deviceExtension
, sizeof(HW_DEVICE_EXTENSION
));
358 PciDevMap
= (PCHAR
)ExAllocatePool(NonPagedPool
, maxPciBus
*PCI_MAX_DEVICES
);
360 KdPrint2((PRINT_PREFIX
"!PciDevMap\n"));
363 RtlZeroMemory(PciDevMap
, maxPciBus
*PCI_MAX_DEVICES
);
365 for(pass
=0; pass
<3; pass
++) {
366 KdPrint2((PRINT_PREFIX
" pass %d\n", pass
));
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
++) {
374 // use cached device presence map from the 1st pass
375 if(PciDevMap
[busNumber
*PCI_MAX_DEVICES
+ slotNumber
] & (1 << funcNumber
)) {
381 // KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x\n",busNumber,slotNumber,funcNumber));
382 slotData
.u
.bits
.DeviceNumber
= slotNumber
;
383 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
385 busDataRead
= HalGetBusData
389 PCIConfiguration
, busNumber
, slotData
.u
.AsULONG
,
390 &pciData
, PCI_COMMON_HDR_LENGTH
);
393 no_buses
= TRUE
; // break all nested bus scan loops and continue with next pass
394 maxPciBus
= busNumber
;
397 // indicate that system has PCI bus(es)
400 // no device in this slot
401 if(busDataRead
== 2) {
402 NeedPciAltInit
= TRUE
;
406 if(busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
407 NeedPciAltInit
= TRUE
;
411 VendorID
= pciData
.VendorID
;
412 DeviceID
= pciData
.DeviceID
;
413 BaseClass
= pciData
.BaseClass
;
414 SubClass
= pciData
.SubClass
;
415 dev_id
= VendorID
| (DeviceID
<< 16);
417 SubVendorID
= pciData
.u
.type0
.SubVendorID
;
418 SubSystemID
= pciData
.u
.type0
.SubSystemID
;
420 if(SubVendorID
&& SubSystemID
) {
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
));
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
));
432 if(g_opt_VirtualMachine
== VM_AUTO
) {
433 g_opt_VirtualMachine
= VM_VBOX
;
436 if((VendorID
== 0x15ad) ||
437 (SubVendorID
== 0x15ad && SubSystemID
== 0x1976)) {
438 KdPrint2((PRINT_PREFIX
"-- BusID: %#x:%#x:%#x - VMWare\n",busNumber
,slotNumber
,funcNumber
));
439 if(g_opt_VirtualMachine
== VM_AUTO
) {
440 g_opt_VirtualMachine
= VM_VMWARE
;
443 if(SubVendorID
== 0x1af4 && SubSystemID
== 0x1100) {
444 KdPrint2((PRINT_PREFIX
"-- BusID: %#x:%#x:%#x - QEmu\n",busNumber
,slotNumber
,funcNumber
));
445 if(g_opt_VirtualMachine
== VM_AUTO
) {
446 g_opt_VirtualMachine
= VM_QEMU
;
449 if(VendorID
== 0x1234 && DeviceID
== 0x1111) {
450 KdPrint2((PRINT_PREFIX
"-- BusID: %#x:%#x:%#x - Bochs\n",busNumber
,slotNumber
,funcNumber
));
451 if(g_opt_VirtualMachine
== VM_AUTO
) {
452 g_opt_VirtualMachine
= VM_BOCHS
;
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;
465 if(BaseClass
!= PCI_DEV_CLASS_STORAGE
) {
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
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
));
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
;
492 found
= (BOOLEAN
)AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"Include", 0);
494 KdPrint2((PRINT_PREFIX
"No force include, check exclude\n"));
495 found
= !AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"Exclude", 0);
497 KdPrint2((PRINT_PREFIX
"Device excluded\n"));
502 //known = UniataChipDetect(HwDeviceExtension, NULL, -1, ConfigInfo, &SimplexOnly);
503 i
= Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION_BASE
)&BusMasterAdapters
[0], VendorID
, DeviceID
, 0, NUM_BUSMASTER_ADAPTERS
);
505 known
= (i
!= BMLIST_TERMINATOR
);
507 deviceExtension
->FullDevName
= BusMasterAdapters
[i
].FullDevName
;
508 RaidFlags
= BusMasterAdapters
[i
].RaidFlags
;
510 deviceExtension
->FullDevName
= "Unknown Storage";
513 found
= UniataCheckPCISubclass(known
, RaidFlags
, SubClass
);
515 KdPrint2((PRINT_PREFIX
"Subclass not supported\n"));
520 /* additional checks for some supported chipsets */
522 if (SubClass
!= PCI_DEV_SUBCLASS_IDE
)
526 /* unknown chipsets, try generic DMA if it seems possible */
528 KdPrint2((PRINT_PREFIX
"Default device\n"));
529 if(Ata_is_supported_dev(&pciData
) ||
530 Ata_is_ahci_dev(&pciData
))
539 KdPrint2((PRINT_PREFIX
"found, pass %d\n", pass
));
541 KdPrint2((PRINT_PREFIX
"InterruptPin = %#x\n", pciData
.u
.type0
.InterruptPin
));
542 KdPrint2((PRINT_PREFIX
"InterruptLine = %#x\n", pciData
.u
.type0
.InterruptLine
));
545 UniataEnableIoPCI(busNumber
, slotData
.u
.AsULONG
, &pciData
);
547 // validate Mem/Io ranges
550 for(i
=0; i
<PCI_TYPE0_ADDRESSES
; i
++) {
551 if(pciData
.u
.type0
.BaseAddresses
[i
] & ~0x7) {
554 KdPrint2((PRINT_PREFIX
"Range %d = %#x\n", i
, pciData
.u
.type0
.BaseAddresses
[i
]));
556 if(StdIsaPorts
[i
] == (pciData
.u
.type0
.BaseAddresses
[i
] & ~0x7)) {
563 KdPrint2((PRINT_PREFIX
"No PCI Mem/Io ranges found on device, skip it\n"));
567 KdPrint2((PRINT_PREFIX
"standard ISA ranges on PCI, special case ?\n"));
571 // fill list of detected devices
572 // it'll be used for further init
573 KdPrint2((PRINT_PREFIX
"found suitable device\n"));
574 PBUSMASTER_CONTROLLER_INFORMATION newBMListPtr
= BMList
+BMListLen
;
577 if(!IsMasterDev(&pciData
)) {
580 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"NativePCIMode", 0)) {
581 KdPrint2((PRINT_PREFIX
"try switch to native mode\n"));
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)) {
589 KdPrint2((PRINT_PREFIX
"default to IRQ 11\n"));
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
,
596 offsetof(PCI_COMMON_CONFIG
, ProgIf
),
597 sizeof(pciData
.ProgIf
));
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"));
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
));
619 KdPrint2((PRINT_PREFIX
"Auto-assigned interrupt line %#x\n",
620 pciData
.u
.type0
.InterruptLine
));
621 IrqForCompat
= pciData
.u
.type0
.InterruptLine
;
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
,
644 offsetof(PCI_COMMON_CONFIG
, ProgIf
),
645 sizeof(pciData
.ProgIf
));
646 // reread config space
647 KdPrint2((PRINT_PREFIX
"reread config space on revert\n"));
648 busDataRead
= HalGetBusData(PCIConfiguration
, busNumber
, slotData
.u
.AsULONG
,
649 &pciData
, PCI_COMMON_HDR_LENGTH
);
651 KdPrint2((PRINT_PREFIX
"Assigned interrupt %#x for device\n", IrqForCompat
));
652 KdPrint2((PRINT_PREFIX
"continue detection on next round\n"));
659 if(IsMasterDev(&pciData
)) {
665 RtlCopyMemory(newBMListPtr, (PVOID)&(BusMasterAdapters[i]), sizeof(BUSMASTER_CONTROLLER_INFORMATION));
667 sprintf((PCHAR
)vendorStrPtr
, "%4.4lx", VendorID
);
668 sprintf((PCHAR
)deviceStrPtr
, "%4.4lx", DeviceID
);
670 RtlCopyMemory(&(newBMListPtr
->VendorIdStr
), (PCHAR
)vendorStrPtr
, 4);
671 RtlCopyMemory(&(newBMListPtr
->DeviceIdStr
), (PCHAR
)deviceStrPtr
, 4);
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;
680 newBMListPtr
->RaidFlags
= RaidFlags
;
682 newBMListPtr
->slotNumber
= slotData
.u
.AsULONG
;
683 newBMListPtr
->MasterDev
= IsMasterDev(&pciData
) ? 1 : 0;
684 newBMListPtr
->busNumber
= busNumber
;
686 newBMListPtr
->NeedAltInit
= NeedPciAltInit
;
687 newBMListPtr
->Known
= known
;
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;
696 KdPrint2((PRINT_PREFIX
"Add to BMList, AltInit %d\n", NeedPciAltInit
));
698 KdPrint2((PRINT_PREFIX
"count: BMListLen++\n"));
699 PciDevMap
[busNumber
*PCI_MAX_DEVICES
+ slotNumber
] |= (1 << funcNumber
);
713 BMList
= (PBUSMASTER_CONTROLLER_INFORMATION
)ExAllocatePool(NonPagedPool
,
714 (BMListLen
+1)*sizeof(BUSMASTER_CONTROLLER_INFORMATION
));
719 RtlZeroMemory(BMList
, (BMListLen
+1)*sizeof(BUSMASTER_CONTROLLER_INFORMATION
));
725 KdPrint2((PRINT_PREFIX
" BMListLen=%x\n", BMListLen
));
726 if(deviceExtension
) {
727 ExFreePool(deviceExtension
);
730 ExFreePool(PciDevMap
);
732 return(SP_RETURN_NOT_FOUND
);
733 } // end UniataEnumBusMasterController__()
737 Wrapper for read PCI config space
741 ScsiPortGetBusDataByOffset(
742 IN PVOID HwDeviceExtension
,
743 IN BUS_DATA_TYPE BusDataType
,
754 if(Offset
+Length
> 256)
757 busDataRead
= HalGetBusData(
758 //ScsiPortGetBusData(HwDeviceExtension,
764 if(busDataRead
< Offset
+Length
) {
765 if(busDataRead
< Offset
)
767 return (Offset
+Length
-busDataRead
);
769 RtlCopyMemory(Buffer
, tmp
+Offset
, Length
);
771 } // end ScsiPortGetBusDataByOffset()
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
781 IN PBUSMASTER_CONTROLLER_INFORMATION_BASE BusMasterAdapters
,
783 IN PVOID HwDeviceExtension
,
786 OUT PCI_SLOT_NUMBER
* _slotData
// optional
789 PCI_SLOT_NUMBER slotData
;
790 PCI_COMMON_CONFIG pciData
;
802 KdPrint2((PRINT_PREFIX
"AtapiFindListedDev: lim=%x, Bus=%x, Slot=%x\n", lim
, BusNumber
, SlotNumber
));
805 if(BusNumber
== PCIBUSNUM_NOT_SPECIFIED
) {
807 busNumber2
= maxPciBus
;
809 busNumber
= BusNumber
;
810 busNumber2
= BusNumber
+1;
812 // set start/end slot
813 if(SlotNumber
== PCISLOTNUM_NOT_SPECIFIED
) {
815 slotNumber2
= PCI_MAX_DEVICES
;
817 slotNumber
= SlotNumber
;
818 slotNumber2
= SlotNumber
+1;
820 slotData
.u
.AsULONG
= 0;
822 KdPrint2((PRINT_PREFIX
" scanning range Bus %x-%x, Slot %x-%x\n", busNumber
, busNumber2
-1, slotNumber
, slotNumber2
-1));
824 for( ; busNumber
< busNumber2
; busNumber
++ ) {
825 for( ; slotNumber
< slotNumber2
; slotNumber
++) {
826 for(funcNumber
=0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
828 slotData
.u
.bits
.DeviceNumber
= slotNumber
;
829 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
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)
839 // no device in this slot
843 if(busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
)
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));
850 i
= Ata_is_dev_listed(BusMasterAdapters
, pciData
.VendorID
, pciData
.DeviceID
, pciData
.RevisionID
, lim
);
851 if(i
!= BMLIST_TERMINATOR
) {
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
));
863 } // end AtapiFindListedDev()
866 Looks for device with specified Device/Vendor and Revision
867 on specified Bus/Slot
872 IN PVOID HwDeviceExtension
,
873 IN BUS_DATA_TYPE BusDataType
,
880 PCI_COMMON_CONFIG pciData
;
886 PCI_SLOT_NUMBER slotData
;
888 slotData
.u
.AsULONG
= SlotNumber
;
889 // walk through all Function Numbers
890 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
892 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
893 if(slotData
.u
.AsULONG
== SlotNumber
)
896 busDataRead
= HalGetBusData(
897 //busDataRead = ScsiPortGetBusData(HwDeviceExtension,
902 PCI_COMMON_HDR_LENGTH
);
904 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
908 VendorID
= pciData
.VendorID
;
909 DeviceID
= pciData
.DeviceID
;
911 if(dev_id
!= (VendorID
| (DeviceID
<< 16)) )
913 if(RevID
>= pciData
.RevisionID
)
917 } // end AtapiFindDev()
924 UniataFindCompatBusMasterController1(
925 IN PVOID HwDeviceExtension
,
927 IN PVOID BusInformation
,
928 IN PCHAR ArgumentString
,
929 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
933 return UniataFindBusMasterController(
941 } // end UniataFindCompatBusMasterController1()
945 UniataFindCompatBusMasterController2(
946 IN PVOID HwDeviceExtension
,
948 IN PVOID BusInformation
,
949 IN PCHAR ArgumentString
,
950 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
954 return UniataFindBusMasterController(
962 } // end UniataFindCompatBusMasterController2()
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.
974 HwDeviceExtension - HBA miniport driver's adapter data storage
975 Context - Address of adapter count
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
988 UniataFindBusMasterController(
989 IN PVOID HwDeviceExtension
,
991 IN PVOID BusInformation
,
992 IN PCHAR ArgumentString
,
993 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
997 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
998 PHW_CHANNEL chan
= NULL
;
1000 // this buffer must be global for UNIATA_CORE build
1001 PCI_COMMON_CONFIG pciData
;
1002 #endif //UNIATA_CORE
1005 ULONG SystemIoBusNumber
;
1007 UCHAR vendorString[5];
1008 UCHAR deviceString[5];
1010 PUCHAR vendorStrPtr;
1011 PUCHAR deviceStrPtr;
1019 PCI_SLOT_NUMBER slotData
;
1031 BOOLEAN found
= FALSE
;
1033 BOOLEAN simplexOnly
= FALSE
;
1035 #ifdef UNIATA_INIT_ON_PROBE
1036 BOOLEAN skip_find_dev
= FALSE
;
1039 BOOLEAN AltInit
= FALSE
;
1041 SCSI_PHYSICAL_ADDRESS IoBasePort1
;
1042 SCSI_PHYSICAL_ADDRESS IoBasePort2
;
1044 PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0
= NULL
;
1045 PIDE_REGISTERS_1 BaseIoAddress1
[IDE_MAX_CHAN
];
1046 PIDE_REGISTERS_2 BaseIoAddress2
[IDE_MAX_CHAN
];
1048 RtlZeroMemory(&BaseIoAddress1
, sizeof(BaseIoAddress1
));
1049 RtlZeroMemory(&BaseIoAddress2
, sizeof(BaseIoAddress2
));
1052 PPORT_CONFIGURATION_INFORMATION_COMMON _ConfigInfo
=
1053 (PPORT_CONFIGURATION_INFORMATION_COMMON
)ConfigInfo
;
1055 if(!WinVer_WDM_Model
) {
1061 KdPrint2((PRINT_PREFIX
"UniataFindBusMasterController: Context=%x, BMListLen=%d\n", Context
, BMListLen
));
1063 KdPrint2((PRINT_PREFIX
"ConfigInfo->Length %x\n", ConfigInfo
->Length
));
1066 KdPrint2((PRINT_PREFIX
"ForceSimplex (1)\n"));
1070 if(ConfigInfo
->AdapterInterfaceType
== Isa
) {
1071 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType: Isa\n"));
1075 if(i
& 0x80000000) {
1079 channel
= BMList
[i
].channel
;
1082 for(i
=0; i
<BMListLen
; i
++) {
1083 if(BMList
[i
].slotNumber
== ConfigInfo
->SlotNumber
&&
1084 BMList
[i
].busNumber
== ConfigInfo
->SystemIoBusNumber
) {
1088 if(i
>= BMListLen
) {
1089 KdPrint2((PRINT_PREFIX
"unexpected device arrival\n"));
1095 if(i
>= BMListLen
) {
1096 KdPrint2((PRINT_PREFIX
" => SP_RETURN_NOT_FOUND\n"));
1100 BMList
[i
].channel
= (UCHAR
)channel
;
1103 bm_offset
= channel
? ATA_BM_OFFSET1
: 0;
1105 KdPrint2((PRINT_PREFIX
"bm_offset %x, channel %x \n", bm_offset
, channel
));
1107 if (!deviceExtension
) {
1108 KdPrint2((PRINT_PREFIX
"!deviceExtension => SP_RETURN_ERROR\n"));
1109 return SP_RETURN_ERROR
;
1111 RtlZeroMemory(deviceExtension
, sizeof(HW_DEVICE_EXTENSION
));
1113 vendorStrPtr = vendorString;
1114 deviceStrPtr = deviceString;
1116 slotNumber
= BMList
[i
].slotNumber
;
1117 SystemIoBusNumber
= BMList
[i
].busNumber
;
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
));
1124 // this buffer must be global and already filled for UNIATA_CORE build
1125 busDataRead
= HalGetBusData(
1126 //busDataRead = ScsiPortGetBusData(HwDeviceExtension,
1131 PCI_COMMON_HDR_LENGTH
);
1134 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1135 KdPrint2((PRINT_PREFIX
"busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n"));
1139 KdPrint2((PRINT_PREFIX
"busDataRead\n"));
1140 if (pciData
.VendorID
== PCI_INVALID_VENDORID
) {
1141 KdPrint2((PRINT_PREFIX
"PCI_INVALID_VENDORID\n"));
1144 #endif //UNIATA_CORE
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
));
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
;
1163 _snprintf(deviceExtension
->Signature
, sizeof(deviceExtension
->Signature
),
1164 "UATA%8.8x/%1.1x@%8.8x", dev_id
, channel
, slotNumber
);
1166 if(BaseClass
!= PCI_DEV_CLASS_STORAGE
) {
1167 KdPrint2((PRINT_PREFIX
"BaseClass != PCI_DEV_CLASS_STORAGE => SP_RETURN_NOT_FOUND\n"));
1171 KdPrint2((PRINT_PREFIX
"Storage Class\n"));
1173 // look for known chipsets
1174 if(VendorID
!= BMList
[i
].nVendorId
||
1175 DeviceID
!= BMList
[i
].nDeviceId
) {
1176 KdPrint2((PRINT_PREFIX
"device not suitable\n"));
1180 found
= UniataCheckPCISubclass(BMList
[i
].Known
, BMList
[i
].RaidFlags
, SubClass
);
1182 KdPrint2((PRINT_PREFIX
"Subclass not supported\n"));
1186 ConfigInfo
->AlignmentMask
= 0x00000003;
1188 MasterDev
= IsMasterDev(&pciData
);
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"));
1200 status
= UniataChipDetect(HwDeviceExtension
, &pciData
, i
, ConfigInfo
, &simplexOnly
);
1202 case STATUS_SUCCESS
:
1205 case STATUS_NOT_FOUND
:
1209 KdPrint2((PRINT_PREFIX
"FAILED => SP_RETURN_ERROR\n"));
1212 KdPrint2((PRINT_PREFIX
"ForceSimplex = %d\n", simplexOnly
));
1213 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (0)", deviceExtension
->HwFlags
));
1215 /* additional checks for some supported chipsets */
1217 if (SubClass
!= PCI_DEV_SUBCLASS_IDE
) {
1218 KdPrint2((PRINT_PREFIX
"0xc6931080, SubClass != PCI_DEV_SUBCLASS_IDE => found = FALSE\n"));
1225 /* unknown chipsets, try generic DMA if it seems possible */
1229 KdPrint2((PRINT_PREFIX
"Default device\n"));
1230 if(Ata_is_supported_dev(&pciData
)) {
1231 KdPrint2((PRINT_PREFIX
"Ata_is_supported_dev\n"));
1234 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
1235 KdPrint2((PRINT_PREFIX
"AHCI candidate\n"));
1238 KdPrint2((PRINT_PREFIX
"!Ata_is_supported_dev => found = FALSE\n"));
1241 deviceExtension
->UnknownDev
= TRUE
;
1245 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (1)", deviceExtension
->HwFlags
));
1247 KdPrint2((PRINT_PREFIX
"!found => SP_RETURN_NOT_FOUND\n"));
1251 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (2)", deviceExtension
->HwFlags
));
1252 KdPrint2((PRINT_PREFIX
"found suitable device\n"));
1254 /***********************************************************/
1255 /***********************************************************/
1256 /***********************************************************/
1258 deviceExtension
->UseDpc
= TRUE
;
1261 deviceExtension
->DriverMustPoll
= TRUE
;
1262 deviceExtension
->UseDpc
= FALSE
;
1263 deviceExtension
->simplexOnly
= TRUE
;
1264 deviceExtension
->HwFlags
|= UNIATA_NO_DPC
;
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
;
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"));
1279 if((channel
==0) && ConfigInfo
->AtdiskPrimaryClaimed
) {
1280 KdPrint2((PRINT_PREFIX
"Error: Primary channel already claimed by another driver\n"));
1283 if((channel
==1) && ConfigInfo
->AtdiskSecondaryClaimed
) {
1284 KdPrint2((PRINT_PREFIX
"Error: Secondary channel already claimed by another driver\n"));
1289 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
1290 KdPrint2((PRINT_PREFIX
" AHCI registers layout\n"));
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
;
1301 deviceExtension
->BusMaster
= DMA_MODE_NONE
;
1303 if(WinVer_WDM_Model
&& !deviceExtension
->UnknownDev
) {
1304 UniataEnableIoPCI(ConfigInfo
->SystemIoBusNumber
, slotData
.u
.AsULONG
, &pciData
);
1306 // validate Mem/Io ranges
1310 for(j
=0; j
<PCI_TYPE0_ADDRESSES
; j
++) {
1311 if(pciData
.u
.type0
.BaseAddresses
[j
] & ~0x7) {
1312 //no_ranges = FALSE;
1314 KdPrint2((PRINT_PREFIX
"Range %d = %#x\n", j
, pciData
.u
.type0
.BaseAddresses
[j
]));
1319 if(IsBusMaster(&pciData
)) {
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
,
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
;
1335 KdPrint2((PRINT_PREFIX
" BusMasterAddress (base): %#x\n", BaseIoAddressBM_0
));
1338 if(!deviceExtension
->BusMaster
) {
1339 KdPrint2((PRINT_PREFIX
" !BusMasterAddress -> PIO4\n"));
1340 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
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
;
1351 if(BaseIoAddressBM_0) {
1352 ScsiPortFreeDeviceBase(HwDeviceExtension,
1354 BaseIoAddressBM_0 = NULL;
1358 if(statusByte
& BM_STATUS_SIMPLEX_ONLY
) {
1359 KdPrint2((PRINT_PREFIX
" BM_STATUS => simplexOnly\n"));
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.
1372 if (dev_id
== 0xc6931080 && slotData
.u
.bits
.FunctionNumber
> 1) {
1373 KdPrint2((PRINT_PREFIX
"dev_id == 0xc6931080 && FunctionNumber > 1 => exit_findbm\n"));
1377 /* do extra chipset specific setups */
1378 AtapiReadChipConfig(HwDeviceExtension
, i
, CHAN_NOT_SPECIFIED
);
1379 AtapiChipInit(HwDeviceExtension
, i
, CHAN_NOT_SPECIFIED_CHECK_CABLE
);
1381 simplexOnly
|= deviceExtension
->simplexOnly
;
1382 deviceExtension
->simplexOnly
|= simplexOnly
;
1384 KdPrint2((PRINT_PREFIX
"simplexOnly = %d (2)", simplexOnly
));
1386 //TODO: fix hang with UseDpc=TRUE in Simplex mode
1387 //deviceExtension->UseDpc = TRUE;
1389 KdPrint2((PRINT_PREFIX
"simplexOnly => UseDpc = FALSE\n"));
1390 deviceExtension
->UseDpc
= FALSE
;
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
,
1400 (*ConfigInfo
->AccessRanges
)[4].RangeInMemory
? TRUE
: FALSE
);
1405 (deviceExtension
->NumberChannels
> 1)) {
1406 KdPrint2((PRINT_PREFIX
"Error: channel > 0 && NumberChannels > 1\n"));
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]));
1416 // Indicate four devices can be attached to the adapter
1417 ConfigInfo
->MaximumNumberOfTargets
= (UCHAR
)(deviceExtension
->NumberLuns
);
1420 KdPrint2((PRINT_PREFIX
"MasterDev (2)\n"));
1422 if((WinVer_Id() > WinVer_NT) ||
1423 (deviceExtension->NumberChannels > 1)) {
1425 KdPrint2((PRINT_PREFIX "2 channels & 2 irq for 1 controller Win 2000+\n"));
1427 if (ConfigInfo->AdapterInterfaceType == MicroChannel) {
1428 ConfigInfo->InterruptMode2 =
1429 ConfigInfo->InterruptMode = LevelSensitive;
1431 ConfigInfo->InterruptMode2 =
1432 ConfigInfo->InterruptMode = Latched;
1434 ConfigInfo->BusInterruptLevel = 14;
1435 ConfigInfo->BusInterruptLevel2 = 15;
1439 KdPrint2((PRINT_PREFIX
"2 channels & 2 irq for 1 controller\n"));
1441 if (ConfigInfo
->AdapterInterfaceType
== MicroChannel
) {
1442 ConfigInfo
->InterruptMode2
=
1443 ConfigInfo
->InterruptMode
= LevelSensitive
;
1445 ConfigInfo
->InterruptMode2
=
1446 ConfigInfo
->InterruptMode
= Latched
;
1448 ConfigInfo
->BusInterruptLevel
= 14;
1449 ConfigInfo
->BusInterruptLevel2
= 15;
1451 KdPrint2((PRINT_PREFIX
"1 channels & 1 irq for 1 controller\n"));
1452 if (ConfigInfo
->AdapterInterfaceType
== MicroChannel
) {
1453 ConfigInfo
->InterruptMode
= LevelSensitive
;
1455 ConfigInfo
->InterruptMode
= Latched
;
1457 ConfigInfo
->BusInterruptLevel
= (channel
== 0 ? 14 : 15);
1460 KdPrint2((PRINT_PREFIX
"!MasterDev\n"));
1461 ConfigInfo
->SlotNumber
= slotNumber
;
1462 ConfigInfo
->SystemIoBusNumber
= SystemIoBusNumber
;
1463 ConfigInfo
->InterruptMode
= LevelSensitive
;
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;
1476 ConfigInfo
->MultipleRequestPerLu
= TRUE
;
1477 ConfigInfo
->AutoRequestSense
= TRUE
;
1478 ConfigInfo
->TaggedQueuing
= TRUE
;
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
);
1488 // _ConfigInfo->nt4.SrbExtensionSize = FIELD_OFFSET(ATA_REQ, dma_tab) + sizeof(BM_DMA_ENTRY)*ATA_DMA_ENTRIES;
1490 KdPrint2((PRINT_PREFIX
"using AtaReq sz %x\n", _ConfigInfo
->nt4
.SrbExtensionSize
));
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
));
1497 // We need not set Dma64BitAddresses since we perform address translation manually.
1499 _ConfigInfo
->w2k
.Dma64BitAddresses
= deviceExtension
->Host64
;
1500 #endif //USE_OWN_DMA
1501 _ConfigInfo
->w2k
.ResetTargetSupported
= TRUE
;
1502 _ConfigInfo
->w2k
.MaximumNumberOfLogicalUnits
= (UCHAR
)deviceExtension
->NumberLuns
;
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
;
1516 KdPrint2((PRINT_PREFIX
"chan[%d] InterruptMode: %d, Level %d, Level2 %d, Vector %d, Vector2 %d\n",
1518 ConfigInfo
->InterruptMode
,
1519 ConfigInfo
->BusInterruptLevel
,
1520 ConfigInfo
->BusInterruptLevel2
,
1521 ConfigInfo
->BusInterruptVector
,
1522 ConfigInfo
->BusInterruptVector2
1527 if(deviceExtension
->BusMaster
) {
1529 KdPrint2((PRINT_PREFIX
"Reconstruct ConfigInfo\n"));
1531 ConfigInfo
->NeedPhysicalAddresses
= FALSE
;
1533 ConfigInfo
->NeedPhysicalAddresses
= TRUE
;
1534 #endif //USE_OWN_DMA
1536 //#ifdef USE_OWN_DMA
1537 // KdPrint2((PRINT_PREFIX "!MasterDev, own DMA\n"));
1539 KdPrint2((PRINT_PREFIX
"set Dma32BitAddresses\n"));
1540 ConfigInfo
->Dma32BitAddresses
= TRUE
;
1541 //#endif //USE_OWN_DMA
1544 // thanks to Vitaliy Vorobyov aka deathsoft@yandex.ru for
1548 // I'm sorry, I have to do this
1551 if(ConfigInfo
->AdapterInterfaceType
== Isa
/*&&
1552 // InDriverEntry*/) {
1553 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType Isa => PCIBus\n"));
1554 ConfigInfo
->AdapterInterfaceType
= PCIBus
;
1556 if(ConfigInfo
->AdapterInterfaceType
== PCIBus
/*&&
1557 // InDriverEntry*/) {
1558 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType PCIBus, update address\n"));
1559 ConfigInfo
->SlotNumber
= slotNumber
;
1560 ConfigInfo
->SystemIoBusNumber
= SystemIoBusNumber
;
1565 ConfigInfo
->Master
= TRUE
;
1566 ConfigInfo
->DmaWidth
= Width16Bits
;
1567 #endif //USE_OWN_DMA
1568 ConfigInfo
->ScatterGather
= TRUE
;
1570 ConfigInfo
->MapBuffers
= TRUE
; // Need for PIO and OWN_DMA
1571 ConfigInfo
->CachesData
= TRUE
;
1573 KdPrint2((PRINT_PREFIX
"BMList[i].channel %#x, NumberChannels %#x, channel %#x\n",BMList
[i
].channel
, deviceExtension
->NumberChannels
, channel
));
1575 for (; channel
< (BMList
[i
].channel
+ deviceExtension
->NumberChannels
); channel
++, c
++) {
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
];
1581 KdPrint2((PRINT_PREFIX
"chan = %#x\n", chan
));
1582 //PrintNtConsole("chan = %#x, c=%#x\n", chan, c);
1583 AtapiSetupLunPtrs(chan
, deviceExtension
, c
);
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"));
1591 if(deviceExtension
->AltRegMap
) {
1592 KdPrint2((PRINT_PREFIX
" Non-standard registers layout\n"));
1594 // Check if the range specified is not used by another driver
1596 KdPrint2((PRINT_PREFIX
"set AccessRanges\n"));
1597 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 0].RangeStart
=
1598 ScsiPortConvertUlongToPhysicalAddress(channel
? IO_WD2
: IO_WD1
);
1599 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 0].RangeLength
= ATA_IOSIZE
;
1601 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 1].RangeStart
=
1602 ScsiPortConvertUlongToPhysicalAddress((channel
? IO_WD2
: IO_WD1
) + ATA_ALTOFFSET
);
1603 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 1].RangeLength
= ATA_ALTIOSIZE
;
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
);
1615 IoBasePort1
= (*ConfigInfo
->AccessRanges
)[channel
* 2 + 0].RangeStart
;
1616 IoBasePort2
= (*ConfigInfo
->AccessRanges
)[channel
* 2 + 1].RangeStart
;
1619 if(!IoBasePort1
.QuadPart
|| !IoBasePort2
.QuadPart
) {
1620 KdPrint2((PRINT_PREFIX
"ScsiPortValidateRange failed (1)\n"));
1625 if(!ScsiPortValidateRange(HwDeviceExtension
,
1626 PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
1627 SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
1631 KdPrint2((PRINT_PREFIX
"ScsiPortValidateRange failed (1)\n"));
1635 if(!ScsiPortValidateRange(HwDeviceExtension
,
1636 PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
1637 SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
1641 KdPrint2((PRINT_PREFIX
"ScsiPortValidateRange failed (2)\n"));
1645 KdPrint2((PRINT_PREFIX
"Getting IO ranges\n"));
1647 // Ok, translate adresses to io-space
1648 if(ScsiPortConvertPhysicalAddressToUlong(IoBasePort2
)) {
1649 if(!(MasterDev
/* || USE_16_BIT */)) {
1650 KdPrint2((PRINT_PREFIX
"!MasterDev mode\n"));
1651 IoBasePort2
= ScsiPortConvertUlongToPhysicalAddress(
1652 ScsiPortConvertPhysicalAddressToUlong(IoBasePort2
) + 2);
1655 KdPrint2((PRINT_PREFIX
"use relative IoBasePort2\n"));
1656 IoBasePort2
= ScsiPortConvertUlongToPhysicalAddress(
1657 ScsiPortConvertPhysicalAddressToUlong(IoBasePort1
) + ATA_PCCARD_ALTOFFSET
);
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*/,
1667 KdPrint2((PRINT_PREFIX
"IO range 1 %#x\n",ioSpace
));
1669 // Check if ioSpace accessible.
1671 KdPrint2((PRINT_PREFIX
"!ioSpace\n"));
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));
1682 //deviceExtension->BaseIoAddress1[c] = (PIDE_REGISTERS_1)(ioSpace);
1683 BaseIoAddress1
[c
] = (PIDE_REGISTERS_1
)(ioSpace
);
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*/,
1692 KdPrint2((PRINT_PREFIX
"IO range 2 %#x\n",ioSpace
));
1694 BaseIoAddress2
[c
] = (PIDE_REGISTERS_2
)(ioSpace
);
1696 // Release all allocated resources
1697 KdPrint2((PRINT_PREFIX
"!deviceExtension->BaseIoAddress2\n"));
1698 //ioSpace = (PUCHAR)BaseIoAddress1[c];
1699 // goto free_iospace_1;
1703 UniataInitMapBase(chan
, BaseIoAddress1
[c
], BaseIoAddress2
[c
]);
1705 //ioSpace = (PUCHAR)(deviceExtension->BaseIoAddress1[c]);
1707 DbgDumpRegTranslation(chan
, IDX_IO1
);
1708 DbgDumpRegTranslation(chan
, IDX_IO2
);
1709 DbgDumpRegTranslation(chan
, IDX_BM_IO
);
1710 DbgDumpRegTranslation(chan
, IDX_SATA_IO
);
1712 if(!(deviceExtension
->HwFlags
& UNIATA_AHCI
)) {
1714 UniataDumpATARegs(chan
);
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"));
1723 SelectDrive(chan
, 0);
1724 AtapiStallExecution(10);
1725 GetBaseStatus(chan
, statusByte
);
1726 skip_find_dev
= FALSE
;
1727 if(!(deviceExtension
->HwFlags
& UNIATA_NO_SLAVE
) && (deviceExtension
->NumberLuns
> 1)) {
1728 if ((statusByte
& 0xf8) == 0xf8 ||
1729 (statusByte
== 0xa5)) {
1731 KdPrint2((PRINT_PREFIX
"Check drive 1\n"));
1732 SelectDrive(chan
, 1);
1733 AtapiStallExecution(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
;
1744 // Search for devices on this controller.
1745 if (!skip_find_dev
&&
1746 FindDevices(HwDeviceExtension
,
1749 KdPrint2((PRINT_PREFIX
"Found some devices\n"));
1752 KdPrint2((PRINT_PREFIX
"no devices\n"));
1753 /* KeBugCheckEx(0xc000000e,
1754 ScsiPortConvertPhysicalAddressToUlong(IoBasePort1),
1755 ScsiPortConvertPhysicalAddressToUlong(IoBasePort2),
1756 (ULONG)(deviceExtension->BaseIoAddressBM[c]), skip_find_dev);*/
1758 //#ifdef UNIATA_INIT_ON_PROBE
1760 #else //UNIATA_INIT_ON_PROBE
1761 KdPrint2((PRINT_PREFIX
"clean IDE intr 0\n"));
1763 SelectDrive(chan
, 0);
1764 AtapiStallExecution(10);
1765 GetBaseStatus(chan
, statusByte
);
1767 if(!(deviceExtension
->HwFlags
& UNIATA_NO_SLAVE
) && (deviceExtension
->NumberLuns
> 1)) {
1768 KdPrint2((PRINT_PREFIX
"clean IDE intr 1\n"));
1770 SelectDrive(chan
, 1);
1771 AtapiStallExecution(1);
1772 GetBaseStatus(chan
, statusByte
);
1774 SelectDrive(chan
, 0);
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
);
1786 #endif //UNIATA_INIT_ON_PROBE
1790 chan
->PrimaryAddress
= FALSE
;
1791 // Claim primary or secondary ATA IO range.
1793 KdPrint2((PRINT_PREFIX
"claim Compatible controller\n"));
1795 KdPrint2((PRINT_PREFIX
"claim Primary\n"));
1796 AtdiskPrimaryClaimed
=
1797 ConfigInfo
->AtdiskPrimaryClaimed
= TRUE
;
1798 chan
->PrimaryAddress
= TRUE
;
1800 FirstMasterOk
= TRUE
;
1804 KdPrint2((PRINT_PREFIX
"claim Secondary\n"));
1805 AtdiskSecondaryClaimed
=
1806 ConfigInfo
->AtdiskSecondaryClaimed
= TRUE
;
1808 FirstMasterOk
= TRUE
;
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"));
1814 AtdiskPrimaryClaimed
=
1815 ConfigInfo
->AtdiskPrimaryClaimed
= TRUE
;
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"));
1820 AtdiskSecondaryClaimed
=
1821 ConfigInfo
->AtdiskSecondaryClaimed
= TRUE
;
1825 AtapiDmaAlloc(HwDeviceExtension
, ConfigInfo
, c
);
1829 #endif //UNIATA_CORE
1830 } // end for(channel)
1836 KdPrint2((PRINT_PREFIX
"exit: !found\n"));
1837 if(BaseIoAddress1
[0])
1838 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1840 if(BaseIoAddress2
[0])
1841 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1844 if(BaseIoAddress1
[1])
1845 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1847 if(BaseIoAddress2
[1])
1848 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1851 if(BaseIoAddressBM_0
)
1852 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1855 if(deviceExtension
->BaseIoAHCI_0
.Addr
) {
1856 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1857 deviceExtension
->BaseIoAHCI_0
.pAddr
);
1860 KdPrint2((PRINT_PREFIX
"return SP_RETURN_NOT_FOUND\n"));
1864 KdPrint2((PRINT_PREFIX
"exit: init spinlock\n"));
1865 //KeInitializeSpinLock(&(deviceExtension->DpcSpinLock));
1866 deviceExtension
->ActiveDpcChan
=
1867 deviceExtension
->FirstDpcChan
= CHAN_NOT_SPECIFIED
;
1869 BMList
[i
].Isr2Enable
= FALSE
;
1871 KdPrint2((PRINT_PREFIX
"MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n",
1872 MasterDev
, deviceExtension
->NumberChannels
, BMList
[i
].Isr2DevObj
));
1874 // ConnectIntr2 should be moved to HwInitialize
1875 status
= UniataConnectIntr2(HwDeviceExtension
);
1877 KdPrint2((PRINT_PREFIX
"MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n",
1878 MasterDev
, deviceExtension
->NumberChannels
, BMList
[i
].Isr2DevObj
));
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,
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;
1892 if(!NT_SUCCESS(status
)) {
1893 KdPrint2((PRINT_PREFIX
"failed\n"));
1898 KdPrint2((PRINT_PREFIX
"final chan[%d] InterruptMode: %d, Level %d, Level2 %d, Vector %d, Vector2 %d\n",
1900 ConfigInfo
->InterruptMode
,
1901 ConfigInfo
->BusInterruptLevel
,
1902 ConfigInfo
->BusInterruptLevel2
,
1903 ConfigInfo
->BusInterruptVector
,
1904 ConfigInfo
->BusInterruptVector2
1909 #endif //UNIATA_CORE
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]);
1915 KdPrint2((PRINT_PREFIX
"Attempt %d of MasterDev ok\n", AltInit
));
1916 FirstMasterOk
= TRUE
;
1919 ConfigInfo
->NumberOfBuses
++; // add virtual channel for communication port
1920 return SP_RETURN_FOUND
;
1923 UniataFreeLunExt(deviceExtension
);
1924 return SP_RETURN_ERROR
;
1927 UniataFreeLunExt(deviceExtension
);
1928 return SP_RETURN_NOT_FOUND
;
1930 } // end UniataFindBusMasterController()
1935 This is for claiming PCI Busmaster in compatible mode under WDM OSes
1939 UniataClaimLegacyPCIIDE(
1944 PCM_RESOURCE_LIST resourceList
= NULL
;
1945 UNICODE_STRING devname
;
1947 KdPrint2((PRINT_PREFIX
"UniataClaimLegacyPCIIDE:\n"));
1949 if(BMList
[i
].PciIdeDevObj
) {
1950 KdPrint2((PRINT_PREFIX
"Already initialized\n"));
1951 return STATUS_UNSUCCESSFUL
;
1954 RtlInitUnicodeString(&devname
, L
"\\Device\\uniata_PCIIDE");
1955 status
= IoCreateDevice(SavedDriverObject
, sizeof(PCIIDE_DEVICE_EXTENSION
),
1956 /*NULL*/ &devname
, FILE_DEVICE_UNKNOWN
,
1957 0, FALSE
, &(BMList
[i
].PciIdeDevObj
));
1959 if(!NT_SUCCESS(status
)) {
1960 KdPrint2((PRINT_PREFIX
"IoCreateDevice failed %#x\n", status
));
1964 resourceList
= (PCM_RESOURCE_LIST
) ExAllocatePool(PagedPool
,
1965 sizeof(CM_RESOURCE_LIST
));
1967 if (!resourceList
) {
1968 KdPrint2((PRINT_PREFIX
"!resourceList\n"));
1969 status
= STATUS_INSUFFICIENT_RESOURCES
;
1971 IoDeleteDevice(BMList
[i
].PciIdeDevObj
);
1972 BMList
[i
].PciIdeDevObj
= NULL
;
1978 sizeof(CM_RESOURCE_LIST
));
1980 // IoReportDetectedDevice() should be used for WDM OSes
1982 // TODO: check if resourceList is actually used inside HalAssignSlotResources()
1983 // Note: with empty resourceList call to HalAssignSlotResources() fails on some HW
1984 // e.g. Intel ICH4, but works with non-empty.
1986 resourceList
->Count
= 1;
1987 resourceList
->List
[0].InterfaceType
= PCIBus
;
1988 resourceList
->List
[0].BusNumber
= BMList
[i
].busNumber
;
1989 // we do not report IO ranges since they are used/claimed by ISA part(s)
1990 resourceList
->List
[0].PartialResourceList
.Count
= 0;
1992 RtlInitUnicodeString(&devname
, L
"PCIIDE");
1993 status
= HalAssignSlotResources(&SavedRegPath
,
1996 BMList
[i
].PciIdeDevObj
,
1998 BMList
[i
].busNumber
,
1999 BMList
[i
].slotNumber
,
2002 if (!NT_SUCCESS(status
)) {
2003 KdPrint2((PRINT_PREFIX
"HalAssignSlotResources failed %#x\n", status
));
2004 // this is always deallocated inside HalAssignSlotResources() implementation
2005 //ExFreePool(resourceList);
2009 KdPrint2((PRINT_PREFIX
"ok %#x\n", status
));
2010 BMList
[i
].ChanInitOk
|= 0x80;
2013 } // end UniataClaimLegacyPCIIDE()
2018 Routine Description:
2020 This function is called to initialize 2nd device object for
2021 multichannel controllers.
2025 HwDeviceExtension - HBA miniport driver's adapter data storage
2035 IN PVOID HwDeviceExtension
2038 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2039 ULONG i
= deviceExtension
->DevIndex
;
2041 PISR2_DEVICE_EXTENSION Isr2DevExt
;
2042 WCHAR devname_str
[33];
2043 UNICODE_STRING devname
;
2045 KdPrint2((PRINT_PREFIX
"Init ISR:\n"));
2048 We MUST register 2nd ISR for multichannel controllers even for UP systems.
2049 This is needed for cases when
2050 multichannel controller generate interrupt while we are still in its ISR for
2051 other channle's interrupt. New interrupt must be detected and queued for
2052 further processing. If we do not do this, system will not route this
2053 interrupt to main ISR (since it is busy) and we shall get to infinite loop
2054 looking for interrupt handler.
2057 if(!deviceExtension
->MasterDev
&& (deviceExtension
->NumberChannels
> 1) && // do not touch MasterDev
2058 !deviceExtension
->simplexOnly
&& /* // this is unnecessary on simplex controllers
2059 !BMList[i].Isr2DevObj*/ // handle re-init under w2k+
2061 /*(CPU_num > 1) && // unnecessary for UP systems*/
2064 KdPrint2((PRINT_PREFIX
"Multichannel native mode, go...\n"));
2065 #ifndef UNIATA_USE_XXableInterrupts
2066 // If we raise IRQL to TIMER value, other interrupt cannot occure on the same CPU
2067 /* if(KeNumberProcessors < 2) {
2068 KdPrint2((PRINT_PREFIX "Unnecessary (?), UP machine\n"));
2069 //return STATUS_SUCCESS;
2071 #endif //UNIATA_USE_XXableInterrupts
2073 KdPrint2((PRINT_PREFIX
"Unnecessary\n"));
2074 return STATUS_SUCCESS
;
2077 if(BMList
[i
].Isr2DevObj
) {
2078 KdPrint2((PRINT_PREFIX
"Already initialized [%d] %#x\n", i
, BMList
[i
].Isr2DevObj
));
2079 return STATUS_SUCCESS
;
2082 KdPrint2((PRINT_PREFIX
"Create DO\n"));
2085 _snwprintf(devname_str
, sizeof(devname_str
)/sizeof(WCHAR
)-1,
2086 L
"\\Device\\uniata%d_2ch", i
);
2087 devname_str
[devname
.Length
] = 0;
2088 devname
.Length
*= sizeof(WCHAR
);
2089 devname
.MaximumLength
= devname
.Length
;
2090 devname
.Buffer
= devname_str
;
2092 KdPrint2((PRINT_PREFIX
"DO name: len(%d, %d), %S\n", devname
.Length
, devname
.MaximumLength
, devname
.Buffer
));
2094 status
= IoCreateDevice(SavedDriverObject
, sizeof(ISR2_DEVICE_EXTENSION
),
2095 /*NULL*/ &devname
, FILE_DEVICE_UNKNOWN
,
2096 0, FALSE
, &(BMList
[i
].Isr2DevObj
));
2098 if(!NT_SUCCESS(status
)) {
2099 KdPrint2((PRINT_PREFIX
"IoCreateDevice failed %#x\n", status
));
2103 KdPrint2((PRINT_PREFIX
"HalGetInterruptVector\n"));
2104 KdPrint2((PRINT_PREFIX
" OrigAdapterInterfaceType=%d\n", deviceExtension
->OrigAdapterInterfaceType
));
2105 KdPrint2((PRINT_PREFIX
" SystemIoBusNumber=%d\n", deviceExtension
->SystemIoBusNumber
));
2106 KdPrint2((PRINT_PREFIX
" BusInterruptLevel=%d\n", deviceExtension
->BusInterruptLevel
));
2107 KdPrint2((PRINT_PREFIX
" BusInterruptVector=%d\n", deviceExtension
->BusInterruptVector
));
2108 BMList
[i
].Isr2Vector
= HalGetInterruptVector(
2109 deviceExtension
->OrigAdapterInterfaceType
,
2110 deviceExtension
->SystemIoBusNumber
,
2111 deviceExtension
->BusInterruptLevel
,
2112 deviceExtension
->BusInterruptVector
,
2113 &(BMList
[i
].Isr2Irql
),
2114 &(BMList
[i
].Isr2Affinity
));
2116 Isr2DevExt
= (PISR2_DEVICE_EXTENSION
)(BMList
[i
].Isr2DevObj
->DeviceExtension
);
2117 Isr2DevExt
->HwDeviceExtension
= deviceExtension
;
2118 Isr2DevExt
->DevIndex
= i
;
2120 KdPrint2((PRINT_PREFIX
"isr2_de %#x\n", Isr2DevExt
));
2121 KdPrint2((PRINT_PREFIX
"isr2_vector %#x\n", BMList
[i
].Isr2Vector
));
2122 KdPrint2((PRINT_PREFIX
"isr2_irql %#x\n", BMList
[i
].Isr2Irql
));
2123 KdPrint2((PRINT_PREFIX
"isr2_affinity %#x\n", BMList
[i
].Isr2Affinity
));
2125 // deviceExtension->QueueNewIrql = BMList[i].Isr2Irql;
2127 KdPrint2((PRINT_PREFIX
"IoConnectInterrupt\n"));
2128 status
= IoConnectInterrupt(
2129 &(BMList
[i
].Isr2InterruptObject
),
2133 BMList
[i
].Isr2Vector
,
2136 (KINTERRUPT_MODE
)(deviceExtension
->InterruptMode
),
2138 BMList
[i
].Isr2Affinity
,
2141 if(!NT_SUCCESS(status
)) {
2142 KdPrint2((PRINT_PREFIX
"IoConnectInterrupt failed\n"));
2143 IoDeleteDevice(BMList
[i
].Isr2DevObj
);
2144 BMList
[i
].Isr2DevObj
= NULL
;
2145 BMList
[i
].Isr2InterruptObject
= NULL
;
2149 //deviceExtension->Isr2DevObj = BMList[i].Isr2DevObj;
2152 } // end UniataConnectIntr2()
2156 UniataDisconnectIntr2(
2157 IN PVOID HwDeviceExtension
2160 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2161 ULONG i
= deviceExtension
->DevIndex
;
2164 KdPrint2((PRINT_PREFIX
"Deinit ISR:\n"));
2166 if(!BMList
[i
].Isr2DevObj
) {
2167 KdPrint2((PRINT_PREFIX
"Already uninitialized %#x\n"));
2168 return STATUS_SUCCESS
;
2171 IoDisconnectInterrupt(BMList
[i
].Isr2InterruptObject
);
2173 BMList
[i
].Isr2InterruptObject
= NULL
;
2175 IoDeleteDevice(BMList
[i
].Isr2DevObj
);
2177 BMList
[i
].Isr2DevObj
= NULL
;
2178 //deviceExtension->Isr2DevObj = NULL;
2180 return STATUS_SUCCESS
;
2181 } // end UniataDisconnectIntr2()
2183 #endif //UNIATA_CORE
2187 AtapiCheckIOInterference(
2188 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
2190 // check if Primary/Secondary Master IDE claimed
2191 if((portBase
== IO_WD1
) &&
2192 (ConfigInfo
->AtdiskPrimaryClaimed
|| AtdiskPrimaryClaimed
)) {
2193 KdPrint2((PRINT_PREFIX
"AtapiCheckIOInterference: AtdiskPrimaryClaimed\n"));
2196 if((portBase
== IO_WD2
) &&
2197 (ConfigInfo
->AtdiskSecondaryClaimed
|| AtdiskSecondaryClaimed
)) {
2198 KdPrint2((PRINT_PREFIX
"AtapiCheckIOInterference: AtdiskSecondaryClaimed\n"));
2202 } // end AtapiCheckIOInterference()
2206 Routine Description:
2208 This function is called by the OS-specific port driver after
2209 the necessary storage has been allocated, to gather information
2210 about the adapter's configuration.
2214 HwDeviceExtension - HBA miniport driver's adapter data storage
2215 Context - Address of adapter count
2216 ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility.
2217 ConfigInfo - Configuration information structure describing HBA
2218 Again - Indicates search for adapters to continue
2227 AtapiFindIsaController(
2228 IN PVOID HwDeviceExtension
,
2230 IN PVOID BusInformation
,
2231 IN PCHAR ArgumentString
,
2232 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
2236 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2238 PULONG adapterCount
= (PULONG
)Context
;
2239 PUCHAR ioSpace
= NULL
;
2244 // BOOLEAN atapiOnly;
2245 UCHAR statusByte
, statusByte2
;
2246 BOOLEAN preConfig
= FALSE
;
2248 PIDE_REGISTERS_1 BaseIoAddress1
;
2249 PIDE_REGISTERS_2 BaseIoAddress2
= NULL
;
2251 // The following table specifies the ports to be checked when searching for
2252 // an IDE controller. A zero entry terminates the search.
2253 static CONST ULONG AdapterAddresses
[5] = {IO_WD1
, IO_WD2
, IO_WD1
-8, IO_WD2
-8, 0};
2254 // CONST UCHAR Channels[5] = {0, 1, 0, 1, 0};
2256 // The following table specifies interrupt levels corresponding to the
2257 // port addresses in the previous table.
2258 static CONST ULONG InterruptLevels
[5] = {14, 15, 11, 10, 0};
2260 KdPrint2((PRINT_PREFIX
"AtapiFindIsaController (ISA):\n"));
2262 if (!deviceExtension
) {
2263 return SP_RETURN_ERROR
;
2265 RtlZeroMemory(deviceExtension
, sizeof(HW_DEVICE_EXTENSION
));
2267 KdPrint2((PRINT_PREFIX
" assume max PIO4\n"));
2268 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
2269 deviceExtension
->NumberChannels
= 1;
2270 deviceExtension
->NumberLuns
= IDE_MAX_LUN_PER_CHAN
; // default
2272 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
2276 chan
= &(deviceExtension
->chan
[0]);
2277 AtapiSetupLunPtrs(chan
, deviceExtension
, 0);
2279 deviceExtension
->AdapterInterfaceType
=
2280 deviceExtension
->OrigAdapterInterfaceType
2281 = ConfigInfo
->AdapterInterfaceType
;
2285 /* do extra chipset specific setups */
2286 AtapiReadChipConfig(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, CHAN_NOT_SPECIFIED
);
2287 AtapiChipInit(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, CHAN_NOT_SPECIFIED
);
2289 // Check to see if this is a special configuration environment.
2291 if (ArgumentString
) {
2293 irq
= AtapiParseArgumentString(ArgumentString
, "Interrupt");
2296 // Both parameters must be present to proceed
2297 portBase
= AtapiParseArgumentString(ArgumentString
, "BaseAddress");
2300 // Try a default search for the part.
2306 #endif //UNIATA_CORE
2308 for(i=0; i<2; i++) {
2309 if((*ConfigInfo->AccessRanges)[i].RangeStart) {
2310 KdPrint2((PRINT_PREFIX " IoRange[%d], start %#x, len %#x, mem %#x\n",
2312 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[i].RangeStart),
2313 (*ConfigInfo->AccessRanges)[i].RangeLength,
2314 (*ConfigInfo->AccessRanges)[i].RangeInMemory
2319 // if((*ConfigInfo->AccessRanges)[0].RangeStart) {
2320 portBase
= ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[0].RangeStart
);
2323 if(!AtapiCheckIOInterference(ConfigInfo
, portBase
)) {
2324 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2325 ConfigInfo
->AdapterInterfaceType
,
2326 ConfigInfo
->SystemIoBusNumber
,
2327 (*ConfigInfo
->AccessRanges
)[0].RangeStart
,
2328 (*ConfigInfo
->AccessRanges
)[0].RangeLength
,
2329 (BOOLEAN
) !((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
));
2331 // do not touch resources, just fail later inside loop on next call to
2332 // AtapiCheckIOInterference()
2335 // Since we have pre-configured information we only need to go through this loop once
2337 KdPrint2((PRINT_PREFIX
" preconfig, portBase=%x, len=%x\n", portBase
, (*ConfigInfo
->AccessRanges
)[0].RangeLength
));
2340 // Scan through the adapter address looking for adapters.
2342 while (AdapterAddresses
[*adapterCount
] != 0) {
2345 #endif //UNIATA_CORE
2348 deviceExtension
->DevIndex
= (*adapterCount
); // this is used inside AtapiRegCheckDevValue()
2349 KdPrint2((PRINT_PREFIX
"AtapiFindIsaController: adapterCount=%d\n", *adapterCount
));
2351 for (i
= 0; i
< deviceExtension
->NumberLuns
; i
++) {
2352 // Zero device fields to ensure that if earlier devices were found,
2353 // but not claimed, the fields are cleared.
2354 deviceExtension
->lun
[i
].DeviceFlags
&= ~(DFLAGS_ATAPI_DEVICE
| DFLAGS_DEVICE_PRESENT
| DFLAGS_TAPE_DEVICE
);
2356 // Get the system physical address for this IO range.
2358 // Check if configInfo has the default information
2359 // if not, we go and find ourselves
2360 if (preConfig
== FALSE
) {
2362 ULONG portBase_reg
= 0;
2366 portBase
= AdapterAddresses
[*adapterCount
];
2367 KdPrint2((PRINT_PREFIX
"portBase[%d]=%x\n", *adapterCount
, portBase
));
2369 KdPrint2((PRINT_PREFIX
"portBase=%x\n", portBase
));
2372 portBase_reg
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"PortBase", 0);
2373 irq_reg
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"Irq", 0);
2374 if(portBase_reg
&& irq_reg
) {
2375 KdPrint2((PRINT_PREFIX
"use registry settings portBase=%x, irq=%d\n", portBase_reg
, irq_reg
));
2376 portBase
= portBase_reg
;
2379 // check if Primary/Secondary Master IDE claimed
2380 if(AtapiCheckIOInterference(ConfigInfo
, portBase
)) {
2383 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2384 ConfigInfo
->AdapterInterfaceType
,
2385 ConfigInfo
->SystemIoBusNumber
,
2386 ScsiPortConvertUlongToPhysicalAddress(portBase
),
2391 KdPrint2((PRINT_PREFIX
"preconfig portBase=%x\n", portBase
));
2392 // Check if Primary/Secondary Master IDE claimed
2393 // We can also get here from preConfig branc with conflicting portBase
2394 // (and thus, w/o ioSpace allocated)
2395 if(AtapiCheckIOInterference(ConfigInfo
, portBase
)) {
2399 BaseIoAddress1
= (PIDE_REGISTERS_1
)ioSpace
;
2401 // Update the adapter count.
2404 // Check if ioSpace accessible.
2406 KdPrint2((PRINT_PREFIX
"AtapiFindIsaController: !ioSpace\n"));
2411 // Get the system physical address for the second IO range.
2412 if (BaseIoAddress1
) {
2414 !ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[1].RangeStart
)) {
2415 KdPrint2((PRINT_PREFIX
"AtapiFindIsaController: PCMCIA ?\n"));
2416 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2417 ConfigInfo
->AdapterInterfaceType
,
2418 ConfigInfo
->SystemIoBusNumber
,
2419 ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR
)BaseIoAddress1
+ 0x0E),
2423 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2424 ConfigInfo
->AdapterInterfaceType
,
2425 ConfigInfo
->SystemIoBusNumber
,
2426 ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR
)BaseIoAddress1
+ ATA_ALTOFFSET
),
2431 BaseIoAddress2
= (PIDE_REGISTERS_2
)ioSpace
;
2432 KdPrint2((PRINT_PREFIX
" BaseIoAddress1=%x\n", BaseIoAddress1
));
2433 KdPrint2((PRINT_PREFIX
" BaseIoAddress2=%x\n", BaseIoAddress2
));
2435 KdPrint2((PRINT_PREFIX
" expected InterruptLevel=%x\n", InterruptLevels
[*adapterCount
- 1]));
2438 UniataInitMapBase(chan
, BaseIoAddress1
, BaseIoAddress2
);
2439 UniataInitMapBM(deviceExtension
, 0, FALSE
);
2442 UniataDumpATARegs(chan
);
2446 SelectDrive(chan
, 0);
2448 statusByte
= AtapiReadPort1(chan
, IDX_IO1_i_Status
);
2449 statusByte2
= AtapiReadPort1(chan
, IDX_IO2_AltStatus
);
2450 if((statusByte
^ statusByte2
) & ~IDE_STATUS_INDEX
) {
2451 KdPrint2((PRINT_PREFIX
"AtapiFindIsaController: Status %x vs AltStatus %x missmatch, abort init ?\n", statusByte
, statusByte2
));
2453 if(BaseIoAddress2
) {
2454 ScsiPortFreeDeviceBase(HwDeviceExtension
,
2455 (PCHAR
)BaseIoAddress2
);
2456 BaseIoAddress2
= NULL
;
2458 BaseIoAddress2
= (PIDE_REGISTERS_2
)((ULONGIO_PTR
)BaseIoAddress1
+ 0x0E);
2459 KdPrint2((PRINT_PREFIX
" try BaseIoAddress2=%x\n", BaseIoAddress2
));
2460 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2461 ConfigInfo
->AdapterInterfaceType
,
2462 ConfigInfo
->SystemIoBusNumber
,
2463 ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR
)BaseIoAddress2
),
2467 BaseIoAddress2
= NULL
;
2468 KdPrint2((PRINT_PREFIX
" abort (0)\n"));
2471 UniataInitMapBase(chan
, BaseIoAddress1
, BaseIoAddress2
);
2472 statusByte
= AtapiReadPort1(chan
, IDX_IO1_i_Status
);
2473 statusByte2
= AtapiReadPort1(chan
, IDX_IO2_AltStatus
);
2474 if((statusByte
^ statusByte2
) & ~IDE_STATUS_INDEX
) {
2475 KdPrint2((PRINT_PREFIX
" abort: Status %x vs AltStatus %x missmatch\n", statusByte
, statusByte2
));
2483 SelectDrive(chan
, 0);
2485 // Check if card at this address.
2486 AtapiWritePort1(chan
, IDX_IO1_o_CylinderLow
, 0xAA);
2487 statusByte
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
);
2489 // Check if indentifier can be read back.
2490 if (AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
) != 0xAA ||
2491 statusByte
== IDE_STATUS_WRONG
) {
2493 KdPrint2((PRINT_PREFIX
"AtapiFindIsaController: Identifier read back from Master (%#x)\n",
2496 statusByte
= AtapiReadPort1(chan
, IDX_IO2_AltStatus
);
2498 if (statusByte
!= IDE_STATUS_WRONG
&& (statusByte
& IDE_STATUS_BUSY
)) {
2502 // Could be the TEAC in a thinkpad. Their dos driver puts it in a sleep-mode that
2503 // warm boots don't clear.
2505 AtapiStallExecution(1000);
2506 statusByte
= AtapiReadPort1(chan
, IDX_ATAPI_IO1_i_Status
);
2507 KdPrint2((PRINT_PREFIX
2508 "AtapiFindIsaController: First access to status %#x\n",
2510 } while ((statusByte
& IDE_STATUS_BUSY
) && ++i
< 10);
2512 if (retryCount
-- && (!(statusByte
& IDE_STATUS_BUSY
))) {
2513 goto retryIdentifier
;
2518 SelectDrive(chan
, 1);
2519 statusByte
= AtapiReadPort1(chan
, IDX_IO2_AltStatus
);
2521 // See if slave is present.
2522 AtapiWritePort1(chan
, IDX_IO1_o_CylinderLow
, 0xAA);
2524 if (AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
) != 0xAA ||
2525 statusByte
== IDE_STATUS_WRONG
) {
2527 KdPrint2((PRINT_PREFIX
2528 "AtapiFindIsaController: Identifier read back from Slave (%#x)\n",
2534 // Fill in the access array information only if default params are not in there.
2535 if (preConfig
== FALSE
) {
2537 // An adapter has been found request another call, only if we didn't get preconfigured info.
2541 (*ConfigInfo
->AccessRanges
)[0].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(portBase
);
2543 (*ConfigInfo
->AccessRanges
)[0].RangeStart
=
2544 ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses
[*adapterCount
- 1]);
2547 (*ConfigInfo
->AccessRanges
)[0].RangeLength
= ATA_IOSIZE
;
2548 (*ConfigInfo
->AccessRanges
)[0].RangeInMemory
= FALSE
;
2550 if(BaseIoAddress2
) {
2552 (*ConfigInfo
->AccessRanges
)[1].RangeStart
= ScsiPortConvertUlongToPhysicalAddress((ULONG
)BaseIoAddress2
);
2553 (*ConfigInfo
->AccessRanges
)[1].RangeLength
= ATA_ALTIOSIZE
;
2554 (*ConfigInfo
->AccessRanges
)[1].RangeInMemory
= FALSE
;
2556 // NT4 and NT3.51 on ISA-only hardware definitly fail floppy.sys load
2557 // when this range is claimed by other driver.
2558 // However, floppy should use only 0x3f0-3f5,3f7
2559 if((ULONG
)BaseIoAddress2
>= 0x3f0 && (ULONG
)BaseIoAddress2
<= 0x3f7) {
2560 KdPrint2((PRINT_PREFIX
"!!! Possible AltStatus vs Floppy IO range interference !!!\n"));
2562 KdPrint2((PRINT_PREFIX
"Do not expose to OS on old ISA\n"));
2563 (*ConfigInfo
->AccessRanges
)[1].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(0);
2564 (*ConfigInfo
->AccessRanges
)[1].RangeLength
= 0;
2568 // Indicate the interrupt level corresponding to this IO range.
2570 ConfigInfo
->BusInterruptLevel
= irq
;
2572 ConfigInfo
->BusInterruptLevel
= InterruptLevels
[*adapterCount
- 1];
2575 if (ConfigInfo
->AdapterInterfaceType
== MicroChannel
) {
2576 ConfigInfo
->InterruptMode
= LevelSensitive
;
2578 ConfigInfo
->InterruptMode
= Latched
;
2582 ConfigInfo
->NumberOfBuses
= 1;
2583 ConfigInfo
->MaximumNumberOfTargets
= IDE_MAX_LUN_PER_CHAN
;
2585 // Indicate maximum transfer length is 64k.
2586 ConfigInfo
->MaximumTransferLength
= 0x10000;
2587 deviceExtension
->MaximumDmaTransferLength
= ConfigInfo
->MaximumTransferLength
;
2589 KdPrint2((PRINT_PREFIX
"de %#x, Channel ???\n", deviceExtension
));
2590 //PrintNtConsole("de %#x, Channel %#x, nchan %#x\n",deviceExtension, channel, deviceExtension->NumberChannels);
2592 KdPrint2((PRINT_PREFIX
"chan = %#x\n", chan
));
2593 //PrintNtConsole("chan = %#x, c=%#x\n", chan, c);
2595 // should be already set up in AtapiSetupLunPtrs(chan, deviceExtension, 0);
2597 chan->DeviceExtension = deviceExtension;
2599 chan->lun[0] = &(deviceExtension->lun[0]);
2600 chan->lun[1] = &(deviceExtension->lun[1]);*/
2602 /* do extra channel-specific setups */
2603 AtapiReadChipConfig(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, 0);
2604 AtapiChipInit(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, 0);
2606 KdPrint2((PRINT_PREFIX
2607 "AtapiFindIsaController: Found IDE at %#x\n",
2610 // For Daytona, the atdisk driver gets the first shot at the
2611 // primary and secondary controllers.
2612 if (preConfig
== FALSE
) {
2614 if (*adapterCount
- 1 < 2) {
2616 // Determine whether this driver is being initialized by the
2617 // system or as a crash dump driver.
2620 deviceExtension
->DriverMustPoll
= TRUE
;
2621 #endif //UNIATA_CORE
2623 deviceExtension
->DriverMustPoll
= FALSE
;
2627 //atapiOnly = FALSE;
2632 //atapiOnly = FALSE;
2633 deviceExtension
->DriverMustPoll
= FALSE
;
2637 // Save the Interrupe Mode for later use
2638 deviceExtension
->InterruptMode
= ConfigInfo
->InterruptMode
;
2639 deviceExtension
->BusInterruptLevel
= ConfigInfo
->BusInterruptLevel
;
2640 deviceExtension
->BusInterruptVector
= ConfigInfo
->BusInterruptVector
;
2642 KdPrint2((PRINT_PREFIX
2643 "AtapiFindIsaController: look for devices\n"));
2644 // Search for devices on this controller.
2645 if (FindDevices(HwDeviceExtension
,
2649 KdPrint2((PRINT_PREFIX
2650 "AtapiFindIsaController: detected\n"));
2651 // Claim primary or secondary ATA IO range.
2655 ConfigInfo
->AtdiskSecondaryClaimed
= TRUE
;
2656 chan
->PrimaryAddress
= FALSE
;
2659 ConfigInfo
->AtdiskPrimaryClaimed
= TRUE
;
2660 chan
->PrimaryAddress
= TRUE
;
2666 if (*adapterCount
== 1) {
2667 ConfigInfo
->AtdiskPrimaryClaimed
= TRUE
;
2668 chan
->PrimaryAddress
= TRUE
;
2669 } else if (*adapterCount
== 2) {
2670 ConfigInfo
->AtdiskSecondaryClaimed
= TRUE
;
2671 chan
->PrimaryAddress
= FALSE
;
2675 if(deviceExtension
->AdapterInterfaceType
== Isa
) {
2678 if(deviceExtension
->AdapterInterfaceType
== MicroChannel
) {
2682 ConfigInfo
->NumberOfBuses
++; // add virtual channel for communication port
2683 KdPrint2((PRINT_PREFIX
2684 "AtapiFindIsaController: return SP_RETURN_FOUND\n"));
2685 return(SP_RETURN_FOUND
);
2688 // No controller at this base address.
2689 if(BaseIoAddress1
) {
2690 ScsiPortFreeDeviceBase(HwDeviceExtension
,
2691 (PCHAR
)BaseIoAddress1
);
2692 BaseIoAddress1
= NULL
;
2694 if(BaseIoAddress2
) {
2695 ScsiPortFreeDeviceBase(HwDeviceExtension
,
2696 (PCHAR
)BaseIoAddress2
);
2697 BaseIoAddress2
= NULL
;
2699 for(i
=0; i
<2; i
++) {
2700 KdPrint2((PRINT_PREFIX
2701 "AtapiFindIsaController: cleanup AccessRanges %d\n", i
));
2702 (*ConfigInfo
->AccessRanges
)[i
].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(0);
2703 (*ConfigInfo
->AccessRanges
)[i
].RangeLength
= 0;
2704 (*ConfigInfo
->AccessRanges
)[i
].RangeInMemory
= FALSE
;
2713 #endif //UNIATA_CORE
2715 // The entire table has been searched and no adapters have been found.
2716 // There is no need to call again and the device base can now be freed.
2717 // Clear the adapter count for the next bus.
2719 *(adapterCount
) = 0;
2721 KdPrint2((PRINT_PREFIX
2722 "AtapiFindIsaController: return SP_RETURN_NOT_FOUND\n"));
2723 UniataFreeLunExt(deviceExtension
);
2724 return(SP_RETURN_NOT_FOUND
);
2727 UniataFreeLunExt(deviceExtension
);
2728 return SP_RETURN_ERROR
;
2730 } // end AtapiFindIsaController()
2733 Do nothing, but parse ScsiPort ArgumentString and setup global variables.
2738 AtapiReadArgumentString(
2739 IN PVOID HwDeviceExtension
,
2741 IN PVOID BusInformation
,
2742 IN PCHAR ArgumentString
,
2743 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
2748 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2751 if (AtapiParseArgumentString(ArgumentString
, "dump") == 1) {
2752 KdPrint2((PRINT_PREFIX
2753 "AtapiReadArgumentString: Crash dump\n"));
2754 //atapiOnly = FALSE;
2757 return(SP_RETURN_NOT_FOUND
);
2758 } // end AtapiReadArgumentString()
2763 IN PVOID HwDeviceExtension
,
2765 IN ULONG deviceNumber
2768 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2769 PHW_CHANNEL chan
= &(deviceExtension
->chan
[lChannel
]);
2770 //ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0);
2771 PHW_LU_EXTENSION LunExt
= chan
->lun
[deviceNumber
];
2773 SATA_SSTATUS_REG SStatus
;
2775 UCHAR signatureHigh
;
2777 if(LunExt
->DeviceFlags
& DFLAGS_HIDDEN
) {
2778 KdPrint2((PRINT_PREFIX
" hidden\n"));
2779 UniataForgetDevice(LunExt
);
2780 return ATA_AT_HOME_NOBODY
;
2782 if(UniataIsSATARangeAvailable(deviceExtension
, lChannel
)) {
2784 SStatus
.Reg
= UniataSataReadPort4(chan
, IDX_SATA_SStatus
, deviceNumber
);
2785 KdPrint2((PRINT_PREFIX
"SStatus %x\n", SStatus
.Reg
));
2786 if(SStatus
.DET
<= SStatus_DET_Dev_NoPhy
) {
2787 KdPrint2((PRINT_PREFIX
" SATA DET <= SStatus_DET_Dev_NoPhy\n"));
2788 return ATA_AT_HOME_NOBODY
;
2790 if(SStatus
.SPD
< SStatus_SPD_Gen1
) {
2791 KdPrint2((PRINT_PREFIX
" SATA SPD < SStatus_SPD_Gen1\n"));
2792 return ATA_AT_HOME_NOBODY
;
2794 if(SStatus
.IPM
== SStatus_IPM_NoDev
) {
2795 KdPrint2((PRINT_PREFIX
" SATA IPN == SStatus_IPM_NoDev\n"));
2796 return ATA_AT_HOME_NOBODY
;
2798 if(!(deviceExtension
->HwFlags
& UNIATA_AHCI
)) {
2799 // Select the device for legacy.
2805 // Select the device.
2806 SelectDrive(chan
, deviceNumber
);
2807 AtapiStallExecution(5);
2810 if((deviceExtension
->HwFlags
& UNIATA_AHCI
) &&
2811 UniataIsSATARangeAvailable(deviceExtension
, lChannel
)) {
2812 KdPrint2((PRINT_PREFIX
" AHCI check\n"));
2813 ULONG SIG
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_SIG
);
2814 signatureLow
= (UCHAR
)(SIG
>> 16);
2815 signatureHigh
= (UCHAR
)(SIG
>> 24);
2817 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
);
2818 signatureHigh
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderHigh
);
2821 if (signatureLow
== ATAPI_MAGIC_LSB
&& signatureHigh
== ATAPI_MAGIC_MSB
) {
2822 KdPrint2((PRINT_PREFIX
" ATAPI at home\n"));
2823 return ATA_AT_HOME_ATAPI
;
2825 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
2826 KdPrint2((PRINT_PREFIX
" AHCI HDD at home\n"));
2827 return ATA_AT_HOME_HDD
;
2829 if(g_opt_VirtualMachine
> VM_NONE
/*== VM_BOCHS ||
2830 g_opt_VirtualMachine == VM_VBOX*/) {
2831 GetStatus(chan
, signatureLow
);
2833 KdPrint2((PRINT_PREFIX
" 0-status VM - not present\n"));
2834 UniataForgetDevice(LunExt
);
2835 return ATA_AT_HOME_NOBODY
;
2839 AtapiStallExecution(10);
2841 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0x55);
2842 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0x55);
2843 AtapiStallExecution(5);
2844 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_BlockNumber
);
2845 if(signatureLow
!= 0x55) {
2846 if(signatureLow
== 0xff || signatureLow
== 0) {
2847 KdPrint2((PRINT_PREFIX
" nobody home! %#x != 0x55\n", signatureLow
));
2848 UniataForgetDevice(LunExt
);
2849 return ATA_AT_HOME_NOBODY
;
2852 signatureLow
= AtapiReadPort1(chan
, IDX_ATAPI_IO1_o_ByteCountHigh
);
2854 AtapiWritePort1(chan
, IDX_ATAPI_IO1_o_ByteCountHigh
, signatureLow
);
2855 AtapiStallExecution(5);
2856 signatureHigh
= AtapiReadPort1(chan
, IDX_ATAPI_IO1_o_ByteCountHigh
);
2857 if(signatureLow
!= signatureHigh
) {
2858 KdPrint2((PRINT_PREFIX
" nobody home! last chance failed %#x != %#x\n", signatureLow
, signatureHigh
));
2859 UniataForgetDevice(LunExt
);
2860 return ATA_AT_HOME_NOBODY
;
2862 return ATA_AT_HOME_XXX
;
2865 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0xAA);
2866 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0xAA);
2867 AtapiStallExecution(5);
2868 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_BlockNumber
);
2869 if(signatureLow
!= 0xAA) {
2870 KdPrint2((PRINT_PREFIX
" nobody home! %#x != 0xAA\n", signatureLow
));
2871 UniataForgetDevice(LunExt
);
2872 return ATA_AT_HOME_NOBODY
;
2875 KdPrint2((PRINT_PREFIX
" HDD at home\n"));
2876 return ATA_AT_HOME_HDD
;
2877 } // end UniataAnybodyHome()
2882 IN PVOID HwDeviceExtension
,
2884 IN ULONG deviceNumber
,
2888 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2889 PHW_CHANNEL chan
= &(deviceExtension
->chan
[lChannel
]);
2890 //ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0);
2891 PHW_LU_EXTENSION LunExt
;
2897 ULONG waitCount
= g_opt_WaitBusyResetCount
;
2900 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x\n",
2903 if(deviceNumber
>= chan
->NumberLuns
) {
2906 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
2907 if(!(at_home
= UniataAnybodyHome(HwDeviceExtension
, lChannel
, deviceNumber
))) {
2911 LunExt
= chan
->lun
[deviceNumber
];
2914 LunExt
->PowerState
= 0;
2917 if((deviceExtension
->HwFlags
& UNIATA_SATA
) &&
2918 !UniataIsSATARangeAvailable(deviceExtension
, lChannel
) &&
2920 KdPrint2((PRINT_PREFIX
" SATA w/o i/o registers, check slave presence\n"));
2921 SelectDrive(chan
, deviceNumber
& 0x01);
2922 statusByte
= AtapiReadPort1(chan
, IDX_ATAPI_IO1_i_DriveSelect
);
2923 KdPrint2((PRINT_PREFIX
" DriveSelect: %#x\n", statusByte
));
2924 if((statusByte
& IDE_DRIVE_MASK
) != IDE_DRIVE_SELECT_2
) {
2925 KdPrint2((PRINT_PREFIX
"CheckDevice: (no dev)\n"));
2926 UniataForgetDevice(LunExt
);
2931 if(ResetDev
&& (deviceExtension
->HwFlags
& UNIATA_AHCI
)) {
2932 KdPrint2((PRINT_PREFIX
"CheckDevice: reset AHCI dev\n"));
2933 if(UniataAhciSoftReset(HwDeviceExtension
, chan
->lChannel
, deviceNumber
) == (ULONG
)(-1)) {
2934 KdPrint2((PRINT_PREFIX
"CheckDevice: (no dev)\n"));
2935 UniataForgetDevice(LunExt
);
2940 KdPrint2((PRINT_PREFIX
"CheckDevice: reset dev\n"));
2943 AtapiSoftReset(chan
, deviceNumber
);
2945 if(!(at_home
= UniataAnybodyHome(HwDeviceExtension
, lChannel
, deviceNumber
))) {
2946 //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 1\n"));
2949 statusByte
= WaitOnBusy(chan
);
2951 if((statusByte
| IDE_STATUS_BUSY
) == IDE_STATUS_WRONG
) {
2952 KdPrint2((PRINT_PREFIX
2953 "CheckDevice: bad status %x\n", statusByte
));
2955 if(statusByte
!= IDE_STATUS_WRONG
&& (statusByte
& IDE_STATUS_BUSY
)) {
2956 // Perform hard-reset.
2957 KdPrint2((PRINT_PREFIX
2958 "CheckDevice: BUSY\n"));
2960 AtapiHardReset(chan
, FALSE
, 500 * 1000);
2962 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER );
2963 chan->last_devsel = -1;
2964 AtapiStallExecution(500 * 1000);
2965 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER);
2967 SelectDrive(chan
, deviceNumber
& 0x01);
2970 // Wait for Busy to drop.
2971 AtapiStallExecution(100);
2972 GetStatus(chan
, statusByte
);
2974 } while ((statusByte
& IDE_STATUS_BUSY
) && waitCount
--);
2976 GetBaseStatus(chan
, statusByte
);
2977 KdPrint2((PRINT_PREFIX
2978 "CheckDevice: status after hard reset %x\n", statusByte
));
2981 if((statusByte
| IDE_STATUS_BUSY
) == IDE_STATUS_WRONG
) {
2982 KdPrint2((PRINT_PREFIX
2983 "CheckDevice: no dev ?\n"));
2984 UniataForgetDevice(LunExt
);
2987 if(UniataIsSATARangeAvailable(deviceExtension
, lChannel
)) {
2988 //if(deviceExtension->HwFlags & UNIATA_SATA) {
2989 KdPrint2((PRINT_PREFIX
2990 "CheckDevice: try enable SATA Phy\n"));
2991 statusByte
= UniataSataPhyEnable(HwDeviceExtension
, lChannel
, deviceNumber
);
2992 if(statusByte
== IDE_STATUS_WRONG
) {
2993 KdPrint2((PRINT_PREFIX
"CheckDevice: status %#x (no dev)\n", statusByte
));
2994 UniataForgetDevice(LunExt
);
3000 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
3001 RetVal
= LunExt
->DeviceFlags
;
3002 signatureLow
= signatureHigh
= 0; // make GCC happy
3004 // Select the device.
3005 SelectDrive(chan
, deviceNumber
);
3007 if(!(at_home
= UniataAnybodyHome(HwDeviceExtension
, lChannel
, deviceNumber
))) {
3008 //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 2\n"));
3012 statusByte
= WaitOnBaseBusyLong(chan
);
3014 GetBaseStatus(chan
, statusByte
);
3015 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
3016 UniataSataClearErr(HwDeviceExtension
, lChannel
, UNIATA_SATA_IGNORE_CONNECT
, deviceNumber
);
3019 KdPrint2((PRINT_PREFIX
"CheckDevice: status %#x\n", statusByte
));
3020 if(((statusByte
| IDE_STATUS_BUSY
) == IDE_STATUS_WRONG
) ||
3021 (statusByte
& IDE_STATUS_BUSY
)) {
3022 KdPrint2((PRINT_PREFIX
"CheckDevice: busy => return\n"));
3023 UniataForgetDevice(LunExt
);
3027 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
);
3028 signatureHigh
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderHigh
);
3031 // set default costs
3032 LunExt
->RwSwitchCost
= REORDER_COST_SWITCH_RW_HDD
;
3033 LunExt
->RwSwitchMCost
= REORDER_MCOST_SWITCH_RW_HDD
;
3034 LunExt
->SeekBackMCost
= REORDER_MCOST_SEEK_BACK_HDD
;
3035 LunExt
->AtapiReadyWaitDelay
= 0;
3037 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
3038 if(RetVal
& DFLAGS_DEVICE_PRESENT
) {
3039 if(IssueIdentify(HwDeviceExtension
,
3042 (RetVal
& DFLAGS_ATAPI_DEVICE
) ? IDE_COMMAND_ATAPI_IDENTIFY
: IDE_COMMAND_IDENTIFY
,
3045 KdPrint2((PRINT_PREFIX
"CheckDevice: detected AHCI Device %#x\n",
3048 //RetVal &= ~DFLAGS_ATAPI_DEVICE;
3049 //LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE;
3051 UniataForgetDevice(LunExt
);
3056 if (signatureLow
== ATAPI_MAGIC_LSB
&& signatureHigh
== ATAPI_MAGIC_MSB
) {
3058 KdPrint2((PRINT_PREFIX
"CheckDevice: ATAPI signature found\n"));
3059 // ATAPI signature found.
3060 // Issue the ATAPI identify command if this
3061 // is not for the crash dump utility.
3065 // Issue ATAPI packet identify command.
3066 if (IssueIdentify(HwDeviceExtension
,
3069 IDE_COMMAND_ATAPI_IDENTIFY
, FALSE
)) {
3071 // Indicate ATAPI device.
3072 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x is ATAPI\n",
3075 RetVal
= DFLAGS_DEVICE_PRESENT
| DFLAGS_ATAPI_DEVICE
;
3076 LunExt
->DeviceFlags
|= (DFLAGS_DEVICE_PRESENT
| DFLAGS_ATAPI_DEVICE
);
3078 // some ATAPI devices doesn't work with DPC on CMD-649
3079 // and probably some other controllers
3080 if(deviceExtension
->HwFlags
& UNIATA_NO_DPC_ATAPI
) {
3081 /* CMD 649, ROSB SWK33, ICH4 */
3082 KdPrint2((PRINT_PREFIX
"CheckDevice: UNIATA_NO_DPC_ATAPI\n"));
3083 deviceExtension
->UseDpc
= FALSE
;
3086 GetStatus(chan
, statusByte
);
3087 if (statusByte
& IDE_STATUS_ERROR
) {
3088 AtapiSoftReset(chan
, deviceNumber
);
3093 // Indicate no working device.
3094 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x not responding\n",
3097 UniataForgetDevice(LunExt
);
3100 GetBaseStatus(chan
, statusByte
);
3106 KdPrint2((PRINT_PREFIX
"CheckDevice: IDE device check\n"));
3107 // Issue IDE Identify. If an Atapi device is actually present, the signature
3108 // will be asserted, and the drive will be recognized as such.
3109 if(deviceExtension
->DWordIO
) {
3110 KdPrint2((PRINT_PREFIX
" try 32bit IO\n"));
3111 LunExt
->DeviceFlags
|= DFLAGS_DWORDIO_ENABLED
;
3113 if (IssueIdentify(HwDeviceExtension
,
3116 IDE_COMMAND_IDENTIFY
, FALSE
)) {
3119 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x is IDE\n",
3122 // Indicate IDE - not ATAPI device.
3123 RetVal
= DFLAGS_DEVICE_PRESENT
;
3124 LunExt
->DeviceFlags
|= DFLAGS_DEVICE_PRESENT
;
3125 LunExt
->DeviceFlags
&= ~DFLAGS_ATAPI_DEVICE
;
3127 if(g_opt_VirtualMachine
<= VM_NONE
) {
3128 // This can be ATAPI on broken hardware
3129 GetBaseStatus(chan
, statusByte
);
3130 if(!at_home
&& UniataAnybodyHome(HwDeviceExtension
, lChannel
, deviceNumber
)) {
3131 KdPrint2((PRINT_PREFIX
"CheckDevice: nobody at home post IDE\n"));
3134 KdPrint2((PRINT_PREFIX
"CheckDevice: try ATAPI %#x, status %#x\n",
3135 deviceNumber
, statusByte
));
3138 KdPrint2((PRINT_PREFIX
"CheckDevice: VM Device %#x not present\n",
3141 GetBaseStatus(chan
, statusByte
);
3143 KdPrint2((PRINT_PREFIX
"CheckDevice: check status: %sfound\n", RetVal
? "" : "not "));
3145 } // end CheckDevice()
3150 Routine Description:
3152 This routine is called from AtapiFindXxxController to identify
3153 devices attached to an IDE controller.
3157 HwDeviceExtension - HBA miniport driver's adapter data storage
3158 AtapiOnly - Indicates that routine should return TRUE only if
3159 an ATAPI device is attached to the controller.
3163 TRUE - True if devices found.
3169 IN PVOID HwDeviceExtension
,
3174 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
3175 PHW_CHANNEL chan
= &(deviceExtension
->chan
[Channel
]);
3176 PHW_LU_EXTENSION LunExt
;
3177 BOOLEAN deviceResponded
= FALSE
,
3178 skipSetParameters
= FALSE
;
3179 ULONG waitCount
= 10000;
3180 //ULONG deviceNumber;
3184 BOOLEAN AtapiOnly
= FALSE
;
3186 KdPrint2((PRINT_PREFIX
"FindDevices:\n"));
3188 // Disable interrupts
3189 AtapiDisableInterrupts(deviceExtension
, Channel
);
3190 // AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_DISABLE_INTERRUPTS | IDE_DC_A_4BIT );
3192 // Clear expecting interrupt flag and current SRB field.
3193 UniataExpectChannelInterrupt(chan
, FALSE
);
3194 // chan->CurrentSrb = NULL;
3195 // max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : IDE_MAX_LUN_PER_CHAN;
3196 max_ldev
= (chan
->ChannelCtrlFlags
& CTRFLAGS_NO_SLAVE
) ? 1 : deviceExtension
->NumberLuns
;
3197 KdPrint2((PRINT_PREFIX
" max_ldev %d\n", max_ldev
));
3199 // Search for devices.
3200 for (i
= 0; i
< max_ldev
; i
++) {
3201 //AtapiDisableInterrupts(deviceExtension, Channel);
3202 if(Flags
& UNIATA_FIND_DEV_UNHIDE
) {
3203 chan
->lun
[i
]->DeviceFlags
&= ~DFLAGS_HIDDEN
;
3206 (CheckDevice(HwDeviceExtension
, Channel
, i
, TRUE
) != 0);
3207 //AtapiEnableInterrupts(deviceExtension, Channel);
3210 if(chan
->DeviceExtension
->HwFlags
& UNIATA_AHCI
) {
3211 AtapiEnableInterrupts(deviceExtension
, Channel
);
3212 KdPrint2((PRINT_PREFIX
3213 "FindDevices: returning %d (AHCI)\n",
3215 return deviceResponded
;
3218 for (i
= 0; i
< max_ldev
; i
++) {
3219 LunExt
= chan
->lun
[i
];
3221 if (( LunExt
->DeviceFlags
& DFLAGS_DEVICE_PRESENT
) &&
3222 !(LunExt
->DeviceFlags
& DFLAGS_LBA_ENABLED
) &&
3223 !(LunExt
->DeviceFlags
& DFLAGS_ATAPI_DEVICE
) && deviceResponded
) {
3225 // This hideous hack is to deal with ESDI devices that return
3226 // garbage geometry in the IDENTIFY data.
3227 // This is ONLY for the crashdump environment as
3228 // these are ESDI devices.
3229 if (LunExt
->IdentifyData
.SectorsPerTrack
== 0x35 &&
3230 LunExt
->IdentifyData
.NumberOfHeads
== 0x07) {
3232 KdPrint2((PRINT_PREFIX
"FindDevices: Found nasty Compaq ESDI!\n"));
3234 // Change these values to something reasonable.
3235 LunExt
->IdentifyData
.SectorsPerTrack
= 0x34;
3236 LunExt
->IdentifyData
.NumberOfHeads
= 0x0E;
3239 if (LunExt
->IdentifyData
.SectorsPerTrack
== 0x35 &&
3240 LunExt
->IdentifyData
.NumberOfHeads
== 0x0F) {
3242 KdPrint2((PRINT_PREFIX
"FindDevices: Found nasty Compaq ESDI!\n"));
3244 // Change these values to something reasonable.
3245 LunExt
->IdentifyData
.SectorsPerTrack
= 0x34;
3246 LunExt
->IdentifyData
.NumberOfHeads
= 0x0F;
3250 if (LunExt
->IdentifyData
.SectorsPerTrack
== 0x36 &&
3251 LunExt
->IdentifyData
.NumberOfHeads
== 0x07) {
3253 KdPrint2((PRINT_PREFIX
"FindDevices: Found nasty UltraStor ESDI!\n"));
3255 // Change these values to something reasonable.
3256 LunExt
->IdentifyData
.SectorsPerTrack
= 0x3F;
3257 LunExt
->IdentifyData
.NumberOfHeads
= 0x10;
3258 skipSetParameters
= TRUE
;
3262 if (skipSetParameters
)
3265 statusByte
= WaitOnBusy(chan
);
3267 // Select the device.
3268 SelectDrive(chan
, i
& 0x01);
3269 GetStatus(chan
, statusByte
);
3271 if (statusByte
& IDE_STATUS_ERROR
) {
3273 // Reset the device.
3274 KdPrint2((PRINT_PREFIX
3275 "FindDevices: Resetting controller before SetDriveParameters.\n"));
3277 AtapiHardReset(chan
, FALSE
, 500 * 1000);
3279 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER );
3280 chan->last_devsel = -1;
3281 AtapiStallExecution(500 * 1000);
3282 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER);
3284 SelectDrive(chan
, i
& 0x01);
3287 // Wait for Busy to drop.
3288 AtapiStallExecution(100);
3289 GetStatus(chan
, statusByte
);
3291 } while ((statusByte
& IDE_STATUS_BUSY
) && waitCount
--);
3294 statusByte
= WaitOnBusy(chan
);
3296 KdPrint2((PRINT_PREFIX
3297 "FindDevices: Status before SetDriveParameters: (%#x) (%#x)\n",
3299 AtapiReadPort1(chan
, IDX_IO1_i_DriveSelect
)));
3301 GetBaseStatus(chan
, statusByte
);
3303 // Use the IDENTIFY data to set drive parameters.
3304 if (!SetDriveParameters(HwDeviceExtension
,i
,Channel
)) {
3306 KdPrint2((PRINT_PREFIX
3307 "FindDevices: Set drive parameters for device %d failed\n",
3309 // Don't use this device as writes could cause corruption.
3310 LunExt
->DeviceFlags
&= ~DFLAGS_DEVICE_PRESENT
;
3311 UniataForgetDevice(LunExt
);
3315 if (LunExt
->DeviceFlags
& DFLAGS_REMOVABLE_DRIVE
) {
3317 // Pick up ALL IDE removable drives that conform to Yosemite V0.2...
3321 // Indicate that a device was found.
3323 deviceResponded
= TRUE
;
3328 /* // Reset the controller. This is a feeble attempt to leave the ESDI
3329 // controllers in a state that ATDISK driver will recognize them.
3330 // The problem in ATDISK has to do with timings as it is not reproducible
3331 // in debug. The reset should restore the controller to its poweron state
3332 // and give the system enough time to settle.
3333 if (!deviceResponded) {
3335 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_RESET_CONTROLLER );
3336 AtapiStallExecution(50 * 1000);
3337 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_REENABLE_CONTROLLER);
3340 if(deviceResponded
) {
3341 for (i
= 0; i
< max_ldev
; i
++) {
3342 LunExt
= chan
->lun
[i
];
3344 KdPrint2((PRINT_PREFIX
3345 "FindDevices: select %d dev to clear INTR\n", i
));
3346 SelectDrive(chan
, i
);
3347 GetBaseStatus(chan
, statusByte
);
3348 KdPrint2((PRINT_PREFIX
3349 "FindDevices: statusByte=%#x\n", statusByte
));
3351 for (i
= 0; i
< max_ldev
; i
++) {
3352 LunExt
= chan
->lun
[i
];
3354 if(LunExt
->DeviceFlags
& DFLAGS_DEVICE_PRESENT
) {
3355 // Make sure some device (master is preferred) is selected on exit.
3356 KdPrint2((PRINT_PREFIX
3357 "FindDevices: select %d dev on exit\n", i
));
3358 SelectDrive(chan
, i
);
3364 GetBaseStatus(chan
, statusByte
);
3365 // Enable interrupts
3366 AtapiEnableInterrupts(deviceExtension
, Channel
);
3367 // AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_A_4BIT );
3368 GetBaseStatus(chan
, statusByte
);
3370 KdPrint2((PRINT_PREFIX
3371 "FindDevices: returning %d\n",
3374 return deviceResponded
;
3376 } // end FindDevices()