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