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
;
1259 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (3)", deviceExtension
->HwFlags
));
1260 if(deviceExtension
->HwFlags
& UNIATA_NO_DPC
) {
1261 /* CMD 649, ROSB SWK33, ICH4 */
1262 KdPrint2((PRINT_PREFIX
"UniataFindBusMasterController: UNIATA_NO_DPC (0)\n"));
1263 deviceExtension
->UseDpc
= FALSE
;
1267 if((WinVer_Id() <= WinVer_NT
) && AltInit
&& FirstMasterOk
) {
1268 // this is the 2nd attempt to init this controller by OUR driver
1269 KdPrint2((PRINT_PREFIX
"Skip primary/secondary claiming checks\n"));
1271 if((channel
==0) && ConfigInfo
->AtdiskPrimaryClaimed
) {
1272 KdPrint2((PRINT_PREFIX
"Error: Primary channel already claimed by another driver\n"));
1275 if((channel
==1) && ConfigInfo
->AtdiskSecondaryClaimed
) {
1276 KdPrint2((PRINT_PREFIX
"Error: Secondary channel already claimed by another driver\n"));
1281 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
1282 KdPrint2((PRINT_PREFIX
" AHCI registers layout\n"));
1284 if(deviceExtension
->AltRegMap
) {
1285 KdPrint2((PRINT_PREFIX
" Non-standard registers layout\n"));
1286 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
1287 KdPrint2((PRINT_PREFIX
"UNIATA_SATA -> IsBusMaster == TRUE\n"));
1288 if(!deviceExtension
->BusMaster
) {
1289 deviceExtension
->BusMaster
= DMA_MODE_BM
;
1293 deviceExtension
->BusMaster
= DMA_MODE_NONE
;
1295 if(WinVer_WDM_Model
&& !deviceExtension
->UnknownDev
) {
1296 UniataEnableIoPCI(ConfigInfo
->SystemIoBusNumber
, slotData
.u
.AsULONG
, &pciData
);
1298 // validate Mem/Io ranges
1302 for(j
=0; j
<PCI_TYPE0_ADDRESSES
; j
++) {
1303 if(pciData
.u
.type0
.BaseAddresses
[j
] & ~0x7) {
1304 //no_ranges = FALSE;
1306 KdPrint2((PRINT_PREFIX
"Range %d = %#x\n", j
, pciData
.u
.type0
.BaseAddresses
[j
]));
1311 if(IsBusMaster(&pciData
)) {
1313 KdPrint2((PRINT_PREFIX
"IsBusMaster == TRUE\n"));
1314 BaseIoAddressBM_0
= (PIDE_BUSMASTER_REGISTERS
)
1315 (AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, &pciData
, SystemIoBusNumber
,
1316 4, bm_offset
, MasterDev
? 0x08 : 0x10/*ATA_BMIOSIZE*/)/* - bm_offset*/); //range id
1317 if(BaseIoAddressBM_0
) {
1318 UniataInitMapBM(deviceExtension
,
1320 (*ConfigInfo
->AccessRanges
)[4].RangeInMemory
? TRUE
: FALSE
);
1321 deviceExtension
->BusMaster
= DMA_MODE_BM
;
1322 deviceExtension
->BaseIoAddressBM_0
.Addr
= (ULONGIO_PTR
)BaseIoAddressBM_0
;
1323 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
1324 deviceExtension
->BaseIoAddressBM_0
.MemIo
= TRUE
;
1327 KdPrint2((PRINT_PREFIX
" BusMasterAddress (base): %#x\n", BaseIoAddressBM_0
));
1330 if(!deviceExtension
->BusMaster
) {
1331 KdPrint2((PRINT_PREFIX
" !BusMasterAddress -> PIO4\n"));
1332 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
1335 if(deviceExtension
->BusMaster
&& !MasterDev
) {
1336 KdPrint2((PRINT_PREFIX
"IsBusMaster == TRUE && !MasterDev\n"));
1337 statusByte
= AtapiReadPort1(&(deviceExtension
->chan
[0]), IDX_BM_Status
);
1338 KdPrint2((PRINT_PREFIX
" BM statusByte = %x\n", statusByte
));
1339 if(statusByte
== IDE_STATUS_WRONG
) {
1340 KdPrint2((PRINT_PREFIX
" invalid port ?\n"));
1341 deviceExtension
->BusMaster
= DMA_MODE_NONE
;
1343 if(BaseIoAddressBM_0) {
1344 ScsiPortFreeDeviceBase(HwDeviceExtension,
1346 BaseIoAddressBM_0 = NULL;
1350 if(statusByte
& BM_STATUS_SIMPLEX_ONLY
) {
1351 KdPrint2((PRINT_PREFIX
" BM_STATUS => simplexOnly\n"));
1358 * the Cypress chip is a mess, it contains two ATA functions, but
1359 * both channels are visible on the first one.
1360 * simply ignore the second function for now, as the right
1361 * solution (ignoring the second channel on the first function)
1362 * doesn't work with the crappy ATA interrupt setup on the alpha.
1364 if (dev_id
== 0xc6931080 && slotData
.u
.bits
.FunctionNumber
> 1) {
1365 KdPrint2((PRINT_PREFIX
"dev_id == 0xc6931080 && FunctionNumber > 1 => exit_findbm\n"));
1369 /* do extra chipset specific setups */
1370 AtapiReadChipConfig(HwDeviceExtension
, i
, CHAN_NOT_SPECIFIED
);
1371 AtapiChipInit(HwDeviceExtension
, i
, CHAN_NOT_SPECIFIED_CHECK_CABLE
);
1373 simplexOnly
|= deviceExtension
->simplexOnly
;
1374 deviceExtension
->simplexOnly
|= simplexOnly
;
1376 KdPrint2((PRINT_PREFIX
"simplexOnly = %d (2)", simplexOnly
));
1378 //TODO: fix hang with UseDpc=TRUE in Simplex mode
1379 //deviceExtension->UseDpc = TRUE;
1381 KdPrint2((PRINT_PREFIX
"simplexOnly => UseDpc = FALSE\n"));
1382 deviceExtension
->UseDpc
= FALSE
;
1385 if(simplexOnly
&& MasterDev
) {
1386 if(deviceExtension
->NumberChannels
< IDE_DEFAULT_MAX_CHAN
) {
1387 KdPrint2((PRINT_PREFIX
"set NumberChannels = %d\n", IDE_DEFAULT_MAX_CHAN
));
1388 deviceExtension
->NumberChannels
= IDE_DEFAULT_MAX_CHAN
;
1389 if(BaseIoAddressBM_0
) {
1390 UniataInitMapBM(deviceExtension
,
1392 (*ConfigInfo
->AccessRanges
)[4].RangeInMemory
? TRUE
: FALSE
);
1397 (deviceExtension
->NumberChannels
> 1)) {
1398 KdPrint2((PRINT_PREFIX
"Error: channel > 0 && NumberChannels > 1\n"));
1402 // Indicate number of buses.
1403 ConfigInfo
->NumberOfBuses
= (UCHAR
)(deviceExtension
->NumberChannels
);
1404 if(!ConfigInfo
->InitiatorBusId
[0]) {
1405 ConfigInfo
->InitiatorBusId
[0] = (CHAR
)(IoGetConfigurationInformation()->ScsiPortCount
);
1406 KdPrint2((PRINT_PREFIX
"set ConfigInfo->InitiatorBusId[0] = %#x\n", ConfigInfo
->InitiatorBusId
[0]));
1408 // Indicate four devices can be attached to the adapter
1409 ConfigInfo
->MaximumNumberOfTargets
= (UCHAR
)(deviceExtension
->NumberLuns
);
1412 KdPrint2((PRINT_PREFIX
"MasterDev (2)\n"));
1414 if((WinVer_Id() > WinVer_NT) ||
1415 (deviceExtension->NumberChannels > 1)) {
1417 KdPrint2((PRINT_PREFIX "2 channels & 2 irq for 1 controller Win 2000+\n"));
1419 if (ConfigInfo->AdapterInterfaceType == MicroChannel) {
1420 ConfigInfo->InterruptMode2 =
1421 ConfigInfo->InterruptMode = LevelSensitive;
1423 ConfigInfo->InterruptMode2 =
1424 ConfigInfo->InterruptMode = Latched;
1426 ConfigInfo->BusInterruptLevel = 14;
1427 ConfigInfo->BusInterruptLevel2 = 15;
1431 KdPrint2((PRINT_PREFIX
"2 channels & 2 irq for 1 controller\n"));
1433 if (ConfigInfo
->AdapterInterfaceType
== MicroChannel
) {
1434 ConfigInfo
->InterruptMode2
=
1435 ConfigInfo
->InterruptMode
= LevelSensitive
;
1437 ConfigInfo
->InterruptMode2
=
1438 ConfigInfo
->InterruptMode
= Latched
;
1440 ConfigInfo
->BusInterruptLevel
= 14;
1441 ConfigInfo
->BusInterruptLevel2
= 15;
1443 KdPrint2((PRINT_PREFIX
"1 channels & 1 irq for 1 controller\n"));
1444 if (ConfigInfo
->AdapterInterfaceType
== MicroChannel
) {
1445 ConfigInfo
->InterruptMode
= LevelSensitive
;
1447 ConfigInfo
->InterruptMode
= Latched
;
1449 ConfigInfo
->BusInterruptLevel
= (channel
== 0 ? 14 : 15);
1452 KdPrint2((PRINT_PREFIX
"!MasterDev\n"));
1453 ConfigInfo
->SlotNumber
= slotNumber
;
1454 ConfigInfo
->SystemIoBusNumber
= SystemIoBusNumber
;
1455 ConfigInfo
->InterruptMode
= LevelSensitive
;
1457 /* primary and secondary channels share the same interrupt */
1458 if(!ConfigInfo
->BusInterruptVector
||
1459 (ConfigInfo
->BusInterruptVector
!= pciData
.u
.type0
.InterruptLine
)) {
1460 KdPrint2((PRINT_PREFIX
"patch irq line = %#x\n", pciData
.u
.type0
.InterruptLine
));
1461 ConfigInfo
->BusInterruptVector
= pciData
.u
.type0
.InterruptLine
; // set default value
1462 if(!ConfigInfo
->BusInterruptVector
) {
1463 KdPrint2((PRINT_PREFIX
"patch irq line (2) = 10\n"));
1464 ConfigInfo
->BusInterruptVector
= 10;
1468 ConfigInfo
->MultipleRequestPerLu
= TRUE
;
1469 ConfigInfo
->AutoRequestSense
= TRUE
;
1470 ConfigInfo
->TaggedQueuing
= TRUE
;
1472 if((WinVer_Id() >= WinVer_NT
) ||
1473 (ConfigInfo
->Length
>= sizeof(_ConfigInfo
->comm
) + sizeof(_ConfigInfo
->nt4
))) {
1474 KdPrint2((PRINT_PREFIX
"update ConfigInfo->nt4\n"));
1475 _ConfigInfo
->nt4
.DeviceExtensionSize
= sizeof(HW_DEVICE_EXTENSION
);
1476 _ConfigInfo
->nt4
.SpecificLuExtensionSize
= sizeof(HW_LU_EXTENSION
);
1477 //if(deviceExtension->HwFlags & UNIATA_AHCI) {
1478 _ConfigInfo
->nt4
.SrbExtensionSize
= sizeof(ATA_REQ
);
1480 // _ConfigInfo->nt4.SrbExtensionSize = FIELD_OFFSET(ATA_REQ, dma_tab) + sizeof(BM_DMA_ENTRY)*ATA_DMA_ENTRIES;
1482 KdPrint2((PRINT_PREFIX
"using AtaReq sz %x\n", _ConfigInfo
->nt4
.SrbExtensionSize
));
1484 if((WinVer_Id() > WinVer_2k
) ||
1485 (ConfigInfo
->Length
>= sizeof(_ConfigInfo
->comm
) + sizeof(_ConfigInfo
->nt4
) + sizeof(_ConfigInfo
->w2k
))) {
1486 KdPrint2((PRINT_PREFIX
"update ConfigInfo->w2k: 64bit %d\n",
1487 deviceExtension
->Host64
));
1489 // We need not set Dma64BitAddresses since we perform address translation manually.
1491 _ConfigInfo
->w2k
.Dma64BitAddresses
= deviceExtension
->Host64
;
1492 #endif //USE_OWN_DMA
1493 _ConfigInfo
->w2k
.ResetTargetSupported
= TRUE
;
1494 _ConfigInfo
->w2k
.MaximumNumberOfLogicalUnits
= (UCHAR
)deviceExtension
->NumberLuns
;
1497 // Save the Interrupe Mode for later use
1498 deviceExtension
->InterruptMode
= ConfigInfo
->InterruptMode
;
1499 deviceExtension
->BusInterruptLevel
= ConfigInfo
->BusInterruptLevel
;
1500 deviceExtension
->BusInterruptVector
= ConfigInfo
->BusInterruptVector
;
1501 deviceExtension
->Channel
= channel
;
1502 deviceExtension
->DevIndex
= i
;
1503 deviceExtension
->OrigAdapterInterfaceType
1504 = ConfigInfo
->AdapterInterfaceType
;
1505 deviceExtension
->AlignmentMask
= ConfigInfo
->AlignmentMask
;
1506 deviceExtension
->AdapterInterfaceType
= PCIBus
;
1508 KdPrint2((PRINT_PREFIX
"chan[%d] InterruptMode: %d, Level %d, Level2 %d, Vector %d, Vector2 %d\n",
1510 ConfigInfo
->InterruptMode
,
1511 ConfigInfo
->BusInterruptLevel
,
1512 ConfigInfo
->BusInterruptLevel2
,
1513 ConfigInfo
->BusInterruptVector
,
1514 ConfigInfo
->BusInterruptVector2
1519 if(deviceExtension
->BusMaster
) {
1521 KdPrint2((PRINT_PREFIX
"Reconstruct ConfigInfo\n"));
1523 ConfigInfo
->NeedPhysicalAddresses
= FALSE
;
1525 ConfigInfo
->NeedPhysicalAddresses
= TRUE
;
1526 #endif //USE_OWN_DMA
1528 //#ifdef USE_OWN_DMA
1529 // KdPrint2((PRINT_PREFIX "!MasterDev, own DMA\n"));
1531 KdPrint2((PRINT_PREFIX
"set Dma32BitAddresses\n"));
1532 ConfigInfo
->Dma32BitAddresses
= TRUE
;
1533 //#endif //USE_OWN_DMA
1536 // thanks to Vitaliy Vorobyov aka deathsoft@yandex.ru for
1540 // I'm sorry, I have to do this
1543 if(ConfigInfo
->AdapterInterfaceType
== Isa
/*&&
1544 // InDriverEntry*/) {
1545 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType Isa => PCIBus\n"));
1546 ConfigInfo
->AdapterInterfaceType
= PCIBus
;
1548 if(ConfigInfo
->AdapterInterfaceType
== PCIBus
/*&&
1549 // InDriverEntry*/) {
1550 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType PCIBus, update address\n"));
1551 ConfigInfo
->SlotNumber
= slotNumber
;
1552 ConfigInfo
->SystemIoBusNumber
= SystemIoBusNumber
;
1557 ConfigInfo
->Master
= TRUE
;
1558 ConfigInfo
->DmaWidth
= Width16Bits
;
1559 #endif //USE_OWN_DMA
1560 ConfigInfo
->ScatterGather
= TRUE
;
1562 ConfigInfo
->MapBuffers
= TRUE
; // Need for PIO and OWN_DMA
1563 ConfigInfo
->CachesData
= TRUE
;
1565 KdPrint2((PRINT_PREFIX
"BMList[i].channel %#x, NumberChannels %#x, channel %#x\n",BMList
[i
].channel
, deviceExtension
->NumberChannels
, channel
));
1567 for (; channel
< (BMList
[i
].channel
+ deviceExtension
->NumberChannels
); channel
++, c
++) {
1569 KdPrint2((PRINT_PREFIX
"de %#x, Channel %#x\n",deviceExtension
, channel
));
1570 //PrintNtConsole("de %#x, Channel %#x, nchan %#x\n",deviceExtension, channel, deviceExtension->NumberChannels);
1571 chan
= &deviceExtension
->chan
[c
];
1573 KdPrint2((PRINT_PREFIX
"chan = %#x\n", chan
));
1574 //PrintNtConsole("chan = %#x, c=%#x\n", chan, c);
1575 AtapiSetupLunPtrs(chan
, deviceExtension
, c
);
1577 /* do extra channel-specific setups */
1578 AtapiReadChipConfig(HwDeviceExtension
, i
, channel
);
1579 //AtapiChipInit(HwDeviceExtension, i, channel);
1580 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
1581 KdPrint2((PRINT_PREFIX
" No more setup for AHCI channel\n"));
1583 if(deviceExtension
->AltRegMap
) {
1584 KdPrint2((PRINT_PREFIX
" Non-standard registers layout\n"));
1586 // Check if the range specified is not used by another driver
1588 KdPrint2((PRINT_PREFIX
"set AccessRanges\n"));
1589 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 0].RangeStart
=
1590 ScsiPortConvertUlongToPhysicalAddress(channel
? IO_WD2
: IO_WD1
);
1591 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 0].RangeLength
= ATA_IOSIZE
;
1593 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 1].RangeStart
=
1594 ScsiPortConvertUlongToPhysicalAddress((channel
? IO_WD2
: IO_WD1
) + ATA_ALTOFFSET
);
1595 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 1].RangeLength
= ATA_ALTIOSIZE
;
1598 !(*ConfigInfo
->AccessRanges
)[channel
* 2 + 0].RangeStart
.QuadPart
&&
1599 !(*ConfigInfo
->AccessRanges
)[channel
* 2 + 1].RangeStart
.QuadPart
) {
1600 KdPrint2((PRINT_PREFIX
"cheat ScsiPort, sync real PCI and ConfigInfo IO ranges\n"));
1601 AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, &pciData
, SystemIoBusNumber
,
1602 channel
* 2 + 0, 0, ATA_IOSIZE
);
1603 AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, &pciData
, SystemIoBusNumber
,
1604 channel
* 2 + 1, 0, ATA_ALTIOSIZE
);
1607 IoBasePort1
= (*ConfigInfo
->AccessRanges
)[channel
* 2 + 0].RangeStart
;
1608 IoBasePort2
= (*ConfigInfo
->AccessRanges
)[channel
* 2 + 1].RangeStart
;
1611 if(!IoBasePort1
.QuadPart
|| !IoBasePort2
.QuadPart
) {
1612 KdPrint2((PRINT_PREFIX
"ScsiPortValidateRange failed (1)\n"));
1617 if(!ScsiPortValidateRange(HwDeviceExtension
,
1618 PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
1619 SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
1623 KdPrint2((PRINT_PREFIX
"ScsiPortValidateRange failed (1)\n"));
1627 if(!ScsiPortValidateRange(HwDeviceExtension
,
1628 PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
1629 SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
1633 KdPrint2((PRINT_PREFIX
"ScsiPortValidateRange failed (2)\n"));
1637 KdPrint2((PRINT_PREFIX
"Getting IO ranges\n"));
1639 // Ok, translate adresses to io-space
1640 if(ScsiPortConvertPhysicalAddressToUlong(IoBasePort2
)) {
1641 if(!(MasterDev
/* || USE_16_BIT */)) {
1642 KdPrint2((PRINT_PREFIX
"!MasterDev mode\n"));
1643 IoBasePort2
= ScsiPortConvertUlongToPhysicalAddress(
1644 ScsiPortConvertPhysicalAddressToUlong(IoBasePort2
) + 2);
1647 KdPrint2((PRINT_PREFIX
"use relative IoBasePort2\n"));
1648 IoBasePort2
= ScsiPortConvertUlongToPhysicalAddress(
1649 ScsiPortConvertPhysicalAddressToUlong(IoBasePort1
) + ATA_PCCARD_ALTOFFSET
);
1652 // Get the system physical address for this IO range.
1653 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
1654 MasterDev
? ConfigInfo
->AdapterInterfaceType
: PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
1655 MasterDev
? ConfigInfo
->SystemIoBusNumber
: SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
1659 KdPrint2((PRINT_PREFIX
"IO range 1 %#x\n",ioSpace
));
1661 // Check if ioSpace accessible.
1663 KdPrint2((PRINT_PREFIX
"!ioSpace\n"));
1667 if(deviceExtension->BusMaster) {
1668 KdPrint2((PRINT_PREFIX "set BusMaster io-range in DO\n"));
1669 // bm_offset already includes (channel ? ATA_BM_OFFSET1 : 0)
1670 deviceExtension->BaseIoAddressBM[c] = (PIDE_BUSMASTER_REGISTERS)
1671 ((ULONG)(deviceExtension->BaseIoAddressBM_0) + bm_offset + (c ? ATA_BM_OFFSET1 : 0));
1674 //deviceExtension->BaseIoAddress1[c] = (PIDE_REGISTERS_1)(ioSpace);
1675 BaseIoAddress1
[c
] = (PIDE_REGISTERS_1
)(ioSpace
);
1677 // Get the system physical address for the second IO range.
1678 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
1679 MasterDev
? ConfigInfo
->AdapterInterfaceType
: PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
1680 MasterDev
? ConfigInfo
->SystemIoBusNumber
: SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
1684 KdPrint2((PRINT_PREFIX
"IO range 2 %#x\n",ioSpace
));
1686 BaseIoAddress2
[c
] = (PIDE_REGISTERS_2
)(ioSpace
);
1688 // Release all allocated resources
1689 KdPrint2((PRINT_PREFIX
"!deviceExtension->BaseIoAddress2\n"));
1690 //ioSpace = (PUCHAR)BaseIoAddress1[c];
1691 // goto free_iospace_1;
1695 UniataInitMapBase(chan
, BaseIoAddress1
[c
], BaseIoAddress2
[c
]);
1697 //ioSpace = (PUCHAR)(deviceExtension->BaseIoAddress1[c]);
1699 DbgDumpRegTranslation(chan
, IDX_IO1
);
1700 DbgDumpRegTranslation(chan
, IDX_IO2
);
1701 DbgDumpRegTranslation(chan
, IDX_BM_IO
);
1702 DbgDumpRegTranslation(chan
, IDX_SATA_IO
);
1704 if(!(deviceExtension
->HwFlags
& UNIATA_AHCI
)) {
1706 UniataDumpATARegs(chan
);
1710 #ifdef UNIATA_INIT_ON_PROBE
1711 // if(deviceExtension->HwFlags & UNIATA_SATA) {
1712 //#endif //UNIATA_INIT_ON_PROBE
1713 KdPrint2((PRINT_PREFIX
"Check drive 0\n"));
1715 SelectDrive(chan
, 0);
1716 AtapiStallExecution(10);
1717 GetBaseStatus(chan
, statusByte
);
1718 skip_find_dev
= FALSE
;
1719 if(!(deviceExtension
->HwFlags
& UNIATA_NO_SLAVE
) && (deviceExtension
->NumberLuns
> 1)) {
1720 if ((statusByte
& 0xf8) == 0xf8 ||
1721 (statusByte
== 0xa5)) {
1723 KdPrint2((PRINT_PREFIX
"Check drive 1\n"));
1724 SelectDrive(chan
, 1);
1725 AtapiStallExecution(1);
1726 GetBaseStatus(chan
, statusByte
);
1727 if ((statusByte
& 0xf8) == 0xf8 ||
1728 (statusByte
== 0xa5)) {
1729 // No controller at this base address.
1730 KdPrint2((PRINT_PREFIX
"Empty channel\n"));
1731 skip_find_dev
= TRUE
;
1736 // Search for devices on this controller.
1737 if (!skip_find_dev
&&
1738 FindDevices(HwDeviceExtension
,
1741 KdPrint2((PRINT_PREFIX
"Found some devices\n"));
1744 KdPrint2((PRINT_PREFIX
"no devices\n"));
1745 /* KeBugCheckEx(0xc000000e,
1746 ScsiPortConvertPhysicalAddressToUlong(IoBasePort1),
1747 ScsiPortConvertPhysicalAddressToUlong(IoBasePort2),
1748 (ULONG)(deviceExtension->BaseIoAddressBM[c]), skip_find_dev);*/
1750 //#ifdef UNIATA_INIT_ON_PROBE
1752 #else //UNIATA_INIT_ON_PROBE
1753 KdPrint2((PRINT_PREFIX
"clean IDE intr 0\n"));
1755 SelectDrive(chan
, 0);
1756 AtapiStallExecution(10);
1757 GetBaseStatus(chan
, statusByte
);
1759 if(!(deviceExtension
->HwFlags
& UNIATA_NO_SLAVE
) && (deviceExtension
->NumberLuns
> 1)) {
1760 KdPrint2((PRINT_PREFIX
"clean IDE intr 1\n"));
1762 SelectDrive(chan
, 1);
1763 AtapiStallExecution(1);
1764 GetBaseStatus(chan
, statusByte
);
1766 SelectDrive(chan
, 0);
1769 statusByte
= GetDmaStatus(deviceExtension
, c
);
1770 KdPrint2((PRINT_PREFIX
" DMA status %#x\n", statusByte
));
1771 if(statusByte
& BM_STATUS_INTR
) {
1772 // bullshit, we have DMA interrupt, but had never initiate DMA operation
1773 KdPrint2((PRINT_PREFIX
" clear unexpected DMA intr\n"));
1774 AtapiDmaDone(deviceExtension
, 0, c
, NULL
);
1775 GetBaseStatus(chan
, statusByte
);
1778 #endif //UNIATA_INIT_ON_PROBE
1782 chan
->PrimaryAddress
= FALSE
;
1783 // Claim primary or secondary ATA IO range.
1785 KdPrint2((PRINT_PREFIX
"claim Compatible controller\n"));
1787 KdPrint2((PRINT_PREFIX
"claim Primary\n"));
1788 AtdiskPrimaryClaimed
=
1789 ConfigInfo
->AtdiskPrimaryClaimed
= TRUE
;
1790 chan
->PrimaryAddress
= TRUE
;
1792 FirstMasterOk
= TRUE
;
1796 KdPrint2((PRINT_PREFIX
"claim Secondary\n"));
1797 AtdiskSecondaryClaimed
=
1798 ConfigInfo
->AtdiskSecondaryClaimed
= TRUE
;
1800 FirstMasterOk
= TRUE
;
1803 if(chan
->RegTranslation
[IDX_IO1
].Addr
== IO_WD1
&&
1804 !chan
->RegTranslation
[IDX_IO1
].MemIo
) {
1805 KdPrint2((PRINT_PREFIX
"claim Primary (PCI over ISA range)\n"));
1806 AtdiskPrimaryClaimed
=
1807 ConfigInfo
->AtdiskPrimaryClaimed
= TRUE
;
1809 if(chan
->RegTranslation
[IDX_IO1
].Addr
== IO_WD2
&&
1810 !chan
->RegTranslation
[IDX_IO1
].MemIo
) {
1811 KdPrint2((PRINT_PREFIX
"claim Secondary (PCI over ISA range)\n"));
1812 AtdiskSecondaryClaimed
=
1813 ConfigInfo
->AtdiskSecondaryClaimed
= TRUE
;
1817 AtapiDmaAlloc(HwDeviceExtension
, ConfigInfo
, c
);
1821 #endif //UNIATA_CORE
1822 } // end for(channel)
1828 KdPrint2((PRINT_PREFIX
"exit: !found\n"));
1829 if(BaseIoAddress1
[0])
1830 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1832 if(BaseIoAddress2
[0])
1833 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1836 if(BaseIoAddress1
[1])
1837 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1839 if(BaseIoAddress2
[1])
1840 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1843 if(BaseIoAddressBM_0
)
1844 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1847 if(deviceExtension
->BaseIoAHCI_0
.Addr
) {
1848 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1849 deviceExtension
->BaseIoAHCI_0
.pAddr
);
1852 KdPrint2((PRINT_PREFIX
"return SP_RETURN_NOT_FOUND\n"));
1856 KdPrint2((PRINT_PREFIX
"exit: init spinlock\n"));
1857 //KeInitializeSpinLock(&(deviceExtension->DpcSpinLock));
1858 deviceExtension
->ActiveDpcChan
=
1859 deviceExtension
->FirstDpcChan
= CHAN_NOT_SPECIFIED
;
1861 BMList
[i
].Isr2Enable
= FALSE
;
1863 KdPrint2((PRINT_PREFIX
"MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n",
1864 MasterDev
, deviceExtension
->NumberChannels
, BMList
[i
].Isr2DevObj
));
1866 // ConnectIntr2 should be moved to HwInitialize
1867 status
= UniataConnectIntr2(HwDeviceExtension
);
1869 KdPrint2((PRINT_PREFIX
"MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n",
1870 MasterDev
, deviceExtension
->NumberChannels
, BMList
[i
].Isr2DevObj
));
1872 if(/*WinVer_WDM_Model &&*/ MasterDev
) {
1873 KdPrint2((PRINT_PREFIX
"do not tell system, that we know about PCI IO ranges\n"));
1874 /* if(BaseIoAddressBM_0) {
1875 ScsiPortFreeDeviceBase(HwDeviceExtension,
1878 (*ConfigInfo
->AccessRanges
)[4].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(0);
1879 (*ConfigInfo
->AccessRanges
)[4].RangeLength
= 0;
1880 (*ConfigInfo
->AccessRanges
)[5].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(0);
1881 (*ConfigInfo
->AccessRanges
)[5].RangeLength
= 0;
1884 if(!NT_SUCCESS(status
)) {
1885 KdPrint2((PRINT_PREFIX
"failed\n"));
1890 KdPrint2((PRINT_PREFIX
"final chan[%d] InterruptMode: %d, Level %d, Level2 %d, Vector %d, Vector2 %d\n",
1892 ConfigInfo
->InterruptMode
,
1893 ConfigInfo
->BusInterruptLevel
,
1894 ConfigInfo
->BusInterruptLevel2
,
1895 ConfigInfo
->BusInterruptVector
,
1896 ConfigInfo
->BusInterruptVector2
1901 #endif //UNIATA_CORE
1903 KdPrint2((PRINT_PREFIX
"return SP_RETURN_FOUND\n"));
1904 //PrintNtConsole("return SP_RETURN_FOUND, de %#x, c0.lun0 %#x\n", deviceExtension, deviceExtension->chan[0].lun[0]);
1907 KdPrint2((PRINT_PREFIX
"Attempt %d of MasterDev ok\n", AltInit
));
1908 FirstMasterOk
= TRUE
;
1911 ConfigInfo
->NumberOfBuses
++; // add virtual channel for communication port
1912 return SP_RETURN_FOUND
;
1915 UniataFreeLunExt(deviceExtension
);
1916 return SP_RETURN_ERROR
;
1919 UniataFreeLunExt(deviceExtension
);
1920 return SP_RETURN_NOT_FOUND
;
1922 } // end UniataFindBusMasterController()
1927 This is for claiming PCI Busmaster in compatible mode under WDM OSes
1931 UniataClaimLegacyPCIIDE(
1936 PCM_RESOURCE_LIST resourceList
= NULL
;
1937 UNICODE_STRING devname
;
1939 KdPrint2((PRINT_PREFIX
"UniataClaimLegacyPCIIDE:\n"));
1941 if(BMList
[i
].PciIdeDevObj
) {
1942 KdPrint2((PRINT_PREFIX
"Already initialized\n"));
1943 return STATUS_UNSUCCESSFUL
;
1946 RtlInitUnicodeString(&devname
, L
"\\Device\\uniata_PCIIDE");
1947 status
= IoCreateDevice(SavedDriverObject
, sizeof(PCIIDE_DEVICE_EXTENSION
),
1948 /*NULL*/ &devname
, FILE_DEVICE_UNKNOWN
,
1949 0, FALSE
, &(BMList
[i
].PciIdeDevObj
));
1951 if(!NT_SUCCESS(status
)) {
1952 KdPrint2((PRINT_PREFIX
"IoCreateDevice failed %#x\n", status
));
1956 resourceList
= (PCM_RESOURCE_LIST
) ExAllocatePool(PagedPool
,
1957 sizeof(CM_RESOURCE_LIST
));
1959 if (!resourceList
) {
1960 KdPrint2((PRINT_PREFIX
"!resourceList\n"));
1961 status
= STATUS_INSUFFICIENT_RESOURCES
;
1963 IoDeleteDevice(BMList
[i
].PciIdeDevObj
);
1964 BMList
[i
].PciIdeDevObj
= NULL
;
1970 sizeof(CM_RESOURCE_LIST
));
1972 // IoReportDetectedDevice() should be used for WDM OSes
1974 // TODO: check if resourceList is actually used inside HalAssignSlotResources()
1975 // Note: with empty resourceList call to HalAssignSlotResources() fails on some HW
1976 // e.g. Intel ICH4, but works with non-empty.
1978 resourceList
->Count
= 1;
1979 resourceList
->List
[0].InterfaceType
= PCIBus
;
1980 resourceList
->List
[0].BusNumber
= BMList
[i
].busNumber
;
1981 // we do not report IO ranges since they are used/claimed by ISA part(s)
1982 resourceList
->List
[0].PartialResourceList
.Count
= 0;
1984 RtlInitUnicodeString(&devname
, L
"PCIIDE");
1985 status
= HalAssignSlotResources(&SavedRegPath
,
1988 BMList
[i
].PciIdeDevObj
,
1990 BMList
[i
].busNumber
,
1991 BMList
[i
].slotNumber
,
1994 if (!NT_SUCCESS(status
)) {
1995 KdPrint2((PRINT_PREFIX
"HalAssignSlotResources failed %#x\n", status
));
1996 // this is always deallocated inside HalAssignSlotResources() implementation
1997 //ExFreePool(resourceList);
2001 KdPrint2((PRINT_PREFIX
"ok %#x\n", status
));
2002 BMList
[i
].ChanInitOk
|= 0x80;
2005 } // end UniataClaimLegacyPCIIDE()
2010 Routine Description:
2012 This function is called to initialize 2nd device object for
2013 multichannel controllers.
2017 HwDeviceExtension - HBA miniport driver's adapter data storage
2027 IN PVOID HwDeviceExtension
2030 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2031 ULONG i
= deviceExtension
->DevIndex
;
2033 PISR2_DEVICE_EXTENSION Isr2DevExt
;
2034 WCHAR devname_str
[33];
2035 UNICODE_STRING devname
;
2037 KdPrint2((PRINT_PREFIX
"Init ISR:\n"));
2039 if(!deviceExtension
->MasterDev
&& (deviceExtension
->NumberChannels
> 1) && // do not touch MasterDev
2040 !deviceExtension
->simplexOnly
&& /* // this is unnecessary on simplex controllers
2041 !BMList[i].Isr2DevObj*/ // handle re-init under w2k+
2045 KdPrint2((PRINT_PREFIX
"Multichannel native mode, go...\n"));
2046 #ifndef UNIATA_USE_XXableInterrupts
2047 // If we raise IRQL to TIMER value, other interrupt cannot occure on the same CPU
2048 /* if(KeNumberProcessors < 2) {
2049 KdPrint2((PRINT_PREFIX "Unnecessary (?), UP machine\n"));
2050 //return STATUS_SUCCESS;
2052 #endif //UNIATA_USE_XXableInterrupts
2054 KdPrint2((PRINT_PREFIX
"Unnecessary\n"));
2055 return STATUS_SUCCESS
;
2058 if(BMList
[i
].Isr2DevObj
) {
2059 KdPrint2((PRINT_PREFIX
"Already initialized [%d] %#x\n", i
, BMList
[i
].Isr2DevObj
));
2060 return STATUS_SUCCESS
;
2063 KdPrint2((PRINT_PREFIX
"Create DO\n"));
2066 _snwprintf(devname_str
, sizeof(devname_str
)/sizeof(WCHAR
)-1,
2067 L
"\\Device\\uniata%d_2ch", i
);
2068 devname_str
[devname
.Length
] = 0;
2069 devname
.Length
*= sizeof(WCHAR
);
2070 devname
.MaximumLength
= devname
.Length
;
2071 devname
.Buffer
= devname_str
;
2073 KdPrint2((PRINT_PREFIX
"DO name: len(%d, %d), %S\n", devname
.Length
, devname
.MaximumLength
, devname
.Buffer
));
2075 status
= IoCreateDevice(SavedDriverObject
, sizeof(ISR2_DEVICE_EXTENSION
),
2076 /*NULL*/ &devname
, FILE_DEVICE_UNKNOWN
,
2077 0, FALSE
, &(BMList
[i
].Isr2DevObj
));
2079 if(!NT_SUCCESS(status
)) {
2080 KdPrint2((PRINT_PREFIX
"IoCreateDevice failed %#x\n", status
));
2084 KdPrint2((PRINT_PREFIX
"HalGetInterruptVector\n"));
2085 KdPrint2((PRINT_PREFIX
" OrigAdapterInterfaceType=%d\n", deviceExtension
->OrigAdapterInterfaceType
));
2086 KdPrint2((PRINT_PREFIX
" SystemIoBusNumber=%d\n", deviceExtension
->SystemIoBusNumber
));
2087 KdPrint2((PRINT_PREFIX
" BusInterruptLevel=%d\n", deviceExtension
->BusInterruptLevel
));
2088 KdPrint2((PRINT_PREFIX
" BusInterruptVector=%d\n", deviceExtension
->BusInterruptVector
));
2089 BMList
[i
].Isr2Vector
= HalGetInterruptVector(
2090 deviceExtension
->OrigAdapterInterfaceType
,
2091 deviceExtension
->SystemIoBusNumber
,
2092 deviceExtension
->BusInterruptLevel
,
2093 deviceExtension
->BusInterruptVector
,
2094 &(BMList
[i
].Isr2Irql
),
2095 &(BMList
[i
].Isr2Affinity
));
2097 Isr2DevExt
= (PISR2_DEVICE_EXTENSION
)(BMList
[i
].Isr2DevObj
->DeviceExtension
);
2098 Isr2DevExt
->HwDeviceExtension
= deviceExtension
;
2099 Isr2DevExt
->DevIndex
= i
;
2101 KdPrint2((PRINT_PREFIX
"isr2_de %#x\n", Isr2DevExt
));
2102 KdPrint2((PRINT_PREFIX
"isr2_vector %#x\n", BMList
[i
].Isr2Vector
));
2103 KdPrint2((PRINT_PREFIX
"isr2_irql %#x\n", BMList
[i
].Isr2Irql
));
2104 KdPrint2((PRINT_PREFIX
"isr2_affinity %#x\n", BMList
[i
].Isr2Affinity
));
2106 // deviceExtension->QueueNewIrql = BMList[i].Isr2Irql;
2108 KdPrint2((PRINT_PREFIX
"IoConnectInterrupt\n"));
2109 status
= IoConnectInterrupt(
2110 &(BMList
[i
].Isr2InterruptObject
),
2114 BMList
[i
].Isr2Vector
,
2117 (KINTERRUPT_MODE
)(deviceExtension
->InterruptMode
),
2119 BMList
[i
].Isr2Affinity
,
2122 if(!NT_SUCCESS(status
)) {
2123 KdPrint2((PRINT_PREFIX
"IoConnectInterrupt failed\n"));
2124 IoDeleteDevice(BMList
[i
].Isr2DevObj
);
2125 BMList
[i
].Isr2DevObj
= NULL
;
2126 BMList
[i
].Isr2InterruptObject
= NULL
;
2130 //deviceExtension->Isr2DevObj = BMList[i].Isr2DevObj;
2133 } // end UniataConnectIntr2()
2137 UniataDisconnectIntr2(
2138 IN PVOID HwDeviceExtension
2141 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2142 ULONG i
= deviceExtension
->DevIndex
;
2145 KdPrint2((PRINT_PREFIX
"Deinit ISR:\n"));
2147 if(!BMList
[i
].Isr2DevObj
) {
2148 KdPrint2((PRINT_PREFIX
"Already uninitialized %#x\n"));
2149 return STATUS_SUCCESS
;
2152 IoDisconnectInterrupt(BMList
[i
].Isr2InterruptObject
);
2154 BMList
[i
].Isr2InterruptObject
= NULL
;
2156 IoDeleteDevice(BMList
[i
].Isr2DevObj
);
2158 BMList
[i
].Isr2DevObj
= NULL
;
2159 //deviceExtension->Isr2DevObj = NULL;
2161 return STATUS_SUCCESS
;
2162 } // end UniataDisconnectIntr2()
2164 #endif //UNIATA_CORE
2168 AtapiCheckIOInterference(
2169 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
2171 // check if Primary/Secondary Master IDE claimed
2172 if((portBase
== IO_WD1
) &&
2173 (ConfigInfo
->AtdiskPrimaryClaimed
|| AtdiskPrimaryClaimed
)) {
2174 KdPrint2((PRINT_PREFIX
"AtapiCheckIOInterference: AtdiskPrimaryClaimed\n"));
2177 if((portBase
== IO_WD2
) &&
2178 (ConfigInfo
->AtdiskSecondaryClaimed
|| AtdiskSecondaryClaimed
)) {
2179 KdPrint2((PRINT_PREFIX
"AtapiCheckIOInterference: AtdiskSecondaryClaimed\n"));
2183 } // end AtapiCheckIOInterference()
2187 Routine Description:
2189 This function is called by the OS-specific port driver after
2190 the necessary storage has been allocated, to gather information
2191 about the adapter's configuration.
2195 HwDeviceExtension - HBA miniport driver's adapter data storage
2196 Context - Address of adapter count
2197 ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility.
2198 ConfigInfo - Configuration information structure describing HBA
2199 Again - Indicates search for adapters to continue
2208 AtapiFindIsaController(
2209 IN PVOID HwDeviceExtension
,
2211 IN PVOID BusInformation
,
2212 IN PCHAR ArgumentString
,
2213 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
2217 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2219 PULONG adapterCount
= (PULONG
)Context
;
2220 PUCHAR ioSpace
= NULL
;
2225 // BOOLEAN atapiOnly;
2226 UCHAR statusByte
, statusByte2
;
2227 BOOLEAN preConfig
= FALSE
;
2229 PIDE_REGISTERS_1 BaseIoAddress1
;
2230 PIDE_REGISTERS_2 BaseIoAddress2
= NULL
;
2232 // The following table specifies the ports to be checked when searching for
2233 // an IDE controller. A zero entry terminates the search.
2234 static CONST ULONG AdapterAddresses
[5] = {IO_WD1
, IO_WD2
, IO_WD1
-8, IO_WD2
-8, 0};
2235 // CONST UCHAR Channels[5] = {0, 1, 0, 1, 0};
2237 // The following table specifies interrupt levels corresponding to the
2238 // port addresses in the previous table.
2239 static CONST ULONG InterruptLevels
[5] = {14, 15, 11, 10, 0};
2241 KdPrint2((PRINT_PREFIX
"AtapiFindIsaController (ISA):\n"));
2243 if (!deviceExtension
) {
2244 return SP_RETURN_ERROR
;
2246 RtlZeroMemory(deviceExtension
, sizeof(HW_DEVICE_EXTENSION
));
2248 KdPrint2((PRINT_PREFIX
" assume max PIO4\n"));
2249 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
2250 deviceExtension
->NumberChannels
= 1;
2251 deviceExtension
->NumberLuns
= IDE_MAX_LUN_PER_CHAN
; // default
2253 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
2257 chan
= &(deviceExtension
->chan
[0]);
2258 AtapiSetupLunPtrs(chan
, deviceExtension
, 0);
2260 deviceExtension
->AdapterInterfaceType
=
2261 deviceExtension
->OrigAdapterInterfaceType
2262 = ConfigInfo
->AdapterInterfaceType
;
2266 /* do extra chipset specific setups */
2267 AtapiReadChipConfig(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, CHAN_NOT_SPECIFIED
);
2268 AtapiChipInit(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, CHAN_NOT_SPECIFIED
);
2270 // Check to see if this is a special configuration environment.
2272 if (ArgumentString
) {
2274 irq
= AtapiParseArgumentString(ArgumentString
, "Interrupt");
2277 // Both parameters must be present to proceed
2278 portBase
= AtapiParseArgumentString(ArgumentString
, "BaseAddress");
2281 // Try a default search for the part.
2287 #endif //UNIATA_CORE
2289 for(i=0; i<2; i++) {
2290 if((*ConfigInfo->AccessRanges)[i].RangeStart) {
2291 KdPrint2((PRINT_PREFIX " IoRange[%d], start %#x, len %#x, mem %#x\n",
2293 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[i].RangeStart),
2294 (*ConfigInfo->AccessRanges)[i].RangeLength,
2295 (*ConfigInfo->AccessRanges)[i].RangeInMemory
2300 // if((*ConfigInfo->AccessRanges)[0].RangeStart) {
2301 portBase
= ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[0].RangeStart
);
2304 if(!AtapiCheckIOInterference(ConfigInfo
, portBase
)) {
2305 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2306 ConfigInfo
->AdapterInterfaceType
,
2307 ConfigInfo
->SystemIoBusNumber
,
2308 (*ConfigInfo
->AccessRanges
)[0].RangeStart
,
2309 (*ConfigInfo
->AccessRanges
)[0].RangeLength
,
2310 (BOOLEAN
) !((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
));
2312 // do not touch resources, just fail later inside loop on next call to
2313 // AtapiCheckIOInterference()
2316 // Since we have pre-configured information we only need to go through this loop once
2318 KdPrint2((PRINT_PREFIX
" preconfig, portBase=%x, len=%x\n", portBase
, (*ConfigInfo
->AccessRanges
)[0].RangeLength
));
2321 // Scan through the adapter address looking for adapters.
2323 while (AdapterAddresses
[*adapterCount
] != 0) {
2326 #endif //UNIATA_CORE
2329 deviceExtension
->DevIndex
= (*adapterCount
); // this is used inside AtapiRegCheckDevValue()
2330 KdPrint2((PRINT_PREFIX
"AtapiFindIsaController: adapterCount=%d\n", *adapterCount
));
2332 for (i
= 0; i
< deviceExtension
->NumberLuns
; i
++) {
2333 // Zero device fields to ensure that if earlier devices were found,
2334 // but not claimed, the fields are cleared.
2335 deviceExtension
->lun
[i
].DeviceFlags
&= ~(DFLAGS_ATAPI_DEVICE
| DFLAGS_DEVICE_PRESENT
| DFLAGS_TAPE_DEVICE
);
2337 // Get the system physical address for this IO range.
2339 // Check if configInfo has the default information
2340 // if not, we go and find ourselves
2341 if (preConfig
== FALSE
) {
2344 portBase
= AdapterAddresses
[*adapterCount
];
2345 KdPrint2((PRINT_PREFIX
"portBase[%d]=%x\n", *adapterCount
, portBase
));
2347 KdPrint2((PRINT_PREFIX
"portBase=%x\n", portBase
));
2349 portBase
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"PortBase", portBase
);
2350 irq
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"Irq", irq
);
2351 // check if Primary/Secondary Master IDE claimed
2352 if(AtapiCheckIOInterference(ConfigInfo
, portBase
)) {
2355 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2356 ConfigInfo
->AdapterInterfaceType
,
2357 ConfigInfo
->SystemIoBusNumber
,
2358 ScsiPortConvertUlongToPhysicalAddress(portBase
),
2363 KdPrint2((PRINT_PREFIX
"preconfig portBase=%x\n", portBase
));
2364 // Check if Primary/Secondary Master IDE claimed
2365 // We can also get here from preConfig branc with conflicting portBase
2366 // (and thus, w/o ioSpace allocated)
2367 if(AtapiCheckIOInterference(ConfigInfo
, portBase
)) {
2371 BaseIoAddress1
= (PIDE_REGISTERS_1
)ioSpace
;
2373 // Update the adapter count.
2376 // Check if ioSpace accessible.
2378 KdPrint2((PRINT_PREFIX
"AtapiFindIsaController: !ioSpace\n"));
2383 // Get the system physical address for the second IO range.
2384 if (BaseIoAddress1
) {
2386 !ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[1].RangeStart
)) {
2387 KdPrint2((PRINT_PREFIX
"AtapiFindIsaController: PCMCIA ?\n"));
2388 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2389 ConfigInfo
->AdapterInterfaceType
,
2390 ConfigInfo
->SystemIoBusNumber
,
2391 ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR
)BaseIoAddress1
+ 0x0E),
2395 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2396 ConfigInfo
->AdapterInterfaceType
,
2397 ConfigInfo
->SystemIoBusNumber
,
2398 ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR
)BaseIoAddress1
+ ATA_ALTOFFSET
),
2403 BaseIoAddress2
= (PIDE_REGISTERS_2
)ioSpace
;
2404 KdPrint2((PRINT_PREFIX
" BaseIoAddress1=%x\n", BaseIoAddress1
));
2405 KdPrint2((PRINT_PREFIX
" BaseIoAddress2=%x\n", BaseIoAddress2
));
2407 KdPrint2((PRINT_PREFIX
" expected InterruptLevel=%x\n", InterruptLevels
[*adapterCount
- 1]));
2410 UniataInitMapBase(chan
, BaseIoAddress1
, BaseIoAddress2
);
2411 UniataInitMapBM(deviceExtension
, 0, FALSE
);
2414 UniataDumpATARegs(chan
);
2418 SelectDrive(chan
, 0);
2420 statusByte
= AtapiReadPort1(chan
, IDX_IO1_i_Status
);
2421 statusByte2
= AtapiReadPort1(chan
, IDX_IO2_AltStatus
);
2422 if((statusByte
^ statusByte2
) & ~IDE_STATUS_INDEX
) {
2423 KdPrint2((PRINT_PREFIX
"AtapiFindIsaController: Status %x vs AltStatus %x missmatch, abort init ?\n", statusByte
, statusByte2
));
2425 if(BaseIoAddress2
) {
2426 ScsiPortFreeDeviceBase(HwDeviceExtension
,
2427 (PCHAR
)BaseIoAddress2
);
2428 BaseIoAddress2
= NULL
;
2430 BaseIoAddress2
= (PIDE_REGISTERS_2
)((ULONGIO_PTR
)BaseIoAddress1
+ 0x0E);
2431 KdPrint2((PRINT_PREFIX
" try BaseIoAddress2=%x\n", BaseIoAddress2
));
2432 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2433 ConfigInfo
->AdapterInterfaceType
,
2434 ConfigInfo
->SystemIoBusNumber
,
2435 ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR
)BaseIoAddress2
),
2439 BaseIoAddress2
= NULL
;
2440 KdPrint2((PRINT_PREFIX
" abort (0)\n"));
2443 UniataInitMapBase(chan
, BaseIoAddress1
, BaseIoAddress2
);
2444 statusByte
= AtapiReadPort1(chan
, IDX_IO1_i_Status
);
2445 statusByte2
= AtapiReadPort1(chan
, IDX_IO2_AltStatus
);
2446 if((statusByte
^ statusByte2
) & ~IDE_STATUS_INDEX
) {
2447 KdPrint2((PRINT_PREFIX
" abort: Status %x vs AltStatus %x missmatch\n", statusByte
, statusByte2
));
2455 SelectDrive(chan
, 0);
2457 // Check if card at this address.
2458 AtapiWritePort1(chan
, IDX_IO1_o_CylinderLow
, 0xAA);
2459 statusByte
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
);
2461 // Check if indentifier can be read back.
2462 if (AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
) != 0xAA ||
2463 statusByte
== IDE_STATUS_WRONG
) {
2465 KdPrint2((PRINT_PREFIX
"AtapiFindIsaController: Identifier read back from Master (%#x)\n",
2468 statusByte
= AtapiReadPort1(chan
, IDX_IO2_AltStatus
);
2470 if (statusByte
!= IDE_STATUS_WRONG
&& (statusByte
& IDE_STATUS_BUSY
)) {
2474 // Could be the TEAC in a thinkpad. Their dos driver puts it in a sleep-mode that
2475 // warm boots don't clear.
2477 AtapiStallExecution(1000);
2478 statusByte
= AtapiReadPort1(chan
, IDX_ATAPI_IO1_i_Status
);
2479 KdPrint2((PRINT_PREFIX
2480 "AtapiFindIsaController: First access to status %#x\n",
2482 } while ((statusByte
& IDE_STATUS_BUSY
) && ++i
< 10);
2484 if (retryCount
-- && (!(statusByte
& IDE_STATUS_BUSY
))) {
2485 goto retryIdentifier
;
2490 SelectDrive(chan
, 1);
2491 statusByte
= AtapiReadPort1(chan
, IDX_IO2_AltStatus
);
2493 // See if slave is present.
2494 AtapiWritePort1(chan
, IDX_IO1_o_CylinderLow
, 0xAA);
2496 if (AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
) != 0xAA ||
2497 statusByte
== IDE_STATUS_WRONG
) {
2499 KdPrint2((PRINT_PREFIX
2500 "AtapiFindIsaController: Identifier read back from Slave (%#x)\n",
2506 // Fill in the access array information only if default params are not in there.
2507 if (preConfig
== FALSE
) {
2509 // An adapter has been found request another call, only if we didn't get preconfigured info.
2513 (*ConfigInfo
->AccessRanges
)[0].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(portBase
);
2515 (*ConfigInfo
->AccessRanges
)[0].RangeStart
=
2516 ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses
[*adapterCount
- 1]);
2519 (*ConfigInfo
->AccessRanges
)[0].RangeLength
= ATA_IOSIZE
;
2520 (*ConfigInfo
->AccessRanges
)[0].RangeInMemory
= FALSE
;
2522 if(BaseIoAddress2
) {
2524 (*ConfigInfo
->AccessRanges
)[1].RangeStart
= ScsiPortConvertUlongToPhysicalAddress((ULONG
)BaseIoAddress2
);
2525 (*ConfigInfo
->AccessRanges
)[1].RangeLength
= ATA_ALTIOSIZE
;
2526 (*ConfigInfo
->AccessRanges
)[1].RangeInMemory
= FALSE
;
2528 // NT4 and NT3.51 on ISA-only hardware definitly fail floppy.sys load
2529 // when this range is claimed by other driver.
2530 // However, floppy should use only 0x3f0-3f5,3f7
2531 if((ULONG
)BaseIoAddress2
>= 0x3f0 && (ULONG
)BaseIoAddress2
<= 0x3f7) {
2532 KdPrint2((PRINT_PREFIX
"!!! Possible AltStatus vs Floppy IO range interference !!!\n"));
2534 KdPrint2((PRINT_PREFIX
"Do not expose to OS on old ISA\n"));
2535 (*ConfigInfo
->AccessRanges
)[1].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(0);
2536 (*ConfigInfo
->AccessRanges
)[1].RangeLength
= 0;
2540 // Indicate the interrupt level corresponding to this IO range.
2542 ConfigInfo
->BusInterruptLevel
= irq
;
2544 ConfigInfo
->BusInterruptLevel
= InterruptLevels
[*adapterCount
- 1];
2547 if (ConfigInfo
->AdapterInterfaceType
== MicroChannel
) {
2548 ConfigInfo
->InterruptMode
= LevelSensitive
;
2550 ConfigInfo
->InterruptMode
= Latched
;
2554 ConfigInfo
->NumberOfBuses
= 1;
2555 ConfigInfo
->MaximumNumberOfTargets
= IDE_MAX_LUN_PER_CHAN
;
2557 // Indicate maximum transfer length is 64k.
2558 ConfigInfo
->MaximumTransferLength
= 0x10000;
2559 deviceExtension
->MaximumDmaTransferLength
= ConfigInfo
->MaximumTransferLength
;
2561 KdPrint2((PRINT_PREFIX
"de %#x, Channel ???\n", deviceExtension
));
2562 //PrintNtConsole("de %#x, Channel %#x, nchan %#x\n",deviceExtension, channel, deviceExtension->NumberChannels);
2564 KdPrint2((PRINT_PREFIX
"chan = %#x\n", chan
));
2565 //PrintNtConsole("chan = %#x, c=%#x\n", chan, c);
2567 // should be already set up in AtapiSetupLunPtrs(chan, deviceExtension, 0);
2569 chan->DeviceExtension = deviceExtension;
2571 chan->lun[0] = &(deviceExtension->lun[0]);
2572 chan->lun[1] = &(deviceExtension->lun[1]);*/
2574 /* do extra channel-specific setups */
2575 AtapiReadChipConfig(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, 0);
2576 AtapiChipInit(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, 0);
2578 KdPrint2((PRINT_PREFIX
2579 "AtapiFindIsaController: Found IDE at %#x\n",
2582 // For Daytona, the atdisk driver gets the first shot at the
2583 // primary and secondary controllers.
2584 if (preConfig
== FALSE
) {
2586 if (*adapterCount
- 1 < 2) {
2588 // Determine whether this driver is being initialized by the
2589 // system or as a crash dump driver.
2590 if (ArgumentString
) {
2593 if (AtapiParseArgumentString(ArgumentString
, "dump") == 1) {
2594 KdPrint2((PRINT_PREFIX
2595 "AtapiFindIsaController: Crash dump\n"));
2596 //atapiOnly = FALSE;
2597 deviceExtension
->DriverMustPoll
= TRUE
;
2599 KdPrint2((PRINT_PREFIX
2600 "AtapiFindIsaController: Atapi Only\n"));
2602 deviceExtension
->DriverMustPoll
= FALSE
;
2604 #endif //UNIATA_CORE
2607 KdPrint2((PRINT_PREFIX
2608 "AtapiFindIsaController: Atapi Only (2)\n"));
2610 deviceExtension
->DriverMustPoll
= FALSE
;
2614 //atapiOnly = FALSE;
2619 //atapiOnly = FALSE;
2620 deviceExtension
->DriverMustPoll
= FALSE
;
2624 // Save the Interrupe Mode for later use
2625 deviceExtension
->InterruptMode
= ConfigInfo
->InterruptMode
;
2626 deviceExtension
->BusInterruptLevel
= ConfigInfo
->BusInterruptLevel
;
2627 deviceExtension
->BusInterruptVector
= ConfigInfo
->BusInterruptVector
;
2629 KdPrint2((PRINT_PREFIX
2630 "AtapiFindIsaController: look for devices\n"));
2631 // Search for devices on this controller.
2632 if (FindDevices(HwDeviceExtension
,
2636 KdPrint2((PRINT_PREFIX
2637 "AtapiFindIsaController: detected\n"));
2638 // Claim primary or secondary ATA IO range.
2642 ConfigInfo
->AtdiskSecondaryClaimed
= TRUE
;
2643 chan
->PrimaryAddress
= FALSE
;
2646 ConfigInfo
->AtdiskPrimaryClaimed
= TRUE
;
2647 chan
->PrimaryAddress
= TRUE
;
2653 if (*adapterCount
== 1) {
2654 ConfigInfo
->AtdiskPrimaryClaimed
= TRUE
;
2655 chan
->PrimaryAddress
= TRUE
;
2656 } else if (*adapterCount
== 2) {
2657 ConfigInfo
->AtdiskSecondaryClaimed
= TRUE
;
2658 chan
->PrimaryAddress
= FALSE
;
2662 if(deviceExtension
->AdapterInterfaceType
== Isa
) {
2665 if(deviceExtension
->AdapterInterfaceType
== MicroChannel
) {
2669 ConfigInfo
->NumberOfBuses
++; // add virtual channel for communication port
2670 KdPrint2((PRINT_PREFIX
2671 "AtapiFindIsaController: return SP_RETURN_FOUND\n"));
2672 return(SP_RETURN_FOUND
);
2675 // No controller at this base address.
2676 if(BaseIoAddress1
) {
2677 ScsiPortFreeDeviceBase(HwDeviceExtension
,
2678 (PCHAR
)BaseIoAddress1
);
2679 BaseIoAddress1
= NULL
;
2681 if(BaseIoAddress2
) {
2682 ScsiPortFreeDeviceBase(HwDeviceExtension
,
2683 (PCHAR
)BaseIoAddress2
);
2684 BaseIoAddress2
= NULL
;
2686 for(i
=0; i
<2; i
++) {
2687 KdPrint2((PRINT_PREFIX
2688 "AtapiFindIsaController: cleanup AccessRanges %d\n", i
));
2689 (*ConfigInfo
->AccessRanges
)[i
].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(0);
2690 (*ConfigInfo
->AccessRanges
)[i
].RangeLength
= 0;
2691 (*ConfigInfo
->AccessRanges
)[i
].RangeInMemory
= FALSE
;
2698 #endif //UNIATA_CORE
2700 // The entire table has been searched and no adapters have been found.
2701 // There is no need to call again and the device base can now be freed.
2702 // Clear the adapter count for the next bus.
2704 *(adapterCount
) = 0;
2706 KdPrint2((PRINT_PREFIX
2707 "AtapiFindIsaController: return SP_RETURN_NOT_FOUND\n"));
2708 UniataFreeLunExt(deviceExtension
);
2709 return(SP_RETURN_NOT_FOUND
);
2712 UniataFreeLunExt(deviceExtension
);
2713 return SP_RETURN_ERROR
;
2715 } // end AtapiFindIsaController()
2720 IN PVOID HwDeviceExtension
,
2722 IN ULONG deviceNumber
2725 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2726 PHW_CHANNEL chan
= &(deviceExtension
->chan
[lChannel
]);
2727 //ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0);
2728 PHW_LU_EXTENSION LunExt
= chan
->lun
[deviceNumber
];
2730 SATA_SSTATUS_REG SStatus
;
2732 UCHAR signatureHigh
;
2734 if(LunExt
->DeviceFlags
& DFLAGS_HIDDEN
) {
2735 KdPrint2((PRINT_PREFIX
" hidden\n"));
2736 UniataForgetDevice(LunExt
);
2737 return ATA_AT_HOME_NOBODY
;
2739 if(UniataIsSATARangeAvailable(deviceExtension
, lChannel
)) {
2741 SStatus
.Reg
= UniataSataReadPort4(chan
, IDX_SATA_SStatus
, deviceNumber
);
2742 KdPrint2((PRINT_PREFIX
"SStatus %x\n", SStatus
.Reg
));
2743 if(SStatus
.DET
<= SStatus_DET_Dev_NoPhy
) {
2744 KdPrint2((PRINT_PREFIX
" SATA DET <= SStatus_DET_Dev_NoPhy\n"));
2745 return ATA_AT_HOME_NOBODY
;
2747 if(SStatus
.SPD
< SStatus_SPD_Gen1
) {
2748 KdPrint2((PRINT_PREFIX
" SATA SPD < SStatus_SPD_Gen1\n"));
2749 return ATA_AT_HOME_NOBODY
;
2751 if(SStatus
.IPM
== SStatus_IPM_NoDev
) {
2752 KdPrint2((PRINT_PREFIX
" SATA IPN == SStatus_IPM_NoDev\n"));
2753 return ATA_AT_HOME_NOBODY
;
2755 if(!(deviceExtension
->HwFlags
& UNIATA_AHCI
)) {
2756 // Select the device for legacy.
2762 // Select the device.
2763 SelectDrive(chan
, deviceNumber
);
2764 AtapiStallExecution(5);
2767 if((deviceExtension
->HwFlags
& UNIATA_AHCI
) &&
2768 UniataIsSATARangeAvailable(deviceExtension
, lChannel
)) {
2769 KdPrint2((PRINT_PREFIX
" AHCI check\n"));
2770 ULONG SIG
= UniataAhciReadChannelPort4(chan
, IDX_AHCI_P_SIG
);
2771 signatureLow
= (UCHAR
)(SIG
>> 16);
2772 signatureHigh
= (UCHAR
)(SIG
>> 24);
2774 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
);
2775 signatureHigh
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderHigh
);
2778 if (signatureLow
== ATAPI_MAGIC_LSB
&& signatureHigh
== ATAPI_MAGIC_MSB
) {
2779 KdPrint2((PRINT_PREFIX
" ATAPI at home\n"));
2780 return ATA_AT_HOME_ATAPI
;
2782 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
2783 KdPrint2((PRINT_PREFIX
" AHCI HDD at home\n"));
2784 return ATA_AT_HOME_HDD
;
2786 if(g_opt_VirtualMachine
> VM_NONE
/*== VM_BOCHS ||
2787 g_opt_VirtualMachine == VM_VBOX*/) {
2788 GetStatus(chan
, signatureLow
);
2790 KdPrint2((PRINT_PREFIX
" 0-status VM - not present\n"));
2791 UniataForgetDevice(LunExt
);
2792 return ATA_AT_HOME_NOBODY
;
2796 AtapiStallExecution(10);
2798 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0x55);
2799 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0x55);
2800 AtapiStallExecution(5);
2801 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_BlockNumber
);
2802 if(signatureLow
!= 0x55) {
2803 if(signatureLow
== 0xff || signatureLow
== 0) {
2804 KdPrint2((PRINT_PREFIX
" nobody home! %#x != 0x55\n", signatureLow
));
2805 UniataForgetDevice(LunExt
);
2806 return ATA_AT_HOME_NOBODY
;
2809 signatureLow
= AtapiReadPort1(chan
, IDX_ATAPI_IO1_o_ByteCountHigh
);
2811 AtapiWritePort1(chan
, IDX_ATAPI_IO1_o_ByteCountHigh
, signatureLow
);
2812 AtapiStallExecution(5);
2813 signatureHigh
= AtapiReadPort1(chan
, IDX_ATAPI_IO1_o_ByteCountHigh
);
2814 if(signatureLow
!= signatureHigh
) {
2815 KdPrint2((PRINT_PREFIX
" nobody home! last chance failed %#x != %#x\n", signatureLow
, signatureHigh
));
2816 UniataForgetDevice(LunExt
);
2817 return ATA_AT_HOME_NOBODY
;
2819 return ATA_AT_HOME_XXX
;
2822 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0xAA);
2823 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0xAA);
2824 AtapiStallExecution(5);
2825 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_BlockNumber
);
2826 if(signatureLow
!= 0xAA) {
2827 KdPrint2((PRINT_PREFIX
" nobody home! %#x != 0xAA\n", signatureLow
));
2828 UniataForgetDevice(LunExt
);
2829 return ATA_AT_HOME_NOBODY
;
2832 KdPrint2((PRINT_PREFIX
" HDD at home\n"));
2833 return ATA_AT_HOME_HDD
;
2834 } // end UniataAnybodyHome()
2839 IN PVOID HwDeviceExtension
,
2841 IN ULONG deviceNumber
,
2845 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2846 PHW_CHANNEL chan
= &(deviceExtension
->chan
[lChannel
]);
2847 //ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0);
2848 PHW_LU_EXTENSION LunExt
;
2854 ULONG waitCount
= g_opt_WaitBusyResetCount
;
2857 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x\n",
2860 if(deviceNumber
>= chan
->NumberLuns
) {
2863 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
2864 if(!(at_home
= UniataAnybodyHome(HwDeviceExtension
, lChannel
, deviceNumber
))) {
2868 LunExt
= chan
->lun
[deviceNumber
];
2871 LunExt
->PowerState
= 0;
2874 if((deviceExtension
->HwFlags
& UNIATA_SATA
) &&
2875 !UniataIsSATARangeAvailable(deviceExtension
, lChannel
) &&
2877 KdPrint2((PRINT_PREFIX
" SATA w/o i/o registers, check slave presence\n"));
2878 SelectDrive(chan
, deviceNumber
& 0x01);
2879 statusByte
= AtapiReadPort1(chan
, IDX_ATAPI_IO1_i_DriveSelect
);
2880 KdPrint2((PRINT_PREFIX
" DriveSelect: %#x\n", statusByte
));
2881 if((statusByte
& IDE_DRIVE_MASK
) != IDE_DRIVE_SELECT_2
) {
2882 KdPrint2((PRINT_PREFIX
"CheckDevice: (no dev)\n"));
2883 UniataForgetDevice(LunExt
);
2888 if(ResetDev
&& (deviceExtension
->HwFlags
& UNIATA_AHCI
)) {
2889 KdPrint2((PRINT_PREFIX
"CheckDevice: reset AHCI dev\n"));
2890 if(UniataAhciSoftReset(HwDeviceExtension
, chan
->lChannel
, deviceNumber
) == (ULONG
)(-1)) {
2891 KdPrint2((PRINT_PREFIX
"CheckDevice: (no dev)\n"));
2892 UniataForgetDevice(LunExt
);
2897 KdPrint2((PRINT_PREFIX
"CheckDevice: reset dev\n"));
2900 AtapiSoftReset(chan
, deviceNumber
);
2902 if(!(at_home
= UniataAnybodyHome(HwDeviceExtension
, lChannel
, deviceNumber
))) {
2903 //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 1\n"));
2906 statusByte
= WaitOnBusy(chan
);
2908 if((statusByte
| IDE_STATUS_BUSY
) == IDE_STATUS_WRONG
) {
2909 KdPrint2((PRINT_PREFIX
2910 "CheckDevice: bad status %x\n", statusByte
));
2912 if(statusByte
!= IDE_STATUS_WRONG
&& (statusByte
& IDE_STATUS_BUSY
)) {
2913 // Perform hard-reset.
2914 KdPrint2((PRINT_PREFIX
2915 "CheckDevice: BUSY\n"));
2917 AtapiHardReset(chan
, FALSE
, 500 * 1000);
2919 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER );
2920 chan->last_devsel = -1;
2921 AtapiStallExecution(500 * 1000);
2922 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER);
2924 SelectDrive(chan
, deviceNumber
& 0x01);
2927 // Wait for Busy to drop.
2928 AtapiStallExecution(100);
2929 GetStatus(chan
, statusByte
);
2931 } while ((statusByte
& IDE_STATUS_BUSY
) && waitCount
--);
2933 GetBaseStatus(chan
, statusByte
);
2934 KdPrint2((PRINT_PREFIX
2935 "CheckDevice: status after hard reset %x\n", statusByte
));
2938 if((statusByte
| IDE_STATUS_BUSY
) == IDE_STATUS_WRONG
) {
2939 KdPrint2((PRINT_PREFIX
2940 "CheckDevice: no dev ?\n"));
2941 UniataForgetDevice(LunExt
);
2944 if(UniataIsSATARangeAvailable(deviceExtension
, lChannel
)) {
2945 //if(deviceExtension->HwFlags & UNIATA_SATA) {
2946 KdPrint2((PRINT_PREFIX
2947 "CheckDevice: try enable SATA Phy\n"));
2948 statusByte
= UniataSataPhyEnable(HwDeviceExtension
, lChannel
, deviceNumber
);
2949 if(statusByte
== IDE_STATUS_WRONG
) {
2950 KdPrint2((PRINT_PREFIX
"CheckDevice: status %#x (no dev)\n", statusByte
));
2951 UniataForgetDevice(LunExt
);
2957 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
2958 RetVal
= LunExt
->DeviceFlags
;
2959 signatureLow
= signatureHigh
= 0; // make GCC happy
2961 // Select the device.
2962 SelectDrive(chan
, deviceNumber
);
2964 if(!(at_home
= UniataAnybodyHome(HwDeviceExtension
, lChannel
, deviceNumber
))) {
2965 //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 2\n"));
2969 statusByte
= WaitOnBaseBusyLong(chan
);
2971 GetBaseStatus(chan
, statusByte
);
2972 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
2973 UniataSataClearErr(HwDeviceExtension
, lChannel
, UNIATA_SATA_IGNORE_CONNECT
, deviceNumber
);
2976 KdPrint2((PRINT_PREFIX
"CheckDevice: status %#x\n", statusByte
));
2977 if(((statusByte
| IDE_STATUS_BUSY
) == IDE_STATUS_WRONG
) ||
2978 (statusByte
& IDE_STATUS_BUSY
)) {
2979 KdPrint2((PRINT_PREFIX
"CheckDevice: busy => return\n"));
2980 UniataForgetDevice(LunExt
);
2984 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
);
2985 signatureHigh
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderHigh
);
2988 // set default costs
2989 LunExt
->RwSwitchCost
= REORDER_COST_SWITCH_RW_HDD
;
2990 LunExt
->RwSwitchMCost
= REORDER_MCOST_SWITCH_RW_HDD
;
2991 LunExt
->SeekBackMCost
= REORDER_MCOST_SEEK_BACK_HDD
;
2992 LunExt
->AtapiReadyWaitDelay
= 0;
2994 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
2995 if(RetVal
& DFLAGS_DEVICE_PRESENT
) {
2996 if(IssueIdentify(HwDeviceExtension
,
2999 (RetVal
& DFLAGS_ATAPI_DEVICE
) ? IDE_COMMAND_ATAPI_IDENTIFY
: IDE_COMMAND_IDENTIFY
,
3002 KdPrint2((PRINT_PREFIX
"CheckDevice: detected AHCI Device %#x\n",
3005 //RetVal &= ~DFLAGS_ATAPI_DEVICE;
3006 //LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE;
3008 UniataForgetDevice(LunExt
);
3013 if (signatureLow
== ATAPI_MAGIC_LSB
&& signatureHigh
== ATAPI_MAGIC_MSB
) {
3015 KdPrint2((PRINT_PREFIX
"CheckDevice: ATAPI signature found\n"));
3016 // ATAPI signature found.
3017 // Issue the ATAPI identify command if this
3018 // is not for the crash dump utility.
3020 if (!deviceExtension
->DriverMustPoll
) {
3022 // Issue ATAPI packet identify command.
3023 if (IssueIdentify(HwDeviceExtension
,
3026 IDE_COMMAND_ATAPI_IDENTIFY
, FALSE
)) {
3028 // Indicate ATAPI device.
3029 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x is ATAPI\n",
3032 RetVal
= DFLAGS_DEVICE_PRESENT
| DFLAGS_ATAPI_DEVICE
;
3033 LunExt
->DeviceFlags
|= (DFLAGS_DEVICE_PRESENT
| DFLAGS_ATAPI_DEVICE
);
3035 // some ATAPI devices doesn't work with DPC on CMD-649
3036 // and probably some other controllers
3037 if(deviceExtension
->HwFlags
& UNIATA_NO_DPC_ATAPI
) {
3038 /* CMD 649, ROSB SWK33, ICH4 */
3039 KdPrint2((PRINT_PREFIX
"CheckDevice: UNIATA_NO_DPC_ATAPI\n"));
3040 deviceExtension
->UseDpc
= FALSE
;
3043 GetStatus(chan
, statusByte
);
3044 if (statusByte
& IDE_STATUS_ERROR
) {
3045 AtapiSoftReset(chan
, deviceNumber
);
3050 // Indicate no working device.
3051 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x not responding\n",
3054 UniataForgetDevice(LunExt
);
3057 GetBaseStatus(chan
, statusByte
);
3063 KdPrint2((PRINT_PREFIX
"CheckDevice: IDE device check\n"));
3064 // Issue IDE Identify. If an Atapi device is actually present, the signature
3065 // will be asserted, and the drive will be recognized as such.
3066 if(deviceExtension
->DWordIO
) {
3067 KdPrint2((PRINT_PREFIX
" try 32bit IO\n"));
3068 LunExt
->DeviceFlags
|= DFLAGS_DWORDIO_ENABLED
;
3070 if (IssueIdentify(HwDeviceExtension
,
3073 IDE_COMMAND_IDENTIFY
, FALSE
)) {
3076 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x is IDE\n",
3079 // Indicate IDE - not ATAPI device.
3080 RetVal
= DFLAGS_DEVICE_PRESENT
;
3081 LunExt
->DeviceFlags
|= DFLAGS_DEVICE_PRESENT
;
3082 LunExt
->DeviceFlags
&= ~DFLAGS_ATAPI_DEVICE
;
3084 if(g_opt_VirtualMachine
<= VM_NONE
) {
3085 // This can be ATAPI on broken hardware
3086 GetBaseStatus(chan
, statusByte
);
3087 if(!at_home
&& UniataAnybodyHome(HwDeviceExtension
, lChannel
, deviceNumber
)) {
3088 KdPrint2((PRINT_PREFIX
"CheckDevice: nobody at home post IDE\n"));
3091 KdPrint2((PRINT_PREFIX
"CheckDevice: try ATAPI %#x, status %#x\n",
3092 deviceNumber
, statusByte
));
3095 KdPrint2((PRINT_PREFIX
"CheckDevice: VM Device %#x not present\n",
3098 GetBaseStatus(chan
, statusByte
);
3100 KdPrint2((PRINT_PREFIX
"CheckDevice: check status: %sfound\n", RetVal
? "" : "not "));
3102 } // end CheckDevice()
3107 Routine Description:
3109 This routine is called from AtapiFindXxxController to identify
3110 devices attached to an IDE controller.
3114 HwDeviceExtension - HBA miniport driver's adapter data storage
3115 AtapiOnly - Indicates that routine should return TRUE only if
3116 an ATAPI device is attached to the controller.
3120 TRUE - True if devices found.
3126 IN PVOID HwDeviceExtension
,
3131 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
3132 PHW_CHANNEL chan
= &(deviceExtension
->chan
[Channel
]);
3133 PHW_LU_EXTENSION LunExt
;
3134 BOOLEAN deviceResponded
= FALSE
,
3135 skipSetParameters
= FALSE
;
3136 ULONG waitCount
= 10000;
3137 //ULONG deviceNumber;
3141 BOOLEAN AtapiOnly
= FALSE
;
3143 KdPrint2((PRINT_PREFIX
"FindDevices:\n"));
3145 // Disable interrupts
3146 AtapiDisableInterrupts(deviceExtension
, Channel
);
3147 // AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_DISABLE_INTERRUPTS | IDE_DC_A_4BIT );
3149 // Clear expecting interrupt flag and current SRB field.
3150 UniataExpectChannelInterrupt(chan
, FALSE
);
3151 // chan->CurrentSrb = NULL;
3152 // max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : IDE_MAX_LUN_PER_CHAN;
3153 max_ldev
= (chan
->ChannelCtrlFlags
& CTRFLAGS_NO_SLAVE
) ? 1 : deviceExtension
->NumberLuns
;
3154 KdPrint2((PRINT_PREFIX
" max_ldev %d\n", max_ldev
));
3156 // Search for devices.
3157 for (i
= 0; i
< max_ldev
; i
++) {
3158 //AtapiDisableInterrupts(deviceExtension, Channel);
3159 if(Flags
& UNIATA_FIND_DEV_UNHIDE
) {
3160 chan
->lun
[i
]->DeviceFlags
&= ~DFLAGS_HIDDEN
;
3163 (CheckDevice(HwDeviceExtension
, Channel
, i
, TRUE
) != 0);
3164 //AtapiEnableInterrupts(deviceExtension, Channel);
3167 if(chan
->DeviceExtension
->HwFlags
& UNIATA_AHCI
) {
3168 AtapiEnableInterrupts(deviceExtension
, Channel
);
3169 KdPrint2((PRINT_PREFIX
3170 "FindDevices: returning %d (AHCI)\n",
3172 return deviceResponded
;
3175 for (i
= 0; i
< max_ldev
; i
++) {
3176 LunExt
= chan
->lun
[i
];
3178 if (( LunExt
->DeviceFlags
& DFLAGS_DEVICE_PRESENT
) &&
3179 !(LunExt
->DeviceFlags
& DFLAGS_LBA_ENABLED
) &&
3180 !(LunExt
->DeviceFlags
& DFLAGS_ATAPI_DEVICE
) && deviceResponded
) {
3182 // This hideous hack is to deal with ESDI devices that return
3183 // garbage geometry in the IDENTIFY data.
3184 // This is ONLY for the crashdump environment as
3185 // these are ESDI devices.
3186 if (LunExt
->IdentifyData
.SectorsPerTrack
== 0x35 &&
3187 LunExt
->IdentifyData
.NumberOfHeads
== 0x07) {
3189 KdPrint2((PRINT_PREFIX
"FindDevices: Found nasty Compaq ESDI!\n"));
3191 // Change these values to something reasonable.
3192 LunExt
->IdentifyData
.SectorsPerTrack
= 0x34;
3193 LunExt
->IdentifyData
.NumberOfHeads
= 0x0E;
3196 if (LunExt
->IdentifyData
.SectorsPerTrack
== 0x35 &&
3197 LunExt
->IdentifyData
.NumberOfHeads
== 0x0F) {
3199 KdPrint2((PRINT_PREFIX
"FindDevices: Found nasty Compaq ESDI!\n"));
3201 // Change these values to something reasonable.
3202 LunExt
->IdentifyData
.SectorsPerTrack
= 0x34;
3203 LunExt
->IdentifyData
.NumberOfHeads
= 0x0F;
3207 if (LunExt
->IdentifyData
.SectorsPerTrack
== 0x36 &&
3208 LunExt
->IdentifyData
.NumberOfHeads
== 0x07) {
3210 KdPrint2((PRINT_PREFIX
"FindDevices: Found nasty UltraStor ESDI!\n"));
3212 // Change these values to something reasonable.
3213 LunExt
->IdentifyData
.SectorsPerTrack
= 0x3F;
3214 LunExt
->IdentifyData
.NumberOfHeads
= 0x10;
3215 skipSetParameters
= TRUE
;
3219 if (skipSetParameters
)
3222 statusByte
= WaitOnBusy(chan
);
3224 // Select the device.
3225 SelectDrive(chan
, i
& 0x01);
3226 GetStatus(chan
, statusByte
);
3228 if (statusByte
& IDE_STATUS_ERROR
) {
3230 // Reset the device.
3231 KdPrint2((PRINT_PREFIX
3232 "FindDevices: Resetting controller before SetDriveParameters.\n"));
3234 AtapiHardReset(chan
, FALSE
, 500 * 1000);
3236 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER );
3237 chan->last_devsel = -1;
3238 AtapiStallExecution(500 * 1000);
3239 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER);
3241 SelectDrive(chan
, i
& 0x01);
3244 // Wait for Busy to drop.
3245 AtapiStallExecution(100);
3246 GetStatus(chan
, statusByte
);
3248 } while ((statusByte
& IDE_STATUS_BUSY
) && waitCount
--);
3251 statusByte
= WaitOnBusy(chan
);
3253 KdPrint2((PRINT_PREFIX
3254 "FindDevices: Status before SetDriveParameters: (%#x) (%#x)\n",
3256 AtapiReadPort1(chan
, IDX_IO1_i_DriveSelect
)));
3258 GetBaseStatus(chan
, statusByte
);
3260 // Use the IDENTIFY data to set drive parameters.
3261 if (!SetDriveParameters(HwDeviceExtension
,i
,Channel
)) {
3263 KdPrint2((PRINT_PREFIX
3264 "FindDevices: Set drive parameters for device %d failed\n",
3266 // Don't use this device as writes could cause corruption.
3267 LunExt
->DeviceFlags
&= ~DFLAGS_DEVICE_PRESENT
;
3268 UniataForgetDevice(LunExt
);
3272 if (LunExt
->DeviceFlags
& DFLAGS_REMOVABLE_DRIVE
) {
3274 // Pick up ALL IDE removable drives that conform to Yosemite V0.2...
3278 // Indicate that a device was found.
3280 deviceResponded
= TRUE
;
3285 /* // Reset the controller. This is a feeble attempt to leave the ESDI
3286 // controllers in a state that ATDISK driver will recognize them.
3287 // The problem in ATDISK has to do with timings as it is not reproducible
3288 // in debug. The reset should restore the controller to its poweron state
3289 // and give the system enough time to settle.
3290 if (!deviceResponded) {
3292 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_RESET_CONTROLLER );
3293 AtapiStallExecution(50 * 1000);
3294 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_REENABLE_CONTROLLER);
3297 if(deviceResponded
) {
3298 for (i
= 0; i
< max_ldev
; i
++) {
3299 LunExt
= chan
->lun
[i
];
3301 KdPrint2((PRINT_PREFIX
3302 "FindDevices: select %d dev to clear INTR\n", i
));
3303 SelectDrive(chan
, i
);
3304 GetBaseStatus(chan
, statusByte
);
3305 KdPrint2((PRINT_PREFIX
3306 "FindDevices: statusByte=%#x\n", statusByte
));
3308 for (i
= 0; i
< max_ldev
; i
++) {
3309 LunExt
= chan
->lun
[i
];
3311 if(LunExt
->DeviceFlags
& DFLAGS_DEVICE_PRESENT
) {
3312 // Make sure some device (master is preferred) is selected on exit.
3313 KdPrint2((PRINT_PREFIX
3314 "FindDevices: select %d dev on exit\n", i
));
3315 SelectDrive(chan
, i
);
3321 GetBaseStatus(chan
, statusByte
);
3322 // Enable interrupts
3323 AtapiEnableInterrupts(deviceExtension
, Channel
);
3324 // AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_A_4BIT );
3325 GetBaseStatus(chan
, statusByte
);
3327 KdPrint2((PRINT_PREFIX
3328 "FindDevices: returning %d\n",
3331 return deviceResponded
;
3333 } // end FindDevices()