Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenid_probe.cpp
Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 2002-2011 Alexandr A. Telyatnikov (Alter) 00004 00005 Module Name: 00006 id_probe.cpp 00007 00008 Abstract: 00009 This module scans PCI and ISA buses for IDE controllers 00010 and determines their Busmaster DMA capabilities 00011 00012 Author: 00013 Alexander A. Telyatnikov (Alter) 00014 00015 Environment: 00016 kernel mode only 00017 00018 Notes: 00019 00020 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00021 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00022 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00023 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00024 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00025 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00026 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00027 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00029 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 00031 Revision History: 00032 00033 Some parts of hardware-specific code were taken from FreeBSD 4.3-6.1 ATA driver by 00034 Søren Schmidt, Copyright (c) 1998-2007 00035 00036 Some parts of device detection code were taken from from standard ATAPI.SYS from NT4 DDK by 00037 Mike Glass (MGlass) 00038 Chuck Park (ChuckP) 00039 00040 Device search/init algorithm is completly rewritten by 00041 Alter, Copyright (c) 2002-2004 00042 00043 Fixes for Native/Compatible modes of onboard IDE controller by 00044 Vitaliy Vorobyov, deathsoft@yandex.ru (c) 2004 00045 00046 --*/ 00047 00048 #include "stdafx.h" 00049 00050 PBUSMASTER_CONTROLLER_INFORMATION BMList = NULL; 00051 ULONG BMListLen = 0; 00052 ULONG IsaCount = 0; 00053 ULONG MCACount = 0; 00054 00055 BOOLEAN FirstMasterOk = FALSE; 00056 00057 #ifndef UNIATA_CORE 00058 00059 UCHAR pciBuffer[256]; 00060 ULONG maxPciBus = 16; 00061 00062 PDRIVER_OBJECT SavedDriverObject = NULL; 00063 00064 // local routines 00065 00066 ULONG 00067 NTAPI 00068 UniataEnumBusMasterController__( 00069 /* IN PVOID HwDeviceExtension, 00070 IN PVOID Context, 00071 IN PVOID BusInformation, 00072 IN PCHAR ArgumentString, 00073 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, 00074 OUT PBOOLEAN Again*/ 00075 ); 00076 00077 VOID 00078 NTAPI 00079 AtapiDoNothing(VOID) 00080 { 00081 return; 00082 } // end AtapiDoNothing() 00083 00084 #endif //UNIATA_CORE 00085 00086 /* 00087 Get PCI address by ConfigInfo and RID 00088 */ 00089 ULONG 00090 NTAPI 00091 AtapiGetIoRange( 00092 IN PVOID HwDeviceExtension, 00093 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, 00094 IN PPCI_COMMON_CONFIG pciData, 00095 IN ULONG SystemIoBusNumber, 00096 IN ULONG rid, //range id 00097 IN ULONG offset, 00098 IN ULONG length 00099 ) 00100 { 00101 ULONGIO_PTR io_start = 0; 00102 KdPrint2((PRINT_PREFIX " AtapiGetIoRange:\n")); 00103 00104 if(ConfigInfo->NumberOfAccessRanges <= rid) 00105 return 0; 00106 00107 KdPrint2((PRINT_PREFIX " AtapiGetIoRange: rid %#x, start %#x, offs %#x, len %#x, mem %#x\n", 00108 rid, 00109 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[rid].RangeStart), 00110 offset, 00111 length, 00112 (*ConfigInfo->AccessRanges)[rid].RangeInMemory 00113 )); 00114 00115 if((*ConfigInfo->AccessRanges)[rid].RangeInMemory) { 00116 io_start = 00117 // Get the system physical address for this IO range. 00118 ((ULONG_PTR)ScsiPortGetDeviceBase(HwDeviceExtension, 00119 PCIBus /*ConfigInfo->AdapterInterfaceType*/, 00120 SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/, 00121 ScsiPortConvertUlongToPhysicalAddress( 00122 (ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[rid].RangeStart) & 00123 ~0x07/*PCI_ADDRESS_IOMASK*/) + offset 00124 ), 00125 length, 00126 (BOOLEAN)!(*ConfigInfo->AccessRanges)[rid].RangeInMemory) 00127 ); 00128 00129 KdPrint2((PRINT_PREFIX " AtapiGetIoRange: %#x\n", io_start)); 00130 // if(io_start > offset) { 00131 return io_start; 00132 // } 00133 } 00134 00135 io_start = (pciData->u.type0.BaseAddresses[rid] & ~0x07/*PCI_ADDRESS_IOMASK*/) + offset; 00136 // if(pciData->u.type0.BaseAddresses[rid] != 0) ;) 00137 if(io_start > offset) { 00138 if(/*(WinVer_Id() <= WinVer_NT) &&*/ offset && rid == 4) { 00139 // MS atapi.sys does so for BusMaster controllers 00140 (*ConfigInfo->AccessRanges)[rid+1].RangeStart = 00141 ScsiPortConvertUlongToPhysicalAddress(io_start); 00142 (*ConfigInfo->AccessRanges)[rid+1].RangeLength = length; 00143 } else { 00144 (*ConfigInfo->AccessRanges)[rid].RangeStart = 00145 ScsiPortConvertUlongToPhysicalAddress(io_start); 00146 (*ConfigInfo->AccessRanges)[rid].RangeLength = length; 00147 } 00148 if((pciData->u.type0.BaseAddresses[rid] & PCI_ADDRESS_IO_SPACE)) { 00149 (*ConfigInfo->AccessRanges)[rid].RangeInMemory = FALSE; 00150 } else { 00151 (*ConfigInfo->AccessRanges)[rid].RangeInMemory = TRUE; 00152 } 00153 } else { 00154 io_start = 0; 00155 } 00156 KdPrint2((PRINT_PREFIX " AtapiGetIoRange: (2) %#x\n", io_start)); 00157 return io_start; 00158 00159 } // end AtapiGetIoRange() 00160 00161 #ifndef UNIATA_CORE 00162 00163 /* 00164 Do nothing, but build list of supported IDE controllers 00165 It is a hack, ScsiPort architecture assumes, that DriverEntry 00166 can support only KNOWN Vendor/Device combinations. 00167 Thus, we build list here. Later will pretend that always knew 00168 about found devices. 00169 00170 We shall initiate ISA device init, but callback will use 00171 Hal routines directly in order to scan PCI bus. 00172 */ 00173 VOID 00174 NTAPI 00175 UniataEnumBusMasterController( 00176 IN PVOID DriverObject, 00177 PVOID Argument2 00178 ) 00179 { 00180 UniataEnumBusMasterController__(); 00181 00182 } // end UniataEnumBusMasterController() 00183 00184 BOOLEAN 00185 NTAPI 00186 UniataCheckPCISubclass( 00187 BOOLEAN known, 00188 ULONG RaidFlags, 00189 UCHAR SubClass 00190 ) 00191 { 00192 if(known) { 00193 if((RaidFlags & UNIATA_RAID_CONTROLLER) && 00194 SkipRaids) { 00195 KdPrint2((PRINT_PREFIX "Skip RAID\n")); 00196 return FALSE; 00197 } 00198 return TRUE; 00199 } 00200 KdPrint2((PRINT_PREFIX "unknown\n")); 00201 00202 switch(SubClass) { 00203 case PCI_DEV_SUBCLASS_RAID: 00204 if(SkipRaids) { 00205 KdPrint2((PRINT_PREFIX "Skip RAID (2)\n")); 00206 return FALSE; 00207 } 00208 break; 00209 case PCI_DEV_SUBCLASS_IDE: 00210 case PCI_DEV_SUBCLASS_ATA: 00211 break; 00212 case PCI_DEV_SUBCLASS_SATA: 00213 break; 00214 default: 00215 KdPrint2((PRINT_PREFIX "Subclass not supported\n")); 00216 return FALSE; 00217 } 00218 return TRUE; 00219 } // end UniataCheckPCISubclass() 00220 00221 /* 00222 Device initializaton callback 00223 Builds PCI device list using Hal routines (not ScsiPort wrappers) 00224 */ 00225 ULONG 00226 NTAPI 00227 UniataEnumBusMasterController__( 00228 ) 00229 { 00230 // PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 00231 PVOID HwDeviceExtension; 00232 PHW_DEVICE_EXTENSION deviceExtension = NULL; 00233 PCI_SLOT_NUMBER slotData; 00234 PCI_COMMON_CONFIG pciData; 00235 ULONG busNumber; 00236 ULONG slotNumber; 00237 ULONG funcNumber; 00238 BOOLEAN no_buses = FALSE; 00239 BOOLEAN no_ranges = FALSE; 00240 ULONG busDataRead; 00241 // BOOLEAN SimplexOnly; 00242 00243 UCHAR vendorString[5]; 00244 UCHAR deviceString[5]; 00245 PUCHAR vendorStrPtr; 00246 PUCHAR deviceStrPtr; 00247 00248 UCHAR BaseClass; // (ro) 00249 UCHAR SubClass; // (ro) 00250 ULONG VendorID; 00251 ULONG DeviceID; 00252 ULONG dev_id; 00253 00254 USHORT SubVendorID; 00255 USHORT SubSystemID; 00256 00257 ULONG i; 00258 ULONG pass=0; 00259 00260 ULONG RaidFlags; 00261 00262 BOOLEAN found; 00263 BOOLEAN known; 00264 BOOLEAN NeedPciAltInit; 00265 00266 UCHAR IrqForCompat = 10; 00267 00268 vendorStrPtr = vendorString; 00269 deviceStrPtr = deviceString; 00270 slotData.u.AsULONG = 0; 00271 00272 HwDeviceExtension = 00273 deviceExtension = (PHW_DEVICE_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(HW_DEVICE_EXTENSION)); 00274 if(!deviceExtension) { 00275 return(SP_RETURN_NOT_FOUND); 00276 } 00277 RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION)); 00278 00279 for(pass=0; pass<3; pass++) { 00280 for(busNumber=0 ;busNumber<maxPciBus && !no_buses; busNumber++) { 00281 for(slotNumber=0; slotNumber<PCI_MAX_DEVICES && !no_buses; slotNumber++) { 00282 NeedPciAltInit = FALSE; 00283 for(funcNumber=0; funcNumber<PCI_MAX_FUNCTION && !no_buses; funcNumber++) { 00284 00285 // KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x\n",busNumber,slotNumber,funcNumber)); 00286 slotData.u.bits.DeviceNumber = slotNumber; 00287 slotData.u.bits.FunctionNumber = funcNumber; 00288 00289 busDataRead = HalGetBusData 00290 //ScsiPortGetBusData 00291 ( 00292 //HwDeviceExtension, 00293 PCIConfiguration, busNumber, slotData.u.AsULONG, 00294 &pciData, PCI_COMMON_HDR_LENGTH); 00295 // no more buses 00296 if(!busDataRead) { 00297 no_buses = TRUE; 00298 maxPciBus = busNumber; 00299 break; 00300 } 00301 // no device in this slot 00302 if(busDataRead == 2) { 00303 NeedPciAltInit = TRUE; 00304 continue; 00305 } 00306 00307 if(busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) { 00308 NeedPciAltInit = TRUE; 00309 continue; 00310 } 00311 00312 VendorID = pciData.VendorID; 00313 DeviceID = pciData.DeviceID; 00314 BaseClass = pciData.BaseClass; 00315 SubClass = pciData.SubClass; 00316 dev_id = VendorID | (DeviceID << 16); 00317 00318 SubVendorID = pciData.u.type0.SubVendorID; 00319 SubSystemID = pciData.u.type0.SubSystemID; 00320 00321 00322 //KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass )); 00323 00324 if(VendorID == 0x80ee && DeviceID == 0xcafe) { 00325 KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x - VirtualBox Guest Service\n",busNumber,slotNumber,funcNumber)); 00326 if(g_opt_VirtualMachine == VM_AUTO) { 00327 g_opt_VirtualMachine = VM_VBOX; 00328 } 00329 //continue; 00330 } else 00331 if((VendorID == 0x15ad) || 00332 (SubVendorID == 0x15ad && SubSystemID == 0x1976)) { 00333 KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x - VMWare\n",busNumber,slotNumber,funcNumber)); 00334 if(g_opt_VirtualMachine == VM_AUTO) { 00335 g_opt_VirtualMachine = VM_VMWARE; 00336 } 00337 //g_opt_VirtualBox = TRUE; 00338 } else 00339 if(SubVendorID == 0x1af4 && SubSystemID == 0x1100) { 00340 KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x - QEmu\n",busNumber,slotNumber,funcNumber)); 00341 if(g_opt_VirtualMachine == VM_AUTO) { 00342 g_opt_VirtualMachine = VM_QEMU; 00343 } 00344 } 00345 00346 00347 if(BaseClass != PCI_DEV_CLASS_STORAGE) { 00348 continue; 00349 } 00350 00351 KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x\n",busNumber,slotNumber,funcNumber)); 00352 KdPrint2((PRINT_PREFIX "Storage Class\n")); 00353 KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass )); 00354 // look for known chipsets 00355 found = FALSE; 00356 known = FALSE; 00357 00358 if(deviceExtension) { 00359 deviceExtension->slotNumber = slotData.u.AsULONG; 00360 deviceExtension->SystemIoBusNumber = busNumber; 00361 deviceExtension->DevID = dev_id; 00362 deviceExtension->RevID = pciData.RevisionID; 00363 deviceExtension->AdapterInterfaceType = PCIBus; 00364 } 00365 00366 found = (BOOLEAN)AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Include", 0); 00367 if(!found) { 00368 KdPrint2((PRINT_PREFIX "No force include, check exclude\n")); 00369 found = !AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Exclude", 0); 00370 if(!found) { 00371 KdPrint2((PRINT_PREFIX "Device excluded\n")); 00372 continue; 00373 } 00374 } 00375 00376 //known = UniataChipDetect(HwDeviceExtension, NULL, -1, ConfigInfo, &SimplexOnly); 00377 i = Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION)&BusMasterAdapters[0], VendorID, DeviceID, 0, NUM_BUSMASTER_ADAPTERS); 00378 00379 known = (i != BMLIST_TERMINATOR); 00380 if(known) { 00381 deviceExtension->FullDevName = BusMasterAdapters[i].FullDevName; 00382 RaidFlags = BusMasterAdapters[i].RaidFlags; 00383 } else { 00384 deviceExtension->FullDevName = "Unknown Storage"; 00385 RaidFlags = 0; 00386 } 00387 found = UniataCheckPCISubclass(known, RaidFlags, SubClass); 00388 if(!found) { 00389 KdPrint2((PRINT_PREFIX "Subclass not supported\n")); 00390 continue; 00391 } 00392 00393 switch(dev_id) { 00394 /* additional checks for some supported chipsets */ 00395 case 0xc6931080: 00396 if (SubClass != PCI_DEV_SUBCLASS_IDE) 00397 found = FALSE; 00398 break; 00399 00400 /* unknown chipsets, try generic DMA if it seems possible */ 00401 default: 00402 KdPrint2((PRINT_PREFIX "Default device\n")); 00403 if(Ata_is_supported_dev(&pciData) || 00404 Ata_is_ahci_dev(&pciData)) 00405 found = TRUE; 00406 break; 00407 } 00408 00409 if(found) { 00410 00411 KdPrint2((PRINT_PREFIX "found, pass %d\n", pass)); 00412 00413 KdPrint2((PRINT_PREFIX "InterruptPin = %#x\n", pciData.u.type0.InterruptPin)); 00414 KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine)); 00415 00416 if(!pass && known) { 00417 // Enable Busmastering, IO-space and Mem-space 00418 KdPrint2((PRINT_PREFIX "Enabling Mem/Io spaces and busmastering...\n")); 00419 KdPrint2((PRINT_PREFIX "Initial pciData.Command = %#x\n", pciData.Command)); 00420 for(i=0; i<3; i++) { 00421 switch(i) { 00422 case 0: 00423 KdPrint2((PRINT_PREFIX "PCI_ENABLE_IO_SPACE\n")); 00424 pciData.Command |= PCI_ENABLE_IO_SPACE; 00425 break; 00426 case 1: 00427 KdPrint2((PRINT_PREFIX "PCI_ENABLE_MEMORY_SPACE\n")); 00428 pciData.Command |= PCI_ENABLE_MEMORY_SPACE; 00429 break; 00430 case 2: 00431 KdPrint2((PRINT_PREFIX "PCI_ENABLE_BUS_MASTER\n")); 00432 pciData.Command |= PCI_ENABLE_BUS_MASTER; 00433 break; 00434 } 00435 HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG, 00436 &(pciData.Command), 00437 offsetof(PCI_COMMON_CONFIG, Command), 00438 sizeof(pciData.Command)); 00439 KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine)); 00440 00441 // reread config space 00442 busDataRead = HalGetBusData(PCIConfiguration, busNumber, slotData.u.AsULONG, 00443 &pciData, PCI_COMMON_HDR_LENGTH); 00444 KdPrint2((PRINT_PREFIX "New pciData.Command = %#x\n", pciData.Command)); 00445 } 00446 KdPrint2((PRINT_PREFIX "Final pciData.Command = %#x\n", pciData.Command)); 00447 } 00448 // validate Mem/Io ranges 00449 no_ranges = TRUE; 00450 for(i=0; i<PCI_TYPE0_ADDRESSES; i++) { 00451 if(pciData.u.type0.BaseAddresses[i] & ~0x7) { 00452 no_ranges = FALSE; 00453 //break; 00454 KdPrint2((PRINT_PREFIX "Range %d = %#x\n", i, pciData.u.type0.BaseAddresses[i])); 00455 } 00456 } 00457 if(no_ranges) { 00458 KdPrint2((PRINT_PREFIX "No PCI Mem/Io ranges found on device, skip it\n")); 00459 continue; 00460 } 00461 00462 if(pass) { 00463 // fill list of detected devices 00464 // it'll be used for further init 00465 KdPrint2((PRINT_PREFIX "found suitable device\n")); 00466 PBUSMASTER_CONTROLLER_INFORMATION newBMListPtr = BMList+BMListLen; 00467 00468 if(pass == 1) { 00469 if(!IsMasterDev(&pciData)) { 00470 continue; 00471 } 00472 if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"NativePCIMode", 0)) { 00473 KdPrint2((PRINT_PREFIX "try switch to native mode\n")); 00474 00475 IrqForCompat = (UCHAR)AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"NativePCIModeIRQ", 0xff); 00476 KdPrint2((PRINT_PREFIX "IrqForCompat = %#x\n", IrqForCompat)); 00477 if((IrqForCompat & 0xffffff00) /*|| 00478 (IrqForCompat & 0xff) > 31*/ || 00479 (IrqForCompat == 0xff)) { 00480 IrqForCompat = 0x0b; 00481 KdPrint2((PRINT_PREFIX "default to IRQ 11\n")); 00482 } 00483 00484 //ChangePciConfig1(0x09, a | PCI_IDE_PROGIF_NATIVE_ALL); // ProgIf 00485 pciData.ProgIf |= PCI_IDE_PROGIF_NATIVE_ALL; 00486 HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG, 00487 &(pciData.ProgIf), 00488 offsetof(PCI_COMMON_CONFIG, ProgIf), 00489 sizeof(pciData.ProgIf)); 00490 00491 // reread config space 00492 busDataRead = HalGetBusData(PCIConfiguration, busNumber, slotData.u.AsULONG, 00493 &pciData, PCI_COMMON_HDR_LENGTH); 00494 // check if the device have switched to Native Mode 00495 if(IsMasterDev(&pciData)) { 00496 KdPrint2((PRINT_PREFIX "Can't switch to native mode\n")); 00497 } else { 00498 KdPrint2((PRINT_PREFIX "switched to native mode\n")); 00499 KdPrint2((PRINT_PREFIX "InterruptPin = %#x\n", pciData.u.type0.InterruptPin)); 00500 KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine)); 00501 // check if IRQ is assigned to device 00502 if(!(pciData.u.type0.InterruptLine) || 00503 (pciData.u.type0.InterruptLine == 0xff)) { 00504 KdPrint2((PRINT_PREFIX "assign interrupt for device\n")); 00505 pciData.u.type0.InterruptLine = IrqForCompat; 00506 HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG, 00507 &(pciData.u.type0.InterruptLine), 00508 offsetof(PCI_COMMON_CONFIG, u.type0.InterruptLine), 00509 sizeof(pciData.u.type0.InterruptLine)); 00510 } else { 00511 KdPrint2((PRINT_PREFIX "Auto-assigned interrupt line %#x\n", 00512 pciData.u.type0.InterruptLine)); 00513 IrqForCompat = pciData.u.type0.InterruptLine; 00514 } 00515 KdPrint2((PRINT_PREFIX "reread config space\n")); 00516 // reread config space 00517 busDataRead = HalGetBusData(PCIConfiguration, busNumber, slotData.u.AsULONG, 00518 &pciData, PCI_COMMON_HDR_LENGTH); 00519 KdPrint2((PRINT_PREFIX "busDataRead = %#x\n", busDataRead)); 00520 KdPrint2((PRINT_PREFIX "reread InterruptLine = %#x\n", pciData.u.type0.InterruptLine)); 00521 // check if we have successfully assigned IRQ to device 00522 if((pciData.u.type0.InterruptLine != IrqForCompat) || 00523 (pciData.u.type0.InterruptLine == 0xff) || 00524 !pciData.u.type0.InterruptLine) { 00525 KdPrint2((PRINT_PREFIX "can't assign interrupt for device, revert to compat mode\n")); 00526 pciData.u.type0.InterruptLine = 0xff; 00527 KdPrint2((PRINT_PREFIX "set IntrLine to 0xff\n")); 00528 HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG, 00529 &(pciData.u.type0.InterruptLine), 00530 offsetof(PCI_COMMON_CONFIG, u.type0.InterruptLine), 00531 sizeof(pciData.u.type0.InterruptLine)); 00532 KdPrint2((PRINT_PREFIX "clear PCI_IDE_PROGIF_NATIVE_ALL\n")); 00533 pciData.ProgIf &= ~PCI_IDE_PROGIF_NATIVE_ALL; 00534 HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG, 00535 &(pciData.ProgIf), 00536 offsetof(PCI_COMMON_CONFIG, ProgIf), 00537 sizeof(pciData.ProgIf)); 00538 // reread config space 00539 KdPrint2((PRINT_PREFIX "reread config space on revert\n")); 00540 busDataRead = HalGetBusData(PCIConfiguration, busNumber, slotData.u.AsULONG, 00541 &pciData, PCI_COMMON_HDR_LENGTH); 00542 } else { 00543 KdPrint2((PRINT_PREFIX "Assigned interrupt %#x for device\n", IrqForCompat)); 00544 KdPrint2((PRINT_PREFIX "continue detection on next round\n")); 00545 continue; 00546 } 00547 } 00548 } 00549 } else 00550 if(pass == 2) { 00551 if(IsMasterDev(&pciData)) 00552 continue; 00553 } 00554 00555 /* if(known) { 00556 RtlCopyMemory(newBMListPtr, (PVOID)&(BusMasterAdapters[i]), sizeof(BUSMASTER_CONTROLLER_INFORMATION)); 00557 } else {*/ 00558 sprintf((PCHAR)vendorStrPtr, "%4.4lx", VendorID); 00559 sprintf((PCHAR)deviceStrPtr, "%4.4lx", DeviceID); 00560 00561 RtlCopyMemory(&(newBMListPtr->VendorIdStr), (PCHAR)vendorStrPtr, 4); 00562 RtlCopyMemory(&(newBMListPtr->DeviceIdStr), (PCHAR)deviceStrPtr, 4); 00563 00564 newBMListPtr->nVendorId = VendorID; 00565 newBMListPtr->VendorId = (PCHAR)&(newBMListPtr->VendorIdStr); 00566 newBMListPtr->VendorIdLength = 4; 00567 newBMListPtr->nDeviceId = DeviceID; 00568 newBMListPtr->DeviceId = (PCHAR)&(newBMListPtr->DeviceIdStr); 00569 newBMListPtr->DeviceIdLength = 4; 00570 00571 newBMListPtr->RaidFlags = RaidFlags; 00572 // } 00573 newBMListPtr->slotNumber = slotData.u.AsULONG; 00574 newBMListPtr->MasterDev = IsMasterDev(&pciData) ? 1 : 0; 00575 newBMListPtr->busNumber = busNumber; 00576 00577 newBMListPtr->NeedAltInit = NeedPciAltInit; 00578 newBMListPtr->Known = known; 00579 00580 KdPrint2((PRINT_PREFIX "Add to BMList, AltInit %d\n", NeedPciAltInit)); 00581 } else { 00582 KdPrint2((PRINT_PREFIX "count: BMListLen++\n")); 00583 } 00584 00585 BMListLen++; 00586 } 00587 } 00588 } 00589 } 00590 if(!pass) { 00591 if(!BMListLen) 00592 break; 00593 BMList = (PBUSMASTER_CONTROLLER_INFORMATION)ExAllocatePool(NonPagedPool, 00594 (BMListLen+1)*sizeof(BUSMASTER_CONTROLLER_INFORMATION)); 00595 if(!BMList) { 00596 BMListLen=0; 00597 break; 00598 } 00599 RtlZeroMemory(BMList, (BMListLen+1)*sizeof(BUSMASTER_CONTROLLER_INFORMATION)); 00600 no_buses = FALSE; 00601 BMListLen=0; 00602 } 00603 } 00604 KdPrint2((PRINT_PREFIX " BMListLen=%x\n", BMListLen)); 00605 if(deviceExtension) { 00606 ExFreePool(deviceExtension); 00607 } 00608 return(SP_RETURN_NOT_FOUND); 00609 } // end UniataEnumBusMasterController__() 00610 00611 00612 /* 00613 Wrapper for read PCI config space 00614 */ 00615 ULONG 00616 NTAPI 00617 ScsiPortGetBusDataByOffset( 00618 IN PVOID HwDeviceExtension, 00619 IN BUS_DATA_TYPE BusDataType, 00620 IN ULONG BusNumber, 00621 IN ULONG SlotNumber, 00622 IN PVOID Buffer, 00623 IN ULONG Offset, 00624 IN ULONG Length 00625 ) 00626 { 00627 UCHAR tmp[256]; 00628 ULONG busDataRead; 00629 00630 if(Offset+Length > 256) 00631 return 0; 00632 00633 busDataRead = HalGetBusData( 00634 //ScsiPortGetBusData(HwDeviceExtension, 00635 BusDataType, 00636 BusNumber, 00637 SlotNumber, 00638 &tmp, 00639 Offset+Length); 00640 if(busDataRead < Offset+Length) { 00641 if(busDataRead < Offset) 00642 return 0; 00643 return (Offset+Length-busDataRead); 00644 } 00645 RtlCopyMemory(Buffer, tmp+Offset, Length); 00646 return Length; 00647 } // end ScsiPortGetBusDataByOffset() 00648 00649 /* 00650 Looks for devices from list on specified bus(es)/slot(s) 00651 returnts its index in list. 00652 If no matching record found, -1 is returned 00653 */ 00654 ULONG 00655 NTAPI 00656 AtapiFindListedDev( 00657 PBUSMASTER_CONTROLLER_INFORMATION BusMasterAdapters, 00658 ULONG lim, 00659 IN PVOID HwDeviceExtension, 00660 IN ULONG BusNumber, 00661 IN ULONG SlotNumber, 00662 OUT PCI_SLOT_NUMBER* _slotData // optional 00663 ) 00664 { 00665 PCI_SLOT_NUMBER slotData; 00666 PCI_COMMON_CONFIG pciData; 00667 ULONG busDataRead; 00668 00669 ULONG busNumber; 00670 ULONG slotNumber; 00671 ULONG funcNumber; 00672 00673 ULONG busNumber2; 00674 ULONG slotNumber2; 00675 00676 ULONG i; 00677 00678 KdPrint2((PRINT_PREFIX "AtapiFindListedDev: lim=%x, Bus=%x, Slot=%x\n", lim, BusNumber, SlotNumber)); 00679 00680 // set start/end bus 00681 if(BusNumber == PCIBUSNUM_NOT_SPECIFIED) { 00682 busNumber = 0; 00683 busNumber2 = maxPciBus; 00684 } else { 00685 busNumber = BusNumber; 00686 busNumber2 = BusNumber+1; 00687 } 00688 // set start/end slot 00689 if(SlotNumber == PCISLOTNUM_NOT_SPECIFIED) { 00690 slotNumber = 0; 00691 slotNumber2 = PCI_MAX_DEVICES; 00692 } else { 00693 slotNumber = SlotNumber; 00694 slotNumber2 = SlotNumber+1; 00695 } 00696 slotData.u.AsULONG = 0; 00697 00698 KdPrint2((PRINT_PREFIX " scanning range Bus %x-%x, Slot %x-%x\n", busNumber, busNumber2-1, slotNumber, slotNumber2-1)); 00699 00700 for( ; busNumber < busNumber2 ; busNumber++ ) { 00701 for( ; slotNumber < slotNumber2 ; slotNumber++) { 00702 for(funcNumber=0; funcNumber < PCI_MAX_FUNCTION ; funcNumber++) { 00703 00704 slotData.u.bits.DeviceNumber = slotNumber; 00705 slotData.u.bits.FunctionNumber = funcNumber; 00706 00707 busDataRead = HalGetBusData( 00708 //ScsiPortGetBusData(HwDeviceExtension, 00709 PCIConfiguration, busNumber, slotData.u.AsULONG, 00710 &pciData, PCI_COMMON_HDR_LENGTH); 00711 // no more buses (this should not happen) 00712 if(!busDataRead) { 00713 continue; 00714 } 00715 // no device in this slot 00716 if(busDataRead == 2) 00717 continue; 00718 00719 if(busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) 00720 continue; 00721 /* 00722 KdPrint2((PRINT_PREFIX "AtapiFindListedDev: b:s:f(%x:%x:%x) %4.4x/%4.4x/%2.2x\n", 00723 busNumber, slotNumber, funcNumber, 00724 pciData.VendorID, pciData.DeviceID, pciData.RevisionID)); 00725 */ 00726 i = Ata_is_dev_listed(BusMasterAdapters, pciData.VendorID, pciData.DeviceID, pciData.RevisionID, lim); 00727 if(i != BMLIST_TERMINATOR) { 00728 if(_slotData) 00729 *_slotData = slotData; 00730 KdPrint2((PRINT_PREFIX "AtapiFindListedDev: found\n")); 00731 KdPrint2((PRINT_PREFIX "AtapiFindListedDev: b:s:f(%x:%x:%x) %4.4x/%4.4x/%2.2x\n", 00732 busNumber, slotNumber, funcNumber, 00733 pciData.VendorID, pciData.DeviceID, pciData.RevisionID)); 00734 return i; 00735 } 00736 00737 }}} 00738 return -1; 00739 } // end AtapiFindListedDev() 00740 00741 /* 00742 Looks for device with specified Device/Vendor and Revision 00743 on specified Bus/Slot 00744 */ 00745 ULONG 00746 NTAPI 00747 AtapiFindDev( 00748 IN PVOID HwDeviceExtension, 00749 IN BUS_DATA_TYPE BusDataType, 00750 IN ULONG BusNumber, 00751 IN ULONG SlotNumber, 00752 IN ULONG dev_id, 00753 IN ULONG RevID 00754 ) 00755 { 00756 PCI_COMMON_CONFIG pciData; 00757 ULONG funcNumber; 00758 ULONG busDataRead; 00759 00760 ULONG VendorID; 00761 ULONG DeviceID; 00762 PCI_SLOT_NUMBER slotData; 00763 00764 slotData.u.AsULONG = SlotNumber; 00765 // walk through all Function Numbers 00766 for(funcNumber = 0; funcNumber < PCI_MAX_FUNCTION; funcNumber++) { 00767 00768 slotData.u.bits.FunctionNumber = funcNumber; 00769 if(slotData.u.AsULONG == SlotNumber) 00770 continue; 00771 00772 busDataRead = HalGetBusData( 00773 //busDataRead = ScsiPortGetBusData(HwDeviceExtension, 00774 PCIConfiguration, 00775 BusNumber, 00776 slotData.u.AsULONG, 00777 &pciData, 00778 PCI_COMMON_HDR_LENGTH); 00779 00780 if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) { 00781 continue; 00782 } 00783 00784 VendorID = pciData.VendorID; 00785 DeviceID = pciData.DeviceID; 00786 00787 if(dev_id != (VendorID | (DeviceID << 16)) ) 00788 continue; 00789 if(RevID >= pciData.RevisionID) 00790 return 1; 00791 } 00792 return 0; 00793 } // end AtapiFindDev() 00794 00795 #endif //UNIATA_CORE 00796 00797 00798 ULONG 00799 NTAPI 00800 UniataFindCompatBusMasterController1( 00801 IN PVOID HwDeviceExtension, 00802 IN PVOID Context, 00803 IN PVOID BusInformation, 00804 IN PCHAR ArgumentString, 00805 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, 00806 OUT PBOOLEAN Again 00807 ) 00808 { 00809 return UniataFindBusMasterController( 00810 HwDeviceExtension, 00811 (PVOID)0x00000000, 00812 BusInformation, 00813 ArgumentString, 00814 ConfigInfo, 00815 Again 00816 ); 00817 } // end UniataFindCompatBusMasterController1() 00818 00819 ULONG 00820 NTAPI 00821 UniataFindCompatBusMasterController2( 00822 IN PVOID HwDeviceExtension, 00823 IN PVOID Context, 00824 IN PVOID BusInformation, 00825 IN PCHAR ArgumentString, 00826 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, 00827 OUT PBOOLEAN Again 00828 ) 00829 { 00830 return UniataFindBusMasterController( 00831 HwDeviceExtension, 00832 (PVOID)0x80000000, 00833 BusInformation, 00834 ArgumentString, 00835 ConfigInfo, 00836 Again 00837 ); 00838 } // end UniataFindCompatBusMasterController2() 00839 00840 BOOLEAN 00841 NTAPI 00842 UniataAllocateLunExt( 00843 PHW_DEVICE_EXTENSION deviceExtension, 00844 ULONG NewNumberChannels 00845 ) 00846 { 00847 PHW_LU_EXTENSION old_luns = NULL; 00848 PHW_CHANNEL old_chans = NULL; 00849 00850 KdPrint2((PRINT_PREFIX "allocate Luns for %d channels\n", deviceExtension->NumberChannels)); 00851 00852 old_luns = deviceExtension->lun; 00853 old_chans = deviceExtension->chan; 00854 00855 if(old_luns || old_chans) { 00856 if(NewNumberChannels == UNIATA_ALLOCATE_NEW_LUNS) { 00857 KdPrint2((PRINT_PREFIX "already allocated!\n")); 00858 return FALSE; 00859 } 00860 } 00861 00862 if(!deviceExtension->NumberLuns) { 00863 KdPrint2((PRINT_PREFIX "default NumberLuns=2\n")); 00864 deviceExtension->NumberLuns = 2; 00865 } 00866 00867 deviceExtension->lun = (PHW_LU_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(HW_LU_EXTENSION) * (deviceExtension->NumberChannels+1) * deviceExtension->NumberLuns); 00868 if (!deviceExtension->lun) { 00869 KdPrint2((PRINT_PREFIX "!deviceExtension->lun => SP_RETURN_ERROR\n")); 00870 return FALSE; 00871 } 00872 RtlZeroMemory(deviceExtension->lun, sizeof(HW_LU_EXTENSION) * (deviceExtension->NumberChannels+1) * deviceExtension->NumberLuns); 00873 00874 deviceExtension->chan = (PHW_CHANNEL)ExAllocatePool(NonPagedPool, sizeof(HW_CHANNEL) * (deviceExtension->NumberChannels+1)); 00875 if (!deviceExtension->chan) { 00876 ExFreePool(deviceExtension->lun); 00877 deviceExtension->lun = NULL; 00878 KdPrint2((PRINT_PREFIX "!deviceExtension->chan => SP_RETURN_ERROR\n")); 00879 return FALSE; 00880 } 00881 RtlZeroMemory(deviceExtension->chan, sizeof(HW_CHANNEL) * (deviceExtension->NumberChannels+1)); 00882 return TRUE; 00883 } // end UniataAllocateLunExt() 00884 00885 00886 /*++ 00887 00888 Routine Description: 00889 00890 This function is called by the OS-specific port driver after 00891 the necessary storage has been allocated, to gather information 00892 about the adapter's configuration. 00893 00894 Arguments: 00895 00896 HwDeviceExtension - HBA miniport driver's adapter data storage 00897 Context - Address of adapter count 00898 BusInformation - 00899 ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility. 00900 ConfigInfo - Configuration information structure describing HBA 00901 Again - Indicates search for adapters to continue 00902 00903 Return Value: 00904 00905 ULONG 00906 00907 --*/ 00908 ULONG 00909 NTAPI 00910 UniataFindBusMasterController( 00911 IN PVOID HwDeviceExtension, 00912 IN PVOID Context, 00913 IN PVOID BusInformation, 00914 IN PCHAR ArgumentString, 00915 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, 00916 OUT PBOOLEAN Again 00917 ) 00918 { 00919 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 00920 PHW_CHANNEL chan = NULL; 00921 #ifndef UNIATA_CORE 00922 // this buffer must be global for UNIATA_CORE build 00923 PCI_COMMON_CONFIG pciData; 00924 #endif //UNIATA_CORE 00925 ULONG slotNumber; 00926 ULONG busDataRead; 00927 ULONG SystemIoBusNumber; 00928 00929 UCHAR vendorString[5]; 00930 UCHAR deviceString[5]; 00931 PUCHAR vendorStrPtr; 00932 PUCHAR deviceStrPtr; 00933 00934 UCHAR BaseClass; 00935 UCHAR SubClass; 00936 ULONG VendorID; 00937 ULONG DeviceID; 00938 ULONG RevID; 00939 ULONG dev_id; 00940 PCI_SLOT_NUMBER slotData; 00941 00942 ULONG i; 00943 ULONG channel; 00944 ULONG c = 0; 00945 PUCHAR ioSpace; 00946 UCHAR statusByte; 00947 ULONG bm_offset; 00948 00949 // UCHAR tmp8; 00950 // ULONG irq; 00951 00952 BOOLEAN found = FALSE; 00953 BOOLEAN MasterDev; 00954 BOOLEAN simplexOnly = FALSE; 00955 #ifndef UNIATA_CORE 00956 #ifdef UNIATA_INIT_ON_PROBE 00957 BOOLEAN skip_find_dev = FALSE; 00958 #endif 00959 #endif 00960 BOOLEAN AltInit = FALSE; 00961 00962 SCSI_PHYSICAL_ADDRESS IoBasePort1; 00963 SCSI_PHYSICAL_ADDRESS IoBasePort2; 00964 00965 PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0 = NULL; 00966 PIDE_REGISTERS_1 BaseIoAddress1[IDE_MAX_CHAN]; 00967 PIDE_REGISTERS_2 BaseIoAddress2[IDE_MAX_CHAN]; 00968 00969 RtlZeroMemory(&BaseIoAddress1, sizeof(BaseIoAddress1)); 00970 RtlZeroMemory(&BaseIoAddress2, sizeof(BaseIoAddress2)); 00971 00972 NTSTATUS status; 00973 PPORT_CONFIGURATION_INFORMATION_COMMON _ConfigInfo = 00974 (PPORT_CONFIGURATION_INFORMATION_COMMON)ConfigInfo; 00975 00976 if(!WinVer_WDM_Model) { 00977 *Again = FALSE; 00978 } else { 00979 *Again = TRUE; 00980 } 00981 00982 KdPrint2((PRINT_PREFIX "UniataFindBusMasterController: Context=%x, BMListLen=%d\n", Context, BMListLen)); 00983 00984 KdPrint2((PRINT_PREFIX "ConfigInfo->Length %x\n", ConfigInfo->Length)); 00985 00986 if(ForceSimplex) { 00987 KdPrint2((PRINT_PREFIX "ForceSimplex (1)\n")); 00988 simplexOnly = TRUE; 00989 } 00990 00991 if(ConfigInfo->AdapterInterfaceType == Isa) { 00992 KdPrint2((PRINT_PREFIX "AdapterInterfaceType: Isa\n")); 00993 } 00994 if(InDriverEntry) { 00995 i = (ULONG)Context; 00996 if(i & 0x80000000) { 00997 AltInit = TRUE; 00998 } 00999 i &= ~0x80000000; 01000 channel = BMList[i].channel; 01001 } else { 01002 channel = 0; 01003 for(i=0; i<BMListLen; i++) { 01004 if(BMList[i].slotNumber == ConfigInfo->SlotNumber && 01005 BMList[i].busNumber == ConfigInfo->SystemIoBusNumber) { 01006 break; 01007 } 01008 } 01009 if(i >= BMListLen) { 01010 KdPrint2((PRINT_PREFIX "unexpected device arrival\n")); 01011 i = (ULONG)Context; 01012 if(FirstMasterOk) { 01013 channel = 1; 01014 } 01015 i &= ~0x80000000; 01016 if(i >= BMListLen) { 01017 KdPrint2((PRINT_PREFIX " => SP_RETURN_NOT_FOUND\n")); 01018 goto exit_notfound; 01019 } 01020 } 01021 BMList[i].channel = (UCHAR)channel; 01022 } 01023 01024 bm_offset = channel ? ATA_BM_OFFSET1 : 0; 01025 01026 KdPrint2((PRINT_PREFIX "bm_offset %x, channel %x \n", bm_offset, channel)); 01027 01028 if (!deviceExtension) { 01029 KdPrint2((PRINT_PREFIX "!deviceExtension => SP_RETURN_ERROR\n")); 01030 return SP_RETURN_ERROR; 01031 } 01032 RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION)); 01033 01034 vendorStrPtr = vendorString; 01035 deviceStrPtr = deviceString; 01036 01037 slotNumber = BMList[i].slotNumber; 01038 SystemIoBusNumber = BMList[i].busNumber; 01039 01040 01041 KdPrint2((PRINT_PREFIX "AdapterInterfaceType=%#x\n",ConfigInfo->AdapterInterfaceType)); 01042 KdPrint2((PRINT_PREFIX "IoBusNumber=%#x\n",ConfigInfo->SystemIoBusNumber)); 01043 KdPrint2((PRINT_PREFIX "slotNumber=%#x\n",slotNumber)); 01044 01045 // this buffer must be global and already filled for UNIATA_CORE build 01046 busDataRead = HalGetBusData( 01047 //busDataRead = ScsiPortGetBusData(HwDeviceExtension, 01048 PCIConfiguration, 01049 SystemIoBusNumber, 01050 slotNumber, 01051 &pciData, 01052 PCI_COMMON_HDR_LENGTH); 01053 01054 #ifndef UNIATA_CORE 01055 if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) { 01056 KdPrint2((PRINT_PREFIX "busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n")); 01057 goto exit_error; 01058 } 01059 01060 KdPrint2((PRINT_PREFIX "busDataRead\n")); 01061 if (pciData.VendorID == PCI_INVALID_VENDORID) { 01062 KdPrint2((PRINT_PREFIX "PCI_INVALID_VENDORID\n")); 01063 goto exit_error; 01064 } 01065 #endif //UNIATA_CORE 01066 01067 VendorID = pciData.VendorID; 01068 DeviceID = pciData.DeviceID; 01069 BaseClass = pciData.BaseClass; 01070 SubClass = pciData.SubClass; 01071 RevID = pciData.RevisionID; 01072 dev_id = VendorID | (DeviceID << 16); 01073 slotData.u.AsULONG = slotNumber; 01074 KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass )); 01075 01076 deviceExtension->slotNumber = slotNumber; 01077 deviceExtension->SystemIoBusNumber = SystemIoBusNumber; 01078 deviceExtension->DevID = dev_id; 01079 deviceExtension->RevID = RevID; 01080 deviceExtension->NumberChannels = IDE_DEFAULT_MAX_CHAN; // default 01081 deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN; // default 01082 deviceExtension->DevIndex = i; 01083 01084 _snprintf(deviceExtension->Signature, sizeof(deviceExtension->Signature), 01085 "UATA%8.8x/%1.1x@%8.8x", dev_id, channel, slotNumber); 01086 01087 if(BaseClass != PCI_DEV_CLASS_STORAGE) { 01088 KdPrint2((PRINT_PREFIX "BaseClass != PCI_DEV_CLASS_STORAGE => SP_RETURN_NOT_FOUND\n")); 01089 goto exit_notfound; 01090 } 01091 01092 KdPrint2((PRINT_PREFIX "Storage Class\n")); 01093 01094 // look for known chipsets 01095 if(VendorID != BMList[i].nVendorId || 01096 DeviceID != BMList[i].nDeviceId) { 01097 KdPrint2((PRINT_PREFIX "device not suitable\n")); 01098 goto exit_notfound; 01099 } 01100 01101 found = UniataCheckPCISubclass(BMList[i].Known, BMList[i].RaidFlags, SubClass); 01102 if(!found) { 01103 KdPrint2((PRINT_PREFIX "Subclass not supported\n")); 01104 goto exit_notfound; 01105 } 01106 01107 ConfigInfo->AlignmentMask = 0x00000003; 01108 01109 MasterDev = IsMasterDev(&pciData); 01110 01111 if(MasterDev) { 01112 KdPrint2((PRINT_PREFIX "MasterDev (1)\n")); 01113 deviceExtension->MasterDev = TRUE; 01114 } 01115 01116 status = UniataChipDetect(HwDeviceExtension, &pciData, i, ConfigInfo, &simplexOnly); 01117 switch(status) { 01118 case STATUS_SUCCESS: 01119 found = TRUE; 01120 break; 01121 case STATUS_NOT_FOUND: 01122 found = FALSE; 01123 break; 01124 default: 01125 KdPrint2((PRINT_PREFIX "FAILED => SP_RETURN_ERROR\n")); 01126 goto exit_error; 01127 } 01128 KdPrint2((PRINT_PREFIX "ForceSimplex = %d\n", simplexOnly)); 01129 KdPrint2((PRINT_PREFIX "HwFlags = %x\n (0)", deviceExtension->HwFlags)); 01130 switch(dev_id) { 01131 /* additional checks for some supported chipsets */ 01132 case 0xc6931080: 01133 if (SubClass != PCI_DEV_SUBCLASS_IDE) { 01134 KdPrint2((PRINT_PREFIX "0xc6931080, SubClass != PCI_DEV_SUBCLASS_IDE => found = FALSE\n")); 01135 found = FALSE; 01136 } else { 01137 found = FALSE; 01138 } 01139 break; 01140 01141 /* unknown chipsets, try generic DMA if it seems possible */ 01142 default: 01143 if (found) 01144 break; 01145 KdPrint2((PRINT_PREFIX "Default device\n")); 01146 if(Ata_is_supported_dev(&pciData)) { 01147 KdPrint2((PRINT_PREFIX "Ata_is_supported_dev\n")); 01148 found = TRUE; 01149 } else 01150 if(deviceExtension->HwFlags & UNIATA_AHCI) { 01151 KdPrint2((PRINT_PREFIX "AHCI candidate\n")); 01152 found = TRUE; 01153 } else { 01154 KdPrint2((PRINT_PREFIX "!Ata_is_supported_dev => found = FALSE\n")); 01155 found = FALSE; 01156 } 01157 deviceExtension->UnknownDev = TRUE; 01158 break; 01159 } 01160 01161 KdPrint2((PRINT_PREFIX "HwFlags = %x\n (1)", deviceExtension->HwFlags)); 01162 if(!found) { 01163 KdPrint2((PRINT_PREFIX "!found => SP_RETURN_NOT_FOUND\n")); 01164 goto exit_notfound; 01165 } 01166 01167 KdPrint2((PRINT_PREFIX "HwFlags = %x\n (2)", deviceExtension->HwFlags)); 01168 KdPrint2((PRINT_PREFIX "found suitable device\n")); 01169 01170 /***********************************************************/ 01171 /***********************************************************/ 01172 /***********************************************************/ 01173 01174 deviceExtension->UseDpc = TRUE; 01175 KdPrint2((PRINT_PREFIX "HwFlags = %x\n (3)", deviceExtension->HwFlags)); 01176 if(deviceExtension->HwFlags & UNIATA_NO_DPC) { 01177 /* CMD 649, ROSB SWK33, ICH4 */ 01178 KdPrint2((PRINT_PREFIX "UniataFindBusMasterController: UNIATA_NO_DPC (0)\n")); 01179 deviceExtension->UseDpc = FALSE; 01180 } 01181 01182 if(MasterDev) { 01183 if((WinVer_Id() <= WinVer_NT) && AltInit && FirstMasterOk) { 01184 // this is the 2nd attempt to init this controller by OUR driver 01185 KdPrint2((PRINT_PREFIX "Skip primary/secondary claiming checks\n")); 01186 } else { 01187 if((channel==0) && ConfigInfo->AtdiskPrimaryClaimed) { 01188 KdPrint2((PRINT_PREFIX "Error: Primary channel already claimed by another driver\n")); 01189 goto exit_notfound; 01190 } 01191 if((channel==1) && ConfigInfo->AtdiskSecondaryClaimed) { 01192 KdPrint2((PRINT_PREFIX "Error: Secondary channel already claimed by another driver\n")); 01193 goto exit_notfound; 01194 } 01195 } 01196 } 01197 if(deviceExtension->AltRegMap) { 01198 KdPrint2((PRINT_PREFIX " Non-standard registers layout\n")); 01199 if(deviceExtension->HwFlags & UNIATA_SATA) { 01200 KdPrint2((PRINT_PREFIX "UNIATA_SATA -> IsBusMaster == TRUE\n")); 01201 deviceExtension->BusMaster = TRUE; 01202 } 01203 } else { 01204 deviceExtension->BusMaster = FALSE; 01205 01206 if(WinVer_WDM_Model && !deviceExtension->UnknownDev) { 01207 ULONG i; 01208 // Enable Busmastering, IO-space and Mem-space 01209 KdPrint2((PRINT_PREFIX "Enabling Mem/Io spaces and busmastering...\n")); 01210 KdPrint2((PRINT_PREFIX "Initial pciData.Command = %#x\n", pciData.Command)); 01211 for(i=0; i<3; i++) { 01212 switch(i) { 01213 case 0: 01214 KdPrint2((PRINT_PREFIX "PCI_ENABLE_IO_SPACE\n")); 01215 pciData.Command |= PCI_ENABLE_IO_SPACE; 01216 break; 01217 case 1: 01218 KdPrint2((PRINT_PREFIX "PCI_ENABLE_MEMORY_SPACE\n")); 01219 pciData.Command |= PCI_ENABLE_MEMORY_SPACE; 01220 break; 01221 case 2: 01222 KdPrint2((PRINT_PREFIX "PCI_ENABLE_BUS_MASTER\n")); 01223 pciData.Command |= PCI_ENABLE_BUS_MASTER; 01224 break; 01225 } 01226 HalSetBusDataByOffset( PCIConfiguration, SystemIoBusNumber, slotData.u.AsULONG, 01227 &(pciData.Command), 01228 offsetof(PCI_COMMON_CONFIG, Command), 01229 sizeof(pciData.Command)); 01230 KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine)); 01231 01232 // reread config space 01233 busDataRead = HalGetBusData(PCIConfiguration, SystemIoBusNumber, slotData.u.AsULONG, 01234 &pciData, PCI_COMMON_HDR_LENGTH); 01235 KdPrint2((PRINT_PREFIX "New pciData.Command = %#x\n", pciData.Command)); 01236 } 01237 KdPrint2((PRINT_PREFIX "Final pciData.Command = %#x\n", pciData.Command)); 01238 } 01239 // validate Mem/Io ranges 01240 //no_ranges = TRUE; 01241 { 01242 ULONG i; 01243 for(i=0; i<PCI_TYPE0_ADDRESSES; i++) { 01244 if(pciData.u.type0.BaseAddresses[i] & ~0x7) { 01245 //no_ranges = FALSE; 01246 //break; 01247 KdPrint2((PRINT_PREFIX "Range %d = %#x\n", i, pciData.u.type0.BaseAddresses[i])); 01248 } 01249 } 01250 } 01251 01252 if(IsBusMaster(&pciData)) { 01253 01254 KdPrint2((PRINT_PREFIX "IsBusMaster == TRUE\n")); 01255 BaseIoAddressBM_0 = (PIDE_BUSMASTER_REGISTERS) 01256 (AtapiGetIoRange(HwDeviceExtension, ConfigInfo, &pciData, SystemIoBusNumber, 01257 4, bm_offset, MasterDev ? 0x08 : 0x10/*ATA_BMIOSIZE*/)/* - bm_offset*/); //range id 01258 if(BaseIoAddressBM_0) { 01259 UniataInitMapBM(deviceExtension, 01260 BaseIoAddressBM_0, 01261 (*ConfigInfo->AccessRanges)[4].RangeInMemory ? TRUE : FALSE); 01262 deviceExtension->BusMaster = TRUE; 01263 deviceExtension->BaseIoAddressBM_0.Addr = (ULONGIO_PTR)BaseIoAddressBM_0; 01264 if((*ConfigInfo->AccessRanges)[4].RangeInMemory) { 01265 deviceExtension->BaseIoAddressBM_0.MemIo = TRUE; 01266 } 01267 } 01268 KdPrint2((PRINT_PREFIX " BusMasterAddress (base): %#x\n", BaseIoAddressBM_0)); 01269 } 01270 01271 if(!deviceExtension->BusMaster) { 01272 KdPrint2((PRINT_PREFIX " !BusMasterAddress -> PIO4\n")); 01273 deviceExtension->MaxTransferMode = ATA_PIO4; 01274 } 01275 01276 if(deviceExtension->BusMaster && !MasterDev) { 01277 KdPrint2((PRINT_PREFIX "IsBusMaster == TRUE && !MasterDev\n")); 01278 statusByte = AtapiReadPort1(&(deviceExtension->chan[0]), IDX_BM_Status); 01279 KdPrint2((PRINT_PREFIX " BM statusByte = %x\n", statusByte)); 01280 if(statusByte == 0xff) { 01281 KdPrint2((PRINT_PREFIX " invalid port ?\n")); 01282 /* 01283 if(BaseIoAddressBM_0) { 01284 ScsiPortFreeDeviceBase(HwDeviceExtension, 01285 BaseIoAddressBM_0); 01286 BaseIoAddressBM_0 = NULL; 01287 } 01288 */ 01289 } else 01290 if(statusByte & BM_STATUS_SIMPLEX_ONLY) { 01291 KdPrint2((PRINT_PREFIX " BM_STATUS => simplexOnly\n")); 01292 simplexOnly = TRUE; 01293 } 01294 } 01295 } 01296 01297 /* 01298 * the Cypress chip is a mess, it contains two ATA functions, but 01299 * both channels are visible on the first one. 01300 * simply ignore the second function for now, as the right 01301 * solution (ignoring the second channel on the first function) 01302 * doesn't work with the crappy ATA interrupt setup on the alpha. 01303 */ 01304 if (dev_id == 0xc6931080 && slotData.u.bits.FunctionNumber > 1) { 01305 KdPrint2((PRINT_PREFIX "dev_id == 0xc6931080 && FunctionNumber > 1 => exit_findbm\n")); 01306 goto exit_findbm; 01307 } 01308 01309 /* do extra chipset specific setups */ 01310 AtapiReadChipConfig(HwDeviceExtension, i, CHAN_NOT_SPECIFIED); 01311 AtapiChipInit(HwDeviceExtension, i, CHAN_NOT_SPECIFIED_CHECK_CABLE); 01312 01313 simplexOnly |= deviceExtension->simplexOnly; 01314 deviceExtension->simplexOnly |= simplexOnly; 01315 01316 KdPrint2((PRINT_PREFIX "simplexOnly = %d (2)", simplexOnly)); 01317 01318 //TODO: fix hang with UseDpn=TRUE in Simplex mode 01319 //deviceExtension->UseDpc = TRUE; 01320 if(simplexOnly) { 01321 KdPrint2((PRINT_PREFIX "simplexOnly => UseDpc = FALSE\n")); 01322 deviceExtension->UseDpc = FALSE; 01323 } 01324 01325 if(simplexOnly && MasterDev) { 01326 if(deviceExtension->NumberChannels < IDE_DEFAULT_MAX_CHAN) { 01327 KdPrint2((PRINT_PREFIX "set NumberChannels = %d\n", IDE_DEFAULT_MAX_CHAN)); 01328 deviceExtension->NumberChannels = IDE_DEFAULT_MAX_CHAN; 01329 if(BaseIoAddressBM_0) { 01330 UniataInitMapBM(deviceExtension, 01331 BaseIoAddressBM_0, 01332 (*ConfigInfo->AccessRanges)[4].RangeInMemory ? TRUE : FALSE); 01333 } 01334 } 01335 } 01336 if((channel > 0) && 01337 (deviceExtension->NumberChannels > 1)) { 01338 KdPrint2((PRINT_PREFIX "Error: channel > 0 && NumberChannels > 1\n")); 01339 goto exit_findbm; 01340 } 01341 01342 // Indicate number of buses. 01343 ConfigInfo->NumberOfBuses = (UCHAR)(deviceExtension->NumberChannels); 01344 if(!ConfigInfo->InitiatorBusId[0]) { 01345 ConfigInfo->InitiatorBusId[0] = (CHAR)(IoGetConfigurationInformation()->ScsiPortCount); 01346 KdPrint2((PRINT_PREFIX "set ConfigInfo->InitiatorBusId[0] = %#x\n", ConfigInfo->InitiatorBusId[0])); 01347 } 01348 // Indicate four devices can be attached to the adapter 01349 ConfigInfo->MaximumNumberOfTargets = (UCHAR)(deviceExtension->NumberLuns); 01350 01351 if (MasterDev) { 01352 KdPrint2((PRINT_PREFIX "MasterDev (2)\n")); 01353 /* 01354 if((WinVer_Id() > WinVer_NT) || 01355 (deviceExtension->NumberChannels > 1)) { 01356 01357 KdPrint2((PRINT_PREFIX "2 channels & 2 irq for 1 controller Win 2000+\n")); 01358 01359 if (ConfigInfo->AdapterInterfaceType == MicroChannel) { 01360 ConfigInfo->InterruptMode2 = 01361 ConfigInfo->InterruptMode = LevelSensitive; 01362 } else { 01363 ConfigInfo->InterruptMode2 = 01364 ConfigInfo->InterruptMode = Latched; 01365 } 01366 ConfigInfo->BusInterruptLevel = 14; 01367 ConfigInfo->BusInterruptLevel2 = 15; 01368 } else*/ 01369 if(simplexOnly) { 01370 01371 KdPrint2((PRINT_PREFIX "2 channels & 2 irq for 1 controller\n")); 01372 01373 if (ConfigInfo->AdapterInterfaceType == MicroChannel) { 01374 ConfigInfo->InterruptMode2 = 01375 ConfigInfo->InterruptMode = LevelSensitive; 01376 } else { 01377 ConfigInfo->InterruptMode2 = 01378 ConfigInfo->InterruptMode = Latched; 01379 } 01380 ConfigInfo->BusInterruptLevel = 14; 01381 ConfigInfo->BusInterruptLevel2 = 15; 01382 } else { 01383 KdPrint2((PRINT_PREFIX "1 channels & 1 irq for 1 controller\n")); 01384 if (ConfigInfo->AdapterInterfaceType == MicroChannel) { 01385 ConfigInfo->InterruptMode = LevelSensitive; 01386 } else { 01387 ConfigInfo->InterruptMode = Latched; 01388 } 01389 ConfigInfo->BusInterruptLevel = (channel == 0 ? 14 : 15); 01390 } 01391 } else { 01392 KdPrint2((PRINT_PREFIX "!MasterDev\n")); 01393 ConfigInfo->SlotNumber = slotNumber; 01394 ConfigInfo->SystemIoBusNumber = SystemIoBusNumber; 01395 01396 /* primary and secondary channels share the same interrupt */ 01397 if(!ConfigInfo->BusInterruptVector || 01398 (ConfigInfo->BusInterruptVector != pciData.u.type0.InterruptLine)) { 01399 KdPrint2((PRINT_PREFIX "patch irq line = %#x\n", pciData.u.type0.InterruptLine)); 01400 ConfigInfo->BusInterruptVector = pciData.u.type0.InterruptLine; // set default value 01401 if(!ConfigInfo->BusInterruptVector) { 01402 KdPrint2((PRINT_PREFIX "patch irq line (2) = 10\n")); 01403 ConfigInfo->BusInterruptVector = 10; 01404 } 01405 } 01406 } 01407 ConfigInfo->MultipleRequestPerLu = TRUE; 01408 ConfigInfo->AutoRequestSense = TRUE; 01409 ConfigInfo->TaggedQueuing = TRUE; 01410 01411 if((WinVer_Id() >= WinVer_NT) || 01412 (ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4))) { 01413 KdPrint2((PRINT_PREFIX "update ConfigInfo->nt4\n")); 01414 _ConfigInfo->nt4.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION); 01415 _ConfigInfo->nt4.SpecificLuExtensionSize = sizeof(HW_LU_EXTENSION); 01416 _ConfigInfo->nt4.SrbExtensionSize = sizeof(ATA_REQ); 01417 } 01418 if((WinVer_Id() > WinVer_2k) || 01419 (ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4) + sizeof(_ConfigInfo->w2k))) { 01420 KdPrint2((PRINT_PREFIX "update ConfigInfo->w2k\n")); 01421 _ConfigInfo->w2k.Dma64BitAddresses = 0; 01422 _ConfigInfo->w2k.ResetTargetSupported = TRUE; 01423 _ConfigInfo->w2k.MaximumNumberOfLogicalUnits = (UCHAR)deviceExtension->NumberLuns; 01424 } 01425 01426 // Save the Interrupe Mode for later use 01427 deviceExtension->InterruptMode = ConfigInfo->InterruptMode; 01428 deviceExtension->BusInterruptLevel = ConfigInfo->BusInterruptLevel; 01429 deviceExtension->BusInterruptVector = ConfigInfo->BusInterruptVector; 01430 deviceExtension->Channel = channel; 01431 deviceExtension->DevIndex = i; 01432 deviceExtension->OrigAdapterInterfaceType 01433 = ConfigInfo->AdapterInterfaceType; 01434 deviceExtension->AlignmentMask = ConfigInfo->AlignmentMask; 01435 deviceExtension->AdapterInterfaceType = PCIBus; 01436 01437 found = FALSE; 01438 01439 if(deviceExtension->BusMaster) { 01440 01441 KdPrint2((PRINT_PREFIX "Reconstruct ConfigInfo\n")); 01442 ConfigInfo->MapBuffers = TRUE; 01443 #ifdef USE_OWN_DMA 01444 ConfigInfo->NeedPhysicalAddresses = FALSE; 01445 #else 01446 ConfigInfo->NeedPhysicalAddresses = TRUE; 01447 #endif //USE_OWN_DMA 01448 if(!MasterDev) { 01449 KdPrint2((PRINT_PREFIX "set Dma32BitAddresses\n")); 01450 ConfigInfo->Dma32BitAddresses = TRUE; 01451 } 01452 01453 // thanks to Vitaliy Vorobyov aka deathsoft@yandex.ru for 01454 // better solution: 01455 01456 if(AltInit) { 01457 // I'm sorry, I have to do this 01458 // when Win doesn't 01459 01460 if(ConfigInfo->AdapterInterfaceType == Isa /*&& 01461 // InDriverEntry*/) { 01462 KdPrint2((PRINT_PREFIX "AdapterInterfaceType Isa => PCIBus\n")); 01463 ConfigInfo->AdapterInterfaceType = PCIBus; 01464 } 01465 if(ConfigInfo->AdapterInterfaceType == PCIBus /*&& 01466 // InDriverEntry*/) { 01467 KdPrint2((PRINT_PREFIX "AdapterInterfaceType PCIBus, update address\n")); 01468 ConfigInfo->SlotNumber = slotNumber; 01469 ConfigInfo->SystemIoBusNumber = SystemIoBusNumber; 01470 } 01471 } 01472 01473 #ifndef USE_OWN_DMA 01474 ConfigInfo->Master = TRUE; 01475 ConfigInfo->DmaWidth = Width16Bits; 01476 #endif //USE_OWN_DMA 01477 ConfigInfo->CachesData = TRUE; 01478 ConfigInfo->ScatterGather = TRUE; 01479 } 01480 01481 // Note: now we can support only 4 channels !!! 01482 // in order to add support for multichannel controllers we must rewrite 01483 // io-range claiming algorithm 01484 01485 KdPrint2((PRINT_PREFIX "BMList[i].channel %#x, NumberChannels %#x, channel %#x\n",BMList[i].channel, deviceExtension->NumberChannels, channel)); 01486 01487 for (; channel < (BMList[i].channel + deviceExtension->NumberChannels); channel++, c++) { 01488 01489 KdPrint2((PRINT_PREFIX "de %#x, Channel %#x\n",deviceExtension, channel)); 01490 //PrintNtConsole("de %#x, Channel %#x, nchan %#x\n",deviceExtension, channel, deviceExtension->NumberChannels); 01491 chan = &deviceExtension->chan[c]; 01492 01493 KdPrint2((PRINT_PREFIX "chan = %#x\n", chan)); 01494 //PrintNtConsole("chan = %#x, c=%#x\n", chan, c); 01495 AtapiSetupLunPtrs(chan, deviceExtension, c); 01496 01497 /* do extra channel-specific setups */ 01498 AtapiReadChipConfig(HwDeviceExtension, i, channel); 01499 //AtapiChipInit(HwDeviceExtension, i, channel); 01500 if(deviceExtension->HwFlags & UNIATA_AHCI) { 01501 KdPrint2((PRINT_PREFIX " No more setup for AHCI channel\n")); 01502 } else 01503 if(deviceExtension->AltRegMap) { 01504 KdPrint2((PRINT_PREFIX " Non-standard registers layout\n")); 01505 } else { 01506 // Check if the range specified is not used by another driver 01507 if(MasterDev) { 01508 KdPrint2((PRINT_PREFIX "set AccessRanges\n")); 01509 (*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeStart = 01510 ScsiPortConvertUlongToPhysicalAddress(channel ? IO_WD2 : IO_WD1); 01511 (*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeLength = ATA_IOSIZE; 01512 01513 (*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeStart = 01514 ScsiPortConvertUlongToPhysicalAddress((channel ? IO_WD2 : IO_WD1) + ATA_ALTOFFSET); 01515 (*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeLength = ATA_ALTIOSIZE; 01516 01517 // do not claim 2nd BM io-range for Secondary channel of 01518 // Compatible-mode controllers 01519 if(/*(WinVer_Id() <= WinVer_NT) &&*/ !c && channel == 1) { 01520 KdPrint2((PRINT_PREFIX "cheat ScsiPort for 2nd channel, BM io-range\n")); 01521 (*ConfigInfo->AccessRanges)[4].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0); 01522 (*ConfigInfo->AccessRanges)[4].RangeLength = 0; 01523 } 01524 } else 01525 if(AltInit && 01526 !(*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeStart.QuadPart && 01527 !(*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeStart.QuadPart) { 01528 KdPrint2((PRINT_PREFIX "cheat ScsiPort, sync real PCI and ConfigInfo IO ranges\n")); 01529 AtapiGetIoRange(HwDeviceExtension, ConfigInfo, &pciData, SystemIoBusNumber, 01530 channel * 2 + 0, 0, ATA_IOSIZE); 01531 AtapiGetIoRange(HwDeviceExtension, ConfigInfo, &pciData, SystemIoBusNumber, 01532 channel * 2 + 1, 0, ATA_ALTIOSIZE); 01533 } 01534 01535 IoBasePort1 = (*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeStart; 01536 IoBasePort2 = (*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeStart; 01537 01538 if(!MasterDev) { 01539 if(!IoBasePort1.QuadPart || !IoBasePort2.QuadPart) { 01540 KdPrint2((PRINT_PREFIX "ScsiPortValidateRange failed (1)\n")); 01541 continue; 01542 } 01543 } 01544 01545 if(!ScsiPortValidateRange(HwDeviceExtension, 01546 PCIBus /*ConfigInfo->AdapterInterfaceType*/, 01547 SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/, 01548 IoBasePort1, 01549 ATA_IOSIZE, 01550 TRUE) ) { 01551 KdPrint2((PRINT_PREFIX "ScsiPortValidateRange failed (1)\n")); 01552 continue; 01553 } 01554 01555 if(!ScsiPortValidateRange(HwDeviceExtension, 01556 PCIBus /*ConfigInfo->AdapterInterfaceType*/, 01557 SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/, 01558 IoBasePort2, 01559 ATA_ALTIOSIZE, 01560 TRUE) ) { 01561 KdPrint2((PRINT_PREFIX "ScsiPortValidateRange failed (2)\n")); 01562 continue; 01563 } 01564 01565 KdPrint2((PRINT_PREFIX "Getting IO ranges\n")); 01566 01567 // Ok, translate adresses to io-space 01568 if(ScsiPortConvertPhysicalAddressToUlong(IoBasePort2)) { 01569 if(!(MasterDev /* || USE_16_BIT */)) { 01570 KdPrint2((PRINT_PREFIX "!MasterDev mode\n")); 01571 IoBasePort2 = ScsiPortConvertUlongToPhysicalAddress( 01572 ScsiPortConvertPhysicalAddressToUlong(IoBasePort2) + 2); 01573 } 01574 } else { 01575 KdPrint2((PRINT_PREFIX "use relative IoBasePort2\n")); 01576 IoBasePort2 = ScsiPortConvertUlongToPhysicalAddress( 01577 ScsiPortConvertPhysicalAddressToUlong(IoBasePort1) + ATA_PCCARD_ALTOFFSET); 01578 } 01579 01580 // Get the system physical address for this IO range. 01581 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, 01582 PCIBus /*ConfigInfo->AdapterInterfaceType*/, 01583 SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/, 01584 IoBasePort1, 01585 ATA_IOSIZE, 01586 TRUE); 01587 KdPrint2((PRINT_PREFIX "IO range 1 %#x\n",ioSpace)); 01588 01589 // Check if ioSpace accessible. 01590 if (!ioSpace) { 01591 KdPrint2((PRINT_PREFIX "!ioSpace\n")); 01592 continue; 01593 } 01594 /* 01595 if(deviceExtension->BusMaster) { 01596 KdPrint2((PRINT_PREFIX "set BusMaster io-range in DO\n")); 01597 // bm_offset already includes (channel ? ATA_BM_OFFSET1 : 0) 01598 deviceExtension->BaseIoAddressBM[c] = (PIDE_BUSMASTER_REGISTERS) 01599 ((ULONG)(deviceExtension->BaseIoAddressBM_0) + bm_offset + (c ? ATA_BM_OFFSET1 : 0)); 01600 } 01601 */ 01602 //deviceExtension->BaseIoAddress1[c] = (PIDE_REGISTERS_1)(ioSpace); 01603 BaseIoAddress1[c] = (PIDE_REGISTERS_1)(ioSpace); 01604 01605 // Get the system physical address for the second IO range. 01606 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, 01607 PCIBus /*ConfigInfo->AdapterInterfaceType*/, 01608 SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/, 01609 IoBasePort2, 01610 ATA_ALTIOSIZE, 01611 TRUE); 01612 KdPrint2((PRINT_PREFIX "IO range 2 %#x\n",ioSpace)); 01613 01614 BaseIoAddress2[c] = (PIDE_REGISTERS_2)(ioSpace); 01615 if(!ioSpace) { 01616 // Release all allocated resources 01617 KdPrint2((PRINT_PREFIX "!deviceExtension->BaseIoAddress2\n")); 01618 //ioSpace = (PUCHAR)BaseIoAddress1[c]; 01619 // goto free_iospace_1; 01620 found = FALSE; 01621 goto exit_findbm; 01622 } 01623 UniataInitMapBase(chan, BaseIoAddress1[c], BaseIoAddress2[c]); 01624 } 01625 //ioSpace = (PUCHAR)(deviceExtension->BaseIoAddress1[c]); 01626 01627 KdPrint2((PRINT_PREFIX "IDX_IO1 %x->%x(%s)\n", 01628 IDX_IO1, 01629 chan->RegTranslation[IDX_IO1].Addr, 01630 chan->RegTranslation[IDX_IO1].MemIo ? "mem" : "io")); 01631 01632 KdPrint2((PRINT_PREFIX "IDX_IO2 %x->%x(%s)\n", 01633 IDX_IO2, 01634 chan->RegTranslation[IDX_IO2].Addr, 01635 chan->RegTranslation[IDX_IO2].MemIo ? "mem" : "io")); 01636 01637 KdPrint2((PRINT_PREFIX "IDX_BM_IO %x->%x(%s)\n", 01638 IDX_BM_IO, 01639 chan->RegTranslation[IDX_BM_IO].Addr, 01640 chan->RegTranslation[IDX_BM_IO].MemIo ? "mem" : "io")); 01641 01642 KdPrint2((PRINT_PREFIX "IDX_SATA_IO %x->%x(%s)\n", 01643 IDX_SATA_IO, 01644 chan->RegTranslation[IDX_SATA_IO].Addr, 01645 chan->RegTranslation[IDX_SATA_IO].MemIo ? "mem" : "io")); 01646 01647 if(!(deviceExtension->HwFlags & UNIATA_AHCI)) { 01648 UniataDumpATARegs(chan); 01649 01650 #ifndef UNIATA_CORE 01651 #ifdef UNIATA_INIT_ON_PROBE 01652 // if(deviceExtension->HwFlags & UNIATA_SATA) { 01653 //#endif //UNIATA_INIT_ON_PROBE 01654 KdPrint2((PRINT_PREFIX "Check drive 0\n")); 01655 // Check master. 01656 SelectDrive(chan, 0); 01657 AtapiStallExecution(10); 01658 GetBaseStatus(chan, statusByte); 01659 skip_find_dev = FALSE; 01660 if(!(deviceExtension->HwFlags & UNIATA_NO_SLAVE)) { 01661 if ((statusByte & 0xf8) == 0xf8 || 01662 (statusByte == 0xa5)) { 01663 // Check slave. 01664 KdPrint2((PRINT_PREFIX "Check drive 1\n")); 01665 SelectDrive(chan, 1); 01666 AtapiStallExecution(1); 01667 GetBaseStatus(chan, statusByte); 01668 if ((statusByte & 0xf8) == 0xf8 || 01669 (statusByte == 0xa5)) { 01670 // No controller at this base address. 01671 KdPrint2((PRINT_PREFIX "Empty channel\n")); 01672 skip_find_dev = TRUE; 01673 } 01674 } 01675 } 01676 01677 // Search for devices on this controller. 01678 if (!skip_find_dev && 01679 FindDevices(HwDeviceExtension, 01680 0, 01681 c)) { 01682 KdPrint2((PRINT_PREFIX "Found some devices\n")); 01683 found = TRUE; 01684 } else { 01685 KdPrint2((PRINT_PREFIX "no devices\n")); 01686 /* KeBugCheckEx(0xc000000e, 01687 ScsiPortConvertPhysicalAddressToUlong(IoBasePort1), 01688 ScsiPortConvertPhysicalAddressToUlong(IoBasePort2), 01689 (ULONG)(deviceExtension->BaseIoAddressBM[c]), skip_find_dev);*/ 01690 } 01691 //#ifdef UNIATA_INIT_ON_PROBE 01692 // } 01693 #endif //UNIATA_INIT_ON_PROBE 01694 } 01695 found = TRUE; 01696 01697 chan->PrimaryAddress = FALSE; 01698 // Claim primary or secondary ATA IO range. 01699 if (MasterDev) { 01700 KdPrint2((PRINT_PREFIX "claim Compatible controller\n")); 01701 if (channel == 0) { 01702 KdPrint2((PRINT_PREFIX "claim Primary\n")); 01703 ConfigInfo->AtdiskPrimaryClaimed = TRUE; 01704 chan->PrimaryAddress = TRUE; 01705 01706 FirstMasterOk = TRUE; 01707 01708 } else 01709 if (channel == 1) { 01710 KdPrint2((PRINT_PREFIX "claim Secondary\n")); 01711 ConfigInfo->AtdiskSecondaryClaimed = TRUE; 01712 01713 FirstMasterOk = TRUE; 01714 } 01715 } 01716 01717 AtapiDmaAlloc(HwDeviceExtension, ConfigInfo, c); 01718 #else //UNIATA_CORE 01719 } 01720 found = TRUE; 01721 #endif //UNIATA_CORE 01722 } // end for(channel) 01723 01724 exit_findbm: 01725 01726 #ifndef UNIATA_CORE 01727 if(!found) { 01728 KdPrint2((PRINT_PREFIX "exit: !found\n")); 01729 if(BaseIoAddress1[0]) 01730 ScsiPortFreeDeviceBase(HwDeviceExtension, 01731 BaseIoAddress1[0]); 01732 if(BaseIoAddress2[0]) 01733 ScsiPortFreeDeviceBase(HwDeviceExtension, 01734 BaseIoAddress2[0]); 01735 01736 if(BaseIoAddress1[1]) 01737 ScsiPortFreeDeviceBase(HwDeviceExtension, 01738 BaseIoAddress1[1]); 01739 if(BaseIoAddress2[1]) 01740 ScsiPortFreeDeviceBase(HwDeviceExtension, 01741 BaseIoAddress2[1]); 01742 01743 if(BaseIoAddressBM_0) 01744 ScsiPortFreeDeviceBase(HwDeviceExtension, 01745 BaseIoAddressBM_0); 01746 01747 KdPrint2((PRINT_PREFIX "return SP_RETURN_NOT_FOUND\n")); 01748 goto exit_notfound; 01749 } else { 01750 01751 KdPrint2((PRINT_PREFIX "exit: init spinlock\n")); 01752 //KeInitializeSpinLock(&(deviceExtension->DpcSpinLock)); 01753 deviceExtension->ActiveDpcChan = 01754 deviceExtension->FirstDpcChan = -1; 01755 01756 BMList[i].Isr2Enable = FALSE; 01757 01758 KdPrint2((PRINT_PREFIX "MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n", 01759 MasterDev, deviceExtension->NumberChannels, BMList[i].Isr2DevObj)); 01760 01761 // ConnectIntr2 should be moved to HwInitialize 01762 status = UniataConnectIntr2(HwDeviceExtension); 01763 01764 KdPrint2((PRINT_PREFIX "MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n", 01765 MasterDev, deviceExtension->NumberChannels, BMList[i].Isr2DevObj)); 01766 01767 if(WinVer_WDM_Model && MasterDev) { 01768 KdPrint2((PRINT_PREFIX "do not tell system, that we know about this:\n")); 01769 if(BaseIoAddressBM_0) { 01770 ScsiPortFreeDeviceBase(HwDeviceExtension, 01771 BaseIoAddressBM_0); 01772 } 01773 (*ConfigInfo->AccessRanges)[4].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0); 01774 (*ConfigInfo->AccessRanges)[4].RangeLength = 0; 01775 (*ConfigInfo->AccessRanges)[5].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0); 01776 (*ConfigInfo->AccessRanges)[5].RangeLength = 0; 01777 } 01778 01779 if(!NT_SUCCESS(status)) { 01780 KdPrint2((PRINT_PREFIX "failed\n")); 01781 found = FALSE; 01782 goto exit_findbm; 01783 } 01784 } 01785 #endif //UNIATA_CORE 01786 01787 KdPrint2((PRINT_PREFIX "return SP_RETURN_FOUND\n")); 01788 //PrintNtConsole("return SP_RETURN_FOUND, de %#x, c0.lun0 %#x\n", deviceExtension, deviceExtension->chan[0].lun[0]); 01789 01790 if(MasterDev) { 01791 KdPrint2((PRINT_PREFIX "Attempt %d of MasterDev ok\n", AltInit)); 01792 FirstMasterOk = TRUE; 01793 } 01794 01795 ConfigInfo->NumberOfBuses++; // add virtual channel for communication port 01796 return SP_RETURN_FOUND; 01797 01798 exit_error: 01799 if (deviceExtension->lun) ExFreePool(deviceExtension->lun); 01800 if (deviceExtension->chan) ExFreePool(deviceExtension->chan); 01801 return SP_RETURN_ERROR; 01802 01803 exit_notfound: 01804 ExFreePool(deviceExtension->lun); 01805 ExFreePool(deviceExtension->chan); 01806 return SP_RETURN_NOT_FOUND; 01807 01808 } // end UniataFindBusMasterController() 01809 01810 #ifndef UNIATA_CORE 01811 01812 /* 01813 This is for claiming PCI Busmaster in compatible mode under WDM OSes 01814 */ 01815 ULONG 01816 NTAPI 01817 UniataFindFakeBusMasterController( 01818 IN PVOID HwDeviceExtension, 01819 IN PVOID Context, 01820 IN PVOID BusInformation, 01821 IN PCHAR ArgumentString, 01822 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, 01823 OUT PBOOLEAN Again 01824 ) 01825 { 01826 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 01827 //PHW_CHANNEL chan = NULL; 01828 // this buffer must be global for UNIATA_CORE build 01829 PCI_COMMON_CONFIG pciData; 01830 01831 ULONG slotNumber; 01832 ULONG busDataRead; 01833 ULONG SystemIoBusNumber; 01834 01835 UCHAR vendorString[5]; 01836 UCHAR deviceString[5]; 01837 PUCHAR vendorStrPtr; 01838 PUCHAR deviceStrPtr; 01839 01840 UCHAR BaseClass; 01841 UCHAR SubClass; 01842 ULONG VendorID; 01843 ULONG DeviceID; 01844 ULONG RevID; 01845 ULONG dev_id; 01846 PCI_SLOT_NUMBER slotData; 01847 01848 ULONG i; 01849 // PUCHAR ioSpace; 01850 // UCHAR statusByte; 01851 01852 // UCHAR tmp8; 01853 // ULONG irq; 01854 01855 BOOLEAN found = FALSE; 01856 BOOLEAN MasterDev; 01857 BOOLEAN simplexOnly = FALSE; 01858 //BOOLEAN skip_find_dev = FALSE; 01859 //BOOLEAN AltInit = FALSE; 01860 01861 PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0 = NULL; 01862 01863 NTSTATUS status; 01864 PPORT_CONFIGURATION_INFORMATION_COMMON _ConfigInfo = 01865 (PPORT_CONFIGURATION_INFORMATION_COMMON)ConfigInfo; 01866 01867 *Again = FALSE; 01868 01869 if(InDriverEntry) { 01870 i = (ULONG)Context; 01871 } else { 01872 for(i=0; i<BMListLen; i++) { 01873 if(BMList[i].slotNumber == ConfigInfo->SlotNumber && 01874 BMList[i].busNumber == ConfigInfo->SystemIoBusNumber) { 01875 break; 01876 } 01877 } 01878 if(i >= BMListLen) { 01879 KdPrint2((PRINT_PREFIX "unexpected device arrival => SP_RETURN_NOT_FOUND\n")); 01880 goto exit_notfound; 01881 } 01882 } 01883 01884 KdPrint2((PRINT_PREFIX "UniataFindFakeBusMasterController (WDM)\n")); 01885 01886 if (!deviceExtension) { 01887 KdPrint2((PRINT_PREFIX "!deviceExtension => SP_RETURN_ERROR\n")); 01888 return SP_RETURN_ERROR; 01889 } 01890 RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION)); 01891 01892 vendorStrPtr = vendorString; 01893 deviceStrPtr = deviceString; 01894 01895 slotNumber = BMList[i].slotNumber; 01896 SystemIoBusNumber = BMList[i].busNumber; 01897 01898 KdPrint2((PRINT_PREFIX "AdapterInterfaceType=%#x\n",ConfigInfo->AdapterInterfaceType)); 01899 KdPrint2((PRINT_PREFIX "IoBusNumber=%#x\n",ConfigInfo->SystemIoBusNumber)); 01900 KdPrint2((PRINT_PREFIX "slotNumber=%#x\n",slotNumber)); 01901 01902 // this buffer must be global and already filled for UNIATA_CORE build 01903 busDataRead = HalGetBusData( 01904 //busDataRead = ScsiPortGetBusData(HwDeviceExtension, 01905 PCIConfiguration, 01906 SystemIoBusNumber, 01907 slotNumber, 01908 &pciData, 01909 PCI_COMMON_HDR_LENGTH); 01910 01911 if (busDataRead < PCI_COMMON_HDR_LENGTH) { 01912 KdPrint2((PRINT_PREFIX "busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n")); 01913 goto exit_error; 01914 } 01915 01916 KdPrint2((PRINT_PREFIX "busDataRead\n")); 01917 if (pciData.VendorID == PCI_INVALID_VENDORID) { 01918 KdPrint2((PRINT_PREFIX "PCI_INVALID_VENDORID\n")); 01919 goto exit_error; 01920 } 01921 01922 VendorID = pciData.VendorID; 01923 DeviceID = pciData.DeviceID; 01924 BaseClass = pciData.BaseClass; 01925 SubClass = pciData.SubClass; 01926 RevID = pciData.RevisionID; 01927 dev_id = VendorID | (DeviceID << 16); 01928 slotData.u.AsULONG = slotNumber; 01929 KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass )); 01930 01931 deviceExtension->slotNumber = slotNumber; 01932 deviceExtension->SystemIoBusNumber = SystemIoBusNumber; 01933 deviceExtension->DevID = dev_id; 01934 deviceExtension->RevID = RevID; 01935 deviceExtension->NumberChannels = IDE_DEFAULT_MAX_CHAN; // default 01936 deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN; // default 01937 deviceExtension->DevIndex = i; 01938 01939 _snprintf(deviceExtension->Signature, sizeof(deviceExtension->Signature), 01940 "UATA%8.8x/%1.1x@%8.8x", dev_id, 0xff, slotNumber); 01941 01942 if(BaseClass != PCI_DEV_CLASS_STORAGE) { 01943 KdPrint2((PRINT_PREFIX "BaseClass != PCI_DEV_CLASS_STORAGE => SP_RETURN_NOT_FOUND\n")); 01944 goto exit_notfound; 01945 } 01946 01947 KdPrint2((PRINT_PREFIX "Storage Class\n")); 01948 01949 // look for known chipsets 01950 if(VendorID != BMList[i].nVendorId || 01951 DeviceID != BMList[i].nDeviceId) { 01952 KdPrint2((PRINT_PREFIX "device not suitable\n")); 01953 goto exit_notfound; 01954 } 01955 01956 if((BMList[i].RaidFlags & UNIATA_RAID_CONTROLLER) && 01957 SkipRaids) { 01958 KdPrint2((PRINT_PREFIX "RAID support disabled\n")); 01959 goto exit_notfound; 01960 } 01961 01962 if(!UniataCheckPCISubclass(FALSE, BMList[i].RaidFlags, SubClass)) { 01963 KdPrint2((PRINT_PREFIX "Subclass not supported\n")); 01964 goto exit_notfound; 01965 } 01966 01967 ConfigInfo->AlignmentMask = 0x00000003; 01968 01969 status = UniataChipDetect(HwDeviceExtension, &pciData, i, ConfigInfo, &simplexOnly); 01970 switch(status) { 01971 case STATUS_SUCCESS: 01972 found = TRUE; 01973 break; 01974 case STATUS_NOT_FOUND: 01975 found = FALSE; 01976 break; 01977 default: 01978 KdPrint2((PRINT_PREFIX "FAILED => SP_RETURN_ERROR\n")); 01979 goto exit_error; 01980 } 01981 KdPrint2((PRINT_PREFIX "ForceSimplex = %d\n", simplexOnly)); 01982 KdPrint2((PRINT_PREFIX "HwFlags = %x\n (0)", deviceExtension->HwFlags)); 01983 switch(dev_id) { 01984 /* additional checks for some supported chipsets */ 01985 case 0xc6931080: 01986 if (SubClass != PCI_DEV_SUBCLASS_IDE) { 01987 KdPrint2((PRINT_PREFIX "0xc6931080, SubClass != PCI_DEV_SUBCLASS_IDE => found = FALSE\n")); 01988 found = FALSE; 01989 } else { 01990 found = FALSE; 01991 } 01992 break; 01993 01994 /* unknown chipsets, try generic DMA if it seems possible */ 01995 default: 01996 if (found) 01997 break; 01998 KdPrint2((PRINT_PREFIX "Default device\n")); 01999 if(Ata_is_supported_dev(&pciData)) { 02000 KdPrint2((PRINT_PREFIX "Ata_is_supported_dev\n")); 02001 found = TRUE; 02002 } else { 02003 KdPrint2((PRINT_PREFIX "!Ata_is_supported_dev => found = FALSE\n")); 02004 found = FALSE; 02005 } 02006 deviceExtension->UnknownDev = TRUE; 02007 break; 02008 } 02009 02010 KdPrint2((PRINT_PREFIX "HwFlags = %x\n (1)", deviceExtension->HwFlags)); 02011 if(!found) { 02012 KdPrint2((PRINT_PREFIX "!found => SP_RETURN_NOT_FOUND\n")); 02013 goto exit_notfound; 02014 } 02015 02016 KdPrint2((PRINT_PREFIX "HwFlags = %x\n (2)", deviceExtension->HwFlags)); 02017 KdPrint2((PRINT_PREFIX "found suitable device\n")); 02018 02019 /***********************************************************/ 02020 /***********************************************************/ 02021 /***********************************************************/ 02022 02023 deviceExtension->UseDpc = TRUE; 02024 KdPrint2((PRINT_PREFIX "HwFlags = %x\n (3)", deviceExtension->HwFlags)); 02025 if(deviceExtension->HwFlags & UNIATA_NO_DPC) { 02026 /* CMD 649, ROSB SWK33, ICH4 */ 02027 KdPrint2((PRINT_PREFIX "UniataFindBusMasterController: UNIATA_NO_DPC (0)\n")); 02028 deviceExtension->UseDpc = FALSE; 02029 } 02030 02031 MasterDev = IsMasterDev(&pciData); 02032 02033 if(MasterDev) { 02034 KdPrint2((PRINT_PREFIX "MasterDev\n")); 02035 deviceExtension->MasterDev = TRUE; 02036 deviceExtension->NumberChannels = 1; 02037 } else { 02038 KdPrint2((PRINT_PREFIX "!MasterDev => SP_RETURN_NOT_FOUND\n")); 02039 goto exit_notfound; 02040 } 02041 02042 if(deviceExtension->AltRegMap) { 02043 KdPrint2((PRINT_PREFIX " Non-standard registers layout => SP_RETURN_NOT_FOUND\n")); 02044 goto exit_notfound; 02045 } 02046 if(IsBusMaster(&pciData)) { 02047 KdPrint2((PRINT_PREFIX " !BusMaster => SP_RETURN_NOT_FOUND\n")); 02048 goto exit_notfound; 02049 } 02050 02051 KdPrint2((PRINT_PREFIX "IsBusMaster == TRUE\n")); 02052 BaseIoAddressBM_0 = (PIDE_BUSMASTER_REGISTERS) 02053 (AtapiGetIoRange(HwDeviceExtension, ConfigInfo, &pciData, SystemIoBusNumber, 02054 4, 0, 0x10/*ATA_BMIOSIZE*/)/* - bm_offset*/); //range id 02055 if(BaseIoAddressBM_0) { 02056 UniataInitMapBM(deviceExtension, 02057 BaseIoAddressBM_0, 02058 (*ConfigInfo->AccessRanges)[4].RangeInMemory ? TRUE : FALSE); 02059 deviceExtension->BusMaster = TRUE; 02060 deviceExtension->BaseIoAddressBM_0.Addr = (ULONGIO_PTR)BaseIoAddressBM_0; 02061 if((*ConfigInfo->AccessRanges)[4].RangeInMemory) { 02062 deviceExtension->BaseIoAddressBM_0.MemIo = TRUE; 02063 } 02064 } 02065 KdPrint2((PRINT_PREFIX " BusMasterAddress (base): %#x\n", BaseIoAddressBM_0)); 02066 02067 /* 02068 * the Cypress chip is a mess, it contains two ATA functions, but 02069 * both channels are visible on the first one. 02070 * simply ignore the second function for now, as the right 02071 * solution (ignoring the second channel on the first function) 02072 * doesn't work with the crappy ATA interrupt setup on the alpha. 02073 */ 02074 if (dev_id == 0xc6931080 && slotData.u.bits.FunctionNumber > 1) { 02075 KdPrint2((PRINT_PREFIX "dev_id == 0xc6931080 && FunctionNumber > 1 => exit_findbm\n")); 02076 goto exit_findbm; 02077 } 02078 02079 // Indicate number of buses. 02080 ConfigInfo->NumberOfBuses = 0; 02081 if(!ConfigInfo->InitiatorBusId[0]) { 02082 ConfigInfo->InitiatorBusId[0] = (CHAR)(IoGetConfigurationInformation()->ScsiPortCount); 02083 KdPrint2((PRINT_PREFIX "set ConfigInfo->InitiatorBusId[0] = %#x\n", ConfigInfo->InitiatorBusId[0])); 02084 } 02085 // Indicate four devices can be attached to the adapter 02086 ConfigInfo->MaximumNumberOfTargets = 0; 02087 02088 ConfigInfo->MultipleRequestPerLu = FALSE; 02089 ConfigInfo->AutoRequestSense = FALSE; 02090 ConfigInfo->TaggedQueuing = FALSE; 02091 02092 if((WinVer_Id() >= WinVer_NT) || 02093 (ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4))) { 02094 _ConfigInfo->nt4.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION); 02095 _ConfigInfo->nt4.SpecificLuExtensionSize = sizeof(HW_LU_EXTENSION); 02096 _ConfigInfo->nt4.SrbExtensionSize = sizeof(ATA_REQ); 02097 } 02098 if((WinVer_Id() > WinVer_2k) || 02099 (ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4) + sizeof(_ConfigInfo->w2k))) { 02100 _ConfigInfo->w2k.Dma64BitAddresses = 0; 02101 _ConfigInfo->w2k.ResetTargetSupported = FALSE; 02102 _ConfigInfo->w2k.MaximumNumberOfLogicalUnits = 0; 02103 } 02104 02105 // Save the Interrupe Mode for later use 02106 deviceExtension->InterruptMode = ConfigInfo->InterruptMode; 02107 deviceExtension->BusInterruptLevel = ConfigInfo->BusInterruptLevel; 02108 deviceExtension->BusInterruptVector = ConfigInfo->BusInterruptVector; 02109 deviceExtension->Channel = 0; 02110 deviceExtension->DevIndex = i; 02111 deviceExtension->OrigAdapterInterfaceType 02112 = ConfigInfo->AdapterInterfaceType; 02113 deviceExtension->AlignmentMask = ConfigInfo->AlignmentMask; 02114 deviceExtension->AdapterInterfaceType = PCIBus; 02115 02116 KdPrint2((PRINT_PREFIX "Reconstruct ConfigInfo\n")); 02117 ConfigInfo->MapBuffers = TRUE; 02118 #ifdef USE_OWN_DMA 02119 ConfigInfo->NeedPhysicalAddresses = FALSE; 02120 #else 02121 ConfigInfo->NeedPhysicalAddresses = TRUE; 02122 #endif //USE_OWN_DMA 02123 02124 exit_findbm: 02125 02126 KdPrint2((PRINT_PREFIX "return SP_RETURN_FOUND\n")); 02127 //PrintNtConsole("return SP_RETURN_FOUND, de %#x, c0.lun0 %#x\n", deviceExtension, deviceExtension->chan[0].lun[0]); 02128 02129 return SP_RETURN_FOUND; 02130 02131 exit_error: 02132 if (deviceExtension->lun) ExFreePool(deviceExtension->lun); 02133 if (deviceExtension->chan) ExFreePool(deviceExtension->chan); 02134 return SP_RETURN_ERROR; 02135 02136 exit_notfound: 02137 ExFreePool(deviceExtension->lun); 02138 ExFreePool(deviceExtension->chan); 02139 return SP_RETURN_NOT_FOUND; 02140 02141 } // end UniataFindFakeBusMasterController() 02142 02143 02144 /*++ 02145 02146 Routine Description: 02147 02148 This function is called to initialize 2nd device object for 02149 multichannel controllers. 02150 02151 Arguments: 02152 02153 HwDeviceExtension - HBA miniport driver's adapter data storage 02154 02155 Return Value: 02156 02157 ULONG 02158 02159 --*/ 02160 NTSTATUS 02161 NTAPI 02162 UniataConnectIntr2( 02163 IN PVOID HwDeviceExtension 02164 ) 02165 { 02166 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 02167 ULONG i = deviceExtension->DevIndex; 02168 NTSTATUS status; 02169 PISR2_DEVICE_EXTENSION Isr2DevExt; 02170 WCHAR devname_str[32]; 02171 UNICODE_STRING devname; 02172 02173 KdPrint2((PRINT_PREFIX "Init ISR:\n")); 02174 02175 if(BMList[i].Isr2DevObj) { 02176 KdPrint2((PRINT_PREFIX "Already initialized %#x\n", BMList[i].Isr2DevObj)); 02177 return STATUS_SUCCESS; 02178 } 02179 02180 if(!deviceExtension->MasterDev && (deviceExtension->NumberChannels > 1) && // do not touch MasterDev 02181 !deviceExtension->simplexOnly && /* // this is unnecessary on simplex controllers 02182 !BMList[i].Isr2DevObj*/ // handle re-init under w2k+ 02184 TRUE) { 02185 // Ok, continue... 02186 KdPrint2((PRINT_PREFIX "Multichannel native mode, go...\n")); 02187 } else { 02188 KdPrint2((PRINT_PREFIX "Unnecessary\n")); 02189 return STATUS_SUCCESS; 02190 } 02191 02192 KdPrint2((PRINT_PREFIX "Create DO\n")); 02193 02194 devname.Length = 02195 _snwprintf(devname_str, sizeof(devname_str)/sizeof(WCHAR), 02196 L"\\Device\\uniata%d_2ch", i); 02197 devname.Length *= sizeof(WCHAR); 02198 devname.MaximumLength = devname.Length; 02199 devname.Buffer = devname_str; 02200 02201 KdPrint2((PRINT_PREFIX "DO name: len(%d, %d), %S\n", devname.Length, devname.MaximumLength, devname.Buffer)); 02202 02203 status = IoCreateDevice(SavedDriverObject, sizeof(ISR2_DEVICE_EXTENSION), 02204 /*NULL*/ &devname, FILE_DEVICE_UNKNOWN, 02205 0, FALSE, &(BMList[i].Isr2DevObj)); 02206 02207 if(!NT_SUCCESS(status)) { 02208 KdPrint2((PRINT_PREFIX "IoCreateDevice failed %#x\n")); 02209 return status; 02210 } 02211 02212 KdPrint2((PRINT_PREFIX "HalGetInterruptVector\n")); 02213 KdPrint2((PRINT_PREFIX " OrigAdapterInterfaceType=%d\n", deviceExtension->OrigAdapterInterfaceType)); 02214 KdPrint2((PRINT_PREFIX " SystemIoBusNumber=%d\n", deviceExtension->SystemIoBusNumber)); 02215 KdPrint2((PRINT_PREFIX " BusInterruptLevel=%d\n", deviceExtension->BusInterruptLevel)); 02216 KdPrint2((PRINT_PREFIX " BusInterruptVector=%d\n", deviceExtension->BusInterruptVector)); 02217 BMList[i].Isr2Vector = HalGetInterruptVector( 02218 deviceExtension->OrigAdapterInterfaceType, 02219 deviceExtension->SystemIoBusNumber, 02220 deviceExtension->BusInterruptLevel, 02221 deviceExtension->BusInterruptVector, 02222 &(BMList[i].Isr2Irql), 02223 &(BMList[i].Isr2Affinity)); 02224 02225 Isr2DevExt = (PISR2_DEVICE_EXTENSION)(BMList[i].Isr2DevObj->DeviceExtension); 02226 Isr2DevExt->HwDeviceExtension = deviceExtension; 02227 Isr2DevExt->DevIndex = i; 02228 02229 KdPrint2((PRINT_PREFIX "isr2_de %#x\n", Isr2DevExt)); 02230 KdPrint2((PRINT_PREFIX "isr2_vector %#x\n", BMList[i].Isr2Vector)); 02231 KdPrint2((PRINT_PREFIX "isr2_irql %#x\n", BMList[i].Isr2Irql)); 02232 KdPrint2((PRINT_PREFIX "isr2_affinity %#x\n", BMList[i].Isr2Affinity)); 02233 02234 // deviceExtension->QueueNewIrql = BMList[i].Isr2Irql; 02235 02236 KdPrint2((PRINT_PREFIX "IoConnectInterrupt\n")); 02237 status = IoConnectInterrupt( 02238 &(BMList[i].Isr2InterruptObject), 02239 AtapiInterrupt2, 02240 Isr2DevExt, 02241 NULL, 02242 BMList[i].Isr2Vector, 02243 BMList[i].Isr2Irql, 02244 BMList[i].Isr2Irql, 02245 (KINTERRUPT_MODE)(deviceExtension->InterruptMode), 02246 TRUE, 02247 BMList[i].Isr2Affinity, 02248 FALSE); 02249 02250 if(!NT_SUCCESS(status)) { 02251 KdPrint2((PRINT_PREFIX "IoConnectInterrupt failed\n")); 02252 IoDeleteDevice(BMList[i].Isr2DevObj); 02253 BMList[i].Isr2DevObj = NULL; 02254 BMList[i].Isr2InterruptObject = NULL; 02255 return status; 02256 } 02257 02258 //deviceExtension->Isr2DevObj = BMList[i].Isr2DevObj; 02259 02260 return status; 02261 } // end UniataConnectIntr2() 02262 02263 NTSTATUS 02264 NTAPI 02265 UniataDisconnectIntr2( 02266 IN PVOID HwDeviceExtension 02267 ) 02268 { 02269 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 02270 ULONG i = deviceExtension->DevIndex; 02271 // NTSTATUS status; 02272 02273 KdPrint2((PRINT_PREFIX "Deinit ISR:\n")); 02274 02275 if(!BMList[i].Isr2DevObj) { 02276 KdPrint2((PRINT_PREFIX "Already uninitialized %#x\n")); 02277 return STATUS_SUCCESS; 02278 } 02279 02280 IoDisconnectInterrupt(BMList[i].Isr2InterruptObject); 02281 02282 BMList[i].Isr2InterruptObject = NULL; 02283 02284 IoDeleteDevice(BMList[i].Isr2DevObj); 02285 02286 BMList[i].Isr2DevObj = NULL; 02287 //deviceExtension->Isr2DevObj = NULL; 02288 02289 return STATUS_SUCCESS; 02290 } // end UniataDisconnectIntr2() 02291 02292 #endif //UNIATA_CORE 02293 02294 /*++ 02295 02296 Routine Description: 02297 02298 This function is called by the OS-specific port driver after 02299 the necessary storage has been allocated, to gather information 02300 about the adapter's configuration. 02301 02302 Arguments: 02303 02304 HwDeviceExtension - HBA miniport driver's adapter data storage 02305 Context - Address of adapter count 02306 ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility. 02307 ConfigInfo - Configuration information structure describing HBA 02308 Again - Indicates search for adapters to continue 02309 02310 Return Value: 02311 02312 ULONG 02313 02314 --*/ 02315 ULONG 02316 NTAPI 02317 AtapiFindController( 02318 IN PVOID HwDeviceExtension, 02319 IN PVOID Context, 02320 IN PVOID BusInformation, 02321 IN PCHAR ArgumentString, 02322 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, 02323 OUT PBOOLEAN Again 02324 ) 02325 { 02326 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 02327 PHW_CHANNEL chan; 02328 PULONG adapterCount = (PULONG)Context; 02329 PUCHAR ioSpace = NULL; 02330 ULONG i; 02331 ULONG irq=0; 02332 ULONG portBase; 02333 ULONG retryCount; 02334 BOOLEAN atapiOnly; 02335 UCHAR statusByte; 02336 BOOLEAN preConfig = FALSE; 02337 // 02338 PIDE_REGISTERS_1 BaseIoAddress1; 02339 PIDE_REGISTERS_2 BaseIoAddress2 = NULL; 02340 02341 // The following table specifies the ports to be checked when searching for 02342 // an IDE controller. A zero entry terminates the search. 02343 static CONST ULONG AdapterAddresses[5] = {IO_WD1, IO_WD2, IO_WD1-8, IO_WD2-8, 0}; 02344 // CONST UCHAR Channels[5] = {0, 1, 0, 1, 0}; 02345 02346 // The following table specifies interrupt levels corresponding to the 02347 // port addresses in the previous table. 02348 static CONST ULONG InterruptLevels[5] = {14, 15, 11, 10, 0}; 02349 02350 KdPrint2((PRINT_PREFIX "AtapiFindController:\n")); 02351 02352 if (!deviceExtension) { 02353 return SP_RETURN_ERROR; 02354 } 02355 RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION)); 02356 02357 KdPrint2((PRINT_PREFIX " assume max PIO4\n")); 02358 deviceExtension->MaxTransferMode = ATA_PIO4; 02359 deviceExtension->NumberChannels = 1; 02360 deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN; // default 02361 02362 if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) { 02363 goto exit_error; 02364 } 02365 02366 chan = &(deviceExtension->chan[0]); 02367 02368 deviceExtension->AdapterInterfaceType = 02369 deviceExtension->OrigAdapterInterfaceType 02370 = ConfigInfo->AdapterInterfaceType; 02371 02372 #ifndef UNIATA_CORE 02373 02374 /* do extra chipset specific setups */ 02375 AtapiReadChipConfig(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, CHAN_NOT_SPECIFIED); 02376 AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, CHAN_NOT_SPECIFIED); 02377 02378 // Check to see if this is a special configuration environment. 02379 portBase = irq = 0; 02380 if (ArgumentString) { 02381 02382 irq = AtapiParseArgumentString(ArgumentString, "Interrupt"); 02383 if (irq ) { 02384 02385 // Both parameters must be present to proceed 02386 portBase = AtapiParseArgumentString(ArgumentString, "BaseAddress"); 02387 if (!portBase) { 02388 02389 // Try a default search for the part. 02390 irq = 0; 02391 } 02392 } 02393 } 02394 02395 #endif //UNIATA_CORE 02396 02397 02398 // Scan though the adapter address looking for adapters. 02399 if (ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart) != 0) { 02400 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, 02401 ConfigInfo->AdapterInterfaceType, 02402 ConfigInfo->SystemIoBusNumber, 02403 (*ConfigInfo->AccessRanges)[0].RangeStart, 02404 (*ConfigInfo->AccessRanges)[0].RangeLength, 02405 (BOOLEAN) !((*ConfigInfo->AccessRanges)[0].RangeInMemory)); 02406 *Again = FALSE; 02407 // Since we have pre-configured information we only need to go through this loop once 02408 preConfig = TRUE; 02409 portBase = ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart); 02410 KdPrint2((PRINT_PREFIX " preconfig, portBase=%x\n", portBase)); 02411 } 02412 02413 #ifndef UNIATA_CORE 02414 while (AdapterAddresses[*adapterCount] != 0) { 02415 #else 02416 do { 02417 #endif //UNIATA_CORE 02418 02419 retryCount = 4; 02420 deviceExtension->DevIndex = (*adapterCount); 02421 02422 portBase = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PortBase", portBase); 02423 irq = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Irq", irq); 02424 02425 for (i = 0; i < 4; i++) { 02426 // Zero device fields to ensure that if earlier devices were found, 02427 // but not claimed, the fields are cleared. 02428 deviceExtension->lun[i].DeviceFlags &= ~(DFLAGS_ATAPI_DEVICE | DFLAGS_DEVICE_PRESENT | DFLAGS_TAPE_DEVICE); 02429 } 02430 // Get the system physical address for this IO range. 02431 02432 // Check if configInfo has the default information 02433 // if not, we go and find ourselves 02434 if (preConfig == FALSE) { 02435 02436 if (portBase) { 02437 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, 02438 ConfigInfo->AdapterInterfaceType, 02439 ConfigInfo->SystemIoBusNumber, 02440 ScsiPortConvertUlongToPhysicalAddress(portBase), 02441 8, 02442 TRUE); 02443 } else { 02444 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, 02445 ConfigInfo->AdapterInterfaceType, 02446 ConfigInfo->SystemIoBusNumber, 02447 ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount]), 02448 8, 02449 TRUE); 02450 } 02451 02452 } 02453 BaseIoAddress1 = (PIDE_REGISTERS_1)ioSpace; 02454 02455 // Update the adapter count. 02456 (*adapterCount)++; 02457 02458 // Check if ioSpace accessible. 02459 if (!ioSpace) { 02460 KdPrint2((PRINT_PREFIX "AtapiFindController: !ioSpace\n")); 02461 continue; 02462 } 02463 // check if Primary/Secondary Master IDE claimed 02464 if((ioSpace == (PUCHAR)IO_WD1) && 02465 (ConfigInfo->AtdiskPrimaryClaimed)) { 02466 KdPrint2((PRINT_PREFIX "AtapiFindController: AtdiskPrimaryClaimed\n")); 02467 goto not_found; 02468 } else 02469 if((ioSpace == (PUCHAR)IO_WD2) && 02470 (ConfigInfo->AtdiskSecondaryClaimed)) { 02471 KdPrint2((PRINT_PREFIX "AtapiFindController: AtdiskSecondaryClaimed\n")); 02472 goto not_found; 02473 } 02474 02475 // Get the system physical address for the second IO range. 02476 if (BaseIoAddress1) { 02477 if(preConfig && 02478 !ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[1].RangeStart)) { 02479 KdPrint2((PRINT_PREFIX "AtapiFindController: PCMCIA ?\n")); 02480 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, 02481 ConfigInfo->AdapterInterfaceType, 02482 ConfigInfo->SystemIoBusNumber, 02483 ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR)BaseIoAddress1 + 0x0E), 02484 ATA_ALTIOSIZE, 02485 TRUE); 02486 } else { 02487 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, 02488 ConfigInfo->AdapterInterfaceType, 02489 ConfigInfo->SystemIoBusNumber, 02490 ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR)BaseIoAddress1 + ATA_ALTOFFSET), 02491 ATA_ALTIOSIZE, 02492 TRUE); 02493 } 02494 } 02495 BaseIoAddress2 = (PIDE_REGISTERS_2)ioSpace; 02496 KdPrint2((PRINT_PREFIX " BaseIoAddress1=%x\n", BaseIoAddress1)); 02497 KdPrint2((PRINT_PREFIX " BaseIoAddress2=%x\n", BaseIoAddress2)); 02498 02499 UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2); 02500 UniataInitMapBM(deviceExtension, 0, FALSE); 02501 02502 retryIdentifier: 02503 02504 // Select master. 02505 SelectDrive(chan, 0); 02506 02507 // Check if card at this address. 02508 AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, 0xAA); 02509 02510 // Check if indentifier can be read back. 02511 if ((statusByte = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow)) != 0xAA) { 02512 02513 KdPrint2((PRINT_PREFIX "AtapiFindController: Identifier read back from Master (%#x)\n", 02514 statusByte)); 02515 02516 statusByte = AtapiReadPort1(chan, IDX_IO2_AltStatus); 02517 02518 if (statusByte & IDE_STATUS_BUSY) { 02519 02520 i = 0; 02521 02522 // Could be the TEAC in a thinkpad. Their dos driver puts it in a sleep-mode that 02523 // warm boots don't clear. 02524 do { 02525 AtapiStallExecution(1000); 02526 statusByte = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_Status); 02527 KdPrint2((PRINT_PREFIX 02528 "AtapiFindController: First access to status %#x\n", 02529 statusByte)); 02530 } while ((statusByte & IDE_STATUS_BUSY) && ++i < 10); 02531 02532 if (retryCount-- && (!(statusByte & IDE_STATUS_BUSY))) { 02533 goto retryIdentifier; 02534 } 02535 } 02536 02537 // Select slave. 02538 SelectDrive(chan, 1); 02539 02540 // See if slave is present. 02541 AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, 0xAA); 02542 02543 if ((statusByte = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow)) != 0xAA) { 02544 02545 KdPrint2((PRINT_PREFIX 02546 "AtapiFindController: Identifier read back from Slave (%#x)\n", 02547 statusByte)); 02548 not_found: 02549 // No controller at this base address. 02550 if(BaseIoAddress1) { 02551 ScsiPortFreeDeviceBase(HwDeviceExtension, 02552 (PCHAR)BaseIoAddress1); 02553 BaseIoAddress1 = NULL; 02554 } 02555 if(BaseIoAddress2) { 02556 ScsiPortFreeDeviceBase(HwDeviceExtension, 02557 (PCHAR)BaseIoAddress2); 02558 BaseIoAddress2 = NULL; 02559 } 02560 continue; 02561 } 02562 } 02563 02564 // Fill in the access array information only if default params are not in there. 02565 if (preConfig == FALSE) { 02566 02567 // An adapter has been found request another call, only if we didn't get preconfigured info. 02568 *Again = TRUE; 02569 02570 if (portBase) { 02571 (*ConfigInfo->AccessRanges)[0].RangeStart = ScsiPortConvertUlongToPhysicalAddress(portBase); 02572 } else { 02573 (*ConfigInfo->AccessRanges)[0].RangeStart = 02574 ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount - 1]); 02575 } 02576 02577 (*ConfigInfo->AccessRanges)[0].RangeLength = 8; 02578 (*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE; 02579 02580 // Indicate the interrupt level corresponding to this IO range. 02581 if (irq) { 02582 ConfigInfo->BusInterruptLevel = irq; 02583 } else { 02584 ConfigInfo->BusInterruptLevel = InterruptLevels[*adapterCount - 1]; 02585 } 02586 02587 if (ConfigInfo->AdapterInterfaceType == MicroChannel) { 02588 ConfigInfo->InterruptMode = LevelSensitive; 02589 } else { 02590 ConfigInfo->InterruptMode = Latched; 02591 } 02592 } 02593 02594 ConfigInfo->NumberOfBuses = 1; 02595 ConfigInfo->MaximumNumberOfTargets = IDE_MAX_LUN_PER_CHAN; 02596 02597 // Indicate maximum transfer length is 64k. 02598 ConfigInfo->MaximumTransferLength = 0x10000; 02599 deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength; 02600 02601 KdPrint2((PRINT_PREFIX "de %#x, Channel ???\n", deviceExtension)); 02602 //PrintNtConsole("de %#x, Channel %#x, nchan %#x\n",deviceExtension, channel, deviceExtension->NumberChannels); 02603 02604 KdPrint2((PRINT_PREFIX "chan = %#x\n", chan)); 02605 //PrintNtConsole("chan = %#x, c=%#x\n", chan, c); 02606 chan->DeviceExtension = deviceExtension; 02607 chan->lChannel = 0; 02608 chan->lun[0] = &(deviceExtension->lun[0]); 02609 chan->lun[1] = &(deviceExtension->lun[1]); 02610 02611 /* do extra channel-specific setups */ 02612 AtapiReadChipConfig(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, 0); 02613 AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, 0); 02614 02615 KdPrint2((PRINT_PREFIX 02616 "AtapiFindController: Found IDE at %#x\n", 02617 BaseIoAddress1)); 02618 02619 // For Daytona, the atdisk driver gets the first shot at the 02620 // primary and secondary controllers. 02621 if (preConfig == FALSE) { 02622 02623 if (*adapterCount - 1 < 2) { 02624 02625 // Determine whether this driver is being initialized by the 02626 // system or as a crash dump driver. 02627 if (ArgumentString) { 02628 02629 #ifndef UNIATA_CORE 02630 if (AtapiParseArgumentString(ArgumentString, "dump") == 1) { 02631 KdPrint2((PRINT_PREFIX 02632 "AtapiFindController: Crash dump\n")); 02633 atapiOnly = FALSE; 02634 deviceExtension->DriverMustPoll = TRUE; 02635 } else { 02636 KdPrint2((PRINT_PREFIX 02637 "AtapiFindController: Atapi Only\n")); 02638 atapiOnly = TRUE; 02639 deviceExtension->DriverMustPoll = FALSE; 02640 } 02641 #endif //UNIATA_CORE 02642 } else { 02643 02644 KdPrint2((PRINT_PREFIX 02645 "AtapiFindController: Atapi Only (2)\n")); 02646 atapiOnly = TRUE; 02647 deviceExtension->DriverMustPoll = FALSE; 02648 } 02649 02650 } else { 02651 atapiOnly = FALSE; 02652 } 02653 02654 } else { 02655 02656 atapiOnly = FALSE; 02657 deviceExtension->DriverMustPoll = FALSE; 02658 02659 }// preConfig check 02660 02661 // Save the Interrupe Mode for later use 02662 deviceExtension->InterruptMode = ConfigInfo->InterruptMode; 02663 02664 KdPrint2((PRINT_PREFIX 02665 "AtapiFindController: look for devices\n")); 02666 // Search for devices on this controller. 02667 if (FindDevices(HwDeviceExtension, 02668 0, 02669 0 /* Channel */)) { 02670 02671 KdPrint2((PRINT_PREFIX 02672 "AtapiFindController: detected\n")); 02673 // Claim primary or secondary ATA IO range. 02674 if (portBase) { 02675 switch (portBase) { 02676 case IO_WD2: 02677 ConfigInfo->AtdiskSecondaryClaimed = TRUE; 02678 chan->PrimaryAddress = FALSE; 02679 break; 02680 case IO_WD1: 02681 ConfigInfo->AtdiskPrimaryClaimed = TRUE; 02682 chan->PrimaryAddress = TRUE; 02683 break; 02684 default: 02685 break; 02686 } 02687 } else { 02688 if (*adapterCount == 1) { 02689 ConfigInfo->AtdiskPrimaryClaimed = TRUE; 02690 chan->PrimaryAddress = TRUE; 02691 } else if (*adapterCount == 2) { 02692 ConfigInfo->AtdiskSecondaryClaimed = TRUE; 02693 chan->PrimaryAddress = FALSE; 02694 } 02695 } 02696 02697 if(deviceExtension->AdapterInterfaceType == Isa) { 02698 IsaCount++; 02699 } else 02700 if(deviceExtension->AdapterInterfaceType == MicroChannel) { 02701 MCACount++; 02702 } 02703 02704 KdPrint2((PRINT_PREFIX 02705 "AtapiFindController: return SP_RETURN_FOUND\n")); 02706 return(SP_RETURN_FOUND); 02707 } 02708 #ifndef UNIATA_CORE 02709 } 02710 #else 02711 } while(FALSE); 02712 #endif //UNIATA_CORE 02713 02714 // The entire table has been searched and no adapters have been found. 02715 // There is no need to call again and the device base can now be freed. 02716 // Clear the adapter count for the next bus. 02717 *Again = FALSE; 02718 *(adapterCount) = 0; 02719 02720 KdPrint2((PRINT_PREFIX 02721 "AtapiFindController: return SP_RETURN_NOT_FOUND\n")); 02722 ExFreePool(deviceExtension->lun); 02723 ExFreePool(deviceExtension->chan); 02724 return(SP_RETURN_NOT_FOUND); 02725 02726 exit_error: 02727 if (deviceExtension->lun) ExFreePool(deviceExtension->lun); 02728 if (deviceExtension->chan) ExFreePool(deviceExtension->chan); 02729 return SP_RETURN_ERROR; 02730 02731 } // end AtapiFindController() 02732 02733 BOOLEAN 02734 NTAPI 02735 UniataAnybodyHome( 02736 IN PVOID HwDeviceExtension, 02737 IN ULONG lChannel, 02738 IN ULONG deviceNumber 02739 ) 02740 { 02741 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 02742 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]); 02743 //ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0); 02744 PHW_LU_EXTENSION LunExt = chan->lun[deviceNumber]; 02745 02746 SATA_SSTATUS_REG SStatus; 02747 UCHAR signatureLow; 02748 UCHAR signatureHigh; 02749 02750 if(LunExt->DeviceFlags & DFLAGS_HIDDEN) { 02751 KdPrint2((PRINT_PREFIX " hidden\n")); 02752 UniataForgetDevice(LunExt); 02753 return FALSE; 02754 } 02755 // Select the device. 02756 SelectDrive(chan, deviceNumber); 02757 02758 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow); 02759 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh); 02760 02761 if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) { 02762 KdPrint2((PRINT_PREFIX " ATAPI at home\n", signatureLow)); 02763 return TRUE; 02764 } 02765 02766 if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) { 02767 AtapiStallExecution(10); 02768 02769 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0x55); 02770 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0x55); 02771 AtapiStallExecution(5); 02772 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber); 02773 if(signatureLow != 0x55) { 02774 KdPrint2((PRINT_PREFIX " nobody home! %#x != 0x55\n", signatureLow)); 02775 UniataForgetDevice(LunExt); 02776 return FALSE; 02777 } 02778 02779 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0xAA); 02780 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0xAA); 02781 AtapiStallExecution(5); 02782 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber); 02783 if(signatureLow != 0xAA) { 02784 KdPrint2((PRINT_PREFIX " nobody home! %#x != 0xAA\n", signatureLow)); 02785 UniataForgetDevice(LunExt); 02786 return FALSE; 02787 } 02788 } else { 02789 02790 SStatus.Reg = UniataSataReadPort4(chan, IDX_SATA_SStatus, deviceNumber); 02791 KdPrint2((PRINT_PREFIX "SStatus %x\n", SStatus.Reg)); 02792 if(SStatus.DET <= SStatus_DET_Dev_NoPhy) { 02793 KdPrint2((PRINT_PREFIX " SATA DET <= SStatus_DET_Dev_NoPhy\n")); 02794 return FALSE; 02795 } 02796 if(SStatus.SPD < SStatus_SPD_Gen1) { 02797 KdPrint2((PRINT_PREFIX " SATA SPD < SStatus_SPD_Gen1\n")); 02798 return FALSE; 02799 } 02800 if(SStatus.IPM == SStatus_IPM_NoDev) { 02801 KdPrint2((PRINT_PREFIX " SATA IPN == SStatus_IPM_NoDev\n")); 02802 return FALSE; 02803 } 02804 } 02805 02806 return TRUE; 02807 } // end UniataAnybodyHome() 02808 02809 ULONG 02810 NTAPI 02811 CheckDevice( 02812 IN PVOID HwDeviceExtension, 02813 IN ULONG lChannel, 02814 IN ULONG deviceNumber, 02815 IN BOOLEAN ResetDev 02816 ) 02817 { 02818 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 02819 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]); 02820 //ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0); 02821 PHW_LU_EXTENSION LunExt; 02822 02823 UCHAR signatureLow, 02824 signatureHigh; 02825 UCHAR statusByte; 02826 ULONG RetVal=0; 02827 ULONG waitCount = 10000; 02828 02829 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x\n", 02830 deviceNumber)); 02831 02832 if(deviceNumber > chan->NumberLuns) { 02833 return 0; 02834 } 02835 02836 LunExt = chan->lun[deviceNumber]; 02837 02838 if(ResetDev && (deviceExtension->HwFlags & UNIATA_AHCI)) { 02839 KdPrint2((PRINT_PREFIX "CheckDevice: reset AHCI dev\n")); 02840 if(UniataAhciSoftReset(HwDeviceExtension, chan->lChannel, deviceNumber) == (ULONG)(-1)) { 02841 KdPrint2((PRINT_PREFIX "CheckDevice: (no dev)\n")); 02842 UniataForgetDevice(LunExt); 02843 return 0; 02844 } 02845 } else 02846 if(ResetDev) { 02847 KdPrint2((PRINT_PREFIX "CheckDevice: reset dev\n")); 02848 02849 // Reset device 02850 AtapiSoftReset(chan, deviceNumber); 02851 02852 if(!UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) { 02853 return 0; 02854 } 02855 statusByte = WaitOnBusy(chan); 02856 02857 if((statusByte | IDE_STATUS_BUSY) == 0xff) { 02858 KdPrint2((PRINT_PREFIX 02859 "CheckDevice: bad status %x\n", statusByte)); 02860 } else 02861 if(statusByte != 0xff && (statusByte & IDE_STATUS_BUSY)) { 02862 // Perform hard-reset. 02863 KdPrint2((PRINT_PREFIX 02864 "CheckDevice: BUSY\n")); 02865 02866 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER ); 02867 AtapiStallExecution(500 * 1000); 02868 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER); 02869 SelectDrive(chan, deviceNumber & 0x01); 02870 02871 do { 02872 // Wait for Busy to drop. 02873 AtapiStallExecution(100); 02874 GetStatus(chan, statusByte); 02875 02876 } while ((statusByte & IDE_STATUS_BUSY) && waitCount--); 02877 02878 GetBaseStatus(chan, statusByte); 02879 KdPrint2((PRINT_PREFIX 02880 "CheckDevice: status after hard reset %x\n", statusByte)); 02881 } 02882 02883 if((statusByte | IDE_STATUS_BUSY) == 0xff) { 02884 KdPrint2((PRINT_PREFIX 02885 "CheckDevice: no dev ?\n")); 02886 } else 02887 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) { 02888 //if(deviceExtension->HwFlags & UNIATA_SATA) { 02889 KdPrint2((PRINT_PREFIX 02890 "CheckDevice: try enable SATA Phy\n")); 02891 statusByte = UniataSataPhyEnable(HwDeviceExtension, lChannel, deviceNumber); 02892 if(statusByte == 0xff) { 02893 KdPrint2((PRINT_PREFIX "CheckDevice: status %#x (no dev)\n", statusByte)); 02894 UniataForgetDevice(LunExt); 02895 return 0; 02896 } 02897 } 02898 } 02899 02900 if(deviceExtension->HwFlags & UNIATA_AHCI) { 02901 RetVal = LunExt->DeviceFlags; 02902 signatureLow = signatureHigh = 0; // make GCC happy 02903 } else { 02904 // Select the device. 02905 SelectDrive(chan, deviceNumber); 02906 02907 if(!UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) { 02908 return 0; 02909 } 02910 02911 statusByte = WaitOnBaseBusyLong(chan); 02912 02913 GetBaseStatus(chan, statusByte); 02914 if(deviceExtension->HwFlags & UNIATA_SATA) { 02915 UniataSataClearErr(HwDeviceExtension, lChannel, UNIATA_SATA_IGNORE_CONNECT, deviceNumber); 02916 } 02917 02918 KdPrint2((PRINT_PREFIX "CheckDevice: status %#x\n", statusByte)); 02919 if(((statusByte | IDE_STATUS_BUSY) == 0xff) || 02920 (statusByte & IDE_STATUS_BUSY)) { 02921 KdPrint2((PRINT_PREFIX "CheckDevice: busy => return\n")); 02922 UniataForgetDevice(LunExt); 02923 return 0; 02924 } 02925 02926 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow); 02927 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh); 02928 } 02929 02930 // set default costs 02931 LunExt->RwSwitchCost = REORDER_COST_SWITCH_RW_HDD; 02932 LunExt->RwSwitchMCost = REORDER_MCOST_SWITCH_RW_HDD; 02933 LunExt->SeekBackMCost = REORDER_MCOST_SEEK_BACK_HDD; 02934 02935 if(deviceExtension->HwFlags & UNIATA_AHCI) { 02936 if(RetVal & DFLAGS_DEVICE_PRESENT) { 02937 if(IssueIdentify(HwDeviceExtension, 02938 deviceNumber, 02939 lChannel, 02940 (RetVal & DFLAGS_ATAPI_DEVICE) ? IDE_COMMAND_ATAPI_IDENTIFY : IDE_COMMAND_IDENTIFY, 02941 FALSE)) { 02942 // OK 02943 KdPrint2((PRINT_PREFIX "CheckDevice: detected AHCI Device %#x\n", 02944 deviceNumber)); 02945 } else { 02946 RetVal &= ~DFLAGS_ATAPI_DEVICE; 02947 LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE; 02948 } 02949 } 02950 } else 02951 if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) { 02952 02953 KdPrint2((PRINT_PREFIX "CheckDevice: ATAPI signature found\n")); 02954 // ATAPI signature found. 02955 // Issue the ATAPI identify command if this 02956 // is not for the crash dump utility. 02957 02958 if (!deviceExtension->DriverMustPoll) { 02959 02960 // Issue ATAPI packet identify command. 02961 if (IssueIdentify(HwDeviceExtension, 02962 deviceNumber, 02963 lChannel, 02964 IDE_COMMAND_ATAPI_IDENTIFY, FALSE)) { 02965 02966 // Indicate ATAPI device. 02967 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x is ATAPI\n", 02968 deviceNumber)); 02969 02970 RetVal = DFLAGS_DEVICE_PRESENT | DFLAGS_ATAPI_DEVICE; 02971 LunExt->DeviceFlags |= (DFLAGS_DEVICE_PRESENT | DFLAGS_ATAPI_DEVICE); 02972 02973 // some ATAPI devices doesn't work with DPC on CMD-649 02974 // and probably some other controllers 02975 if(deviceExtension->HwFlags & UNIATA_NO_DPC_ATAPI) { 02976 /* CMD 649, ROSB SWK33, ICH4 */ 02977 KdPrint2((PRINT_PREFIX "CheckDevice: UNIATA_NO_DPC_ATAPI\n")); 02978 deviceExtension->UseDpc = FALSE; 02979 } 02980 02981 GetStatus(chan, statusByte); 02982 if (statusByte & IDE_STATUS_ERROR) { 02983 AtapiSoftReset(chan, deviceNumber); 02984 } 02985 02986 } else { 02987 02988 // Indicate no working device. 02989 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x not responding\n", 02990 deviceNumber)); 02991 02992 UniataForgetDevice(LunExt); 02993 RetVal = 0; 02994 } 02995 GetBaseStatus(chan, statusByte); 02996 02997 } 02998 02999 } else { 03000 03001 KdPrint2((PRINT_PREFIX "CheckDevice: IDE device check\n")); 03002 // Issue IDE Identify. If an Atapi device is actually present, the signature 03003 // will be asserted, and the drive will be recognized as such. 03004 if(deviceExtension->DWordIO) { 03005 KdPrint2((PRINT_PREFIX " try 32bit IO\n")); 03006 LunExt->DeviceFlags |= DFLAGS_DWORDIO_ENABLED; 03007 } 03008 if (IssueIdentify(HwDeviceExtension, 03009 deviceNumber, 03010 lChannel, 03011 IDE_COMMAND_IDENTIFY, FALSE)) { 03012 03013 // IDE drive found. 03014 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x is IDE\n", 03015 deviceNumber)); 03016 03017 // Indicate IDE - not ATAPI device. 03018 RetVal = DFLAGS_DEVICE_PRESENT; 03019 LunExt->DeviceFlags |= DFLAGS_DEVICE_PRESENT; 03020 LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE; 03021 } 03022 GetBaseStatus(chan, statusByte); 03023 } 03024 KdPrint2((PRINT_PREFIX "CheckDevice: check status: %sfound\n", RetVal ? "" : "not ")); 03025 return RetVal; 03026 } // end CheckDevice() 03027 03028 03029 /*++ 03030 03031 Routine Description: 03032 03033 This routine is called from AtapiFindController to identify 03034 devices attached to an IDE controller. 03035 03036 Arguments: 03037 03038 HwDeviceExtension - HBA miniport driver's adapter data storage 03039 AtapiOnly - Indicates that routine should return TRUE only if 03040 an ATAPI device is attached to the controller. 03041 03042 Return Value: 03043 03044 TRUE - True if devices found. 03045 03046 --*/ 03047 BOOLEAN 03048 NTAPI 03049 FindDevices( 03050 IN PVOID HwDeviceExtension, 03051 IN ULONG Flags, 03052 IN ULONG Channel 03053 ) 03054 { 03055 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 03056 PHW_CHANNEL chan = &(deviceExtension->chan[Channel]); 03057 PHW_LU_EXTENSION LunExt; 03058 BOOLEAN deviceResponded = FALSE, 03059 skipSetParameters = FALSE; 03060 ULONG waitCount = 10000; 03061 //ULONG deviceNumber; 03062 ULONG i; 03063 UCHAR statusByte; 03064 ULONG max_ldev; 03065 BOOLEAN AtapiOnly = FALSE; 03066 03067 KdPrint2((PRINT_PREFIX "FindDevices:\n")); 03068 03069 // Disable interrupts 03070 AtapiDisableInterrupts(deviceExtension, Channel); 03071 // AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_DISABLE_INTERRUPTS | IDE_DC_A_4BIT ); 03072 03073 // Clear expecting interrupt flag and current SRB field. 03074 chan->ExpectingInterrupt = FALSE; 03075 // chan->CurrentSrb = NULL; 03076 // max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : IDE_MAX_LUN_PER_CHAN; 03077 max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : deviceExtension->NumberLuns; 03078 KdPrint2((PRINT_PREFIX " max_ldev %d\n", max_ldev)); 03079 03080 // Search for devices. 03081 for (i = 0; i < max_ldev; i++) { 03082 //AtapiDisableInterrupts(deviceExtension, Channel); 03083 if(Flags & UNIATA_FIND_DEV_UNHIDE) { 03084 chan->lun[i]->DeviceFlags &= ~DFLAGS_HIDDEN; 03085 } 03086 deviceResponded |= 03087 (CheckDevice(HwDeviceExtension, Channel, i, TRUE) != 0); 03088 //AtapiEnableInterrupts(deviceExtension, Channel); 03089 } 03090 03091 if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) { 03092 AtapiEnableInterrupts(deviceExtension, Channel); 03093 KdPrint2((PRINT_PREFIX 03094 "FindDevices: returning %d (AHCI)\n", 03095 deviceResponded)); 03096 return deviceResponded; 03097 } 03098 03099 for (i = 0; i < max_ldev; i++) { 03100 LunExt = chan->lun[i]; 03101 03102 if (( LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT) && 03103 !(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) && 03104 !(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) && deviceResponded) { 03105 03106 // This hideous hack is to deal with ESDI devices that return 03107 // garbage geometry in the IDENTIFY data. 03108 // This is ONLY for the crashdump environment as 03109 // these are ESDI devices. 03110 if (LunExt->IdentifyData.SectorsPerTrack == 03111 0x35 && 03112 LunExt->IdentifyData.NumberOfHeads == 03113 0x07) { 03114 03115 KdPrint2((PRINT_PREFIX 03116 "FindDevices: Found nasty Compaq ESDI!\n")); 03117 03118 // Change these values to something reasonable. 03119 LunExt->IdentifyData.SectorsPerTrack = 03120 0x34; 03121 LunExt->IdentifyData.NumberOfHeads = 03122 0x0E; 03123 } 03124 03125 if (LunExt->IdentifyData.SectorsPerTrack == 03126 0x35 && 03127 LunExt->IdentifyData.NumberOfHeads == 03128 0x0F) { 03129 03130 KdPrint2((PRINT_PREFIX 03131 "FindDevices: Found nasty Compaq ESDI!\n")); 03132 03133 // Change these values to something reasonable. 03134 LunExt->IdentifyData.SectorsPerTrack = 03135 0x34; 03136 LunExt->IdentifyData.NumberOfHeads = 03137 0x0F; 03138 } 03139 03140 03141 if (LunExt->IdentifyData.SectorsPerTrack == 03142 0x36 && 03143 LunExt->IdentifyData.NumberOfHeads == 03144 0x07) { 03145 03146 KdPrint2((PRINT_PREFIX "FindDevices: Found nasty UltraStor ESDI!\n")); 03147 03148 // Change these values to something reasonable. 03149 LunExt->IdentifyData.SectorsPerTrack = 03150 0x3F; 03151 LunExt->IdentifyData.NumberOfHeads = 03152 0x10; 03153 skipSetParameters = TRUE; 03154 } 03155 03156 03157 if (skipSetParameters) 03158 continue; 03159 03160 statusByte = WaitOnBusy(chan); 03161 03162 // Select the device. 03163 SelectDrive(chan, i & 0x01); 03164 GetStatus(chan, statusByte); 03165 03166 if (statusByte & IDE_STATUS_ERROR) { 03167 03168 // Reset the device. 03169 KdPrint2((PRINT_PREFIX 03170 "FindDevices: Resetting controller before SetDriveParameters.\n")); 03171 03172 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER ); 03173 AtapiStallExecution(500 * 1000); 03174 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER); 03175 SelectDrive(chan, i & 0x01); 03176 03177 do { 03178 // Wait for Busy to drop. 03179 AtapiStallExecution(100); 03180 GetStatus(chan, statusByte); 03181 03182 } while ((statusByte & IDE_STATUS_BUSY) && waitCount--); 03183 } 03184 03185 statusByte = WaitOnBusy(chan); 03186 03187 KdPrint2((PRINT_PREFIX 03188 "FindDevices: Status before SetDriveParameters: (%#x) (%#x)\n", 03189 statusByte, 03190 AtapiReadPort1(chan, IDX_IO1_i_DriveSelect))); 03191 03192 GetBaseStatus(chan, statusByte); 03193 03194 // Use the IDENTIFY data to set drive parameters. 03195 if (!SetDriveParameters(HwDeviceExtension,i,Channel)) { 03196 03197 KdPrint2((PRINT_PREFIX 03198 "FindDevices: Set drive parameters for device %d failed\n", 03199 i)); 03200 // Don't use this device as writes could cause corruption. 03201 LunExt->DeviceFlags &= ~DFLAGS_DEVICE_PRESENT; 03202 UniataForgetDevice(LunExt); 03203 continue; 03204 03205 } 03206 if (LunExt->DeviceFlags & DFLAGS_REMOVABLE_DRIVE) { 03207 03208 // Pick up ALL IDE removable drives that conform to Yosemite V0.2... 03209 AtapiOnly = FALSE; 03210 } 03211 03212 // Indicate that a device was found. 03213 if (!AtapiOnly) { 03214 deviceResponded = TRUE; 03215 } 03216 } 03217 } 03218 03219 /* // Reset the controller. This is a feeble attempt to leave the ESDI 03220 // controllers in a state that ATDISK driver will recognize them. 03221 // The problem in ATDISK has to do with timings as it is not reproducible 03222 // in debug. The reset should restore the controller to its poweron state 03223 // and give the system enough time to settle. 03224 if (!deviceResponded) { 03225 03226 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_RESET_CONTROLLER ); 03227 AtapiStallExecution(50 * 1000); 03228 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_REENABLE_CONTROLLER); 03229 } 03230 */ 03231 if(deviceResponded) { 03232 for (i = 0; i < max_ldev; i++) { 03233 LunExt = chan->lun[i]; 03234 03235 KdPrint2((PRINT_PREFIX 03236 "FindDevices: select %d dev to clear INTR\n", i)); 03237 SelectDrive(chan, i); 03238 GetBaseStatus(chan, statusByte); 03239 KdPrint2((PRINT_PREFIX 03240 "FindDevices: statusByte=%#x\n", statusByte)); 03241 } 03242 for (i = 0; i < max_ldev; i++) { 03243 LunExt = chan->lun[i]; 03244 03245 if(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT) { 03246 // Make sure some device (master is preferred) is selected on exit. 03247 KdPrint2((PRINT_PREFIX 03248 "FindDevices: select %d dev on exit\n", i)); 03249 SelectDrive(chan, i); 03250 break; 03251 } 03252 } 03253 } 03254 03255 GetBaseStatus(chan, statusByte); 03256 // Enable interrupts 03257 AtapiEnableInterrupts(deviceExtension, Channel); 03258 // AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_A_4BIT ); 03259 GetBaseStatus(chan, statusByte); 03260 03261 KdPrint2((PRINT_PREFIX 03262 "FindDevices: returning %d\n", 03263 deviceResponded)); 03264 03265 return deviceResponded; 03266 03267 } // end FindDevices() Generated on Sat May 26 2012 04:26:57 for ReactOS by
1.7.6.1
|