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