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