[ROSTESTS]
[reactos.git] / reactos / drivers / storage / ide / uniata / id_init.cpp
1 /*++
2
3 Copyright (c) 2004-2011 Alexandr A. Telyatnikov (Alter)
4
5 Module Name:
6 id_init.cpp
7
8 Abstract:
9 This is the chip-specific init module for ATA/ATAPI IDE controllers
10 with Busmaster DMA and Serial ATA support
11
12 Author:
13 Alexander A. Telyatnikov (Alter)
14
15 Environment:
16 kernel mode only
17
18 Notes:
19
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 Revision History:
32
33 Some parts of 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
38 VIA, nVidia
39 added support for non-standard layout of registers
40 added SATA support
41
42 --*/
43
44 #include "stdafx.h"
45
46 BOOLEAN
47 NTAPI
48 UniataChipDetectChannels(
49 IN PVOID HwDeviceExtension,
50 IN PPCI_COMMON_CONFIG pciData, // optional
51 IN ULONG DeviceNumber,
52 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
53 )
54 {
55 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
56 //ULONG slotNumber = deviceExtension->slotNumber;
57 //ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
58 ULONG VendorID = deviceExtension->DevID & 0xffff;
59 //ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
60 //ULONG RevID = deviceExtension->RevID;
61 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
62 ULONG ChipFlags= deviceExtension->HwFlags & CHIPFLAG_MASK;
63
64 KdPrint2((PRINT_PREFIX "UniataChipDetectChannels:\n" ));
65
66 if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI)) {
67 if(!deviceExtension->NumberChannels) {
68 KdPrint2((PRINT_PREFIX "uninitialized SATA/AHCI port number -> 1\n"));
69 deviceExtension->NumberChannels = 1;
70 }
71 if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreAhciPM", 1 /* DEBUG */)) {
72 KdPrint2((PRINT_PREFIX "SATA/AHCI w/o PM, max luns 1\n"));
73 deviceExtension->NumberLuns = 2;
74 //chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
75 } else {
76 KdPrint2((PRINT_PREFIX "SATA/AHCI -> possible PM, max luns %d\n", SATA_MAX_PM_UNITS));
77 deviceExtension->NumberLuns = SATA_MAX_PM_UNITS;
78 //deviceExtension->NumberLuns = 1;
79 }
80 }
81 if(deviceExtension->MasterDev) {
82 KdPrint2((PRINT_PREFIX "MasterDev -> 1 chan\n"));
83 deviceExtension->NumberChannels = 1;
84 }
85
86 switch(VendorID) {
87 case ATA_ACER_LABS_ID:
88 switch(deviceExtension->DevID) {
89 case 0x528710b9:
90 case 0x528810b9:
91 deviceExtension->NumberChannels = 4;
92 KdPrint2((PRINT_PREFIX "Acer 4 chan\n"));
93 }
94 break;
95 case ATA_PROMISE_ID:
96
97 if(ChipType != PRMIO) {
98 break;
99 }
100 deviceExtension->NumberChannels = 4;
101 KdPrint2((PRINT_PREFIX "Promise 4 chan\n"));
102 break;
103 case ATA_MARVELL_ID:
104 KdPrint2((PRINT_PREFIX "Marvell\n"));
105 switch(deviceExtension->DevID) {
106 case 0x610111ab:
107 /* 88SX6101 only have 1 PATA channel */
108 if(BMList[deviceExtension->DevIndex].channel) {
109 KdPrint2((PRINT_PREFIX "88SX6101 has no 2nd PATA chan\n"));
110 return FALSE;
111 }
112 deviceExtension->NumberChannels = 1;
113 KdPrint2((PRINT_PREFIX "88SX6101 PATA 1 chan\n"));
114 break;
115 }
116 break;
117 case ATA_ATI_ID:
118 KdPrint2((PRINT_PREFIX "ATI\n"));
119 switch(deviceExtension->DevID) {
120 case ATA_ATI_IXP600:
121 case ATA_ATI_IXP700:
122 /* IXP600 & IXP700 only have 1 PATA channel */
123 if(BMList[deviceExtension->DevIndex].channel) {
124 KdPrint2((PRINT_PREFIX "New ATI no 2nd PATA chan\n"));
125 return FALSE;
126 }
127 deviceExtension->NumberChannels = 1;
128 KdPrint2((PRINT_PREFIX "New ATI PATA 1 chan\n"));
129 break;
130 }
131 /* FALLTHROUGH */
132 case ATA_SILICON_IMAGE_ID:
133
134 if(ChipFlags & SIIBUG) {
135 }
136 if(ChipType != SIIMIO) {
137 break;
138 }
139 if(!pciData) {
140 break;
141 }
142
143 if(VendorID == ATA_SILICON_IMAGE_ID) {
144 KdPrint2((PRINT_PREFIX "New SII\n"));
145 } else {
146 KdPrint2((PRINT_PREFIX "ATI SATA\n"));
147 }
148 if(deviceExtension->HwFlags & SII4CH) {
149 deviceExtension->NumberChannels = 4;
150 KdPrint2((PRINT_PREFIX "4 chan\n"));
151 }
152 break;
153 case ATA_VIA_ID:
154 if(/*(deviceExtension->DevID == 0x32491106) &&
155 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[5].RangeStart)*/
156 deviceExtension->HwFlags & VIABAR) {
157 deviceExtension->NumberChannels = 3;
158 KdPrint2((PRINT_PREFIX "VIA 3 chan\n"));
159 }
160 if(ChipFlags & VIASATA) {
161 /* 2 SATA without SATA registers on first channel + 1 PATA on second */
162 // do nothing, generic PATA INIT
163 KdPrint2((PRINT_PREFIX "VIA SATA without SATA regs -> no PM\n"));
164 deviceExtension->NumberLuns = 1;
165 }
166 break;
167 case ATA_ITE_ID:
168 /* ITE ATA133 controller */
169 if(deviceExtension->DevID == 0x82131283) {
170 if(BMList[deviceExtension->DevIndex].channel) {
171 KdPrint2((PRINT_PREFIX "New ITE has no 2nd PATA chan\n"));
172 return FALSE;
173 }
174 deviceExtension->NumberChannels = 1;
175 KdPrint2((PRINT_PREFIX "New ITE PATA 1 chan\n"));
176 }
177 break;
178 case ATA_INTEL_ID:
179 /* New Intel PATA controllers */
180 if(/*deviceExtension->DevID == 0x27df8086 ||
181 deviceExtension->DevID == 0x269e8086 ||
182 deviceExtension->DevID == ATA_I82801HBM*/
183 ChipFlags & I1CH) {
184 if(BMList[deviceExtension->DevIndex].channel) {
185 KdPrint2((PRINT_PREFIX "New Intel PATA has no 2nd chan\n"));
186 return FALSE;
187 }
188 deviceExtension->NumberChannels = 1;
189 KdPrint2((PRINT_PREFIX "New Intel PATA 1 chan\n"));
190 }
191 break;
192 case ATA_JMICRON_ID:
193 /* New JMicron PATA controllers */
194 if(deviceExtension->DevID == ATA_JMB361 ||
195 deviceExtension->DevID == ATA_JMB363 ||
196 deviceExtension->DevID == ATA_JMB368) {
197 if(BMList[deviceExtension->DevIndex].channel) {
198 KdPrint2((PRINT_PREFIX "New JMicron has no 2nd chan\n"));
199 return FALSE;
200 }
201 deviceExtension->NumberChannels = 1;
202 KdPrint2((PRINT_PREFIX "New JMicron PATA 1 chan\n"));
203 }
204 break;
205 } // end switch(VendorID)
206 return TRUE;
207
208 } // end UniataChipDetectChannels()
209
210 NTSTATUS
211 NTAPI
212 UniataChipDetect(
213 IN PVOID HwDeviceExtension,
214 IN PPCI_COMMON_CONFIG pciData, // optional
215 IN ULONG DeviceNumber,
216 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
217 IN BOOLEAN* simplexOnly
218 )
219 {
220 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
221 ULONG slotNumber = deviceExtension->slotNumber;
222 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
223 ULONG VendorID = deviceExtension->DevID & 0xffff;
224 ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
225 ULONG RevID = deviceExtension->RevID;
226 ULONG i, c;
227 BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo;
228 PHW_CHANNEL chan;
229 ULONG ChipType;
230 ULONG ChipFlags;
231 ULONG tmp32;
232 UCHAR tmp8;
233 ULONG BaseMemAddress;
234 ULONG BaseIoAddress1;
235 ULONG BaseIoAddress2;
236 ULONG BaseIoAddressBM;
237 BOOLEAN MemIo = FALSE;
238
239 KdPrint2((PRINT_PREFIX "UniataChipDetect:\n" ));
240 KdPrint2((PRINT_PREFIX "HwFlags: %#x\n", deviceExtension->HwFlags));
241
242 i = Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION)&BusMasterAdapters[0], VendorID, 0xffff, 0, NUM_BUSMASTER_ADAPTERS);
243
244 c = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"ForceSimplex", 0);
245 if(c) {
246 *simplexOnly = TRUE;
247 }
248
249 // defaults
250 BaseIoAddressBM = pciData->u.type0.BaseAddresses[4] & ~0x07;
251 deviceExtension->MaxTransferMode = BaseIoAddressBM ? ATA_DMA : ATA_PIO4;
252 ConfigInfo->MaximumTransferLength = DEV_BSIZE*256;
253 deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
254
255 KdPrint2((PRINT_PREFIX "i: %#x\n", i));
256 if(i != BMLIST_TERMINATOR) {
257 DevTypeInfo = (PBUSMASTER_CONTROLLER_INFORMATION)&BusMasterAdapters[i];
258 } else {
259 if(Ata_is_ahci_dev(pciData)) {
260 KdPrint2((PRINT_PREFIX " AHCI candidate"));
261
262 deviceExtension->NumberChannels = 0;
263 if(!UniataAhciDetect(HwDeviceExtension, pciData, ConfigInfo)) {
264 KdPrint2((PRINT_PREFIX " AHCI init failed - not detected\n"));
265 return STATUS_UNSUCCESSFUL;
266 }
267 KdPrint2((PRINT_PREFIX " unknown AHCI dev, addr %#x", deviceExtension->BaseIoAHCI_0.Addr));
268 }
269 unknown_dev:
270 KdPrint2((PRINT_PREFIX " unknown dev, BM addr %#I64x", BaseIoAddressBM));
271 DevTypeInfo = NULL;
272 KdPrint2((PRINT_PREFIX " MaxTransferMode %#x\n", deviceExtension->MaxTransferMode));
273
274 if(!UniataChipDetectChannels(HwDeviceExtension, pciData, DeviceNumber, ConfigInfo)) {
275 return STATUS_UNSUCCESSFUL;
276 }
277 if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) {
278 return STATUS_UNSUCCESSFUL;
279 }
280
281 return STATUS_NOT_FOUND;
282 }
283
284 static BUSMASTER_CONTROLLER_INFORMATION const SiSAdapters[] = {
285 PCI_DEV_HW_SPEC_BM( 0182, 1039, 0x00, ATA_SA150, "SiS 182" , SISSATA | UNIATA_SATA),
286 PCI_DEV_HW_SPEC_BM( 0181, 1039, 0x00, ATA_SA150, "SiS 181" , SISSATA | UNIATA_SATA),
287 PCI_DEV_HW_SPEC_BM( 0180, 1039, 0x00, ATA_SA150, "SiS 180" , SISSATA | UNIATA_SATA),
288 PCI_DEV_HW_SPEC_BM( 0965, 1039, 0x00, ATA_UDMA6, "SiS 965" , SIS133NEW ),
289 PCI_DEV_HW_SPEC_BM( 0964, 1039, 0x00, ATA_UDMA6, "SiS 964" , SIS133NEW ),
290 PCI_DEV_HW_SPEC_BM( 0963, 1039, 0x00, ATA_UDMA6, "SiS 963" , SIS133NEW ),
291 PCI_DEV_HW_SPEC_BM( 0962, 1039, 0x00, ATA_UDMA6, "SiS 962" , SIS133NEW ),
292
293 PCI_DEV_HW_SPEC_BM( 0745, 1039, 0x00, ATA_UDMA5, "SiS 745" , SIS100NEW ),
294 PCI_DEV_HW_SPEC_BM( 0735, 1039, 0x00, ATA_UDMA5, "SiS 735" , SIS100NEW ),
295 PCI_DEV_HW_SPEC_BM( 0733, 1039, 0x00, ATA_UDMA5, "SiS 733" , SIS100NEW ),
296 PCI_DEV_HW_SPEC_BM( 0730, 1039, 0x00, ATA_UDMA5, "SiS 730" , SIS100OLD ),
297
298 PCI_DEV_HW_SPEC_BM( 0646, 1039, 0x00, ATA_UDMA6, "SiS 645DX", SIS133NEW ),
299 /* PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645" , SIS133NEW ),*/
300 /* PCI_DEV_HW_SPEC_BM( 0640, 1039, 0x00, ATA_UDMA4, "SiS 640" , SIS_SOUTH ),*/
301 PCI_DEV_HW_SPEC_BM( 0635, 1039, 0x00, ATA_UDMA5, "SiS 635" , SIS100NEW ),
302 PCI_DEV_HW_SPEC_BM( 0633, 1039, 0x00, ATA_UDMA5, "SiS 633" , SIS100NEW ),
303 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA5, "SiS 630S" , SIS100OLD ),
304 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA4, "SiS 630" , SIS66 ),
305 PCI_DEV_HW_SPEC_BM( 0620, 1039, 0x00, ATA_UDMA4, "SiS 620" , SIS66 ),
306
307 PCI_DEV_HW_SPEC_BM( 0550, 1039, 0x00, ATA_UDMA5, "SiS 550" , SIS66 ),
308 PCI_DEV_HW_SPEC_BM( 0540, 1039, 0x00, ATA_UDMA4, "SiS 540" , SIS66 ),
309 PCI_DEV_HW_SPEC_BM( 0530, 1039, 0x00, ATA_UDMA4, "SiS 530" , SIS66 ),
310
311 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x04, ATA_UDMA6, "SiS 962L" , SIS133OLD ), // ???
312 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, ATA_UDMA6, "SiS 961" , SIS133OLD ),
313
314 PCI_DEV_HW_SPEC_BM( 5517, 1039, 0x00, ATA_UDMA5, "SiS 961" , SIS100NEW | SIS_BASE ),
315 PCI_DEV_HW_SPEC_BM( 5518, 1039, 0x00, ATA_UDMA6, "SiS 962/3", SIS133NEW | SIS_BASE ),
316 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0xc2, ATA_UDMA2, "SiS 5513" , SIS33 | SIS_BASE ),
317 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0x00, ATA_WDMA2, "SiS 5513" , SIS33 | SIS_BASE ),
318 PCI_DEV_HW_SPEC_BM( 0601, 1039, 0x00, ATA_UDMA2, "SiS 5513" , SIS33 | SIS_BASE ),
319 PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, BMLIST_TERMINATOR , NULL , BMLIST_TERMINATOR )
320 };
321
322 static BUSMASTER_CONTROLLER_INFORMATION const ViaAdapters[] = {
323 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x41, ATA_UDMA2, "VIA 82C586B", VIA33 | 0x00 ),
324 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x40, ATA_UDMA2, "VIA 82C586B", VIA33 | VIAPRQ ),
325 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x02, ATA_UDMA2, "VIA 82C586B", VIA33 | 0x00 ),
326 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x00, ATA_WDMA2, "VIA 82C586" , VIA33 | 0x00 ),
327 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x12, ATA_UDMA4, "VIA 82C596B", VIA66 | VIACLK ),
328 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x00, ATA_UDMA2, "VIA 82C596" , VIA33 | 0x00 ),
329 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x40, ATA_UDMA5, "VIA 82C686B", VIA100 | VIABUG ),
330 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x10, ATA_UDMA4, "VIA 82C686A", VIA66 | VIACLK ),
331 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x00, ATA_UDMA2, "VIA 82C686" , VIA33 | 0x00 ),
332 PCI_DEV_HW_SPEC_BM( 8231, 1106, 0x00, ATA_UDMA5, "VIA 8231" , VIA100 | VIABUG ),
333 PCI_DEV_HW_SPEC_BM( 3074, 1106, 0x00, ATA_UDMA5, "VIA 8233" , VIA100 | 0x00 ),
334 PCI_DEV_HW_SPEC_BM( 3109, 1106, 0x00, ATA_UDMA5, "VIA 8233C" , VIA100 | 0x00 ),
335 PCI_DEV_HW_SPEC_BM( 3147, 1106, 0x00, ATA_UDMA6, "VIA 8233A" , VIA133 | 0x00 ),
336 PCI_DEV_HW_SPEC_BM( 3177, 1106, 0x00, ATA_UDMA6, "VIA 8235" , VIA133 | 0x00 ),
337 PCI_DEV_HW_SPEC_BM( 3227, 1106, 0x00, ATA_UDMA6, "VIA 8237" , VIA133 | 0x00 ),
338 PCI_DEV_HW_SPEC_BM( 0591, 1106, 0x00, ATA_UDMA6, "VIA 8237A" , VIA133 | 0x00 ),
339 // presence of AHCI controller means something about isa-mapped part
340 PCI_DEV_HW_SPEC_BM( 5337, 1106, 0x00, ATA_UDMA6, "VIA 8237S" , VIA133 | 0x00 ),
341 PCI_DEV_HW_SPEC_BM( 5372, 1106, 0x00, ATA_UDMA6, "VIA 8237" , VIA133 | 0x00 ),
342 PCI_DEV_HW_SPEC_BM( 7372, 1106, 0x00, ATA_UDMA6, "VIA 8237" , VIA133 | 0x00 ),
343 PCI_DEV_HW_SPEC_BM( 3349, 1106, 0x00, ATA_UDMA6, "VIA 8251" , VIA133 | 0x00 ),
344 PCI_DEV_HW_SPEC_BM( 8324, 1106, 0x00, ATA_SA150, "VIA CX700" , VIA133 | VIASATA),
345 PCI_DEV_HW_SPEC_BM( 8353, 1106, 0x00, ATA_SA150, "VIA VX800" , VIA133 | VIASATA),
346 PCI_DEV_HW_SPEC_BM( 8409, 1106, 0x00, ATA_UDMA6, "VIA VX855" , VIA133 | 0x00 ),
347 PCI_DEV_HW_SPEC_BM( 8410, 1106, 0x00, ATA_SA300, "VIA VX900" , VIA133 | VIASATA),
348 PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, BMLIST_TERMINATOR , NULL , BMLIST_TERMINATOR )
349 };
350
351 static BUSMASTER_CONTROLLER_INFORMATION const ViaSouthAdapters[] = {
352 PCI_DEV_HW_SPEC_BM( 3112, 1106, 0x00, -1, "VIA 8361", VIASOUTH ),
353 PCI_DEV_HW_SPEC_BM( 0305, 1106, 0x00, -1, "VIA 8363", VIASOUTH ),
354 PCI_DEV_HW_SPEC_BM( 0391, 1106, 0x00, -1, "VIA 8371", VIASOUTH ),
355 PCI_DEV_HW_SPEC_BM( 3102, 1106, 0x00, -1, "VIA 8662", VIASOUTH ),
356 PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, BMLIST_TERMINATOR, NULL , BMLIST_TERMINATOR )
357 };
358
359 KdPrint2((PRINT_PREFIX "VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID, DeviceID, RevID));
360
361 switch(VendorID) {
362
363 case ATA_SIS_ID:
364 KdPrint2((PRINT_PREFIX "ATA_SIS_ID\n"));
365 DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION*)&SiSAdapters[0];
366 i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL);
367 if(i != BMLIST_TERMINATOR) {
368 deviceExtension->FullDevName = SiSAdapters[i].FullDevName;
369 }
370 goto for_ugly_chips;
371
372 case ATA_VIA_ID:
373 KdPrint2((PRINT_PREFIX "ATA_VIA_ID\n"));
374 // New chips have own DeviceId
375 if(deviceExtension->DevID != ATA_VIA82C571 &&
376 deviceExtension->DevID != ATA_VIACX700IDE &&
377 deviceExtension->DevID != ATA_VIASATAIDE &&
378 deviceExtension->DevID != ATA_VIASATAIDE2 &&
379 deviceExtension->DevID != ATA_VIASATAIDE3) {
380 KdPrint2((PRINT_PREFIX "Via new\n"));
381 break;
382 }
383 KdPrint2((PRINT_PREFIX "Via-old-style %x\n", deviceExtension->DevID));
384 // Traditionally, chips have same DeviceId, we can distinguish between them
385 // only by ISA Bridge DeviceId
386 DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION*)&ViaSouthAdapters[0];
387 i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber,
388 PCISLOTNUM_NOT_SPECIFIED/*slotNumber*/, NULL);
389 /* if(i == BMLIST_TERMINATOR) {
390 i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL);
391 }*/
392 if(i != BMLIST_TERMINATOR) {
393 KdPrint2((PRINT_PREFIX "VIASOUTH\n"));
394 deviceExtension->HwFlags |= VIASOUTH;
395 }
396 DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION*)&ViaAdapters[0];
397 i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber,
398 PCISLOTNUM_NOT_SPECIFIED/*slotNumber*/, NULL);
399 if(i != BMLIST_TERMINATOR) {
400 deviceExtension->FullDevName = ViaAdapters[i].FullDevName;
401 }
402 goto for_ugly_chips;
403
404 default:
405
406 // do nothing
407 break;
408
409 #if 0
410 KdPrint2((PRINT_PREFIX "Default\n"));
411
412 deviceExtension->MaxTransferMode = deviceExtension->BaseIoAddressBM_0 ? ATA_DMA : ATA_PIO4;
413 /* do extra chipset specific setups */
414 switch(deviceExtension->DevID) {
415
416 //case ATA_CYPRESS_ID:
417 case 0xc6931080: /* 82c693 ATA controller */
418 deviceExtension->MaxTransferMode = ATA_WDMA2;
419 break;
420
421 case 0x000116ca: /* Cenatek Rocket Drive controller */
422 deviceExtension->MaxTransferMode = ATA_WDMA2;
423 break;
424
425 /* case ATA_CYRIX_ID:
426 DevTypeInfo = &CyrixAdapters[0];
427 break;*/
428 case 0x01021078: /* Cyrix 5530 ATA33 controller */
429 deviceExtension->MaxTransferMode = ATA_UDMA2;
430 break;
431
432 case 0x06401039: /* CMD 640 known bad, no DMA */
433 case 0x06011039:
434 *simplexOnly = TRUE;
435
436 /* FALLTHROUGH */
437
438 case 0x10001042: /* RZ 100x known bad, no DMA */
439 case 0x10011042:
440
441 if(deviceExtension->BaseIoAddressBM_0)
442 ScsiPortFreeDeviceBase(HwDeviceExtension,
443 deviceExtension->BaseIoAddressBM_0);
444
445 deviceExtension->BaseIoAddressBM_0 = 0;
446 deviceExtension->BusMaster = FALSE;
447 deviceExtension->MaxTransferMode = ATA_PIO4;
448 break;
449
450 case 0x81721283: /* IT8172 IDE controller */
451 deviceExtension->MaxTransferMode = ATA_UDMA2;
452 *simplexOnly = TRUE;
453 break;
454
455 default:
456 return STATUS_NOT_FOUND;
457 }
458 return STATUS_SUCCESS;
459 #endif
460 }
461
462 i = Ata_is_dev_listed(DevTypeInfo, VendorID, DeviceID, RevID, -1);
463 for_ugly_chips:
464 KdPrint2((PRINT_PREFIX "i: %#x\n", i));
465 if(i == BMLIST_TERMINATOR) {
466 goto unknown_dev;
467 //return STATUS_NOT_FOUND;
468 }
469 deviceExtension->MaxTransferMode = DevTypeInfo[i].MaxTransferMode;
470 deviceExtension->HwFlags |= DevTypeInfo[i].RaidFlags;
471
472 KdPrint2((PRINT_PREFIX "HwFlags: %#x\n", deviceExtension->HwFlags));
473
474 tmp32 = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"HwFlagsOverride", deviceExtension->HwFlags);
475 KdPrint2((PRINT_PREFIX "HwFlagsOverride: %#x\n", tmp32));
476 deviceExtension->HwFlags = tmp32;
477
478 tmp32 = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"HwFlagsAdd", 0);
479 KdPrint2((PRINT_PREFIX "HwFlagsAdd: %#x\n", tmp32));
480 deviceExtension->HwFlags |= tmp32;
481
482 KdPrint2((PRINT_PREFIX "HwFlags (final): %#x\n", deviceExtension->HwFlags));
483 if(deviceExtension->HwFlags & UNIATA_SIMPLEX_ONLY) {
484 KdPrint2((PRINT_PREFIX "UNIATA_SIMPLEX_ONLY\n" ));
485 *simplexOnly = TRUE;
486 }
487
488 KdPrint2((PRINT_PREFIX "MaxTransferMode: %#x\n", deviceExtension->MaxTransferMode));
489 tmp32 = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"MaxTransferMode", deviceExtension->MaxTransferMode);
490 if(tmp32 != 0xffffffff) {
491 KdPrint2((PRINT_PREFIX "MaxTransferMode (overriden): %#x\n", deviceExtension->MaxTransferMode));
492 deviceExtension->MaxTransferMode = tmp32;
493 }
494
495 if(deviceExtension->MaxTransferMode >= ATA_SA150) {
496 deviceExtension->HwFlags |= UNIATA_SATA;
497 }
498 /*
499 ConfigInfo->MaximumTransferLength = DEV_BSIZE*256;
500 deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
501 */
502 ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
503 ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
504
505 if(ChipFlags & UNIATA_AHCI) {
506 deviceExtension->NumberChannels = 0;
507 if(!UniataAhciDetect(HwDeviceExtension, pciData, ConfigInfo)) {
508 KdPrint2((PRINT_PREFIX " AHCI detect failed\n"));
509 return STATUS_UNSUCCESSFUL;
510 }
511 } else
512 if(!UniataChipDetectChannels(HwDeviceExtension, pciData, DeviceNumber, ConfigInfo)) {
513 return STATUS_UNSUCCESSFUL;
514 }
515 // UniataAhciDetect() sets proper number of channels
516 if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) {
517 return STATUS_UNSUCCESSFUL;
518 }
519
520 if(ChipFlags & UNIATA_AHCI) {
521 }
522
523 switch(VendorID) {
524 case ATA_ACER_LABS_ID:
525 if(ChipFlags & UNIATA_SATA) {
526 deviceExtension->AltRegMap = TRUE; // inform generic resource allocator
527 BaseIoAddress1 = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
528 0, 0, 0x10);
529 BaseIoAddress2 = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
530 1, 0, 0x10);
531 BaseIoAddressBM = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
532 4, 0, deviceExtension->NumberChannels*sizeof(IDE_BUSMASTER_REGISTERS));
533 for(c=0; c<deviceExtension->NumberChannels; c++) {
534 //ULONG unit01 = (c & 1);
535 ULONG unit10 = (c & 2);
536 chan = &deviceExtension->chan[c];
537
538 for (i=0; i<=IDX_IO1_SZ; i++) {
539 chan->RegTranslation[IDX_IO1+i].Addr = BaseIoAddress1 + i + (unit10 ? 8 : 0);
540 }
541 chan->RegTranslation[IDX_IO2_AltStatus].Addr = BaseIoAddress2 + 2 + (unit10 ? 4 : 0);
542 UniataInitSyncBaseIO(chan);
543
544 for (i=0; i<=IDX_BM_IO_SZ; i++) {
545 chan->RegTranslation[IDX_BM_IO+i].Addr = BaseIoAddressBM + i + (c * sizeof(IDE_BUSMASTER_REGISTERS));
546 }
547
548 // SATA not supported yet
549
550 //chan->RegTranslation[IDX_BM_Command] = BaseMemAddress + 0x260 + offs7;
551 //chan->RegTranslation[IDX_BM_PRD_Table] = BaseMemAddress + 0x244 + offs7;
552 //chan->RegTranslation[IDX_BM_DeviceSpecific0] = BaseMemAddress + (c << 2);
553
554 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
555 }
556 }
557 break;
558 case ATA_NVIDIA_ID:
559 if(ChipFlags & UNIATA_SATA) {
560 KdPrint2((PRINT_PREFIX "NVIDIA SATA\n"));
561 BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
562 5, 0, ((ChipFlags & NV4OFF) ? 0x400 : 0) + 0x40*2);
563 KdPrint2((PRINT_PREFIX "BaseMemAddress %x\n", BaseMemAddress));
564 if((*ConfigInfo->AccessRanges)[5].RangeInMemory) {
565 KdPrint2((PRINT_PREFIX "MemIo\n"));
566 MemIo = TRUE;
567 }
568 deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress;
569 deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
570 for(c=0; c<deviceExtension->NumberChannels; c++) {
571 chan = &deviceExtension->chan[c];
572
573 chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + (c << 6);
574 chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo;
575 chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + 4 + (c << 6);
576 chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo;
577 chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + 8 + (c << 6);
578 chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo;
579
580 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
581 }
582 }
583 break;
584 case ATA_PROMISE_ID:
585
586 if(ChipType != PRMIO) {
587 break;
588 }
589 if(!pciData) {
590 break;
591 }
592 deviceExtension->AltRegMap = TRUE; // inform generic resource allocator
593 BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
594 4, 0, 0x4000);
595 KdPrint2((PRINT_PREFIX "BaseMemAddress %x\n", BaseMemAddress));
596 if((*ConfigInfo->AccessRanges)[4].RangeInMemory) {
597 KdPrint2((PRINT_PREFIX "MemIo\n"));
598 MemIo = TRUE;
599 }
600 deviceExtension->BaseIoAddressBM_0.Addr = BaseMemAddress;
601 deviceExtension->BaseIoAddressBM_0.MemIo = MemIo;
602 for(c=0; c<deviceExtension->NumberChannels; c++) {
603
604 ULONG offs12, offs7;
605
606 chan = &deviceExtension->chan[c];
607
608 offs12 = c << 12;
609 offs7 = c << 7;
610
611 for (i=0; i<=IDX_IO1_SZ; i++) {
612 chan->RegTranslation[IDX_IO1+i].Addr = BaseMemAddress + 0x200 + (i << 2) + offs12;
613 chan->RegTranslation[IDX_IO1+i].MemIo = MemIo;
614 }
615 chan->RegTranslation[IDX_IO2_AltStatus].Addr = BaseMemAddress + 0x238 + offs7;
616 chan->RegTranslation[IDX_IO2_AltStatus].MemIo = MemIo;
617
618 UniataInitSyncBaseIO(chan);
619
620 chan->RegTranslation[IDX_BM_Command].Addr = BaseMemAddress + 0x260 + offs7;
621 chan->RegTranslation[IDX_BM_Command].MemIo = MemIo;
622 chan->RegTranslation[IDX_BM_PRD_Table].Addr = BaseMemAddress + 0x244 + offs7;
623 chan->RegTranslation[IDX_BM_PRD_Table].MemIo = MemIo;
624 chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr = BaseMemAddress + (c << 2);
625 chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo;
626 }
627 break;
628
629 case ATA_ATI_ID:
630 KdPrint2((PRINT_PREFIX "ATI\n"));
631 /* FALLTHROUGH */
632 case ATA_SILICON_IMAGE_ID: {
633
634 if(ChipFlags & SIIBUG) {
635 }
636 if(ChipType != SIIMIO) {
637 break;
638 }
639 if(!pciData) {
640 break;
641 }
642
643 if(VendorID == ATA_SILICON_IMAGE_ID) {
644 KdPrint2((PRINT_PREFIX "New SII\n"));
645 } else {
646 KdPrint2((PRINT_PREFIX "ATI SATA\n"));
647 }
648 //if(deviceExtension->HwFlags & SII4CH) {
649 deviceExtension->AltRegMap = TRUE; // inform generic resource allocator
650 //}
651 BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
652 5, 0, 0x800);
653 KdPrint2((PRINT_PREFIX "BaseMemAddress %x\n", BaseMemAddress));
654 if((*ConfigInfo->AccessRanges)[5].RangeInMemory) {
655 KdPrint2((PRINT_PREFIX "MemIo\n"));
656 MemIo = TRUE;
657 }
658 deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress;
659 deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
660
661 for(c=0; c<deviceExtension->NumberChannels; c++) {
662 ULONG unit01 = (c & 1);
663 ULONG unit10 = (c & 2);
664
665 chan = &deviceExtension->chan[c];
666
667 if(deviceExtension->AltRegMap) {
668 for (i=0; i<=IDX_IO1_SZ; i++) {
669 chan->RegTranslation[IDX_IO1+i].Addr = BaseMemAddress + 0x80 + i + (unit01 << 6) + (unit10 << 8);
670 chan->RegTranslation[IDX_IO1+i].MemIo = MemIo;
671 }
672 chan->RegTranslation[IDX_IO2_AltStatus].Addr = BaseMemAddress + 0x8a + (unit01 << 6) + (unit10 << 8);
673 chan->RegTranslation[IDX_IO2_AltStatus].MemIo = MemIo;
674 UniataInitSyncBaseIO(chan);
675
676 chan->RegTranslation[IDX_BM_Command].Addr = BaseMemAddress + 0x00 + (unit01 << 3) + (unit10 << 8);
677 chan->RegTranslation[IDX_BM_Command].MemIo = MemIo;
678 chan->RegTranslation[IDX_BM_Status].Addr = BaseMemAddress + 0x02 + (unit01 << 3) + (unit10 << 8);
679 chan->RegTranslation[IDX_BM_Status].MemIo = MemIo;
680 chan->RegTranslation[IDX_BM_PRD_Table].Addr = BaseMemAddress + 0x04 + (unit01 << 3) + (unit10 << 8);
681 chan->RegTranslation[IDX_BM_PRD_Table].MemIo = MemIo;
682 //chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr = BaseMemAddress + 0xa1 + (unit01 << 6) + (unit10 << 8);
683 //chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo;
684 chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr = BaseMemAddress + 0x10 + (unit01 << 3) + (unit10 << 8);
685 chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo;
686 chan->RegTranslation[IDX_BM_DeviceSpecific1].Addr = BaseMemAddress + 0x40 + (unit01 << 2) + (unit10 << 8);
687 chan->RegTranslation[IDX_BM_DeviceSpecific1].MemIo = MemIo;
688 }
689
690 if(ChipFlags & UNIATA_SATA) {
691 chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + 0x104 + (unit01 << 7) + (unit10 << 8);
692 chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo;
693 chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + 0x108 + (unit01 << 7) + (unit10 << 8);
694 chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo;
695 chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + 0x100 + (unit01 << 7) + (unit10 << 8);
696 chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo;
697
698 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
699 }
700 }
701 break; }
702
703 case ATA_SERVERWORKS_ID: {
704
705 if(ChipType != SWKSMIO) {
706 break;
707 }
708 if(!pciData) {
709 break;
710 }
711
712 KdPrint2((PRINT_PREFIX "ServerWorks\n"));
713
714 deviceExtension->AltRegMap = TRUE; // inform generic resource allocator
715 BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
716 5, 0, 0x400);
717 KdPrint2((PRINT_PREFIX "BaseMemAddress %x\n", BaseMemAddress));
718 if((*ConfigInfo->AccessRanges)[5].RangeInMemory) {
719 KdPrint2((PRINT_PREFIX "MemIo\n"));
720 MemIo = TRUE;
721 }
722 deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress;
723 deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
724
725 for(c=0; c<deviceExtension->NumberChannels; c++) {
726 ULONG offs = c*0x100;
727
728 chan = &deviceExtension->chan[c];
729 for (i=0; i<=IDX_IO1_SZ; i++) {
730 chan->RegTranslation[IDX_IO1+i].Addr = BaseMemAddress + offs + i*4;
731 chan->RegTranslation[IDX_IO1+i].MemIo = MemIo;
732 }
733 chan->RegTranslation[IDX_IO2_AltStatus].Addr = BaseMemAddress + offs + 0x20;
734 chan->RegTranslation[IDX_IO2_AltStatus].MemIo = MemIo;
735 UniataInitSyncBaseIO(chan);
736
737 chan->RegTranslation[IDX_BM_Command].Addr = BaseMemAddress + offs + 0x30;
738 chan->RegTranslation[IDX_BM_Command].MemIo = MemIo;
739 chan->RegTranslation[IDX_BM_Status].Addr = BaseMemAddress + offs + 0x32;
740 chan->RegTranslation[IDX_BM_Status].MemIo = MemIo;
741 chan->RegTranslation[IDX_BM_PRD_Table].Addr = BaseMemAddress + offs + 0x34;
742 chan->RegTranslation[IDX_BM_PRD_Table].MemIo = MemIo;
743
744 chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + offs + 0x40;
745 chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo;
746 chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + offs + 0x44;
747 chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo;
748 chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + offs + 0x48;
749 chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo;
750
751 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
752 }
753 break; }
754
755 case ATA_SIS_ID: {
756 //if(ChipType != SIS_SOUTH) {}
757 BOOLEAN SIS_182=FALSE;
758
759 if(!(ChipFlags & SIS_BASE)) {
760 KdPrint2((PRINT_PREFIX "Found SIS_SOUTH\n"));
761 //PrintNtConsole("Found SIS_SOUTH\n");
762 break;
763 }
764 // Make some additional checks
765 KdPrint2((PRINT_PREFIX "ChipType == SIS_BASE\n"));
766 ChangePciConfig1(0x57, (a & 0x7f));
767 GetPciConfig4(0x00, tmp32);
768 if(tmp32 == ATA_SIS5518) {
769 ChipType = SIS133NEW;
770 deviceExtension->HwFlags = (deviceExtension->HwFlags & ~CHIPTYPE_MASK) | SIS133NEW;
771 deviceExtension->MaxTransferMode = ATA_UDMA6;
772 KdPrint2((PRINT_PREFIX "UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension->MaxTransferMode));
773 //PrintNtConsole("UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension->MaxTransferMode);
774 // Restore device ID
775 ChangePciConfig1(0x57, (a | 0x80));
776 } else {
777 static BUSMASTER_CONTROLLER_INFORMATION const SiSSouthAdapters[] = {
778 PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x10, -1, "SiS 961", 0 ),
779 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, -1, "SiS 961", 0 ),
780 PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, -1, NULL , -1 )
781 };
782 // Save settings
783 GetPciConfig1(0x4a, tmp8);
784 ChangePciConfig1(0x4a, (a | 0x10));
785 if(tmp32 == ATA_SIS5513 ||
786 tmp32 == ATA_SIS5517) {
787 i = AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION*)&SiSSouthAdapters[0],
788 -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL);
789 if(i != BMLIST_TERMINATOR) {
790 deviceExtension->HwFlags = (deviceExtension->HwFlags & ~CHIPTYPE_MASK) | SIS133OLD;
791 //deviceExtension->MaxTransferMode = ATA_UDMA6;
792 deviceExtension->MaxTransferMode = SiSSouthAdapters[i].MaxTransferMode;
793 if(SiSSouthAdapters[i].RaidFlags & UNIATA_SATA) {
794 deviceExtension->HwFlags |= UNIATA_SATA;
795 if(SiSSouthAdapters[i].nDeviceId == 0x1182) {
796 SIS_182 = TRUE;
797 }
798 }
799 } else {
800 // SiS-South not found
801 if(tmp32 == ATA_SIS5517) {
802 deviceExtension->HwFlags = (deviceExtension->HwFlags & ~CHIPTYPE_MASK) | SIS100NEW;
803 deviceExtension->MaxTransferMode = ATA_UDMA5;
804 } else {
805 // generic SiS33
806 KdPrint2((PRINT_PREFIX "Generic SiS DMA\n"));
807 }
808 }
809 }
810 // Restore settings
811 SetPciConfig1(0x4a, tmp8);
812 KdPrint2((PRINT_PREFIX "UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension->MaxTransferMode));
813 //PrintNtConsole("UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension->MaxTransferMode);
814 if(deviceExtension->HwFlags & UNIATA_SATA) {
815 KdPrint2((PRINT_PREFIX "SiS SATA\n"));
816
817 BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
818 5, 0, 0x400);
819 KdPrint2((PRINT_PREFIX "BaseMemAddress %x\n", BaseMemAddress));
820 if((*ConfigInfo->AccessRanges)[5].RangeInMemory) {
821 KdPrint2((PRINT_PREFIX "MemIo\n"));
822 MemIo = TRUE;
823 }
824 deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress;
825 deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
826
827 for(c=0; c<deviceExtension->NumberChannels; c++) {
828 ULONG offs = c << (SIS_182 ? 5 : 6);
829
830 chan = &deviceExtension->chan[c];
831 chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + 0 + offs;
832 chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo;
833 chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + 4 + offs;
834 chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo;
835 chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + 8 + offs;
836 chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo;
837
838 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
839 }
840 }
841 }
842 //ChangePciConfig1(0x57, (a | 0x80));
843 break; }
844
845 case ATA_VIA_ID: {
846
847 if(ChipFlags & VIASATA) {
848 /* 2 SATA without SATA registers on first channel + 1 PATA on second */
849 // do nothing, generic PATA INIT
850 KdPrint2((PRINT_PREFIX "VIA SATA without SATA regs\n"));
851 break;
852 }
853 if(ChipFlags & UNIATA_SATA) {
854
855 ULONG IoSize = 0;
856 ULONG BaseMemAddress = 0;
857
858 switch(DeviceID) {
859 case 0x3149: // VIA 6420
860 KdPrint2((PRINT_PREFIX "VIA 6420\n"));
861 IoSize = 0x80;
862 break;
863 case 0x3249: // VIA 6421
864 KdPrint2((PRINT_PREFIX "VIA 6421\n"));
865 IoSize = 0x40;
866 break;
867 }
868 if(IoSize) {
869 KdPrint2((PRINT_PREFIX "IoSize %x\n", IoSize));
870 /*deviceExtension->*/BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
871 5, 0, IoSize * deviceExtension->NumberChannels);
872 if(BaseMemAddress && (*ConfigInfo->AccessRanges)[5].RangeInMemory) {
873 KdPrint2((PRINT_PREFIX "MemIo\n"));
874 MemIo = TRUE;
875 }
876 deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress;
877 deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
878 }
879 if(/*deviceExtension->*/BaseMemAddress) {
880 KdPrint2((PRINT_PREFIX "UniataChipDetect: BAR5 %x\n", /*deviceExtension->*/BaseMemAddress));
881 if(ChipFlags & VIABAR) {
882
883 ULONG BaseIoAddressBM_0;
884 ULONG BaseIo;
885
886 KdPrint2((PRINT_PREFIX "UniataChipDetect: VIABAR\n"));
887 /*deviceExtension->*/BaseIoAddressBM_0 = /*(PIDE_BUSMASTER_REGISTERS)*/
888 AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber, 4, 0,
889 sizeof(IDE_BUSMASTER_REGISTERS)*deviceExtension->NumberChannels);
890 deviceExtension->AltRegMap = TRUE; // inform generic resource allocator
891 for(c=0; c<deviceExtension->NumberChannels; c++) {
892
893 chan = &deviceExtension->chan[c];
894
895 BaseIo = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber, c, 0, /*0x80*/ sizeof(IDE_REGISTERS_1) + sizeof(IDE_REGISTERS_2)*2);
896
897 for (i=0; i<=IDX_IO1_SZ; i++) {
898 chan->RegTranslation[IDX_IO1+i].Addr = BaseIo + i;
899 }
900 chan->RegTranslation[IDX_IO2_AltStatus].Addr = BaseIo + sizeof(IDE_REGISTERS_1) + 2;
901 UniataInitSyncBaseIO(chan);
902
903 for (i=0; i<=IDX_BM_IO_SZ; i++) {
904 chan->RegTranslation[IDX_BM_IO+i].Addr = BaseIoAddressBM_0 + sizeof(IDE_BUSMASTER_REGISTERS)*c + i;
905 }
906
907 }
908 }
909 for(c=0; c<deviceExtension->NumberChannels; c++) {
910 chan = &deviceExtension->chan[c];
911 if((ChipFlags & VIABAR) && (c==2)) {
912 // Do not setup SATA registers for PATA part
913 for (i=0; i<=IDX_SATA_IO_SZ; i++) {
914 chan->RegTranslation[IDX_SATA_IO+i].Addr = 0;
915 chan->RegTranslation[IDX_SATA_IO+i].MemIo = 0;
916 }
917 break;
918 }
919 chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + (c * IoSize);
920 chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo;
921 chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + 4 + (c * IoSize);
922 chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo;
923 chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + 8 + (c * IoSize);
924 chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo;
925
926 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
927 }
928
929 }
930 }
931 break; }
932 case ATA_INTEL_ID: {
933
934 BOOLEAN IsPata;
935 if(!(ChipFlags & UNIATA_SATA)) {
936 break;
937 }
938
939 /* the intel 31244 needs special care if in DPA mode */
940 if(DeviceID == 3200 && // Intel 31244
941 pciData->SubClass != PCI_DEV_SUBCLASS_IDE) {
942
943 KdPrint2((PRINT_PREFIX "UniataChipDetect: Intel 31244, DPA mode\n"));
944 BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
945 0, 0, 0x0c00);
946 if((*ConfigInfo->AccessRanges)[0].RangeInMemory) {
947 KdPrint2((PRINT_PREFIX "MemIo\n"));
948 MemIo = TRUE;
949 }
950 deviceExtension->AltRegMap = TRUE; // inform generic resource allocator
951 deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress;
952 deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
953
954 for(c=0; c<deviceExtension->NumberChannels; c++) {
955 ULONG offs = 0x200 + c*0x200;
956
957 chan = &deviceExtension->chan[c];
958 for (i=0; i<=IDX_IO1_SZ; i++) {
959 chan->RegTranslation[IDX_IO1+i].MemIo = MemIo;
960 chan->RegTranslation[IDX_IO1_o+i].MemIo = MemIo;
961 }
962
963 chan->RegTranslation[IDX_IO1_i_Data ].Addr = BaseMemAddress + 0x00 + offs;
964 chan->RegTranslation[IDX_IO1_i_Error ].Addr = BaseMemAddress + 0x04 + offs;
965 chan->RegTranslation[IDX_IO1_i_BlockCount ].Addr = BaseMemAddress + 0x08 + offs;
966 chan->RegTranslation[IDX_IO1_i_BlockNumber ].Addr = BaseMemAddress + 0x0c + offs;
967 chan->RegTranslation[IDX_IO1_i_CylinderLow ].Addr = BaseMemAddress + 0x10 + offs;
968 chan->RegTranslation[IDX_IO1_i_CylinderHigh].Addr = BaseMemAddress + 0x14 + offs;
969 chan->RegTranslation[IDX_IO1_i_DriveSelect ].Addr = BaseMemAddress + 0x18 + offs;
970 chan->RegTranslation[IDX_IO1_i_Status ].Addr = BaseMemAddress + 0x1c + offs;
971
972 UniataInitSyncBaseIO(chan);
973
974 chan->RegTranslation[IDX_IO1_o_Command ].Addr = BaseMemAddress + 0x1d + offs;
975 chan->RegTranslation[IDX_IO1_o_Feature ].Addr = BaseMemAddress + 0x06 + offs;
976 chan->RegTranslation[IDX_IO2_o_Control ].Addr = BaseMemAddress + 0x29 + offs;
977
978 chan->RegTranslation[IDX_IO2_AltStatus].Addr = BaseMemAddress + 0x28 + offs;
979 chan->RegTranslation[IDX_IO2_AltStatus].MemIo = MemIo;
980
981 chan->RegTranslation[IDX_BM_Command].Addr = BaseMemAddress + offs + 0x70;
982 chan->RegTranslation[IDX_BM_Command].MemIo = MemIo;
983 chan->RegTranslation[IDX_BM_Status].Addr = BaseMemAddress + offs + 0x72;
984 chan->RegTranslation[IDX_BM_Status].MemIo = MemIo;
985 chan->RegTranslation[IDX_BM_PRD_Table].Addr = BaseMemAddress + offs + 0x74;
986 chan->RegTranslation[IDX_BM_PRD_Table].MemIo = MemIo;
987
988 chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + 0x100 + offs;
989 chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo;
990 chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + 0x104 + offs;
991 chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo;
992 chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + 0x108 + offs;
993 chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo;
994
995 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
996 }
997
998 break;
999 }
1000 if(deviceExtension->MaxTransferMode >= ATA_SA150) {
1001 GetPciConfig1(0x90, tmp8);
1002 KdPrint2((PRINT_PREFIX "Intel chip config: %x\n", tmp8));
1003 /* SATA parts can be either compat or AHCI */
1004 if(ChipFlags & UNIATA_AHCI) {
1005
1006 if(tmp8 & 0xc0) {
1007 //KdPrint2((PRINT_PREFIX "AHCI not supported yet\n"));
1008 //return FALSE;
1009 KdPrint2((PRINT_PREFIX "try run AHCI\n"));
1010 break;
1011 }
1012 KdPrint2((PRINT_PREFIX "Compatible mode\n"));
1013 }
1014 deviceExtension->HwFlags &= ~UNIATA_AHCI;
1015
1016 /* if BAR(5) is IO it should point to SATA interface registers */
1017 BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
1018 5, 0, 0x10);
1019 if(BaseMemAddress && (*ConfigInfo->AccessRanges)[5].RangeInMemory) {
1020 KdPrint2((PRINT_PREFIX "MemIo\n"));
1021 MemIo = TRUE;
1022 }
1023 deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress;
1024 deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
1025
1026 for(c=0; c<deviceExtension->NumberChannels; c++) {
1027 chan = &deviceExtension->chan[c];
1028 IsPata = FALSE;
1029 if(ChipFlags & ICH5) {
1030 KdPrint2((PRINT_PREFIX "ICH5\n"));
1031 if ((tmp8 & 0x04) == 0) {
1032 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
1033 } else if ((tmp8 & 0x02) == 0) {
1034 if(c != 0) {
1035 IsPata = TRUE;
1036 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1037 }
1038 } else if ((tmp8 & 0x02) != 0) {
1039 if(c != 1) {
1040 IsPata = TRUE;
1041 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1042 }
1043 }
1044 } else
1045 if(ChipFlags & I6CH2) {
1046 KdPrint2((PRINT_PREFIX "I6CH2\n"));
1047 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
1048 } else {
1049 KdPrint2((PRINT_PREFIX "other Intel\n"));
1050 switch(tmp8 & 0x03) {
1051 case 2:
1052 if(c!=0) {
1053 // PATA
1054 IsPata = TRUE;
1055 }
1056 break;
1057 case 1:
1058 if(c!=1) {
1059 // PATA
1060 IsPata = TRUE;
1061 }
1062 break;
1063 }
1064 }
1065
1066 if(IsPata) {
1067 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA5);
1068 KdPrint2((PRINT_PREFIX "PATA part\n"));
1069 } else {
1070
1071 if(/*(ChipFlags & ICH5) &&*/ BaseMemAddress) {
1072 KdPrint2((PRINT_PREFIX "BaseMemAddress[5] -> indexed\n"));
1073 chan->RegTranslation[IDX_INDEXED_ADDR].Addr = BaseMemAddress + 0;
1074 chan->RegTranslation[IDX_INDEXED_ADDR].MemIo = MemIo;
1075 chan->RegTranslation[IDX_INDEXED_DATA].Addr = BaseMemAddress + 4;
1076 chan->RegTranslation[IDX_INDEXED_DATA].MemIo = MemIo;
1077 }
1078 if((ChipFlags & ICH5) || BaseMemAddress) {
1079
1080 KdPrint2((PRINT_PREFIX "io indexed\n"));
1081 // Rather interesting way of register access...
1082 ChipType = INTEL_IDX;
1083 deviceExtension->HwFlags &= ~CHIPTYPE_MASK;
1084 deviceExtension->HwFlags |= ChipType;
1085
1086 chan->RegTranslation[IDX_SATA_SStatus].Addr = 0x200*c + 0;
1087 chan->RegTranslation[IDX_SATA_SStatus].Proc = 1;
1088 chan->RegTranslation[IDX_SATA_SError].Addr = 0x200*c + 2;
1089 chan->RegTranslation[IDX_SATA_SError].Proc = 1;
1090 chan->RegTranslation[IDX_SATA_SControl].Addr = 0x200*c + 1;
1091 chan->RegTranslation[IDX_SATA_SControl].Proc = 1;
1092 }
1093 }
1094
1095 } // end for()
1096
1097 // rest of INIT staff is in AtapiChipInit()
1098
1099 } // ATA_SA150
1100 break; }
1101 case ATA_CYRIX_ID:
1102 /* Cyrix 5530 ATA33 controller */
1103 if(deviceExtension->DevID == 0x01021078) {
1104 ConfigInfo->AlignmentMask = 0x0f;
1105 deviceExtension->MaximumDmaTransferLength = 63*1024;
1106 }
1107 break;
1108 case ATA_JMICRON_ID:
1109 /* New JMicron PATA controllers */
1110 GetPciConfig1(0xdf, tmp8);
1111 if(tmp8 & 0x40) {
1112 KdPrint((" Check JMicron AHCI\n"));
1113 if(Ata_is_ahci_dev(pciData)) {
1114 ChipFlags |= UNIATA_AHCI;
1115 deviceExtension->HwFlags |= UNIATA_AHCI;
1116 } else {
1117 KdPrint((" JMicron PATA\n"));
1118 }
1119 } else {
1120 /* set controller configuration to a combined setup we support */
1121 SetPciConfig4(0x40, 0x80c0a131);
1122 SetPciConfig4(0x80, 0x01200000);
1123 //KdPrint((" JMicron Combined (not supported yet)\n"));
1124 //return STATUS_NOT_FOUND;
1125 }
1126 break;
1127 }
1128
1129 return STATUS_SUCCESS;
1130
1131 } // end UniataChipDetect()
1132
1133
1134 /*
1135 Do some 'magic staff' for VIA SouthBridge
1136 This will prevent data losses
1137 */
1138 VOID
1139 NTAPI
1140 AtapiViaSouthBridgeFixup(
1141 IN PVOID HwDeviceExtension,
1142 IN BUS_DATA_TYPE BusDataType,
1143 IN ULONG SystemIoBusNumber,
1144 IN ULONG slotNumber
1145 )
1146 {
1147 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1148 PCI_COMMON_CONFIG pciData;
1149 ULONG funcNumber;
1150 ULONG busDataRead;
1151
1152 ULONG VendorID;
1153 ULONG DeviceID;
1154 PCI_SLOT_NUMBER slotData;
1155 ULONG dev_id;
1156 BOOLEAN found = FALSE;
1157
1158 slotData.u.AsULONG = slotNumber;
1159 for(funcNumber = 0; funcNumber < PCI_MAX_FUNCTION; funcNumber++) {
1160
1161 slotData.u.bits.FunctionNumber = funcNumber;
1162
1163 busDataRead = ScsiPortGetBusData(HwDeviceExtension,
1164 PCIConfiguration,
1165 SystemIoBusNumber,
1166 slotData.u.AsULONG,
1167 &pciData,
1168 PCI_COMMON_HDR_LENGTH);
1169
1170 if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
1171 continue;
1172 }
1173
1174 VendorID = pciData.VendorID;
1175 DeviceID = pciData.DeviceID;
1176 dev_id = (VendorID | (DeviceID << 16));
1177
1178 if (dev_id == 0x03051106 || /* VIA VT8363 */
1179 dev_id == 0x03911106 || /* VIA VT8371 */
1180 dev_id == 0x31021106 || /* VIA VT8662 */
1181 dev_id == 0x31121106) { /* VIA VT8361 */
1182 UCHAR reg76;
1183
1184 GetPciConfig1(0x76, reg76);
1185
1186 if ((reg76 & 0xf0) != 0xd0) {
1187 SetPciConfig1(0x75, 0x80);
1188 SetPciConfig1(0x76, (reg76 & 0x0f) | 0xd0);
1189 }
1190 found = TRUE;
1191 break;
1192 }
1193 }
1194 if(!found) {
1195 deviceExtension->HwFlags &= ~VIABUG;
1196 }
1197 } // end AtapiViaSouthBridgeFixup()
1198
1199 /*
1200 Do some 'magic staff' for ROSB SouthBridge
1201 This will prevent data losses
1202 */
1203 VOID
1204 NTAPI
1205 AtapiRosbSouthBridgeFixup(
1206 IN PVOID HwDeviceExtension,
1207 IN BUS_DATA_TYPE BusDataType,
1208 IN ULONG SystemIoBusNumber,
1209 IN ULONG slotNumber
1210 )
1211 {
1212 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1213 PCI_COMMON_CONFIG pciData;
1214 ULONG funcNumber;
1215 ULONG busDataRead;
1216
1217 ULONG VendorID;
1218 ULONG DeviceID;
1219 PCI_SLOT_NUMBER slotData;
1220 ULONG dev_id;
1221 // BOOLEAN found = FALSE;
1222
1223 /* locate the ISA part in the southbridge and enable UDMA33 */
1224 slotData.u.AsULONG = slotNumber;
1225 for(funcNumber = 0; funcNumber < PCI_MAX_FUNCTION; funcNumber++) {
1226
1227 slotData.u.bits.FunctionNumber = funcNumber;
1228
1229 busDataRead = ScsiPortGetBusData(HwDeviceExtension,
1230 PCIConfiguration,
1231 SystemIoBusNumber,
1232 slotData.u.AsULONG,
1233 &pciData,
1234 PCI_COMMON_HDR_LENGTH);
1235
1236 if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
1237 continue;
1238 }
1239
1240 VendorID = pciData.VendorID;
1241 DeviceID = pciData.DeviceID;
1242 dev_id = (VendorID | (DeviceID << 16));
1243
1244 if (dev_id == ATA_ROSB4_ISA) { /* */
1245 ChangePciConfig4(0x64, ((a & ~0x00002000) | 0x00004000));
1246 break;
1247 }
1248 }
1249 } // end AtapiRosbSouthBridgeFixup()
1250
1251 /*
1252 Do some 'magic staff' for ROSB SouthBridge
1253 This will prevent data losses
1254 */
1255 VOID
1256 NTAPI
1257 AtapiAliSouthBridgeFixup(
1258 IN PVOID HwDeviceExtension,
1259 IN BUS_DATA_TYPE BusDataType,
1260 IN ULONG SystemIoBusNumber,
1261 IN ULONG slotNumber,
1262 IN ULONG c
1263 )
1264 {
1265 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1266 PCI_COMMON_CONFIG pciData;
1267 ULONG funcNumber;
1268 ULONG busDataRead;
1269
1270 ULONG VendorID;
1271 ULONG DeviceID;
1272 PCI_SLOT_NUMBER slotData;
1273 ULONG dev_id;
1274 // BOOLEAN found = FALSE;
1275
1276 /* workaround for datacorruption bug found on at least SUN Blade-100
1277 * find the ISA function on the southbridge and disable then enable
1278 * the ATA channel tristate buffer */
1279 slotData.u.AsULONG = slotNumber;
1280 for(funcNumber = 0; funcNumber < PCI_MAX_FUNCTION; funcNumber++) {
1281
1282 slotData.u.bits.FunctionNumber = funcNumber;
1283
1284 busDataRead = ScsiPortGetBusData(HwDeviceExtension,
1285 PCIConfiguration,
1286 SystemIoBusNumber,
1287 slotData.u.AsULONG,
1288 &pciData,
1289 PCI_COMMON_HDR_LENGTH);
1290
1291 if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
1292 continue;
1293 }
1294
1295 VendorID = pciData.VendorID;
1296 DeviceID = pciData.DeviceID;
1297 dev_id = (VendorID | (DeviceID << 16));
1298
1299 if (dev_id == ATA_ALI_1533) { /* SOUTH */
1300 ChangePciConfig1(0x58, (a & ~(0x04 << c)));
1301 ChangePciConfig1(0x58, (a | (0x04 << c)));
1302 break;
1303 }
1304 }
1305 } // end AtapiRosbSouthBridgeFixup()
1306
1307 ULONG
1308 NTAPI
1309 hpt_cable80(
1310 IN PHW_DEVICE_EXTENSION deviceExtension,
1311 IN ULONG channel // physical channel number (0-1)
1312 )
1313 {
1314 PVOID HwDeviceExtension = (PVOID)deviceExtension;
1315 ULONG slotNumber = deviceExtension->slotNumber;
1316 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
1317
1318 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1319
1320 UCHAR reg, val, res;
1321 PCI_SLOT_NUMBER slotData;
1322
1323 slotData.u.AsULONG = deviceExtension->slotNumber;
1324
1325 if(ChipType == HPT374 && slotData.u.bits.FunctionNumber == 1) {
1326 reg = channel ? 0x57 : 0x53;
1327 GetPciConfig1(reg, val);
1328 SetPciConfig1(reg, val | 0x80);
1329 }
1330 else {
1331 reg = 0x5b;
1332 GetPciConfig1(reg, val);
1333 SetPciConfig1(reg, val & 0xfe);
1334 }
1335 GetPciConfig1(0x5a, res);
1336 res = res & (channel ? 0x01 : 0x02);
1337 SetPciConfig1(reg, val);
1338 return !res;
1339 } // end hpt_cable80()
1340
1341
1342 ULONG
1343 NTAPI
1344 via_cable80(
1345 IN PHW_DEVICE_EXTENSION deviceExtension,
1346 IN ULONG channel // physical channel number (0-1)
1347 )
1348 {
1349 PVOID HwDeviceExtension = (PVOID)deviceExtension;
1350 ULONG slotNumber = deviceExtension->slotNumber;
1351 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
1352
1353 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1354
1355 ULONG reg50;
1356 ULONG a;
1357 ULONG i, j;
1358 BOOLEAN res;
1359
1360 GetPciConfig1(0x50, reg50);
1361
1362 switch(ChipType) {
1363 case VIA133:
1364 a = 8;
1365 break;
1366 case VIA100:
1367 a = 4;
1368 break;
1369 case VIA66:
1370 a = 2;
1371 break;
1372 default:
1373 return false;
1374 }
1375
1376 res = FALSE;
1377 for (j=0; j>=2; i -= 8) {
1378 i = (3-(channel*2+j))*8;
1379 if (((reg50 >> (i & 0x10)) & 8) &&
1380 ((reg50 >> i) & 0x20) &&
1381 (((reg50 >> i) & 7) < a)) {
1382
1383 res |= TRUE; //(1 << (1 - (i >> 4)));
1384 }
1385 }
1386 return res;
1387
1388 } // end via_cable80()
1389
1390 BOOLEAN
1391 NTAPI
1392 generic_cable80(
1393 IN PHW_DEVICE_EXTENSION deviceExtension,
1394 IN ULONG channel, // physical channel number (0-1)
1395 IN ULONG pci_reg,
1396 IN ULONG bit_offs
1397 )
1398 {
1399 PVOID HwDeviceExtension = (PVOID)deviceExtension;
1400 ULONG slotNumber = deviceExtension->slotNumber;
1401 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
1402
1403 //ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1404 PHW_CHANNEL chan;
1405 ULONG c; // logical channel (for Compatible Mode controllers)
1406 UCHAR tmp8;
1407
1408 c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
1409 chan = &deviceExtension->chan[c];
1410
1411 GetPciConfig1(pci_reg, tmp8);
1412 if(!(tmp8 & (1 << (channel << bit_offs)))) {
1413 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
1414 return FALSE;
1415 }
1416
1417 return TRUE;
1418 } // end generic_cable80()
1419
1420 VOID
1421 NTAPI
1422 UniAtaReadLunConfig(
1423 IN PHW_DEVICE_EXTENSION deviceExtension,
1424 IN ULONG channel, // physical channel
1425 IN ULONG DeviceNumber
1426 )
1427 {
1428 ULONG tmp32;
1429 PHW_CHANNEL chan;
1430 PHW_LU_EXTENSION LunExt;
1431 ULONG c;
1432
1433 c = channel - deviceExtension->Channel; // logical channel
1434
1435 chan = &deviceExtension->chan[c];
1436 DeviceNumber = (DeviceNumber % deviceExtension->NumberLuns);
1437 LunExt = chan->lun[DeviceNumber];
1438
1439 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"ReadCacheEnable", 1);
1440 LunExt->opt_ReadCacheEnable = tmp32 ? TRUE : FALSE;
1441
1442 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"WriteCacheEnable", 1);
1443 LunExt->opt_WriteCacheEnable = tmp32 ? TRUE : FALSE;
1444
1445 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"MaxTransferMode", chan->MaxTransferMode);
1446 LunExt->opt_MaxTransferMode = tmp32;
1447
1448 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"PreferedTransferMode", 0xffffffff);
1449 LunExt->opt_PreferedTransferMode = tmp32;
1450
1451 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"ReadOnly", 0);
1452 if(tmp32 <= 2) {
1453 LunExt->opt_ReadOnly = (UCHAR)tmp32;
1454 }
1455
1456 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"GeomType", 0xffffffff);
1457 if(tmp32 > 2) {
1458 tmp32 = 0xffffffff;
1459 }
1460 LunExt->opt_GeomType = tmp32;
1461
1462 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"Hidden", 0);
1463 if(tmp32) {
1464 LunExt->DeviceFlags |= DFLAGS_HIDDEN;
1465 }
1466
1467 return;
1468 } // end UniAtaReadLunConfig()
1469
1470 BOOLEAN
1471 NTAPI
1472 AtapiReadChipConfig(
1473 IN PVOID HwDeviceExtension,
1474 IN ULONG DeviceNumber,
1475 IN ULONG channel // physical channel
1476 )
1477 {
1478 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1479 PHW_CHANNEL chan;
1480 ULONG tmp32;
1481 ULONG c; // logical channel (for Compatible Mode controllers)
1482 ULONG i;
1483
1484 KdPrint2((PRINT_PREFIX "AtapiReadChipConfig: devExt %#x\n", deviceExtension ));
1485 ASSERT(deviceExtension);
1486
1487 if(channel != CHAN_NOT_SPECIFIED) {
1488 c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
1489 } else {
1490 c = CHAN_NOT_SPECIFIED;
1491 }
1492
1493 KdPrint2((PRINT_PREFIX "AtapiReadChipConfig: dev %#x, ph chan %d\n", DeviceNumber, channel ));
1494
1495 if(channel == CHAN_NOT_SPECIFIED) {
1496 if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"ForceSimplex", FALSE)) {
1497 deviceExtension->simplexOnly = TRUE;
1498 }
1499 deviceExtension->opt_AtapiDmaZeroTransfer = FALSE;
1500 deviceExtension->opt_AtapiDmaControlCmd = FALSE;
1501 deviceExtension->opt_AtapiDmaRawRead = g_opt_AtapiDmaRawRead;
1502 deviceExtension->opt_AtapiDmaReadWrite = TRUE;
1503 }
1504
1505 if(c == CHAN_NOT_SPECIFIED) {
1506 KdPrint2((PRINT_PREFIX "MaxTransferMode (base): %#x\n", deviceExtension->MaxTransferMode));
1507 for(c=0; c<deviceExtension->NumberChannels; c++) {
1508 chan = &deviceExtension->chan[c];
1509 chan->MaxTransferMode = deviceExtension->MaxTransferMode;
1510 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DEVNUM_NOT_SPECIFIED, L"MaxTransferMode", chan->MaxTransferMode);
1511 if(tmp32 != 0xffffffff) {
1512 KdPrint2((PRINT_PREFIX "MaxTransferMode (overriden): %#x\n", chan->MaxTransferMode));
1513 chan->MaxTransferMode = tmp32;
1514 }
1515 //UniAtaReadLunConfig(deviceExtension, c, 0);
1516 //UniAtaReadLunConfig(deviceExtension, c, 1);
1517 }
1518
1519 deviceExtension->opt_AtapiDmaZeroTransfer =
1520 AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaZeroTransfer", deviceExtension->opt_AtapiDmaZeroTransfer) ?
1521 TRUE : FALSE;
1522
1523 deviceExtension->opt_AtapiDmaControlCmd =
1524 AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaControlCmd", deviceExtension->opt_AtapiDmaControlCmd) ?
1525 TRUE : FALSE;
1526
1527 deviceExtension->opt_AtapiDmaRawRead =
1528 AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaRawRead", deviceExtension->opt_AtapiDmaRawRead) ?
1529 TRUE : FALSE;
1530
1531 deviceExtension->opt_AtapiDmaReadWrite =
1532 AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaReadWrite", deviceExtension->opt_AtapiDmaReadWrite) ?
1533 TRUE : FALSE;
1534
1535 } else {
1536 chan = &deviceExtension->chan[c];
1537 chan->MaxTransferMode = deviceExtension->MaxTransferMode;
1538 tmp32 = AtapiRegCheckDevValue(deviceExtension, c, DEVNUM_NOT_SPECIFIED, L"MaxTransferMode", chan->MaxTransferMode);
1539 if(tmp32 != 0xffffffff) {
1540 KdPrint2((PRINT_PREFIX "MaxTransferMode (overriden): %#x\n", chan->MaxTransferMode));
1541 chan->MaxTransferMode = tmp32;
1542 }
1543 tmp32 = AtapiRegCheckDevValue(deviceExtension, c, DEVNUM_NOT_SPECIFIED, L"ReorderEnable", TRUE);
1544 chan->UseReorder = tmp32 ? TRUE : FALSE;
1545
1546 for(i=0; i<deviceExtension->NumberLuns; i++) {
1547 UniAtaReadLunConfig(deviceExtension, channel, i);
1548 }
1549 }
1550
1551 return TRUE;
1552 } // end AtapiReadChipConfig()
1553
1554 BOOLEAN
1555 NTAPI
1556 AtapiChipInit(
1557 IN PVOID HwDeviceExtension,
1558 IN ULONG DeviceNumber,
1559 IN ULONG channel // physical channel
1560 )
1561 {
1562 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1563 ULONG slotNumber = deviceExtension->slotNumber;
1564 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
1565 ULONG VendorID = deviceExtension->DevID & 0xffff;
1566 #ifdef _DEBUG
1567 ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
1568 #endif
1569 ULONG RevID = deviceExtension->RevID;
1570 // ULONG i;
1571 // BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo;
1572 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1573 ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
1574 PHW_CHANNEL chan;
1575 UCHAR tmp8;
1576 USHORT tmp16;
1577 ULONG tmp32;
1578 ULONG c; // logical channel (for Compatible Mode controllers)
1579 BOOLEAN CheckCable = FALSE;
1580 //ULONG BaseIoAddress;
1581
1582 switch(channel) {
1583 case CHAN_NOT_SPECIFIED_CHECK_CABLE:
1584 CheckCable = TRUE;
1585 /* FALLTHROUGH */
1586 case CHAN_NOT_SPECIFIED:
1587 c = CHAN_NOT_SPECIFIED;
1588 break;
1589 default:
1590 c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
1591 }
1592
1593 KdPrint2((PRINT_PREFIX "AtapiChipInit: dev %#x, ph chan %d\n", DeviceNumber, channel ));
1594
1595 KdPrint2((PRINT_PREFIX "HwFlags: %#x\n", deviceExtension->HwFlags));
1596 KdPrint2((PRINT_PREFIX "VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID, DeviceID, RevID));
1597
1598 if(deviceExtension->UnknownDev) {
1599 KdPrint2((PRINT_PREFIX " Unknown chip\n" ));
1600 //return TRUE;
1601 VendorID = 0xffffffff;
1602 }
1603
1604
1605 if(ChipFlags & UNIATA_AHCI) {
1606 /* if BAR(5) is IO it should point to SATA interface registers */
1607 if(!deviceExtension->BaseIoAHCI_0.Addr) {
1608 KdPrint2((PRINT_PREFIX " !BaseIoAHCI_0, exiting\n" ));
1609 return FALSE;
1610 }
1611 if(c == CHAN_NOT_SPECIFIED) {
1612 return UniataAhciInit(HwDeviceExtension);
1613 } else
1614 if(c<deviceExtension->NumberChannels) {
1615 KdPrint2((PRINT_PREFIX " AHCI single channel init\n" ));
1616 UniataAhciReset(HwDeviceExtension, c);
1617 return TRUE;
1618 } else {
1619 KdPrint2((PRINT_PREFIX " AHCI non-existent channel\n" ));
1620 return FALSE;
1621 }
1622 }
1623
1624 switch(VendorID) {
1625 // case ATA_ACARD_ID:
1626 // break;
1627 case ATA_ACER_LABS_ID:
1628 if(ChipFlags & UNIATA_SATA) {
1629 if(c == CHAN_NOT_SPECIFIED) {
1630 for(c=0; c<deviceExtension->NumberChannels; c++) {
1631 chan = &deviceExtension->chan[c];
1632 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
1633 /* the southbridge might need the data corruption fix */
1634 if(RevID == 0xc2 || RevID == 0xc3) {
1635 AtapiAliSouthBridgeFixup(HwDeviceExtension, PCIConfiguration,
1636 SystemIoBusNumber, slotNumber, c);
1637 }
1638 }
1639 /* enable PCI interrupt */
1640 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400));
1641 }
1642 } else
1643 if(ChipFlags & ALINEW) {
1644 if(c == CHAN_NOT_SPECIFIED) {
1645 /* use device interrupt as byte count end */
1646 ChangePciConfig1(0x4a, (a | 0x20));
1647 /* enable cable detection and UDMA support on newer chips, rev < 0xc7 */
1648 if(RevID < 0xc7) {
1649 ChangePciConfig1(0x4b, (a | 0x09));
1650 }
1651
1652 /* enable ATAPI UDMA mode */
1653 ChangePciConfig1(0x53, (a | (RevID >= 0xc7 ? 0x03 : 0x01)));
1654
1655 } else {
1656 // check 80-pin cable
1657 generic_cable80(deviceExtension, channel, 0x4a, 0);
1658 }
1659 } else {
1660 if(c == CHAN_NOT_SPECIFIED) {
1661 /* deactivate the ATAPI FIFO and enable ATAPI UDMA */
1662 ChangePciConfig1(0x53, (a | 0x03));
1663 } else {
1664 // ATAPI DMA R/O
1665 deviceExtension->chan[c].ChannelCtrlFlags |= CTRFLAGS_DMA_RO;
1666 }
1667 }
1668 break;
1669 case ATA_AMD_ID:
1670 if(c == CHAN_NOT_SPECIFIED) {
1671 /* set prefetch, postwrite */
1672 if(ChipFlags & AMDBUG) {
1673 ChangePciConfig1(0x41, (a & 0x0f));
1674 } else {
1675 ChangePciConfig1(0x41, (a | 0xf0));
1676 }
1677 }
1678 if(deviceExtension->MaxTransferMode < ATA_UDMA2)
1679 break;
1680 // check 80-pin cable
1681 if(!(ChipFlags & UNIATA_NO80CHK)) {
1682 if(c == CHAN_NOT_SPECIFIED) {
1683 // do nothing
1684 } else {
1685 generic_cable80(deviceExtension, channel, 0x42, 0);
1686 }
1687 }
1688 break;
1689 case ATA_HIGHPOINT_ID:
1690
1691 if(c == CHAN_NOT_SPECIFIED) {
1692
1693 if(ChipFlags & HPTOLD) {
1694 /* turn off interrupt prediction */
1695 ChangePciConfig1(0x51, (a & ~0x80));
1696 } else {
1697 /* turn off interrupt prediction */
1698 ChangePciConfig1(0x51, (a & ~0x03));
1699 ChangePciConfig1(0x55, (a & ~0x03));
1700 /* turn on interrupts */
1701 ChangePciConfig1(0x5a, (a & ~0x10));
1702 /* set clocks etc */
1703 if(ChipType < HPT372) {
1704 SetPciConfig1(0x5b, 0x22);
1705 } else {
1706 ChangePciConfig1(0x5b, ((a & 0x01) | 0x20));
1707 }
1708 }
1709
1710 } else {
1711 // check 80-pin cable
1712 chan = &deviceExtension->chan[c];
1713 if(!hpt_cable80(deviceExtension, channel)) {
1714 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
1715 }
1716 }
1717 break;
1718 case ATA_INTEL_ID: {
1719 BOOLEAN IsPata;
1720 USHORT reg54;
1721 UCHAR tmp8;
1722 if(ChipFlags & UNIATA_SATA) {
1723
1724 KdPrint2((PRINT_PREFIX "Intel SATA\n"));
1725 if(ChipFlags & UNIATA_AHCI) {
1726 KdPrint2((PRINT_PREFIX "Do nothing for AHCI\n"));
1727 break;
1728 }
1729 if(c == CHAN_NOT_SPECIFIED) {
1730 KdPrint2((PRINT_PREFIX "Base init\n"));
1731 /* force all ports active "the legacy way" */
1732 ChangePciConfig2(0x92, (a | 0x0f));
1733 /* enable PCI interrupt */
1734 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a & ~0x0400));
1735
1736 } else {
1737
1738 KdPrint2((PRINT_PREFIX "channel init\n"));
1739
1740 GetPciConfig1(0x90, tmp8);
1741 KdPrint2((PRINT_PREFIX "reg 90: %x, init lun map\n", tmp8));
1742
1743 KdPrint2((PRINT_PREFIX "chan %d\n", c));
1744 chan = &deviceExtension->chan[c];
1745 IsPata = FALSE;
1746 if(ChipFlags & ICH5) {
1747 KdPrint2((PRINT_PREFIX "ICH5\n"));
1748 if ((tmp8 & 0x04) == 0) {
1749 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
1750 chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ^ c;
1751 chan->lun[1]->SATA_lun_map = 0;
1752 } else if ((tmp8 & 0x02) == 0) {
1753 if(c == 0) {
1754 chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ? 1 : 0;
1755 chan->lun[1]->SATA_lun_map = (tmp8 & 0x01) ? 0 : 1;
1756 } else {
1757 IsPata = TRUE;
1758 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1759 }
1760 } else if ((tmp8 & 0x02) != 0) {
1761 if(c == 1) {
1762 chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ? 1 : 0;
1763 chan->lun[1]->SATA_lun_map = (tmp8 & 0x01) ? 0 : 1;
1764 } else {
1765 IsPata = TRUE;
1766 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1767 }
1768 }
1769 } else
1770 if(ChipFlags & I6CH2) {
1771 KdPrint2((PRINT_PREFIX "I6CH2\n"));
1772 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
1773 chan->lun[0]->SATA_lun_map = c ? 4 : 5;
1774 chan->lun[1]->SATA_lun_map = 0;
1775 } else {
1776 KdPrint2((PRINT_PREFIX "other Intel\n"));
1777 switch(tmp8 & 0x03) {
1778 case 0:
1779 chan->lun[0]->SATA_lun_map = 0+c;
1780 chan->lun[1]->SATA_lun_map = 2+c;
1781 break;
1782 case 2:
1783 if(c==0) {
1784 chan->lun[0]->SATA_lun_map = 0;
1785 chan->lun[1]->SATA_lun_map = 2;
1786 } else {
1787 // PATA
1788 IsPata = TRUE;
1789 }
1790 break;
1791 case 1:
1792 if(c==1) {
1793 chan->lun[0]->SATA_lun_map = 1;
1794 chan->lun[1]->SATA_lun_map = 3;
1795 } else {
1796 // PATA
1797 IsPata = TRUE;
1798 }
1799 break;
1800 }
1801 }
1802
1803 if(IsPata) {
1804 KdPrint2((PRINT_PREFIX "PATA part\n"));
1805 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA5);
1806 }
1807
1808 if(ChipType == INTEL_IDX) {
1809 KdPrint2((PRINT_PREFIX "io indexed\n"));
1810 //for(c=0; c<deviceExtension->NumberChannels; c++) {
1811 chan = &deviceExtension->chan[c];
1812 UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 0);
1813 if(!(chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE)) {
1814 UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 1);
1815 }
1816 //}
1817 }
1818 }
1819
1820 break;
1821 }
1822 if(deviceExtension->MaxTransferMode < ATA_UDMA2)
1823 break;
1824 // check 80-pin cable
1825 if(c == CHAN_NOT_SPECIFIED) {
1826 // do nothing
1827 } else {
1828 chan = &deviceExtension->chan[c];
1829 GetPciConfig2(0x54, reg54);
1830 if( ((reg54 >> (channel*2)) & 30) != 30) {
1831 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
1832 }
1833 }
1834 break; }
1835 case ATA_NVIDIA_ID: {
1836 if(ChipFlags & UNIATA_SATA) {
1837 if(c == CHAN_NOT_SPECIFIED) {
1838 ULONG offs = (ChipFlags & NV4OFF) ? 0x0440 : 0x0010;
1839 /* enable control access */
1840 ChangePciConfig1(0x50, (a | 0x04));
1841 /* MCP55 seems to need some time to allow r_res2 read. */
1842 AtapiStallExecution(10);
1843 KdPrint2((PRINT_PREFIX "BaseIoAddressSATA_0=%x\n", deviceExtension->BaseIoAddressSATA_0.Addr));
1844 if(ChipFlags & NVQ) {
1845 /* clear interrupt status */
1846 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, 0x00ff00ff);
1847 /* enable device and PHY state change interrupts */
1848 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4, 0x000d000d);
1849 /* disable NCQ support */
1850 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0400,
1851 AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0400) & 0xfffffff9);
1852 } else {
1853 /* clear interrupt status */
1854 AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, 0xff);
1855 /* enable device and PHY state change interrupts */
1856 AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1, 0xdd);
1857 }
1858 /* enable PCI interrupt */
1859 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400));
1860 } else {
1861 //UniataSataPhyEnable(HwDeviceExtension, c);
1862 }
1863 } else {
1864 //UCHAR reg52;
1865
1866 if(c == CHAN_NOT_SPECIFIED) {
1867 /* set prefetch, postwrite */
1868 ChangePciConfig1(0x51, (a & 0x0f));
1869 } else {
1870 // check 80-pin cable
1871 generic_cable80(deviceExtension, channel, 0x52, 1);
1872 /* chan = &deviceExtension->chan[c];
1873 GetPciConfig1(0x52, reg52);
1874 if( !((reg52 >> (channel*2)) & 0x01)) {
1875 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
1876 }*/
1877 }
1878 }
1879 break; }
1880 case ATA_PROMISE_ID: {
1881 USHORT Reg50;
1882 switch(ChipType) {
1883 case PRNEW:
1884 /* setup clocks */
1885 if(c == CHAN_NOT_SPECIFIED) {
1886 // ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);
1887 AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11,
1888 AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) | 0x0a );
1889 }
1890 /* FALLTHROUGH */
1891 case PROLD:
1892 /* enable burst mode */
1893 // ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
1894 if(c == CHAN_NOT_SPECIFIED) {
1895 AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x1f,
1896 AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x1f) | 0x01 );
1897 } else {
1898 // check 80-pin cable
1899 chan = &deviceExtension->chan[c];
1900 GetPciConfig2(0x50, Reg50);
1901 if(Reg50 & (1 << (channel+10))) {
1902 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
1903 }
1904 }
1905 break;
1906 case PRTX:
1907 if(c == CHAN_NOT_SPECIFIED) {
1908 // do nothing
1909 } else {
1910 // check 80-pin cable
1911 chan = &deviceExtension->chan[c];
1912 AtapiWritePort1(chan, IDX_BM_DeviceSpecific0, 0x0b);
1913 if(AtapiReadPort1(chan, IDX_BM_DeviceSpecific1) & 0x04) {
1914 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
1915 }
1916 }
1917 break;
1918 case PRMIO:
1919 if(c == CHAN_NOT_SPECIFIED) {
1920 if(ChipFlags & PRSATA) {
1921 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x6c, 0x000000ff);
1922 }
1923 } else {
1924 chan = &deviceExtension->chan[c];
1925 AtapiWritePort4(chan, IDX_BM_Command,
1926 (AtapiReadPort4(chan, IDX_BM_Command) & ~0x00000f8f) | channel );
1927 AtapiWritePort4(chan, IDX_BM_DeviceSpecific0, 0x00000001);
1928 // check 80-pin cable
1929 if(chan->MaxTransferMode < ATA_SA150 &&
1930 (AtapiReadPort4(chan, IDX_BM_Command) & 0x01000000)) {
1931 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
1932 }
1933 }
1934 break;
1935 }
1936 break; }
1937 case ATA_SERVERWORKS_ID:
1938 if(c == CHAN_NOT_SPECIFIED) {
1939 if(ChipType == SWKS33) {
1940 AtapiRosbSouthBridgeFixup(HwDeviceExtension, PCIConfiguration,
1941 SystemIoBusNumber, slotNumber);
1942 } else {
1943 ChangePciConfig1(0x5a, ((a & ~0x40) | ((ChipType == SWKS100) ? 0x03 : 0x02)));
1944 }
1945 }
1946 break;
1947 case ATA_ATI_ID:
1948 if(ChipType == SIIMIO) {
1949 KdPrint2((PRINT_PREFIX "ATI New\n"));
1950 // fall to SiI
1951 } else {
1952 KdPrint2((PRINT_PREFIX "ATI\n"));
1953 break;
1954 }
1955 case ATA_SILICON_IMAGE_ID:
1956 /* if(ChipFlags & SIIENINTR) {
1957 SetPciConfig1(0x71, 0x01);
1958 }*/
1959 switch(ChipType) {
1960 case SIIMIO: {
1961
1962 KdPrint2((PRINT_PREFIX "SII\n"));
1963 USHORT Reg79;
1964
1965 if(c == CHAN_NOT_SPECIFIED) {
1966 if(ChipFlags & SIISETCLK) {
1967 KdPrint2((PRINT_PREFIX "SIISETCLK\n"));
1968 GetPciConfig1(0x8a, tmp8);
1969 if ((tmp8 & 0x30) != 0x10)
1970 ChangePciConfig1(0x8a, (a & 0xcf) | 0x10);
1971 GetPciConfig1(0x8a, tmp8);
1972 if ((tmp8 & 0x30) != 0x10) {
1973 KdPrint2((PRINT_PREFIX "Sil 0680 could not set ATA133 clock\n"));
1974 deviceExtension->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA5);
1975 }
1976 }
1977 }
1978 if(deviceExtension->MaxTransferMode < ATA_SA150) {
1979 // check 80-pin cable
1980 if(c == CHAN_NOT_SPECIFIED) {
1981 // do nothing
1982 } else {
1983 KdPrint2((PRINT_PREFIX "Check UDMA66 cable\n"));
1984 chan = &deviceExtension->chan[c];
1985 GetPciConfig2(0x79, Reg79);
1986 if(Reg79 & (channel ? 0x02 : 0x01)) {
1987 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
1988 }
1989 }
1990 } else {
1991 ULONG unit01 = (c & 1);
1992 ULONG unit10 = (c & 2);
1993 /* enable/disable PHY state change interrupt */
1994 if(c == CHAN_NOT_SPECIFIED) {
1995 for(c=0; c<deviceExtension->NumberChannels; c++) {
1996 unit01 = (c & 1);
1997 unit10 = (c & 2);
1998 if(ChipFlags & SIINOSATAIRQ) {
1999 KdPrint2((PRINT_PREFIX "Disable broken SATA intr on c=%x\n", c));
2000 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x148 + (unit01 << 7) + (unit10 << 8),0);
2001 }
2002 }
2003 } else {
2004 if(ChipFlags & SIINOSATAIRQ) {
2005 KdPrint2((PRINT_PREFIX "Disable broken SATA intr on c=%x\n", c));
2006 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x148 + (unit01 << 7) + (unit10 << 8),0);
2007 } else {
2008 KdPrint2((PRINT_PREFIX "Enable SATA intr on c=%x\n", c));
2009 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x148 + (unit01 << 7) + (unit10 << 8),(1 << 16));
2010 }
2011 }
2012 }
2013 if(c == CHAN_NOT_SPECIFIED) {
2014 /* enable interrupt as BIOS might not */
2015 ChangePciConfig1(0x8a, (a & 0x3f));
2016 // Enable 3rd and 4th channels
2017 if (ChipFlags & SII4CH) {
2018 KdPrint2((PRINT_PREFIX "SII4CH\n"));
2019 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0200, 0x00000002);
2020 }
2021 } else {
2022 chan = &deviceExtension->chan[c];
2023 /* dont block interrupts */
2024 //ChangePciConfig4(0x48, (a & ~0x03c00000));
2025 tmp32 = AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x48);
2026 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x48, (1 << 22) << c);
2027 // flush
2028 tmp32 = AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x48);
2029
2030 /* Initialize FIFO PCI bus arbitration */
2031 GetPciConfig1(offsetof(PCI_COMMON_CONFIG, CacheLineSize), tmp8);
2032 if(tmp8) {
2033 KdPrint2((PRINT_PREFIX "SII: CacheLine=%d\n", tmp32));
2034 tmp8 = (tmp8/8)+1;
2035 AtapiWritePort2(chan, IDX_BM_DeviceSpecific1, ((USHORT)tmp8) << 8 | tmp8);
2036 } else {
2037 KdPrint2((PRINT_PREFIX "SII: CacheLine=0 !!!\n"));
2038 }
2039 }
2040 break; }
2041
2042 case SIICMD: {
2043
2044 KdPrint2((PRINT_PREFIX "SII_CMD\n"));
2045 if(c == CHAN_NOT_SPECIFIED) {
2046 /* Setup interrupts. */
2047 SetPciConfig1(0x71, 0x01);
2048
2049 /* GetPciConfig1(0x8a, tmp8);
2050 tmp8 &= ~(0x30);
2051 SetPciConfig1(0x71, tmp8);*/
2052
2053 /* Use MEMORY READ LINE for reads.
2054 * NOTE: Although not mentioned in the PCI0646U specs,
2055 * these bits are write only and won't be read
2056 * back as set or not. The PCI0646U2 specs clarify
2057 * this point.
2058 */
2059 /* tmp8 |= 0x02;
2060 SetPciConfig1(0x71, tmp8);
2061 */
2062 /* Set reasonable active/recovery/address-setup values. */
2063 SetPciConfig1(0x53, 0x40);
2064 SetPciConfig1(0x54, 0x3f);
2065 SetPciConfig1(0x55, 0x40);
2066 SetPciConfig1(0x56, 0x3f);
2067 SetPciConfig1(0x57, 0x1c);
2068 SetPciConfig1(0x58, 0x3f);
2069 SetPciConfig1(0x5b, 0x3f);
2070 }
2071
2072 break; }
2073 }
2074 break;
2075 case ATA_SIS_ID:
2076 if(c == CHAN_NOT_SPECIFIED) {
2077 switch(ChipType) {
2078 case SIS33:
2079 break;
2080 case SIS66:
2081 case SIS100OLD:
2082 ChangePciConfig1(0x52, (a & ~0x04));
2083 break;
2084 case SIS100NEW:
2085 case SIS133OLD:
2086 ChangePciConfig1(0x49, (a & ~0x01));
2087 break;
2088 case SIS133NEW:
2089 ChangePciConfig2(0x50, (a | 0x0008));
2090 ChangePciConfig2(0x52, (a | 0x0008));
2091 break;
2092 case SISSATA:
2093 ChangePciConfig2(0x04, (a & ~0x0400));
2094 }
2095 }
2096 if(ChipType == SIS133NEW) {
2097 USHORT tmp16;
2098 // check 80-pin cable
2099 if(c == CHAN_NOT_SPECIFIED) {
2100 // do nothing
2101 } else {
2102 chan = &deviceExtension->chan[c];
2103 GetPciConfig2(channel ? 0x52 : 0x50, tmp16);
2104 if(tmp16 & 0x8000) {
2105 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2106 }
2107 }
2108 } else {
2109 // check 80-pin cable
2110 if(c == CHAN_NOT_SPECIFIED) {
2111 // do nothing
2112 } else {
2113 chan = &deviceExtension->chan[c];
2114 GetPciConfig1(48, tmp8);
2115 if(tmp8 & (0x10 << channel)) {
2116 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2117 }
2118 }
2119 }
2120 break;
2121 case ATA_VIA_ID:
2122
2123 /* if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI | VIASATA) {
2124 break;
2125 }*/
2126 if(c == CHAN_NOT_SPECIFIED) {
2127 /* prepare for ATA-66 on the 82C686a and 82C596b */
2128 if(ChipFlags & VIACLK) {
2129 ChangePciConfig4(0x50, (a | 0x030b030b));
2130 }
2131 // no init for SATA
2132 if(ChipFlags & (UNIATA_SATA | VIASATA)) {
2133 /* enable PCI interrupt */
2134 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a & ~0x0400));
2135 break;
2136 }
2137
2138 /* the southbridge might need the data corruption fix */
2139 if(ChipFlags & VIABUG) {
2140 AtapiViaSouthBridgeFixup(HwDeviceExtension, PCIConfiguration,
2141 SystemIoBusNumber, slotNumber);
2142 }
2143 /* set prefetch, postwrite */
2144 if(ChipType != VIA133) {
2145 ChangePciConfig1(0x41, (a | 0xf0));
2146 }
2147
2148 /* set fifo configuration half'n'half */
2149 ChangePciConfig1(0x43, ((a & ((ChipFlags & VIAPRQ) ? 0x80 : 0x90)) | 0x2a));
2150
2151 /* set status register read retry */
2152 ChangePciConfig1(0x44, (a | 0x08));
2153
2154 /* set DMA read & end-of-sector fifo flush */
2155 ChangePciConfig1(0x46, ((a & 0x0c) | 0xf0));
2156
2157 /* set sector size */
2158 SetPciConfig2(0x60, DEV_BSIZE);
2159 SetPciConfig2(0x68, DEV_BSIZE);
2160 } else {
2161
2162 chan = &deviceExtension->chan[c];
2163 // no init for SATA
2164 if(ChipFlags & (UNIATA_SATA | VIASATA)) {
2165 if((ChipFlags & VIABAR) && (c >= 2)) {
2166 break;
2167 }
2168 UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 0);
2169 break;
2170 }
2171
2172 // check 80-pin cable
2173 if(!via_cable80(deviceExtension, channel)) {
2174 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2175 }
2176 }
2177
2178 break;
2179
2180 case ATA_ITE_ID:
2181 if(ChipType == ITE_33 || ChipType == ITE_133_NEW) {
2182 break;
2183 }
2184 if(ChipType == ITE_133) {
2185 if(c == CHAN_NOT_SPECIFIED) {
2186 /* set PCI mode and 66Mhz reference clock */
2187 ChangePciConfig1(0x50, a & ~0x83);
2188
2189 /* set default active & recover timings */
2190 SetPciConfig1(0x54, 0x31);
2191 SetPciConfig1(0x56, 0x31);
2192 } else {
2193 // check 80-pin cable
2194 GetPciConfig2(0x40, tmp16);
2195 chan = &deviceExtension->chan[c];
2196 if(!(tmp16 & (channel ? 0x08 : 0x04))) {
2197 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2198 }
2199 }
2200 } else
2201 if(ChipType == ITE_133_NEW) {
2202 }
2203 break;
2204 default:
2205 if(c != CHAN_NOT_SPECIFIED) {
2206 // We don't know how to check for 80-pin cable on unknown controllers.
2207 // Later we shall check bit in IDENTIFY structure, but it is not reliable way.
2208 // So, leave this flag to use as hint in error recovery procedures
2209 KdPrint2((PRINT_PREFIX "UNIATA_NO80CHK\n"));
2210 deviceExtension->HwFlags |= UNIATA_NO80CHK;
2211 }
2212 break;
2213 }
2214
2215 // In all places separate channels are inited after common controller init
2216 // The only exception is probe. But there we may need info about 40/80 pin and MaxTransferRate
2217 if(CheckCable && !(ChipFlags & (UNIATA_NO80CHK | UNIATA_SATA))) {
2218 for(c=0; c<deviceExtension->NumberChannels; c++) {
2219 AtapiChipInit(HwDeviceExtension, DeviceNumber, c);
2220 }
2221 }
2222
2223 return TRUE;
2224 } // end AtapiChipInit()
2225
2226 VOID
2227 NTAPI
2228 UniataInitMapBM(
2229 IN PHW_DEVICE_EXTENSION deviceExtension,
2230 IN PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0,
2231 IN BOOLEAN MemIo
2232 )
2233 {
2234 PHW_CHANNEL chan;
2235 ULONG c;
2236 ULONG i;
2237
2238 if(!BaseIoAddressBM_0) {
2239 MemIo = FALSE;
2240 }
2241 for(c=0; c<deviceExtension->NumberChannels; c++) {
2242 chan = &deviceExtension->chan[c];
2243 for (i=0; i<IDX_BM_IO_SZ; i++) {
2244 chan->RegTranslation[IDX_BM_IO+i].Addr = BaseIoAddressBM_0 ? ((ULONGIO_PTR)BaseIoAddressBM_0 + i) : 0;
2245 chan->RegTranslation[IDX_BM_IO+i].MemIo = MemIo;
2246 }
2247 if(BaseIoAddressBM_0) {
2248 BaseIoAddressBM_0++;
2249 }
2250 }
2251 } // end UniataInitMapBM()
2252
2253 VOID
2254 NTAPI
2255 UniataInitMapBase(
2256 IN PHW_CHANNEL chan,
2257 IN PIDE_REGISTERS_1 BaseIoAddress1,
2258 IN PIDE_REGISTERS_2 BaseIoAddress2
2259 )
2260 {
2261 ULONG i;
2262
2263 for (i=0; i<IDX_IO1_SZ; i++) {
2264 chan->RegTranslation[IDX_IO1+i].Addr = BaseIoAddress1 ? ((ULONGIO_PTR)BaseIoAddress1 + i) : 0;
2265 chan->RegTranslation[IDX_IO1+i].MemIo = FALSE;
2266 }
2267 for (i=0; i<IDX_IO2_SZ; i++) {
2268 chan->RegTranslation[IDX_IO2+i].Addr = BaseIoAddress2 ? ((ULONGIO_PTR)BaseIoAddress2 + i) : 0;
2269 chan->RegTranslation[IDX_IO2+i].MemIo = FALSE;
2270 }
2271 UniataInitSyncBaseIO(chan);
2272 } // end UniataInitMapBase()
2273
2274 VOID
2275 NTAPI
2276 UniataInitSyncBaseIO(
2277 IN PHW_CHANNEL chan
2278 )
2279 {
2280 RtlCopyMemory(&chan->RegTranslation[IDX_IO1_o], &chan->RegTranslation[IDX_IO1], IDX_IO1_SZ*sizeof(chan->RegTranslation[0]));
2281 RtlCopyMemory(&chan->RegTranslation[IDX_IO2_o], &chan->RegTranslation[IDX_IO2], IDX_IO2_SZ*sizeof(chan->RegTranslation[0]));
2282 } // end UniataInitSyncBaseIO()
2283
2284 VOID
2285 NTAPI
2286 AtapiSetupLunPtrs(
2287 IN PHW_CHANNEL chan,
2288 IN PHW_DEVICE_EXTENSION deviceExtension,
2289 IN ULONG c
2290 )
2291 {
2292 ULONG i;
2293
2294 if(!deviceExtension->NumberLuns) {
2295 deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN;
2296 }
2297 chan->DeviceExtension = deviceExtension;
2298 chan->lChannel = c;
2299 chan->NumberLuns = deviceExtension->NumberLuns;
2300 for(i=0; i<deviceExtension->NumberLuns; i++) {
2301 chan->lun[i] = &(deviceExtension->lun[c*deviceExtension->NumberLuns+i]);
2302 }
2303 chan->AltRegMap = deviceExtension->AltRegMap;
2304 chan->NextDpcChan = -1;
2305 for(i=0; i<deviceExtension->NumberLuns; i++) {
2306 chan->lun[i]->DeviceExtension = deviceExtension;
2307 chan->lun[i]->chan = chan;
2308 chan->lun[i]->Lun = i;
2309 }
2310 } // end AtapiSetupLunPtrs()
2311