3 Copyright (c) 2004-2012 Alexandr A. Telyatnikov (Alter)
9 This is the chip-specific init module for ATA/ATAPI IDE controllers
10 with Busmaster DMA and Serial ATA support
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 code were taken from FreeBSD 5.1-6.1 ATA driver by
34 Søren Schmidt, Copyright (c) 1998-2007
35 added IT8172 IDE controller support from Linux
36 added VIA 8233/8235 fix from Linux
37 added 80-pin cable detection from Linux for
39 added support for non-standard layout of registers
46 static BUSMASTER_CONTROLLER_INFORMATION
const AtiSouthAdapters
[] = {
47 PCI_DEV_HW_SPEC_BM( 4385, 1002, 0x00, ATA_MODE_NOT_SPEC
, "ATI South", 0 ),
48 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
54 UniataChipDetectChannels(
55 IN PVOID HwDeviceExtension
,
56 IN PPCI_COMMON_CONFIG pciData
, // optional
57 IN ULONG DeviceNumber
,
58 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
61 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
62 //ULONG slotNumber = deviceExtension->slotNumber;
63 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
64 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
65 //ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
66 //ULONG RevID = deviceExtension->RevID;
67 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
68 ULONG ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
71 KdPrint2((PRINT_PREFIX
"UniataChipDetectChannels:\n" ));
73 deviceExtension
->AHCI_PI_mask
= 0;
75 if(ChipFlags
& (UNIATA_SATA
| UNIATA_AHCI
)) {
76 if(!deviceExtension
->NumberChannels
) {
77 KdPrint2((PRINT_PREFIX
"uninitialized SATA/AHCI port number -> 1\n"));
78 deviceExtension
->NumberChannels
= 1;
80 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"IgnoreAhciPM", 1 /* DEBUG */)) {
81 KdPrint2((PRINT_PREFIX
"SATA/AHCI w/o PM, max luns 1 or 2\n"));
82 deviceExtension
->NumberLuns
= 2; // we may be in Legacy mode
83 //chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
85 KdPrint2((PRINT_PREFIX
"SATA/AHCI -> possible PM, max luns %d\n", SATA_MAX_PM_UNITS
));
86 deviceExtension
->NumberLuns
= SATA_MAX_PM_UNITS
;
87 //deviceExtension->NumberLuns = 1;
90 if(deviceExtension
->MasterDev
) {
91 KdPrint2((PRINT_PREFIX
"MasterDev -> 1 chan\n"));
92 deviceExtension
->NumberChannels
= 1;
94 for(n
=0; n
<deviceExtension
->NumberChannels
; n
++) {
95 if(AtapiRegCheckDevValue(deviceExtension
, n
, DEVNUM_NOT_SPECIFIED
, L
"Exclude", 0)) {
96 KdPrint2((PRINT_PREFIX
"Channel %d excluded\n", n
));
97 deviceExtension
->AHCI_PI_mask
&= ~((ULONG
)1 << n
);
99 deviceExtension
->AHCI_PI_mask
|= ((ULONG
)1 << n
);
102 KdPrint2((PRINT_PREFIX
"PortMask %#x\n", deviceExtension
->AHCI_PI_mask
));
103 deviceExtension
->AHCI_PI_mask
=
104 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"PortMask", (ULONG
)0xffffffff >> (32-deviceExtension
->NumberChannels
) );
105 KdPrint2((PRINT_PREFIX
"Force PortMask %#x\n", deviceExtension
->AHCI_PI_mask
));
107 for(i
=deviceExtension
->AHCI_PI_mask
, n
=0; i
; n
++, i
=i
>>1);
108 KdPrint2((PRINT_PREFIX
"mask -> %d chans\n", n
));
111 case ATA_ACER_LABS_ID
:
112 switch(deviceExtension
->DevID
) {
115 deviceExtension
->NumberChannels
= 4;
116 KdPrint2((PRINT_PREFIX
"Acer 4 chan\n"));
121 if(ChipType
!= PRMIO
) {
124 if(!(ChipFlags
& UNIATA_SATA
)) {
125 deviceExtension
->NumberChannels
= 4;
126 KdPrint2((PRINT_PREFIX
"Promise up to 4 chan\n"));
128 if(ChipFlags
& PRCMBO
) {
129 deviceExtension
->NumberChannels
= 3;
130 KdPrint2((PRINT_PREFIX
"Promise 3 chan\n"));
132 deviceExtension
->NumberChannels
= 4;
133 KdPrint2((PRINT_PREFIX
"Promise 4 chan\n"));
137 KdPrint2((PRINT_PREFIX
"Marvell\n"));
138 /* AHCI part has own DevID-based workaround */
139 switch(deviceExtension
->DevID
) {
141 /* 88SX6101 only have 1 PATA channel */
142 if(BMList
[deviceExtension
->DevIndex
].channel
) {
143 KdPrint2((PRINT_PREFIX
"88SX6101/11 has no 2nd PATA chan\n"));
146 deviceExtension
->NumberChannels
= 1;
147 KdPrint2((PRINT_PREFIX
"88SX6101 PATA 1 chan\n"));
152 KdPrint2((PRINT_PREFIX
"ATI\n"));
153 switch(deviceExtension
->DevID
) {
155 KdPrint2((PRINT_PREFIX
" IXP600\n"));
156 /* IXP600 only have 1 PATA channel */
157 if(BMList
[deviceExtension
->DevIndex
].channel
) {
158 KdPrint2((PRINT_PREFIX
"New ATI no 2nd PATA chan\n"));
161 deviceExtension
->NumberChannels
= 1;
162 KdPrint2((PRINT_PREFIX
"New ATI PATA 1 chan\n"));
165 case ATA_ATI_IXP700
: {
167 PCI_SLOT_NUMBER slotData
;
170 KdPrint2((PRINT_PREFIX
" IXP700\n"));
172 * When "combined mode" is enabled, an additional PATA channel is
173 * emulated with two SATA ports and appears on this device.
174 * This mode can only be detected via SMB controller.
176 i
= AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION
*)&AtiSouthAdapters
[0], -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, &slotData
);
177 if(i
!= BMLIST_TERMINATOR
) {
178 slotNumber
= slotData
.u
.AsULONG
;
180 GetPciConfig1(0xad, satacfg
);
181 KdPrint(("SATA controller %s (%s%s channel)\n",
182 (satacfg
& 0x01) == 0 ? "disabled" : "enabled",
183 (satacfg
& 0x08) == 0 ? "" : "combined mode, ",
184 (satacfg
& 0x10) == 0 ? "primary" : "secondary"));
186 * If SATA controller is enabled but combined mode is disabled,
187 * we have only one PATA channel. Ignore a non-existent channel.
189 if ((satacfg
& 0x09) == 0x01) {
190 if(BMList
[deviceExtension
->DevIndex
].channel
) {
191 KdPrint2((PRINT_PREFIX
"New ATI no 2nd PATA chan\n"));
194 deviceExtension
->NumberChannels
= 1;
195 KdPrint2((PRINT_PREFIX
"New ATI PATA 1 chan\n"));
198 KdPrint2((PRINT_PREFIX
"New ATI 2 chan\n"));
199 deviceExtension
->NumberChannels
= 2;
201 if (BMList[deviceExtension->DevIndex].channel != ((satacfg & 0x10) >> 4)) {
212 case ATA_SILICON_IMAGE_ID
:
214 if(ChipFlags
& SIIBUG
) {
215 /* work around errata in early chips */
216 deviceExtension
->DmaSegmentLength
= 15 * DEV_BSIZE
;
217 deviceExtension
->DmaSegmentAlignmentMask
= 8192-1;
219 if(ChipType
!= SIIMIO
) {
226 if(VendorID
== ATA_SILICON_IMAGE_ID
) {
227 KdPrint2((PRINT_PREFIX
"New SII\n"));
229 KdPrint2((PRINT_PREFIX
"ATI SATA\n"));
231 if(deviceExtension
->HwFlags
& SII4CH
) {
232 deviceExtension
->NumberChannels
= 4;
233 KdPrint2((PRINT_PREFIX
"4 chan\n"));
237 if(/*(deviceExtension->DevID == 0x32491106) &&
238 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[5].RangeStart)*/
239 deviceExtension
->HwFlags
& VIABAR
) {
240 deviceExtension
->NumberChannels
= 3;
241 KdPrint2((PRINT_PREFIX
"VIA 3 chan\n"));
243 if(ChipFlags
& VIASATA
) {
244 /* 2 SATA without SATA registers on first channel + 1 PATA on second */
245 // do nothing, generic PATA INIT
246 KdPrint2((PRINT_PREFIX
"VIA SATA without SATA regs -> no PM\n"));
247 deviceExtension
->NumberLuns
= 1;
251 /* ITE ATA133 controller */
252 if(deviceExtension
->DevID
== 0x82131283) {
253 if(BMList
[deviceExtension
->DevIndex
].channel
) {
254 KdPrint2((PRINT_PREFIX
"New ITE has no 2nd PATA chan\n"));
257 deviceExtension
->NumberChannels
= 1;
258 KdPrint2((PRINT_PREFIX
"New ITE PATA 1 chan\n"));
263 /* New Intel PATA controllers */
264 if(g_opt_VirtualMachine
!= VM_VBOX
&&
265 /*deviceExtension->DevID == 0x27df8086 ||
266 deviceExtension->DevID == 0x269e8086 ||
267 deviceExtension->DevID == ATA_I82801HBM*/
269 if(BMList
[deviceExtension
->DevIndex
].channel
) {
270 KdPrint2((PRINT_PREFIX
"New Intel PATA has no 2nd chan\n"));
273 deviceExtension
->NumberChannels
= 1;
274 KdPrint2((PRINT_PREFIX
"New Intel PATA 1 chan\n"));
277 #endif // this code is removed from newer FreeBSD
279 /* New JMicron PATA controllers */
280 if(deviceExtension
->DevID
== ATA_JMB361
||
281 deviceExtension
->DevID
== ATA_JMB363
||
282 deviceExtension
->DevID
== ATA_JMB368
) {
283 if(BMList
[deviceExtension
->DevIndex
].channel
) {
284 KdPrint2((PRINT_PREFIX
"New JMicron has no 2nd chan\n"));
287 deviceExtension
->NumberChannels
= 1;
288 KdPrint2((PRINT_PREFIX
"New JMicron PATA 1 chan\n"));
292 if(ChipType
== CYRIX_OLD
) {
295 slotNumber
= deviceExtension
->slotNumber
;
296 KdPrint2((PRINT_PREFIX
"Cyrix slot %#x\n", slotNumber
));
297 GetPciConfig1(0x60, tmp8
);
298 if(tmp8
& (1 << BMList
[deviceExtension
->DevIndex
].channel
)) {
299 KdPrint2((PRINT_PREFIX
"Old Cyrix chan %d ok\n", BMList
[deviceExtension
->DevIndex
].channel
));
301 KdPrint2((PRINT_PREFIX
"Old Cyrix no chan %d\n", BMList
[deviceExtension
->DevIndex
].channel
));
306 } // end switch(VendorID)
308 i
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"NumberChannels", n
);
312 KdPrint2((PRINT_PREFIX
"reg -> %d chans\n", n
));
314 deviceExtension
->NumberChannels
= min(i
, deviceExtension
->NumberChannels
);
315 if(!deviceExtension
->NumberChannels
) {
316 KdPrint2((PRINT_PREFIX
"all channels blocked\n", n
));
319 deviceExtension
->AHCI_PI_mask
&= (ULONG
)0xffffffff >> (32-deviceExtension
->NumberChannels
);
320 KdPrint2((PRINT_PREFIX
"Final PortMask %#x\n", deviceExtension
->AHCI_PI_mask
));
324 } // end UniataChipDetectChannels()
329 IN PVOID HwDeviceExtension
,
330 IN PPCI_COMMON_CONFIG pciData
, // optional
331 IN ULONG DeviceNumber
,
332 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
333 IN BOOLEAN
* simplexOnly
336 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
337 ULONG slotNumber
= deviceExtension
->slotNumber
;
338 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
339 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
340 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
341 ULONG RevID
= deviceExtension
->RevID
;
343 BUSMASTER_CONTROLLER_INFORMATION
* DevTypeInfo
;
349 ULONG BaseMemAddress
;
350 ULONG BaseIoAddress1
;
351 ULONG BaseIoAddress2
;
352 ULONG BaseIoAddressBM
;
353 BOOLEAN MemIo
= FALSE
;
354 BOOLEAN IsPata
= FALSE
;
356 KdPrint2((PRINT_PREFIX
"UniataChipDetect:\n" ));
357 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
359 i
= Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[0], VendorID
, 0xffff, 0, NUM_BUSMASTER_ADAPTERS
);
361 c
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", 0);
367 BaseIoAddressBM
= pciData
->u
.type0
.BaseAddresses
[4] & ~0x07;
368 deviceExtension
->MaxTransferMode
= BaseIoAddressBM
? ATA_DMA
: ATA_PIO4
;
369 ConfigInfo
->MaximumTransferLength
= DEV_BSIZE
*256;
370 deviceExtension
->MaximumDmaTransferLength
= ConfigInfo
->MaximumTransferLength
;
371 //deviceExtension->NumberOfPhysicalBreaks = min(deviceExtension->MaximumDmaTransferLength/PAGE_SIZE+1, ATA_DMA_ENTRIES);
372 deviceExtension
->DmaSegmentLength
= 0x10000;
373 deviceExtension
->DmaSegmentAlignmentMask
= 0xffff;
375 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
376 if(i
!= BMLIST_TERMINATOR
) {
377 DevTypeInfo
= (PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[i
];
380 if(Ata_is_ahci_dev(pciData
)) {
381 KdPrint2((PRINT_PREFIX
" AHCI candidate"));
383 deviceExtension
->NumberChannels
= 0;
384 if(!UniataAhciDetect(HwDeviceExtension
, pciData
, ConfigInfo
)) {
385 KdPrint2((PRINT_PREFIX
" AHCI init failed - not detected\n"));
386 return STATUS_UNSUCCESSFUL
;
388 KdPrint2((PRINT_PREFIX
" unknown AHCI dev, addr %#x ", deviceExtension
->BaseIoAHCI_0
.Addr
));
390 KdPrint2((PRINT_PREFIX
" unknown dev, BM addr %#x ", BaseIoAddressBM
));
392 KdPrint2((PRINT_PREFIX
" MaxTransferMode %#x\n", deviceExtension
->MaxTransferMode
));
394 if(!UniataChipDetectChannels(HwDeviceExtension
, pciData
, DeviceNumber
, ConfigInfo
)) {
395 return STATUS_UNSUCCESSFUL
;
397 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
398 return STATUS_UNSUCCESSFUL
;
400 // DEBUG, we shall return success when AHCI is completly supported
401 //return STATUS_NOT_FOUND;
402 return STATUS_SUCCESS
;
405 static BUSMASTER_CONTROLLER_INFORMATION
const SiSAdapters
[] = {
406 PCI_DEV_HW_SPEC_BM( 1183, 1039, 0x00, ATA_SA150
, "SiS 1183 IDE" , SIS133NEW
),
407 PCI_DEV_HW_SPEC_BM( 1182, 1039, 0x00, ATA_SA150
, "SiS 1182" , SISSATA
| UNIATA_SATA
),
408 PCI_DEV_HW_SPEC_BM( 0183, 1039, 0x00, ATA_SA150
, "SiS 183 RAID" , SISSATA
| UNIATA_SATA
),
409 PCI_DEV_HW_SPEC_BM( 0182, 1039, 0x00, ATA_SA150
, "SiS 182" , SISSATA
| UNIATA_SATA
),
410 PCI_DEV_HW_SPEC_BM( 0181, 1039, 0x00, ATA_SA150
, "SiS 181" , SISSATA
| UNIATA_SATA
),
411 PCI_DEV_HW_SPEC_BM( 0180, 1039, 0x00, ATA_SA150
, "SiS 180" , SISSATA
| UNIATA_SATA
),
412 PCI_DEV_HW_SPEC_BM( 0965, 1039, 0x00, ATA_UDMA6
, "SiS 965" , SIS133NEW
),
413 PCI_DEV_HW_SPEC_BM( 0964, 1039, 0x00, ATA_UDMA6
, "SiS 964" , SIS133NEW
),
414 PCI_DEV_HW_SPEC_BM( 0963, 1039, 0x00, ATA_UDMA6
, "SiS 963" , SIS133NEW
),
415 PCI_DEV_HW_SPEC_BM( 0962, 1039, 0x00, ATA_UDMA6
, "SiS 962" , SIS133NEW
),
417 PCI_DEV_HW_SPEC_BM( 0745, 1039, 0x00, ATA_UDMA5
, "SiS 745" , SIS100NEW
),
418 PCI_DEV_HW_SPEC_BM( 0735, 1039, 0x00, ATA_UDMA5
, "SiS 735" , SIS100NEW
),
419 PCI_DEV_HW_SPEC_BM( 0733, 1039, 0x00, ATA_UDMA5
, "SiS 733" , SIS100NEW
),
420 PCI_DEV_HW_SPEC_BM( 0730, 1039, 0x00, ATA_UDMA5
, "SiS 730" , SIS100OLD
),
422 PCI_DEV_HW_SPEC_BM( 0646, 1039, 0x00, ATA_UDMA6
, "SiS 645DX", SIS133NEW
),
423 /* PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645" , SIS133NEW ),*/
424 /* PCI_DEV_HW_SPEC_BM( 0640, 1039, 0x00, ATA_UDMA4, "SiS 640" , SIS_SOUTH ),*/
425 PCI_DEV_HW_SPEC_BM( 0635, 1039, 0x00, ATA_UDMA5
, "SiS 635" , SIS100NEW
),
426 PCI_DEV_HW_SPEC_BM( 0633, 1039, 0x00, ATA_UDMA5
, "SiS 633" , SIS100NEW
),
427 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x30, ATA_UDMA5
, "SiS 630S" , SIS100OLD
),
428 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA4
, "SiS 630" , SIS66
),
429 PCI_DEV_HW_SPEC_BM( 0620, 1039, 0x00, ATA_UDMA4
, "SiS 620" , SIS66
),
431 PCI_DEV_HW_SPEC_BM( 0550, 1039, 0x00, ATA_UDMA5
, "SiS 550" , SIS66
),
432 PCI_DEV_HW_SPEC_BM( 0540, 1039, 0x00, ATA_UDMA4
, "SiS 540" , SIS66
),
433 PCI_DEV_HW_SPEC_BM( 0530, 1039, 0x00, ATA_UDMA4
, "SiS 530" , SIS66
),
435 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x04, ATA_UDMA6, "SiS 962L" , SIS133OLD ), // ???
436 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, ATA_UDMA6, "SiS 961" , SIS133OLD ),
438 PCI_DEV_HW_SPEC_BM( 5517, 1039, 0x00, ATA_UDMA5
, "SiS 961" , SIS100NEW
| SIS_BASE
),
439 PCI_DEV_HW_SPEC_BM( 5518, 1039, 0x00, ATA_UDMA6
, "SiS 962/3", SIS133NEW
| SIS_BASE
),
440 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0xc2, ATA_UDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
441 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0x00, ATA_WDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
442 PCI_DEV_HW_SPEC_BM( 0601, 1039, 0x00, ATA_UDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
443 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
446 static BUSMASTER_CONTROLLER_INFORMATION
const ViaAdapters
[] = {
447 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x41, ATA_UDMA2
, "VIA 82C586B", VIA33
| 0x00 ),
448 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x40, ATA_UDMA2
, "VIA 82C586B", VIA33
| VIAPRQ
),
449 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x02, ATA_UDMA2
, "VIA 82C586B", VIA33
| 0x00 ),
450 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x00, ATA_WDMA2
, "VIA 82C586" , VIA33
| 0x00 ),
451 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x12, ATA_UDMA4
, "VIA 82C596B", VIA66
| VIACLK
),
452 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x00, ATA_UDMA2
, "VIA 82C596" , VIA33
| 0x00 ),
453 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x40, ATA_UDMA5
, "VIA 82C686B", VIA100
| VIABUG
),
454 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x10, ATA_UDMA4
, "VIA 82C686A", VIA66
| VIACLK
),
455 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x00, ATA_UDMA2
, "VIA 82C686" , VIA33
| 0x00 ),
456 PCI_DEV_HW_SPEC_BM( 8231, 1106, 0x00, ATA_UDMA5
, "VIA 8231" , VIA100
| VIABUG
),
457 PCI_DEV_HW_SPEC_BM( 3074, 1106, 0x00, ATA_UDMA5
, "VIA 8233" , VIA100
| 0x00 ),
458 PCI_DEV_HW_SPEC_BM( 3109, 1106, 0x00, ATA_UDMA5
, "VIA 8233C" , VIA100
| 0x00 ),
459 PCI_DEV_HW_SPEC_BM( 3147, 1106, 0x00, ATA_UDMA6
, "VIA 8233A" , VIA133
| 0x00 ),
460 PCI_DEV_HW_SPEC_BM( 3177, 1106, 0x00, ATA_UDMA6
, "VIA 8235" , VIA133
| 0x00 ),
461 PCI_DEV_HW_SPEC_BM( 3227, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| 0x00 ),
462 PCI_DEV_HW_SPEC_BM( 0591, 1106, 0x00, ATA_UDMA6
, "VIA 8237A" , VIA133
| 0x00 ),
463 // presence of AHCI controller means something about isa-mapped part
464 PCI_DEV_HW_SPEC_BM( 5337, 1106, 0x00, ATA_UDMA6
, "VIA 8237S" , VIA133
| 0x00 ),
465 PCI_DEV_HW_SPEC_BM( 5372, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| 0x00 ),
466 PCI_DEV_HW_SPEC_BM( 7372, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| 0x00 ),
467 PCI_DEV_HW_SPEC_BM( 3349, 1106, 0x00, ATA_UDMA6
, "VIA 8251" , VIA133
| 0x00 ),
468 PCI_DEV_HW_SPEC_BM( 8324, 1106, 0x00, ATA_SA150
, "VIA CX700" , VIA133
| VIASATA
),
469 PCI_DEV_HW_SPEC_BM( 8353, 1106, 0x00, ATA_SA150
, "VIA VX800" , VIA133
| VIASATA
),
470 PCI_DEV_HW_SPEC_BM( 8409, 1106, 0x00, ATA_UDMA6
, "VIA VX855" , VIA133
| 0x00 ),
471 PCI_DEV_HW_SPEC_BM( 8410, 1106, 0x00, ATA_SA300
, "VIA VX900" , VIA133
| VIASATA
),
472 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
475 static BUSMASTER_CONTROLLER_INFORMATION
const ViaSouthAdapters
[] = {
476 PCI_DEV_HW_SPEC_BM( 3112, 1106, 0x00, ATA_MODE_NOT_SPEC
, "VIA 8361", VIASOUTH
),
477 PCI_DEV_HW_SPEC_BM( 0305, 1106, 0x00, ATA_MODE_NOT_SPEC
, "VIA 8363", VIASOUTH
),
478 PCI_DEV_HW_SPEC_BM( 0391, 1106, 0x00, ATA_MODE_NOT_SPEC
, "VIA 8371", VIASOUTH
),
479 PCI_DEV_HW_SPEC_BM( 3102, 1106, 0x00, ATA_MODE_NOT_SPEC
, "VIA 8662", VIASOUTH
),
480 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
483 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
489 We shall get here for all SIS controllers, even unlisted.
490 Then perform bus scan to find SIS bridge and decide what to do with controller
492 KdPrint2((PRINT_PREFIX
"ATA_SIS_ID\n"));
493 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&SiSAdapters
[0];
494 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, NULL
);
495 if(i
!= BMLIST_TERMINATOR
) {
496 deviceExtension
->FullDevName
= SiSAdapters
[i
].FullDevName
;
501 KdPrint2((PRINT_PREFIX
"ATA_VIA_ID\n"));
502 // New chips have own DeviceId
503 if(deviceExtension
->DevID
!= ATA_VIA82C571
&&
504 deviceExtension
->DevID
!= ATA_VIACX700IDE
&&
505 deviceExtension
->DevID
!= ATA_VIASATAIDE
&&
506 deviceExtension
->DevID
!= ATA_VIASATAIDE2
&&
507 deviceExtension
->DevID
!= ATA_VIASATAIDE3
) {
508 KdPrint2((PRINT_PREFIX
"Via new\n"));
511 KdPrint2((PRINT_PREFIX
"Via-old-style %x\n", deviceExtension
->DevID
));
512 // Traditionally, chips have same DeviceId, we can distinguish between them
513 // only by ISA Bridge DeviceId
514 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&ViaSouthAdapters
[0];
515 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
,
516 PCISLOTNUM_NOT_SPECIFIED
/*slotNumber*/, NULL
);
517 /* if(i == BMLIST_TERMINATOR) {
518 i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL);
520 if(i
!= BMLIST_TERMINATOR
) {
521 KdPrint2((PRINT_PREFIX
"VIASOUTH\n"));
522 deviceExtension
->HwFlags
|= VIASOUTH
;
524 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&ViaAdapters
[0];
525 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
,
526 PCISLOTNUM_NOT_SPECIFIED
/*slotNumber*/, NULL
);
527 if(i
!= BMLIST_TERMINATOR
) {
528 deviceExtension
->FullDevName
= ViaAdapters
[i
].FullDevName
;
538 KdPrint2((PRINT_PREFIX
"Default\n"));
540 deviceExtension
->MaxTransferMode
= deviceExtension
->BaseIoAddressBM_0
? ATA_DMA
: ATA_PIO4
;
541 /* do extra chipset specific setups */
542 switch(deviceExtension
->DevID
) {
544 //case ATA_CYPRESS_ID:
545 case 0xc6931080: /* 82c693 ATA controller */
546 deviceExtension
->MaxTransferMode
= ATA_WDMA2
;
549 case 0x000116ca: /* Cenatek Rocket Drive controller */
550 deviceExtension
->MaxTransferMode
= ATA_WDMA2
;
553 /* case ATA_CYRIX_ID:
554 DevTypeInfo = &CyrixAdapters[0];
556 case 0x01021078: /* Cyrix 5530 ATA33 controller */
557 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
560 case 0x06401039: /* CMD 640 known bad, no DMA */
566 case 0x10001042: /* RZ 100x known bad, no DMA */
569 if(deviceExtension
->BaseIoAddressBM_0
)
570 ScsiPortFreeDeviceBase(HwDeviceExtension
,
571 deviceExtension
->BaseIoAddressBM_0
);
573 deviceExtension
->BaseIoAddressBM_0
.Addr
= 0;
574 deviceExtension
->BaseIoAddressBM_0
.MemIo
= 0;
575 deviceExtension
->BusMaster
= DMA_MODE_NONE
;
576 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
579 case 0x81721283: /* IT8172 IDE controller */
580 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
585 return STATUS_NOT_FOUND
;
587 return STATUS_SUCCESS
;
591 i
= Ata_is_dev_listed(DevTypeInfo
, VendorID
, DeviceID
, RevID
, -1);
593 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
594 if(i
== BMLIST_TERMINATOR
) {
596 //return STATUS_NOT_FOUND;
598 deviceExtension
->MaxTransferMode
= DevTypeInfo
[i
].MaxTransferMode
;
599 deviceExtension
->HwFlags
|= DevTypeInfo
[i
].RaidFlags
;
601 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
603 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsOverride", deviceExtension
->HwFlags
);
604 KdPrint2((PRINT_PREFIX
"HwFlagsOverride: %#x\n", tmp32
));
605 deviceExtension
->HwFlags
= tmp32
;
607 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsAdd", 0);
608 KdPrint2((PRINT_PREFIX
"HwFlagsAdd: %#x\n", tmp32
));
609 deviceExtension
->HwFlags
|= tmp32
;
611 KdPrint2((PRINT_PREFIX
"HwFlags (final): %#x\n", deviceExtension
->HwFlags
));
612 if(deviceExtension
->HwFlags
& UNIATA_SIMPLEX_ONLY
) {
613 KdPrint2((PRINT_PREFIX
"UNIATA_SIMPLEX_ONLY\n" ));
617 KdPrint2((PRINT_PREFIX
"MaxTransferMode: %#x\n", deviceExtension
->MaxTransferMode
));
618 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", deviceExtension
->MaxTransferMode
);
619 if(tmp32
!= 0xffffffff) {
620 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", deviceExtension
->MaxTransferMode
));
621 deviceExtension
->MaxTransferMode
= tmp32
;
624 if(deviceExtension
->MaxTransferMode
>= ATA_SA150
) {
625 deviceExtension
->HwFlags
|= UNIATA_SATA
;
629 ConfigInfo->MaximumTransferLength = DEV_BSIZE*256;
630 deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
632 ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
633 ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
635 /* for even more ugly AHCI-capable chips */
636 if(ChipFlags
& UNIATA_AHCI
) {
638 Seems, some chips may have inoperable/alternative BAR5 in SATA mode
639 This can be detected via PCI SubClass
644 KdPrint2((PRINT_PREFIX
"ATA_xxx_ID check AHCI subclass\n"));
645 if((pciData
)->SubClass
== PCI_DEV_SUBCLASS_IDE
) {
646 KdPrint2((PRINT_PREFIX
"Non-AHCI mode\n"));
647 ChipFlags
&= ~UNIATA_AHCI
;
648 deviceExtension
->HwFlags
&= ~UNIATA_AHCI
;
654 if(ChipFlags
& UNIATA_AHCI
) {
655 deviceExtension
->NumberChannels
= 0;
656 if(!UniataAhciDetect(HwDeviceExtension
, pciData
, ConfigInfo
)) {
657 KdPrint2((PRINT_PREFIX
" AHCI detect failed\n"));
658 return STATUS_UNSUCCESSFUL
;
661 if(!UniataChipDetectChannels(HwDeviceExtension
, pciData
, DeviceNumber
, ConfigInfo
)) {
662 return STATUS_UNSUCCESSFUL
;
664 // UniataAhciDetect() sets proper number of channels
665 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
666 return STATUS_UNSUCCESSFUL
;
670 case ATA_ACER_LABS_ID
:
671 if(ChipFlags
& UNIATA_SATA
) {
672 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
673 BaseIoAddress1
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
675 BaseIoAddress2
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
677 BaseIoAddressBM
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
678 4, 0, deviceExtension
->NumberChannels
*sizeof(IDE_BUSMASTER_REGISTERS
));
679 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
680 //ULONG unit01 = (c & 1);
681 ULONG unit10
= (c
& 2);
682 chan
= &deviceExtension
->chan
[c
];
684 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
685 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
+ i
+ (unit10
? 8 : 0);
687 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIoAddress2
+ 2 + (unit10
? 4 : 0);
688 UniataInitSyncBaseIO(chan
);
690 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
691 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM
+ i
+ (c
* sizeof(IDE_BUSMASTER_REGISTERS
));
694 // SATA not supported yet
696 //chan->RegTranslation[IDX_BM_Command] = BaseMemAddress + 0x260 + offs7;
697 //chan->RegTranslation[IDX_BM_PRD_Table] = BaseMemAddress + 0x244 + offs7;
698 //chan->RegTranslation[IDX_BM_DeviceSpecific0] = BaseMemAddress + (c << 2);
700 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
705 if(ChipFlags
& UNIATA_SATA
) {
706 KdPrint2((PRINT_PREFIX
"NVIDIA SATA\n"));
707 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
708 5, 0, ((ChipFlags
& NV4OFF
) ? 0x400 : 0) + 0x40*2);
709 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
710 if(!BaseMemAddress
) {
711 return STATUS_UNSUCCESSFUL
;
713 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
714 KdPrint2((PRINT_PREFIX
"MemIo\n"));
717 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
718 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
719 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
720 chan
= &deviceExtension
->chan
[c
];
722 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
<< 6);
723 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
724 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
<< 6);
725 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
726 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
<< 6);
727 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
729 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
735 if(ChipType
!= PRMIO
) {
741 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
744 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
746 KdPrint2((PRINT_PREFIX
"BaseMemAddress[4] %x\n", BaseMemAddress
));
747 if(!BaseMemAddress
) {
748 return STATUS_UNSUCCESSFUL
;
750 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
751 KdPrint2((PRINT_PREFIX
"MemIo\n"));
754 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
755 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
758 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
760 KdPrint2((PRINT_PREFIX
"BaseMemAddress[3] %x\n", BaseMemAddress
));
761 if(!BaseMemAddress
) {
762 return STATUS_UNSUCCESSFUL
;
764 if((*ConfigInfo
->AccessRanges
)[3].RangeInMemory
) {
765 KdPrint2((PRINT_PREFIX
"MemIo\n"));
768 deviceExtension
->BaseIoAddressBM_0
.Addr
= BaseMemAddress
;
769 deviceExtension
->BaseIoAddressBM_0
.MemIo
= MemIo
;
771 if(!(ChipFlags
& UNIATA_SATA
)) {
774 reg48
= AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
775 deviceExtension
->NumberChannels
= ((reg48
& 0x01) ? 1 : 0) +
776 ((reg48
& 0x02) ? 1 : 0) +
778 KdPrint2((PRINT_PREFIX
"Channels -> %d\n", deviceExtension
->NumberChannels
));
781 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
786 chan
= &deviceExtension
->chan
[c
];
791 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
792 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x200 + (i
<< 2) + offs7
;
793 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
795 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x238 + offs7
;
796 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
798 UniataInitSyncBaseIO(chan
);
800 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x260 + offs7
;
801 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
802 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x244 + offs7
;
803 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
804 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ (c
<< 2);
805 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
807 if((ChipFlags
& PRSATA
) ||
808 ((ChipFlags
& PRCMBO
) && c
<2)) {
809 KdPrint2((PRINT_PREFIX
"Promise SATA\n"));
811 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x400 + offs7
;
812 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
813 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x404 + offs7
;
814 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
815 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x408 + offs7
;
816 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
818 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
820 KdPrint2((PRINT_PREFIX
"Promise PATA\n"));
821 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA6
);
827 KdPrint2((PRINT_PREFIX
"ATI\n"));
828 if(ChipType
== ATI700
) {
829 KdPrint2((PRINT_PREFIX
"ATI700\n"));
830 if(!(ChipFlags
& UNIATA_AHCI
)) {
831 KdPrint2((PRINT_PREFIX
"IXP700 PATA\n"));
832 chan
= &deviceExtension
->chan
[0];
833 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
838 case ATA_SILICON_IMAGE_ID
: {
840 if(ChipFlags
& SIIBUG
) {
842 if(ChipType
!= SIIMIO
) {
849 if(VendorID
== ATA_SILICON_IMAGE_ID
) {
850 KdPrint2((PRINT_PREFIX
"New SII\n"));
852 KdPrint2((PRINT_PREFIX
"ATI SATA\n"));
854 //if(deviceExtension->HwFlags & SII4CH) {
855 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
857 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
859 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
860 if(!BaseMemAddress
) {
861 return STATUS_UNSUCCESSFUL
;
863 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
864 KdPrint2((PRINT_PREFIX
"MemIo\n"));
867 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
868 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
870 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
871 ULONG unit01
= (c
& 1);
872 ULONG unit10
= (c
& 2);
874 chan
= &deviceExtension
->chan
[c
];
876 if(deviceExtension
->AltRegMap
) {
877 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
878 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x80 + i
+ (unit01
<< 6) + (unit10
<< 8);
879 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
881 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x8a + (unit01
<< 6) + (unit10
<< 8);
882 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
883 UniataInitSyncBaseIO(chan
);
885 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x00 + (unit01
<< 3) + (unit10
<< 8);
886 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
887 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ 0x02 + (unit01
<< 3) + (unit10
<< 8);
888 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
889 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x04 + (unit01
<< 3) + (unit10
<< 8);
890 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
891 //chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr = BaseMemAddress + 0xa1 + (unit01 << 6) + (unit10 << 8);
892 //chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo;
893 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ 0x10 + (unit01
<< 3) + (unit10
<< 8);
894 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
895 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].Addr
= BaseMemAddress
+ 0x40 + (unit01
<< 2) + (unit10
<< 8);
896 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].MemIo
= MemIo
;
899 if(chan
->MaxTransferMode
< ATA_SA150
) {
900 // do nothing for PATA part
901 KdPrint2((PRINT_PREFIX
"No SATA regs for PATA part\n"));
903 if(ChipFlags
& UNIATA_SATA
) {
904 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x104 + (unit01
<< 7) + (unit10
<< 8);
905 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
906 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x108 + (unit01
<< 7) + (unit10
<< 8);
907 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
908 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x100 + (unit01
<< 7) + (unit10
<< 8);
909 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
911 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
916 case ATA_SERVERWORKS_ID
: {
918 if(ChipType
!= SWKSMIO
) {
925 KdPrint2((PRINT_PREFIX
"ServerWorks\n"));
927 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
928 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
930 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
931 if(!BaseMemAddress
) {
932 return STATUS_UNSUCCESSFUL
;
934 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
935 KdPrint2((PRINT_PREFIX
"MemIo\n"));
938 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
939 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
941 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
942 ULONG offs
= c
*0x100;
944 chan
= &deviceExtension
->chan
[c
];
945 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
946 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ offs
+ i
*4;
947 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
949 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ offs
+ 0x20;
950 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
951 UniataInitSyncBaseIO(chan
);
953 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x30;
954 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
955 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x32;
956 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
957 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x34;
958 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
960 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ offs
+ 0x40;
961 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
962 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ offs
+ 0x44;
963 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
964 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ offs
+ 0x48;
965 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
967 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
972 //if(ChipType != SIS_SOUTH) {}
973 BOOLEAN SIS_182
=FALSE
;
975 if(!(ChipFlags
& SIS_BASE
)) {
976 KdPrint2((PRINT_PREFIX
"Found SIS_SOUTH\n"));
977 //PrintNtConsole("Found SIS_SOUTH\n");
980 // Make some additional checks
981 KdPrint2((PRINT_PREFIX
"ChipType == SIS_BASE\n"));
982 ChangePciConfig1(0x57, (a
& 0x7f));
983 GetPciConfig4(0x00, tmp32
);
984 if(tmp32
== ATA_SIS5518
) {
985 ChipType
= SIS133NEW
;
986 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133NEW
;
987 deviceExtension
->MaxTransferMode
= ATA_UDMA6
;
988 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
989 //PrintNtConsole("UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension->MaxTransferMode);
991 ChangePciConfig1(0x57, (a
| 0x80));
993 static BUSMASTER_CONTROLLER_INFORMATION
const SiSSouthAdapters
[] = {
994 PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x10, ATA_MODE_NOT_SPEC
, "SiS 961", 0 ),
995 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, ATA_MODE_NOT_SPEC, "SiS 961", 0 ),
996 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, ATA_MODE_NOT_SPEC
, NULL
, -1 )
999 GetPciConfig1(0x4a, tmp8
);
1000 ChangePciConfig1(0x4a, (a
| 0x10));
1001 if(tmp32
== ATA_SIS5513
||
1002 tmp32
== ATA_SIS5517
) {
1003 i
= AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION
*)&SiSSouthAdapters
[0],
1004 -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, NULL
);
1005 if(i
!= BMLIST_TERMINATOR
) {
1006 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133OLD
;
1007 deviceExtension
->MaxTransferMode
= ATA_UDMA6
;
1008 //deviceExtension->MaxTransferMode = SiSSouthAdapters[i].MaxTransferMode;
1009 if(SiSSouthAdapters
[i
].RaidFlags
& UNIATA_SATA
) {
1010 deviceExtension
->HwFlags
|= UNIATA_SATA
;
1011 if(SiSSouthAdapters
[i
].nDeviceId
== 0x1182 ||
1012 SiSSouthAdapters
[i
].nDeviceId
== 0x1183) {
1017 // SiS-South not found
1018 if(tmp32
== ATA_SIS5517
) {
1019 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS100NEW
;
1020 deviceExtension
->MaxTransferMode
= ATA_UDMA5
;
1023 KdPrint2((PRINT_PREFIX
"Generic SiS DMA\n"));
1028 SetPciConfig1(0x4a, tmp8
);
1029 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
1030 //PrintNtConsole("UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension->MaxTransferMode);
1031 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
1032 KdPrint2((PRINT_PREFIX
"SiS SATA\n"));
1034 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
1036 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
1037 if(BaseMemAddress
) {
1038 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
1039 KdPrint2((PRINT_PREFIX
"MemIo\n"));
1042 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
1043 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
1045 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1046 ULONG offs
= c
<< (SIS_182
? 5 : 6);
1048 chan
= &deviceExtension
->chan
[c
];
1049 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0 + offs
;
1050 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
1051 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + offs
;
1052 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
1053 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + offs
;
1054 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
1056 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1061 //ChangePciConfig1(0x57, (a | 0x80));
1066 if(ChipFlags
& VIASATA
) {
1067 /* 2 SATA without SATA registers on first channel + 1 PATA on second */
1068 // do nothing, generic PATA INIT
1069 KdPrint2((PRINT_PREFIX
"VIA SATA without SATA regs\n"));
1072 if(ChipFlags
& UNIATA_SATA
) {
1075 ULONG BaseMemAddress
= 0;
1078 case 0x3149: // VIA 6420
1079 KdPrint2((PRINT_PREFIX
"VIA 6420\n"));
1082 case 0x3249: // VIA 6421
1083 KdPrint2((PRINT_PREFIX
"VIA 6421\n"));
1088 KdPrint2((PRINT_PREFIX
"IoSize %x\n", IoSize
));
1089 /*deviceExtension->*/BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
1090 5, 0, IoSize
* deviceExtension
->NumberChannels
);
1091 if(BaseMemAddress
&& (*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
1092 KdPrint2((PRINT_PREFIX
"MemIo\n"));
1095 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
1096 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
1098 if(/*deviceExtension->*/BaseMemAddress
) {
1099 KdPrint2((PRINT_PREFIX
"UniataChipDetect: BAR5 %x\n", /*deviceExtension->*/BaseMemAddress
));
1100 if(ChipFlags
& VIABAR
) {
1102 ULONG BaseIoAddressBM_0
;
1105 KdPrint2((PRINT_PREFIX
"UniataChipDetect: VIABAR\n"));
1106 /*deviceExtension->*/BaseIoAddressBM_0
= /*(PIDE_BUSMASTER_REGISTERS)*/
1107 AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, 4, 0,
1108 sizeof(IDE_BUSMASTER_REGISTERS
)*deviceExtension
->NumberChannels
);
1109 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
1110 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1112 chan
= &deviceExtension
->chan
[c
];
1114 BaseIo
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, c
, 0, /*0x80*/ sizeof(IDE_REGISTERS_1
) + sizeof(IDE_REGISTERS_2
)*2);
1116 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
1117 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIo
+ i
;
1119 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIo
+ sizeof(IDE_REGISTERS_1
) + 2;
1120 UniataInitSyncBaseIO(chan
);
1122 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
1123 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
+ sizeof(IDE_BUSMASTER_REGISTERS
)*c
+ i
;
1128 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1129 chan
= &deviceExtension
->chan
[c
];
1130 if((ChipFlags
& VIABAR
) && (c
==2)) {
1131 // Do not setup SATA registers for PATA part
1132 for (i
=0; i
<=IDX_SATA_IO_SZ
; i
++) {
1133 chan
->RegTranslation
[IDX_SATA_IO
+i
].Addr
= 0;
1134 chan
->RegTranslation
[IDX_SATA_IO
+i
].MemIo
= 0;
1138 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
* IoSize
);
1139 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
1140 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
* IoSize
);
1141 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
1142 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
* IoSize
);
1143 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
1145 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1151 case ATA_INTEL_ID
: {
1153 if(!(ChipFlags
& UNIATA_SATA
)) {
1157 /* the intel 31244 needs special care if in DPA mode */
1158 if(DeviceID
== 3200 && // Intel 31244
1159 pciData
->SubClass
!= PCI_DEV_SUBCLASS_IDE
) {
1161 KdPrint2((PRINT_PREFIX
"UniataChipDetect: Intel 31244, DPA mode\n"));
1162 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
1164 if(!BaseMemAddress
) {
1165 return STATUS_UNSUCCESSFUL
;
1167 if((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
) {
1168 KdPrint2((PRINT_PREFIX
"MemIo\n"));
1171 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
1172 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
1173 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
1175 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1176 ULONG offs
= 0x200 + c
*0x200;
1178 chan
= &deviceExtension
->chan
[c
];
1179 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
1180 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
1181 chan
->RegTranslation
[IDX_IO1_o
+i
].MemIo
= MemIo
;
1184 chan
->RegTranslation
[IDX_IO1_i_Data
].Addr
= BaseMemAddress
+ 0x00 + offs
;
1185 chan
->RegTranslation
[IDX_IO1_i_Error
].Addr
= BaseMemAddress
+ 0x04 + offs
;
1186 chan
->RegTranslation
[IDX_IO1_i_BlockCount
].Addr
= BaseMemAddress
+ 0x08 + offs
;
1187 chan
->RegTranslation
[IDX_IO1_i_BlockNumber
].Addr
= BaseMemAddress
+ 0x0c + offs
;
1188 chan
->RegTranslation
[IDX_IO1_i_CylinderLow
].Addr
= BaseMemAddress
+ 0x10 + offs
;
1189 chan
->RegTranslation
[IDX_IO1_i_CylinderHigh
].Addr
= BaseMemAddress
+ 0x14 + offs
;
1190 chan
->RegTranslation
[IDX_IO1_i_DriveSelect
].Addr
= BaseMemAddress
+ 0x18 + offs
;
1191 chan
->RegTranslation
[IDX_IO1_i_Status
].Addr
= BaseMemAddress
+ 0x1c + offs
;
1193 UniataInitSyncBaseIO(chan
);
1195 chan
->RegTranslation
[IDX_IO1_o_Command
].Addr
= BaseMemAddress
+ 0x1d + offs
;
1196 chan
->RegTranslation
[IDX_IO1_o_Feature
].Addr
= BaseMemAddress
+ 0x06 + offs
;
1197 chan
->RegTranslation
[IDX_IO2_o_Control
].Addr
= BaseMemAddress
+ 0x29 + offs
;
1199 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x28 + offs
;
1200 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
1202 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x70;
1203 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
1204 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x72;
1205 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
1206 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x74;
1207 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
1209 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x100 + offs
;
1210 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
1211 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x104 + offs
;
1212 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
1213 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x108 + offs
;
1214 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
1216 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1221 if(deviceExtension
->MaxTransferMode
>= ATA_SA150
) {
1223 BOOLEAN OrigAHCI
= FALSE
;
1225 GetPciConfig1(0x90, tmp8
);
1226 KdPrint2((PRINT_PREFIX
"Intel chip config: %x\n", tmp8
));
1227 /* SATA parts can be either compat or AHCI */
1229 if(ChipFlags
& UNIATA_AHCI
) {
1232 //KdPrint2((PRINT_PREFIX "AHCI not supported yet\n"));
1234 KdPrint2((PRINT_PREFIX
"try run AHCI\n"));
1237 BaseIoAddressBM
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
1238 4, 0, sizeof(IDE_BUSMASTER_REGISTERS
));
1239 if(BaseIoAddressBM
) {
1240 KdPrint2((PRINT_PREFIX
"Intel BM check at %x\n", BaseIoAddressBM
));
1241 /* check if we really have valid BM registers */
1242 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
1243 KdPrint2((PRINT_PREFIX
"MemIo[4]\n"));
1246 deviceExtension
->BaseIoAddressBM_0
.Addr
= BaseIoAddressBM
;
1247 deviceExtension
->BaseIoAddressBM_0
.MemIo
= MemIo
;
1249 tmp8
= AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),IDX_BM_Status
);
1250 KdPrint2((PRINT_PREFIX
"BM status: %x\n", tmp8
));
1252 ScsiPortFreeDeviceBase(HwDeviceExtension
, (PCHAR
)BaseIoAddressBM
);
1253 deviceExtension
->BaseIoAddressBM_0
.Addr
= 0;
1254 deviceExtension
->BaseIoAddressBM_0
.MemIo
= 0;
1257 KdPrint2((PRINT_PREFIX
"invalid BM status, keep AHCI mode\n"));
1261 KdPrint2((PRINT_PREFIX
"Compatible mode, reallocate LUNs\n"));
1262 deviceExtension
->NumberLuns
= 2; // we may be in Legacy mode
1263 if(!UniataAllocateLunExt(deviceExtension
, 2)) {
1264 KdPrint2((PRINT_PREFIX
"can't re-allocate Luns\n"));
1265 return STATUS_UNSUCCESSFUL
;
1268 deviceExtension
->HwFlags
&= ~UNIATA_AHCI
;
1271 /* if BAR(5) is IO it should point to SATA interface registers */
1273 /* Skip BAR(5) in compatible mode */
1274 KdPrint2((PRINT_PREFIX
"Ignore BAR5 on compatible\n"));
1277 if(deviceExtension
->DevID
== 0x28288086 &&
1278 pciData
->u
.type0
.SubVendorID
== 0x106b) {
1279 /* Skip BAR(5) on ICH8M Apples, system locks up on access. */
1280 KdPrint2((PRINT_PREFIX
"Ignore BAR5 on ICH8M Apples\n"));
1283 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
1285 if(BaseMemAddress
&& (*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
1286 KdPrint2((PRINT_PREFIX
"MemIo[5]\n"));
1290 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
1291 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
1293 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1294 chan
= &deviceExtension
->chan
[c
];
1296 if(ChipFlags
& ICH5
) {
1297 KdPrint2((PRINT_PREFIX
"ICH5\n"));
1298 if ((tmp8
& 0x04) == 0) {
1299 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1300 } else if ((tmp8
& 0x02) == 0) {
1303 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1305 } else if ((tmp8
& 0x02) != 0) {
1308 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1312 if(ChipFlags
& I6CH2
) {
1313 KdPrint2((PRINT_PREFIX
"I6CH2\n"));
1314 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1316 KdPrint2((PRINT_PREFIX
"other Intel\n"));
1317 switch(tmp8
& 0x03) {
1334 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
1335 KdPrint2((PRINT_PREFIX
"PATA part\n"));
1338 if(!(ChipFlags
& ICH7
) && BaseMemAddress
) {
1339 KdPrint2((PRINT_PREFIX
"BaseMemAddress[5] -> indexed\n"));
1340 chan
->RegTranslation
[IDX_INDEXED_ADDR
].Addr
= BaseMemAddress
+ 0;
1341 chan
->RegTranslation
[IDX_INDEXED_ADDR
].MemIo
= MemIo
;
1342 chan
->RegTranslation
[IDX_INDEXED_DATA
].Addr
= BaseMemAddress
+ 4;
1343 chan
->RegTranslation
[IDX_INDEXED_DATA
].MemIo
= MemIo
;
1345 if((ChipFlags
& ICH5
) || BaseMemAddress
) {
1347 KdPrint2((PRINT_PREFIX
"io proc()\n"));
1348 // Rather interesting way of register access...
1349 ChipType
= INTEL_IDX
;
1350 deviceExtension
->HwFlags
&= ~CHIPTYPE_MASK
;
1351 deviceExtension
->HwFlags
|= ChipType
;
1353 if(ChipFlags
& ICH7
) {
1354 KdPrint2((PRINT_PREFIX
"ICH7 way\n"));
1356 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= 0x200*c
+ 0; // this is fake non-zero value
1357 chan
->RegTranslation
[IDX_SATA_SStatus
].Proc
= 1;
1358 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= 0x200*c
+ 2; // this is fake non-zero value
1359 chan
->RegTranslation
[IDX_SATA_SError
].Proc
= 1;
1360 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= 0x200*c
+ 1; // this is fake non-zero value
1361 chan
->RegTranslation
[IDX_SATA_SControl
].Proc
= 1;
1367 // rest of INIT staff is in AtapiChipInit()
1372 /* Cyrix 5530 ATA33 controller */
1373 if(deviceExtension
->DevID
== 0x01021078) {
1374 ConfigInfo
->AlignmentMask
= 0x0f;
1375 deviceExtension
->MaximumDmaTransferLength
= 63*1024;
1378 case ATA_JMICRON_ID
:
1379 /* New JMicron PATA controllers */
1380 GetPciConfig1(0xdf, tmp8
);
1382 KdPrint((" Check JMicron AHCI\n"));
1383 if(Ata_is_ahci_dev(pciData
)) {
1384 ChipFlags
|= UNIATA_AHCI
;
1385 deviceExtension
->HwFlags
|= UNIATA_AHCI
;
1387 KdPrint((" JMicron PATA\n"));
1390 /* set controller configuration to a combined setup we support */
1391 SetPciConfig4(0x40, 0x80c0a131);
1392 SetPciConfig4(0x80, 0x01200000);
1393 //KdPrint((" JMicron Combined (not supported yet)\n"));
1394 //return STATUS_NOT_FOUND;
1399 return STATUS_SUCCESS
;
1401 } // end UniataChipDetect()
1405 Do some 'magic staff' for VIA SouthBridge
1406 This will prevent data losses
1410 AtapiViaSouthBridgeFixup(
1411 IN PVOID HwDeviceExtension
,
1412 IN BUS_DATA_TYPE BusDataType
,
1413 IN ULONG SystemIoBusNumber
,
1417 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1418 PCI_COMMON_CONFIG pciData
;
1424 PCI_SLOT_NUMBER slotData
;
1426 BOOLEAN found
= FALSE
;
1428 slotData
.u
.AsULONG
= slotNumber
;
1429 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1431 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1433 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1438 PCI_COMMON_HDR_LENGTH
);
1440 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1444 VendorID
= pciData
.VendorID
;
1445 DeviceID
= pciData
.DeviceID
;
1446 dev_id
= (VendorID
| (DeviceID
<< 16));
1448 if (dev_id
== 0x03051106 || /* VIA VT8363 */
1449 dev_id
== 0x03911106 || /* VIA VT8371 */
1450 dev_id
== 0x31021106 || /* VIA VT8662 */
1451 dev_id
== 0x31121106) { /* VIA VT8361 */
1454 GetPciConfig1(0x76, reg76
);
1456 if ((reg76
& 0xf0) != 0xd0) {
1457 SetPciConfig1(0x75, 0x80);
1458 SetPciConfig1(0x76, (reg76
& 0x0f) | 0xd0);
1465 deviceExtension
->HwFlags
&= ~VIABUG
;
1467 } // end AtapiViaSouthBridgeFixup()
1470 Do some 'magic staff' for ROSB SouthBridge
1471 This will prevent data losses
1475 AtapiRosbSouthBridgeFixup(
1476 IN PVOID HwDeviceExtension
,
1477 IN BUS_DATA_TYPE BusDataType
,
1478 IN ULONG SystemIoBusNumber
,
1482 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1483 PCI_COMMON_CONFIG pciData
;
1489 PCI_SLOT_NUMBER slotData
;
1491 // BOOLEAN found = FALSE;
1493 /* locate the ISA part in the southbridge and enable UDMA33 */
1494 slotData
.u
.AsULONG
= slotNumber
;
1495 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1497 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1499 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1504 PCI_COMMON_HDR_LENGTH
);
1506 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1510 VendorID
= pciData
.VendorID
;
1511 DeviceID
= pciData
.DeviceID
;
1512 dev_id
= (VendorID
| (DeviceID
<< 16));
1514 if (dev_id
== ATA_ROSB4_ISA
) { /* */
1515 ChangePciConfig4(0x64, ((a
& ~0x00002000) | 0x00004000));
1519 } // end AtapiRosbSouthBridgeFixup()
1522 Do some 'magic staff' for ROSB SouthBridge
1523 This will prevent data losses
1527 AtapiAliSouthBridgeFixup(
1528 IN PVOID HwDeviceExtension
,
1529 IN BUS_DATA_TYPE BusDataType
,
1530 IN ULONG SystemIoBusNumber
,
1531 IN ULONG slotNumber
,
1535 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1536 PCI_COMMON_CONFIG pciData
;
1542 PCI_SLOT_NUMBER slotData
;
1544 // BOOLEAN found = FALSE;
1546 /* workaround for datacorruption bug found on at least SUN Blade-100
1547 * find the ISA function on the southbridge and disable then enable
1548 * the ATA channel tristate buffer */
1549 slotData
.u
.AsULONG
= slotNumber
;
1550 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1552 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1554 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1559 PCI_COMMON_HDR_LENGTH
);
1561 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1565 VendorID
= pciData
.VendorID
;
1566 DeviceID
= pciData
.DeviceID
;
1567 dev_id
= (VendorID
| (DeviceID
<< 16));
1569 if (dev_id
== ATA_ALI_1533
) { /* SOUTH */
1570 ChangePciConfig1(0x58, (a
& ~(0x04 << c
)));
1571 ChangePciConfig1(0x58, (a
| (0x04 << c
)));
1575 } // end AtapiRosbSouthBridgeFixup()
1580 IN PHW_DEVICE_EXTENSION deviceExtension
,
1581 IN ULONG channel
// physical channel number (0-1)
1584 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1585 ULONG slotNumber
= deviceExtension
->slotNumber
;
1586 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1588 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1590 UCHAR reg
, val
, res
;
1591 PCI_SLOT_NUMBER slotData
;
1594 ULONG c
; // logical channel (for Compatible Mode controllers)
1596 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1597 chan
= &deviceExtension
->chan
[c
];
1599 slotData
.u
.AsULONG
= deviceExtension
->slotNumber
;
1601 if(deviceExtension
->HwFlags
& UNIATA_NO80CHK
) {
1602 KdPrint2((PRINT_PREFIX
"UNIATA_NO80CHK\n"));
1606 if(ChipType
== HPT374
&& slotData
.u
.bits
.FunctionNumber
== 1) {
1607 reg
= channel
? 0x57 : 0x53;
1608 GetPciConfig1(reg
, val
);
1609 SetPciConfig1(reg
, val
| 0x80);
1613 GetPciConfig1(reg
, val
);
1614 SetPciConfig1(reg
, val
& 0xfe);
1616 GetPciConfig1(0x5a, res
);
1617 res
= res
& (channel
? 0x01 : 0x02);
1618 SetPciConfig1(reg
, val
);
1619 if(chan
->Force80pin
) {
1620 KdPrint2((PRINT_PREFIX
"Force80pin\n"));
1623 KdPrint2((PRINT_PREFIX
"hpt_cable80(%d) = %d\n", channel
, !res
));
1625 } // end hpt_cable80()
1631 IN PHW_DEVICE_EXTENSION deviceExtension,
1632 IN ULONG channel // physical channel number (0-1)
1635 PVOID HwDeviceExtension = (PVOID)deviceExtension;
1636 ULONG slotNumber = deviceExtension->slotNumber;
1637 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
1639 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1646 GetPciConfig1(0x50, reg50);
1663 for (j=0; j>=2; i -= 8) {
1664 i = (3-(channel*2+j))*8;
1665 if (((reg50 >> (i & 0x10)) & 8) &&
1666 ((reg50 >> i) & 0x20) &&
1667 (((reg50 >> i) & 7) < a)) {
1669 res |= TRUE; //(1 << (1 - (i >> 4)));
1672 KdPrint2((PRINT_PREFIX "via_cable80(%d) = %d\n", channel, res));
1675 } // end via_cable80()
1681 IN PHW_DEVICE_EXTENSION deviceExtension
,
1682 IN ULONG channel
, // physical channel number (0-1)
1687 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1688 ULONG slotNumber
= deviceExtension
->slotNumber
;
1689 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1691 if(deviceExtension
->MaxTransferMode
<= ATA_UDMA2
) {
1692 KdPrint2((PRINT_PREFIX
"generic_cable80(%d, %#x, %d) <= UDMA2\n", channel
, pci_reg
, bit_offs
));
1696 //ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1698 ULONG c
; // logical channel (for Compatible Mode controllers)
1701 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1702 chan
= &deviceExtension
->chan
[c
];
1704 if(chan
->Force80pin
) {
1705 KdPrint2((PRINT_PREFIX
"Force80pin\n"));
1709 GetPciConfig1(pci_reg
, tmp8
);
1710 if(!(tmp8
& (1 << (channel
<< bit_offs
)))) {
1711 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1712 KdPrint2((PRINT_PREFIX
"generic_cable80(%d, %#x, %d) = 0\n", channel
, pci_reg
, bit_offs
));
1716 KdPrint2((PRINT_PREFIX
"generic_cable80(%d, %#x, %d) = 1\n", channel
, pci_reg
, bit_offs
));
1718 } // end generic_cable80()
1722 UniAtaReadLunConfig(
1723 IN PHW_DEVICE_EXTENSION deviceExtension
,
1724 IN ULONG channel
, // physical channel
1725 IN ULONG DeviceNumber
1730 PHW_LU_EXTENSION LunExt
;
1733 c
= channel
- deviceExtension
->Channel
; // logical channel
1735 chan
= &deviceExtension
->chan
[c
];
1736 DeviceNumber
= (DeviceNumber
% deviceExtension
->NumberLuns
);
1737 LunExt
= chan
->lun
[DeviceNumber
];
1739 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"ReadCacheEnable", 1);
1740 LunExt
->opt_ReadCacheEnable
= tmp32
? TRUE
: FALSE
;
1742 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"WriteCacheEnable", 1);
1743 LunExt
->opt_WriteCacheEnable
= tmp32
? TRUE
: FALSE
;
1745 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1746 LunExt
->opt_MaxTransferMode
= tmp32
;
1748 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"PreferedTransferMode", 0xffffffff);
1749 LunExt
->opt_PreferedTransferMode
= tmp32
;
1751 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"AdvancedPowerMode", ATA_C_F_APM_CNT_MIN_NO_STANDBY
);
1753 tmp32
= 0xfe; // max. performance
1755 LunExt
->opt_AdvPowerMode
= (UCHAR
)tmp32
;
1757 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"AcousticMgmt", ATA_C_F_AAM_CNT_MAX_POWER_SAVE
);
1759 tmp32
= 0xfe; // max. performance
1762 tmp32
= 0x0; // disable feature
1764 LunExt
->opt_AcousticMode
= (UCHAR
)tmp32
;
1766 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"StandbyTimer", 0);
1770 LunExt
->opt_StandbyTimer
= (UCHAR
)tmp32
;
1772 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"ReadOnly", 0);
1774 LunExt
->opt_ReadOnly
= (UCHAR
)tmp32
;
1777 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"GeomType", 0xffffffff);
1778 if(tmp32
> GEOM_MANUAL
) {
1781 LunExt
->opt_GeomType
= tmp32
;
1782 if(tmp32
== GEOM_MANUAL
) {
1783 LunExt
->DeviceFlags
|= DFLAGS_MANUAL_CHS
;
1784 LunExt
->opt_GeomType
= GEOM_ORIG
;
1785 // assume IdentifyData is already zero-filled
1786 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"C", 0);
1787 LunExt
->IdentifyData
.NumberOfCurrentCylinders
=
1788 LunExt
->IdentifyData
.NumberOfCylinders
= (USHORT
)tmp32
;
1789 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"H", 0);
1790 LunExt
->IdentifyData
.NumberOfCurrentHeads
=
1791 LunExt
->IdentifyData
.NumberOfHeads
= (USHORT
)tmp32
;
1792 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"S", 0);
1793 LunExt
->IdentifyData
.CurrentSectorsPerTrack
=
1794 LunExt
->IdentifyData
.SectorsPerTrack
= (USHORT
)tmp32
;
1795 memcpy(LunExt
->IdentifyData
.ModelNumber
, "SEIDH DD", 8); // ESDI HDD
1796 memcpy(LunExt
->IdentifyData
.SerialNumber
, ".10", 4);
1797 memcpy(LunExt
->IdentifyData
.FirmwareRevision
, ".10", 4);
1798 if(!LunExt
->IdentifyData
.SectorsPerTrack
||
1799 !LunExt
->IdentifyData
.NumberOfCylinders
||
1800 !LunExt
->IdentifyData
.NumberOfHeads
) {
1802 KdPrint2((PRINT_PREFIX
"Wrong CHS\n"));
1803 LunExt
->opt_GeomType
= GEOM_AUTO
;
1805 LunExt
->DeviceFlags
|= DFLAGS_MANUAL_CHS
;
1806 LunExt
->opt_GeomType
= GEOM_ORIG
;
1810 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"Hidden", 0);
1812 LunExt
->DeviceFlags
|= DFLAGS_HIDDEN
;
1817 } // end UniAtaReadLunConfig()
1821 AtapiReadChipConfig(
1822 IN PVOID HwDeviceExtension
,
1823 IN ULONG DeviceNumber
,
1824 IN ULONG channel
// physical channel
1827 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1830 ULONG c
; // logical channel (for Compatible Mode controllers)
1833 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: devExt %#x\n", deviceExtension
));
1834 ASSERT(deviceExtension
);
1836 if(channel
!= CHAN_NOT_SPECIFIED
) {
1837 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1839 c
= CHAN_NOT_SPECIFIED
;
1842 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: dev %#x, ph chan %d\n", DeviceNumber
, channel
));
1844 if(channel
== CHAN_NOT_SPECIFIED
) {
1845 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", FALSE
)) {
1846 deviceExtension
->simplexOnly
= TRUE
;
1848 deviceExtension
->opt_AtapiDmaZeroTransfer
= FALSE
;
1849 deviceExtension
->opt_AtapiDmaControlCmd
= FALSE
;
1850 deviceExtension
->opt_AtapiDmaRawRead
= g_opt_AtapiDmaRawRead
;
1851 deviceExtension
->opt_AtapiDmaReadWrite
= TRUE
;
1854 if(c
== CHAN_NOT_SPECIFIED
) {
1855 KdPrint2((PRINT_PREFIX
"MaxTransferMode (base): %#x\n", deviceExtension
->MaxTransferMode
));
1856 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1857 chan
= &deviceExtension
->chan
[c
];
1858 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1859 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1860 if(tmp32
!= 0xffffffff) {
1861 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1862 chan
->MaxTransferMode
= tmp32
;
1864 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"Force80pin", FALSE
);
1865 chan
->Force80pin
= tmp32
? TRUE
: FALSE
;
1866 if(chan
->Force80pin
) {
1867 KdPrint2((PRINT_PREFIX
"Force80pin on chip\n"));
1868 deviceExtension
->HwFlags
|= UNIATA_NO80CHK
;
1871 //UniAtaReadLunConfig(deviceExtension, c, 0);
1872 //UniAtaReadLunConfig(deviceExtension, c, 1);
1875 deviceExtension
->opt_AtapiDmaZeroTransfer
=
1876 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaZeroTransfer", deviceExtension
->opt_AtapiDmaZeroTransfer
) ?
1879 deviceExtension
->opt_AtapiDmaControlCmd
=
1880 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaControlCmd", deviceExtension
->opt_AtapiDmaControlCmd
) ?
1883 deviceExtension
->opt_AtapiDmaRawRead
=
1884 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaRawRead", deviceExtension
->opt_AtapiDmaRawRead
) ?
1887 deviceExtension
->opt_AtapiDmaReadWrite
=
1888 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaReadWrite", deviceExtension
->opt_AtapiDmaReadWrite
) ?
1892 chan
= &deviceExtension
->chan
[c
];
1893 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1894 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1895 if(tmp32
!= 0xffffffff) {
1896 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1897 chan
->MaxTransferMode
= tmp32
;
1899 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"ReorderEnable", TRUE
);
1900 chan
->UseReorder
= tmp32
? TRUE
: FALSE
;
1902 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"Force80pin", FALSE
);
1903 chan
->Force80pin
= tmp32
? TRUE
: FALSE
;
1904 if(chan
->Force80pin
) {
1905 KdPrint2((PRINT_PREFIX
"Force80pin on channel\n"));
1908 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
1909 UniAtaReadLunConfig(deviceExtension
, channel
, i
);
1914 } // end AtapiReadChipConfig()
1919 IN PVOID HwDeviceExtension
,
1920 IN ULONG DeviceNumber
,
1921 IN ULONG channel
// logical channel
1924 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1925 ULONG slotNumber
= deviceExtension
->slotNumber
;
1926 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1927 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
1928 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
1929 ULONG RevID
= deviceExtension
->RevID
;
1931 // BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo;
1932 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1933 ULONG ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
1938 ULONG c
; // logical channel (for Compatible Mode controllers)
1939 BOOLEAN CheckCable
= FALSE
;
1940 BOOLEAN GlobalInit
= FALSE
;
1941 //ULONG BaseIoAddress;
1944 case CHAN_NOT_SPECIFIED_CHECK_CABLE
:
1947 case CHAN_NOT_SPECIFIED
:
1948 c
= CHAN_NOT_SPECIFIED
;
1952 //c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
1954 channel
+= deviceExtension
->Channel
;
1957 KdPrint2((PRINT_PREFIX
"AtapiChipInit: dev %#x, ph chan %d, c %d\n", DeviceNumber
, channel
, c
));
1959 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
1960 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
1962 if(deviceExtension
->UnknownDev
) {
1963 KdPrint2((PRINT_PREFIX
" Unknown chip\n" ));
1965 VendorID
= 0xffffffff;
1969 if(ChipFlags
& UNIATA_AHCI
) {
1970 /* if BAR(5) is IO it should point to SATA interface registers */
1971 if(!deviceExtension
->BaseIoAHCI_0
.Addr
) {
1972 KdPrint2((PRINT_PREFIX
" !BaseIoAHCI_0, exiting\n" ));
1975 if(c
== CHAN_NOT_SPECIFIED
) {
1976 return UniataAhciInit(HwDeviceExtension
);
1978 if(c
<deviceExtension
->NumberChannels
) {
1979 KdPrint2((PRINT_PREFIX
" AHCI single channel init\n" ));
1980 UniataAhciReset(HwDeviceExtension
, c
);
1983 KdPrint2((PRINT_PREFIX
" AHCI non-existent channel\n" ));
1988 if((WinVer_Id() > WinVer_NT
) &&
1990 deviceExtension
->MasterDev
) {
1991 PCI_COMMON_CONFIG pciData
;
1994 KdPrint2((PRINT_PREFIX
" re-enable IO resources of MasterDev\n" ));
1996 busDataRead
= HalGetBusData
1997 //ScsiPortGetBusData
1999 //HwDeviceExtension,
2000 PCIConfiguration
, SystemIoBusNumber
, slotNumber
,
2001 &pciData
, PCI_COMMON_HDR_LENGTH
);
2002 if(busDataRead
== PCI_COMMON_HDR_LENGTH
) {
2003 UniataEnableIoPCI(SystemIoBusNumber
, slotNumber
, &pciData
);
2005 KdPrint2((PRINT_PREFIX
" re-enable IO resources of MasterDev FAILED\n" ));
2010 // case ATA_ACARD_ID:
2012 case ATA_ACER_LABS_ID
:
2013 if(ChipFlags
& UNIATA_SATA
) {
2014 if(c
== CHAN_NOT_SPECIFIED
) {
2015 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2016 chan
= &deviceExtension
->chan
[c
];
2017 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
2018 /* the southbridge might need the data corruption fix */
2019 if(RevID
== 0xc2 || RevID
== 0xc3) {
2020 AtapiAliSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
2021 SystemIoBusNumber
, slotNumber
, c
);
2024 /* enable PCI interrupt */
2025 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
2028 if(ChipFlags
& ALINEW
) {
2029 if(c
== CHAN_NOT_SPECIFIED
) {
2030 /* use device interrupt as byte count end */
2031 ChangePciConfig1(0x4a, (a
| 0x20));
2032 /* enable cable detection and UDMA support on newer chips, rev < 0xc7 */
2034 ChangePciConfig1(0x4b, (a
| 0x09));
2037 /* enable ATAPI UDMA mode */
2038 ChangePciConfig1(0x53, (a
| (RevID
>= 0xc7 ? 0x03 : 0x01)));
2041 // check 80-pin cable
2042 generic_cable80(deviceExtension
, channel
, 0x4a, 0);
2045 if(c
== CHAN_NOT_SPECIFIED
) {
2046 /* deactivate the ATAPI FIFO and enable ATAPI UDMA */
2047 ChangePciConfig1(0x53, (a
| 0x03));
2050 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_DMA_RO
;
2055 if(c
== CHAN_NOT_SPECIFIED
) {
2056 /* set prefetch, postwrite */
2057 if(ChipFlags
& AMDBUG
) {
2058 ChangePciConfig1(0x41, (a
& 0x0f));
2060 ChangePciConfig1(0x41, (a
| 0xf0));
2063 if(deviceExtension
->MaxTransferMode
< ATA_UDMA2
)
2065 // check 80-pin cable
2066 if(!(ChipFlags
& UNIATA_NO80CHK
)) {
2067 if(c
== CHAN_NOT_SPECIFIED
) {
2070 generic_cable80(deviceExtension
, channel
, 0x42, 0);
2074 case ATA_HIGHPOINT_ID
:
2076 if(c
== CHAN_NOT_SPECIFIED
) {
2078 if(ChipFlags
& HPTOLD
) {
2079 /* turn off interrupt prediction */
2080 ChangePciConfig1(0x51, (a
& ~0x80));
2082 /* turn off interrupt prediction */
2083 ChangePciConfig1(0x51, (a
& ~0x03));
2084 ChangePciConfig1(0x55, (a
& ~0x03));
2085 /* turn on interrupts */
2086 ChangePciConfig1(0x5a, (a
& ~0x10));
2087 /* set clocks etc */
2088 if(ChipType
< HPT372
) {
2089 SetPciConfig1(0x5b, 0x22);
2091 ChangePciConfig1(0x5b, ((a
& 0x01) | 0x20));
2096 // check 80-pin cable
2097 chan
= &deviceExtension
->chan
[c
];
2098 if(!hpt_cable80(deviceExtension
, channel
)) {
2099 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2103 case ATA_INTEL_ID
: {
2107 if(ChipFlags
& UNIATA_SATA
) {
2109 KdPrint2((PRINT_PREFIX
"Intel SATA\n"));
2110 if(ChipFlags
& UNIATA_AHCI
) {
2111 KdPrint2((PRINT_PREFIX
"Do nothing for AHCI\n"));
2112 /* enable PCI interrupt */
2113 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
2116 if(c
== CHAN_NOT_SPECIFIED
) {
2117 KdPrint2((PRINT_PREFIX
"Base init\n"));
2118 /* force all ports active "the legacy way" */
2119 ChangePciConfig2(0x92, (a
| 0x0f));
2121 if(deviceExtension
->BaseIoAddressSATA_0
.Addr
&& (ChipFlags
& ICH7
)) {
2122 /* Set SCRAE bit to enable registers access. */
2123 ChangePciConfig4(0x94, (a
| (1 << 9)));
2124 /* Set Ports Implemented register bits. */
2125 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x0c,
2126 AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x0c) | 0x0f);
2128 /* enable PCI interrupt */
2129 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
2133 KdPrint2((PRINT_PREFIX
"channel init\n"));
2135 GetPciConfig1(0x90, tmp8
);
2136 KdPrint2((PRINT_PREFIX
"reg 90: %x, init lun map\n", tmp8
));
2138 KdPrint2((PRINT_PREFIX
"chan %d\n", c
));
2139 chan
= &deviceExtension
->chan
[c
];
2141 if(ChipFlags
& ICH5
) {
2142 KdPrint2((PRINT_PREFIX
"ICH5\n"));
2143 if ((tmp8
& 0x04) == 0) {
2144 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
2145 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ^ c
;
2146 chan
->lun
[1]->SATA_lun_map
= 0;
2147 } else if ((tmp8
& 0x02) == 0) {
2149 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ? 1 : 0;
2150 chan
->lun
[1]->SATA_lun_map
= (tmp8
& 0x01) ? 0 : 1;
2153 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
2155 } else if ((tmp8
& 0x02) != 0) {
2157 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ? 1 : 0;
2158 chan
->lun
[1]->SATA_lun_map
= (tmp8
& 0x01) ? 0 : 1;
2161 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
2165 if(ChipFlags
& I6CH2
) {
2166 KdPrint2((PRINT_PREFIX
"I6CH2\n"));
2167 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
2168 chan
->lun
[0]->SATA_lun_map
= c
? 0 : 1;
2169 chan
->lun
[1]->SATA_lun_map
= 0;
2171 KdPrint2((PRINT_PREFIX
"other Intel\n"));
2172 switch(tmp8
& 0x03) {
2174 KdPrint2((PRINT_PREFIX
"0 -> %d/%d\n", 0+c
, 2+c
));
2175 chan
->lun
[0]->SATA_lun_map
= 0+c
;
2176 chan
->lun
[1]->SATA_lun_map
= 2+c
;
2180 KdPrint2((PRINT_PREFIX
"2 -> %d/%d\n", 0, 2));
2181 chan
->lun
[0]->SATA_lun_map
= 0;
2182 chan
->lun
[1]->SATA_lun_map
= 2;
2185 KdPrint2((PRINT_PREFIX
"PATA\n"));
2191 KdPrint2((PRINT_PREFIX
"2 -> %d/%d\n", 1, 3));
2192 chan
->lun
[0]->SATA_lun_map
= 1;
2193 chan
->lun
[1]->SATA_lun_map
= 3;
2196 KdPrint2((PRINT_PREFIX
"PATA\n"));
2204 KdPrint2((PRINT_PREFIX
"PATA part\n"));
2205 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
2208 if(ChipType
== INTEL_IDX
) {
2209 KdPrint2((PRINT_PREFIX
"io indexed\n"));
2210 //for(c=0; c<deviceExtension->NumberChannels; c++) {
2211 chan
= &deviceExtension
->chan
[c
];
2212 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 0);
2213 if(!(chan
->ChannelCtrlFlags
& CTRFLAGS_NO_SLAVE
)) {
2214 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 1);
2222 if(deviceExtension
->MaxTransferMode
<= ATA_UDMA2
)
2224 // check 80-pin cable
2225 if(c
== CHAN_NOT_SPECIFIED
) {
2228 chan
= &deviceExtension
->chan
[c
];
2229 GetPciConfig2(0x54, reg54
);
2230 KdPrint2((PRINT_PREFIX
" intel 80-pin check (reg54=%x)\n", reg54
));
2231 if(deviceExtension
->HwFlags
& UNIATA_NO80CHK
) {
2232 KdPrint2((PRINT_PREFIX
" No check (administrative)\n"));
2233 if(chan
->Force80pin
) {
2234 KdPrint2((PRINT_PREFIX
"Force80pin\n"));
2237 if(reg54
== 0x0000 || reg54
== 0xffff) {
2238 KdPrint2((PRINT_PREFIX
" check failed (not supported)\n"));
2240 if( ((reg54
>> (channel
*2)) & 30) == 0) {
2241 KdPrint2((PRINT_PREFIX
" intel 40-pin\n"));
2242 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2246 case ATA_NVIDIA_ID
: {
2247 if(ChipFlags
& UNIATA_SATA
) {
2248 if(c
== CHAN_NOT_SPECIFIED
) {
2249 ULONG offs
= (ChipFlags
& NV4OFF
) ? 0x0440 : 0x0010;
2250 /* enable control access */
2251 ChangePciConfig1(0x50, (a
| 0x04));
2252 /* MCP55 seems to need some time to allow r_res2 read. */
2253 AtapiStallExecution(10);
2254 KdPrint2((PRINT_PREFIX
"BaseIoAddressSATA_0=%x\n", deviceExtension
->BaseIoAddressSATA_0
.Addr
));
2255 if(ChipFlags
& NVQ
) {
2256 /* clear interrupt status */
2257 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0x00ff00ff);
2258 /* enable device and PHY state change interrupts */
2259 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+4, 0x000d000d);
2260 /* disable NCQ support */
2261 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400,
2262 AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400) & 0xfffffff9);
2264 /* clear interrupt status */
2265 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0xff);
2266 /* enable device and PHY state change interrupts */
2267 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+1, 0xdd);
2269 /* enable PCI interrupt */
2270 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
2272 //UniataSataPhyEnable(HwDeviceExtension, c);
2277 if(c
== CHAN_NOT_SPECIFIED
) {
2278 /* set prefetch, postwrite */
2279 ChangePciConfig1(0x51, (a
& 0x0f));
2281 // check 80-pin cable
2282 generic_cable80(deviceExtension
, channel
, 0x52, 1);
2283 /* chan = &deviceExtension->chan[c];
2284 GetPciConfig1(0x52, reg52);
2285 if( !((reg52 >> (channel*2)) & 0x01)) {
2286 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2291 case ATA_PROMISE_ID
: {
2296 if(c
== CHAN_NOT_SPECIFIED
) {
2297 // ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);
2298 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x11,
2299 AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x11) | 0x0a );
2303 /* enable burst mode */
2304 // ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
2305 if(c
== CHAN_NOT_SPECIFIED
) {
2306 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f,
2307 AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f) | 0x01 );
2309 // check 80-pin cable
2310 chan
= &deviceExtension
->chan
[c
];
2311 GetPciConfig2(0x50, Reg50
);
2312 if(Reg50
& (1 << (channel
+10))) {
2313 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2318 if(c
== CHAN_NOT_SPECIFIED
) {
2321 // check 80-pin cable
2322 chan
= &deviceExtension
->chan
[c
];
2323 AtapiWritePort1(chan
, IDX_BM_DeviceSpecific0
, 0x0b);
2324 if(AtapiReadPort1(chan
, IDX_BM_DeviceSpecific1
) & 0x04) {
2325 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2330 if(c
== CHAN_NOT_SPECIFIED
) {
2331 /* clear SATA status and unmask interrupts */
2332 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),
2333 (ChipFlags
& PRG2
) ? 0x60 : 0x6c, 0x000000ff);
2334 if(ChipFlags
& UNIATA_SATA
) {
2335 /* enable "long burst length" on gen2 chips */
2336 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
), 0x44,
2337 AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
), 0x44) | 0x2000);
2340 chan
= &deviceExtension
->chan
[c
];
2341 AtapiWritePort4(chan
, IDX_BM_Command
,
2342 (AtapiReadPort4(chan
, IDX_BM_Command
) & ~0x00000f8f) | channel
);
2343 AtapiWritePort4(chan
, IDX_BM_DeviceSpecific0
, 0x00000001);
2344 // check 80-pin cable
2345 if(chan
->MaxTransferMode
< ATA_SA150
&&
2346 (AtapiReadPort4(chan
, IDX_BM_Command
) & 0x01000000)) {
2347 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2353 case ATA_SERVERWORKS_ID
:
2354 if(c
== CHAN_NOT_SPECIFIED
) {
2355 if(ChipType
== SWKS33
) {
2356 AtapiRosbSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
2357 SystemIoBusNumber
, slotNumber
);
2359 ChangePciConfig1(0x5a, ((a
& ~0x40) | ((ChipType
== SWKS100
) ? 0x03 : 0x02)));
2364 if(ChipType
== SIIMIO
) {
2365 KdPrint2((PRINT_PREFIX
"ATI New\n"));
2368 KdPrint2((PRINT_PREFIX
"ATI\n"));
2372 case ATA_SILICON_IMAGE_ID
:
2373 /* if(ChipFlags & SIIENINTR) {
2374 SetPciConfig1(0x71, 0x01);
2379 KdPrint2((PRINT_PREFIX
"SII\n"));
2382 if(c
== CHAN_NOT_SPECIFIED
) {
2383 if(ChipFlags
& SIISETCLK
) {
2384 KdPrint2((PRINT_PREFIX
"SIISETCLK\n"));
2385 GetPciConfig1(0x8a, tmp8
);
2386 if ((tmp8
& 0x30) != 0x10)
2387 ChangePciConfig1(0x8a, (a
& 0xcf) | 0x10);
2388 GetPciConfig1(0x8a, tmp8
);
2389 if ((tmp8
& 0x30) != 0x10) {
2390 KdPrint2((PRINT_PREFIX
"Sil 0680 could not set ATA133 clock\n"));
2391 deviceExtension
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
2395 if(deviceExtension
->MaxTransferMode
< ATA_SA150
) {
2396 // check 80-pin cable
2397 if(c
== CHAN_NOT_SPECIFIED
) {
2400 KdPrint2((PRINT_PREFIX
"Check UDMA66 cable\n"));
2401 chan
= &deviceExtension
->chan
[c
];
2402 GetPciConfig2(0x79, Reg79
);
2403 if(Reg79
& (channel
? 0x02 : 0x01)) {
2404 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2408 ULONG unit01
= (c
& 1);
2409 ULONG unit10
= (c
& 2);
2410 /* enable/disable PHY state change interrupt */
2411 if(c
== CHAN_NOT_SPECIFIED
) {
2412 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2415 if(ChipFlags
& SIINOSATAIRQ
) {
2416 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
2417 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
2421 if(ChipFlags
& SIINOSATAIRQ
) {
2422 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
2423 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
2425 KdPrint2((PRINT_PREFIX
"Enable SATA intr on c=%x\n", c
));
2426 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),(1 << 16));
2430 if(c
== CHAN_NOT_SPECIFIED
) {
2431 /* enable interrupt as BIOS might not */
2432 ChangePciConfig1(0x8a, (a
& 0x3f));
2433 // Enable 3rd and 4th channels
2434 if (ChipFlags
& SII4CH
) {
2435 KdPrint2((PRINT_PREFIX
"SII4CH\n"));
2436 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0200, 0x00000002);
2439 chan
= &deviceExtension
->chan
[c
];
2440 /* dont block interrupts */
2441 //ChangePciConfig4(0x48, (a & ~0x03c00000));
2442 /*tmp32 =*/ AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
2443 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48, (1 << 22) << c
);
2445 /*tmp32 =*/ AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
2447 /* Initialize FIFO PCI bus arbitration */
2448 GetPciConfig1(offsetof(PCI_COMMON_CONFIG
, CacheLineSize
), tmp8
);
2450 KdPrint2((PRINT_PREFIX
"SII: CacheLine=%d\n", tmp8
));
2452 AtapiWritePort2(chan
, IDX_BM_DeviceSpecific1
, ((USHORT
)tmp8
) << 8 | tmp8
);
2454 KdPrint2((PRINT_PREFIX
"SII: CacheLine=0 !!!\n"));
2461 KdPrint2((PRINT_PREFIX
"SII_CMD\n"));
2462 if(c
== CHAN_NOT_SPECIFIED
) {
2463 /* Setup interrupts. */
2464 SetPciConfig1(0x71, 0x01);
2466 /* GetPciConfig1(0x8a, tmp8);
2468 SetPciConfig1(0x71, tmp8);*/
2470 /* Use MEMORY READ LINE for reads.
2471 * NOTE: Although not mentioned in the PCI0646U specs,
2472 * these bits are write only and won't be read
2473 * back as set or not. The PCI0646U2 specs clarify
2477 SetPciConfig1(0x71, tmp8);
2479 /* Set reasonable active/recovery/address-setup values. */
2480 SetPciConfig1(0x53, 0x40);
2481 SetPciConfig1(0x54, 0x3f);
2482 SetPciConfig1(0x55, 0x40);
2483 SetPciConfig1(0x56, 0x3f);
2484 SetPciConfig1(0x57, 0x1c);
2485 SetPciConfig1(0x58, 0x3f);
2486 SetPciConfig1(0x5b, 0x3f);
2491 KdPrint2((PRINT_PREFIX
"ATI700\n"));
2492 if(c
== 0 && !(ChipFlags
& UNIATA_AHCI
)) {
2493 KdPrint2((PRINT_PREFIX
"IXP700 PATA\n"));
2494 chan
= &deviceExtension
->chan
[c
];
2495 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
2498 } /* switch(ChipType) */
2501 if(c
== CHAN_NOT_SPECIFIED
) {
2507 ChangePciConfig1(0x52, (a
& ~0x04));
2511 ChangePciConfig1(0x49, (a
& ~0x01));
2514 ChangePciConfig2(0x50, (a
| 0x0008));
2515 ChangePciConfig2(0x52, (a
| 0x0008));
2518 ChangePciConfig2(0x04, (a
& ~0x0400));
2522 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
2523 // do nothing for SATA
2525 if(ChipType
== SIS133NEW
) {
2527 // check 80-pin cable
2528 if(c
== CHAN_NOT_SPECIFIED
) {
2531 chan
= &deviceExtension
->chan
[c
];
2532 GetPciConfig2(channel
? 0x52 : 0x50, tmp16
);
2533 if(tmp16
& 0x8000) {
2534 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2538 // check 80-pin cable
2539 if(c
== CHAN_NOT_SPECIFIED
) {
2542 chan
= &deviceExtension
->chan
[c
];
2543 GetPciConfig1(48, tmp8
);
2544 if(tmp8
& (0x10 << channel
)) {
2545 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2552 /* if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI | VIASATA) {
2555 if(c
== CHAN_NOT_SPECIFIED
) {
2556 /* prepare for ATA-66 on the 82C686a and 82C596b */
2557 if(ChipFlags
& VIACLK
) {
2558 ChangePciConfig4(0x50, (a
| 0x030b030b));
2561 if(ChipFlags
& (UNIATA_SATA
| VIASATA
)) {
2562 /* enable PCI interrupt */
2563 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
2566 * vt6420/1 has problems talking to some drives. The following
2567 * is based on the fix from Joseph Chan <JosephChan@via.com.tw>.
2569 * When host issues HOLD, device may send up to 20DW of data
2570 * before acknowledging it with HOLDA and the host should be
2571 * able to buffer them in FIFO. Unfortunately, some WD drives
2572 * send upto 40DW before acknowledging HOLD and, in the
2573 * default configuration, this ends up overflowing vt6421's
2574 * FIFO, making the controller abort the transaction with
2577 * Rx52[2] is the internal 128DW FIFO Flow control watermark
2578 * adjusting mechanism enable bit and the default value 0
2579 * means host will issue HOLD to device when the left FIFO
2580 * size goes below 32DW. Setting it to 1 makes the watermark
2583 * http://www.reactos.org/bugzilla/show_bug.cgi?id=6500
2586 if(DeviceID
== 0x3149 || DeviceID
== 0x3249) { //vt6420 or vt6421
2587 KdPrint2((PRINT_PREFIX
"VIA 642x FIFO\n"));
2588 ChangePciConfig1(0x52, a
| (1 << 2));
2594 /* the southbridge might need the data corruption fix */
2595 if(ChipFlags
& VIABUG
) {
2596 AtapiViaSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
2597 SystemIoBusNumber
, slotNumber
);
2599 /* set prefetch, postwrite */
2600 if(ChipType
!= VIA133
) {
2601 ChangePciConfig1(0x41, (a
| 0xf0));
2604 /* set fifo configuration half'n'half */
2605 ChangePciConfig1(0x43, ((a
& ((ChipFlags
& VIAPRQ
) ? 0x80 : 0x90)) | 0x2a));
2607 /* set status register read retry */
2608 ChangePciConfig1(0x44, (a
| 0x08));
2610 /* set DMA read & end-of-sector fifo flush */
2611 ChangePciConfig1(0x46, ((a
& 0x0c) | 0xf0));
2613 /* set sector size */
2614 SetPciConfig2(0x60, DEV_BSIZE
);
2615 SetPciConfig2(0x68, DEV_BSIZE
);
2618 chan
= &deviceExtension
->chan
[c
];
2620 if(ChipFlags
& (UNIATA_SATA
| VIASATA
)) {
2621 if((ChipFlags
& VIABAR
) && (c
>= 2)) {
2622 // this is PATA channel
2623 chan
->MaxTransferMode
= ATA_UDMA5
;
2626 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 0);
2630 // check 80-pin cable
2631 if(!via_cable80(deviceExtension, channel)) {
2632 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2640 if(ChipType
== ITE_33
|| ChipType
== ITE_133_NEW
) {
2643 if(ChipType
== ITE_133
) {
2644 if(c
== CHAN_NOT_SPECIFIED
) {
2645 /* set PCI mode and 66Mhz reference clock */
2646 ChangePciConfig1(0x50, a
& ~0x83);
2648 /* set default active & recover timings */
2649 SetPciConfig1(0x54, 0x31);
2650 SetPciConfig1(0x56, 0x31);
2652 // check 80-pin cable
2653 GetPciConfig2(0x40, tmp16
);
2654 chan
= &deviceExtension
->chan
[c
];
2655 if(!(tmp16
& (channel
? 0x08 : 0x04))) {
2656 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2660 if(ChipType
== ITE_133_NEW
) {
2664 KdPrint2((PRINT_PREFIX
"Cyrix\n"));
2665 if(ChipType
== CYRIX_OLD
) {
2666 if(c
== CHAN_NOT_SPECIFIED
) {
2667 GetPciConfig1(0x60, tmp8
);
2668 if(!(tmp8
& 0x40)) {
2669 KdPrint2((PRINT_PREFIX
"Enable DMA\n"));
2671 SetPciConfig1(0x60, tmp8
);
2677 if(c
!= CHAN_NOT_SPECIFIED
) {
2678 // We don't know how to check for 80-pin cable on unknown controllers.
2679 // Later we shall check bit in IDENTIFY structure, but it is not reliable way.
2680 // So, leave this flag to use as hint in error recovery procedures
2681 KdPrint2((PRINT_PREFIX
"UNIATA_NO80CHK\n"));
2682 deviceExtension
->HwFlags
|= UNIATA_NO80CHK
;
2687 // In all places separate channels are inited after common controller init
2688 // The only exception is probe. But there we may need info about 40/80 pin and MaxTransferRate
2689 if(CheckCable
&& !(ChipFlags
& (UNIATA_NO80CHK
| UNIATA_SATA
))) {
2690 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2691 AtapiChipInit(HwDeviceExtension
, DeviceNumber
, c
);
2696 } // end AtapiChipInit()
2701 IN PHW_DEVICE_EXTENSION deviceExtension
,
2702 IN PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0
,
2710 if(!BaseIoAddressBM_0
) {
2713 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2714 chan
= &deviceExtension
->chan
[c
];
2715 for (i
=0; i
<IDX_BM_IO_SZ
; i
++) {
2716 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
? ((ULONGIO_PTR
)BaseIoAddressBM_0
+ i
) : 0;
2717 chan
->RegTranslation
[IDX_BM_IO
+i
].MemIo
= MemIo
;
2719 if(BaseIoAddressBM_0
) {
2720 BaseIoAddressBM_0
++;
2724 } // end UniataInitMapBM()
2729 IN PHW_CHANNEL chan
,
2730 IN PIDE_REGISTERS_1 BaseIoAddress1
,
2731 IN PIDE_REGISTERS_2 BaseIoAddress2
2736 for (i
=0; i
<IDX_IO1_SZ
; i
++) {
2737 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
? ((ULONGIO_PTR
)BaseIoAddress1
+ i
) : 0;
2738 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= FALSE
;
2740 for (i
=0; i
<IDX_IO2_SZ
; i
++) {
2741 chan
->RegTranslation
[IDX_IO2
+i
].Addr
= BaseIoAddress2
? ((ULONGIO_PTR
)BaseIoAddress2
+ i
) : 0;
2742 chan
->RegTranslation
[IDX_IO2
+i
].MemIo
= FALSE
;
2744 UniataInitSyncBaseIO(chan
);
2746 } // end UniataInitMapBase()
2750 UniataInitSyncBaseIO(
2754 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO1_o
], &chan
->RegTranslation
[IDX_IO1
], IDX_IO1_SZ
*sizeof(chan
->RegTranslation
[0]));
2755 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO2_o
], &chan
->RegTranslation
[IDX_IO2
], IDX_IO2_SZ
*sizeof(chan
->RegTranslation
[0]));
2757 } // end UniataInitSyncBaseIO()
2762 IN PHW_CHANNEL chan
,
2763 IN PHW_DEVICE_EXTENSION deviceExtension
,
2769 KdPrint2((PRINT_PREFIX
"AtapiSetupLunPtrs for channel %d of %d, %d luns \n", c
, deviceExtension
->NumberChannels
, deviceExtension
->NumberLuns
));
2771 if(!deviceExtension
->NumberLuns
) {
2772 KdPrint2((PRINT_PREFIX
"Achtung !deviceExtension->NumberLuns \n"));
2773 deviceExtension
->NumberLuns
= IDE_MAX_LUN_PER_CHAN
;
2775 KdPrint2((PRINT_PREFIX
" Chan %#x\n", chan
));
2776 chan
->DeviceExtension
= deviceExtension
;
2778 chan
->NumberLuns
= deviceExtension
->NumberLuns
;
2779 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
2780 chan
->lun
[i
] = &(deviceExtension
->lun
[c
*deviceExtension
->NumberLuns
+i
]);
2781 KdPrint2((PRINT_PREFIX
" Lun %#x\n", i
));
2782 KdPrint2((PRINT_PREFIX
" Lun ptr %#x\n", chan
->lun
[i
]));
2784 chan
->AltRegMap
= deviceExtension
->AltRegMap
;
2785 chan
->NextDpcChan
= -1;
2786 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
2787 chan
->lun
[i
]->DeviceExtension
= deviceExtension
;
2788 chan
->lun
[i
]->chan
= chan
;
2789 chan
->lun
[i
]->Lun
= i
;
2791 if((deviceExtension
->HwFlags
& UNIATA_AHCI
) &&
2792 deviceExtension
->AhciInternalAtaReq0
&&
2793 deviceExtension
->AhciInternalSrb0
) {
2794 chan
->AhciInternalAtaReq
= &(deviceExtension
->AhciInternalAtaReq0
[c
]);
2795 chan
->AhciInternalSrb
= &(deviceExtension
->AhciInternalSrb0
[c
]);
2796 UniataAhciSetupCmdPtr(chan
->AhciInternalAtaReq
);
2797 chan
->AhciInternalSrb
->SrbExtension
= chan
->AhciInternalAtaReq
;
2798 chan
->AhciInternalAtaReq
->Srb
= chan
->AhciInternalSrb
;
2801 } // end AtapiSetupLunPtrs()
2805 UniataAllocateLunExt(
2806 PHW_DEVICE_EXTENSION deviceExtension
,
2807 ULONG NewNumberChannels
2810 PHW_LU_EXTENSION old_luns
= NULL
;
2811 PHW_CHANNEL old_chans
= NULL
;
2813 KdPrint2((PRINT_PREFIX
"allocate %d Luns for %d channels\n", deviceExtension
->NumberLuns
, deviceExtension
->NumberChannels
));
2815 old_luns
= deviceExtension
->lun
;
2816 old_chans
= deviceExtension
->chan
;
2818 if(old_luns
|| old_chans
) {
2819 if(NewNumberChannels
== UNIATA_ALLOCATE_NEW_LUNS
) {
2820 KdPrint2((PRINT_PREFIX
"already allocated!\n"));
2825 if(!deviceExtension
->NumberLuns
) {
2826 KdPrint2((PRINT_PREFIX
"default NumberLuns=2\n"));
2827 deviceExtension
->NumberLuns
= 2;
2830 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
2831 if(!deviceExtension
->AhciInternalAtaReq0
) {
2832 deviceExtension
->AhciInternalAtaReq0
= (PATA_REQ
)ExAllocatePool(NonPagedPool
, sizeof(ATA_REQ
)*deviceExtension
->NumberChannels
);
2833 if (!deviceExtension
->AhciInternalAtaReq0
) {
2834 KdPrint2((PRINT_PREFIX
"!deviceExtension->AhciInternalAtaReq0 => SP_RETURN_ERROR\n"));
2837 RtlZeroMemory(deviceExtension
->AhciInternalAtaReq0
, sizeof(ATA_REQ
)*deviceExtension
->NumberChannels
);
2839 if(!deviceExtension
->AhciInternalSrb0
) {
2840 deviceExtension
->AhciInternalSrb0
= (PSCSI_REQUEST_BLOCK
)ExAllocatePool(NonPagedPool
, sizeof(SCSI_REQUEST_BLOCK
)*deviceExtension
->NumberChannels
);
2841 if (!deviceExtension
->AhciInternalSrb0
) {
2842 KdPrint2((PRINT_PREFIX
"!deviceExtension->AhciInternalSrb0 => SP_RETURN_ERROR\n"));
2843 UniataFreeLunExt(deviceExtension
);
2846 RtlZeroMemory(deviceExtension
->AhciInternalSrb0
, sizeof(SCSI_REQUEST_BLOCK
)*deviceExtension
->NumberChannels
);
2850 deviceExtension
->lun
= (PHW_LU_EXTENSION
)ExAllocatePool(NonPagedPool
, sizeof(HW_LU_EXTENSION
) * (deviceExtension
->NumberChannels
+1) * deviceExtension
->NumberLuns
);
2851 if (!deviceExtension
->lun
) {
2852 KdPrint2((PRINT_PREFIX
"!deviceExtension->lun => SP_RETURN_ERROR\n"));
2853 UniataFreeLunExt(deviceExtension
);
2856 RtlZeroMemory(deviceExtension
->lun
, sizeof(HW_LU_EXTENSION
) * (deviceExtension
->NumberChannels
+1) * deviceExtension
->NumberLuns
);
2858 deviceExtension
->chan
= (PHW_CHANNEL
)ExAllocatePool(NonPagedPool
, sizeof(HW_CHANNEL
) * (deviceExtension
->NumberChannels
+1));
2859 if (!deviceExtension
->chan
) {
2860 UniataFreeLunExt(deviceExtension
);
2861 KdPrint2((PRINT_PREFIX
"!deviceExtension->chan => SP_RETURN_ERROR\n"));
2864 RtlZeroMemory(deviceExtension
->chan
, sizeof(HW_CHANNEL
) * (deviceExtension
->NumberChannels
+1));
2866 } // end UniataAllocateLunExt()
2871 PHW_DEVICE_EXTENSION deviceExtension
2874 if (deviceExtension
->lun
) {
2875 ExFreePool(deviceExtension
->lun
);
2876 deviceExtension
->lun
= NULL
;
2878 if (deviceExtension
->chan
) {
2879 ExFreePool(deviceExtension
->chan
);
2880 deviceExtension
->chan
= NULL
;
2882 if(deviceExtension
->AhciInternalAtaReq0
) {
2883 ExFreePool(deviceExtension
->AhciInternalAtaReq0
);
2884 deviceExtension
->AhciInternalAtaReq0
= NULL
;
2886 if(deviceExtension
->AhciInternalSrb0
) {
2887 ExFreePool(deviceExtension
->AhciInternalSrb0
);
2888 deviceExtension
->AhciInternalSrb0
= NULL
;
2892 } // end UniataFreeLunExt()