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