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