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