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