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