3 Copyright (c) 2002-2010 Alexandr A. Telyatnikov (Alter)
9 This module scans PCI and ISA buses for IDE controllers
10 and determines their Busmaster DMA capabilities
13 Alexander A. Telyatnikov (Alter)
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 Some parts of hardware-specific code were taken from FreeBSD 4.3-6.1 ATA driver by
34 Søren Schmidt, Copyright (c) 1998-2007
36 Some parts of device detection code were taken from from standard ATAPI.SYS from NT4 DDK by
40 Device search/init algorithm is completly rewritten by
41 Alter, Copyright (c) 2002-2004
43 Fixes for Native/Compatible modes of onboard IDE controller by
44 Vitaliy Vorobyov, deathsoft@yandex.ru (c) 2004
50 PBUSMASTER_CONTROLLER_INFORMATION BMList
= NULL
;
55 BOOLEAN FirstMasterOk
= FALSE
;
62 PDRIVER_OBJECT SavedDriverObject
= NULL
;
68 UniataEnumBusMasterController__(
69 /* IN PVOID HwDeviceExtension,
71 IN PVOID BusInformation,
72 IN PCHAR ArgumentString,
73 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
82 } // end AtapiDoNothing()
87 Get PCI address by ConfigInfo and RID
92 IN PVOID HwDeviceExtension
,
93 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
94 IN PPCI_COMMON_CONFIG pciData
,
95 IN ULONG SystemIoBusNumber
,
96 IN ULONG rid
, //range id
101 ULONG_PTR io_start
= 0;
102 KdPrint2((PRINT_PREFIX
" AtapiGetIoRange:\n"));
104 if(ConfigInfo
->NumberOfAccessRanges
<= rid
)
107 KdPrint2((PRINT_PREFIX
" AtapiGetIoRange: rid %#x, start %#x, offs %#x, len %#x, mem %#x\n",
109 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[rid
].RangeStart
),
112 (*ConfigInfo
->AccessRanges
)[rid
].RangeInMemory
115 if((*ConfigInfo
->AccessRanges
)[rid
].RangeInMemory
) {
117 // Get the system physical address for this IO range.
118 ((ULONG_PTR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
119 PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
120 SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
121 ScsiPortConvertUlongToPhysicalAddress(
122 (ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[rid
].RangeStart
) &
123 ~0x07/*PCI_ADDRESS_IOMASK*/) + offset
126 (BOOLEAN
)!(*ConfigInfo
->AccessRanges
)[rid
].RangeInMemory
)
129 KdPrint2((PRINT_PREFIX
" AtapiGetIoRange: %#x\n", io_start
));
130 // if(io_start > offset) {
135 io_start
= (pciData
->u
.type0
.BaseAddresses
[rid
] & ~0x07/*PCI_ADDRESS_IOMASK*/) + offset
;
136 // if(pciData->u.type0.BaseAddresses[rid] != 0) ;)
137 if(io_start
> offset
) {
138 if(/*(WinVer_Id() <= WinVer_NT) &&*/ offset
&& rid
== 4) {
139 // MS atapi.sys does so for BusMaster controllers
140 (*ConfigInfo
->AccessRanges
)[rid
+1].RangeStart
=
141 ScsiPortConvertUlongToPhysicalAddress(io_start
);
142 (*ConfigInfo
->AccessRanges
)[rid
+1].RangeLength
= length
;
144 (*ConfigInfo
->AccessRanges
)[rid
].RangeStart
=
145 ScsiPortConvertUlongToPhysicalAddress(io_start
);
146 (*ConfigInfo
->AccessRanges
)[rid
].RangeLength
= length
;
151 KdPrint2((PRINT_PREFIX
" AtapiGetIoRange: (2) %#x\n", io_start
));
154 } // end AtapiGetIoRange()
159 Do nothing, but build list of supported IDE controllers
160 It is a hack, ScsiPort architecture assumes, that DriverEntry
161 can support only KNOWN Vendor/Device combinations.
162 Thus, we build list here. Later will pretend that always knew
165 We shall initiate ISA device init, but callback will use
166 Hal routines directly in order to scan PCI bus.
170 UniataEnumBusMasterController(
171 IN PVOID DriverObject
,
175 UniataEnumBusMasterController__();
177 } // end UniataEnumBusMasterController()
181 UniataCheckPCISubclass(
188 if((RaidFlags
& UNIATA_RAID_CONTROLLER
) &&
190 KdPrint2((PRINT_PREFIX
"Skip RAID\n"));
195 KdPrint2((PRINT_PREFIX
"unknown\n"));
198 case PCI_DEV_SUBCLASS_RAID
:
200 KdPrint2((PRINT_PREFIX
"Skip RAID (2)\n"));
204 case PCI_DEV_SUBCLASS_IDE
:
205 case PCI_DEV_SUBCLASS_ATA
:
206 case PCI_DEV_SUBCLASS_SATA
:
209 KdPrint2((PRINT_PREFIX
"Subclass not supported\n"));
213 } // end UniataCheckPCISubclass()
216 Device initializaton callback
217 Builds PCI device list using Hal routines (not ScsiPort wrappers)
221 UniataEnumBusMasterController__(
224 // PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
225 PVOID HwDeviceExtension
;
226 PHW_DEVICE_EXTENSION deviceExtension
= NULL
;
227 PCI_SLOT_NUMBER slotData
;
228 PCI_COMMON_CONFIG pciData
;
232 BOOLEAN no_buses
= FALSE
;
233 BOOLEAN no_ranges
= FALSE
;
235 // BOOLEAN SimplexOnly;
237 UCHAR vendorString
[5];
238 UCHAR deviceString
[5];
242 UCHAR BaseClass
; // (ro)
243 UCHAR SubClass
; // (ro)
256 UCHAR IrqForCompat
= 10;
258 vendorStrPtr
= vendorString
;
259 deviceStrPtr
= deviceString
;
260 slotData
.u
.AsULONG
= 0;
263 deviceExtension
= (PHW_DEVICE_EXTENSION
)ExAllocatePool(NonPagedPool
, sizeof(HW_DEVICE_EXTENSION
));
264 if(!deviceExtension
) {
265 return(SP_RETURN_NOT_FOUND
);
267 RtlZeroMemory(deviceExtension
, sizeof(HW_DEVICE_EXTENSION
));
269 for(pass
=0; pass
<3; pass
++) {
270 for(busNumber
=0 ;busNumber
<maxPciBus
&& !no_buses
; busNumber
++) {
271 for(slotNumber
=0; slotNumber
<PCI_MAX_DEVICES
&& !no_buses
; slotNumber
++) {
272 for(funcNumber
=0; funcNumber
<PCI_MAX_FUNCTION
&& !no_buses
; funcNumber
++) {
274 // KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x\n",busNumber,slotNumber,funcNumber));
275 slotData
.u
.bits
.DeviceNumber
= slotNumber
;
276 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
278 busDataRead
= HalGetBusData
282 PCIConfiguration
, busNumber
, slotData
.u
.AsULONG
,
283 &pciData
, PCI_COMMON_HDR_LENGTH
);
287 maxPciBus
= busNumber
;
290 // no device in this slot
294 if(busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
)
297 VendorID
= pciData
.VendorID
;
298 DeviceID
= pciData
.DeviceID
;
299 BaseClass
= pciData
.BaseClass
;
300 SubClass
= pciData
.SubClass
;
301 dev_id
= VendorID
| (DeviceID
<< 16);
302 //KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass ));
304 if(BaseClass
!= PCI_DEV_CLASS_STORAGE
)
307 KdPrint2((PRINT_PREFIX
"Storage Class\n"));
308 KdPrint2((PRINT_PREFIX
"DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id
, BaseClass
, SubClass
));
309 // look for known chipsets
313 if(deviceExtension
) {
314 deviceExtension
->slotNumber
= slotData
.u
.AsULONG
;
315 deviceExtension
->SystemIoBusNumber
= busNumber
;
316 deviceExtension
->DevID
= dev_id
;
317 deviceExtension
->RevID
= pciData
.RevisionID
;
318 deviceExtension
->AdapterInterfaceType
= PCIBus
;
321 found
= (BOOLEAN
)AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"Include", 0);
323 KdPrint2((PRINT_PREFIX
"No force include, check exclude\n"));
324 found
= !AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"Exclude", 0);
326 KdPrint2((PRINT_PREFIX
"Device excluded\n"));
331 //known = UniataChipDetect(HwDeviceExtension, NULL, -1, ConfigInfo, &SimplexOnly);
332 i
= Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[0], VendorID
, DeviceID
, 0, NUM_BUSMASTER_ADAPTERS
);
334 known
= (i
!= BMLIST_TERMINATOR
);
336 deviceExtension
->FullDevName
= BusMasterAdapters
[i
].FullDevName
;
337 RaidFlags
= BusMasterAdapters
[i
].RaidFlags
;
339 deviceExtension
->FullDevName
= "Unknown Storage";
342 found
= UniataCheckPCISubclass(known
, RaidFlags
, SubClass
);
344 KdPrint2((PRINT_PREFIX
"Subclass not supported\n"));
349 /* additional checks for some supported chipsets */
351 if (SubClass
!= PCI_DEV_SUBCLASS_IDE
)
355 /* unknown chipsets, try generic DMA if it seems possible */
357 KdPrint2((PRINT_PREFIX
"Default device\n"));
358 if(Ata_is_supported_dev(&pciData
))
365 KdPrint2((PRINT_PREFIX
"found, pass %d\n", pass
));
367 KdPrint2((PRINT_PREFIX
"InterruptPin = %#x\n", pciData
.u
.type0
.InterruptPin
));
368 KdPrint2((PRINT_PREFIX
"InterruptLine = %#x\n", pciData
.u
.type0
.InterruptLine
));
371 // Enable Busmastering, IO-space and Mem-space
372 KdPrint2((PRINT_PREFIX
"Enabling Mem/Io spaces and busmastering...\n"));
373 KdPrint2((PRINT_PREFIX
"Initial pciData.Command = %#x\n", pciData
.Command
));
377 KdPrint2((PRINT_PREFIX
"PCI_ENABLE_IO_SPACE\n"));
378 pciData
.Command
|= PCI_ENABLE_IO_SPACE
;
381 KdPrint2((PRINT_PREFIX
"PCI_ENABLE_MEMORY_SPACE\n"));
382 pciData
.Command
|= PCI_ENABLE_MEMORY_SPACE
;
385 KdPrint2((PRINT_PREFIX
"PCI_ENABLE_BUS_MASTER\n"));
386 pciData
.Command
|= PCI_ENABLE_BUS_MASTER
;
389 HalSetBusDataByOffset( PCIConfiguration
, busNumber
, slotData
.u
.AsULONG
,
391 offsetof(PCI_COMMON_CONFIG
, Command
),
392 sizeof(pciData
.Command
));
393 KdPrint2((PRINT_PREFIX
"InterruptLine = %#x\n", pciData
.u
.type0
.InterruptLine
));
395 // reread config space
396 busDataRead
= HalGetBusData(PCIConfiguration
, busNumber
, slotData
.u
.AsULONG
,
397 &pciData
, PCI_COMMON_HDR_LENGTH
);
398 KdPrint2((PRINT_PREFIX
"New pciData.Command = %#x\n", pciData
.Command
));
400 KdPrint2((PRINT_PREFIX
"Final pciData.Command = %#x\n", pciData
.Command
));
402 // validate Mem/Io ranges
404 for(i
=0; i
<PCI_TYPE0_ADDRESSES
; i
++) {
405 if(pciData
.u
.type0
.BaseAddresses
[i
] & ~0x7) {
408 KdPrint2((PRINT_PREFIX
"Range %d = %#x\n", i
, pciData
.u
.type0
.BaseAddresses
[i
]));
412 KdPrint2((PRINT_PREFIX
"No PCI Mem/Io ranges found on device, skip it\n"));
417 // fill list of detected devices
418 // it'll be used for further init
419 KdPrint2((PRINT_PREFIX
"found suitable device\n"));
420 PBUSMASTER_CONTROLLER_INFORMATION newBMListPtr
= BMList
+BMListLen
;
423 if(!IsMasterDev(&pciData
)) {
426 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"NativePCIMode", 0)) {
427 KdPrint2((PRINT_PREFIX
"try switch to native mode\n"));
429 IrqForCompat
= (UCHAR
)AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"NativePCIModeIRQ", 0xff);
430 KdPrint2((PRINT_PREFIX
"IrqForCompat = %#x\n", IrqForCompat
));
431 if((IrqForCompat
& 0xffffff00) /*||
432 (IrqForCompat & 0xff) > 31*/ ||
433 (IrqForCompat
== 0xff)) {
435 KdPrint2((PRINT_PREFIX
"default to IRQ 11\n"));
438 //ChangePciConfig1(0x09, a | PCI_IDE_PROGIF_NATIVE_ALL); // ProgIf
439 pciData
.ProgIf
|= PCI_IDE_PROGIF_NATIVE_ALL
;
440 HalSetBusDataByOffset( PCIConfiguration
, busNumber
, slotData
.u
.AsULONG
,
442 offsetof(PCI_COMMON_CONFIG
, ProgIf
),
443 sizeof(pciData
.ProgIf
));
445 // reread config space
446 busDataRead
= HalGetBusData(PCIConfiguration
, busNumber
, slotData
.u
.AsULONG
,
447 &pciData
, PCI_COMMON_HDR_LENGTH
);
448 // check if the device have switched to Native Mode
449 if(IsMasterDev(&pciData
)) {
450 KdPrint2((PRINT_PREFIX
"Can't switch to native mode\n"));
452 KdPrint2((PRINT_PREFIX
"switched to native mode\n"));
453 KdPrint2((PRINT_PREFIX
"InterruptPin = %#x\n", pciData
.u
.type0
.InterruptPin
));
454 KdPrint2((PRINT_PREFIX
"InterruptLine = %#x\n", pciData
.u
.type0
.InterruptLine
));
455 // check if IRQ is assigned to device
456 if(!(pciData
.u
.type0
.InterruptLine
) ||
457 (pciData
.u
.type0
.InterruptLine
== 0xff)) {
458 KdPrint2((PRINT_PREFIX
"assign interrupt for device\n"));
459 pciData
.u
.type0
.InterruptLine
= IrqForCompat
;
460 HalSetBusDataByOffset( PCIConfiguration
, busNumber
, slotData
.u
.AsULONG
,
461 &(pciData
.u
.type0
.InterruptLine
),
462 offsetof(PCI_COMMON_CONFIG
, u
.type0
.InterruptLine
),
463 sizeof(pciData
.u
.type0
.InterruptLine
));
465 KdPrint2((PRINT_PREFIX
"Auto-assigned interrupt line %#x\n",
466 pciData
.u
.type0
.InterruptLine
));
467 IrqForCompat
= pciData
.u
.type0
.InterruptLine
;
469 KdPrint2((PRINT_PREFIX
"reread config space\n"));
470 // reread config space
471 busDataRead
= HalGetBusData(PCIConfiguration
, busNumber
, slotData
.u
.AsULONG
,
472 &pciData
, PCI_COMMON_HDR_LENGTH
);
473 KdPrint2((PRINT_PREFIX
"busDataRead = %#x\n", busDataRead
));
474 KdPrint2((PRINT_PREFIX
"reread InterruptLine = %#x\n", pciData
.u
.type0
.InterruptLine
));
475 // check if we have successfully assigned IRQ to device
476 if((pciData
.u
.type0
.InterruptLine
!= IrqForCompat
) ||
477 (pciData
.u
.type0
.InterruptLine
== 0xff) ||
478 !pciData
.u
.type0
.InterruptLine
) {
479 KdPrint2((PRINT_PREFIX
"can't assign interrupt for device, revert to compat mode\n"));
480 pciData
.u
.type0
.InterruptLine
= 0xff;
481 KdPrint2((PRINT_PREFIX
"set IntrLine to 0xff\n"));
482 HalSetBusDataByOffset( PCIConfiguration
, busNumber
, slotData
.u
.AsULONG
,
483 &(pciData
.u
.type0
.InterruptLine
),
484 offsetof(PCI_COMMON_CONFIG
, u
.type0
.InterruptLine
),
485 sizeof(pciData
.u
.type0
.InterruptLine
));
486 KdPrint2((PRINT_PREFIX
"clear PCI_IDE_PROGIF_NATIVE_ALL\n"));
487 pciData
.ProgIf
&= ~PCI_IDE_PROGIF_NATIVE_ALL
;
488 HalSetBusDataByOffset( PCIConfiguration
, busNumber
, slotData
.u
.AsULONG
,
490 offsetof(PCI_COMMON_CONFIG
, ProgIf
),
491 sizeof(pciData
.ProgIf
));
492 // reread config space
493 KdPrint2((PRINT_PREFIX
"reread config space on revert\n"));
494 busDataRead
= HalGetBusData(PCIConfiguration
, busNumber
, slotData
.u
.AsULONG
,
495 &pciData
, PCI_COMMON_HDR_LENGTH
);
497 KdPrint2((PRINT_PREFIX
"Assigned interrupt %#x for device\n", IrqForCompat
));
498 KdPrint2((PRINT_PREFIX
"continue detection on next round\n"));
505 if(IsMasterDev(&pciData
))
510 RtlCopyMemory(newBMListPtr, (PVOID)&(BusMasterAdapters[i]), sizeof(BUSMASTER_CONTROLLER_INFORMATION));
512 sprintf((PCHAR
)vendorStrPtr
, "%4.4lx", VendorID
);
513 sprintf((PCHAR
)deviceStrPtr
, "%4.4lx", DeviceID
);
515 RtlCopyMemory(&(newBMListPtr
->VendorIdStr
), (PCHAR
)vendorStrPtr
, 4);
516 RtlCopyMemory(&(newBMListPtr
->DeviceIdStr
), (PCHAR
)deviceStrPtr
, 4);
518 newBMListPtr
->nVendorId
= VendorID
;
519 newBMListPtr
->VendorId
= (PCHAR
)&(newBMListPtr
->VendorIdStr
);
520 newBMListPtr
->VendorIdLength
= 4;
521 newBMListPtr
->nDeviceId
= DeviceID
;
522 newBMListPtr
->DeviceId
= (PCHAR
)&(newBMListPtr
->DeviceIdStr
);
523 newBMListPtr
->DeviceIdLength
= 4;
525 newBMListPtr
->RaidFlags
= RaidFlags
;
527 newBMListPtr
->slotNumber
= slotData
.u
.AsULONG
;
528 newBMListPtr
->MasterDev
= IsMasterDev(&pciData
) ? 1 : 0;
529 newBMListPtr
->busNumber
= busNumber
;
531 newBMListPtr
->Known
= known
;
533 KdPrint2((PRINT_PREFIX
"Add to BMList\n"));
535 KdPrint2((PRINT_PREFIX
"count: BMListLen++\n"));
546 BMList
= (PBUSMASTER_CONTROLLER_INFORMATION
)ExAllocatePool(NonPagedPool
,
547 (BMListLen
+1)*sizeof(BUSMASTER_CONTROLLER_INFORMATION
));
552 RtlZeroMemory(BMList
, (BMListLen
+1)*sizeof(BUSMASTER_CONTROLLER_INFORMATION
));
557 KdPrint2((PRINT_PREFIX
" BMListLen=%x\n", BMListLen
));
558 if(deviceExtension
) {
559 ExFreePool(deviceExtension
);
561 return(SP_RETURN_NOT_FOUND
);
562 } // end UniataEnumBusMasterController__()
566 Wrapper for read PCI config space
570 ScsiPortGetBusDataByOffset(
571 IN PVOID HwDeviceExtension
,
572 IN BUS_DATA_TYPE BusDataType
,
583 if(Offset
+Length
> 256)
586 busDataRead
= HalGetBusData(
587 //ScsiPortGetBusData(HwDeviceExtension,
593 if(busDataRead
< Offset
+Length
) {
594 if(busDataRead
< Offset
)
596 return (Offset
+Length
-busDataRead
);
598 RtlCopyMemory(Buffer
, tmp
+Offset
, Length
);
600 } // end ScsiPortGetBusDataByOffset()
603 Looks for devices from list on specified bus(es)/slot(s)
604 returnts its index in list.
605 If no matching record found, -1 is returned
610 PBUSMASTER_CONTROLLER_INFORMATION BusMasterAdapters
,
612 IN PVOID HwDeviceExtension
,
615 OUT PCI_SLOT_NUMBER
* _slotData
// optional
618 PCI_SLOT_NUMBER slotData
;
619 PCI_COMMON_CONFIG pciData
;
631 KdPrint2((PRINT_PREFIX
"AtapiFindListedDev: lim=%x, Bus=%x, Slot=%x\n", lim
, BusNumber
, SlotNumber
));
634 if(BusNumber
== PCIBUSNUM_NOT_SPECIFIED
) {
636 busNumber2
= maxPciBus
;
638 busNumber
= BusNumber
;
639 busNumber2
= BusNumber
+1;
641 // set start/end slot
642 if(SlotNumber
== PCISLOTNUM_NOT_SPECIFIED
) {
644 slotNumber2
= PCI_MAX_DEVICES
;
646 slotNumber
= SlotNumber
;
647 slotNumber2
= SlotNumber
+1;
649 slotData
.u
.AsULONG
= 0;
651 KdPrint2((PRINT_PREFIX
" scanning range Bus %x-%x, Slot %x-%x\n", busNumber
, busNumber2
-1, slotNumber
, slotNumber2
-1));
653 for( ; busNumber
< busNumber2
; busNumber
++ ) {
654 for( ; slotNumber
< slotNumber2
; slotNumber
++) {
655 for(funcNumber
=0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
657 slotData
.u
.bits
.DeviceNumber
= slotNumber
;
658 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
660 busDataRead
= HalGetBusData(
661 //ScsiPortGetBusData(HwDeviceExtension,
662 PCIConfiguration
, busNumber
, slotData
.u
.AsULONG
,
663 &pciData
, PCI_COMMON_HDR_LENGTH
);
664 // no more buses (this should not happen)
668 // no device in this slot
672 if(busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
)
675 KdPrint2((PRINT_PREFIX "AtapiFindListedDev: b:s:f(%x:%x:%x) %4.4x/%4.4x/%2.2x\n",
676 busNumber, slotNumber, funcNumber,
677 pciData.VendorID, pciData.DeviceID, pciData.RevisionID));
679 i
= Ata_is_dev_listed(BusMasterAdapters
, pciData
.VendorID
, pciData
.DeviceID
, pciData
.RevisionID
, lim
);
680 if(i
!= BMLIST_TERMINATOR
) {
682 *_slotData
= slotData
;
683 KdPrint2((PRINT_PREFIX
"AtapiFindListedDev: found\n"));
684 KdPrint2((PRINT_PREFIX
"AtapiFindListedDev: b:s:f(%x:%x:%x) %4.4x/%4.4x/%2.2x\n",
685 busNumber
, slotNumber
, funcNumber
,
686 pciData
.VendorID
, pciData
.DeviceID
, pciData
.RevisionID
));
692 } // end AtapiFindListedDev()
695 Looks for device with specified Device/Vendor and Revision
696 on specified Bus/Slot
701 IN PVOID HwDeviceExtension
,
702 IN BUS_DATA_TYPE BusDataType
,
709 PCI_COMMON_CONFIG pciData
;
715 PCI_SLOT_NUMBER slotData
;
717 slotData
.u
.AsULONG
= SlotNumber
;
718 // walk through all Function Numbers
719 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
721 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
722 if(slotData
.u
.AsULONG
== SlotNumber
)
725 busDataRead
= HalGetBusData(
726 //busDataRead = ScsiPortGetBusData(HwDeviceExtension,
731 PCI_COMMON_HDR_LENGTH
);
733 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
737 VendorID
= pciData
.VendorID
;
738 DeviceID
= pciData
.DeviceID
;
740 if(dev_id
!= (VendorID
| (DeviceID
<< 16)) )
742 if(RevID
>= pciData
.RevisionID
)
746 } // end AtapiFindDev()
753 UniataFindCompatBusMasterController1(
754 IN PVOID HwDeviceExtension
,
756 IN PVOID BusInformation
,
757 IN PCHAR ArgumentString
,
758 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
762 return UniataFindBusMasterController(
770 } // end UniataFindCompatBusMasterController1()
774 UniataFindCompatBusMasterController2(
775 IN PVOID HwDeviceExtension
,
777 IN PVOID BusInformation
,
778 IN PCHAR ArgumentString
,
779 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
783 return UniataFindBusMasterController(
791 } // end UniataFindCompatBusMasterController2()
795 UniataAllocateLunExt(
796 PHW_DEVICE_EXTENSION deviceExtension
,
797 ULONG NewNumberChannels
800 PHW_LU_EXTENSION old_luns
= NULL
;
801 PHW_CHANNEL old_chans
= NULL
;
803 KdPrint2((PRINT_PREFIX
"allocate Luns for %d channels\n", deviceExtension
->NumberChannels
));
805 old_luns
= deviceExtension
->lun
;
806 old_chans
= deviceExtension
->chan
;
808 if(old_luns
|| old_chans
) {
809 if(NewNumberChannels
== UNIATA_ALLOCATE_NEW_LUNS
) {
810 KdPrint2((PRINT_PREFIX
"already allocated!\n"));
815 deviceExtension
->lun
= (PHW_LU_EXTENSION
)ExAllocatePool(NonPagedPool
, sizeof(HW_LU_EXTENSION
) * (deviceExtension
->NumberChannels
+1) * IDE_MAX_LUN_PER_CHAN
);
816 if (!deviceExtension
->lun
) {
817 KdPrint2((PRINT_PREFIX
"!deviceExtension->lun => SP_RETURN_ERROR\n"));
820 RtlZeroMemory(deviceExtension
->lun
, sizeof(HW_LU_EXTENSION
) * (deviceExtension
->NumberChannels
+1) * IDE_MAX_LUN_PER_CHAN
);
822 deviceExtension
->chan
= (PHW_CHANNEL
)ExAllocatePool(NonPagedPool
, sizeof(HW_CHANNEL
) * (deviceExtension
->NumberChannels
+1));
823 if (!deviceExtension
->chan
) {
824 ExFreePool(deviceExtension
->lun
);
825 deviceExtension
->lun
= NULL
;
826 KdPrint2((PRINT_PREFIX
"!deviceExtension->chan => SP_RETURN_ERROR\n"));
829 RtlZeroMemory(deviceExtension
->chan
, sizeof(HW_CHANNEL
) * (deviceExtension
->NumberChannels
+1));
831 } // end UniataAllocateLunExt()
838 This function is called by the OS-specific port driver after
839 the necessary storage has been allocated, to gather information
840 about the adapter's configuration.
844 HwDeviceExtension - HBA miniport driver's adapter data storage
845 Context - Address of adapter count
847 ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility.
848 ConfigInfo - Configuration information structure describing HBA
849 Again - Indicates search for adapters to continue
858 UniataFindBusMasterController(
859 IN PVOID HwDeviceExtension
,
861 IN PVOID BusInformation
,
862 IN PCHAR ArgumentString
,
863 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
867 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
868 PHW_CHANNEL chan
= NULL
;
870 // this buffer must be global for UNIATA_CORE build
871 PCI_COMMON_CONFIG pciData
;
875 ULONG SystemIoBusNumber
;
877 UCHAR vendorString
[5];
878 UCHAR deviceString
[5];
888 PCI_SLOT_NUMBER slotData
;
900 BOOLEAN found
= FALSE
;
902 BOOLEAN simplexOnly
= FALSE
;
904 #ifdef UNIATA_INIT_ON_PROBE
905 BOOLEAN skip_find_dev
= FALSE
;
908 BOOLEAN AltInit
= FALSE
;
910 SCSI_PHYSICAL_ADDRESS IoBasePort1
;
911 SCSI_PHYSICAL_ADDRESS IoBasePort2
;
913 PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0
= NULL
;
914 PIDE_REGISTERS_1 BaseIoAddress1
[IDE_MAX_CHAN
];
915 PIDE_REGISTERS_2 BaseIoAddress2
[IDE_MAX_CHAN
];
917 RtlZeroMemory(&BaseIoAddress1
, sizeof(BaseIoAddress1
));
918 RtlZeroMemory(&BaseIoAddress2
, sizeof(BaseIoAddress2
));
921 PPORT_CONFIGURATION_INFORMATION_COMMON _ConfigInfo
=
922 (PPORT_CONFIGURATION_INFORMATION_COMMON
)ConfigInfo
;
924 if(!WinVer_WDM_Model
) {
930 KdPrint2((PRINT_PREFIX
"UniataFindBusMasterController: Context=%x, BMListLen=%d\n", Context
, BMListLen
));
932 KdPrint2((PRINT_PREFIX
"ConfigInfo->Length %x\n", ConfigInfo
->Length
));
935 KdPrint2((PRINT_PREFIX
"ForceSimplex (1)\n"));
939 if(ConfigInfo
->AdapterInterfaceType
== Isa
) {
940 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType: Isa\n"));
943 i
= (ULONG_PTR
)Context
;
948 channel
= BMList
[i
].channel
;
951 for(i
=0; i
<BMListLen
; i
++) {
952 if(BMList
[i
].slotNumber
== ConfigInfo
->SlotNumber
&&
953 BMList
[i
].busNumber
== ConfigInfo
->SystemIoBusNumber
) {
958 KdPrint2((PRINT_PREFIX
"unexpected device arrival\n"));
959 i
= (ULONG_PTR
)Context
;
965 KdPrint2((PRINT_PREFIX
" => SP_RETURN_NOT_FOUND\n"));
969 BMList
[i
].channel
= (UCHAR
)channel
;
972 bm_offset
= channel
? ATA_BM_OFFSET1
: 0;
974 KdPrint2((PRINT_PREFIX
"bm_offset %x, channel %x \n", bm_offset
, channel
));
976 if (!deviceExtension
) {
977 KdPrint2((PRINT_PREFIX
"!deviceExtension => SP_RETURN_ERROR\n"));
978 return SP_RETURN_ERROR
;
980 RtlZeroMemory(deviceExtension
, sizeof(HW_DEVICE_EXTENSION
));
982 vendorStrPtr
= vendorString
;
983 deviceStrPtr
= deviceString
;
985 slotNumber
= BMList
[i
].slotNumber
;
986 SystemIoBusNumber
= BMList
[i
].busNumber
;
989 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType=%#x\n",ConfigInfo
->AdapterInterfaceType
));
990 KdPrint2((PRINT_PREFIX
"IoBusNumber=%#x\n",ConfigInfo
->SystemIoBusNumber
));
991 KdPrint2((PRINT_PREFIX
"slotNumber=%#x\n",slotNumber
));
993 // this buffer must be global and already filled for UNIATA_CORE build
994 busDataRead
= HalGetBusData(
995 //busDataRead = ScsiPortGetBusData(HwDeviceExtension,
1000 PCI_COMMON_HDR_LENGTH
);
1003 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1004 KdPrint2((PRINT_PREFIX
"busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n"));
1008 KdPrint2((PRINT_PREFIX
"busDataRead\n"));
1009 if (pciData
.VendorID
== PCI_INVALID_VENDORID
) {
1010 KdPrint2((PRINT_PREFIX
"PCI_INVALID_VENDORID\n"));
1013 #endif //UNIATA_CORE
1015 VendorID
= pciData
.VendorID
;
1016 DeviceID
= pciData
.DeviceID
;
1017 BaseClass
= pciData
.BaseClass
;
1018 SubClass
= pciData
.SubClass
;
1019 RevID
= pciData
.RevisionID
;
1020 dev_id
= VendorID
| (DeviceID
<< 16);
1021 slotData
.u
.AsULONG
= slotNumber
;
1022 KdPrint2((PRINT_PREFIX
"DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id
, BaseClass
, SubClass
));
1024 deviceExtension
->slotNumber
= slotNumber
;
1025 deviceExtension
->SystemIoBusNumber
= SystemIoBusNumber
;
1026 deviceExtension
->DevID
= dev_id
;
1027 deviceExtension
->RevID
= RevID
;
1028 deviceExtension
->NumberChannels
= 2; // default
1029 deviceExtension
->DevIndex
= i
;
1031 _snprintf(deviceExtension
->Signature
, sizeof(deviceExtension
->Signature
),
1032 "UATA%8.8x/%1.1x@%8.8x", dev_id
, channel
, slotNumber
);
1034 if(BaseClass
!= PCI_DEV_CLASS_STORAGE
) {
1035 KdPrint2((PRINT_PREFIX
"BaseClass != PCI_DEV_CLASS_STORAGE => SP_RETURN_NOT_FOUND\n"));
1039 KdPrint2((PRINT_PREFIX
"Storage Class\n"));
1041 // look for known chipsets
1042 if(VendorID
!= BMList
[i
].nVendorId
||
1043 DeviceID
!= BMList
[i
].nDeviceId
) {
1044 KdPrint2((PRINT_PREFIX
"device not suitable\n"));
1048 found
= UniataCheckPCISubclass(BMList
[i
].Known
, BMList
[i
].RaidFlags
, SubClass
);
1050 KdPrint2((PRINT_PREFIX
"Subclass not supported\n"));
1054 ConfigInfo
->AlignmentMask
= 0x00000003;
1056 MasterDev
= IsMasterDev(&pciData
);
1059 KdPrint2((PRINT_PREFIX
"MasterDev (1)\n"));
1060 deviceExtension
->MasterDev
= TRUE
;
1063 status
= UniataChipDetect(HwDeviceExtension
, &pciData
, i
, ConfigInfo
, &simplexOnly
);
1065 case STATUS_SUCCESS
:
1068 case STATUS_NOT_FOUND
:
1072 KdPrint2((PRINT_PREFIX
"FAILED => SP_RETURN_ERROR\n"));
1075 KdPrint2((PRINT_PREFIX
"ForceSimplex = %d\n", simplexOnly
));
1076 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (0)", deviceExtension
->HwFlags
));
1078 /* additional checks for some supported chipsets */
1080 if (SubClass
!= PCI_DEV_SUBCLASS_IDE
) {
1081 KdPrint2((PRINT_PREFIX
"0xc6931080, SubClass != PCI_DEV_SUBCLASS_IDE => found = FALSE\n"));
1088 /* unknown chipsets, try generic DMA if it seems possible */
1092 KdPrint2((PRINT_PREFIX
"Default device\n"));
1093 if(!Ata_is_supported_dev(&pciData
)) {
1094 KdPrint2((PRINT_PREFIX
"!Ata_is_supported_dev => found = FALSE\n"));
1097 KdPrint2((PRINT_PREFIX
"Ata_is_supported_dev\n"));
1100 deviceExtension
->UnknownDev
= TRUE
;
1104 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (1)", deviceExtension
->HwFlags
));
1106 KdPrint2((PRINT_PREFIX
"!found => SP_RETURN_NOT_FOUND\n"));
1110 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (2)", deviceExtension
->HwFlags
));
1111 KdPrint2((PRINT_PREFIX
"found suitable device\n"));
1113 /***********************************************************/
1114 /***********************************************************/
1115 /***********************************************************/
1117 deviceExtension
->UseDpc
= TRUE
;
1118 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (3)", deviceExtension
->HwFlags
));
1119 if(deviceExtension
->HwFlags
& UNIATA_NO_DPC
) {
1120 /* CMD 649, ROSB SWK33, ICH4 */
1121 KdPrint2((PRINT_PREFIX
"UniataFindBusMasterController: UNIATA_NO_DPC (0)\n"));
1122 deviceExtension
->UseDpc
= FALSE
;
1126 if((WinVer_Id() <= WinVer_NT
) && AltInit
&& FirstMasterOk
) {
1127 // this is the 2nd attempt to init this controller by OUR driver
1128 KdPrint2((PRINT_PREFIX
"Skip primary/secondary claiming checks\n"));
1130 if((channel
==0) && ConfigInfo
->AtdiskPrimaryClaimed
) {
1131 KdPrint2((PRINT_PREFIX
"Error: Primary channel already claimed by another driver\n"));
1134 if((channel
==1) && ConfigInfo
->AtdiskSecondaryClaimed
) {
1135 KdPrint2((PRINT_PREFIX
"Error: Secondary channel already claimed by another driver\n"));
1140 if(deviceExtension
->AltRegMap
) {
1141 KdPrint2((PRINT_PREFIX
" Non-standard registers layout\n"));
1142 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
1143 KdPrint2((PRINT_PREFIX
"UNIATA_SATA -> IsBusMaster == TRUE\n"));
1144 deviceExtension
->BusMaster
= TRUE
;
1147 deviceExtension
->BusMaster
= FALSE
;
1149 if(WinVer_WDM_Model
&& !deviceExtension
->UnknownDev
) {
1151 // Enable Busmastering, IO-space and Mem-space
1152 KdPrint2((PRINT_PREFIX
"Enabling Mem/Io spaces and busmastering...\n"));
1153 KdPrint2((PRINT_PREFIX
"Initial pciData.Command = %#x\n", pciData
.Command
));
1154 for(i
=0; i
<3; i
++) {
1157 KdPrint2((PRINT_PREFIX
"PCI_ENABLE_IO_SPACE\n"));
1158 pciData
.Command
|= PCI_ENABLE_IO_SPACE
;
1161 KdPrint2((PRINT_PREFIX
"PCI_ENABLE_MEMORY_SPACE\n"));
1162 pciData
.Command
|= PCI_ENABLE_MEMORY_SPACE
;
1165 KdPrint2((PRINT_PREFIX
"PCI_ENABLE_BUS_MASTER\n"));
1166 pciData
.Command
|= PCI_ENABLE_BUS_MASTER
;
1169 HalSetBusDataByOffset( PCIConfiguration
, SystemIoBusNumber
, slotData
.u
.AsULONG
,
1171 offsetof(PCI_COMMON_CONFIG
, Command
),
1172 sizeof(pciData
.Command
));
1173 KdPrint2((PRINT_PREFIX
"InterruptLine = %#x\n", pciData
.u
.type0
.InterruptLine
));
1175 // reread config space
1176 busDataRead
= HalGetBusData(PCIConfiguration
, SystemIoBusNumber
, slotData
.u
.AsULONG
,
1177 &pciData
, PCI_COMMON_HDR_LENGTH
);
1178 KdPrint2((PRINT_PREFIX
"New pciData.Command = %#x\n", pciData
.Command
));
1180 KdPrint2((PRINT_PREFIX
"Final pciData.Command = %#x\n", pciData
.Command
));
1182 // validate Mem/Io ranges
1186 for(i
=0; i
<PCI_TYPE0_ADDRESSES
; i
++) {
1187 if(pciData
.u
.type0
.BaseAddresses
[i
] & ~0x7) {
1188 //no_ranges = FALSE;
1190 KdPrint2((PRINT_PREFIX
"Range %d = %#x\n", i
, pciData
.u
.type0
.BaseAddresses
[i
]));
1195 if(IsBusMaster(&pciData
)) {
1197 KdPrint2((PRINT_PREFIX
"IsBusMaster == TRUE\n"));
1198 BaseIoAddressBM_0
= (PIDE_BUSMASTER_REGISTERS
)
1199 (AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, &pciData
, SystemIoBusNumber
,
1200 4, bm_offset
, MasterDev
? 0x08 : 0x10/*ATA_BMIOSIZE*/)/* - bm_offset*/); //range id
1201 if(BaseIoAddressBM_0
) {
1202 UniataInitMapBM(deviceExtension
,
1204 (*ConfigInfo
->AccessRanges
)[4].RangeInMemory
? TRUE
: FALSE
);
1205 deviceExtension
->BusMaster
= TRUE
;
1206 deviceExtension
->BaseIoAddressBM_0
.Addr
= (ULONG_PTR
)BaseIoAddressBM_0
;
1207 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
1208 deviceExtension
->BaseIoAddressBM_0
.MemIo
= TRUE
;
1211 KdPrint2((PRINT_PREFIX
" BusMasterAddress (base): %#x\n", BaseIoAddressBM_0
));
1214 if(!deviceExtension
->BusMaster
) {
1215 KdPrint2((PRINT_PREFIX
" !BusMasterAddress -> PIO4\n"));
1216 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
1219 if(deviceExtension
->BusMaster
&& !MasterDev
) {
1220 KdPrint2((PRINT_PREFIX
"IsBusMaster == TRUE && !MasterDev\n"));
1221 statusByte
= AtapiReadPort1(&(deviceExtension
->chan
[0]), IDX_BM_Status
);
1222 KdPrint2((PRINT_PREFIX
" statusByte = %x\n", statusByte
));
1223 if(statusByte
== 0xff) {
1224 KdPrint2((PRINT_PREFIX
" invalid port ?\n"));
1226 if(BaseIoAddressBM_0) {
1227 ScsiPortFreeDeviceBase(HwDeviceExtension,
1229 BaseIoAddressBM_0 = NULL;
1233 if(statusByte
& BM_STATUS_SIMPLEX_ONLY
) {
1234 KdPrint2((PRINT_PREFIX
" BM_STATUS => simplexOnly\n"));
1241 * the Cypress chip is a mess, it contains two ATA functions, but
1242 * both channels are visible on the first one.
1243 * simply ignore the second function for now, as the right
1244 * solution (ignoring the second channel on the first function)
1245 * doesn't work with the crappy ATA interrupt setup on the alpha.
1247 if (dev_id
== 0xc6931080 && slotData
.u
.bits
.FunctionNumber
> 1) {
1248 KdPrint2((PRINT_PREFIX
"dev_id == 0xc6931080 && FunctionNumber > 1 => exit_findbm\n"));
1252 /* do extra chipset specific setups */
1253 AtapiReadChipConfig(HwDeviceExtension
, i
, CHAN_NOT_SPECIFIED
);
1254 AtapiChipInit(HwDeviceExtension
, i
, CHAN_NOT_SPECIFIED_CHECK_CABLE
);
1256 simplexOnly
|= deviceExtension
->simplexOnly
;
1257 deviceExtension
->simplexOnly
|= simplexOnly
;
1259 KdPrint2((PRINT_PREFIX
"simplexOnly = %d (2)", simplexOnly
));
1261 //TODO: fix hang with UseDpn=TRUE in Simplex mode
1262 //deviceExtension->UseDpc = TRUE;
1264 KdPrint2((PRINT_PREFIX
"simplexOnly => UseDpc = FALSE\n"));
1265 deviceExtension
->UseDpc
= FALSE
;
1268 if(simplexOnly
&& MasterDev
) {
1269 if(deviceExtension
->NumberChannels
< 2) {
1270 KdPrint2((PRINT_PREFIX
"set NumberChannels = 2\n"));
1271 deviceExtension
->NumberChannels
= 2;
1272 if(BaseIoAddressBM_0
) {
1273 UniataInitMapBM(deviceExtension
,
1275 (*ConfigInfo
->AccessRanges
)[4].RangeInMemory
? TRUE
: FALSE
);
1280 (deviceExtension
->NumberChannels
> 1)) {
1281 KdPrint2((PRINT_PREFIX
"Error: channel > 0 && NumberChannels > 1\n"));
1285 // Indicate number of buses.
1286 ConfigInfo
->NumberOfBuses
= (UCHAR
)(deviceExtension
->NumberChannels
);
1287 if(!ConfigInfo
->InitiatorBusId
[0]) {
1288 ConfigInfo
->InitiatorBusId
[0] = (CHAR
)(IoGetConfigurationInformation()->ScsiPortCount
);
1289 KdPrint2((PRINT_PREFIX
"set ConfigInfo->InitiatorBusId[0] = %#x\n", ConfigInfo
->InitiatorBusId
[0]));
1291 // Indicate four devices can be attached to the adapter
1292 ConfigInfo
->MaximumNumberOfTargets
= (UCHAR
)(/*deviceExtension->NumberChannels **/ 2);
1295 KdPrint2((PRINT_PREFIX
"MasterDev (2)\n"));
1297 if((WinVer_Id() > WinVer_NT) ||
1298 (deviceExtension->NumberChannels > 1)) {
1300 KdPrint2((PRINT_PREFIX "2 channels & 2 irq for 1 controller Win 2000+\n"));
1302 if (ConfigInfo->AdapterInterfaceType == MicroChannel) {
1303 ConfigInfo->InterruptMode2 =
1304 ConfigInfo->InterruptMode = LevelSensitive;
1306 ConfigInfo->InterruptMode2 =
1307 ConfigInfo->InterruptMode = Latched;
1309 ConfigInfo->BusInterruptLevel = 14;
1310 ConfigInfo->BusInterruptLevel2 = 15;
1314 KdPrint2((PRINT_PREFIX
"2 channels & 2 irq for 1 controller\n"));
1316 if (ConfigInfo
->AdapterInterfaceType
== MicroChannel
) {
1317 ConfigInfo
->InterruptMode2
=
1318 ConfigInfo
->InterruptMode
= LevelSensitive
;
1320 ConfigInfo
->InterruptMode2
=
1321 ConfigInfo
->InterruptMode
= Latched
;
1323 ConfigInfo
->BusInterruptLevel
= 14;
1324 ConfigInfo
->BusInterruptLevel2
= 15;
1326 KdPrint2((PRINT_PREFIX
"1 channels & 1 irq for 1 controller\n"));
1327 if (ConfigInfo
->AdapterInterfaceType
== MicroChannel
) {
1328 ConfigInfo
->InterruptMode
= LevelSensitive
;
1330 ConfigInfo
->InterruptMode
= Latched
;
1332 ConfigInfo
->BusInterruptLevel
= (channel
== 0 ? 14 : 15);
1335 KdPrint2((PRINT_PREFIX
"!MasterDev\n"));
1336 ConfigInfo
->SlotNumber
= slotNumber
;
1337 ConfigInfo
->SystemIoBusNumber
= SystemIoBusNumber
;
1339 /* primary and secondary channels share the same interrupt */
1340 if(!ConfigInfo
->BusInterruptVector
||
1341 (ConfigInfo
->BusInterruptVector
!= pciData
.u
.type0
.InterruptLine
)) {
1342 KdPrint2((PRINT_PREFIX
"patch irq line = %#x\n", pciData
.u
.type0
.InterruptLine
));
1343 ConfigInfo
->BusInterruptVector
= pciData
.u
.type0
.InterruptLine
; // set default value
1344 if(!ConfigInfo
->BusInterruptVector
) {
1345 KdPrint2((PRINT_PREFIX
"patch irq line (2) = 10\n"));
1346 ConfigInfo
->BusInterruptVector
= 10;
1350 ConfigInfo
->MultipleRequestPerLu
= TRUE
;
1351 ConfigInfo
->AutoRequestSense
= TRUE
;
1352 ConfigInfo
->TaggedQueuing
= TRUE
;
1354 if((WinVer_Id() >= WinVer_NT
) ||
1355 (ConfigInfo
->Length
>= sizeof(_ConfigInfo
->comm
) + sizeof(_ConfigInfo
->nt4
))) {
1356 KdPrint2((PRINT_PREFIX
"update ConfigInfo->nt4\n"));
1357 _ConfigInfo
->nt4
.DeviceExtensionSize
= sizeof(HW_DEVICE_EXTENSION
);
1358 _ConfigInfo
->nt4
.SpecificLuExtensionSize
= sizeof(HW_LU_EXTENSION
);
1359 _ConfigInfo
->nt4
.SrbExtensionSize
= sizeof(ATA_REQ
);
1361 if((WinVer_Id() > WinVer_2k
) ||
1362 (ConfigInfo
->Length
>= sizeof(_ConfigInfo
->comm
) + sizeof(_ConfigInfo
->nt4
) + sizeof(_ConfigInfo
->w2k
))) {
1363 KdPrint2((PRINT_PREFIX
"update ConfigInfo->w2k\n"));
1364 _ConfigInfo
->w2k
.Dma64BitAddresses
= 0;
1365 _ConfigInfo
->w2k
.ResetTargetSupported
= TRUE
;
1366 _ConfigInfo
->w2k
.MaximumNumberOfLogicalUnits
= 2;
1369 // Save the Interrupe Mode for later use
1370 deviceExtension
->InterruptMode
= ConfigInfo
->InterruptMode
;
1371 deviceExtension
->BusInterruptLevel
= ConfigInfo
->BusInterruptLevel
;
1372 deviceExtension
->BusInterruptVector
= ConfigInfo
->BusInterruptVector
;
1373 deviceExtension
->Channel
= channel
;
1374 deviceExtension
->DevIndex
= i
;
1375 deviceExtension
->OrigAdapterInterfaceType
1376 = ConfigInfo
->AdapterInterfaceType
;
1377 deviceExtension
->AlignmentMask
= ConfigInfo
->AlignmentMask
;
1378 deviceExtension
->AdapterInterfaceType
= PCIBus
;
1382 if(deviceExtension
->BusMaster
) {
1384 KdPrint2((PRINT_PREFIX
"Reconstruct ConfigInfo\n"));
1385 ConfigInfo
->MapBuffers
= TRUE
;
1387 ConfigInfo
->NeedPhysicalAddresses
= FALSE
;
1389 ConfigInfo
->NeedPhysicalAddresses
= TRUE
;
1390 #endif //USE_OWN_DMA
1392 KdPrint2((PRINT_PREFIX
"set Dma32BitAddresses\n"));
1393 ConfigInfo
->Dma32BitAddresses
= TRUE
;
1396 // thanks to Vitaliy Vorobyov aka deathsoft@yandex.ru for
1400 // I'm sorry, I have to do this
1403 if(ConfigInfo
->AdapterInterfaceType
== Isa
/*&&
1404 // InDriverEntry*/) {
1405 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType Isa => PCIBus\n"));
1406 ConfigInfo
->AdapterInterfaceType
= PCIBus
;
1408 if(ConfigInfo
->AdapterInterfaceType
== PCIBus
/*&&
1409 // InDriverEntry*/) {
1410 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType PCIBus, update address\n"));
1411 ConfigInfo
->SlotNumber
= slotNumber
;
1412 ConfigInfo
->SystemIoBusNumber
= SystemIoBusNumber
;
1417 ConfigInfo
->Master
= TRUE
;
1418 ConfigInfo
->DmaWidth
= Width16Bits
;
1419 #endif //USE_OWN_DMA
1420 ConfigInfo
->CachesData
= TRUE
;
1421 ConfigInfo
->ScatterGather
= TRUE
;
1424 // Note: now we can support only 4 channels !!!
1425 // in order to add support for multichannel controllers we must rewrite
1426 // io-range claiming algorithm
1428 KdPrint2((PRINT_PREFIX
"BMList[i].channel %#x, NumberChannels %#x, channel %#x\n",BMList
[i
].channel
, deviceExtension
->NumberChannels
, channel
));
1430 for (; channel
< (BMList
[i
].channel
+ deviceExtension
->NumberChannels
); channel
++, c
++) {
1432 KdPrint2((PRINT_PREFIX
"de %#x, Channel %#x\n",deviceExtension
, channel
));
1433 //PrintNtConsole("de %#x, Channel %#x, nchan %#x\n",deviceExtension, channel, deviceExtension->NumberChannels);
1434 chan
= &deviceExtension
->chan
[c
];
1436 KdPrint2((PRINT_PREFIX
"chan = %#x\n", chan
));
1437 //PrintNtConsole("chan = %#x, c=%#x\n", chan, c);
1438 AtapiSetupLunPtrs(chan
, deviceExtension
, c
);
1440 /* do extra channel-specific setups */
1441 AtapiReadChipConfig(HwDeviceExtension
, i
, channel
);
1442 //AtapiChipInit(HwDeviceExtension, i, channel);
1443 if(deviceExtension
->AltRegMap
) {
1444 KdPrint2((PRINT_PREFIX
" Non-standard registers layout\n"));
1446 // Check if the range specified is not used by another driver
1448 KdPrint2((PRINT_PREFIX
"set AccessRanges\n"));
1449 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 0].RangeStart
=
1450 ScsiPortConvertUlongToPhysicalAddress(channel
? IO_WD2
: IO_WD1
);
1451 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 0].RangeLength
= ATA_IOSIZE
;
1453 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 1].RangeStart
=
1454 ScsiPortConvertUlongToPhysicalAddress((channel
? IO_WD2
: IO_WD1
) + ATA_ALTOFFSET
);
1455 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 1].RangeLength
= ATA_ALTIOSIZE
;
1457 // do not claim 2nd BM io-range for Secondary channel of
1458 // Compatible-mode controllers
1459 if(/*(WinVer_Id() <= WinVer_NT) &&*/ !c
&& channel
== 1) {
1460 KdPrint2((PRINT_PREFIX
"cheat ScsiPort for 2nd channel, BM io-range\n"));
1461 (*ConfigInfo
->AccessRanges
)[4].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(0);
1462 (*ConfigInfo
->AccessRanges
)[4].RangeLength
= 0;
1466 IoBasePort1
= (*ConfigInfo
->AccessRanges
)[channel
* 2 + 0].RangeStart
;
1467 IoBasePort2
= (*ConfigInfo
->AccessRanges
)[channel
* 2 + 1].RangeStart
;
1470 if(!IoBasePort1
.QuadPart
|| !IoBasePort2
.QuadPart
) {
1471 KdPrint2((PRINT_PREFIX
"ScsiPortValidateRange failed (1)\n"));
1476 if(!ScsiPortValidateRange(HwDeviceExtension
,
1477 PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
1478 SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
1482 KdPrint2((PRINT_PREFIX
"ScsiPortValidateRange failed (1)\n"));
1486 if(!ScsiPortValidateRange(HwDeviceExtension
,
1487 PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
1488 SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
1492 KdPrint2((PRINT_PREFIX
"ScsiPortValidateRange failed (2)\n"));
1496 KdPrint2((PRINT_PREFIX
"Getting IO ranges\n"));
1498 // Ok, translate adresses to io-space
1499 if(ScsiPortConvertPhysicalAddressToUlong(IoBasePort2
)) {
1500 if(!(MasterDev
/* || USE_16_BIT */)) {
1501 KdPrint2((PRINT_PREFIX
"!MasterDev mode\n"));
1502 IoBasePort2
= ScsiPortConvertUlongToPhysicalAddress(
1503 ScsiPortConvertPhysicalAddressToUlong(IoBasePort2
) + 2);
1506 KdPrint2((PRINT_PREFIX
"use relative IoBasePort2\n"));
1507 IoBasePort2
= ScsiPortConvertUlongToPhysicalAddress(
1508 ScsiPortConvertPhysicalAddressToUlong(IoBasePort1
) + ATA_PCCARD_ALTOFFSET
);
1511 // Get the system physical address for this IO range.
1512 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
1513 PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
1514 SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
1518 KdPrint2((PRINT_PREFIX
"IO range 1 %#x\n",ioSpace
));
1520 // Check if ioSpace accessible.
1522 KdPrint2((PRINT_PREFIX
"!ioSpace\n"));
1526 if(deviceExtension->BusMaster) {
1527 KdPrint2((PRINT_PREFIX "set BusMaster io-range in DO\n"));
1528 // bm_offset already includes (channel ? ATA_BM_OFFSET1 : 0)
1529 deviceExtension->BaseIoAddressBM[c] = (PIDE_BUSMASTER_REGISTERS)
1530 ((ULONG)(deviceExtension->BaseIoAddressBM_0) + bm_offset + (c ? ATA_BM_OFFSET1 : 0));
1533 //deviceExtension->BaseIoAddress1[c] = (PIDE_REGISTERS_1)(ioSpace);
1534 BaseIoAddress1
[c
] = (PIDE_REGISTERS_1
)(ioSpace
);
1536 // Get the system physical address for the second IO range.
1537 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
1538 PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
1539 SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
1543 KdPrint2((PRINT_PREFIX
"IO range 2 %#x\n",ioSpace
));
1545 BaseIoAddress2
[c
] = (PIDE_REGISTERS_2
)(ioSpace
);
1547 // Release all allocated resources
1548 KdPrint2((PRINT_PREFIX
"!deviceExtension->BaseIoAddress2\n"));
1549 //ioSpace = (PUCHAR)BaseIoAddress1[c];
1550 // goto free_iospace_1;
1554 UniataInitMapBase(chan
, BaseIoAddress1
[c
], BaseIoAddress2
[c
]);
1556 //ioSpace = (PUCHAR)(deviceExtension->BaseIoAddress1[c]);
1558 KdPrint2((PRINT_PREFIX
"IDX_IO1 %x->%x(%s)\n",
1560 chan
->RegTranslation
[IDX_IO1
].Addr
,
1561 chan
->RegTranslation
[IDX_IO1
].MemIo
? "mem" : "io"));
1563 KdPrint2((PRINT_PREFIX
"IDX_IO2 %x->%x(%s)\n",
1565 chan
->RegTranslation
[IDX_IO2
].Addr
,
1566 chan
->RegTranslation
[IDX_IO2
].MemIo
? "mem" : "io"));
1568 KdPrint2((PRINT_PREFIX
"IDX_BM_IO %x->%x(%s)\n",
1570 chan
->RegTranslation
[IDX_BM_IO
].Addr
,
1571 chan
->RegTranslation
[IDX_BM_IO
].MemIo
? "mem" : "io"));
1573 KdPrint2((PRINT_PREFIX
"IDX_SATA_IO %x->%x(%s)\n",
1575 chan
->RegTranslation
[IDX_SATA_IO
].Addr
,
1576 chan
->RegTranslation
[IDX_SATA_IO
].MemIo
? "mem" : "io"));
1578 UniataDumpATARegs(chan
);
1581 #ifdef UNIATA_INIT_ON_PROBE
1582 // if(deviceExtension->HwFlags & UNIATA_SATA) {
1583 //#endif //UNIATA_INIT_ON_PROBE
1584 KdPrint2((PRINT_PREFIX
"Check drive 0\n"));
1586 SelectDrive(chan
, 0);
1587 AtapiStallExecution(10);
1588 GetBaseStatus(chan
, statusByte
);
1589 skip_find_dev
= FALSE
;
1590 if(!(deviceExtension
->HwFlags
& UNIATA_NO_SLAVE
)) {
1591 if ((statusByte
& 0xf8) == 0xf8 ||
1592 (statusByte
== 0xa5)) {
1594 KdPrint2((PRINT_PREFIX
"Check drive 1\n"));
1595 SelectDrive(chan
, 1);
1596 AtapiStallExecution(1);
1597 GetBaseStatus(chan
, statusByte
);
1598 if ((statusByte
& 0xf8) == 0xf8 ||
1599 (statusByte
== 0xa5)) {
1600 // No controller at this base address.
1601 KdPrint2((PRINT_PREFIX
"Empty channel\n"));
1602 skip_find_dev
= TRUE
;
1607 // Search for devices on this controller.
1608 if (!skip_find_dev
&&
1609 FindDevices(HwDeviceExtension
,
1612 KdPrint2((PRINT_PREFIX
"Found some devices\n"));
1615 KdPrint2((PRINT_PREFIX
"no devices\n"));
1616 /* KeBugCheckEx(0xc000000e,
1617 ScsiPortConvertPhysicalAddressToUlong(IoBasePort1),
1618 ScsiPortConvertPhysicalAddressToUlong(IoBasePort2),
1619 (ULONG)(deviceExtension->BaseIoAddressBM[c]), skip_find_dev);*/
1621 //#ifdef UNIATA_INIT_ON_PROBE
1623 #endif //UNIATA_INIT_ON_PROBE
1626 chan
->PrimaryAddress
= FALSE
;
1627 // Claim primary or secondary ATA IO range.
1629 KdPrint2((PRINT_PREFIX
"claim Compatible controller\n"));
1631 KdPrint2((PRINT_PREFIX
"claim Primary\n"));
1632 ConfigInfo
->AtdiskPrimaryClaimed
= TRUE
;
1633 chan
->PrimaryAddress
= TRUE
;
1635 FirstMasterOk
= TRUE
;
1639 KdPrint2((PRINT_PREFIX
"claim Secondary\n"));
1640 ConfigInfo
->AtdiskSecondaryClaimed
= TRUE
;
1642 FirstMasterOk
= TRUE
;
1646 AtapiDmaAlloc(HwDeviceExtension
, ConfigInfo
, c
);
1649 #endif //UNIATA_CORE
1650 } // end for(channel)
1656 KdPrint2((PRINT_PREFIX
"exit: !found\n"));
1657 if(BaseIoAddress1
[0])
1658 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1660 if(BaseIoAddress2
[0])
1661 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1664 if(BaseIoAddress1
[1])
1665 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1667 if(BaseIoAddress2
[1])
1668 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1671 if(BaseIoAddressBM_0
)
1672 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1675 KdPrint2((PRINT_PREFIX
"return SP_RETURN_NOT_FOUND\n"));
1679 KdPrint2((PRINT_PREFIX
"exit: init spinlock\n"));
1680 //KeInitializeSpinLock(&(deviceExtension->DpcSpinLock));
1681 deviceExtension
->ActiveDpcChan
=
1682 deviceExtension
->FirstDpcChan
= -1;
1684 BMList
[i
].Isr2Enable
= FALSE
;
1686 KdPrint2((PRINT_PREFIX
"MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n",
1687 MasterDev
, deviceExtension
->NumberChannels
, BMList
[i
].Isr2DevObj
));
1689 // ConnectIntr2 should be moved to HwInitialize
1690 status
= UniataConnectIntr2(HwDeviceExtension
);
1692 KdPrint2((PRINT_PREFIX
"MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n",
1693 MasterDev
, deviceExtension
->NumberChannels
, BMList
[i
].Isr2DevObj
));
1695 if(WinVer_WDM_Model
&& MasterDev
) {
1696 KdPrint2((PRINT_PREFIX
"do not tell system, that we know about this:\n"));
1697 if(BaseIoAddressBM_0
) {
1698 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1701 (*ConfigInfo
->AccessRanges
)[4].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(0);
1702 (*ConfigInfo
->AccessRanges
)[4].RangeLength
= 0;
1703 (*ConfigInfo
->AccessRanges
)[5].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(0);
1704 (*ConfigInfo
->AccessRanges
)[5].RangeLength
= 0;
1707 if(!NT_SUCCESS(status
)) {
1708 KdPrint2((PRINT_PREFIX
"failed\n"));
1713 #endif //UNIATA_CORE
1715 KdPrint2((PRINT_PREFIX
"return SP_RETURN_FOUND\n"));
1716 //PrintNtConsole("return SP_RETURN_FOUND, de %#x, c0.lun0 %#x\n", deviceExtension, deviceExtension->chan[0].lun[0]);
1719 KdPrint2((PRINT_PREFIX
"Attempt %d of MasterDev ok\n", AltInit
));
1720 FirstMasterOk
= TRUE
;
1723 ConfigInfo
->NumberOfBuses
++; // add virtual channel for communication port
1724 return SP_RETURN_FOUND
;
1727 if (deviceExtension
->lun
) ExFreePool(deviceExtension
->lun
);
1728 if (deviceExtension
->chan
) ExFreePool(deviceExtension
->chan
);
1729 return SP_RETURN_ERROR
;
1732 ExFreePool(deviceExtension
->lun
);
1733 ExFreePool(deviceExtension
->chan
);
1734 return SP_RETURN_NOT_FOUND
;
1736 } // end UniataFindBusMasterController()
1741 This is for claiming PCI Busmaster in compatible mode under WDM OSes
1745 UniataFindFakeBusMasterController(
1746 IN PVOID HwDeviceExtension
,
1748 IN PVOID BusInformation
,
1749 IN PCHAR ArgumentString
,
1750 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1754 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1755 //PHW_CHANNEL chan = NULL;
1756 // this buffer must be global for UNIATA_CORE build
1757 PCI_COMMON_CONFIG pciData
;
1761 ULONG SystemIoBusNumber
;
1763 UCHAR vendorString
[5];
1764 UCHAR deviceString
[5];
1765 PUCHAR vendorStrPtr
;
1766 PUCHAR deviceStrPtr
;
1774 PCI_SLOT_NUMBER slotData
;
1778 // UCHAR statusByte;
1783 BOOLEAN found
= FALSE
;
1785 BOOLEAN simplexOnly
= FALSE
;
1786 //BOOLEAN skip_find_dev = FALSE;
1787 //BOOLEAN AltInit = FALSE;
1789 PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0
= NULL
;
1792 PPORT_CONFIGURATION_INFORMATION_COMMON _ConfigInfo
=
1793 (PPORT_CONFIGURATION_INFORMATION_COMMON
)ConfigInfo
;
1798 i
= (ULONG_PTR
)Context
;
1800 for(i
=0; i
<BMListLen
; i
++) {
1801 if(BMList
[i
].slotNumber
== ConfigInfo
->SlotNumber
&&
1802 BMList
[i
].busNumber
== ConfigInfo
->SystemIoBusNumber
) {
1806 if(i
>= BMListLen
) {
1807 KdPrint2((PRINT_PREFIX
"unexpected device arrival => SP_RETURN_NOT_FOUND\n"));
1812 KdPrint2((PRINT_PREFIX
"UniataFindFakeBusMasterController (WDM)\n"));
1814 if (!deviceExtension
) {
1815 KdPrint2((PRINT_PREFIX
"!deviceExtension => SP_RETURN_ERROR\n"));
1816 return SP_RETURN_ERROR
;
1818 RtlZeroMemory(deviceExtension
, sizeof(HW_DEVICE_EXTENSION
));
1820 vendorStrPtr
= vendorString
;
1821 deviceStrPtr
= deviceString
;
1823 slotNumber
= BMList
[i
].slotNumber
;
1824 SystemIoBusNumber
= BMList
[i
].busNumber
;
1826 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType=%#x\n",ConfigInfo
->AdapterInterfaceType
));
1827 KdPrint2((PRINT_PREFIX
"IoBusNumber=%#x\n",ConfigInfo
->SystemIoBusNumber
));
1828 KdPrint2((PRINT_PREFIX
"slotNumber=%#x\n",slotNumber
));
1830 // this buffer must be global and already filled for UNIATA_CORE build
1831 busDataRead
= HalGetBusData(
1832 //busDataRead = ScsiPortGetBusData(HwDeviceExtension,
1837 PCI_COMMON_HDR_LENGTH
);
1839 if (busDataRead
< PCI_COMMON_HDR_LENGTH
) {
1840 KdPrint2((PRINT_PREFIX
"busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n"));
1844 KdPrint2((PRINT_PREFIX
"busDataRead\n"));
1845 if (pciData
.VendorID
== PCI_INVALID_VENDORID
) {
1846 KdPrint2((PRINT_PREFIX
"PCI_INVALID_VENDORID\n"));
1850 VendorID
= pciData
.VendorID
;
1851 DeviceID
= pciData
.DeviceID
;
1852 BaseClass
= pciData
.BaseClass
;
1853 SubClass
= pciData
.SubClass
;
1854 RevID
= pciData
.RevisionID
;
1855 dev_id
= VendorID
| (DeviceID
<< 16);
1856 slotData
.u
.AsULONG
= slotNumber
;
1857 KdPrint2((PRINT_PREFIX
"DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id
, BaseClass
, SubClass
));
1859 deviceExtension
->slotNumber
= slotNumber
;
1860 deviceExtension
->SystemIoBusNumber
= SystemIoBusNumber
;
1861 deviceExtension
->DevID
= dev_id
;
1862 deviceExtension
->RevID
= RevID
;
1863 deviceExtension
->NumberChannels
= 2; // default
1864 deviceExtension
->DevIndex
= i
;
1866 _snprintf(deviceExtension
->Signature
, sizeof(deviceExtension
->Signature
),
1867 "UATA%8.8x/%1.1x@%8.8x", dev_id
, 0xff, slotNumber
);
1869 if(BaseClass
!= PCI_DEV_CLASS_STORAGE
) {
1870 KdPrint2((PRINT_PREFIX
"BaseClass != PCI_DEV_CLASS_STORAGE => SP_RETURN_NOT_FOUND\n"));
1874 KdPrint2((PRINT_PREFIX
"Storage Class\n"));
1876 // look for known chipsets
1877 if(VendorID
!= BMList
[i
].nVendorId
||
1878 DeviceID
!= BMList
[i
].nDeviceId
) {
1879 KdPrint2((PRINT_PREFIX
"device not suitable\n"));
1883 if((BMList
[i
].RaidFlags
& UNIATA_RAID_CONTROLLER
) &&
1885 KdPrint2((PRINT_PREFIX
"RAID support disabled\n"));
1890 case PCI_DEV_SUBCLASS_IDE
:
1891 case PCI_DEV_SUBCLASS_RAID
:
1892 case PCI_DEV_SUBCLASS_ATA
:
1893 case PCI_DEV_SUBCLASS_SATA
:
1897 KdPrint2((PRINT_PREFIX
"Subclass not supported\n"));
1901 ConfigInfo
->AlignmentMask
= 0x00000003;
1903 status
= UniataChipDetect(HwDeviceExtension
, &pciData
, i
, ConfigInfo
, &simplexOnly
);
1905 case STATUS_SUCCESS
:
1908 case STATUS_NOT_FOUND
:
1912 KdPrint2((PRINT_PREFIX
"FAILED => SP_RETURN_ERROR\n"));
1915 KdPrint2((PRINT_PREFIX
"ForceSimplex = %d\n", simplexOnly
));
1916 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (0)", deviceExtension
->HwFlags
));
1918 /* additional checks for some supported chipsets */
1920 if (SubClass
!= PCI_DEV_SUBCLASS_IDE
) {
1921 KdPrint2((PRINT_PREFIX
"0xc6931080, SubClass != PCI_DEV_SUBCLASS_IDE => found = FALSE\n"));
1928 /* unknown chipsets, try generic DMA if it seems possible */
1932 KdPrint2((PRINT_PREFIX
"Default device\n"));
1933 if(!Ata_is_supported_dev(&pciData
)) {
1934 KdPrint2((PRINT_PREFIX
"!Ata_is_supported_dev => found = FALSE\n"));
1937 KdPrint2((PRINT_PREFIX
"Ata_is_supported_dev\n"));
1940 deviceExtension
->UnknownDev
= TRUE
;
1944 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (1)", deviceExtension
->HwFlags
));
1946 KdPrint2((PRINT_PREFIX
"!found => SP_RETURN_NOT_FOUND\n"));
1950 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (2)", deviceExtension
->HwFlags
));
1951 KdPrint2((PRINT_PREFIX
"found suitable device\n"));
1953 /***********************************************************/
1954 /***********************************************************/
1955 /***********************************************************/
1957 deviceExtension
->UseDpc
= TRUE
;
1958 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (3)", deviceExtension
->HwFlags
));
1959 if(deviceExtension
->HwFlags
& UNIATA_NO_DPC
) {
1960 /* CMD 649, ROSB SWK33, ICH4 */
1961 KdPrint2((PRINT_PREFIX
"UniataFindBusMasterController: UNIATA_NO_DPC (0)\n"));
1962 deviceExtension
->UseDpc
= FALSE
;
1965 MasterDev
= IsMasterDev(&pciData
);
1968 KdPrint2((PRINT_PREFIX
"MasterDev\n"));
1969 deviceExtension
->MasterDev
= TRUE
;
1970 deviceExtension
->NumberChannels
= 1;
1972 KdPrint2((PRINT_PREFIX
"!MasterDev => SP_RETURN_NOT_FOUND\n"));
1976 if(deviceExtension
->AltRegMap
) {
1977 KdPrint2((PRINT_PREFIX
" Non-standard registers layout => SP_RETURN_NOT_FOUND\n"));
1980 if(IsBusMaster(&pciData
)) {
1981 KdPrint2((PRINT_PREFIX
" !BusMaster => SP_RETURN_NOT_FOUND\n"));
1985 KdPrint2((PRINT_PREFIX
"IsBusMaster == TRUE\n"));
1986 BaseIoAddressBM_0
= (PIDE_BUSMASTER_REGISTERS
)
1987 (AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, &pciData
, SystemIoBusNumber
,
1988 4, 0, 0x10/*ATA_BMIOSIZE*/)/* - bm_offset*/); //range id
1989 if(BaseIoAddressBM_0
) {
1990 UniataInitMapBM(deviceExtension
,
1992 (*ConfigInfo
->AccessRanges
)[4].RangeInMemory
? TRUE
: FALSE
);
1993 deviceExtension
->BusMaster
= TRUE
;
1994 deviceExtension
->BaseIoAddressBM_0
.Addr
= (ULONG_PTR
)BaseIoAddressBM_0
;
1995 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
1996 deviceExtension
->BaseIoAddressBM_0
.MemIo
= TRUE
;
1999 KdPrint2((PRINT_PREFIX
" BusMasterAddress (base): %#x\n", BaseIoAddressBM_0
));
2002 * the Cypress chip is a mess, it contains two ATA functions, but
2003 * both channels are visible on the first one.
2004 * simply ignore the second function for now, as the right
2005 * solution (ignoring the second channel on the first function)
2006 * doesn't work with the crappy ATA interrupt setup on the alpha.
2008 if (dev_id
== 0xc6931080 && slotData
.u
.bits
.FunctionNumber
> 1) {
2009 KdPrint2((PRINT_PREFIX
"dev_id == 0xc6931080 && FunctionNumber > 1 => exit_findbm\n"));
2013 // Indicate number of buses.
2014 ConfigInfo
->NumberOfBuses
= 0;
2015 if(!ConfigInfo
->InitiatorBusId
[0]) {
2016 ConfigInfo
->InitiatorBusId
[0] = (CHAR
)(IoGetConfigurationInformation()->ScsiPortCount
);
2017 KdPrint2((PRINT_PREFIX
"set ConfigInfo->InitiatorBusId[0] = %#x\n", ConfigInfo
->InitiatorBusId
[0]));
2019 // Indicate four devices can be attached to the adapter
2020 ConfigInfo
->MaximumNumberOfTargets
= 0;
2022 ConfigInfo
->MultipleRequestPerLu
= FALSE
;
2023 ConfigInfo
->AutoRequestSense
= FALSE
;
2024 ConfigInfo
->TaggedQueuing
= FALSE
;
2026 if((WinVer_Id() >= WinVer_NT
) ||
2027 (ConfigInfo
->Length
>= sizeof(_ConfigInfo
->comm
) + sizeof(_ConfigInfo
->nt4
))) {
2028 _ConfigInfo
->nt4
.DeviceExtensionSize
= sizeof(HW_DEVICE_EXTENSION
);
2029 _ConfigInfo
->nt4
.SpecificLuExtensionSize
= sizeof(HW_LU_EXTENSION
);
2030 _ConfigInfo
->nt4
.SrbExtensionSize
= sizeof(ATA_REQ
);
2032 if((WinVer_Id() > WinVer_2k
) ||
2033 (ConfigInfo
->Length
>= sizeof(_ConfigInfo
->comm
) + sizeof(_ConfigInfo
->nt4
) + sizeof(_ConfigInfo
->w2k
))) {
2034 _ConfigInfo
->w2k
.Dma64BitAddresses
= 0;
2035 _ConfigInfo
->w2k
.ResetTargetSupported
= FALSE
;
2036 _ConfigInfo
->w2k
.MaximumNumberOfLogicalUnits
= 0;
2039 // Save the Interrupe Mode for later use
2040 deviceExtension
->InterruptMode
= ConfigInfo
->InterruptMode
;
2041 deviceExtension
->BusInterruptLevel
= ConfigInfo
->BusInterruptLevel
;
2042 deviceExtension
->BusInterruptVector
= ConfigInfo
->BusInterruptVector
;
2043 deviceExtension
->Channel
= 0;
2044 deviceExtension
->DevIndex
= i
;
2045 deviceExtension
->OrigAdapterInterfaceType
2046 = ConfigInfo
->AdapterInterfaceType
;
2047 deviceExtension
->AlignmentMask
= ConfigInfo
->AlignmentMask
;
2048 deviceExtension
->AdapterInterfaceType
= PCIBus
;
2050 KdPrint2((PRINT_PREFIX
"Reconstruct ConfigInfo\n"));
2051 ConfigInfo
->MapBuffers
= TRUE
;
2053 ConfigInfo
->NeedPhysicalAddresses
= FALSE
;
2055 ConfigInfo
->NeedPhysicalAddresses
= TRUE
;
2056 #endif //USE_OWN_DMA
2060 KdPrint2((PRINT_PREFIX
"return SP_RETURN_FOUND\n"));
2061 //PrintNtConsole("return SP_RETURN_FOUND, de %#x, c0.lun0 %#x\n", deviceExtension, deviceExtension->chan[0].lun[0]);
2063 return SP_RETURN_FOUND
;
2066 if (deviceExtension
->lun
) ExFreePool(deviceExtension
->lun
);
2067 if (deviceExtension
->chan
) ExFreePool(deviceExtension
->chan
);
2068 return SP_RETURN_ERROR
;
2071 ExFreePool(deviceExtension
->lun
);
2072 ExFreePool(deviceExtension
->chan
);
2073 return SP_RETURN_NOT_FOUND
;
2075 } // end UniataFindFakeBusMasterController()
2080 Routine Description:
2082 This function is called to initialize 2nd device object for
2083 multichannel controllers.
2087 HwDeviceExtension - HBA miniport driver's adapter data storage
2097 IN PVOID HwDeviceExtension
2100 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2101 ULONG i
= deviceExtension
->DevIndex
;
2103 PISR2_DEVICE_EXTENSION Isr2DevExt
;
2104 WCHAR devname_str
[32];
2105 UNICODE_STRING devname
;
2107 KdPrint2((PRINT_PREFIX
"Init ISR:\n"));
2109 if(BMList
[i
].Isr2DevObj
) {
2110 KdPrint2((PRINT_PREFIX
"Already initialized %#x\n", BMList
[i
].Isr2DevObj
));
2111 return STATUS_SUCCESS
;
2114 if(!deviceExtension
->MasterDev
&& (deviceExtension
->NumberChannels
> 1) && // do not touch MasterDev
2115 !deviceExtension
->simplexOnly
&& /* // this is unnecessary on simplex controllers
2116 !BMList[i].Isr2DevObj*/ // handle re-init under w2k+
2120 KdPrint2((PRINT_PREFIX
"Multichannel native mode, go...\n"));
2122 KdPrint2((PRINT_PREFIX
"Unnecessary\n"));
2123 return STATUS_SUCCESS
;
2126 KdPrint2((PRINT_PREFIX
"Create DO\n"));
2129 _snwprintf(devname_str
, sizeof(devname_str
)/sizeof(WCHAR
),
2130 L
"\\Device\\uniata%d_2ch", i
);
2131 devname
.Length
*= sizeof(WCHAR
);
2132 devname
.MaximumLength
= devname
.Length
;
2133 devname
.Buffer
= devname_str
;
2135 KdPrint2((PRINT_PREFIX
"DO name: len(%d, %d), %S\n", devname
.Length
, devname
.MaximumLength
, devname
.Buffer
));
2137 status
= IoCreateDevice(SavedDriverObject
, sizeof(ISR2_DEVICE_EXTENSION
),
2138 /*NULL*/ &devname
, FILE_DEVICE_UNKNOWN
,
2139 0, FALSE
, &(BMList
[i
].Isr2DevObj
));
2141 if(!NT_SUCCESS(status
)) {
2142 KdPrint2((PRINT_PREFIX
"IoCreateDevice failed %#x\n"));
2146 KdPrint2((PRINT_PREFIX
"HalGetInterruptVector\n"));
2147 KdPrint2((PRINT_PREFIX
" OrigAdapterInterfaceType=%d\n", deviceExtension
->OrigAdapterInterfaceType
));
2148 KdPrint2((PRINT_PREFIX
" SystemIoBusNumber=%d\n", deviceExtension
->SystemIoBusNumber
));
2149 KdPrint2((PRINT_PREFIX
" BusInterruptLevel=%d\n", deviceExtension
->BusInterruptLevel
));
2150 KdPrint2((PRINT_PREFIX
" BusInterruptVector=%d\n", deviceExtension
->BusInterruptVector
));
2151 BMList
[i
].Isr2Vector
= HalGetInterruptVector(
2152 deviceExtension
->OrigAdapterInterfaceType
,
2153 deviceExtension
->SystemIoBusNumber
,
2154 deviceExtension
->BusInterruptLevel
,
2155 deviceExtension
->BusInterruptVector
,
2156 &(BMList
[i
].Isr2Irql
),
2157 &(BMList
[i
].Isr2Affinity
));
2159 Isr2DevExt
= (PISR2_DEVICE_EXTENSION
)(BMList
[i
].Isr2DevObj
->DeviceExtension
);
2160 Isr2DevExt
->HwDeviceExtension
= deviceExtension
;
2161 Isr2DevExt
->DevIndex
= i
;
2163 KdPrint2((PRINT_PREFIX
"isr2_de %#x\n", Isr2DevExt
));
2164 KdPrint2((PRINT_PREFIX
"isr2_vector %#x\n", BMList
[i
].Isr2Vector
));
2165 KdPrint2((PRINT_PREFIX
"isr2_irql %#x\n", BMList
[i
].Isr2Irql
));
2166 KdPrint2((PRINT_PREFIX
"isr2_affinity %#x\n", BMList
[i
].Isr2Affinity
));
2168 // deviceExtension->QueueNewIrql = BMList[i].Isr2Irql;
2170 KdPrint2((PRINT_PREFIX
"IoConnectInterrupt\n"));
2171 status
= IoConnectInterrupt(
2172 &(BMList
[i
].Isr2InterruptObject
),
2176 BMList
[i
].Isr2Vector
,
2179 (KINTERRUPT_MODE
)(deviceExtension
->InterruptMode
),
2181 BMList
[i
].Isr2Affinity
,
2184 if(!NT_SUCCESS(status
)) {
2185 KdPrint2((PRINT_PREFIX
"IoConnectInterrupt failed\n"));
2186 IoDeleteDevice(BMList
[i
].Isr2DevObj
);
2187 BMList
[i
].Isr2DevObj
= NULL
;
2188 BMList
[i
].Isr2InterruptObject
= NULL
;
2192 //deviceExtension->Isr2DevObj = BMList[i].Isr2DevObj;
2195 } // end UniataConnectIntr2()
2199 UniataDisconnectIntr2(
2200 IN PVOID HwDeviceExtension
2203 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2204 ULONG i
= deviceExtension
->DevIndex
;
2207 KdPrint2((PRINT_PREFIX
"Deinit ISR:\n"));
2209 if(!BMList
[i
].Isr2DevObj
) {
2210 KdPrint2((PRINT_PREFIX
"Already uninitialized %#x\n"));
2211 return STATUS_SUCCESS
;
2214 IoDisconnectInterrupt(BMList
[i
].Isr2InterruptObject
);
2216 BMList
[i
].Isr2InterruptObject
= NULL
;
2218 IoDeleteDevice(BMList
[i
].Isr2DevObj
);
2220 BMList
[i
].Isr2DevObj
= NULL
;
2221 //deviceExtension->Isr2DevObj = NULL;
2223 return STATUS_SUCCESS
;
2224 } // end UniataDisconnectIntr2()
2226 #endif //UNIATA_CORE
2230 Routine Description:
2232 This function is called by the OS-specific port driver after
2233 the necessary storage has been allocated, to gather information
2234 about the adapter's configuration.
2238 HwDeviceExtension - HBA miniport driver's adapter data storage
2239 Context - Address of adapter count
2240 ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility.
2241 ConfigInfo - Configuration information structure describing HBA
2242 Again - Indicates search for adapters to continue
2251 AtapiFindController(
2252 IN PVOID HwDeviceExtension
,
2254 IN PVOID BusInformation
,
2255 IN PCHAR ArgumentString
,
2256 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
2260 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2262 PULONG adapterCount
= (PULONG
)Context
;
2263 PUCHAR ioSpace
= NULL
;
2270 BOOLEAN preConfig
= FALSE
;
2272 PIDE_REGISTERS_1 BaseIoAddress1
;
2273 PIDE_REGISTERS_2 BaseIoAddress2
= NULL
;
2275 // The following table specifies the ports to be checked when searching for
2276 // an IDE controller. A zero entry terminates the search.
2277 static CONST ULONG AdapterAddresses
[5] = {IO_WD1
, IO_WD2
, IO_WD1
-8, IO_WD2
-8, 0};
2278 // CONST UCHAR Channels[5] = {0, 1, 0, 1, 0};
2280 // The following table specifies interrupt levels corresponding to the
2281 // port addresses in the previous table.
2282 static CONST ULONG InterruptLevels
[5] = {14, 15, 11, 10, 0};
2284 KdPrint2((PRINT_PREFIX
"AtapiFindController:\n"));
2286 if (!deviceExtension
) {
2287 return SP_RETURN_ERROR
;
2289 RtlZeroMemory(deviceExtension
, sizeof(HW_DEVICE_EXTENSION
));
2291 KdPrint2((PRINT_PREFIX
" assume max PIO4\n"));
2292 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
2293 deviceExtension
->NumberChannels
= 1;
2295 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
2299 chan
= &(deviceExtension
->chan
[0]);
2301 deviceExtension
->AdapterInterfaceType
=
2302 deviceExtension
->OrigAdapterInterfaceType
2303 = ConfigInfo
->AdapterInterfaceType
;
2307 /* do extra chipset specific setups */
2308 AtapiReadChipConfig(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, CHAN_NOT_SPECIFIED
);
2309 AtapiChipInit(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, CHAN_NOT_SPECIFIED
);
2311 // Check to see if this is a special configuration environment.
2313 if (ArgumentString
) {
2315 irq
= AtapiParseArgumentString(ArgumentString
, "Interrupt");
2318 // Both parameters must be present to proceed
2319 portBase
= AtapiParseArgumentString(ArgumentString
, "BaseAddress");
2322 // Try a default search for the part.
2328 #endif //UNIATA_CORE
2331 // Scan though the adapter address looking for adapters.
2332 if (ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[0].RangeStart
) != 0) {
2333 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2334 ConfigInfo
->AdapterInterfaceType
,
2335 ConfigInfo
->SystemIoBusNumber
,
2336 (*ConfigInfo
->AccessRanges
)[0].RangeStart
,
2337 (*ConfigInfo
->AccessRanges
)[0].RangeLength
,
2338 (BOOLEAN
) !((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
));
2340 // Since we have pre-configured information we only need to go through this loop once
2342 portBase
= ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[0].RangeStart
);
2343 KdPrint2((PRINT_PREFIX
" preconfig, portBase=%x\n", portBase
));
2347 while (AdapterAddresses
[*adapterCount
] != 0) {
2350 #endif //UNIATA_CORE
2353 deviceExtension
->DevIndex
= (*adapterCount
);
2355 portBase
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"PortBase", portBase
);
2356 irq
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"Irq", irq
);
2358 for (i
= 0; i
< 4; i
++) {
2359 // Zero device fields to ensure that if earlier devices were found,
2360 // but not claimed, the fields are cleared.
2361 deviceExtension
->lun
[i
].DeviceFlags
&= ~(DFLAGS_ATAPI_DEVICE
| DFLAGS_DEVICE_PRESENT
| DFLAGS_TAPE_DEVICE
);
2363 // Get the system physical address for this IO range.
2365 // Check if configInfo has the default information
2366 // if not, we go and find ourselves
2367 if (preConfig
== FALSE
) {
2370 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2371 ConfigInfo
->AdapterInterfaceType
,
2372 ConfigInfo
->SystemIoBusNumber
,
2373 ScsiPortConvertUlongToPhysicalAddress(portBase
),
2377 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2378 ConfigInfo
->AdapterInterfaceType
,
2379 ConfigInfo
->SystemIoBusNumber
,
2380 ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses
[*adapterCount
]),
2386 BaseIoAddress1
= (PIDE_REGISTERS_1
)ioSpace
;
2388 // Update the adapter count.
2391 // Check if ioSpace accessible.
2393 KdPrint2((PRINT_PREFIX
"AtapiFindController: !ioSpace\n"));
2396 // check if Primary/Secondary Master IDE claimed
2397 if((ioSpace
== (PUCHAR
)IO_WD1
) &&
2398 (ConfigInfo
->AtdiskPrimaryClaimed
)) {
2399 KdPrint2((PRINT_PREFIX
"AtapiFindController: AtdiskPrimaryClaimed\n"));
2402 if((ioSpace
== (PUCHAR
)IO_WD2
) &&
2403 (ConfigInfo
->AtdiskSecondaryClaimed
)) {
2404 KdPrint2((PRINT_PREFIX
"AtapiFindController: AtdiskSecondaryClaimed\n"));
2408 // Get the system physical address for the second IO range.
2409 if (BaseIoAddress1
) {
2411 !ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[1].RangeStart
)) {
2412 KdPrint2((PRINT_PREFIX
"AtapiFindController: PCMCIA ?\n"));
2413 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2414 ConfigInfo
->AdapterInterfaceType
,
2415 ConfigInfo
->SystemIoBusNumber
,
2416 ScsiPortConvertUlongToPhysicalAddress((ULONG_PTR
)BaseIoAddress1
+ 0x0E),
2420 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2421 ConfigInfo
->AdapterInterfaceType
,
2422 ConfigInfo
->SystemIoBusNumber
,
2423 ScsiPortConvertUlongToPhysicalAddress((ULONG_PTR
)BaseIoAddress1
+ ATA_ALTOFFSET
),
2428 BaseIoAddress2
= (PIDE_REGISTERS_2
)ioSpace
;
2429 KdPrint2((PRINT_PREFIX
" BaseIoAddress1=%x\n", BaseIoAddress1
));
2430 KdPrint2((PRINT_PREFIX
" BaseIoAddress2=%x\n", BaseIoAddress2
));
2432 UniataInitMapBase(chan
, BaseIoAddress1
, BaseIoAddress2
);
2433 UniataInitMapBM(deviceExtension
, 0, FALSE
);
2438 SelectDrive(chan
, 0);
2440 // Check if card at this address.
2441 AtapiWritePort1(chan
, IDX_IO1_o_CylinderLow
, 0xAA);
2443 // Check if indentifier can be read back.
2444 if ((statusByte
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
)) != 0xAA) {
2446 KdPrint2((PRINT_PREFIX
"AtapiFindController: Identifier read back from Master (%#x)\n",
2449 statusByte
= AtapiReadPort1(chan
, IDX_IO2_AltStatus
);
2451 if (statusByte
& IDE_STATUS_BUSY
) {
2455 // Could be the TEAC in a thinkpad. Their dos driver puts it in a sleep-mode that
2456 // warm boots don't clear.
2458 AtapiStallExecution(1000);
2459 statusByte
= AtapiReadPort1(chan
, IDX_ATAPI_IO1_i_Status
);
2460 KdPrint2((PRINT_PREFIX
2461 "AtapiFindController: First access to status %#x\n",
2463 } while ((statusByte
& IDE_STATUS_BUSY
) && ++i
< 10);
2465 if (retryCount
-- && (!(statusByte
& IDE_STATUS_BUSY
))) {
2466 goto retryIdentifier
;
2471 SelectDrive(chan
, 1);
2473 // See if slave is present.
2474 AtapiWritePort1(chan
, IDX_IO1_o_CylinderLow
, 0xAA);
2476 if ((statusByte
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
)) != 0xAA) {
2478 KdPrint2((PRINT_PREFIX
2479 "AtapiFindController: Identifier read back from Slave (%#x)\n",
2482 // No controller at this base address.
2483 if(BaseIoAddress1
) {
2484 ScsiPortFreeDeviceBase(HwDeviceExtension
,
2485 (PCHAR
)BaseIoAddress1
);
2486 BaseIoAddress1
= NULL
;
2488 if(BaseIoAddress2
) {
2489 ScsiPortFreeDeviceBase(HwDeviceExtension
,
2490 (PCHAR
)BaseIoAddress2
);
2491 BaseIoAddress2
= NULL
;
2497 // Fill in the access array information only if default params are not in there.
2498 if (preConfig
== FALSE
) {
2500 // An adapter has been found request another call, only if we didn't get preconfigured info.
2504 (*ConfigInfo
->AccessRanges
)[0].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(portBase
);
2506 (*ConfigInfo
->AccessRanges
)[0].RangeStart
=
2507 ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses
[*adapterCount
- 1]);
2510 (*ConfigInfo
->AccessRanges
)[0].RangeLength
= 8;
2511 (*ConfigInfo
->AccessRanges
)[0].RangeInMemory
= FALSE
;
2513 // Indicate the interrupt level corresponding to this IO range.
2515 ConfigInfo
->BusInterruptLevel
= irq
;
2517 ConfigInfo
->BusInterruptLevel
= InterruptLevels
[*adapterCount
- 1];
2520 if (ConfigInfo
->AdapterInterfaceType
== MicroChannel
) {
2521 ConfigInfo
->InterruptMode
= LevelSensitive
;
2523 ConfigInfo
->InterruptMode
= Latched
;
2527 ConfigInfo
->NumberOfBuses
= 1;
2528 ConfigInfo
->MaximumNumberOfTargets
= 2;
2530 // Indicate maximum transfer length is 64k.
2531 ConfigInfo
->MaximumTransferLength
= 0x10000;
2532 deviceExtension
->MaximumDmaTransferLength
= ConfigInfo
->MaximumTransferLength
;
2534 KdPrint2((PRINT_PREFIX
"de %#x, Channel ???\n", deviceExtension
));
2535 //PrintNtConsole("de %#x, Channel %#x, nchan %#x\n",deviceExtension, channel, deviceExtension->NumberChannels);
2537 KdPrint2((PRINT_PREFIX
"chan = %#x\n", chan
));
2538 //PrintNtConsole("chan = %#x, c=%#x\n", chan, c);
2539 chan
->DeviceExtension
= deviceExtension
;
2541 chan
->lun
[0] = &(deviceExtension
->lun
[0]);
2542 chan
->lun
[1] = &(deviceExtension
->lun
[1]);
2544 /* do extra channel-specific setups */
2545 AtapiReadChipConfig(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, 0);
2546 AtapiChipInit(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, 0);
2548 KdPrint2((PRINT_PREFIX
2549 "AtapiFindController: Found IDE at %#x\n",
2552 // For Daytona, the atdisk driver gets the first shot at the
2553 // primary and secondary controllers.
2554 if (preConfig
== FALSE
) {
2556 if (*adapterCount
- 1 < 2) {
2558 // Determine whether this driver is being initialized by the
2559 // system or as a crash dump driver.
2560 if (ArgumentString
) {
2563 if (AtapiParseArgumentString(ArgumentString
, "dump") == 1) {
2564 KdPrint2((PRINT_PREFIX
2565 "AtapiFindController: Crash dump\n"));
2567 deviceExtension
->DriverMustPoll
= TRUE
;
2569 KdPrint2((PRINT_PREFIX
2570 "AtapiFindController: Atapi Only\n"));
2572 deviceExtension
->DriverMustPoll
= FALSE
;
2574 #endif //UNIATA_CORE
2577 KdPrint2((PRINT_PREFIX
2578 "AtapiFindController: Atapi Only (2)\n"));
2580 deviceExtension
->DriverMustPoll
= FALSE
;
2590 deviceExtension
->DriverMustPoll
= FALSE
;
2594 // Save the Interrupe Mode for later use
2595 deviceExtension
->InterruptMode
= ConfigInfo
->InterruptMode
;
2597 KdPrint2((PRINT_PREFIX
2598 "AtapiFindController: look for devices\n"));
2599 // Search for devices on this controller.
2600 if (FindDevices(HwDeviceExtension
,
2604 KdPrint2((PRINT_PREFIX
2605 "AtapiFindController: detected\n"));
2606 // Claim primary or secondary ATA IO range.
2610 ConfigInfo
->AtdiskSecondaryClaimed
= TRUE
;
2611 chan
->PrimaryAddress
= FALSE
;
2614 ConfigInfo
->AtdiskPrimaryClaimed
= TRUE
;
2615 chan
->PrimaryAddress
= TRUE
;
2621 if (*adapterCount
== 1) {
2622 ConfigInfo
->AtdiskPrimaryClaimed
= TRUE
;
2623 chan
->PrimaryAddress
= TRUE
;
2624 } else if (*adapterCount
== 2) {
2625 ConfigInfo
->AtdiskSecondaryClaimed
= TRUE
;
2626 chan
->PrimaryAddress
= FALSE
;
2630 if(deviceExtension
->AdapterInterfaceType
== Isa
) {
2633 if(deviceExtension
->AdapterInterfaceType
== MicroChannel
) {
2637 KdPrint2((PRINT_PREFIX
2638 "AtapiFindController: return SP_RETURN_FOUND\n"));
2639 return(SP_RETURN_FOUND
);
2645 #endif //UNIATA_CORE
2647 // The entire table has been searched and no adapters have been found.
2648 // There is no need to call again and the device base can now be freed.
2649 // Clear the adapter count for the next bus.
2651 *(adapterCount
) = 0;
2653 KdPrint2((PRINT_PREFIX
2654 "AtapiFindController: return SP_RETURN_NOT_FOUND\n"));
2655 ExFreePool(deviceExtension
->lun
);
2656 ExFreePool(deviceExtension
->chan
);
2657 return(SP_RETURN_NOT_FOUND
);
2660 if (deviceExtension
->lun
) ExFreePool(deviceExtension
->lun
);
2661 if (deviceExtension
->chan
) ExFreePool(deviceExtension
->chan
);
2662 return SP_RETURN_ERROR
;
2664 } // end AtapiFindController()
2669 IN PVOID HwDeviceExtension
,
2671 IN ULONG deviceNumber
2674 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2675 PHW_CHANNEL chan
= &(deviceExtension
->chan
[lChannel
]);
2676 ULONG ldev
= GET_LDEV2(lChannel
, deviceNumber
, 0);
2677 PHW_LU_EXTENSION LunExt
= &(deviceExtension
->lun
[ldev
]);
2679 SATA_SSTATUS_REG SStatus
;
2681 UCHAR signatureHigh
;
2683 if(LunExt
->DeviceFlags
& DFLAGS_HIDDEN
) {
2684 KdPrint2((PRINT_PREFIX
" hidden\n"));
2685 UniataForgetDevice(LunExt
);
2688 // Select the device.
2689 SelectDrive(chan
, deviceNumber
);
2691 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
);
2692 signatureHigh
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderHigh
);
2694 if (signatureLow
== ATAPI_MAGIC_LSB
&& signatureHigh
== ATAPI_MAGIC_MSB
) {
2695 KdPrint2((PRINT_PREFIX
" ATAPI at home\n", signatureLow
));
2699 if(!UniataIsSATARangeAvailable(deviceExtension
, lChannel
)) {
2700 AtapiStallExecution(10);
2702 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0x55);
2703 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0x55);
2704 AtapiStallExecution(5);
2705 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_BlockNumber
);
2706 if(signatureLow
!= 0x55) {
2707 KdPrint2((PRINT_PREFIX
" nobody home! %#x != 0x55\n", signatureLow
));
2708 UniataForgetDevice(LunExt
);
2712 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0xAA);
2713 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0xAA);
2714 AtapiStallExecution(5);
2715 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_BlockNumber
);
2716 if(signatureLow
!= 0xAA) {
2717 KdPrint2((PRINT_PREFIX
" nobody home! %#x != 0xAA\n", signatureLow
));
2718 UniataForgetDevice(LunExt
);
2723 SStatus
.Reg
= UniataSataReadPort4(chan
, IDX_SATA_SStatus
, deviceNumber
);
2724 KdPrint2((PRINT_PREFIX
"SStatus %x\n", SStatus
.Reg
));
2725 if(SStatus
.DET
<= SStatus_DET_Dev_NoPhy
) {
2726 KdPrint2((PRINT_PREFIX
" SATA DET <= SStatus_DET_Dev_NoPhy\n"));
2729 if(SStatus
.SPD
< SStatus_SPD_Gen1
) {
2730 KdPrint2((PRINT_PREFIX
" SATA SPD < SStatus_SPD_Gen1\n"));
2733 if(SStatus
.IPM
== SStatus_IPM_NoDev
) {
2734 KdPrint2((PRINT_PREFIX
" SATA IPN == SStatus_IPM_NoDev\n"));
2740 } // end UniataAnybodyHome()
2745 IN PVOID HwDeviceExtension
,
2747 IN ULONG deviceNumber
,
2751 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2752 PHW_CHANNEL chan
= &(deviceExtension
->chan
[lChannel
]);
2753 ULONG ldev
= GET_LDEV2(lChannel
, deviceNumber
, 0);
2754 PHW_LU_EXTENSION LunExt
= &(deviceExtension
->lun
[ldev
]);
2760 ULONG waitCount
= 10000;
2762 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x\n",
2765 KdPrint2((PRINT_PREFIX
"CheckDevice: reset dev\n"));
2768 AtapiSoftReset(chan
, deviceNumber
);
2770 if(!UniataAnybodyHome(HwDeviceExtension
, lChannel
, deviceNumber
)) {
2773 statusByte
= WaitOnBusy(chan
);
2775 if((statusByte
| IDE_STATUS_BUSY
) == 0xff) {
2776 KdPrint2((PRINT_PREFIX
2777 "CheckDevice: bad status %x\n", statusByte
));
2779 if(statusByte
!= 0xff && (statusByte
& IDE_STATUS_BUSY
)) {
2780 // Perform hard-reset.
2781 KdPrint2((PRINT_PREFIX
2782 "CheckDevice: BUSY\n"));
2784 AtapiWritePort1(chan
, IDX_IO2_o_Control
, IDE_DC_RESET_CONTROLLER
);
2785 AtapiStallExecution(500 * 1000);
2786 AtapiWritePort1(chan
, IDX_IO2_o_Control
, IDE_DC_REENABLE_CONTROLLER
);
2787 SelectDrive(chan
, deviceNumber
& 0x01);
2790 // Wait for Busy to drop.
2791 AtapiStallExecution(100);
2792 GetStatus(chan
, statusByte
);
2794 } while ((statusByte
& IDE_STATUS_BUSY
) && waitCount
--);
2796 GetBaseStatus(chan
, statusByte
);
2797 KdPrint2((PRINT_PREFIX
2798 "CheckDevice: status after hard reset %x\n", statusByte
));
2801 if((statusByte
| IDE_STATUS_BUSY
) == 0xff) {
2802 KdPrint2((PRINT_PREFIX
2803 "CheckDevice: no dev ?\n"));
2805 if(UniataIsSATARangeAvailable(deviceExtension
, lChannel
)) {
2806 //if(deviceExtension->HwFlags & UNIATA_SATA) {
2807 KdPrint2((PRINT_PREFIX
2808 "CheckDevice: try enable SATA Phy\n"));
2809 statusByte
= UniataSataPhyEnable(HwDeviceExtension
, lChannel
, deviceNumber
);
2810 if(statusByte
== 0xff) {
2811 KdPrint2((PRINT_PREFIX
"CheckDevice: status %#x (no dev)\n", statusByte
));
2812 UniataForgetDevice(LunExt
);
2817 // Select the device.
2818 SelectDrive(chan
, deviceNumber
);
2820 if(!UniataAnybodyHome(HwDeviceExtension
, lChannel
, deviceNumber
)) {
2824 statusByte
= WaitOnBaseBusyLong(chan
);
2826 GetBaseStatus(chan
, statusByte
);
2827 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
2828 UniataSataClearErr(HwDeviceExtension
, lChannel
, UNIATA_SATA_IGNORE_CONNECT
, deviceNumber
);
2831 KdPrint2((PRINT_PREFIX
"CheckDevice: status %#x\n", statusByte
));
2832 if(((statusByte
| IDE_STATUS_BUSY
) == 0xff) ||
2833 (statusByte
& IDE_STATUS_BUSY
)) {
2834 KdPrint2((PRINT_PREFIX
"CheckDevice: busy => return\n"));
2835 UniataForgetDevice(LunExt
);
2839 // set default costs
2840 LunExt
->RwSwitchCost
= REORDER_COST_SWITCH_RW_HDD
;
2841 LunExt
->RwSwitchMCost
= REORDER_MCOST_SWITCH_RW_HDD
;
2842 LunExt
->SeekBackMCost
= REORDER_MCOST_SEEK_BACK_HDD
;
2844 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
);
2845 signatureHigh
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderHigh
);
2847 if (signatureLow
== ATAPI_MAGIC_LSB
&& signatureHigh
== ATAPI_MAGIC_MSB
) {
2849 KdPrint2((PRINT_PREFIX
"CheckDevice: ATAPI signature found\n"));
2850 // ATAPI signature found.
2851 // Issue the ATAPI identify command if this
2852 // is not for the crash dump utility.
2854 if (!deviceExtension
->DriverMustPoll
) {
2856 // Issue ATAPI packet identify command.
2857 if (IssueIdentify(HwDeviceExtension
,
2860 IDE_COMMAND_ATAPI_IDENTIFY
, FALSE
)) {
2862 // Indicate ATAPI device.
2863 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x is ATAPI\n",
2866 RetVal
= DFLAGS_DEVICE_PRESENT
| DFLAGS_ATAPI_DEVICE
;
2867 LunExt
->DeviceFlags
|= (DFLAGS_DEVICE_PRESENT
| DFLAGS_ATAPI_DEVICE
);
2869 // some ATAPI devices doesn't work with DPC on CMD-649
2870 // and probably some other controllers
2871 if(deviceExtension
->HwFlags
& UNIATA_NO_DPC_ATAPI
) {
2872 /* CMD 649, ROSB SWK33, ICH4 */
2873 KdPrint2((PRINT_PREFIX
"CheckDevice: UNIATA_NO_DPC_ATAPI\n"));
2874 deviceExtension
->UseDpc
= FALSE
;
2877 GetStatus(chan
, statusByte
);
2878 if (statusByte
& IDE_STATUS_ERROR
) {
2879 AtapiSoftReset(chan
, deviceNumber
);
2884 // Indicate no working device.
2885 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x not responding\n",
2888 UniataForgetDevice(LunExt
);
2891 GetBaseStatus(chan
, statusByte
);
2897 KdPrint2((PRINT_PREFIX
"CheckDevice: IDE device check\n"));
2898 // Issue IDE Identify. If an Atapi device is actually present, the signature
2899 // will be asserted, and the drive will be recognized as such.
2900 if(deviceExtension
->DWordIO
) {
2901 KdPrint2((PRINT_PREFIX
" try 32bit IO\n"));
2902 LunExt
->DeviceFlags
|= DFLAGS_DWORDIO_ENABLED
;
2904 if (IssueIdentify(HwDeviceExtension
,
2907 IDE_COMMAND_IDENTIFY
, FALSE
)) {
2910 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x is IDE\n",
2913 // Indicate IDE - not ATAPI device.
2914 RetVal
= DFLAGS_DEVICE_PRESENT
;
2915 LunExt
->DeviceFlags
|= DFLAGS_DEVICE_PRESENT
;
2916 LunExt
->DeviceFlags
&= ~DFLAGS_ATAPI_DEVICE
;
2918 GetBaseStatus(chan
, statusByte
);
2920 KdPrint2((PRINT_PREFIX
"CheckDevice: check status: %sfound\n", RetVal
? "" : "not "));
2922 } // end CheckDevice()
2927 Routine Description:
2929 This routine is called from AtapiFindController to identify
2930 devices attached to an IDE controller.
2934 HwDeviceExtension - HBA miniport driver's adapter data storage
2935 AtapiOnly - Indicates that routine should return TRUE only if
2936 an ATAPI device is attached to the controller.
2940 TRUE - True if devices found.
2946 IN PVOID HwDeviceExtension
,
2951 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2952 PHW_CHANNEL chan
= &(deviceExtension
->chan
[Channel
]);
2953 PHW_LU_EXTENSION LunExt
;
2954 BOOLEAN deviceResponded
= FALSE
,
2955 skipSetParameters
= FALSE
;
2956 ULONG waitCount
= 10000;
2957 //ULONG deviceNumber;
2962 BOOLEAN AtapiOnly
= FALSE
;
2964 KdPrint2((PRINT_PREFIX
"FindDevices:\n"));
2966 // Disable interrupts
2967 AtapiDisableInterrupts(deviceExtension
, Channel
);
2968 // AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_DISABLE_INTERRUPTS | IDE_DC_A_4BIT );
2970 // Clear expecting interrupt flag and current SRB field.
2971 chan
->ExpectingInterrupt
= FALSE
;
2972 // chan->CurrentSrb = NULL;
2973 max_ldev
= (chan
->ChannelCtrlFlags
& CTRFLAGS_NO_SLAVE
) ? 1 : 2;
2974 KdPrint2((PRINT_PREFIX
" max_ldev %d\n", max_ldev
));
2976 // Search for devices.
2977 for (i
= 0; i
< max_ldev
; i
++) {
2978 AtapiDisableInterrupts(deviceExtension
, Channel
);
2979 if(Flags
& UNIATA_FIND_DEV_UNHIDE
) {
2980 ldev
= GET_LDEV2(Channel
, i
, 0);
2981 deviceExtension
->lun
[ldev
].DeviceFlags
&= ~DFLAGS_HIDDEN
;
2984 (CheckDevice(HwDeviceExtension
, Channel
, i
, TRUE
) != 0);
2985 AtapiEnableInterrupts(deviceExtension
, Channel
);
2988 for (i
= 0; i
< max_ldev
; i
++) {
2989 ldev
= GET_LDEV2(Channel
, i
, 0);
2990 LunExt
= &(deviceExtension
->lun
[ldev
]);
2992 if (( LunExt
->DeviceFlags
& DFLAGS_DEVICE_PRESENT
) &&
2993 !(LunExt
->DeviceFlags
& DFLAGS_LBA_ENABLED
) &&
2994 !(LunExt
->DeviceFlags
& DFLAGS_ATAPI_DEVICE
) && deviceResponded
) {
2996 // This hideous hack is to deal with ESDI devices that return
2997 // garbage geometry in the IDENTIFY data.
2998 // This is ONLY for the crashdump environment as
2999 // these are ESDI devices.
3000 if (LunExt
->IdentifyData
.SectorsPerTrack
==
3002 LunExt
->IdentifyData
.NumberOfHeads
==
3005 KdPrint2((PRINT_PREFIX
3006 "FindDevices: Found nasty Compaq ESDI!\n"));
3008 // Change these values to something reasonable.
3009 LunExt
->IdentifyData
.SectorsPerTrack
=
3011 LunExt
->IdentifyData
.NumberOfHeads
=
3015 if (LunExt
->IdentifyData
.SectorsPerTrack
==
3017 LunExt
->IdentifyData
.NumberOfHeads
==
3020 KdPrint2((PRINT_PREFIX
3021 "FindDevices: Found nasty Compaq ESDI!\n"));
3023 // Change these values to something reasonable.
3024 LunExt
->IdentifyData
.SectorsPerTrack
=
3026 LunExt
->IdentifyData
.NumberOfHeads
=
3031 if (LunExt
->IdentifyData
.SectorsPerTrack
==
3033 LunExt
->IdentifyData
.NumberOfHeads
==
3036 KdPrint2((PRINT_PREFIX
"FindDevices: Found nasty UltraStor ESDI!\n"));
3038 // Change these values to something reasonable.
3039 LunExt
->IdentifyData
.SectorsPerTrack
=
3041 LunExt
->IdentifyData
.NumberOfHeads
=
3043 skipSetParameters
= TRUE
;
3047 if (skipSetParameters
)
3050 statusByte
= WaitOnBusy(chan
);
3052 // Select the device.
3053 SelectDrive(chan
, i
& 0x01);
3054 GetStatus(chan
, statusByte
);
3056 if (statusByte
& IDE_STATUS_ERROR
) {
3058 // Reset the device.
3059 KdPrint2((PRINT_PREFIX
3060 "FindDevices: Resetting controller before SetDriveParameters.\n"));
3062 AtapiWritePort1(chan
, IDX_IO2_o_Control
, IDE_DC_RESET_CONTROLLER
);
3063 AtapiStallExecution(500 * 1000);
3064 AtapiWritePort1(chan
, IDX_IO2_o_Control
, IDE_DC_REENABLE_CONTROLLER
);
3065 SelectDrive(chan
, i
& 0x01);
3068 // Wait for Busy to drop.
3069 AtapiStallExecution(100);
3070 GetStatus(chan
, statusByte
);
3072 } while ((statusByte
& IDE_STATUS_BUSY
) && waitCount
--);
3075 statusByte
= WaitOnBusy(chan
);
3077 KdPrint2((PRINT_PREFIX
3078 "FindDevices: Status before SetDriveParameters: (%#x) (%#x)\n",
3080 AtapiReadPort1(chan
, IDX_IO1_i_DriveSelect
)));
3082 GetBaseStatus(chan
, statusByte
);
3084 // Use the IDENTIFY data to set drive parameters.
3085 if (!SetDriveParameters(HwDeviceExtension
,i
,Channel
)) {
3087 KdPrint2((PRINT_PREFIX
3088 "FindDevices: Set drive parameters for device %d failed\n",
3090 // Don't use this device as writes could cause corruption.
3091 LunExt
->DeviceFlags
&= ~DFLAGS_DEVICE_PRESENT
;
3092 UniataForgetDevice(&(deviceExtension
->lun
[ldev
]));
3096 if (LunExt
->DeviceFlags
& DFLAGS_REMOVABLE_DRIVE
) {
3098 // Pick up ALL IDE removable drives that conform to Yosemite V0.2...
3102 // Indicate that a device was found.
3104 deviceResponded
= TRUE
;
3109 /* // Reset the controller. This is a feeble attempt to leave the ESDI
3110 // controllers in a state that ATDISK driver will recognize them.
3111 // The problem in ATDISK has to do with timings as it is not reproducible
3112 // in debug. The reset should restore the controller to its poweron state
3113 // and give the system enough time to settle.
3114 if (!deviceResponded) {
3116 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_RESET_CONTROLLER );
3117 AtapiStallExecution(50 * 1000);
3118 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_REENABLE_CONTROLLER);
3121 if(deviceResponded
) {
3122 for (i
= 0; i
< max_ldev
; i
++) {
3123 ldev
= GET_LDEV2(Channel
, i
, 0);
3124 LunExt
= &(deviceExtension
->lun
[ldev
]);
3126 KdPrint2((PRINT_PREFIX
3127 "FindDevices: select %d dev to clear INTR\n", i
));
3128 SelectDrive(chan
, i
);
3129 GetBaseStatus(chan
, statusByte
);
3130 KdPrint2((PRINT_PREFIX
3131 "FindDevices: statusByte=%#x\n", statusByte
));
3133 for (i
= 0; i
< max_ldev
; i
++) {
3134 ldev
= GET_LDEV2(Channel
, i
, 0);
3135 LunExt
= &(deviceExtension
->lun
[ldev
]);
3137 if(LunExt
->DeviceFlags
& DFLAGS_DEVICE_PRESENT
) {
3138 // Make sure some device (master is preferred) is selected on exit.
3139 KdPrint2((PRINT_PREFIX
3140 "FindDevices: select %d dev on exit\n", i
));
3141 SelectDrive(chan
, i
);
3147 GetBaseStatus(chan
, statusByte
);
3148 // Enable interrupts
3149 AtapiEnableInterrupts(deviceExtension
, Channel
);
3150 // AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_A_4BIT );
3151 GetBaseStatus(chan
, statusByte
);
3153 KdPrint2((PRINT_PREFIX
3154 "FindDevices: returning %d\n",
3157 return deviceResponded
;
3159 } // end FindDevices()