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