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 1947 KdPrint2((PRINT_PREFIX "UniataClaimLegacyPCIIDE:\n")); 1948 1949 if(BMList[i].PciIdeDevObj) { 1950 KdPrint2((PRINT_PREFIX "Already initialized\n")); 1951 return STATUS_UNSUCCESSFUL; 1952 } 1953 1954 RtlInitUnicodeString(&devname, L"\\Device\\uniata_PCIIDE"); 1955 status = IoCreateDevice(SavedDriverObject, sizeof(PCIIDE_DEVICE_EXTENSION), 1956 /*NULL*/ &devname, FILE_DEVICE_UNKNOWN, 1957 0, FALSE, &(BMList[i].PciIdeDevObj)); 1958 1959 if(!NT_SUCCESS(status)) { 1960 KdPrint2((PRINT_PREFIX "IoCreateDevice failed %#x\n", status)); 1961 return status; 1962 } 1963 1964 resourceList = (PCM_RESOURCE_LIST) ExAllocatePool(PagedPool, 1965 sizeof(CM_RESOURCE_LIST)); 1966 1967 if (!resourceList) { 1968 KdPrint2((PRINT_PREFIX "!resourceList\n")); 1969 status = STATUS_INSUFFICIENT_RESOURCES; 1970 del_do: 1971 IoDeleteDevice(BMList[i].PciIdeDevObj); 1972 BMList[i].PciIdeDevObj = NULL; 1973 return status; 1974 } 1975 1976 RtlZeroMemory( 1977 resourceList, 1978 sizeof(CM_RESOURCE_LIST)); 1979 1980 // IoReportDetectedDevice() should be used for WDM OSes 1981 1982 // TODO: check if resourceList is actually used inside HalAssignSlotResources() 1983 // Note: with empty resourceList call to HalAssignSlotResources() fails on some HW 1984 // e.g. Intel ICH4, but works with non-empty. 1985 1986 resourceList->Count = 1; 1987 resourceList->List[0].InterfaceType = PCIBus; 1988 resourceList->List[0].BusNumber = BMList[i].busNumber; 1989 // we do not report IO ranges since they are used/claimed by ISA part(s) 1990 resourceList->List[0].PartialResourceList.Count = 0; 1991 1992 RtlInitUnicodeString(&devname, L"PCIIDE"); 1993 status = HalAssignSlotResources(&SavedRegPath, 1994 &devname, 1995 SavedDriverObject, 1996 BMList[i].PciIdeDevObj, 1997 PCIBus, 1998 BMList[i].busNumber, 1999 BMList[i].slotNumber, 2000 &resourceList); 2001 2002 if (!NT_SUCCESS(status)) { 2003 KdPrint2((PRINT_PREFIX "HalAssignSlotResources failed %#x\n", status)); 2004 // this is always deallocated inside HalAssignSlotResources() implementation 2005 //ExFreePool(resourceList); 2006 goto del_do; 2007 } 2008 2009 KdPrint2((PRINT_PREFIX "ok %#x\n", status)); 2010 BMList[i].ChanInitOk |= 0x80; 2011 2012 return status; 2013 } // end UniataClaimLegacyPCIIDE() 2014 2015 2016 /*++ 2017 2018 Routine Description: 2019 2020 This function is called to initialize 2nd device object for 2021 multichannel controllers. 2022 2023 Arguments: 2024 2025 HwDeviceExtension - HBA miniport driver's adapter data storage 2026 2027 Return Value: 2028 2029 ULONG 2030 2031 --*/ 2032 NTSTATUS 2033 NTAPI 2034 UniataConnectIntr2( 2035 IN PVOID HwDeviceExtension 2036 ) 2037 { 2038 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 2039 ULONG i = deviceExtension->DevIndex; 2040 NTSTATUS status; 2041 PISR2_DEVICE_EXTENSION Isr2DevExt; 2042 WCHAR devname_str[33]; 2043 UNICODE_STRING devname; 2044 2045 KdPrint2((PRINT_PREFIX "Init ISR:\n")); 2046 2047 /* 2048 We MUST register 2nd ISR for multichannel controllers even for UP systems. 2049 This is needed for cases when 2050 multichannel controller generate interrupt while we are still in its ISR for 2051 other channle's interrupt. New interrupt must be detected and queued for 2052 further processing. If we do not do this, system will not route this 2053 interrupt to main ISR (since it is busy) and we shall get to infinite loop 2054 looking for interrupt handler. 2055 */ 2056 2057 if(!deviceExtension->MasterDev && (deviceExtension->NumberChannels > 1) && // do not touch MasterDev 2058 !deviceExtension->simplexOnly && /* // this is unnecessary on simplex controllers 2059 !BMList[i].Isr2DevObj*/ // handle re-init under w2k+ 2060 /*!ForceSimplex*/ 2061 /*(CPU_num > 1) && // unnecessary for UP systems*/ 2062 TRUE) { 2063 // Ok, continue... 2064 KdPrint2((PRINT_PREFIX "Multichannel native mode, go...\n")); 2065 #ifndef UNIATA_USE_XXableInterrupts 2066 // If we raise IRQL to TIMER value, other interrupt cannot occure on the same CPU 2067 /* if(KeNumberProcessors < 2) { 2068 KdPrint2((PRINT_PREFIX "Unnecessary (?), UP machine\n")); 2069 //return STATUS_SUCCESS; 2070 }*/ 2071 #endif //UNIATA_USE_XXableInterrupts 2072 } else { 2073 KdPrint2((PRINT_PREFIX "Unnecessary\n")); 2074 return STATUS_SUCCESS; 2075 } 2076 2077 if(BMList[i].Isr2DevObj) { 2078 KdPrint2((PRINT_PREFIX "Already initialized [%d] %#x\n", i, BMList[i].Isr2DevObj)); 2079 return STATUS_SUCCESS; 2080 } 2081 2082 KdPrint2((PRINT_PREFIX "Create DO\n")); 2083 2084 devname.Length = 2085 _snwprintf(devname_str, sizeof(devname_str)/sizeof(WCHAR)-1, 2086 L"\\Device\\uniata%d_2ch", i); 2087 devname_str[devname.Length] = 0; 2088 devname.Length *= sizeof(WCHAR); 2089 devname.MaximumLength = devname.Length; 2090 devname.Buffer = devname_str; 2091 2092 KdPrint2((PRINT_PREFIX "DO name: len(%d, %d), %S\n", devname.Length, devname.MaximumLength, devname.Buffer)); 2093 2094 status = IoCreateDevice(SavedDriverObject, sizeof(ISR2_DEVICE_EXTENSION), 2095 /*NULL*/ &devname, FILE_DEVICE_UNKNOWN, 2096 0, FALSE, &(BMList[i].Isr2DevObj)); 2097 2098 if(!NT_SUCCESS(status)) { 2099 KdPrint2((PRINT_PREFIX "IoCreateDevice failed %#x\n", status)); 2100 return status; 2101 } 2102 2103 KdPrint2((PRINT_PREFIX "HalGetInterruptVector\n")); 2104 KdPrint2((PRINT_PREFIX " OrigAdapterInterfaceType=%d\n", deviceExtension->OrigAdapterInterfaceType)); 2105 KdPrint2((PRINT_PREFIX " SystemIoBusNumber=%d\n", deviceExtension->SystemIoBusNumber)); 2106 KdPrint2((PRINT_PREFIX " BusInterruptLevel=%d\n", deviceExtension->BusInterruptLevel)); 2107 KdPrint2((PRINT_PREFIX " BusInterruptVector=%d\n", deviceExtension->BusInterruptVector)); 2108 BMList[i].Isr2Vector = HalGetInterruptVector( 2109 deviceExtension->OrigAdapterInterfaceType, 2110 deviceExtension->SystemIoBusNumber, 2111 deviceExtension->BusInterruptLevel, 2112 deviceExtension->BusInterruptVector, 2113 &(BMList[i].Isr2Irql), 2114 &(BMList[i].Isr2Affinity)); 2115 2116 Isr2DevExt = (PISR2_DEVICE_EXTENSION)(BMList[i].Isr2DevObj->DeviceExtension); 2117 Isr2DevExt->HwDeviceExtension = deviceExtension; 2118 Isr2DevExt->DevIndex = i; 2119 2120 KdPrint2((PRINT_PREFIX "isr2_de %#x\n", Isr2DevExt)); 2121 KdPrint2((PRINT_PREFIX "isr2_vector %#x\n", BMList[i].Isr2Vector)); 2122 KdPrint2((PRINT_PREFIX "isr2_irql %#x\n", BMList[i].Isr2Irql)); 2123 KdPrint2((PRINT_PREFIX "isr2_affinity %#x\n", BMList[i].Isr2Affinity)); 2124 2125 // deviceExtension->QueueNewIrql = BMList[i].Isr2Irql; 2126 2127 KdPrint2((PRINT_PREFIX "IoConnectInterrupt\n")); 2128 status = IoConnectInterrupt( 2129 &(BMList[i].Isr2InterruptObject), 2130 AtapiInterrupt2, 2131 Isr2DevExt, 2132 NULL, 2133 BMList[i].Isr2Vector, 2134 BMList[i].Isr2Irql, 2135 BMList[i].Isr2Irql, 2136 (KINTERRUPT_MODE)(deviceExtension->InterruptMode), 2137 TRUE, 2138 BMList[i].Isr2Affinity, 2139 FALSE); 2140 2141 if(!NT_SUCCESS(status)) { 2142 KdPrint2((PRINT_PREFIX "IoConnectInterrupt failed\n")); 2143 IoDeleteDevice(BMList[i].Isr2DevObj); 2144 BMList[i].Isr2DevObj = NULL; 2145 BMList[i].Isr2InterruptObject = NULL; 2146 return status; 2147 } 2148 2149 //deviceExtension->Isr2DevObj = BMList[i].Isr2DevObj; 2150 2151 return status; 2152 } // end UniataConnectIntr2() 2153 2154 NTSTATUS 2155 NTAPI 2156 UniataDisconnectIntr2( 2157 IN PVOID HwDeviceExtension 2158 ) 2159 { 2160 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 2161 ULONG i = deviceExtension->DevIndex; 2162 // NTSTATUS status; 2163 2164 KdPrint2((PRINT_PREFIX "Deinit ISR:\n")); 2165 2166 if(!BMList[i].Isr2DevObj) { 2167 KdPrint2((PRINT_PREFIX "Already uninitialized %#x\n")); 2168 return STATUS_SUCCESS; 2169 } 2170 2171 IoDisconnectInterrupt(BMList[i].Isr2InterruptObject); 2172 2173 BMList[i].Isr2InterruptObject = NULL; 2174 2175 IoDeleteDevice(BMList[i].Isr2DevObj); 2176 2177 BMList[i].Isr2DevObj = NULL; 2178 //deviceExtension->Isr2DevObj = NULL; 2179 2180 return STATUS_SUCCESS; 2181 } // end UniataDisconnectIntr2() 2182 2183 #endif //UNIATA_CORE 2184 2185 BOOLEAN 2186 NTAPI 2187 AtapiCheckIOInterference( 2188 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, 2189 ULONG portBase) { 2190 // check if Primary/Secondary Master IDE claimed 2191 if((portBase == IO_WD1) && 2192 (ConfigInfo->AtdiskPrimaryClaimed || AtdiskPrimaryClaimed)) { 2193 KdPrint2((PRINT_PREFIX "AtapiCheckIOInterference: AtdiskPrimaryClaimed\n")); 2194 return TRUE; 2195 } else 2196 if((portBase == IO_WD2) && 2197 (ConfigInfo->AtdiskSecondaryClaimed || AtdiskSecondaryClaimed)) { 2198 KdPrint2((PRINT_PREFIX "AtapiCheckIOInterference: AtdiskSecondaryClaimed\n")); 2199 return TRUE; 2200 } 2201 return FALSE; 2202 } // end AtapiCheckIOInterference() 2203 2204 /*++ 2205 2206 Routine Description: 2207 2208 This function is called by the OS-specific port driver after 2209 the necessary storage has been allocated, to gather information 2210 about the adapter's configuration. 2211 2212 Arguments: 2213 2214 HwDeviceExtension - HBA miniport driver's adapter data storage 2215 Context - Address of adapter count 2216 ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility. 2217 ConfigInfo - Configuration information structure describing HBA 2218 Again - Indicates search for adapters to continue 2219 2220 Return Value: 2221 2222 ULONG 2223 2224 --*/ 2225 ULONG 2226 NTAPI 2227 AtapiFindIsaController( 2228 IN PVOID HwDeviceExtension, 2229 IN PVOID Context, 2230 IN PVOID BusInformation, 2231 IN PCHAR ArgumentString, 2232 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, 2233 OUT PBOOLEAN Again 2234 ) 2235 { 2236 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 2237 PHW_CHANNEL chan; 2238 PULONG adapterCount = (PULONG)Context; 2239 PUCHAR ioSpace = NULL; 2240 ULONG i; 2241 ULONG irq=0; 2242 ULONG portBase=0; 2243 ULONG retryCount; 2244 // BOOLEAN atapiOnly; 2245 UCHAR statusByte, statusByte2; 2246 BOOLEAN preConfig = FALSE; 2247 // 2248 PIDE_REGISTERS_1 BaseIoAddress1; 2249 PIDE_REGISTERS_2 BaseIoAddress2 = NULL; 2250 2251 // The following table specifies the ports to be checked when searching for 2252 // an IDE controller. A zero entry terminates the search. 2253 static CONST ULONG AdapterAddresses[5] = {IO_WD1, IO_WD2, IO_WD1-8, IO_WD2-8, 0}; 2254 // CONST UCHAR Channels[5] = {0, 1, 0, 1, 0}; 2255 2256 // The following table specifies interrupt levels corresponding to the 2257 // port addresses in the previous table. 2258 static CONST ULONG InterruptLevels[5] = {14, 15, 11, 10, 0}; 2259 2260 KdPrint2((PRINT_PREFIX "AtapiFindIsaController (ISA):\n")); 2261 2262 if (!deviceExtension) { 2263 return SP_RETURN_ERROR; 2264 } 2265 RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION)); 2266 2267 KdPrint2((PRINT_PREFIX " assume max PIO4\n")); 2268 deviceExtension->MaxTransferMode = ATA_PIO4; 2269 deviceExtension->NumberChannels = 1; 2270 deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN; // default 2271 2272 if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) { 2273 goto exit_error; 2274 } 2275 2276 chan = &(deviceExtension->chan[0]); 2277 AtapiSetupLunPtrs(chan, deviceExtension, 0); 2278 2279 deviceExtension->AdapterInterfaceType = 2280 deviceExtension->OrigAdapterInterfaceType 2281 = ConfigInfo->AdapterInterfaceType; 2282 2283 #ifndef UNIATA_CORE 2284 2285 /* do extra chipset specific setups */ 2286 AtapiReadChipConfig(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, CHAN_NOT_SPECIFIED); 2287 AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, CHAN_NOT_SPECIFIED); 2288 2289 // Check to see if this is a special configuration environment. 2290 portBase = irq = 0; 2291 if (ArgumentString) { 2292 2293 irq = AtapiParseArgumentString(ArgumentString, "Interrupt"); 2294 if (irq ) { 2295 2296 // Both parameters must be present to proceed 2297 portBase = AtapiParseArgumentString(ArgumentString, "BaseAddress"); 2298 if (!portBase) { 2299 2300 // Try a default search for the part. 2301 irq = 0; 2302 } 2303 } 2304 } 2305 2306 #endif //UNIATA_CORE 2307 /* 2308 for(i=0; i<2; i++) { 2309 if((*ConfigInfo->AccessRanges)[i].RangeStart) { 2310 KdPrint2((PRINT_PREFIX " IoRange[%d], start %#x, len %#x, mem %#x\n", 2311 i, 2312 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[i].RangeStart), 2313 (*ConfigInfo->AccessRanges)[i].RangeLength, 2314 (*ConfigInfo->AccessRanges)[i].RangeInMemory 2315 )); 2316 } 2317 } 2318 */ 2319 // if((*ConfigInfo->AccessRanges)[0].RangeStart) { 2320 portBase = ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart); 2321 // } 2322 if(portBase) { 2323 if(!AtapiCheckIOInterference(ConfigInfo, portBase)) { 2324 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, 2325 ConfigInfo->AdapterInterfaceType, 2326 ConfigInfo->SystemIoBusNumber, 2327 (*ConfigInfo->AccessRanges)[0].RangeStart, 2328 (*ConfigInfo->AccessRanges)[0].RangeLength, 2329 (BOOLEAN) !((*ConfigInfo->AccessRanges)[0].RangeInMemory)); 2330 } else { 2331 // do not touch resources, just fail later inside loop on next call to 2332 // AtapiCheckIOInterference() 2333 } 2334 *Again = FALSE; 2335 // Since we have pre-configured information we only need to go through this loop once 2336 preConfig = TRUE; 2337 KdPrint2((PRINT_PREFIX " preconfig, portBase=%x, len=%x\n", portBase, (*ConfigInfo->AccessRanges)[0].RangeLength)); 2338 } 2339 2340 // Scan through the adapter address looking for adapters. 2341 #ifndef UNIATA_CORE 2342 while (AdapterAddresses[*adapterCount] != 0) { 2343 #else 2344 do { 2345 #endif //UNIATA_CORE 2346 2347 retryCount = 4; 2348 deviceExtension->DevIndex = (*adapterCount); // this is used inside AtapiRegCheckDevValue() 2349 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: adapterCount=%d\n", *adapterCount)); 2350 2351 for (i = 0; i < deviceExtension->NumberLuns; i++) { 2352 // Zero device fields to ensure that if earlier devices were found, 2353 // but not claimed, the fields are cleared. 2354 deviceExtension->lun[i].DeviceFlags &= ~(DFLAGS_ATAPI_DEVICE | DFLAGS_DEVICE_PRESENT | DFLAGS_TAPE_DEVICE); 2355 } 2356 // Get the system physical address for this IO range. 2357 2358 // Check if configInfo has the default information 2359 // if not, we go and find ourselves 2360 if (preConfig == FALSE) { 2361 2362 ULONG portBase_reg = 0; 2363 ULONG irq_reg = 0; 2364 2365 if (!portBase) { 2366 portBase = AdapterAddresses[*adapterCount]; 2367 KdPrint2((PRINT_PREFIX "portBase[%d]=%x\n", *adapterCount, portBase)); 2368 } else { 2369 KdPrint2((PRINT_PREFIX "portBase=%x\n", portBase)); 2370 } 2371 2372 portBase_reg = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PortBase", 0); 2373 irq_reg = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Irq", 0); 2374 if(portBase_reg && irq_reg) { 2375 KdPrint2((PRINT_PREFIX "use registry settings portBase=%x, irq=%d\n", portBase_reg, irq_reg)); 2376 portBase = portBase_reg; 2377 irq = irq_reg; 2378 } 2379 // check if Primary/Secondary Master IDE claimed 2380 if(AtapiCheckIOInterference(ConfigInfo, portBase)) { 2381 goto next_adapter; 2382 } 2383 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, 2384 ConfigInfo->AdapterInterfaceType, 2385 ConfigInfo->SystemIoBusNumber, 2386 ScsiPortConvertUlongToPhysicalAddress(portBase), 2387 ATA_IOSIZE, 2388 TRUE); 2389 2390 } else { 2391 KdPrint2((PRINT_PREFIX "preconfig portBase=%x\n", portBase)); 2392 // Check if Primary/Secondary Master IDE claimed 2393 // We can also get here from preConfig branc with conflicting portBase 2394 // (and thus, w/o ioSpace allocated) 2395 if(AtapiCheckIOInterference(ConfigInfo, portBase)) { 2396 goto not_found; 2397 } 2398 } 2399 BaseIoAddress1 = (PIDE_REGISTERS_1)ioSpace; 2400 next_adapter: 2401 // Update the adapter count. 2402 (*adapterCount)++; 2403 2404 // Check if ioSpace accessible. 2405 if (!ioSpace) { 2406 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: !ioSpace\n")); 2407 portBase = 0; 2408 continue; 2409 } 2410 2411 // Get the system physical address for the second IO range. 2412 if (BaseIoAddress1) { 2413 if(preConfig && 2414 !ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[1].RangeStart)) { 2415 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: PCMCIA ?\n")); 2416 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, 2417 ConfigInfo->AdapterInterfaceType, 2418 ConfigInfo->SystemIoBusNumber, 2419 ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR)BaseIoAddress1 + 0x0E), 2420 ATA_ALTIOSIZE, 2421 TRUE); 2422 } else { 2423 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, 2424 ConfigInfo->AdapterInterfaceType, 2425 ConfigInfo->SystemIoBusNumber, 2426 ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR)BaseIoAddress1 + ATA_ALTOFFSET), 2427 ATA_ALTIOSIZE, 2428 TRUE); 2429 } 2430 } 2431 BaseIoAddress2 = (PIDE_REGISTERS_2)ioSpace; 2432 KdPrint2((PRINT_PREFIX " BaseIoAddress1=%x\n", BaseIoAddress1)); 2433 KdPrint2((PRINT_PREFIX " BaseIoAddress2=%x\n", BaseIoAddress2)); 2434 if(!irq) { 2435 KdPrint2((PRINT_PREFIX " expected InterruptLevel=%x\n", InterruptLevels[*adapterCount - 1])); 2436 } 2437 2438 UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2); 2439 UniataInitMapBM(deviceExtension, 0, FALSE); 2440 2441 #ifdef _DEBUG 2442 UniataDumpATARegs(chan); 2443 #endif 2444 2445 // Select master. 2446 SelectDrive(chan, 0); 2447 2448 statusByte = AtapiReadPort1(chan, IDX_IO1_i_Status); 2449 statusByte2 = AtapiReadPort1(chan, IDX_IO2_AltStatus); 2450 if((statusByte ^ statusByte2) & ~IDE_STATUS_INDEX) { 2451 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: Status %x vs AltStatus %x missmatch, abort init ?\n", statusByte, statusByte2)); 2452 2453 if(BaseIoAddress2) { 2454 ScsiPortFreeDeviceBase(HwDeviceExtension, 2455 (PCHAR)BaseIoAddress2); 2456 BaseIoAddress2 = NULL; 2457 } 2458 BaseIoAddress2 = (PIDE_REGISTERS_2)((ULONGIO_PTR)BaseIoAddress1 + 0x0E); 2459 KdPrint2((PRINT_PREFIX " try BaseIoAddress2=%x\n", BaseIoAddress2)); 2460 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, 2461 ConfigInfo->AdapterInterfaceType, 2462 ConfigInfo->SystemIoBusNumber, 2463 ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR)BaseIoAddress2), 2464 ATA_ALTIOSIZE, 2465 TRUE); 2466 if(!ioSpace) { 2467 BaseIoAddress2 = NULL; 2468 KdPrint2((PRINT_PREFIX " abort (0)\n")); 2469 goto not_found; 2470 } 2471 UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2); 2472 statusByte = AtapiReadPort1(chan, IDX_IO1_i_Status); 2473 statusByte2 = AtapiReadPort1(chan, IDX_IO2_AltStatus); 2474 if((statusByte ^ statusByte2) & ~IDE_STATUS_INDEX) { 2475 KdPrint2((PRINT_PREFIX " abort: Status %x vs AltStatus %x missmatch\n", statusByte, statusByte2)); 2476 goto not_found; 2477 } 2478 } 2479 2480 retryIdentifier: 2481 2482 // Select master. 2483 SelectDrive(chan, 0); 2484 2485 // Check if card at this address. 2486 AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, 0xAA); 2487 statusByte = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow); 2488 2489 // Check if indentifier can be read back. 2490 if (AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) != 0xAA || 2491 statusByte == IDE_STATUS_WRONG) { 2492 2493 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: Identifier read back from Master (%#x)\n", 2494 statusByte)); 2495 2496 statusByte = AtapiReadPort1(chan, IDX_IO2_AltStatus); 2497 2498 if (statusByte != IDE_STATUS_WRONG && (statusByte & IDE_STATUS_BUSY)) { 2499 2500 i = 0; 2501 2502 // Could be the TEAC in a thinkpad. Their dos driver puts it in a sleep-mode that 2503 // warm boots don't clear. 2504 do { 2505 AtapiStallExecution(1000); 2506 statusByte = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_Status); 2507 KdPrint2((PRINT_PREFIX 2508 "AtapiFindIsaController: First access to status %#x\n", 2509 statusByte)); 2510 } while ((statusByte & IDE_STATUS_BUSY) && ++i < 10); 2511 2512 if (retryCount-- && (!(statusByte & IDE_STATUS_BUSY))) { 2513 goto retryIdentifier; 2514 } 2515 } 2516 2517 // Select slave. 2518 SelectDrive(chan, 1); 2519 statusByte = AtapiReadPort1(chan, IDX_IO2_AltStatus); 2520 2521 // See if slave is present. 2522 AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, 0xAA); 2523 2524 if (AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) != 0xAA || 2525 statusByte == IDE_STATUS_WRONG) { 2526 2527 KdPrint2((PRINT_PREFIX 2528 "AtapiFindIsaController: Identifier read back from Slave (%#x)\n", 2529 statusByte)); 2530 goto not_found; 2531 } 2532 } 2533 2534 // Fill in the access array information only if default params are not in there. 2535 if (preConfig == FALSE) { 2536 2537 // An adapter has been found request another call, only if we didn't get preconfigured info. 2538 *Again = TRUE; 2539 2540 if (portBase) { 2541 (*ConfigInfo->AccessRanges)[0].RangeStart = ScsiPortConvertUlongToPhysicalAddress(portBase); 2542 } else { 2543 (*ConfigInfo->AccessRanges)[0].RangeStart = 2544 ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount - 1]); 2545 } 2546 2547 (*ConfigInfo->AccessRanges)[0].RangeLength = ATA_IOSIZE; 2548 (*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE; 2549 2550 if(BaseIoAddress2) { 2551 if(hasPCI) { 2552 (*ConfigInfo->AccessRanges)[1].RangeStart = ScsiPortConvertUlongToPhysicalAddress((ULONG_PTR)BaseIoAddress2); 2553 (*ConfigInfo->AccessRanges)[1].RangeLength = ATA_ALTIOSIZE; 2554 (*ConfigInfo->AccessRanges)[1].RangeInMemory = FALSE; 2555 } else { 2556 // NT4 and NT3.51 on ISA-only hardware definitly fail floppy.sys load 2557 // when this range is claimed by other driver. 2558 // However, floppy should use only 0x3f0-3f5,3f7 2559 if((ULONGIO_PTR)BaseIoAddress2 >= 0x3f0 && (ULONGIO_PTR)BaseIoAddress2 <= 0x3f7) { 2560 KdPrint2((PRINT_PREFIX "!!! Possible AltStatus vs Floppy IO range interference !!!\n")); 2561 } 2562 KdPrint2((PRINT_PREFIX "Do not expose to OS on old ISA\n")); 2563 (*ConfigInfo->AccessRanges)[1].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0); 2564 (*ConfigInfo->AccessRanges)[1].RangeLength = 0; 2565 } 2566 } 2567 2568 // Indicate the interrupt level corresponding to this IO range. 2569 if (irq) { 2570 ConfigInfo->BusInterruptLevel = irq; 2571 } else { 2572 ConfigInfo->BusInterruptLevel = InterruptLevels[*adapterCount - 1]; 2573 } 2574 2575 if (ConfigInfo->AdapterInterfaceType == MicroChannel) { 2576 ConfigInfo->InterruptMode = LevelSensitive; 2577 } else { 2578 ConfigInfo->InterruptMode = Latched; 2579 } 2580 } 2581 2582 ConfigInfo->NumberOfBuses = 1; 2583 ConfigInfo->MaximumNumberOfTargets = IDE_MAX_LUN_PER_CHAN; 2584 2585 // Indicate maximum transfer length is 64k. 2586 ConfigInfo->MaximumTransferLength = 0x10000; 2587 deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength; 2588 2589 KdPrint2((PRINT_PREFIX "de %#x, Channel ???\n", deviceExtension)); 2590 //PrintNtConsole("de %#x, Channel %#x, nchan %#x\n",deviceExtension, channel, deviceExtension->NumberChannels); 2591 2592 KdPrint2((PRINT_PREFIX "chan = %#x\n", chan)); 2593 //PrintNtConsole("chan = %#x, c=%#x\n", chan, c); 2594 /* 2595 // should be already set up in AtapiSetupLunPtrs(chan, deviceExtension, 0); 2596 2597 chan->DeviceExtension = deviceExtension; 2598 chan->lChannel = 0; 2599 chan->lun[0] = &(deviceExtension->lun[0]); 2600 chan->lun[1] = &(deviceExtension->lun[1]);*/ 2601 2602 /* do extra channel-specific setups */ 2603 AtapiReadChipConfig(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, 0); 2604 AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, 0); 2605 2606 KdPrint2((PRINT_PREFIX 2607 "AtapiFindIsaController: Found IDE at %#x\n", 2608 BaseIoAddress1)); 2609 2610 // For Daytona, the atdisk driver gets the first shot at the 2611 // primary and secondary controllers. 2612 if (preConfig == FALSE) { 2613 2614 if (*adapterCount - 1 < 2) { 2615 2616 // Determine whether this driver is being initialized by the 2617 // system or as a crash dump driver. 2618 if (g_Dump) { 2619 #ifndef UNIATA_CORE 2620 deviceExtension->DriverMustPoll = TRUE; 2621 #endif //UNIATA_CORE 2622 } else { 2623 deviceExtension->DriverMustPoll = FALSE; 2624 } 2625 2626 } else { 2627 //atapiOnly = FALSE; 2628 } 2629 2630 } else { 2631 2632 //atapiOnly = FALSE; 2633 deviceExtension->DriverMustPoll = FALSE; 2634 2635 }// preConfig check 2636 2637 // Save the Interrupe Mode for later use 2638 deviceExtension->InterruptMode = ConfigInfo->InterruptMode; 2639 deviceExtension->BusInterruptLevel = ConfigInfo->BusInterruptLevel; 2640 deviceExtension->BusInterruptVector = ConfigInfo->BusInterruptVector; 2641 2642 KdPrint2((PRINT_PREFIX 2643 "AtapiFindIsaController: look for devices\n")); 2644 // Search for devices on this controller. 2645 if (FindDevices(HwDeviceExtension, 2646 0, 2647 0 /* Channel */)) { 2648 2649 KdPrint2((PRINT_PREFIX 2650 "AtapiFindIsaController: detected\n")); 2651 // Claim primary or secondary ATA IO range. 2652 if (portBase) { 2653 switch (portBase) { 2654 case IO_WD2: 2655 ConfigInfo->AtdiskSecondaryClaimed = TRUE; 2656 chan->PrimaryAddress = FALSE; 2657 break; 2658 case IO_WD1: 2659 ConfigInfo->AtdiskPrimaryClaimed = TRUE; 2660 chan->PrimaryAddress = TRUE; 2661 break; 2662 default: 2663 break; 2664 } 2665 } else { 2666 if (*adapterCount == 1) { 2667 ConfigInfo->AtdiskPrimaryClaimed = TRUE; 2668 chan->PrimaryAddress = TRUE; 2669 } else if (*adapterCount == 2) { 2670 ConfigInfo->AtdiskSecondaryClaimed = TRUE; 2671 chan->PrimaryAddress = FALSE; 2672 } 2673 } 2674 2675 if(deviceExtension->AdapterInterfaceType == Isa) { 2676 IsaCount++; 2677 } else 2678 if(deviceExtension->AdapterInterfaceType == MicroChannel) { 2679 MCACount++; 2680 } 2681 2682 ConfigInfo->NumberOfBuses++; // add virtual channel for communication port 2683 KdPrint2((PRINT_PREFIX 2684 "AtapiFindIsaController: return SP_RETURN_FOUND\n")); 2685 return(SP_RETURN_FOUND); 2686 } else { 2687 not_found: 2688 // No controller at this base address. 2689 if(BaseIoAddress1) { 2690 ScsiPortFreeDeviceBase(HwDeviceExtension, 2691 (PCHAR)BaseIoAddress1); 2692 BaseIoAddress1 = NULL; 2693 } 2694 if(BaseIoAddress2) { 2695 ScsiPortFreeDeviceBase(HwDeviceExtension, 2696 (PCHAR)BaseIoAddress2); 2697 BaseIoAddress2 = NULL; 2698 } 2699 for(i=0; i<2; i++) { 2700 KdPrint2((PRINT_PREFIX 2701 "AtapiFindIsaController: cleanup AccessRanges %d\n", i)); 2702 (*ConfigInfo->AccessRanges)[i].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0); 2703 (*ConfigInfo->AccessRanges)[i].RangeLength = 0; 2704 (*ConfigInfo->AccessRanges)[i].RangeInMemory = FALSE; 2705 } 2706 irq = 0; 2707 portBase = 0; 2708 } 2709 #ifndef UNIATA_CORE 2710 } 2711 #else 2712 } while(FALSE); 2713 #endif //UNIATA_CORE 2714 2715 // The entire table has been searched and no adapters have been found. 2716 // There is no need to call again and the device base can now be freed. 2717 // Clear the adapter count for the next bus. 2718 *Again = FALSE; 2719 *(adapterCount) = 0; 2720 2721 KdPrint2((PRINT_PREFIX 2722 "AtapiFindIsaController: return SP_RETURN_NOT_FOUND\n")); 2723 UniataFreeLunExt(deviceExtension); 2724 return(SP_RETURN_NOT_FOUND); 2725 2726 exit_error: 2727 UniataFreeLunExt(deviceExtension); 2728 return SP_RETURN_ERROR; 2729 2730 } // end AtapiFindIsaController() 2731 2732 /* 2733 Do nothing, but parse ScsiPort ArgumentString and setup global variables. 2734 */ 2735 2736 ULONG 2737 NTAPI 2738 AtapiReadArgumentString( 2739 IN PVOID HwDeviceExtension, 2740 IN PVOID Context, 2741 IN PVOID BusInformation, 2742 IN PCHAR ArgumentString, 2743 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, 2744 OUT PBOOLEAN Again 2745 ) 2746 { 2747 #ifndef __REACTOS__ 2748 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 2749 #endif 2750 2751 if (AtapiParseArgumentString(ArgumentString, "dump") == 1) { 2752 KdPrint2((PRINT_PREFIX 2753 "AtapiReadArgumentString: Crash dump\n")); 2754 //atapiOnly = FALSE; 2755 g_Dump = TRUE; 2756 } 2757 return(SP_RETURN_NOT_FOUND); 2758 } // end AtapiReadArgumentString() 2759 2760 ULONG 2761 NTAPI 2762 UniataAnybodyHome( 2763 IN PVOID HwDeviceExtension, 2764 IN ULONG lChannel, 2765 IN ULONG deviceNumber 2766 ) 2767 { 2768 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 2769 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]); 2770 //ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0); 2771 PHW_LU_EXTENSION LunExt = chan->lun[deviceNumber]; 2772 2773 SATA_SSTATUS_REG SStatus; 2774 UCHAR signatureLow; 2775 UCHAR signatureHigh; 2776 2777 if(LunExt->DeviceFlags & DFLAGS_HIDDEN) { 2778 KdPrint2((PRINT_PREFIX " hidden\n")); 2779 UniataForgetDevice(LunExt); 2780 return ATA_AT_HOME_NOBODY; 2781 } 2782 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) { 2783 2784 SStatus.Reg = UniataSataReadPort4(chan, IDX_SATA_SStatus, deviceNumber); 2785 KdPrint2((PRINT_PREFIX "SStatus %x\n", SStatus.Reg)); 2786 if(SStatus.DET <= SStatus_DET_Dev_NoPhy) { 2787 KdPrint2((PRINT_PREFIX " SATA DET <= SStatus_DET_Dev_NoPhy\n")); 2788 return ATA_AT_HOME_NOBODY; 2789 } 2790 if(SStatus.SPD < SStatus_SPD_Gen1) { 2791 KdPrint2((PRINT_PREFIX " SATA SPD < SStatus_SPD_Gen1\n")); 2792 return ATA_AT_HOME_NOBODY; 2793 } 2794 if(SStatus.IPM == SStatus_IPM_NoDev) { 2795 KdPrint2((PRINT_PREFIX " SATA IPN == SStatus_IPM_NoDev\n")); 2796 return ATA_AT_HOME_NOBODY; 2797 } 2798 if(!(deviceExtension->HwFlags & UNIATA_AHCI)) { 2799 // Select the device for legacy. 2800 goto legacy_select; 2801 } 2802 2803 } else { 2804 legacy_select: 2805 // Select the device. 2806 SelectDrive(chan, deviceNumber); 2807 AtapiStallExecution(5); 2808 } 2809 2810 if((deviceExtension->HwFlags & UNIATA_AHCI) && 2811 UniataIsSATARangeAvailable(deviceExtension, lChannel)) { 2812 KdPrint2((PRINT_PREFIX " AHCI check\n")); 2813 ULONG SIG = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_SIG); 2814 signatureLow = (UCHAR)(SIG >> 16); 2815 signatureHigh = (UCHAR)(SIG >> 24); 2816 } else { 2817 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow); 2818 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh); 2819 } 2820 2821 if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) { 2822 KdPrint2((PRINT_PREFIX " ATAPI at home\n")); 2823 return ATA_AT_HOME_ATAPI; 2824 } 2825 if(deviceExtension->HwFlags & UNIATA_AHCI) { 2826 KdPrint2((PRINT_PREFIX " AHCI HDD at home\n")); 2827 return ATA_AT_HOME_HDD; 2828 } 2829 if(g_opt_VirtualMachine > VM_NONE /*== VM_BOCHS || 2830 g_opt_VirtualMachine == VM_VBOX*/) { 2831 GetStatus(chan, signatureLow); 2832 if(!signatureLow) { 2833 KdPrint2((PRINT_PREFIX " 0-status VM - not present\n")); 2834 UniataForgetDevice(LunExt); 2835 return ATA_AT_HOME_NOBODY; 2836 } 2837 } 2838 2839 AtapiStallExecution(10); 2840 2841 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0x55); 2842 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0x55); 2843 AtapiStallExecution(5); 2844 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber); 2845 if(signatureLow != 0x55) { 2846 if(signatureLow == 0xff || signatureLow == 0) { 2847 KdPrint2((PRINT_PREFIX " nobody home! %#x != 0x55\n", signatureLow)); 2848 UniataForgetDevice(LunExt); 2849 return ATA_AT_HOME_NOBODY; 2850 } 2851 // another chance 2852 signatureLow = AtapiReadPort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh); 2853 signatureLow += 2; 2854 AtapiWritePort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh, signatureLow); 2855 AtapiStallExecution(5); 2856 signatureHigh = AtapiReadPort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh); 2857 if(signatureLow != signatureHigh) { 2858 KdPrint2((PRINT_PREFIX " nobody home! last chance failed %#x != %#x\n", signatureLow, signatureHigh)); 2859 UniataForgetDevice(LunExt); 2860 return ATA_AT_HOME_NOBODY; 2861 } 2862 return ATA_AT_HOME_XXX; 2863 } 2864 2865 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0xAA); 2866 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0xAA); 2867 AtapiStallExecution(5); 2868 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber); 2869 if(signatureLow != 0xAA) { 2870 KdPrint2((PRINT_PREFIX " nobody home! %#x != 0xAA\n", signatureLow)); 2871 UniataForgetDevice(LunExt); 2872 return ATA_AT_HOME_NOBODY; 2873 } 2874 2875 KdPrint2((PRINT_PREFIX " HDD at home\n")); 2876 return ATA_AT_HOME_HDD; 2877 } // end UniataAnybodyHome() 2878 2879 ULONG 2880 NTAPI 2881 CheckDevice( 2882 IN PVOID HwDeviceExtension, 2883 IN ULONG lChannel, 2884 IN ULONG deviceNumber, 2885 IN BOOLEAN ResetDev 2886 ) 2887 { 2888 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 2889 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]); 2890 //ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0); 2891 PHW_LU_EXTENSION LunExt; 2892 2893 UCHAR signatureLow, 2894 signatureHigh; 2895 UCHAR statusByte; 2896 ULONG RetVal=0; 2897 ULONG waitCount = g_opt_WaitBusyResetCount; 2898 ULONG at_home = 0; 2899 2900 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x\n", 2901 deviceNumber)); 2902 2903 if(deviceNumber >= chan->NumberLuns) { 2904 return 0; 2905 } 2906 if(deviceExtension->HwFlags & UNIATA_AHCI) { 2907 if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) { 2908 return 0; 2909 } 2910 } 2911 LunExt = chan->lun[deviceNumber]; 2912 2913 if(ResetDev) { 2914 LunExt->PowerState = 0; 2915 } 2916 2917 if((deviceExtension->HwFlags & UNIATA_SATA) && 2918 !UniataIsSATARangeAvailable(deviceExtension, lChannel) && 2919 deviceNumber) { 2920 KdPrint2((PRINT_PREFIX " SATA w/o i/o registers, check slave presence\n")); 2921 SelectDrive(chan, deviceNumber & 0x01); 2922 statusByte = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_DriveSelect); 2923 KdPrint2((PRINT_PREFIX " DriveSelect: %#x\n", statusByte)); 2924 if((statusByte & IDE_DRIVE_MASK) != IDE_DRIVE_SELECT_2) { 2925 KdPrint2((PRINT_PREFIX "CheckDevice: (no dev)\n")); 2926 UniataForgetDevice(LunExt); 2927 return 0; 2928 } 2929 } 2930 2931 if(ResetDev && (deviceExtension->HwFlags & UNIATA_AHCI)) { 2932 KdPrint2((PRINT_PREFIX "CheckDevice: reset AHCI dev\n")); 2933 if(UniataAhciSoftReset(HwDeviceExtension, chan->lChannel, deviceNumber) == (ULONG)(-1)) { 2934 KdPrint2((PRINT_PREFIX "CheckDevice: (no dev)\n")); 2935 UniataForgetDevice(LunExt); 2936 return 0; 2937 } 2938 } else 2939 if(ResetDev) { 2940 KdPrint2((PRINT_PREFIX "CheckDevice: reset dev\n")); 2941 2942 // Reset device 2943 AtapiSoftReset(chan, deviceNumber); 2944 2945 if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) { 2946 //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 1\n")); 2947 return 0; 2948 } 2949 statusByte = WaitOnBusy(chan); 2950 2951 if((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) { 2952 KdPrint2((PRINT_PREFIX 2953 "CheckDevice: bad status %x\n", statusByte)); 2954 } else 2955 if(statusByte != IDE_STATUS_WRONG && (statusByte & IDE_STATUS_BUSY)) { 2956 // Perform hard-reset. 2957 KdPrint2((PRINT_PREFIX 2958 "CheckDevice: BUSY\n")); 2959 2960 AtapiHardReset(chan, FALSE, 500 * 1000); 2961 /* 2962 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER ); 2963 chan->last_devsel = -1; 2964 AtapiStallExecution(500 * 1000); 2965 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER); 2966 */ 2967 SelectDrive(chan, deviceNumber & 0x01); 2968 2969 do { 2970 // Wait for Busy to drop. 2971 AtapiStallExecution(100); 2972 GetStatus(chan, statusByte); 2973 2974 } while ((statusByte & IDE_STATUS_BUSY) && waitCount--); 2975 2976 GetBaseStatus(chan, statusByte); 2977 KdPrint2((PRINT_PREFIX 2978 "CheckDevice: status after hard reset %x\n", statusByte)); 2979 } 2980 2981 if((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) { 2982 KdPrint2((PRINT_PREFIX 2983 "CheckDevice: no dev ?\n")); 2984 UniataForgetDevice(LunExt); 2985 return 0; 2986 } else 2987 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) { 2988 //if(deviceExtension->HwFlags & UNIATA_SATA) { 2989 KdPrint2((PRINT_PREFIX 2990 "CheckDevice: try enable SATA Phy\n")); 2991 statusByte = UniataSataPhyEnable(HwDeviceExtension, lChannel, deviceNumber); 2992 if(statusByte == IDE_STATUS_WRONG) { 2993 KdPrint2((PRINT_PREFIX "CheckDevice: status %#x (no dev)\n", statusByte)); 2994 UniataForgetDevice(LunExt); 2995 return 0; 2996 } 2997 } 2998 } 2999 3000 if(deviceExtension->HwFlags & UNIATA_AHCI) { 3001 RetVal = LunExt->DeviceFlags; 3002 signatureLow = signatureHigh = 0; // make GCC happy 3003 } else { 3004 // Select the device. 3005 SelectDrive(chan, deviceNumber); 3006 3007 if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) { 3008 //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 2\n")); 3009 return 0; 3010 } 3011 3012 statusByte = WaitOnBaseBusyLong(chan); 3013 3014 GetBaseStatus(chan, statusByte); 3015 if(deviceExtension->HwFlags & UNIATA_SATA) { 3016 UniataSataClearErr(HwDeviceExtension, lChannel, UNIATA_SATA_IGNORE_CONNECT, deviceNumber); 3017 } 3018 3019 KdPrint2((PRINT_PREFIX "CheckDevice: status %#x\n", statusByte)); 3020 if(((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) || 3021 (statusByte & IDE_STATUS_BUSY)) { 3022 KdPrint2((PRINT_PREFIX "CheckDevice: busy => return\n")); 3023 UniataForgetDevice(LunExt); 3024 return 0; 3025 } 3026 3027 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow); 3028 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh); 3029 } 3030 3031 // set default costs 3032 LunExt->RwSwitchCost = REORDER_COST_SWITCH_RW_HDD; 3033 LunExt->RwSwitchMCost = REORDER_MCOST_SWITCH_RW_HDD; 3034 LunExt->SeekBackMCost = REORDER_MCOST_SEEK_BACK_HDD; 3035 LunExt->AtapiReadyWaitDelay = 0; 3036 3037 if(deviceExtension->HwFlags & UNIATA_AHCI) { 3038 if(RetVal & DFLAGS_DEVICE_PRESENT) { 3039 if(IssueIdentify(HwDeviceExtension, 3040 deviceNumber, 3041 lChannel, 3042 (RetVal & DFLAGS_ATAPI_DEVICE) ? IDE_COMMAND_ATAPI_IDENTIFY : IDE_COMMAND_IDENTIFY, 3043 FALSE)) { 3044 // OK 3045 KdPrint2((PRINT_PREFIX "CheckDevice: detected AHCI Device %#x\n", 3046 deviceNumber)); 3047 } else { 3048 //RetVal &= ~DFLAGS_ATAPI_DEVICE; 3049 //LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE; 3050 3051 UniataForgetDevice(LunExt); 3052 RetVal = 0; 3053 } 3054 } 3055 } else 3056 if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) { 3057 3058 KdPrint2((PRINT_PREFIX "CheckDevice: ATAPI signature found\n")); 3059 // ATAPI signature found. 3060 // Issue the ATAPI identify command if this 3061 // is not for the crash dump utility. 3062 try_atapi: 3063 if (!g_Dump) { 3064 3065 // Issue ATAPI packet identify command. 3066 if (IssueIdentify(HwDeviceExtension, 3067 deviceNumber, 3068 lChannel, 3069 IDE_COMMAND_ATAPI_IDENTIFY, FALSE)) { 3070 3071 // Indicate ATAPI device. 3072 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x is ATAPI\n", 3073 deviceNumber)); 3074 3075 RetVal = DFLAGS_DEVICE_PRESENT | DFLAGS_ATAPI_DEVICE; 3076 LunExt->DeviceFlags |= (DFLAGS_DEVICE_PRESENT | DFLAGS_ATAPI_DEVICE); 3077 3078 // some ATAPI devices doesn't work with DPC on CMD-649 3079 // and probably some other controllers 3080 if(deviceExtension->HwFlags & UNIATA_NO_DPC_ATAPI) { 3081 /* CMD 649, ROSB SWK33, ICH4 */ 3082 KdPrint2((PRINT_PREFIX "CheckDevice: UNIATA_NO_DPC_ATAPI\n")); 3083 deviceExtension->UseDpc = FALSE; 3084 } 3085 3086 GetStatus(chan, statusByte); 3087 if (statusByte & IDE_STATUS_ERROR) { 3088 AtapiSoftReset(chan, deviceNumber); 3089 } 3090 3091 } else { 3092 forget_device: 3093 // Indicate no working device. 3094 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x not responding\n", 3095 deviceNumber)); 3096 3097 UniataForgetDevice(LunExt); 3098 RetVal = 0; 3099 } 3100 GetBaseStatus(chan, statusByte); 3101 3102 } 3103 3104 } else { 3105 3106 KdPrint2((PRINT_PREFIX "CheckDevice: IDE device check\n")); 3107 // Issue IDE Identify. If an Atapi device is actually present, the signature 3108 // will be asserted, and the drive will be recognized as such. 3109 if(deviceExtension->DWordIO) { 3110 KdPrint2((PRINT_PREFIX " try 32bit IO\n")); 3111 LunExt->DeviceFlags |= DFLAGS_DWORDIO_ENABLED; 3112 } 3113 if (IssueIdentify(HwDeviceExtension, 3114 deviceNumber, 3115 lChannel, 3116 IDE_COMMAND_IDENTIFY, FALSE)) { 3117 3118 // IDE drive found. 3119 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x is IDE\n", 3120 deviceNumber)); 3121 3122 // Indicate IDE - not ATAPI device. 3123 RetVal = DFLAGS_DEVICE_PRESENT; 3124 LunExt->DeviceFlags |= DFLAGS_DEVICE_PRESENT; 3125 LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE; 3126 } else 3127 if(g_opt_VirtualMachine <= VM_NONE) { 3128 // This can be ATAPI on broken hardware 3129 GetBaseStatus(chan, statusByte); 3130 if(!at_home && UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) { 3131 KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home post IDE\n")); 3132 goto forget_device; 3133 } 3134 KdPrint2((PRINT_PREFIX "CheckDevice: try ATAPI %#x, status %#x\n", 3135 deviceNumber, statusByte)); 3136 goto try_atapi; 3137 } else { 3138 KdPrint2((PRINT_PREFIX "CheckDevice: VM Device %#x not present\n", 3139 deviceNumber)); 3140 } 3141 GetBaseStatus(chan, statusByte); 3142 } 3143 KdPrint2((PRINT_PREFIX "CheckDevice: check status: %sfound\n", RetVal ? "" : "not ")); 3144 return RetVal; 3145 } // end CheckDevice() 3146 3147 3148 /*++ 3149 3150 Routine Description: 3151 3152 This routine is called from AtapiFindXxxController to identify 3153 devices attached to an IDE controller. 3154 3155 Arguments: 3156 3157 HwDeviceExtension - HBA miniport driver's adapter data storage 3158 AtapiOnly - Indicates that routine should return TRUE only if 3159 an ATAPI device is attached to the controller. 3160 3161 Return Value: 3162 3163 TRUE - True if devices found. 3164 3165 --*/ 3166 BOOLEAN 3167 NTAPI 3168 FindDevices( 3169 IN PVOID HwDeviceExtension, 3170 IN ULONG Flags, 3171 IN ULONG Channel 3172 ) 3173 { 3174 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 3175 PHW_CHANNEL chan = &(deviceExtension->chan[Channel]); 3176 PHW_LU_EXTENSION LunExt; 3177 BOOLEAN deviceResponded = FALSE, 3178 skipSetParameters = FALSE; 3179 ULONG waitCount = 10000; 3180 //ULONG deviceNumber; 3181 ULONG i; 3182 UCHAR statusByte; 3183 ULONG max_ldev; 3184 BOOLEAN AtapiOnly = FALSE; 3185 3186 KdPrint2((PRINT_PREFIX "FindDevices:\n")); 3187 3188 // Disable interrupts 3189 AtapiDisableInterrupts(deviceExtension, Channel); 3190 // AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_DISABLE_INTERRUPTS | IDE_DC_A_4BIT ); 3191 3192 // Clear expecting interrupt flag and current SRB field. 3193 UniataExpectChannelInterrupt(chan, FALSE); 3194 // chan->CurrentSrb = NULL; 3195 // max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : IDE_MAX_LUN_PER_CHAN; 3196 max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : deviceExtension->NumberLuns; 3197 KdPrint2((PRINT_PREFIX " max_ldev %d\n", max_ldev)); 3198 3199 // Search for devices. 3200 for (i = 0; i < max_ldev; i++) { 3201 //AtapiDisableInterrupts(deviceExtension, Channel); 3202 if(Flags & UNIATA_FIND_DEV_UNHIDE) { 3203 chan->lun[i]->DeviceFlags &= ~DFLAGS_HIDDEN; 3204 } 3205 deviceResponded |= 3206 (CheckDevice(HwDeviceExtension, Channel, i, TRUE) != 0); 3207 //AtapiEnableInterrupts(deviceExtension, Channel); 3208 } 3209 3210 if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) { 3211 AtapiEnableInterrupts(deviceExtension, Channel); 3212 KdPrint2((PRINT_PREFIX 3213 "FindDevices: returning %d (AHCI)\n", 3214 deviceResponded)); 3215 return deviceResponded; 3216 } 3217 3218 for (i = 0; i < max_ldev; i++) { 3219 LunExt = chan->lun[i]; 3220 3221 if (( LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT) && 3222 !(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) && 3223 !(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) && deviceResponded) { 3224 3225 // This hideous hack is to deal with ESDI devices that return 3226 // garbage geometry in the IDENTIFY data. 3227 // This is ONLY for the crashdump environment as 3228 // these are ESDI devices. 3229 if (LunExt->IdentifyData.SectorsPerTrack == 0x35 && 3230 LunExt->IdentifyData.NumberOfHeads == 0x07) { 3231 3232 KdPrint2((PRINT_PREFIX "FindDevices: Found nasty Compaq ESDI!\n")); 3233 3234 // Change these values to something reasonable. 3235 LunExt->IdentifyData.SectorsPerTrack = 0x34; 3236 LunExt->IdentifyData.NumberOfHeads = 0x0E; 3237 } 3238 3239 if (LunExt->IdentifyData.SectorsPerTrack == 0x35 && 3240 LunExt->IdentifyData.NumberOfHeads == 0x0F) { 3241 3242 KdPrint2((PRINT_PREFIX "FindDevices: Found nasty Compaq ESDI!\n")); 3243 3244 // Change these values to something reasonable. 3245 LunExt->IdentifyData.SectorsPerTrack = 0x34; 3246 LunExt->IdentifyData.NumberOfHeads = 0x0F; 3247 } 3248 3249 3250 if (LunExt->IdentifyData.SectorsPerTrack == 0x36 && 3251 LunExt->IdentifyData.NumberOfHeads == 0x07) { 3252 3253 KdPrint2((PRINT_PREFIX "FindDevices: Found nasty UltraStor ESDI!\n")); 3254 3255 // Change these values to something reasonable. 3256 LunExt->IdentifyData.SectorsPerTrack = 0x3F; 3257 LunExt->IdentifyData.NumberOfHeads = 0x10; 3258 skipSetParameters = TRUE; 3259 } 3260 3261 3262 if (skipSetParameters) 3263 continue; 3264 3265 statusByte = WaitOnBusy(chan); 3266 3267 // Select the device. 3268 SelectDrive(chan, i & 0x01); 3269 GetStatus(chan, statusByte); 3270 3271 if (statusByte & IDE_STATUS_ERROR) { 3272 3273 // Reset the device. 3274 KdPrint2((PRINT_PREFIX 3275 "FindDevices: Resetting controller before SetDriveParameters.\n")); 3276 3277 AtapiHardReset(chan, FALSE, 500 * 1000); 3278 /* 3279 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER ); 3280 chan->last_devsel = -1; 3281 AtapiStallExecution(500 * 1000); 3282 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER); 3283 */ 3284 SelectDrive(chan, i & 0x01); 3285 3286 do { 3287 // Wait for Busy to drop. 3288 AtapiStallExecution(100); 3289 GetStatus(chan, statusByte); 3290 3291 } while ((statusByte & IDE_STATUS_BUSY) && waitCount--); 3292 } 3293 3294 statusByte = WaitOnBusy(chan); 3295 3296 KdPrint2((PRINT_PREFIX 3297 "FindDevices: Status before SetDriveParameters: (%#x) (%#x)\n", 3298 statusByte, 3299 AtapiReadPort1(chan, IDX_IO1_i_DriveSelect))); 3300 3301 GetBaseStatus(chan, statusByte); 3302 3303 // Use the IDENTIFY data to set drive parameters. 3304 if (!SetDriveParameters(HwDeviceExtension,i,Channel)) { 3305 3306 KdPrint2((PRINT_PREFIX 3307 "FindDevices: Set drive parameters for device %d failed\n", 3308 i)); 3309 // Don't use this device as writes could cause corruption. 3310 LunExt->DeviceFlags &= ~DFLAGS_DEVICE_PRESENT; 3311 UniataForgetDevice(LunExt); 3312 continue; 3313 3314 } 3315 if (LunExt->DeviceFlags & DFLAGS_REMOVABLE_DRIVE) { 3316 3317 // Pick up ALL IDE removable drives that conform to Yosemite V0.2... 3318 AtapiOnly = FALSE; 3319 } 3320 3321 // Indicate that a device was found. 3322 if (!AtapiOnly) { 3323 deviceResponded = TRUE; 3324 } 3325 } 3326 } 3327 3328 /* // Reset the controller. This is a feeble attempt to leave the ESDI 3329 // controllers in a state that ATDISK driver will recognize them. 3330 // The problem in ATDISK has to do with timings as it is not reproducible 3331 // in debug. The reset should restore the controller to its poweron state 3332 // and give the system enough time to settle. 3333 if (!deviceResponded) { 3334 3335 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_RESET_CONTROLLER ); 3336 AtapiStallExecution(50 * 1000); 3337 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_REENABLE_CONTROLLER); 3338 } 3339 */ 3340 if(deviceResponded) { 3341 for (i = 0; i < max_ldev; i++) { 3342 LunExt = chan->lun[i]; 3343 3344 KdPrint2((PRINT_PREFIX 3345 "FindDevices: select %d dev to clear INTR\n", i)); 3346 SelectDrive(chan, i); 3347 GetBaseStatus(chan, statusByte); 3348 KdPrint2((PRINT_PREFIX 3349 "FindDevices: statusByte=%#x\n", statusByte)); 3350 } 3351 for (i = 0; i < max_ldev; i++) { 3352 LunExt = chan->lun[i]; 3353 3354 if(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT) { 3355 // Make sure some device (master is preferred) is selected on exit. 3356 KdPrint2((PRINT_PREFIX 3357 "FindDevices: select %d dev on exit\n", i)); 3358 SelectDrive(chan, i); 3359 break; 3360 } 3361 } 3362 } 3363 3364 GetBaseStatus(chan, statusByte); 3365 // Enable interrupts 3366 AtapiEnableInterrupts(deviceExtension, Channel); 3367 // AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_A_4BIT ); 3368 GetBaseStatus(chan, statusByte); 3369 3370 KdPrint2((PRINT_PREFIX 3371 "FindDevices: returning %d\n", 3372 deviceResponded)); 3373 3374 return deviceResponded; 3375 3376 } // end FindDevices() 3377