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