3 Copyright (c) 2002-2008 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
;
632 if(BusNumber
== PCIBUSNUM_NOT_SPECIFIED
) {
634 busNumber2
= maxPciBus
;
636 busNumber
= BusNumber
;
637 busNumber2
= BusNumber
+1;
639 // set start/end slot
640 if(SlotNumber
== PCISLOTNUM_NOT_SPECIFIED
) {
642 slotNumber2
= PCI_MAX_DEVICES
;
644 slotNumber
= SlotNumber
;
645 slotNumber2
= SlotNumber
+1;
647 slotData
.u
.AsULONG
= 0;
649 for( ; busNumber
< busNumber2
; busNumber
++ ) {
650 for( ; slotNumber
< slotNumber2
; slotNumber
++) {
651 for(funcNumber
=0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
653 slotData
.u
.bits
.DeviceNumber
= slotNumber
;
654 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
656 busDataRead
= HalGetBusData(
657 //ScsiPortGetBusData(HwDeviceExtension,
658 PCIConfiguration
, busNumber
, slotData
.u
.AsULONG
,
659 &pciData
, PCI_COMMON_HDR_LENGTH
);
660 // no more buses (this should not happen)
664 // no device in this slot
668 if(busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
)
671 i
= Ata_is_dev_listed(BusMasterAdapters
, pciData
.VendorID
, pciData
.DeviceID
, pciData
.RevisionID
, lim
);
672 if(i
!= BMLIST_TERMINATOR
) {
674 *_slotData
= slotData
;
680 } // end AtapiFindListedDev()
683 Looks for device with specified Device/Vendor and Revision
684 on specified Bus/Slot
689 IN PVOID HwDeviceExtension
,
690 IN BUS_DATA_TYPE BusDataType
,
697 PCI_COMMON_CONFIG pciData
;
703 PCI_SLOT_NUMBER slotData
;
705 slotData
.u
.AsULONG
= SlotNumber
;
706 // walk through all Function Numbers
707 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
709 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
710 if(slotData
.u
.AsULONG
== SlotNumber
)
713 busDataRead
= HalGetBusData(
714 //busDataRead = ScsiPortGetBusData(HwDeviceExtension,
719 PCI_COMMON_HDR_LENGTH
);
721 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
725 VendorID
= pciData
.VendorID
;
726 DeviceID
= pciData
.DeviceID
;
728 if(dev_id
!= (VendorID
| (DeviceID
<< 16)) )
730 if(RevID
>= pciData
.RevisionID
)
734 } // end AtapiFindDev()
741 UniataFindCompatBusMasterController1(
742 IN PVOID HwDeviceExtension
,
744 IN PVOID BusInformation
,
745 IN PCHAR ArgumentString
,
746 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
750 return UniataFindBusMasterController(
758 } // end UniataFindCompatBusMasterController1()
762 UniataFindCompatBusMasterController2(
763 IN PVOID HwDeviceExtension
,
765 IN PVOID BusInformation
,
766 IN PCHAR ArgumentString
,
767 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
771 return UniataFindBusMasterController(
779 } // end UniataFindCompatBusMasterController2()
783 UniataAllocateLunExt(
784 PHW_DEVICE_EXTENSION deviceExtension
,
785 ULONG NewNumberChannels
788 PHW_LU_EXTENSION old_luns
= NULL
;
789 PHW_CHANNEL old_chans
= NULL
;
791 KdPrint2((PRINT_PREFIX
"allocate Luns for %d channels\n", deviceExtension
->NumberChannels
));
793 old_luns
= deviceExtension
->lun
;
794 old_chans
= deviceExtension
->chan
;
796 if(old_luns
|| old_chans
) {
797 if(NewNumberChannels
== UNIATA_ALLOCATE_NEW_LUNS
) {
798 KdPrint2((PRINT_PREFIX
"already allocated!\n"));
803 deviceExtension
->lun
= (PHW_LU_EXTENSION
)ExAllocatePool(NonPagedPool
, sizeof(HW_LU_EXTENSION
) * (deviceExtension
->NumberChannels
+1) * IDE_MAX_LUN_PER_CHAN
);
804 if (!deviceExtension
->lun
) {
805 KdPrint2((PRINT_PREFIX
"!deviceExtension->lun => SP_RETURN_ERROR\n"));
808 RtlZeroMemory(deviceExtension
->lun
, sizeof(HW_LU_EXTENSION
) * (deviceExtension
->NumberChannels
+1) * IDE_MAX_LUN_PER_CHAN
);
810 deviceExtension
->chan
= (PHW_CHANNEL
)ExAllocatePool(NonPagedPool
, sizeof(HW_CHANNEL
) * (deviceExtension
->NumberChannels
+1));
811 if (!deviceExtension
->chan
) {
812 KdPrint2((PRINT_PREFIX
"!deviceExtension->chan => SP_RETURN_ERROR\n"));
815 RtlZeroMemory(deviceExtension
->chan
, sizeof(HW_CHANNEL
) * (deviceExtension
->NumberChannels
+1));
817 } // end UniataAllocateLunExt()
824 This function is called by the OS-specific port driver after
825 the necessary storage has been allocated, to gather information
826 about the adapter's configuration.
830 HwDeviceExtension - HBA miniport driver's adapter data storage
831 Context - Address of adapter count
833 ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility.
834 ConfigInfo - Configuration information structure describing HBA
835 Again - Indicates search for adapters to continue
844 UniataFindBusMasterController(
845 IN PVOID HwDeviceExtension
,
847 IN PVOID BusInformation
,
848 IN PCHAR ArgumentString
,
849 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
853 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
854 PHW_CHANNEL chan
= NULL
;
856 // this buffer must be global for UNIATA_CORE build
857 PCI_COMMON_CONFIG pciData
;
861 ULONG SystemIoBusNumber
;
863 UCHAR vendorString
[5];
864 UCHAR deviceString
[5];
874 PCI_SLOT_NUMBER slotData
;
886 BOOLEAN found
= FALSE
;
888 BOOLEAN simplexOnly
= FALSE
;
890 #ifdef UNIATA_INIT_ON_PROBE
891 BOOLEAN skip_find_dev
= FALSE
;
894 BOOLEAN AltInit
= FALSE
;
896 SCSI_PHYSICAL_ADDRESS IoBasePort1
;
897 SCSI_PHYSICAL_ADDRESS IoBasePort2
;
899 PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0
= NULL
;
900 PIDE_REGISTERS_1 BaseIoAddress1
[IDE_MAX_CHAN
];
901 PIDE_REGISTERS_2 BaseIoAddress2
[IDE_MAX_CHAN
];
903 RtlZeroMemory(&BaseIoAddress1
, sizeof(BaseIoAddress1
));
904 RtlZeroMemory(&BaseIoAddress2
, sizeof(BaseIoAddress2
));
907 PPORT_CONFIGURATION_INFORMATION_COMMON _ConfigInfo
=
908 (PPORT_CONFIGURATION_INFORMATION_COMMON
)ConfigInfo
;
910 if(!WinVer_WDM_Model
) {
916 KdPrint2((PRINT_PREFIX
"UniataFindBusMasterController: Context=%x, BMListLen=%d\n", Context
, BMListLen
));
918 KdPrint2((PRINT_PREFIX
"ConfigInfo->Length %x\n", ConfigInfo
->Length
));
921 KdPrint2((PRINT_PREFIX
"ForceSimplex (1)\n"));
925 if(ConfigInfo
->AdapterInterfaceType
== Isa
) {
926 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType: Isa\n"));
929 i
= (ULONG_PTR
)Context
;
934 channel
= BMList
[i
].channel
;
937 for(i
=0; i
<BMListLen
; i
++) {
938 if(BMList
[i
].slotNumber
== ConfigInfo
->SlotNumber
&&
939 BMList
[i
].busNumber
== ConfigInfo
->SystemIoBusNumber
) {
944 KdPrint2((PRINT_PREFIX
"unexpected device arrival\n"));
945 i
= (ULONG_PTR
)Context
;
951 KdPrint2((PRINT_PREFIX
" => SP_RETURN_NOT_FOUND\n"));
955 BMList
[i
].channel
= (UCHAR
)channel
;
958 bm_offset
= channel
? ATA_BM_OFFSET1
: 0;
960 KdPrint2((PRINT_PREFIX
"bm_offset %x, channel %x \n", bm_offset
, channel
));
962 if (!deviceExtension
) {
963 KdPrint2((PRINT_PREFIX
"!deviceExtension => SP_RETURN_ERROR\n"));
964 return SP_RETURN_ERROR
;
967 RtlZeroMemory(deviceExtension
, sizeof(HW_DEVICE_EXTENSION
));
969 vendorStrPtr
= vendorString
;
970 deviceStrPtr
= deviceString
;
972 slotNumber
= BMList
[i
].slotNumber
;
973 SystemIoBusNumber
= BMList
[i
].busNumber
;
976 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType=%#x\n",ConfigInfo
->AdapterInterfaceType
));
977 KdPrint2((PRINT_PREFIX
"IoBusNumber=%#x\n",ConfigInfo
->SystemIoBusNumber
));
978 KdPrint2((PRINT_PREFIX
"slotNumber=%#x\n",slotNumber
));
980 // this buffer must be global and already filled for UNIATA_CORE build
981 busDataRead
= HalGetBusData(
982 //busDataRead = ScsiPortGetBusData(HwDeviceExtension,
987 PCI_COMMON_HDR_LENGTH
);
990 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
991 KdPrint2((PRINT_PREFIX
"busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n"));
995 KdPrint2((PRINT_PREFIX
"busDataRead\n"));
996 if (pciData
.VendorID
== PCI_INVALID_VENDORID
) {
997 KdPrint2((PRINT_PREFIX
"PCI_INVALID_VENDORID\n"));
1000 #endif //UNIATA_CORE
1002 VendorID
= pciData
.VendorID
;
1003 DeviceID
= pciData
.DeviceID
;
1004 BaseClass
= pciData
.BaseClass
;
1005 SubClass
= pciData
.SubClass
;
1006 RevID
= pciData
.RevisionID
;
1007 dev_id
= VendorID
| (DeviceID
<< 16);
1008 slotData
.u
.AsULONG
= slotNumber
;
1009 KdPrint2((PRINT_PREFIX
"DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id
, BaseClass
, SubClass
));
1011 deviceExtension
->slotNumber
= slotNumber
;
1012 deviceExtension
->SystemIoBusNumber
= SystemIoBusNumber
;
1013 deviceExtension
->DevID
= dev_id
;
1014 deviceExtension
->RevID
= RevID
;
1015 deviceExtension
->NumberChannels
= 2; // default
1016 deviceExtension
->DevIndex
= i
;
1018 _snprintf(deviceExtension
->Signature
, sizeof(deviceExtension
->Signature
),
1019 "UATA%8.8x/%1.1x@%8.8x", dev_id
, channel
, slotNumber
);
1021 if(BaseClass
!= PCI_DEV_CLASS_STORAGE
) {
1022 KdPrint2((PRINT_PREFIX
"BaseClass != PCI_DEV_CLASS_STORAGE => SP_RETURN_NOT_FOUND\n"));
1026 KdPrint2((PRINT_PREFIX
"Storage Class\n"));
1028 // look for known chipsets
1029 if(VendorID
!= BMList
[i
].nVendorId
||
1030 DeviceID
!= BMList
[i
].nDeviceId
) {
1031 KdPrint2((PRINT_PREFIX
"device not suitable\n"));
1035 found
= UniataCheckPCISubclass(BMList
[i
].Known
, BMList
[i
].RaidFlags
, SubClass
);
1037 KdPrint2((PRINT_PREFIX
"Subclass not supported\n"));
1041 ConfigInfo
->AlignmentMask
= 0x00000003;
1043 MasterDev
= IsMasterDev(&pciData
);
1046 KdPrint2((PRINT_PREFIX
"MasterDev (1)\n"));
1047 deviceExtension
->NumberChannels
= 1;
1050 found
= UniataChipDetect(HwDeviceExtension
, &pciData
, i
, ConfigInfo
, &simplexOnly
);
1051 KdPrint2((PRINT_PREFIX
"ForceSimplex = %d\n", simplexOnly
));
1052 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (0)", deviceExtension
->HwFlags
));
1054 /* additional checks for some supported chipsets */
1056 if (SubClass
!= PCI_DEV_SUBCLASS_IDE
) {
1057 KdPrint2((PRINT_PREFIX
"0xc6931080, SubClass != PCI_DEV_SUBCLASS_IDE => found = FALSE\n"));
1064 /* unknown chipsets, try generic DMA if it seems possible */
1068 KdPrint2((PRINT_PREFIX
"Default device\n"));
1069 if(!Ata_is_supported_dev(&pciData
)) {
1070 KdPrint2((PRINT_PREFIX
"!Ata_is_supported_dev => found = FALSE\n"));
1073 KdPrint2((PRINT_PREFIX
"Ata_is_supported_dev\n"));
1076 deviceExtension
->UnknownDev
= TRUE
;
1080 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (1)", deviceExtension
->HwFlags
));
1082 KdPrint2((PRINT_PREFIX
"!found => SP_RETURN_NOT_FOUND\n"));
1086 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (2)", deviceExtension
->HwFlags
));
1087 KdPrint2((PRINT_PREFIX
"found suitable device\n"));
1089 /***********************************************************/
1090 /***********************************************************/
1091 /***********************************************************/
1093 deviceExtension
->UseDpc
= TRUE
;
1094 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (3)", deviceExtension
->HwFlags
));
1095 if(deviceExtension
->HwFlags
& UNIATA_NO_DPC
) {
1096 /* CMD 649, ROSB SWK33, ICH4 */
1097 KdPrint2((PRINT_PREFIX
"UniataFindBusMasterController: UNIATA_NO_DPC (0)\n"));
1098 deviceExtension
->UseDpc
= FALSE
;
1102 if((WinVer_Id() <= WinVer_NT
) && AltInit
&& FirstMasterOk
) {
1103 // this is the 2nd attempt to init this controller by OUR driver
1104 KdPrint2((PRINT_PREFIX
"Skip primary/secondary claiming checks\n"));
1106 if((channel
==0) && ConfigInfo
->AtdiskPrimaryClaimed
) {
1107 KdPrint2((PRINT_PREFIX
"Error: Primary channel already claimed by another driver\n"));
1110 if((channel
==1) && ConfigInfo
->AtdiskSecondaryClaimed
) {
1111 KdPrint2((PRINT_PREFIX
"Error: Secondary channel already claimed by another driver\n"));
1116 if(deviceExtension
->AltRegMap
) {
1117 KdPrint2((PRINT_PREFIX
" Non-standard registers layout\n"));
1118 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
1119 KdPrint2((PRINT_PREFIX
"UNIATA_SATA -> IsBusMaster == TRUE\n"));
1120 deviceExtension
->BusMaster
= TRUE
;
1123 deviceExtension
->BusMaster
= FALSE
;
1125 if(WinVer_WDM_Model
&& !deviceExtension
->UnknownDev
) {
1127 // Enable Busmastering, IO-space and Mem-space
1128 KdPrint2((PRINT_PREFIX
"Enabling Mem/Io spaces and busmastering...\n"));
1129 KdPrint2((PRINT_PREFIX
"Initial pciData.Command = %#x\n", pciData
.Command
));
1130 for(i
=0; i
<3; i
++) {
1133 KdPrint2((PRINT_PREFIX
"PCI_ENABLE_IO_SPACE\n"));
1134 pciData
.Command
|= PCI_ENABLE_IO_SPACE
;
1137 KdPrint2((PRINT_PREFIX
"PCI_ENABLE_MEMORY_SPACE\n"));
1138 pciData
.Command
|= PCI_ENABLE_MEMORY_SPACE
;
1141 KdPrint2((PRINT_PREFIX
"PCI_ENABLE_BUS_MASTER\n"));
1142 pciData
.Command
|= PCI_ENABLE_BUS_MASTER
;
1145 HalSetBusDataByOffset( PCIConfiguration
, SystemIoBusNumber
, slotData
.u
.AsULONG
,
1147 offsetof(PCI_COMMON_CONFIG
, Command
),
1148 sizeof(pciData
.Command
));
1149 KdPrint2((PRINT_PREFIX
"InterruptLine = %#x\n", pciData
.u
.type0
.InterruptLine
));
1151 // reread config space
1152 busDataRead
= HalGetBusData(PCIConfiguration
, SystemIoBusNumber
, slotData
.u
.AsULONG
,
1153 &pciData
, PCI_COMMON_HDR_LENGTH
);
1154 KdPrint2((PRINT_PREFIX
"New pciData.Command = %#x\n", pciData
.Command
));
1156 KdPrint2((PRINT_PREFIX
"Final pciData.Command = %#x\n", pciData
.Command
));
1158 // validate Mem/Io ranges
1162 for(i
=0; i
<PCI_TYPE0_ADDRESSES
; i
++) {
1163 if(pciData
.u
.type0
.BaseAddresses
[i
] & ~0x7) {
1164 //no_ranges = FALSE;
1166 KdPrint2((PRINT_PREFIX
"Range %d = %#x\n", i
, pciData
.u
.type0
.BaseAddresses
[i
]));
1171 if(IsBusMaster(&pciData
)) {
1173 KdPrint2((PRINT_PREFIX
"IsBusMaster == TRUE\n"));
1174 BaseIoAddressBM_0
= (PIDE_BUSMASTER_REGISTERS
)
1175 (AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, &pciData
, SystemIoBusNumber
,
1176 4, bm_offset
, MasterDev
? 0x08 : 0x10/*ATA_BMIOSIZE*/)/* - bm_offset*/); //range id
1177 if(BaseIoAddressBM_0
) {
1178 UniataInitMapBM(deviceExtension
,
1180 (*ConfigInfo
->AccessRanges
)[4].RangeInMemory
? TRUE
: FALSE
);
1181 deviceExtension
->BusMaster
= TRUE
;
1182 deviceExtension
->BaseIoAddressBM_0
.Addr
= (ULONG_PTR
)BaseIoAddressBM_0
;
1183 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
1184 deviceExtension
->BaseIoAddressBM_0
.MemIo
= TRUE
;
1187 KdPrint2((PRINT_PREFIX
" BusMasterAddress (base): %#x\n", BaseIoAddressBM_0
));
1190 if(!deviceExtension
->BusMaster
) {
1191 KdPrint2((PRINT_PREFIX
" !BusMasterAddress -> PIO4\n"));
1192 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
1195 if(deviceExtension
->BusMaster
&& !MasterDev
) {
1196 KdPrint2((PRINT_PREFIX
"IsBusMaster == TRUE && !MasterDev\n"));
1197 statusByte
= AtapiReadPort1(&(deviceExtension
->chan
[0]), IDX_BM_Status
);
1198 KdPrint2((PRINT_PREFIX
" statusByte = %x\n", statusByte
));
1199 if(statusByte
== 0xff) {
1200 KdPrint2((PRINT_PREFIX
" invalid port ?\n"));
1202 if(BaseIoAddressBM_0) {
1203 ScsiPortFreeDeviceBase(HwDeviceExtension,
1205 BaseIoAddressBM_0 = NULL;
1209 if(statusByte
& BM_STATUS_SIMPLEX_ONLY
) {
1210 KdPrint2((PRINT_PREFIX
" BM_STATUS => simplexOnly\n"));
1217 * the Cypress chip is a mess, it contains two ATA functions, but
1218 * both channels are visible on the first one.
1219 * simply ignore the second function for now, as the right
1220 * solution (ignoring the second channel on the first function)
1221 * doesn't work with the crappy ATA interrupt setup on the alpha.
1223 if (dev_id
== 0xc6931080 && slotData
.u
.bits
.FunctionNumber
> 1) {
1224 KdPrint2((PRINT_PREFIX
"dev_id == 0xc6931080 && FunctionNumber > 1 => exit_findbm\n"));
1228 /* do extra chipset specific setups */
1229 AtapiReadChipConfig(HwDeviceExtension
, i
, CHAN_NOT_SPECIFIED
);
1230 AtapiChipInit(HwDeviceExtension
, i
, CHAN_NOT_SPECIFIED_CHECK_CABLE
);
1232 simplexOnly
|= deviceExtension
->simplexOnly
;
1233 deviceExtension
->simplexOnly
|= simplexOnly
;
1235 KdPrint2((PRINT_PREFIX
"simplexOnly = %d (2)", simplexOnly
));
1237 //TODO: fix hang with UseDpn=TRUE in Simplex mode
1238 //deviceExtension->UseDpc = TRUE;
1240 KdPrint2((PRINT_PREFIX
"simplexOnly => UseDpc = FALSE\n"));
1241 deviceExtension
->UseDpc
= FALSE
;
1244 if(simplexOnly
&& MasterDev
/*|| (WinVer_Id() > WinVer_NT)*/) {
1245 if(deviceExtension
->NumberChannels
< 2) {
1246 KdPrint2((PRINT_PREFIX
"set NumberChannels = 2\n"));
1247 deviceExtension
->NumberChannels
= 2;
1248 if(BaseIoAddressBM_0
) {
1249 UniataInitMapBM(deviceExtension
,
1251 (*ConfigInfo
->AccessRanges
)[4].RangeInMemory
? TRUE
: FALSE
);
1256 (deviceExtension
->NumberChannels
> 1)) {
1257 KdPrint2((PRINT_PREFIX
"Error: channel > 0 && NumberChannels > 1\n"));
1261 // Indicate number of buses.
1262 ConfigInfo
->NumberOfBuses
= (UCHAR
)(deviceExtension
->NumberChannels
);
1263 if(!ConfigInfo
->InitiatorBusId
[0]) {
1264 ConfigInfo
->InitiatorBusId
[0] = (CHAR
)(IoGetConfigurationInformation()->ScsiPortCount
);
1265 KdPrint2((PRINT_PREFIX
"set ConfigInfo->InitiatorBusId[0] = %#x\n", ConfigInfo
->InitiatorBusId
[0]));
1267 // Indicate four devices can be attached to the adapter
1268 ConfigInfo
->MaximumNumberOfTargets
= (UCHAR
)(/*deviceExtension->NumberChannels **/ 2);
1271 KdPrint2((PRINT_PREFIX
"MasterDev (2)\n"));
1273 if((WinVer_Id() > WinVer_NT) ||
1274 (deviceExtension->NumberChannels > 1)) {
1276 KdPrint2((PRINT_PREFIX "2 channels & 2 irq for 1 controller Win 2000+\n"));
1278 if (ConfigInfo->AdapterInterfaceType == MicroChannel) {
1279 ConfigInfo->InterruptMode2 =
1280 ConfigInfo->InterruptMode = LevelSensitive;
1282 ConfigInfo->InterruptMode2 =
1283 ConfigInfo->InterruptMode = Latched;
1285 ConfigInfo->BusInterruptLevel = 14;
1286 ConfigInfo->BusInterruptLevel2 = 15;
1290 KdPrint2((PRINT_PREFIX
"2 channels & 2 irq for 1 controller\n"));
1292 if (ConfigInfo
->AdapterInterfaceType
== MicroChannel
) {
1293 ConfigInfo
->InterruptMode2
=
1294 ConfigInfo
->InterruptMode
= LevelSensitive
;
1296 ConfigInfo
->InterruptMode2
=
1297 ConfigInfo
->InterruptMode
= Latched
;
1299 ConfigInfo
->BusInterruptLevel
= 14;
1300 ConfigInfo
->BusInterruptLevel2
= 15;
1302 KdPrint2((PRINT_PREFIX
"1 channels & 1 irq for 1 controller\n"));
1303 if (ConfigInfo
->AdapterInterfaceType
== MicroChannel
) {
1304 ConfigInfo
->InterruptMode
= LevelSensitive
;
1306 ConfigInfo
->InterruptMode
= Latched
;
1308 ConfigInfo
->BusInterruptLevel
= (channel
== 0 ? 14 : 15);
1311 KdPrint2((PRINT_PREFIX
"!MasterDev\n"));
1312 ConfigInfo
->SlotNumber
= slotNumber
;
1313 ConfigInfo
->SystemIoBusNumber
= SystemIoBusNumber
;
1315 /* primary and secondary channels share the same interrupt */
1316 if(!ConfigInfo
->BusInterruptVector
||
1317 (ConfigInfo
->BusInterruptVector
!= pciData
.u
.type0
.InterruptLine
)) {
1318 KdPrint2((PRINT_PREFIX
"patch irq line = %#x\n", pciData
.u
.type0
.InterruptLine
));
1319 ConfigInfo
->BusInterruptVector
= pciData
.u
.type0
.InterruptLine
; // set default value
1320 if(!ConfigInfo
->BusInterruptVector
) {
1321 KdPrint2((PRINT_PREFIX
"patch irq line (2) = 10\n"));
1322 ConfigInfo
->BusInterruptVector
= 10;
1326 ConfigInfo
->MultipleRequestPerLu
= TRUE
;
1327 ConfigInfo
->AutoRequestSense
= TRUE
;
1328 ConfigInfo
->TaggedQueuing
= TRUE
;
1330 if((WinVer_Id() >= WinVer_NT
) ||
1331 (ConfigInfo
->Length
>= sizeof(_ConfigInfo
->comm
) + sizeof(_ConfigInfo
->nt4
))) {
1332 KdPrint2((PRINT_PREFIX
"update ConfigInfo->nt4\n"));
1333 _ConfigInfo
->nt4
.DeviceExtensionSize
= sizeof(HW_DEVICE_EXTENSION
);
1334 _ConfigInfo
->nt4
.SpecificLuExtensionSize
= sizeof(HW_LU_EXTENSION
);
1335 _ConfigInfo
->nt4
.SrbExtensionSize
= sizeof(ATA_REQ
);
1337 if((WinVer_Id() > WinVer_2k
) ||
1338 (ConfigInfo
->Length
>= sizeof(_ConfigInfo
->comm
) + sizeof(_ConfigInfo
->nt4
) + sizeof(_ConfigInfo
->w2k
))) {
1339 KdPrint2((PRINT_PREFIX
"update ConfigInfo->w2k\n"));
1340 _ConfigInfo
->w2k
.Dma64BitAddresses
= 0;
1341 _ConfigInfo
->w2k
.ResetTargetSupported
= TRUE
;
1342 _ConfigInfo
->w2k
.MaximumNumberOfLogicalUnits
= 2;
1345 // Save the Interrupe Mode for later use
1346 deviceExtension
->InterruptMode
= ConfigInfo
->InterruptMode
;
1347 deviceExtension
->BusInterruptLevel
= ConfigInfo
->BusInterruptLevel
;
1348 deviceExtension
->BusInterruptVector
= ConfigInfo
->BusInterruptVector
;
1349 deviceExtension
->Channel
= channel
;
1350 deviceExtension
->DevIndex
= i
;
1351 deviceExtension
->OrigAdapterInterfaceType
1352 = ConfigInfo
->AdapterInterfaceType
;
1353 deviceExtension
->AlignmentMask
= ConfigInfo
->AlignmentMask
;
1354 deviceExtension
->AdapterInterfaceType
= PCIBus
;
1358 if(deviceExtension
->BusMaster
) {
1360 KdPrint2((PRINT_PREFIX
"Reconstruct ConfigInfo\n"));
1361 ConfigInfo
->MapBuffers
= TRUE
;
1363 ConfigInfo
->NeedPhysicalAddresses
= FALSE
;
1365 ConfigInfo
->NeedPhysicalAddresses
= TRUE
;
1366 #endif //USE_OWN_DMA
1368 KdPrint2((PRINT_PREFIX
"set Dma32BitAddresses\n"));
1369 ConfigInfo
->Dma32BitAddresses
= TRUE
;
1372 // thanks to Vitaliy Vorobyov aka deathsoft@yandex.ru for
1376 // I'm sorry, I have to do this
1379 if(ConfigInfo
->AdapterInterfaceType
== Isa
/*&&
1380 // InDriverEntry*/) {
1381 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType Isa => PCIBus\n"));
1382 ConfigInfo
->AdapterInterfaceType
= PCIBus
;
1384 if(ConfigInfo
->AdapterInterfaceType
== PCIBus
/*&&
1385 // InDriverEntry*/) {
1386 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType PCIBus, update address\n"));
1387 ConfigInfo
->SlotNumber
= slotNumber
;
1388 ConfigInfo
->SystemIoBusNumber
= SystemIoBusNumber
;
1393 ConfigInfo
->Master
= TRUE
;
1394 ConfigInfo
->DmaWidth
= Width16Bits
;
1395 #endif //USE_OWN_DMA
1396 ConfigInfo
->CachesData
= TRUE
;
1397 ConfigInfo
->ScatterGather
= TRUE
;
1400 // Note: now we can support only 4 channels !!!
1401 // in order to add support for multichannel controllers we must rewrite
1402 // io-range claiming algorithm
1404 KdPrint2((PRINT_PREFIX
"BMList[i].channel %#x, NumberChannels %#x, channel %#x\n",BMList
[i
].channel
, deviceExtension
->NumberChannels
, channel
));
1406 for (; channel
< (BMList
[i
].channel
+ deviceExtension
->NumberChannels
); channel
++, c
++) {
1408 KdPrint2((PRINT_PREFIX
"de %#x, Channel %#x\n",deviceExtension
, channel
));
1409 //PrintNtConsole("de %#x, Channel %#x, nchan %#x\n",deviceExtension, channel, deviceExtension->NumberChannels);
1410 chan
= &deviceExtension
->chan
[c
];
1412 KdPrint2((PRINT_PREFIX
"chan = %#x\n", chan
));
1413 //PrintNtConsole("chan = %#x, c=%#x\n", chan, c);
1414 AtapiSetupLunPtrs(chan
, deviceExtension
, c
);
1416 /* do extra channel-specific setups */
1417 AtapiReadChipConfig(HwDeviceExtension
, i
, channel
);
1418 //AtapiChipInit(HwDeviceExtension, i, channel);
1419 if(deviceExtension
->AltRegMap
) {
1420 KdPrint2((PRINT_PREFIX
" Non-standard registers layout\n"));
1422 // Check if the range specified is not used by another driver
1424 KdPrint2((PRINT_PREFIX
"set AccessRanges\n"));
1425 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 0].RangeStart
=
1426 ScsiPortConvertUlongToPhysicalAddress(channel
? IO_WD2
: IO_WD1
);
1427 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 0].RangeLength
= ATA_IOSIZE
;
1429 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 1].RangeStart
=
1430 ScsiPortConvertUlongToPhysicalAddress((channel
? IO_WD2
: IO_WD1
) + ATA_ALTOFFSET
);
1431 (*ConfigInfo
->AccessRanges
)[channel
* 2 + 1].RangeLength
= ATA_ALTIOSIZE
;
1433 // do not claim 2nd BM io-range for Secondary channel of
1434 // Compatible-mode controllers
1435 if(/*(WinVer_Id() <= WinVer_NT) &&*/ !c
&& channel
== 1) {
1436 KdPrint2((PRINT_PREFIX
"cheat ScsiPort for 2nd channel, BM io-range\n"));
1437 (*ConfigInfo
->AccessRanges
)[4].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(0);
1438 (*ConfigInfo
->AccessRanges
)[4].RangeLength
= 0;
1442 IoBasePort1
= (*ConfigInfo
->AccessRanges
)[channel
* 2 + 0].RangeStart
;
1443 IoBasePort2
= (*ConfigInfo
->AccessRanges
)[channel
* 2 + 1].RangeStart
;
1446 if(!IoBasePort1
.QuadPart
|| !IoBasePort2
.QuadPart
) {
1447 KdPrint2((PRINT_PREFIX
"ScsiPortValidateRange failed (1)\n"));
1452 if(!ScsiPortValidateRange(HwDeviceExtension
,
1453 PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
1454 SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
1458 KdPrint2((PRINT_PREFIX
"ScsiPortValidateRange failed (1)\n"));
1462 if(!ScsiPortValidateRange(HwDeviceExtension
,
1463 PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
1464 SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
1468 KdPrint2((PRINT_PREFIX
"ScsiPortValidateRange failed (2)\n"));
1472 KdPrint2((PRINT_PREFIX
"Getting IO ranges\n"));
1474 // Ok, translate adresses to io-space
1475 if(ScsiPortConvertPhysicalAddressToUlong(IoBasePort2
)) {
1476 if(!(MasterDev
/* || USE_16_BIT */)) {
1477 KdPrint2((PRINT_PREFIX
"!MasterDev mode\n"));
1478 IoBasePort2
= ScsiPortConvertUlongToPhysicalAddress(
1479 ScsiPortConvertPhysicalAddressToUlong(IoBasePort2
) + 2);
1482 KdPrint2((PRINT_PREFIX
"use relative IoBasePort2\n"));
1483 IoBasePort2
= ScsiPortConvertUlongToPhysicalAddress(
1484 ScsiPortConvertPhysicalAddressToUlong(IoBasePort1
) + ATA_PCCARD_ALTOFFSET
);
1487 // Get the system physical address for this IO range.
1488 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
1489 PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
1490 SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
1494 KdPrint2((PRINT_PREFIX
"IO range 1 %#x\n",ioSpace
));
1496 // Check if ioSpace accessible.
1498 KdPrint2((PRINT_PREFIX
"!ioSpace\n"));
1502 if(deviceExtension->BusMaster) {
1503 KdPrint2((PRINT_PREFIX "set BusMaster io-range in DO\n"));
1504 // bm_offset already includes (channel ? ATA_BM_OFFSET1 : 0)
1505 deviceExtension->BaseIoAddressBM[c] = (PIDE_BUSMASTER_REGISTERS)
1506 ((ULONG)(deviceExtension->BaseIoAddressBM_0) + bm_offset + (c ? ATA_BM_OFFSET1 : 0));
1509 //deviceExtension->BaseIoAddress1[c] = (PIDE_REGISTERS_1)(ioSpace);
1510 BaseIoAddress1
[c
] = (PIDE_REGISTERS_1
)(ioSpace
);
1512 // Get the system physical address for the second IO range.
1513 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
1514 PCIBus
/*ConfigInfo->AdapterInterfaceType*/,
1515 SystemIoBusNumber
/*ConfigInfo->SystemIoBusNumber*/,
1519 KdPrint2((PRINT_PREFIX
"IO range 2 %#x\n",ioSpace
));
1521 BaseIoAddress2
[c
] = (PIDE_REGISTERS_2
)(ioSpace
);
1523 // Release all allocated resources
1524 KdPrint2((PRINT_PREFIX
"!deviceExtension->BaseIoAddress2\n"));
1525 //ioSpace = (PUCHAR)BaseIoAddress1[c];
1526 // goto free_iospace_1;
1530 UniataInitMapBase(chan
, BaseIoAddress1
[c
], BaseIoAddress2
[c
]);
1532 //ioSpace = (PUCHAR)(deviceExtension->BaseIoAddress1[c]);
1534 KdPrint2((PRINT_PREFIX
"IDX_IO1 %x->%x(%s)\n",
1536 chan
->RegTranslation
[IDX_IO1
].Addr
,
1537 chan
->RegTranslation
[IDX_IO1
].MemIo
? "mem" : "io"));
1539 KdPrint2((PRINT_PREFIX
"IDX_IO2 %x->%x(%s)\n",
1541 chan
->RegTranslation
[IDX_IO2
].Addr
,
1542 chan
->RegTranslation
[IDX_IO2
].MemIo
? "mem" : "io"));
1544 KdPrint2((PRINT_PREFIX
"IDX_BM_IO %x->%x(%s)\n",
1546 chan
->RegTranslation
[IDX_BM_IO
].Addr
,
1547 chan
->RegTranslation
[IDX_BM_IO
].MemIo
? "mem" : "io"));
1549 KdPrint2((PRINT_PREFIX
"IDX_SATA_IO %x->%x(%s)\n",
1551 chan
->RegTranslation
[IDX_SATA_IO
].Addr
,
1552 chan
->RegTranslation
[IDX_SATA_IO
].MemIo
? "mem" : "io"));
1554 UniataDumpATARegs(chan
);
1557 #ifdef UNIATA_INIT_ON_PROBE
1558 // if(deviceExtension->HwFlags & UNIATA_SATA) {
1559 //#endif //UNIATA_INIT_ON_PROBE
1560 KdPrint2((PRINT_PREFIX
"Check drive 0\n"));
1562 SelectDrive(chan
, 0);
1563 AtapiStallExecution(10);
1564 GetBaseStatus(chan
, statusByte
);
1565 skip_find_dev
= FALSE
;
1566 if(!(deviceExtension
->HwFlags
& UNIATA_NO_SLAVE
)) {
1567 if ((statusByte
& 0xf8) == 0xf8 ||
1568 (statusByte
== 0xa5)) {
1570 KdPrint2((PRINT_PREFIX
"Check drive 1\n"));
1571 SelectDrive(chan
, 1);
1572 AtapiStallExecution(1);
1573 GetBaseStatus(chan
, statusByte
);
1574 if ((statusByte
& 0xf8) == 0xf8 ||
1575 (statusByte
== 0xa5)) {
1576 // No controller at this base address.
1577 KdPrint2((PRINT_PREFIX
"Empty channel\n"));
1578 skip_find_dev
= TRUE
;
1583 // Search for devices on this controller.
1584 if (!skip_find_dev
&&
1585 FindDevices(HwDeviceExtension
,
1588 KdPrint2((PRINT_PREFIX
"Found some devices\n"));
1591 KdPrint2((PRINT_PREFIX
"no devices\n"));
1592 /* KeBugCheckEx(0xc000000e,
1593 ScsiPortConvertPhysicalAddressToUlong(IoBasePort1),
1594 ScsiPortConvertPhysicalAddressToUlong(IoBasePort2),
1595 (ULONG)(deviceExtension->BaseIoAddressBM[c]), skip_find_dev);*/
1597 //#ifdef UNIATA_INIT_ON_PROBE
1599 #endif //UNIATA_INIT_ON_PROBE
1602 chan
->PrimaryAddress
= FALSE
;
1603 // Claim primary or secondary ATA IO range.
1605 KdPrint2((PRINT_PREFIX
"claim Compatible controller\n"));
1607 KdPrint2((PRINT_PREFIX
"claim Primary\n"));
1608 ConfigInfo
->AtdiskPrimaryClaimed
= TRUE
;
1609 chan
->PrimaryAddress
= TRUE
;
1611 FirstMasterOk
= TRUE
;
1615 KdPrint2((PRINT_PREFIX
"claim Secondary\n"));
1616 ConfigInfo
->AtdiskSecondaryClaimed
= TRUE
;
1618 FirstMasterOk
= TRUE
;
1622 AtapiDmaAlloc(HwDeviceExtension
, ConfigInfo
, c
);
1625 #endif //UNIATA_CORE
1626 } // end for(channel)
1632 KdPrint2((PRINT_PREFIX
"exit: !found\n"));
1633 if(BaseIoAddress1
[0])
1634 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1636 if(BaseIoAddress2
[0])
1637 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1640 if(BaseIoAddress1
[1])
1641 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1643 if(BaseIoAddress2
[1])
1644 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1647 if(BaseIoAddressBM_0
)
1648 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1651 KdPrint2((PRINT_PREFIX
"return SP_RETURN_NOT_FOUND\n"));
1655 KdPrint2((PRINT_PREFIX
"exit: init spinlock\n"));
1656 //KeInitializeSpinLock(&(deviceExtension->DpcSpinLock));
1657 deviceExtension
->ActiveDpcChan
=
1658 deviceExtension
->FirstDpcChan
= -1;
1660 BMList
[i
].Isr2Enable
= FALSE
;
1662 KdPrint2((PRINT_PREFIX
"MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n",
1663 MasterDev
, deviceExtension
->NumberChannels
, BMList
[i
].Isr2DevObj
));
1665 // ConnectIntr2 should be moved to HwInitialize
1666 status
= UniataConnectIntr2(HwDeviceExtension
);
1668 KdPrint2((PRINT_PREFIX
"MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n",
1669 MasterDev
, deviceExtension
->NumberChannels
, BMList
[i
].Isr2DevObj
));
1671 if(WinVer_WDM_Model
&& MasterDev
) {
1672 KdPrint2((PRINT_PREFIX
"do not tell system, that we know about this:\n"));
1673 if(BaseIoAddressBM_0
) {
1674 ScsiPortFreeDeviceBase(HwDeviceExtension
,
1677 (*ConfigInfo
->AccessRanges
)[4].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(0);
1678 (*ConfigInfo
->AccessRanges
)[4].RangeLength
= 0;
1679 (*ConfigInfo
->AccessRanges
)[5].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(0);
1680 (*ConfigInfo
->AccessRanges
)[5].RangeLength
= 0;
1683 if(!NT_SUCCESS(status
)) {
1684 KdPrint2((PRINT_PREFIX
"failed\n"));
1689 #endif //UNIATA_CORE
1691 KdPrint2((PRINT_PREFIX
"return SP_RETURN_FOUND\n"));
1692 //PrintNtConsole("return SP_RETURN_FOUND, de %#x, c0.lun0 %#x\n", deviceExtension, deviceExtension->chan[0].lun[0]);
1695 KdPrint2((PRINT_PREFIX
"Attempt %d of MasterDev ok\n", AltInit
));
1696 FirstMasterOk
= TRUE
;
1699 ConfigInfo
->NumberOfBuses
++; // add virtual channel for communication port
1700 return SP_RETURN_FOUND
;
1703 if (deviceExtension
->lun
) ExFreePool(deviceExtension
->lun
);
1704 if (deviceExtension
->chan
) ExFreePool(deviceExtension
->chan
);
1705 return SP_RETURN_ERROR
;
1708 ExFreePool(deviceExtension
->lun
);
1709 ExFreePool(deviceExtension
->chan
);
1710 return SP_RETURN_NOT_FOUND
;
1712 } // end UniataFindBusMasterController()
1717 This is for claiming PCI Busmaster in compatible mode under WDM OSes
1721 UniataFindFakeBusMasterController(
1722 IN PVOID HwDeviceExtension
,
1724 IN PVOID BusInformation
,
1725 IN PCHAR ArgumentString
,
1726 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1730 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1731 //PHW_CHANNEL chan = NULL;
1732 // this buffer must be global for UNIATA_CORE build
1733 PCI_COMMON_CONFIG pciData
;
1737 ULONG SystemIoBusNumber
;
1739 UCHAR vendorString
[5];
1740 UCHAR deviceString
[5];
1741 PUCHAR vendorStrPtr
;
1742 PUCHAR deviceStrPtr
;
1750 PCI_SLOT_NUMBER slotData
;
1754 // UCHAR statusByte;
1759 BOOLEAN found
= FALSE
;
1761 BOOLEAN simplexOnly
= FALSE
;
1762 //BOOLEAN skip_find_dev = FALSE;
1763 //BOOLEAN AltInit = FALSE;
1765 PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0
= NULL
;
1768 PPORT_CONFIGURATION_INFORMATION_COMMON _ConfigInfo
=
1769 (PPORT_CONFIGURATION_INFORMATION_COMMON
)ConfigInfo
;
1774 i
= (ULONG_PTR
)Context
;
1776 for(i
=0; i
<BMListLen
; i
++) {
1777 if(BMList
[i
].slotNumber
== ConfigInfo
->SlotNumber
&&
1778 BMList
[i
].busNumber
== ConfigInfo
->SystemIoBusNumber
) {
1782 if(i
>= BMListLen
) {
1783 KdPrint2((PRINT_PREFIX
"unexpected device arrival => SP_RETURN_NOT_FOUND\n"));
1788 KdPrint2((PRINT_PREFIX
"UniataFindFakeBusMasterController (WDM)\n"));
1790 if (!deviceExtension
) {
1791 KdPrint2((PRINT_PREFIX
"!deviceExtension => SP_RETURN_ERROR\n"));
1792 return SP_RETURN_ERROR
;
1795 RtlZeroMemory(deviceExtension
, sizeof(HW_DEVICE_EXTENSION
));
1797 vendorStrPtr
= vendorString
;
1798 deviceStrPtr
= deviceString
;
1800 slotNumber
= BMList
[i
].slotNumber
;
1801 SystemIoBusNumber
= BMList
[i
].busNumber
;
1803 KdPrint2((PRINT_PREFIX
"AdapterInterfaceType=%#x\n",ConfigInfo
->AdapterInterfaceType
));
1804 KdPrint2((PRINT_PREFIX
"IoBusNumber=%#x\n",ConfigInfo
->SystemIoBusNumber
));
1805 KdPrint2((PRINT_PREFIX
"slotNumber=%#x\n",slotNumber
));
1807 // this buffer must be global and already filled for UNIATA_CORE build
1808 busDataRead
= HalGetBusData(
1809 //busDataRead = ScsiPortGetBusData(HwDeviceExtension,
1814 PCI_COMMON_HDR_LENGTH
);
1816 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1817 KdPrint2((PRINT_PREFIX
"busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n"));
1821 KdPrint2((PRINT_PREFIX
"busDataRead\n"));
1822 if (pciData
.VendorID
== PCI_INVALID_VENDORID
) {
1823 KdPrint2((PRINT_PREFIX
"PCI_INVALID_VENDORID\n"));
1827 VendorID
= pciData
.VendorID
;
1828 DeviceID
= pciData
.DeviceID
;
1829 BaseClass
= pciData
.BaseClass
;
1830 SubClass
= pciData
.SubClass
;
1831 RevID
= pciData
.RevisionID
;
1832 dev_id
= VendorID
| (DeviceID
<< 16);
1833 slotData
.u
.AsULONG
= slotNumber
;
1834 KdPrint2((PRINT_PREFIX
"DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id
, BaseClass
, SubClass
));
1836 deviceExtension
->slotNumber
= slotNumber
;
1837 deviceExtension
->SystemIoBusNumber
= SystemIoBusNumber
;
1838 deviceExtension
->DevID
= dev_id
;
1839 deviceExtension
->RevID
= RevID
;
1840 deviceExtension
->NumberChannels
= 2; // default
1841 deviceExtension
->DevIndex
= i
;
1843 _snprintf(deviceExtension
->Signature
, sizeof(deviceExtension
->Signature
),
1844 "UATA%8.8x/%1.1x@%8.8x", dev_id
, 0xff, slotNumber
);
1846 if(BaseClass
!= PCI_DEV_CLASS_STORAGE
) {
1847 KdPrint2((PRINT_PREFIX
"BaseClass != PCI_DEV_CLASS_STORAGE => SP_RETURN_NOT_FOUND\n"));
1851 KdPrint2((PRINT_PREFIX
"Storage Class\n"));
1853 // look for known chipsets
1854 if(VendorID
!= BMList
[i
].nVendorId
||
1855 DeviceID
!= BMList
[i
].nDeviceId
) {
1856 KdPrint2((PRINT_PREFIX
"device not suitable\n"));
1860 if((BMList
[i
].RaidFlags
& UNIATA_RAID_CONTROLLER
) &&
1862 KdPrint2((PRINT_PREFIX
"RAID support disabled\n"));
1867 case PCI_DEV_SUBCLASS_IDE
:
1868 case PCI_DEV_SUBCLASS_RAID
:
1869 case PCI_DEV_SUBCLASS_ATA
:
1870 case PCI_DEV_SUBCLASS_SATA
:
1874 KdPrint2((PRINT_PREFIX
"Subclass not supported\n"));
1878 ConfigInfo
->AlignmentMask
= 0x00000003;
1880 found
= UniataChipDetect(HwDeviceExtension
, &pciData
, i
, ConfigInfo
, &simplexOnly
);
1881 KdPrint2((PRINT_PREFIX
"ForceSimplex = %d\n", simplexOnly
));
1882 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (0)", deviceExtension
->HwFlags
));
1884 /* additional checks for some supported chipsets */
1886 if (SubClass
!= PCI_DEV_SUBCLASS_IDE
) {
1887 KdPrint2((PRINT_PREFIX
"0xc6931080, SubClass != PCI_DEV_SUBCLASS_IDE => found = FALSE\n"));
1894 /* unknown chipsets, try generic DMA if it seems possible */
1898 KdPrint2((PRINT_PREFIX
"Default device\n"));
1899 if(!Ata_is_supported_dev(&pciData
)) {
1900 KdPrint2((PRINT_PREFIX
"!Ata_is_supported_dev => found = FALSE\n"));
1903 KdPrint2((PRINT_PREFIX
"Ata_is_supported_dev\n"));
1906 deviceExtension
->UnknownDev
= TRUE
;
1910 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (1)", deviceExtension
->HwFlags
));
1912 KdPrint2((PRINT_PREFIX
"!found => SP_RETURN_NOT_FOUND\n"));
1916 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (2)", deviceExtension
->HwFlags
));
1917 KdPrint2((PRINT_PREFIX
"found suitable device\n"));
1919 /***********************************************************/
1920 /***********************************************************/
1921 /***********************************************************/
1923 deviceExtension
->UseDpc
= TRUE
;
1924 KdPrint2((PRINT_PREFIX
"HwFlags = %x\n (3)", deviceExtension
->HwFlags
));
1925 if(deviceExtension
->HwFlags
& UNIATA_NO_DPC
) {
1926 /* CMD 649, ROSB SWK33, ICH4 */
1927 KdPrint2((PRINT_PREFIX
"UniataFindBusMasterController: UNIATA_NO_DPC (0)\n"));
1928 deviceExtension
->UseDpc
= FALSE
;
1931 MasterDev
= IsMasterDev(&pciData
);
1934 KdPrint2((PRINT_PREFIX
"MasterDev\n"));
1935 deviceExtension
->MasterDev
= TRUE
;
1936 deviceExtension
->NumberChannels
= 1;
1938 KdPrint2((PRINT_PREFIX
"!MasterDev => SP_RETURN_NOT_FOUND\n"));
1942 if(deviceExtension
->AltRegMap
) {
1943 KdPrint2((PRINT_PREFIX
" Non-standard registers layout => SP_RETURN_NOT_FOUND\n"));
1946 if(IsBusMaster(&pciData
)) {
1947 KdPrint2((PRINT_PREFIX
" !BusMaster => SP_RETURN_NOT_FOUND\n"));
1951 KdPrint2((PRINT_PREFIX
"IsBusMaster == TRUE\n"));
1952 BaseIoAddressBM_0
= (PIDE_BUSMASTER_REGISTERS
)
1953 (AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, &pciData
, SystemIoBusNumber
,
1954 4, 0, 0x10/*ATA_BMIOSIZE*/)/* - bm_offset*/); //range id
1955 if(BaseIoAddressBM_0
) {
1956 UniataInitMapBM(deviceExtension
,
1958 (*ConfigInfo
->AccessRanges
)[4].RangeInMemory
? TRUE
: FALSE
);
1959 deviceExtension
->BusMaster
= TRUE
;
1960 deviceExtension
->BaseIoAddressBM_0
.Addr
= (ULONG_PTR
)BaseIoAddressBM_0
;
1961 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
1962 deviceExtension
->BaseIoAddressBM_0
.MemIo
= TRUE
;
1965 KdPrint2((PRINT_PREFIX
" BusMasterAddress (base): %#x\n", BaseIoAddressBM_0
));
1968 * the Cypress chip is a mess, it contains two ATA functions, but
1969 * both channels are visible on the first one.
1970 * simply ignore the second function for now, as the right
1971 * solution (ignoring the second channel on the first function)
1972 * doesn't work with the crappy ATA interrupt setup on the alpha.
1974 if (dev_id
== 0xc6931080 && slotData
.u
.bits
.FunctionNumber
> 1) {
1975 KdPrint2((PRINT_PREFIX
"dev_id == 0xc6931080 && FunctionNumber > 1 => exit_findbm\n"));
1979 // Indicate number of buses.
1980 ConfigInfo
->NumberOfBuses
= 0;
1981 if(!ConfigInfo
->InitiatorBusId
[0]) {
1982 ConfigInfo
->InitiatorBusId
[0] = (CHAR
)(IoGetConfigurationInformation()->ScsiPortCount
);
1983 KdPrint2((PRINT_PREFIX
"set ConfigInfo->InitiatorBusId[0] = %#x\n", ConfigInfo
->InitiatorBusId
[0]));
1985 // Indicate four devices can be attached to the adapter
1986 ConfigInfo
->MaximumNumberOfTargets
= 0;
1988 ConfigInfo
->MultipleRequestPerLu
= FALSE
;
1989 ConfigInfo
->AutoRequestSense
= FALSE
;
1990 ConfigInfo
->TaggedQueuing
= FALSE
;
1992 if((WinVer_Id() >= WinVer_NT
) ||
1993 (ConfigInfo
->Length
>= sizeof(_ConfigInfo
->comm
) + sizeof(_ConfigInfo
->nt4
))) {
1994 _ConfigInfo
->nt4
.DeviceExtensionSize
= sizeof(HW_DEVICE_EXTENSION
);
1995 _ConfigInfo
->nt4
.SpecificLuExtensionSize
= sizeof(HW_LU_EXTENSION
);
1996 _ConfigInfo
->nt4
.SrbExtensionSize
= sizeof(ATA_REQ
);
1998 if((WinVer_Id() > WinVer_2k
) ||
1999 (ConfigInfo
->Length
>= sizeof(_ConfigInfo
->comm
) + sizeof(_ConfigInfo
->nt4
) + sizeof(_ConfigInfo
->w2k
))) {
2000 _ConfigInfo
->w2k
.Dma64BitAddresses
= 0;
2001 _ConfigInfo
->w2k
.ResetTargetSupported
= FALSE
;
2002 _ConfigInfo
->w2k
.MaximumNumberOfLogicalUnits
= 0;
2005 // Save the Interrupe Mode for later use
2006 deviceExtension
->InterruptMode
= ConfigInfo
->InterruptMode
;
2007 deviceExtension
->BusInterruptLevel
= ConfigInfo
->BusInterruptLevel
;
2008 deviceExtension
->BusInterruptVector
= ConfigInfo
->BusInterruptVector
;
2009 deviceExtension
->Channel
= 0;
2010 deviceExtension
->DevIndex
= i
;
2011 deviceExtension
->OrigAdapterInterfaceType
2012 = ConfigInfo
->AdapterInterfaceType
;
2013 deviceExtension
->AlignmentMask
= ConfigInfo
->AlignmentMask
;
2014 deviceExtension
->AdapterInterfaceType
= PCIBus
;
2016 KdPrint2((PRINT_PREFIX
"Reconstruct ConfigInfo\n"));
2017 ConfigInfo
->MapBuffers
= TRUE
;
2019 ConfigInfo
->NeedPhysicalAddresses
= FALSE
;
2021 ConfigInfo
->NeedPhysicalAddresses
= TRUE
;
2022 #endif //USE_OWN_DMA
2026 KdPrint2((PRINT_PREFIX
"return SP_RETURN_FOUND\n"));
2027 //PrintNtConsole("return SP_RETURN_FOUND, de %#x, c0.lun0 %#x\n", deviceExtension, deviceExtension->chan[0].lun[0]);
2029 return SP_RETURN_FOUND
;
2032 if (deviceExtension
->lun
) ExFreePool(deviceExtension
->lun
);
2033 if (deviceExtension
->chan
) ExFreePool(deviceExtension
->chan
);
2034 return SP_RETURN_ERROR
;
2037 ExFreePool(deviceExtension
->lun
);
2038 ExFreePool(deviceExtension
->chan
);
2039 return SP_RETURN_NOT_FOUND
;
2041 } // end UniataFindFakeBusMasterController()
2046 Routine Description:
2048 This function is called to initialize 2nd device object for
2049 multichannel controllers.
2053 HwDeviceExtension - HBA miniport driver's adapter data storage
2063 IN PVOID HwDeviceExtension
2066 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2067 ULONG i
= deviceExtension
->DevIndex
;
2069 PISR2_DEVICE_EXTENSION Isr2DevExt
;
2070 WCHAR devname_str
[32];
2071 UNICODE_STRING devname
;
2073 KdPrint2((PRINT_PREFIX
"Init ISR:\n"));
2075 if(BMList
[i
].Isr2DevObj
) {
2076 KdPrint2((PRINT_PREFIX
"Already initialized %#x\n", BMList
[i
].Isr2DevObj
));
2077 return STATUS_SUCCESS
;
2080 if(!deviceExtension
->MasterDev
&& (deviceExtension
->NumberChannels
> 1) && // do not touch MasterDev
2081 !deviceExtension
->simplexOnly
&& /* // this is unnecessary on simplex controllers
2082 !BMList[i].Isr2DevObj*/ // handle re-init under w2k+
2086 KdPrint2((PRINT_PREFIX
"Multichannel native mode, go...\n"));
2088 KdPrint2((PRINT_PREFIX
"Unnecessary\n"));
2089 return STATUS_SUCCESS
;
2092 KdPrint2((PRINT_PREFIX
"Create DO\n"));
2095 _snwprintf(devname_str
, sizeof(devname_str
)/sizeof(WCHAR
),
2096 L
"\\Device\\uniata%d_2ch", i
);
2097 devname
.Length
*= sizeof(WCHAR
);
2098 devname
.MaximumLength
= devname
.Length
;
2099 devname
.Buffer
= devname_str
;
2101 KdPrint2((PRINT_PREFIX
"DO name: len(%d, %d), %S\n", devname
.Length
, devname
.MaximumLength
, devname
.Buffer
));
2103 status
= IoCreateDevice(SavedDriverObject
, sizeof(ISR2_DEVICE_EXTENSION
),
2104 /*NULL*/ &devname
, FILE_DEVICE_UNKNOWN
,
2105 0, FALSE
, &(BMList
[i
].Isr2DevObj
));
2107 if(!NT_SUCCESS(status
)) {
2108 KdPrint2((PRINT_PREFIX
"IoCreateDevice failed %#x\n"));
2112 KdPrint2((PRINT_PREFIX
"HalGetInterruptVector\n"));
2113 KdPrint2((PRINT_PREFIX
" OrigAdapterInterfaceType=%d\n", deviceExtension
->OrigAdapterInterfaceType
));
2114 KdPrint2((PRINT_PREFIX
" SystemIoBusNumber=%d\n", deviceExtension
->SystemIoBusNumber
));
2115 KdPrint2((PRINT_PREFIX
" BusInterruptLevel=%d\n", deviceExtension
->BusInterruptLevel
));
2116 KdPrint2((PRINT_PREFIX
" BusInterruptVector=%d\n", deviceExtension
->BusInterruptVector
));
2117 BMList
[i
].Isr2Vector
= HalGetInterruptVector(
2118 deviceExtension
->OrigAdapterInterfaceType
,
2119 deviceExtension
->SystemIoBusNumber
,
2120 deviceExtension
->BusInterruptLevel
,
2121 deviceExtension
->BusInterruptVector
,
2122 &(BMList
[i
].Isr2Irql
),
2123 &(BMList
[i
].Isr2Affinity
));
2125 Isr2DevExt
= (PISR2_DEVICE_EXTENSION
)(BMList
[i
].Isr2DevObj
->DeviceExtension
);
2126 Isr2DevExt
->HwDeviceExtension
= deviceExtension
;
2127 Isr2DevExt
->DevIndex
= i
;
2129 KdPrint2((PRINT_PREFIX
"isr2_de %#x\n", Isr2DevExt
));
2130 KdPrint2((PRINT_PREFIX
"isr2_vector %#x\n", BMList
[i
].Isr2Vector
));
2131 KdPrint2((PRINT_PREFIX
"isr2_irql %#x\n", BMList
[i
].Isr2Irql
));
2132 KdPrint2((PRINT_PREFIX
"isr2_affinity %#x\n", BMList
[i
].Isr2Affinity
));
2134 // deviceExtension->QueueNewIrql = BMList[i].Isr2Irql;
2136 KdPrint2((PRINT_PREFIX
"IoConnectInterrupt\n"));
2137 status
= IoConnectInterrupt(
2138 &(BMList
[i
].Isr2InterruptObject
),
2142 BMList
[i
].Isr2Vector
,
2145 (KINTERRUPT_MODE
)(deviceExtension
->InterruptMode
),
2147 BMList
[i
].Isr2Affinity
,
2150 if(!NT_SUCCESS(status
)) {
2151 KdPrint2((PRINT_PREFIX
"IoConnectInterrupt failed\n"));
2152 IoDeleteDevice(BMList
[i
].Isr2DevObj
);
2153 BMList
[i
].Isr2DevObj
= NULL
;
2154 BMList
[i
].Isr2InterruptObject
= NULL
;
2158 //deviceExtension->Isr2DevObj = BMList[i].Isr2DevObj;
2161 } // end UniataConnectIntr2()
2165 UniataDisconnectIntr2(
2166 IN PVOID HwDeviceExtension
2169 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2170 ULONG i
= deviceExtension
->DevIndex
;
2173 KdPrint2((PRINT_PREFIX
"Deinit ISR:\n"));
2175 if(!BMList
[i
].Isr2DevObj
) {
2176 KdPrint2((PRINT_PREFIX
"Already uninitialized %#x\n"));
2177 return STATUS_SUCCESS
;
2180 IoDisconnectInterrupt(BMList
[i
].Isr2InterruptObject
);
2182 BMList
[i
].Isr2InterruptObject
= NULL
;
2184 IoDeleteDevice(BMList
[i
].Isr2DevObj
);
2186 BMList
[i
].Isr2DevObj
= NULL
;
2187 //deviceExtension->Isr2DevObj = NULL;
2189 return STATUS_SUCCESS
;
2190 } // end UniataDisconnectIntr2()
2192 #endif //UNIATA_CORE
2196 Routine Description:
2198 This function is called by the OS-specific port driver after
2199 the necessary storage has been allocated, to gather information
2200 about the adapter's configuration.
2204 HwDeviceExtension - HBA miniport driver's adapter data storage
2205 Context - Address of adapter count
2206 ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility.
2207 ConfigInfo - Configuration information structure describing HBA
2208 Again - Indicates search for adapters to continue
2217 AtapiFindController(
2218 IN PVOID HwDeviceExtension
,
2220 IN PVOID BusInformation
,
2221 IN PCHAR ArgumentString
,
2222 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
2226 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2228 PULONG adapterCount
= (PULONG
)Context
;
2229 PUCHAR ioSpace
= NULL
;
2236 BOOLEAN preConfig
= FALSE
;
2238 PIDE_REGISTERS_1 BaseIoAddress1
;
2239 PIDE_REGISTERS_2 BaseIoAddress2
= NULL
;
2241 // The following table specifies the ports to be checked when searching for
2242 // an IDE controller. A zero entry terminates the search.
2243 static CONST ULONG AdapterAddresses
[5] = {IO_WD1
, IO_WD2
, IO_WD1
-8, IO_WD2
-8, 0};
2244 // CONST UCHAR Channels[5] = {0, 1, 0, 1, 0};
2246 // The following table specifies interrupt levels corresponding to the
2247 // port addresses in the previous table.
2248 static CONST ULONG InterruptLevels
[5] = {14, 15, 11, 10, 0};
2250 KdPrint2((PRINT_PREFIX
"AtapiFindController:\n"));
2252 if (!deviceExtension
) {
2253 return SP_RETURN_ERROR
;
2255 RtlZeroMemory(deviceExtension
, sizeof(HW_DEVICE_EXTENSION
));
2257 KdPrint2((PRINT_PREFIX
" assume max PIO4\n"));
2258 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
2259 deviceExtension
->NumberChannels
= 1;
2261 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
2265 chan
= &(deviceExtension
->chan
[0]);
2267 deviceExtension
->AdapterInterfaceType
=
2268 deviceExtension
->OrigAdapterInterfaceType
2269 = ConfigInfo
->AdapterInterfaceType
;
2273 /* do extra chipset specific setups */
2274 AtapiReadChipConfig(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, CHAN_NOT_SPECIFIED
);
2275 AtapiChipInit(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, CHAN_NOT_SPECIFIED
);
2277 // Check to see if this is a special configuration environment.
2279 if (ArgumentString
) {
2281 irq
= AtapiParseArgumentString(ArgumentString
, "Interrupt");
2284 // Both parameters must be present to proceed
2285 portBase
= AtapiParseArgumentString(ArgumentString
, "BaseAddress");
2288 // Try a default search for the part.
2294 #endif //UNIATA_CORE
2297 // Scan though the adapter address looking for adapters.
2298 if (ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[0].RangeStart
) != 0) {
2299 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2300 ConfigInfo
->AdapterInterfaceType
,
2301 ConfigInfo
->SystemIoBusNumber
,
2302 (*ConfigInfo
->AccessRanges
)[0].RangeStart
,
2303 (*ConfigInfo
->AccessRanges
)[0].RangeLength
,
2304 (BOOLEAN
) !((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
));
2306 // Since we have pre-configured information we only need to go through this loop once
2308 portBase
= ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[0].RangeStart
);
2309 KdPrint2((PRINT_PREFIX
" preconfig, portBase=%x\n", portBase
));
2313 while (AdapterAddresses
[*adapterCount
] != 0) {
2316 #endif //UNIATA_CORE
2319 deviceExtension
->DevIndex
= (*adapterCount
);
2321 portBase
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"PortBase", portBase
);
2322 irq
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"Irq", irq
);
2324 for (i
= 0; i
< 4; i
++) {
2325 // Zero device fields to ensure that if earlier devices were found,
2326 // but not claimed, the fields are cleared.
2327 deviceExtension
->lun
[i
].DeviceFlags
&= ~(DFLAGS_ATAPI_DEVICE
| DFLAGS_DEVICE_PRESENT
| DFLAGS_TAPE_DEVICE
);
2329 // Get the system physical address for this IO range.
2331 // Check if configInfo has the default information
2332 // if not, we go and find ourselves
2333 if (preConfig
== FALSE
) {
2336 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2337 ConfigInfo
->AdapterInterfaceType
,
2338 ConfigInfo
->SystemIoBusNumber
,
2339 ScsiPortConvertUlongToPhysicalAddress(portBase
),
2343 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2344 ConfigInfo
->AdapterInterfaceType
,
2345 ConfigInfo
->SystemIoBusNumber
,
2346 ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses
[*adapterCount
]),
2352 BaseIoAddress1
= (PIDE_REGISTERS_1
)ioSpace
;
2354 // Update the adapter count.
2357 // Check if ioSpace accessible.
2359 KdPrint2((PRINT_PREFIX
"AtapiFindController: !ioSpace\n"));
2362 // check if Primary/Secondary Master IDE claimed
2363 if((ioSpace
== (PUCHAR
)IO_WD1
) &&
2364 (ConfigInfo
->AtdiskPrimaryClaimed
)) {
2365 KdPrint2((PRINT_PREFIX
"AtapiFindController: AtdiskPrimaryClaimed\n"));
2368 if((ioSpace
== (PUCHAR
)IO_WD2
) &&
2369 (ConfigInfo
->AtdiskSecondaryClaimed
)) {
2370 KdPrint2((PRINT_PREFIX
"AtapiFindController: AtdiskSecondaryClaimed\n"));
2374 // Get the system physical address for the second IO range.
2375 if (BaseIoAddress1
) {
2377 !ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[1].RangeStart
)) {
2378 KdPrint2((PRINT_PREFIX
"AtapiFindController: PCMCIA ?\n"));
2379 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2380 ConfigInfo
->AdapterInterfaceType
,
2381 ConfigInfo
->SystemIoBusNumber
,
2382 ScsiPortConvertUlongToPhysicalAddress((ULONG_PTR
)BaseIoAddress1
+ 0x0E),
2386 ioSpace
= (PUCHAR
)ScsiPortGetDeviceBase(HwDeviceExtension
,
2387 ConfigInfo
->AdapterInterfaceType
,
2388 ConfigInfo
->SystemIoBusNumber
,
2389 ScsiPortConvertUlongToPhysicalAddress((ULONG_PTR
)BaseIoAddress1
+ ATA_ALTOFFSET
),
2394 BaseIoAddress2
= (PIDE_REGISTERS_2
)ioSpace
;
2395 KdPrint2((PRINT_PREFIX
" BaseIoAddress1=%x\n", BaseIoAddress1
));
2396 KdPrint2((PRINT_PREFIX
" BaseIoAddress2=%x\n", BaseIoAddress2
));
2398 UniataInitMapBase(chan
, BaseIoAddress1
, BaseIoAddress2
);
2399 UniataInitMapBM(deviceExtension
, 0, FALSE
);
2404 SelectDrive(chan
, 0);
2406 // Check if card at this address.
2407 AtapiWritePort1(chan
, IDX_IO1_o_CylinderLow
, 0xAA);
2409 // Check if indentifier can be read back.
2410 if ((statusByte
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
)) != 0xAA) {
2412 KdPrint2((PRINT_PREFIX
"AtapiFindController: Identifier read back from Master (%#x)\n",
2415 statusByte
= AtapiReadPort1(chan
, IDX_IO2_AltStatus
);
2417 if (statusByte
& IDE_STATUS_BUSY
) {
2421 // Could be the TEAC in a thinkpad. Their dos driver puts it in a sleep-mode that
2422 // warm boots don't clear.
2424 AtapiStallExecution(1000);
2425 statusByte
= AtapiReadPort1(chan
, IDX_ATAPI_IO1_i_Status
);
2426 KdPrint2((PRINT_PREFIX
2427 "AtapiFindController: First access to status %#x\n",
2429 } while ((statusByte
& IDE_STATUS_BUSY
) && ++i
< 10);
2431 if (retryCount
-- && (!(statusByte
& IDE_STATUS_BUSY
))) {
2432 goto retryIdentifier
;
2437 SelectDrive(chan
, 1);
2439 // See if slave is present.
2440 AtapiWritePort1(chan
, IDX_IO1_o_CylinderLow
, 0xAA);
2442 if ((statusByte
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
)) != 0xAA) {
2444 KdPrint2((PRINT_PREFIX
2445 "AtapiFindController: Identifier read back from Slave (%#x)\n",
2448 // No controller at this base address.
2449 if(BaseIoAddress1
) {
2450 ScsiPortFreeDeviceBase(HwDeviceExtension
,
2451 (PCHAR
)BaseIoAddress1
);
2452 BaseIoAddress1
= NULL
;
2454 if(BaseIoAddress2
) {
2455 ScsiPortFreeDeviceBase(HwDeviceExtension
,
2456 (PCHAR
)BaseIoAddress2
);
2457 BaseIoAddress2
= NULL
;
2463 // Fill in the access array information only if default params are not in there.
2464 if (preConfig
== FALSE
) {
2466 // An adapter has been found request another call, only if we didn't get preconfigured info.
2470 (*ConfigInfo
->AccessRanges
)[0].RangeStart
= ScsiPortConvertUlongToPhysicalAddress(portBase
);
2472 (*ConfigInfo
->AccessRanges
)[0].RangeStart
=
2473 ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses
[*adapterCount
- 1]);
2476 (*ConfigInfo
->AccessRanges
)[0].RangeLength
= 8;
2477 (*ConfigInfo
->AccessRanges
)[0].RangeInMemory
= FALSE
;
2479 // Indicate the interrupt level corresponding to this IO range.
2481 ConfigInfo
->BusInterruptLevel
= irq
;
2483 ConfigInfo
->BusInterruptLevel
= InterruptLevels
[*adapterCount
- 1];
2486 if (ConfigInfo
->AdapterInterfaceType
== MicroChannel
) {
2487 ConfigInfo
->InterruptMode
= LevelSensitive
;
2489 ConfigInfo
->InterruptMode
= Latched
;
2493 ConfigInfo
->NumberOfBuses
= 1;
2494 ConfigInfo
->MaximumNumberOfTargets
= 2;
2496 // Indicate maximum transfer length is 64k.
2497 ConfigInfo
->MaximumTransferLength
= 0x10000;
2498 deviceExtension
->MaximumDmaTransferLength
= ConfigInfo
->MaximumTransferLength
;
2500 KdPrint2((PRINT_PREFIX
"de %#x, Channel ???\n", deviceExtension
));
2501 //PrintNtConsole("de %#x, Channel %#x, nchan %#x\n",deviceExtension, channel, deviceExtension->NumberChannels);
2503 KdPrint2((PRINT_PREFIX
"chan = %#x\n", chan
));
2504 //PrintNtConsole("chan = %#x, c=%#x\n", chan, c);
2505 chan
->DeviceExtension
= deviceExtension
;
2507 chan
->lun
[0] = &(deviceExtension
->lun
[0]);
2508 chan
->lun
[1] = &(deviceExtension
->lun
[1]);
2510 /* do extra channel-specific setups */
2511 AtapiReadChipConfig(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, 0);
2512 AtapiChipInit(HwDeviceExtension
, DEVNUM_NOT_SPECIFIED
, 0);
2514 KdPrint2((PRINT_PREFIX
2515 "AtapiFindController: Found IDE at %#x\n",
2518 // For Daytona, the atdisk driver gets the first shot at the
2519 // primary and secondary controllers.
2520 if (preConfig
== FALSE
) {
2522 if (*adapterCount
- 1 < 2) {
2524 // Determine whether this driver is being initialized by the
2525 // system or as a crash dump driver.
2526 if (ArgumentString
) {
2529 if (AtapiParseArgumentString(ArgumentString
, "dump") == 1) {
2530 KdPrint2((PRINT_PREFIX
2531 "AtapiFindController: Crash dump\n"));
2533 deviceExtension
->DriverMustPoll
= TRUE
;
2535 KdPrint2((PRINT_PREFIX
2536 "AtapiFindController: Atapi Only\n"));
2538 deviceExtension
->DriverMustPoll
= FALSE
;
2540 #endif //UNIATA_CORE
2543 KdPrint2((PRINT_PREFIX
2544 "AtapiFindController: Atapi Only (2)\n"));
2546 deviceExtension
->DriverMustPoll
= FALSE
;
2556 deviceExtension
->DriverMustPoll
= FALSE
;
2560 // Save the Interrupe Mode for later use
2561 deviceExtension
->InterruptMode
= ConfigInfo
->InterruptMode
;
2563 KdPrint2((PRINT_PREFIX
2564 "AtapiFindController: look for devices\n"));
2565 // Search for devices on this controller.
2566 if (FindDevices(HwDeviceExtension
,
2570 KdPrint2((PRINT_PREFIX
2571 "AtapiFindController: detected\n"));
2572 // Claim primary or secondary ATA IO range.
2576 ConfigInfo
->AtdiskSecondaryClaimed
= TRUE
;
2577 chan
->PrimaryAddress
= FALSE
;
2580 ConfigInfo
->AtdiskPrimaryClaimed
= TRUE
;
2581 chan
->PrimaryAddress
= TRUE
;
2587 if (*adapterCount
== 1) {
2588 ConfigInfo
->AtdiskPrimaryClaimed
= TRUE
;
2589 chan
->PrimaryAddress
= TRUE
;
2590 } else if (*adapterCount
== 2) {
2591 ConfigInfo
->AtdiskSecondaryClaimed
= TRUE
;
2592 chan
->PrimaryAddress
= FALSE
;
2596 if(deviceExtension
->AdapterInterfaceType
== Isa
) {
2599 if(deviceExtension
->AdapterInterfaceType
== MicroChannel
) {
2603 KdPrint2((PRINT_PREFIX
2604 "AtapiFindController: return SP_RETURN_FOUND\n"));
2605 return(SP_RETURN_FOUND
);
2611 #endif //UNIATA_CORE
2613 // The entire table has been searched and no adapters have been found.
2614 // There is no need to call again and the device base can now be freed.
2615 // Clear the adapter count for the next bus.
2617 *(adapterCount
) = 0;
2619 KdPrint2((PRINT_PREFIX
2620 "AtapiFindController: return SP_RETURN_NOT_FOUND\n"));
2621 ExFreePool(deviceExtension
->lun
);
2622 ExFreePool(deviceExtension
->chan
);
2623 return(SP_RETURN_NOT_FOUND
);
2626 if (deviceExtension
->lun
) ExFreePool(deviceExtension
->lun
);
2627 if (deviceExtension
->chan
) ExFreePool(deviceExtension
->chan
);
2628 return SP_RETURN_ERROR
;
2630 } // end AtapiFindController()
2635 IN PVOID HwDeviceExtension
,
2637 IN ULONG deviceNumber
2640 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2641 PHW_CHANNEL chan
= &(deviceExtension
->chan
[lChannel
]);
2642 ULONG ldev
= GET_LDEV2(lChannel
, deviceNumber
, 0);
2643 PHW_LU_EXTENSION LunExt
= &(deviceExtension
->lun
[ldev
]);
2645 SATA_SSTATUS_REG SStatus
;
2647 UCHAR signatureHigh
;
2649 if(LunExt
->DeviceFlags
& DFLAGS_HIDDEN
) {
2650 KdPrint2((PRINT_PREFIX
" hidden\n"));
2651 UniataForgetDevice(LunExt
);
2654 // Select the device.
2655 SelectDrive(chan
, deviceNumber
);
2657 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
);
2658 signatureHigh
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderHigh
);
2660 if (signatureLow
== ATAPI_MAGIC_LSB
&& signatureHigh
== ATAPI_MAGIC_MSB
) {
2661 KdPrint2((PRINT_PREFIX
" ATAPI at home\n", signatureLow
));
2665 if(!UniataIsSATARangeAvailable(deviceExtension
, lChannel
)) {
2666 AtapiStallExecution(10);
2668 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0x55);
2669 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0x55);
2670 AtapiStallExecution(5);
2671 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_BlockNumber
);
2672 if(signatureLow
!= 0x55) {
2673 KdPrint2((PRINT_PREFIX
" nobody home! %#x != 0x55\n", signatureLow
));
2674 UniataForgetDevice(LunExt
);
2678 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0xAA);
2679 AtapiWritePort1(chan
, IDX_IO1_o_BlockNumber
, 0xAA);
2680 AtapiStallExecution(5);
2681 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_BlockNumber
);
2682 if(signatureLow
!= 0xAA) {
2683 KdPrint2((PRINT_PREFIX
" nobody home! %#x != 0xAA\n", signatureLow
));
2684 UniataForgetDevice(LunExt
);
2689 SStatus
.Reg
= AtapiReadPort4(chan
, IDX_SATA_SStatus
);
2690 KdPrint2((PRINT_PREFIX
"SStatus %x\n", SStatus
.Reg
));
2691 if(SStatus
.DET
<= SStatus_DET_Dev_NoPhy
) {
2692 KdPrint2((PRINT_PREFIX
" SATA DET <= SStatus_DET_Dev_NoPhy\n"));
2695 if(SStatus
.SPD
< SStatus_SPD_Gen1
) {
2696 KdPrint2((PRINT_PREFIX
" SATA SPD < SStatus_SPD_Gen1\n"));
2699 if(SStatus
.IPM
== SStatus_IPM_NoDev
) {
2700 KdPrint2((PRINT_PREFIX
" SATA IPN == SStatus_IPM_NoDev\n"));
2706 } // end UniataAnybodyHome()
2711 IN PVOID HwDeviceExtension
,
2713 IN ULONG deviceNumber
,
2717 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2718 PHW_CHANNEL chan
= &(deviceExtension
->chan
[lChannel
]);
2719 ULONG ldev
= GET_LDEV2(lChannel
, deviceNumber
, 0);
2720 PHW_LU_EXTENSION LunExt
= &(deviceExtension
->lun
[ldev
]);
2726 ULONG waitCount
= 10000;
2728 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x\n",
2731 KdPrint2((PRINT_PREFIX
"CheckDevice: reset dev\n"));
2734 AtapiSoftReset(chan
, deviceNumber
);
2736 if(!UniataAnybodyHome(HwDeviceExtension
, lChannel
, deviceNumber
)) {
2739 statusByte
= WaitOnBusy(chan
);
2741 if((statusByte
| IDE_STATUS_BUSY
) == 0xff) {
2742 KdPrint2((PRINT_PREFIX
2743 "CheckDevice: bad status %x\n", statusByte
));
2745 if(statusByte
!= 0xff && (statusByte
& IDE_STATUS_BUSY
)) {
2746 // Perform hard-reset.
2747 KdPrint2((PRINT_PREFIX
2748 "CheckDevice: BUSY\n"));
2750 AtapiWritePort1(chan
, IDX_IO2_o_Control
, IDE_DC_RESET_CONTROLLER
);
2751 AtapiStallExecution(500 * 1000);
2752 AtapiWritePort1(chan
, IDX_IO2_o_Control
, IDE_DC_REENABLE_CONTROLLER
);
2753 SelectDrive(chan
, deviceNumber
& 0x01);
2756 // Wait for Busy to drop.
2757 AtapiStallExecution(100);
2758 GetStatus(chan
, statusByte
);
2760 } while ((statusByte
& IDE_STATUS_BUSY
) && waitCount
--);
2762 GetBaseStatus(chan
, statusByte
);
2763 KdPrint2((PRINT_PREFIX
2764 "CheckDevice: status after hard reset %x\n", statusByte
));
2767 if((statusByte
| IDE_STATUS_BUSY
) == 0xff) {
2768 KdPrint2((PRINT_PREFIX
2769 "CheckDevice: no dev ?\n"));
2771 if(UniataIsSATARangeAvailable(deviceExtension
, lChannel
)) {
2772 //if(deviceExtension->HwFlags & UNIATA_SATA) {
2773 KdPrint2((PRINT_PREFIX
2774 "CheckDevice: try enable SATA Phy\n"));
2775 statusByte
= UniataSataPhyEnable(HwDeviceExtension
, lChannel
);
2776 if(statusByte
== 0xff) {
2777 KdPrint2((PRINT_PREFIX
"CheckDevice: status %#x (no dev)\n", statusByte
));
2778 UniataForgetDevice(LunExt
);
2783 // Select the device.
2784 SelectDrive(chan
, deviceNumber
);
2786 if(!UniataAnybodyHome(HwDeviceExtension
, lChannel
, deviceNumber
)) {
2790 statusByte
= WaitOnBaseBusyLong(chan
);
2792 GetBaseStatus(chan
, statusByte
);
2793 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
2794 UniataSataClearErr(HwDeviceExtension
, lChannel
, UNIATA_SATA_IGNORE_CONNECT
);
2797 KdPrint2((PRINT_PREFIX
"CheckDevice: status %#x\n", statusByte
));
2798 if(((statusByte
| IDE_STATUS_BUSY
) == 0xff) ||
2799 (statusByte
& IDE_STATUS_BUSY
)) {
2800 KdPrint2((PRINT_PREFIX
"CheckDevice: busy => return\n"));
2801 UniataForgetDevice(LunExt
);
2805 // set default costs
2806 LunExt
->RwSwitchCost
= REORDER_COST_SWITCH_RW_HDD
;
2807 LunExt
->RwSwitchMCost
= REORDER_MCOST_SWITCH_RW_HDD
;
2808 LunExt
->SeekBackMCost
= REORDER_MCOST_SEEK_BACK_HDD
;
2810 signatureLow
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderLow
);
2811 signatureHigh
= AtapiReadPort1(chan
, IDX_IO1_i_CylinderHigh
);
2813 if (signatureLow
== ATAPI_MAGIC_LSB
&& signatureHigh
== ATAPI_MAGIC_MSB
) {
2815 KdPrint2((PRINT_PREFIX
"CheckDevice: ATAPI signature found\n"));
2816 // ATAPI signature found.
2817 // Issue the ATAPI identify command if this
2818 // is not for the crash dump utility.
2820 if (!deviceExtension
->DriverMustPoll
) {
2822 // Issue ATAPI packet identify command.
2823 if (IssueIdentify(HwDeviceExtension
,
2826 IDE_COMMAND_ATAPI_IDENTIFY
, FALSE
)) {
2828 // Indicate ATAPI device.
2829 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x is ATAPI\n",
2832 RetVal
= DFLAGS_DEVICE_PRESENT
| DFLAGS_ATAPI_DEVICE
;
2833 LunExt
->DeviceFlags
|= (DFLAGS_DEVICE_PRESENT
| DFLAGS_ATAPI_DEVICE
);
2835 // some ATAPI devices doesn't work with DPC on CMD-649
2836 // and probably some other controllers
2837 if(deviceExtension
->HwFlags
& UNIATA_NO_DPC_ATAPI
) {
2838 /* CMD 649, ROSB SWK33, ICH4 */
2839 KdPrint2((PRINT_PREFIX
"CheckDevice: UNIATA_NO_DPC_ATAPI\n"));
2840 deviceExtension
->UseDpc
= FALSE
;
2843 GetStatus(chan
, statusByte
);
2844 if (statusByte
& IDE_STATUS_ERROR
) {
2845 AtapiSoftReset(chan
, deviceNumber
);
2850 // Indicate no working device.
2851 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x not responding\n",
2854 UniataForgetDevice(LunExt
);
2857 GetBaseStatus(chan
, statusByte
);
2863 KdPrint2((PRINT_PREFIX
"CheckDevice: IDE device check\n"));
2864 // Issue IDE Identify. If an Atapi device is actually present, the signature
2865 // will be asserted, and the drive will be recognized as such.
2866 if(deviceExtension
->DWordIO
) {
2867 KdPrint2((PRINT_PREFIX
" try 32bit IO\n"));
2868 LunExt
->DeviceFlags
|= DFLAGS_DWORDIO_ENABLED
;
2870 if (IssueIdentify(HwDeviceExtension
,
2873 IDE_COMMAND_IDENTIFY
, FALSE
)) {
2876 KdPrint2((PRINT_PREFIX
"CheckDevice: Device %#x is IDE\n",
2879 // Indicate IDE - not ATAPI device.
2880 RetVal
= DFLAGS_DEVICE_PRESENT
;
2881 LunExt
->DeviceFlags
|= DFLAGS_DEVICE_PRESENT
;
2882 LunExt
->DeviceFlags
&= ~DFLAGS_ATAPI_DEVICE
;
2884 GetBaseStatus(chan
, statusByte
);
2886 KdPrint2((PRINT_PREFIX
"CheckDevice: check status: %sfound\n", RetVal
? "" : "not "));
2888 } // end CheckDevice()
2893 Routine Description:
2895 This routine is called from AtapiFindController to identify
2896 devices attached to an IDE controller.
2900 HwDeviceExtension - HBA miniport driver's adapter data storage
2901 AtapiOnly - Indicates that routine should return TRUE only if
2902 an ATAPI device is attached to the controller.
2906 TRUE - True if devices found.
2912 IN PVOID HwDeviceExtension
,
2917 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
2918 PHW_CHANNEL chan
= &(deviceExtension
->chan
[Channel
]);
2919 PHW_LU_EXTENSION LunExt
;
2920 BOOLEAN deviceResponded
= FALSE
,
2921 skipSetParameters
= FALSE
;
2922 ULONG waitCount
= 10000;
2923 //ULONG deviceNumber;
2928 BOOLEAN AtapiOnly
= FALSE
;
2930 KdPrint2((PRINT_PREFIX
"FindDevices:\n"));
2932 // Disable interrupts
2933 AtapiDisableInterrupts(deviceExtension
, Channel
);
2934 // AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_DISABLE_INTERRUPTS | IDE_DC_A_4BIT );
2936 // Clear expecting interrupt flag and current SRB field.
2937 chan
->ExpectingInterrupt
= FALSE
;
2938 // chan->CurrentSrb = NULL;
2939 max_ldev
= (chan
->ChannelCtrlFlags
& CTRFLAGS_NO_SLAVE
) ? 1 : 2;
2940 KdPrint2((PRINT_PREFIX
" max_ldev %d\n", max_ldev
));
2942 // Search for devices.
2943 for (i
= 0; i
< max_ldev
; i
++) {
2944 AtapiDisableInterrupts(deviceExtension
, Channel
);
2945 if(Flags
& UNIATA_FIND_DEV_UNHIDE
) {
2946 ldev
= GET_LDEV2(Channel
, i
, 0);
2947 deviceExtension
->lun
[ldev
].DeviceFlags
&= ~DFLAGS_HIDDEN
;
2950 (CheckDevice(HwDeviceExtension
, Channel
, i
, TRUE
) != 0);
2951 AtapiEnableInterrupts(deviceExtension
, Channel
);
2954 for (i
= 0; i
< max_ldev
; i
++) {
2955 ldev
= GET_LDEV2(Channel
, i
, 0);
2956 LunExt
= &(deviceExtension
->lun
[ldev
]);
2958 if (( LunExt
->DeviceFlags
& DFLAGS_DEVICE_PRESENT
) &&
2959 !(LunExt
->DeviceFlags
& DFLAGS_LBA_ENABLED
) &&
2960 !(LunExt
->DeviceFlags
& DFLAGS_ATAPI_DEVICE
) && deviceResponded
) {
2962 // This hideous hack is to deal with ESDI devices that return
2963 // garbage geometry in the IDENTIFY data.
2964 // This is ONLY for the crashdump environment as
2965 // these are ESDI devices.
2966 if (LunExt
->IdentifyData
.SectorsPerTrack
==
2968 LunExt
->IdentifyData
.NumberOfHeads
==
2971 KdPrint2((PRINT_PREFIX
2972 "FindDevices: Found nasty Compaq ESDI!\n"));
2974 // Change these values to something reasonable.
2975 LunExt
->IdentifyData
.SectorsPerTrack
=
2977 LunExt
->IdentifyData
.NumberOfHeads
=
2981 if (LunExt
->IdentifyData
.SectorsPerTrack
==
2983 LunExt
->IdentifyData
.NumberOfHeads
==
2986 KdPrint2((PRINT_PREFIX
2987 "FindDevices: Found nasty Compaq ESDI!\n"));
2989 // Change these values to something reasonable.
2990 LunExt
->IdentifyData
.SectorsPerTrack
=
2992 LunExt
->IdentifyData
.NumberOfHeads
=
2997 if (LunExt
->IdentifyData
.SectorsPerTrack
==
2999 LunExt
->IdentifyData
.NumberOfHeads
==
3002 KdPrint2((PRINT_PREFIX
"FindDevices: Found nasty UltraStor ESDI!\n"));
3004 // Change these values to something reasonable.
3005 LunExt
->IdentifyData
.SectorsPerTrack
=
3007 LunExt
->IdentifyData
.NumberOfHeads
=
3009 skipSetParameters
= TRUE
;
3013 if (skipSetParameters
)
3016 statusByte
= WaitOnBusy(chan
);
3018 // Select the device.
3019 SelectDrive(chan
, i
& 0x01);
3020 GetStatus(chan
, statusByte
);
3022 if (statusByte
& IDE_STATUS_ERROR
) {
3024 // Reset the device.
3025 KdPrint2((PRINT_PREFIX
3026 "FindDevices: Resetting controller before SetDriveParameters.\n"));
3028 AtapiWritePort1(chan
, IDX_IO2_o_Control
, IDE_DC_RESET_CONTROLLER
);
3029 AtapiStallExecution(500 * 1000);
3030 AtapiWritePort1(chan
, IDX_IO2_o_Control
, IDE_DC_REENABLE_CONTROLLER
);
3031 SelectDrive(chan
, i
& 0x01);
3034 // Wait for Busy to drop.
3035 AtapiStallExecution(100);
3036 GetStatus(chan
, statusByte
);
3038 } while ((statusByte
& IDE_STATUS_BUSY
) && waitCount
--);
3041 statusByte
= WaitOnBusy(chan
);
3043 KdPrint2((PRINT_PREFIX
3044 "FindDevices: Status before SetDriveParameters: (%#x) (%#x)\n",
3046 AtapiReadPort1(chan
, IDX_IO1_i_DriveSelect
)));
3048 GetBaseStatus(chan
, statusByte
);
3050 // Use the IDENTIFY data to set drive parameters.
3051 if (!SetDriveParameters(HwDeviceExtension
,i
,Channel
)) {
3053 KdPrint2((PRINT_PREFIX
3054 "FindDevices: Set drive parameters for device %d failed\n",
3056 // Don't use this device as writes could cause corruption.
3057 LunExt
->DeviceFlags
&= ~DFLAGS_DEVICE_PRESENT
;
3058 UniataForgetDevice(&(deviceExtension
->lun
[ldev
]));
3062 if (LunExt
->DeviceFlags
& DFLAGS_REMOVABLE_DRIVE
) {
3064 // Pick up ALL IDE removable drives that conform to Yosemite V0.2...
3068 // Indicate that a device was found.
3070 deviceResponded
= TRUE
;
3075 /* // Reset the controller. This is a feeble attempt to leave the ESDI
3076 // controllers in a state that ATDISK driver will recognize them.
3077 // The problem in ATDISK has to do with timings as it is not reproducible
3078 // in debug. The reset should restore the controller to its poweron state
3079 // and give the system enough time to settle.
3080 if (!deviceResponded) {
3082 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_RESET_CONTROLLER );
3083 AtapiStallExecution(50 * 1000);
3084 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_REENABLE_CONTROLLER);
3087 if(deviceResponded
) {
3088 for (i
= 0; i
< max_ldev
; i
++) {
3089 ldev
= GET_LDEV2(Channel
, i
, 0);
3090 LunExt
= &(deviceExtension
->lun
[ldev
]);
3092 KdPrint2((PRINT_PREFIX
3093 "FindDevices: select %d dev to clear INTR\n", i
));
3094 SelectDrive(chan
, i
);
3095 GetBaseStatus(chan
, statusByte
);
3096 KdPrint2((PRINT_PREFIX
3097 "FindDevices: statusByte=%#x\n", statusByte
));
3099 for (i
= 0; i
< max_ldev
; i
++) {
3100 ldev
= GET_LDEV2(Channel
, i
, 0);
3101 LunExt
= &(deviceExtension
->lun
[ldev
]);
3103 if(LunExt
->DeviceFlags
& DFLAGS_DEVICE_PRESENT
) {
3104 // Make sure some device (master is preferred) is selected on exit.
3105 KdPrint2((PRINT_PREFIX
3106 "FindDevices: select %d dev on exit\n", i
));
3107 SelectDrive(chan
, i
);
3113 GetBaseStatus(chan
, statusByte
);
3114 // Enable interrupts
3115 AtapiEnableInterrupts(deviceExtension
, Channel
);
3116 // AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_A_4BIT );
3117 GetBaseStatus(chan
, statusByte
);
3119 KdPrint2((PRINT_PREFIX
3120 "FindDevices: returning %d\n",
3123 return deviceResponded
;
3125 } // end FindDevices()