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